Directory Listings WordPress plugin – uListing <= 2.2.0 - Authenticated (Editor+) Arbitrary File Download
Description
The Directory Listings WordPress plugin – uListing plugin for WordPress is vulnerable to Directory Traversal in all versions up to, and including, 2.2.0. This makes it possible for authenticated attackers, with Editor-level access and above, to read the contents of arbitrary files on the server, which can contain sensitive information.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:N/A:NTechnical Details
This research plan focuses on identifying and exploiting an authenticated directory traversal vulnerability in the **uListing** plugin (versions <= 2.2.0). --- ### 1. Vulnerability Summary The **uListing** plugin for WordPress is vulnerable to **Arbitrary File Download** via directory traversal. T…
Show full research plan
This research plan focuses on identifying and exploiting an authenticated directory traversal vulnerability in the uListing plugin (versions <= 2.2.0).
1. Vulnerability Summary
The uListing plugin for WordPress is vulnerable to Arbitrary File Download via directory traversal. The vulnerability exists because an authenticated user with Editor-level permissions or higher can trigger a file download action where the file path is constructed using user-supplied input without sufficient sanitization or validation. This allows attackers to escape the intended directory and read sensitive files like wp-config.php or system files like /etc/passwd.
2. Attack Vector Analysis
- Endpoint:
wp-admin/admin-ajax.php - Action (Inferred): Likely a
wp_ajax_handler associated with exporting listings, downloading logs, or template management. (Common uListing patterns suggest actions likeulisting_ajax_download_exportorulisting_ajax_get_file). - Parameter: A GET or POST parameter (likely
file,path, orfilename) containing the traversal string. - Authentication: Required (Editor or higher).
- Preconditions: The plugin must be active, and the attacker must have valid Editor credentials.
3. Code Flow (Inferred Strategy)
The automated agent must trace the input using the following methodology:
Entry Point Identification:
Search for AJAX handlers registered by the plugin that involve file operations:grep -r "wp_ajax_" wp-content/plugins/ulisting/ | grep -E "download|export|file|log"Sink Discovery:
Identify where the callback function for that action uses dangerous file system sinks:# Potential sinks: readfile, file_get_contents, fopen, wp_send_json with file content grep -rE "readfile|file_get_contents|download" wp-content/plugins/ulisting/Tracing:
Locate the function associated with thewp_ajax_action. Confirm if it retrieves a parameter (e.g.,$_GET['file']) and passes it directly into a sink likereadfile()without callingbasename()or validating the path against a whitelist/allowed directory.
4. Nonce Acquisition Strategy
uListing typically localizes its AJAX configuration and nonces.
- Identify Shortcode/Page: uListing often enqueues scripts on pages where directory listings are displayed or in the admin dashboard.
- Creation: Create a post containing a uListing shortcode if needed:
wp post create --post_type=page --post_status=publish --post_content='[ulisting_listing_grid]' - Extraction:
Navigate to the page (or the uListing admin menu) and extract the nonce from the global JavaScript objects:- Common Variable Name (Inferred):
ulisting_ajaxorulisting_common. - Key (Inferred):
nonceorulisting_ajax_nonce. - Execution:
browser_eval("window.ulisting_ajax?.nonce")orbrowser_eval("window.ulisting_common?.nonce").
- Common Variable Name (Inferred):
Note: If check_ajax_referer is used with the action string and the localized nonce, the agent must use that specific nonce.
5. Exploitation Strategy
Once the vulnerable action and parameter are identified via grep:
- Login: Authenticate as an Editor.
- Nonce: Extract the nonce using the strategy in Section 4.
- Request: Use the
http_requesttool to perform the traversal.
Example Payload (Hypothetical):
- Action:
ulisting_ajax_download_export(Verify via grep) - Parameter:
file(Verify via grep) - Method: GET
HTTP Request:
POST /wp-admin/admin-ajax.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded
action=ulisting_ajax_download_export&nonce=[NONCE]&file=../../../../wp-config.php
6. Test Data Setup
- Install Plugin: Ensure uListing v2.2.0 is installed and active.
- Create User:
wp user create attacker attacker@example.com --role=editor --user_pass=password123 - Create Content: Ensure at least one directory listing exists if the download logic requires a valid listing ID context.
7. Expected Results
- Success: The server response should contain the cleartext contents of
wp-config.php(identifiable bydefine('DB_NAME', ...);) or the targeted file. - Headers: The
Content-Typemight beapplication/octet-streamortext/plain, andContent-Dispositionmay contain the filename.
8. Verification Steps
After the http_request returns the data:
- Content Check: Verify the presence of WordPress configuration strings in the response body.
- File System Check: Use
wp_clito confirm the content matches the actualwp-config.phpon the server:cat /var/www/html/wp-config.php(Compare with exploit output).
9. Alternative Approaches
- If Action is restricted to Admin: Check if the Editor can access the uListing "Settings" or "Tools" page in the dashboard where export functionality might be triggered.
- Path Variations:
- Try absolute paths:
/etc/passwd - Try depth variations:
../../../../../../../../etc/passwd - Try null byte injection (if PHP version is < 5.3.4, unlikely here):
../../wp-config.php%00 - Try URL encoding variations for the dots and slashes.
- Try absolute paths:
- Different Parameters: If
filefails, check forpath,src,url, ordocument.
Summary
The uListing plugin for WordPress is vulnerable to directory traversal in versions up to and including 2.2.0 due to insufficient input validation in its file download functionality. Authenticated attackers with Editor-level permissions can exploit this vulnerability to read arbitrary files from the server, including sensitive configuration files like wp-config.php.
Security Fix
@@ -115,7 +115,7 @@ public function download_export() { - $file = $_GET['file']; + $file = basename(sanitize_text_field($_GET['file'])); $file_path = ULISTING_UPLOAD_DIR . '/exports/' . $file; if (file_exists($file_path)) { header('Content-Type: application/octet-stream');
Exploit Outline
The exploit is performed by an authenticated user with Editor-level access or higher. First, the attacker extracts an AJAX nonce (e.g., 'ulisting_ajax_nonce') typically localized within the 'ulisting_ajax' JavaScript object in the WordPress admin dashboard. The attacker then sends a request to '/wp-admin/admin-ajax.php' using a vulnerable action such as 'ulisting_ajax_download_export'. By providing a 'file' parameter containing a directory traversal payload (e.g., '../../../../wp-config.php'), the attacker can bypass the intended directory restrictions and download sensitive files from the server.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.