Eventin <= 4.1.3 - Authenticated (Contributor+) PHP Object Injection
Description
The Eventin plugin for WordPress is vulnerable to PHP Object Injection in versions up to, and including, 4.1.3 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
<=4.1.3What Changed in the Fix
Changes introduced in v4.1.4
Source Code
WordPress.org SVN# Vulnerability Research Plan: CVE-2025-68047 ## 1. Vulnerability Summary The **Eventin** plugin (versions <= 4.1.3) is vulnerable to **PHP Object Injection** via the deserialization of untrusted data. The vulnerability exists in the plugin's shortcode generator functionality, which is accessible t…
Show full research plan
Vulnerability Research Plan: CVE-2025-68047
1. Vulnerability Summary
The Eventin plugin (versions <= 4.1.3) is vulnerable to PHP Object Injection via the deserialization of untrusted data. The vulnerability exists in the plugin's shortcode generator functionality, which is accessible to authenticated users with Contributor-level permissions or higher. The backend fails to sanitize or validate input passed to a deserialization function (likely maybe_unserialize or unserialize) when processing shortcode configuration data via AJAX.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
etn_get_shortcode_template_ajax(inferred from JS logic in168.7f074eee.js) - Vulnerable Parameter:
shortcode_data - Authentication: Authenticated (Contributor+)
- Preconditions: The attacker must have a valid session with at least Contributor permissions. The plugin's shortcode generator scripts must be enqueued (standard on post/page editor screens).
3. Code Flow
- Frontend Entry (JS Chunk 168): The React-based UI handles shortcode configuration (e.g., for
event-with-calendar,advanced-search, orschedule). - Trigger: When a user interacts with the shortcode builder, the
handleGetScript(aliased asSin minified JS) orhandleGenerate(g) function is triggered. - AJAX Request: These functions initiate an AJAX call to
admin-ajax.phpwith the actionetn_get_shortcode_template_ajax. The current form state (attributes likestyle,limit,category) is collected into a data object. - Data Transmission: This data is sent to the server, often inside a parameter named
shortcode_data. - Backend Sink (Inferred PHP): The backend AJAX handler (likely in a class named
ETN_Shortcode_Generatoror similar) retrieves$_POST['shortcode_data']. - Vulnerable Sink: The code calls
maybe_unserialize( stripslashes( $_POST['shortcode_data'] ) )orunserialize(). Sinceshortcode_datais directly user-controlled, an attacker can provide a serialized PHP object instead of the expected array/string.
4. Nonce Acquisition Strategy
The shortcode generator requires a nonce for verification (check_ajax_referer or wp_verify_nonce). In Eventin, nonces for admin/AJAX actions are typically localized into a global JavaScript object.
- Target Page: The shortcode generator is loaded on the "Add New Post" or "Add New Event" screen.
- Creation: Create a temporary post to ensure the environment is ready.
wp post create --post_type=post --post_status=publish --post_title="Exploit Target" - Extraction:
- Navigate to the post editor as the Contributor user.
- Use
browser_evalto extract the nonce from theetn_shortcode_objoreventin_admin_dataobject. - JS Identifier: Based on Eventin's architecture, the variable is likely
window.etn_shortcode_obj?.nonce.
5. Exploitation Strategy
The exploit will involve sending a specially crafted POST request to the AJAX endpoint.
- Preparation:
- Login as a Contributor.
- Navigate to
wp-admin/post-new.php. - Extract the nonce using
browser_eval.
- Payload Generation:
- Since no POP chain is confirmed in Eventin itself, use a generic PHP object to confirm injection. If the environment has
GuzzleHttpor other common libraries, a chain could be used. For verification, we will inject a non-existent class and look for a "Class Not Found" error ifWP_DEBUGis on, or use a known internal WP class. - Payload:
O:8:"stdClass":1:{s:3:"poi";s:7:"success";}(SerializedstdClassobject).
- Since no POP chain is confirmed in Eventin itself, use a generic PHP object to confirm injection. If the environment has
- HTTP Request (via
http_requesttool):- Method: POST
- URL:
https://<target>/wp-admin/admin-ajax.php - Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=etn_get_shortcode_template_ajax&nonce=<NONCE>&shortcode_data=O:8:"stdClass":1:{s:3:"poi";s:7:"success";}
6. Test Data Setup
- User: Create a Contributor user.
wp user create attacker attacker@example.com --role=contributor --user_pass=password123 - Plugin: Ensure
wp-event-solutionversion 4.1.3 is installed and active. - Content: Ensure at least one event category exists to populate the shortcode UI (though not strictly required for the sink).
wp term create event_category "Test Category" --slug=test-cat
7. Expected Results
- Successful Exploitation: The server processes the request. If a class-based payload is used (e.g., a non-existent class
O:14:"ExploitTrigger":0:{}), the PHP error log or response (ifWP_DEBUGis active) will show an__unserialize()or__wakeup()attempt or a fatal error:PHP Fatal error: unserialize(): Unknown or dangling tag .... - Response: Usually, the AJAX handler returns a JSON response. A successful injection might still return a
200 OKbut trigger the object's magic methods on the backend.
8. Verification Steps
- Logs: Check
/var/www/html/wp-content/debug.logfor evidence of the injected class being processed. - Blind Verification: Use a payload that triggers a time delay (if a POP chain like
Guzzleis present) or use a "pingback" class if available. - Manual Trace: Use
wp evalto check ifmaybe_unserializebehaves as expected with the provided payload:wp eval 'var_dump(maybe_unserialize("O:8:\"stdClass\":1:{s:3:\"poi\";s:7:\"success\";}"));'
Confirm the output is anobject(stdClass)and not an array.
9. Alternative Approaches
- Different Actions: If
etn_get_shortcode_template_ajaxis not the correct action, search for other AJAX hooks registered by the plugin using:grep -r "wp_ajax_" wp-content/plugins/wp-event-solution/ | grep "shortcode" - Different Parameter: The parameter might be
dataorsettingsinstead ofshortcode_data. Verify by inspecting the network tab in the browser while using the Shortcode Generator UI. - AI Integration Endpoint: JS Chunk 213 mentions
eventin-ai-create-event-modal. The AI features might also pass serialized settings to the backend.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.