#!/usr/bin/env python3 """Agent for detecting MS17-010 (EternalBlue) vulnerability — authorized testing only.""" import argparse import json import socket import subprocess from datetime import datetime, timezone SMB_NEGOTIATE = ( b"\x00\x00\x00\x85" # NetBIOS b"\xff\x53\x4d\x42" # SMB magic b"\x72" # Negotiate Protocol b"\x00\x00\x00\x00" # Status b"\x18\x53\xc8" # Flags b"\x00\x00" # Flags2 b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" # Extra b"\x00\x00\xff\xfe\x00\x00\x00\x00" # TreeID/PID b"\x00\x00\x00\x00" # UserID/MuxID b"\x00" # WordCount b"\x62\x00" # ByteCount b"\x02\x50\x43\x20\x4e\x45\x54\x57\x4f\x52\x4b\x20\x50\x52\x4f" b"\x47\x52\x41\x4d\x20\x31\x2e\x30\x00" b"\x02\x4c\x41\x4e\x4d\x41\x4e\x31\x2e\x30\x00" b"\x02\x57\x69\x6e\x64\x6f\x77\x73\x20\x66\x6f\x72\x20\x57\x6f" b"\x72\x6b\x67\x72\x6f\x75\x70\x73\x20\x33\x2e\x31\x61\x00" b"\x02\x4c\x4d\x31\x2e\x32\x58\x30\x30\x32\x00" b"\x02\x4c\x41\x4e\x4d\x41\x4e\x32\x2e\x31\x00" b"\x02\x4e\x54\x20\x4c\x4d\x20\x30\x2e\x31\x32\x00" ) def check_ms17_010(target_ip, port=445, timeout=5): """Check if target is vulnerable to MS17-010 via SMB negotiation.""" result = { "target": target_ip, "port": port, "smb_open": False, "vulnerable": False, "os_info": "", } try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(timeout) sock.connect((target_ip, port)) result["smb_open"] = True sock.send(SMB_NEGOTIATE) data = sock.recv(4096) if len(data) > 36: result["os_info"] = "SMB service responding" if data[4:8] == b"\xff\x53\x4d\x42": result["smb_version"] = "SMBv1" sock.close() except (socket.timeout, ConnectionRefusedError, OSError): pass return result def nmap_ms17_010_check(target_ip): """Use nmap NSE script to check for MS17-010.""" try: result = subprocess.check_output( ["nmap", "-p", "445", "--script", "smb-vuln-ms17-010", target_ip], text=True, errors="replace", timeout=30 ) vulnerable = "VULNERABLE" in result return { "target": target_ip, "method": "nmap", "vulnerable": vulnerable, "output": result[:500], } except (subprocess.SubprocessError, FileNotFoundError): return {"target": target_ip, "method": "nmap", "status": "nmap not available"} def scan_network(cidr, port=445): """Scan a network range for SMB port and MS17-010.""" import ipaddress results = [] try: network = ipaddress.ip_network(cidr, strict=False) except ValueError: return results for ip in list(network.hosts())[:256]: ip_str = str(ip) result = check_ms17_010(ip_str, port, timeout=2) if result["smb_open"]: results.append(result) return results def main(): parser = argparse.ArgumentParser( description="Detect MS17-010 EternalBlue vulnerability (authorized testing only)" ) parser.add_argument("--target", help="Target IP address") parser.add_argument("--network", help="Network CIDR to scan") parser.add_argument("--nmap", action="store_true", help="Use nmap NSE script") parser.add_argument("--output", "-o", help="Output JSON report") args = parser.parse_args() print("[*] MS17-010 (EternalBlue) Vulnerability Detection Agent") print("[!] For authorized security testing only") report = {"timestamp": datetime.now(timezone.utc).isoformat(), "findings": []} if args.target: if args.nmap: result = nmap_ms17_010_check(args.target) else: result = check_ms17_010(args.target) report["findings"].append(result) print(f"[*] {args.target}: SMB open={result.get('smb_open')}") if args.network: results = scan_network(args.network) report["findings"].extend(results) print(f"[*] Network scan: {len(results)} hosts with SMB open") report["risk_level"] = "CRITICAL" if any(f.get("vulnerable") for f in report["findings"]) else "LOW" if args.output: with open(args.output, "w") as f: json.dump(report, f, indent=2) print(f"[*] Report saved to {args.output}") else: print(json.dumps(report, indent=2)) if __name__ == "__main__": main()