Execute the red-blue loop against a target. Args: target: IP, CIDR, hostname, or range mode: recon_only | confirm_only | confirm_and_plan | full_auto scan_profile: Scan intensity: quick | normal | full | s
(
self,
target: str,
mode: str = "confirm_only",
scan_profile: str = "normal",
os_hint: str = "Linux",
max_exploit_concurrent: int = 5,
)
| 161 | |
| 162 | async def run( |
| 163 | self, |
| 164 | target: str, |
| 165 | mode: str = "confirm_only", |
| 166 | scan_profile: str = "normal", |
| 167 | os_hint: str = "Linux", |
| 168 | max_exploit_concurrent: int = 5, |
| 169 | ) -> LoopReport: |
| 170 | """ |
| 171 | Execute the red-blue loop against a target. |
| 172 | |
| 173 | Args: |
| 174 | target: IP, CIDR, hostname, or range |
| 175 | mode: recon_only | confirm_only | confirm_and_plan | full_auto |
| 176 | scan_profile: Scan intensity: quick | normal | full | stealth |
| 177 | os_hint: OS family for AI remediation prompts |
| 178 | max_exploit_concurrent: Max parallel Metasploit check() calls |
| 179 | """ |
| 180 | if mode not in VALID_MODES: |
| 181 | raise ValueError(f"Invalid mode '{mode}'. Choose from: {VALID_MODES}") |
| 182 | |
| 183 | session = guardrails.active_session() |
| 184 | if not session: |
| 185 | raise PermissionError( |
| 186 | "No active engagement session. " |
| 187 | "Call guardrails.create_session() before running the loop." |
| 188 | ) |
| 189 | if session.is_expired(): |
| 190 | raise PermissionError("Engagement session has expired. Create a new session.") |
| 191 | |
| 192 | report = LoopReport( |
| 193 | target=target, |
| 194 | mode=mode, |
| 195 | operator=session.operator, |
| 196 | engagement_id=session.engagement_id, |
| 197 | session_id=session.session_id, |
| 198 | started_at=datetime.now(timezone.utc).isoformat(), |
| 199 | ) |
| 200 | |
| 201 | logger.info(f"[LOOP] Starting {scrub(mode)} loop: {scrub(target)} " |
| 202 | f"(operator: {scrub(session.operator)}, " |
| 203 | f"engagement: {scrub(session.engagement_id)})") |
| 204 | |
| 205 | # ── Phase RED-1: Scan + CVE lookup ──────────────────────────────────── |
| 206 | cve_findings = await self._phase_scan(target, scan_profile, report) |
| 207 | if not cve_findings: |
| 208 | report.completed_at = datetime.now(timezone.utc).isoformat() |
| 209 | return report |
| 210 | |
| 211 | if mode == "recon_only": |
| 212 | report.completed_at = datetime.now(timezone.utc).isoformat() |
| 213 | report.audit_log = guardrails.get_audit_log() |
| 214 | self._write_report(report) |
| 215 | return report |
| 216 | |
| 217 | # ── Phase RED-2: Exploit confirmation ───────────────────────────────── |
| 218 | await self._phase_exploit_check(cve_findings, report, max_exploit_concurrent) |
| 219 | |
| 220 | if mode == "confirm_only": |
no test coverage detected