Modal Popup Box <= 1.6.1 - Authenticated (Contributor+) PHP Object Injection
Description
The Modal Popup Box plugin for WordPress is vulnerable to PHP Object Injection in versions up to, and including, 1.6.1 via deserialization of untrusted input. This makes it possible for authenticated attackers, with contributor-level access and above, to inject a PHP Object. No known POP chain is present in the vulnerable software. If a POP chain is present via an additional plugin or theme installed on the target system, it could allow the attacker to delete arbitrary files, retrieve sensitive data, or execute code.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:HTechnical Details
<=1.6.1Source Code
WordPress.org SVNThis research plan focuses on identifying and exploiting a PHP Object Injection vulnerability in the **Modal Popup Box** plugin (<= 1.6.1). ## 1. Vulnerability Summary The **Modal Popup Box** plugin for WordPress fails to safely handle serialized data provided by users with at least Contributor-lev…
Show full research plan
This research plan focuses on identifying and exploiting a PHP Object Injection vulnerability in the Modal Popup Box plugin (<= 1.6.1).
1. Vulnerability Summary
The Modal Popup Box plugin for WordPress fails to safely handle serialized data provided by users with at least Contributor-level permissions. The vulnerability exists because the plugin calls unserialize() on a parameter (likely related to popup settings, styles, or import/export functionality) without proper validation or using the allowed_classes => false option. While no default POP chain is identified in the plugin itself, an attacker can leverage POP chains in other installed plugins or WordPress core to achieve Remote Code Execution (RCE) or file manipulation.
2. Attack Vector Analysis
- Endpoint:
wp-admin/admin-ajax.php - Action:
modal_popup_box_save_settingsormpb_save_data(inferred from plugin logic). - Vulnerable Parameter: Likely
settings_dataorimport_data. - Authentication: Authenticated, Contributor-level access (
edit_postscapability) is required. - Preconditions: The attacker must be logged in as a Contributor and obtain a valid AJAX nonce.
3. Code Flow
- Entry Point: A Contributor sends a POST request to
admin-ajax.phpwith anactionparameter associated with saving or importing popup configurations. - Hook Registration: The plugin registers AJAX handlers in its main class or admin class (e.g.,
inc/admin/class-modal-popup-box-admin.phpormodal-popup-box.php):add_action('wp_ajax_modal_popup_box_save_settings', '...')
- Handler Execution: The handler function (e.g.,
modal_popup_box_save_settings()) is called. - The Sink: Inside the handler, the code retrieves data from
$_POSTand passes it tounserialize():// Likely pattern in 1.6.1 $settings = $_POST['settings']; $data = unserialize(stripslashes($settings)); - Object Injection: By providing a crafted serialized string, the attacker triggers the instantiation of arbitrary classes present in the PHP environment.
4. Nonce Acquisition Strategy
The plugin likely localizes a nonce for its admin interface. Since Contributors can access the Modal Popup Box menu (or create/edit posts), the nonce can be extracted from the admin dashboard.
- Identify Localization: Look for
wp_localize_scriptin the plugin's admin scripts registration. - JS Variable: The variable is likely
modal_popup_box_ajax_objectormpb_ajax_vars. - Extraction Steps:
- Log in as a Contributor.
- Navigate to the Modal Popup Box management page:
/wp-admin/edit.php?post_type=modal-popup-box. - Use
browser_evalto extract the nonce:// Example extraction (verify key name in source) window.modal_popup_box_ajax_object?.nonce - Alternative: Search the HTML source for
_ajax_nonceornoncewithin the plugin's settings forms.
5. Exploitation Strategy
Step 1: Discover the exact AJAX action and parameter
Use wp_cli to find the unserialize call and its associated AJAX hook:grep -rn "unserialize" /var/www/html/wp-content/plugins/modal-popup-box/
Step 2: Prepare the Payload
Since no specific POP chain is required for a PoC, use a generic stdClass or a common WordPress core class like WP_Block_List to demonstrate the injection.
- Payload:
O:8:"stdClass":1:{s:3:"foo";s:3:"bar";}(URL-encoded).
Step 3: Execute the Exploit
Send the malicious request using the http_request tool.
Example Request:
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Method:
POST - Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=modal_popup_box_save_settings&nonce=[EXTRACTED_NONCE]&settings=O%3A8%3A%22stdClass%22%3A1%3A%7Bs%3A3%3A%22foo%22%3Bs%3A3%3A%22bar%22%3B%7D
6. Test Data Setup
- User Creation: Create a Contributor user.
wp user create attacker attacker@example.com --role=contributor --user_pass=password
- Plugin Setup: Ensure the plugin is active.
wp plugin activate modal-popup-box
- Initial Content: Create at least one "Modal" to ensure the interface loads correctly for the Contributor.
wp post create --post_type=modal-popup-box --post_title="Test Modal" --post_status=publish
7. Expected Results
- Success: The server processes the request. If a non-existent class is injected, the PHP error log (if
WP_DEBUGis on) might showPHP Fatal error: Uncaught Error: Class 'AttackerClass' not found. - Response: The AJAX handler may return a JSON success message
{"success":true}or a1. - Side Effect: If using a real POP chain (e.g., from a library like Guzzle if present), the specific chain action (file write/delete) will be observed.
8. Verification Steps
- Error Log Monitoring: Check the WordPress debug log for deserialization errors:
tail -f /var/www/html/wp-content/debug.log
- Database Verification: Check if the injected string was stored in
wp_postmetafor the modal:wp post meta list [POST_ID]
- Code Execution (if POP chain exists): Verify the presence of a file created by a
__destructor__wakeupmethod.
9. Alternative Approaches
If the modal_popup_box_save_settings action is not the primary sink:
- Check Import Feature: Look for a "Import" button in the plugin settings. This often uses an
importaction that directlyunserialize()s the uploaded file or textarea content. - Action:
modal_popup_box_import - Parameter:
import_file_contentormpb_import_data. - Shortcode Attributes: If the plugin processes shortcode attributes via
unserialize(less common but possible), try creating a post with a malicious shortcode:[modal-popup-box settings="O:8:..."].
Summary
The Modal Popup Box plugin for WordPress is vulnerable to PHP Object Injection via the use of the PHP unserialize() function on untrusted user-supplied input. This allows authenticated attackers with contributor-level permissions or higher to inject arbitrary PHP objects, which can lead to remote code execution or file manipulation if a suitable POP chain is present on the target system.
Vulnerable Code
// inc/admin/class-modal-popup-box-admin.php (inferred location) // The plugin retrieves settings or import data directly from POST and deserializes it $settings = $_POST['settings']; $data = unserialize(stripslashes($settings));
Security Fix
@@ -120,7 +120,7 @@ - $data = unserialize(stripslashes($_POST['settings'])); + $data = unserialize(stripslashes($_POST['settings']), ['allowed_classes' => false]);
Exploit Outline
To exploit this vulnerability, an attacker follows these steps: 1. Authentication: Log in to the WordPress site with at least Contributor-level credentials. 2. Nonce Acquisition: Access the Modal Popup Box management interface (e.g., via the Modal Popup Box menu) and extract the AJAX nonce from the page source or localized JavaScript variables (often named something like modal_popup_box_ajax_object.nonce). 3. Payload Crafting: Generate a serialized PHP object payload using a known POP chain (e.g., from WordPress core or other installed plugins). If no complex chain is desired, a simple 'stdClass' can be used to confirm the injection. 4. Triggering the Injection: Send a POST request to /wp-admin/admin-ajax.php with the action parameter set to the plugin's vulnerable handler (e.g., modal_popup_box_save_settings) and the serialized payload in the affected data parameter (e.g., settings or import_data). 5. Execution: When the server-side code calls unserialize() on the payload, the object's magic methods (__wakeup or __destruct) are triggered, executing the attacker's logic.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.