{"slug": "show-hn-redhands-mcp-for-multi-stage-offensive-security-tools", "title": "Show HN: RedHands – MCP for multi-stage offensive security tools", "summary": "Developer Yasin D. C. released RedHands, an open-source Model Context Protocol (MCP) server written in Go with zero external dependencies that chains multi-stage offensive security tools for authorized security assessments. RedHands supports stdio, SSE and WebSocket transports and ships install profiles — minimal (nmap, subfinder, httpx, nuclei), web, network, ad, k8s, uefi, telecom, aegis, sbom, recon and all — plus structured parsing, report generation, a plugin system, rate limiting, caching and audit logging. The release verifies install archives against published SHA256SUMS and is configured as an MCP server in Claude Code, Cursor and VS Code.", "body_md": "**MCP server for authorized security assessments**\n\n  Built in Go with zero external dependencies. Multi-transport (stdio/SSE/WebSocket), tool chaining,\n\n  structured parsing, report generation, plugin system, rate limiting, caching, and audit logging.\n\n```\ngo install github.com/yasindce1998/redhands/cmd/redhands@latest\ncurl -fsSL https://raw.githubusercontent.com/yasindce1998/redhands/main/scripts/install.sh | bash\n```\n\nThis verifies a release archive against its published `SHA256SUMS` and prints MCP\nconfiguration instructions. Older releases without checksums must be built from source.\nTo install security tools, use a reviewed checkout containing the dependency lock:\n\n```\ngit clone https://github.com/yasindce1998/redhands.git && cd redhands\nsudo ./scripts/install-tools.sh --profile web\ngit clone https://github.com/yasindce1998/redhands.git && cd redhands\nmake build\nsudo make install\n\n# Install security tool dependencies (pick a profile)\nsudo make install-tools PROFILE=minimal   # nmap, nuclei, httpx, subfinder\nsudo make install-tools PROFILE=web       # web assessment tools\nsudo make install-tools PROFILE=network   # network/infrastructure tools\nsudo make install-tools PROFILE=ad        # Active Directory tools\nsudo make install-tools PROFILE=k8s       # Kubernetes offensive tools\nsudo make install-tools PROFILE=uefi      # UEFI bootkit simulation\nsudo make install-tools PROFILE=telecom   # StaticZero telecom research (Linux only)\nsudo make install-tools PROFILE=aegis     # Aegis-Shadow eBPF research (Linux only)\nsudo make install-tools PROFILE=sbom      # SBOM + vulnerability scanning (syft, grype)\nsudo make install-tools PROFILE=recon     # deep reconnaissance tools\nsudo make install-tools PROFILE=all       # everything\n\n# Check what's installed\nmake check-deps\ngit clone https://github.com/yasindce1998/redhands.git; cd redhands\ngo build -o bin\\redhands.exe .\\cmd\\redhands\n\n# Install tool dependencies\n.\\scripts\\install-tools.ps1 -Profile web\n.\\scripts\\install-tools.ps1 -Check    # show what's installed/missing\n```\n\nAdd to your MCP client config:\n\n**Claude Code** (`~/.claude/claude_desktop_config.json`), **Cursor** (`.cursor/mcp.json`), **VS Code** (`.vscode/mcp.json`):\n\n```\n{\n  \"mcpServers\": {\n    \"redhands\": {\n      \"command\": \"redhands\"\n    }\n  }\n}\n# stdio (default, for MCP clients)\nredhands\n\n# SSE transport (local CLI or remote use with TLS/auth)\nREDHANDS_TRANSPORT=sse redhands  # loopback only; see secure remote setup below\n\n# WebSocket transport\nREDHANDS_TRANSPORT=ws redhands  # loopback only\n\n# Docker (selected tools pre-installed)\ndocker compose run --rm -i redhands\n```\n\n| Profile | Tools Included | Use Case | \n|---|---|---|\n| `minimal` | nmap, subfinder, httpx, nuclei | Quick recon and scanning | \n| `web` | nmap, recon set (subfinder, amass, dig, waybackurls, gau, arjun), web set (httpx, katana, nikto, whatweb, testssl.sh), ffuf, gobuster, feroxbuster, masscan, rustscan, nuclei, sqlmap | Web application testing | \n| `network` | nmap, masscan, rustscan, tshark, chisel, ligolo | Network/infrastructure | \n| `ad` | nmap, impacket, certipy, crackmapexec, hashcat, john | Active Directory attacks | \n| `k8s` | nmap, kubedagger-client, kubedagger-operator, kubedagger-server | Kubernetes offensive (eBPF) | \n| `uefi` | barzakh-adversary, barzakh-scanner, barzakh-server | UEFI bootkit adversary simulation | \n| `telecom` | staticzero-defense, staticzero-offense, modem-firmware, sdr-bridge | Telecom security research (eBPF, Linux only) | \n| `aegis` | aegis-shadow-defense, aegis-shadow-offense, aegis-c2 | Linux eBPF security research (Aegis-Shadow) | \n| `sbom` | syft, grype | SBOM generation and vulnerability scanning | \n| `recon` | recon set (subfinder, amass, dig, waybackurls, gau, arjun) + web set (httpx, katana, nikto, whatweb, testssl.sh) | Deep reconnaissance | \n| `all` | Everything | Full offensive toolkit | \n\nProfiles describe desired dependencies, not a guarantee every dependency is available\non every OS. RustScan, testssl.sh, and CrackMapExec currently need manual installation;\nKubeDagger client is Linux-only. Installers report missing tools rather than downloading\nunverified replacements. See [dependency maintenance](https://github.com/yasindce1998/RedHands/blob/main/docs/dependencies.md).\n\n`make build` produces `redhands`, `redhands-cli`, and `redhands-creds` in `bin/`.\nThe CLI uses the same authenticated SSE transport as MCP clients:\n\n```\n# Terminal 1\nREDHANDS_TRANSPORT=sse ./bin/redhands\n# Terminal 2\n./bin/redhands-cli tools\n./bin/redhands-cli targets add 192.0.2.1 lab-host\n./bin/redhands-cli status\n```\n\nFor HTTPS, set `REDHANDS_URL=https://your-server:8443`, `REDHANDS_API_KEY`, and\n`REDHANDS_CLIENT_CA=/path/to/ca.pem`. For mTLS, also set `REDHANDS_CLIENT_CERT`\nand `REDHANDS_CLIENT_KEY`. The CLI rejects untrusted certificates, redirects, and\nnon-loopback plain HTTP. `REDHANDS_CLIENT_TIMEOUT` sets its total deadline (default `6m`).\nTool failures return a nonzero exit status; calls are never retried automatically.\n\n- Go 1.26.11+ (for building from source; if using Go 1.27, use 1.27.4+)\n- Security tools on PATH (installed via scripts above, Docker, or manually)\n\n294 tools are registered across 36 toolsets. A default startup serves 287 of\nthem: the two credstore tools additionally require `REDHANDS_CREDSTORE_KEY`,\nand the five GoPhish phishing tools additionally require `REDHANDS_GOPHISH_*`\nenvironment variables.\n\n| Tool | Description | \n|---|---|\n| `nmap_port_scan` | TCP/UDP port scanning (SYN, connect, UDP) | \n| `nmap_service_detect` | Service and version detection (-sV) | \n| `nmap_os_detect` | OS fingerprinting (-O) | \n| `nmap_vuln_scan` | NSE vulnerability scripts | \n\n| Tool | Description | \n|---|---|\n| `subfinder_enum` | Subdomain enumeration from passive sources | \n| `amass_enum` | Network mapping and ASN discovery (OWASP Amass) | \n| `dns_lookup` | DNS record queries via dig (A, AAAA, MX, NS, TXT, etc.) | \n| `waybackurls` | Fetch archived URLs from the Wayback Machine | \n| `gau_urls` | Fetch URLs from AlienVault OTX, Wayback, CommonCrawl, URLScan | \n| `arjun_discover` | HTTP parameter discovery (hidden GET/POST params) | \n\n| Tool | Description | \n|---|---|\n| `httpx_probe` | HTTP service probing with tech detection | \n| `katana_crawl` | Next-gen web crawler (JS crawling, headless) | \n| `nikto_scan` | Web server vulnerability scanner | \n| `whatweb_fingerprint` | Web technology fingerprinting | \n| `testssl_scan` | TLS/SSL encryption testing | \n\n| Tool | Description | \n|---|---|\n| `ffuf_fuzz` | Web fuzzing (dirs, params, vhosts) | \n| `gobuster_dir` | Directory/file brute-forcing | \n| `feroxbuster_scan` | Recursive content discovery (forced browsing) | \n\n| Tool | Description | \n|---|---|\n| `masscan_scan` | Internet-scale port scanning (10M pps) | \n| `rustscan_scan` | Modern fast port scanner (all 65535 ports in seconds) | \n\n| Tool | Description | \n|---|---|\n| `sqlmap_scan` | Automatic SQL injection detection and exploitation | \n\n| Tool | Description | \n|---|---|\n| `nuclei_scan` | Template-based vulnerability scanning | \n\nKerberos interaction toolkit — for Windows engagement hosts running RedHands\nwith an operator-compiled `Rubeus.exe` allowlisted as `rubeus` (GhostPack\nships no compiled releases by design; Linux execution is not possible — the\ntool P/Invokes Windows LSA APIs).\n\n| Tool | Description | \n|---|---|\n| `rubeus_kerberoast` |  | \n| `rubeus_asktgt` |  | \n| `rubeus_asreproast` |  | \n| `rubeus_harvest` |  | \n| `rubeus_dump` |  | \n| `rubeus_describe` | Decode and describe a base64 ticket | \n\n| Tool | Description | \n|---|---|\n| `impacket_secretsdump` | Dump SAM/LSA/NTDS.dit secrets | \n| `impacket_psexec` | PsExec-style remote execution | \n| `impacket_wmiexec` | WMI-based remote execution | \n| `impacket_smbclient` | SMB client operations | \n| `impacket_dcomexec` | DCOM remote execution | \n| `impacket_get_tgt` | Request Kerberos TGT | \n| `impacket_get_st` | Request service ticket (Kerberoast/delegation) | \n| `impacket_ntlmrelay` | NTLM relay attack | \n\n| Tool | Description | \n|---|---|\n| `sliver_generate` | Generate implant (mTLS, HTTP/S, DNS, WireGuard) | \n| `sliver_listeners` | Manage C2 listeners | \n| `sliver_sessions` | List/interact with sessions | \n| `sliver_beacons` | List/interact with beacons | \n| `sliver_execute` | Execute commands on implant | \n| `sliver_upload` | Upload files to implant | \n| `sliver_download` | Download files from implant | \n| `sliver_pivot` | Pivot setup and management | \n| `sliver_portfwd` | Port forwarding through implant | \n\n| Tool | Description | \n|---|---|\n| `chisel_server` | Start Chisel reverse tunnel endpoint | \n| `chisel_client` | Chisel client (forward/reverse/SOCKS) | \n| `ligolo_start` | Start Ligolo-ng proxy server | \n| `ligolo_route` | Add routes through Ligolo tunnel | \n| `ligolo_listener` | Manage Ligolo listeners on agent | \n\n| Tool | Description | \n|---|---|\n| `hashcat_crack` | Crack hashes (dictionary, rules, masks) | \n| `hashcat_benchmark` | Benchmark hash types | \n| `hashcat_show` | Show cracked from potfile | \n| `john_crack` | Crack passwords with John the Ripper | \n| `john_show` | Show cracked passwords | \n| `john_formats` | List supported hash formats (graceful degradation on core john builds) | \n| `hydra_attack` |  | \n\n| Tool | Description | \n|---|---|\n| `cme_smb` | SMB enumeration/exec/pass-the-hash | \n| `cme_winrm` | WinRM execution | \n| `cme_ldap` | LDAP enumeration | \n| `cme_mssql` | MSSQL queries/execution | \n| `cme_ssh` | SSH credential spray/exec | \n\n| Tool | Description | \n|---|---|\n| `certipy_find` | Find AD CS templates and CAs | \n| `certipy_req` | Request certificates | \n| `certipy_auth` | Authenticate via PKINIT | \n| `certipy_shadow` | Shadow credentials attack | \n| `certipy_forge` | Golden certificate forgery | \n| `certipy_relay` | NTLM relay to AD CS | \n\n| Tool | Description | \n|---|---|\n| `tshark_capture` | Capture packets (interface, filter, duration) | \n| `tshark_read` | Read pcap with display filter | \n| `tshark_stats` | Protocol statistics | \n| `tshark_extract` | Extract fields from captures | \n| `tshark_follow` | Follow TCP/UDP/HTTP streams | \n\n| Tool | Description | \n|---|---|\n| 69 tools | eBPF-powered Kubernetes offensive toolkit, including managed C2-server lifecycle ( `kubedagger_server_*` ) — see`tools/kubedagger/` | \n\n| Tool | Description | \n|---|---|\n| `barzakh_list` | List available UEFI bootkit payload types (134 payloads) | \n| `barzakh_generate` | Generate a UEFI bootkit payload for adversary simulation (x86-64, aarch64, riscv64, power64, armv7) | \n| `barzakh_corpus` | Generate full test corpus of malicious/clean firmware pairs | \n| `barzakh_scan` | Scan firmware images with 138 specialized bootkit detectors (exit 1 = detection, reported as a finding) | \n| `barzakh_validate` | Validate detector coverage (TPR/FPR) against a corpus | \n| `barzakh_scenario` | List/show/run multi-stage ATT&CK-mapped attack chains (6 bundled) | \n| `barzakh_robustness` | Mutation-based detector evasion benchmark | \n| `barzakh_detectors` | List/describe the 138 detectors | \n| `barzakh_baseline` | Create/show firmware baselines | \n| `barzakh_intel` | Query IOC feeds, MISP, ATT&CK, STIX intel | \n| `barzakh_server_start` | Start the Barzakh REST scanner server as a managed background daemon (X-API-Key auth, SQLite history) | \n| `barzakh_server_stop` | Stop a managed Barzakh server | \n| `barzakh_server_status` | Status of managed Barzakh servers | \n| `barzakh_inject` |  | \n| `barzakh_esp_build` |  | \n| `barzakh_qemu` | Boot firmware in an emulated QEMU/OVMF environment (run config / memory dump) | \n| `barzakh_range` | Boot QEMU/OVMF/swTPM cyber-range suites with assert-on-detection (exit 1 = failed assertions, surfaced as a result) | \n| `barzakh_fuzz` | Protocol-aware firmware fuzzing (dhcpv6/bmp/capsule/httpboot/tcg/hii) | \n| `barzakh_history` | Query the SQLite scan history (list/show/diff/trends) | \n| `barzakh_kb` | Manage the firmware knowledge base (add/list/search/export/import) | \n| `barzakh_ml` | Train/evaluate the ML anomaly models | \n| `barzakh_manifest_validate` | Validate detectors against a labeled corpus manifest with train/validation/test splits | \n| `barzakh_info` | Scanner build/version, detector, architecture, and format metadata | \n| `barzakh_report` | Generate report files (json/html/markdown/sarif/csv/ecs/cef/leef) from scan results | \n\nWraps StaticZero, an eBPF telecom security research framework (2G–5G, satellite, baseband firmware). Authorized lab use only.\n\nWarning\n\n`telecom_offense_start` launches the **telecom interception research loader**\n(features F89–F172: IMSI targeting, GTP/SS7/Diameter interception, RF and\nsatellite domains). Intercepting telecommunications is **illegal without\nauthorization in most jurisdictions — including in labs in some**. Use only\nin an isolated lab environment with equipment you own, and only where you\nhold explicit permission. The tool is approval-gated and requires root.\n\n| Tool | Description | \n|---|---|\n| `telecom_doctor` | Read-only StaticZero defense engine preflight (platform/kernel/BPF checks) | \n| `telecom_firmware_analyze` | Static vulnerability analysis of modem/baseband firmware images | \n| `telecom_firmware_extract` | Extract firmware components with manifest | \n| `telecom_firmware_diff` | Diff two firmware images | \n| `telecom_firmware_nv_dump` | Extract NV items (carrier/band/security config) | \n| `telecom_firmware_patch` |  | \n| `telecom_firmware_monitor` | Monitor a modem device protocol stream (diag/at/qmi/mbim; bounded by the execution timeout) | \n| `telecom_sdr_scan` | Receive-only LTE cell scan via SDR | \n| `telecom_sdr_capture` | Receive-only IQ capture via SDR | \n| `telecom_sdr_inject` |  | \n| `telecom_sdr_relay` |  | \n| `telecom_sdr_selftest` |  | \n| `telecom_threats` | Correlated threats from a running defense engine | \n| `telecom_alerts` | Raw alerts from a running defense engine | \n| `telecom_stats` | Engine runtime statistics | \n| `telecom_defense_start` | Start the StaticZero defense engine as a managed background daemon (JSON alerts stream to a file) | \n| `telecom_defense_stop` | Stop a managed defense engine daemon | \n| `telecom_defense_status` | Status of managed defense engine daemons | \n| `telecom_offense_start` |  | \n| `telecom_offense_stop` | Stop a managed offense loader daemon | \n| `telecom_offense_status` | Status of managed offense loader daemons | \n| `telecom_correlator_start` | Start the protocol correlator as a managed daemon (JSON-lines event ingest on loopback) | \n| `telecom_correlator_stop` | Stop a managed correlator daemon | \n| `telecom_correlator_status` | Status of managed correlator daemons | \n\nStaticZero binaries ship as checksum-verified release assets (v0.5.0, Linux\nonly, eBPF embedded) and install via the `telecom` profile:\n`sudo make install-tools PROFILE=telecom`.\n\nWraps Aegis-Shadow, a Linux eBPF security research platform (educational, VM-only).\nThe analysis tools never execute binaries; `aegis_offense_plan` renders the manual\nlab command with risk notes without executing it. The defense engine and the\noffense rootkit loader can each be started as a managed background daemon\n(approval-gated).\n\n[!DANGER]\n`aegis_offense_start` launches the **eBPF rootkit loader** — process hiding,\ncredential harvesting, log tampering, anti-forensics, and covert C2, running\nat kernel level with root. Two capabilities are **destructive by design**:\n`deadman_switch` (scorched-earth wipe triggered on tamper or timeout — the\nVM may become unrecoverable) and `wipe_bytecode` (erases the loaded eBPF\nbytecode from memory, defeating live forensics). Both are opt-in, emit loud\nwarnings in every result, and expect a **disposable, snapshotted lab VM**.\nData loss from these flags is expected behavior, not a bug.\n\n| Tool | Description | \n|---|---|\n| `aegis_alerts_parse` | Parse/filter NDJSON alert files from the defense engine | \n| `aegis_alerts_tail` | Tail the last N alerts from an alert file | \n| `aegis_modules_list` | Reference catalog of defense modules and offense features | \n| `aegis_defense_config_read` | Read/validate a defense engine hot-reload config | \n| `aegis_defense_config_write` | Write a defense engine config (threshold, window) | \n| `aegis_offense_plan` | Dry-run planner: validate offense feature flags and render the exact manual command line with risk notes | \n| `aegis_defense_start` | Start the Aegis-Shadow defense engine as a managed background daemon (NDJSON alerts stream to a file; requires root) | \n| `aegis_defense_stop` | Stop a managed defense engine daemon | \n| `aegis_defense_status` | Status of managed defense engine daemons | \n| `aegis_offense_start` | ☠️ Launch the Aegis-Shadow eBPF rootkit loader as a managed daemon (destructive `deadman_switch` /`wipe_bytecode` are opt-in with warnings; disposable VM only) | \n| `aegis_offense_stop` | Stop a managed offense loader daemon | \n| `aegis_offense_status` | Status of managed offense loader daemons | \n| `aegis_c2_send` | ☠️ Send a command to a running rootkit over its encrypted C2 channel (hide/unhide pid, obfuscate file, exfil, kill-switch; fire-and-forget; requires the `aegis-c2` CLI from Aegis-Shadow ≥ v0.2.0) | \n\nExploitDB search and CVE enrichment — the connective tissue from scanner findings\nto Metasploit: nuclei finding → CVE → public exploits → `msf_module_run`.\nRequires the `searchsploit` binary + on-disk database (distro `exploitdb`\npackage — manual install, not checksum-pinnable).\n\n| Tool | Description | \n|---|---|\n| `searchsploit_search` | Search ExploitDB by keyword (JSON results) | \n| `searchsploit_cve` | Map a CVE ID to public exploits (EDB-IDs, paths) | \n| `searchsploit_edb` | Look up an EDB-ID (exploit file path + copy hint) | \n| `cve_enrich` | Extract CVEs from scanner output text, map to exploits, and suggest Metasploit modules (EDB `.rb` paths →`msf_module_run` candidates) | \n\nGeneric embedded firmware analysis with binwalk v2 — completes the firmware\nstory alongside UEFI (Barzakh) and baseband (modem-firmware). Requires\n`binwalk` (v2, Python — distro/pip manual install; do **not** use the v3 Rust\nrewrite, different CLI).\n\n| Tool | Description | \n|---|---|\n| `firmware_scan` | Signature scan with a structured JSON summary (signatures → record rules) | \n| `firmware_extract` |  | \n| `firmware_entropy` | Entropy analysis (encrypted/compressed region detection) | \n\nSBOM generation and vulnerability scanning with Anchore syft + grype —\nchecksum-pinned releases, installed by the `sbom` profile.\n\n| Tool | Description | \n|---|---|\n| `sbom_generate` | Generate an SBOM (syft-json, CycloneDX, SPDX) from an image, directory, or file | \n| `vuln_scan_image` | Vulnerability-scan an image or SBOM with grype (exit-2-on-findings surfaced as a result with a severity summary) | \n| `vuln_scan_sbom` | Scan an existing SBOM file with grype | \n\nWraps Metasploit Framework (msfvenom + msfconsole). Console tools generate\nvalidated `.rc` resource files from structured parameters — never\n`msfconsole -x` — so console-command injection is structurally impossible.\nMetasploit is not checksum-pinnable (no stable release binaries); install it\nmanually (`apt install metasploit-framework` on Kali/Parrot) and the allowlist\ndiscovers `msfconsole`/` msfvenom` on PATH. msfconsole startup takes 10–60s;\nruns are bounded by `REDHANDS_TIMEOUT`.\n\n| Tool | Description | \n|---|---|\n| `msf_payload_generate` |  | \n| `msf_payload_list` | List payloads, encoders, formats, platforms, or architectures | \n| `msf_module_info` | Show module documentation (exploit/auxiliary/post/payload/encoder/nop) | \n| `msf_module_run` |  | \n| `msf_resource_run` | `.rc` resource file (arbitrary console commands; approval-gated) | \n\n| Tool | Description | \n|---|---|\n| `redhands_health` | Server health check and binary dependency status | \n\nRedHands supports four transport modes:\n\n| Transport | Use Case | Config | \n|---|---|---|\n| **stdio** (default) | Local use with Claude Code, Cursor, VS Code | `REDHANDS_TRANSPORT=stdio` | \n| **HTTP** (Streamable) | Modern MCP `2026-07-28` clients: stateless single-endpoint JSON-RPC | `REDHANDS_TRANSPORT=http` (`REDHANDS_HTTP_ADDR` , default`127.0.0.1:8082` ;`REDHANDS_HTTP_PATH` , default`/mcp` ) | \n| **SSE** | Legacy HTTP clients (deprecated-era transport) | `REDHANDS_TRANSPORT=sse` (loopback by default) | \n| **WebSocket** | Real-time bidirectional (custom transport) | `REDHANDS_TRANSPORT=ws` (loopback by default) | \n\nThe HTTP transport implements the modern spec: POST-only `/mcp` endpoint,\nrequired `MCP-Protocol-Version`/` Mcp-Method` (and `Mcp-Name` for `tools/call`)\nheaders validated against the body, `405` for GET/DELETE, `404`+`-32601` for\nunknown methods, `202` for notifications, and per-request `_meta` protocol\nversion validation (`-32022` with the supported list). Legacy clients that\nopen with `initialize` are served by the dual-era handshake on every\ntransport. Non-loopback listeners require authentication **and TLS**.\n\n| Mode | Config | Description | \n|---|---|---|\n| **none** (default) | `REDHANDS_AUTH=none` | No authentication | \n| **API key** | `REDHANDS_AUTH=apikey` +`REDHANDS_API_KEY=<secret>` | `X-API-Key` header validation | \n| **mTLS** | `REDHANDS_AUTH=mtls` + cert/key/CA env vars | Client certificate verification | \n\nChain tools sequentially with variable substitution:\n\n```\n{\n  \"method\": \"workflow/run\",\n  \"params\": {\n    \"steps\": [\n      {\"tool\": \"nmap_port_scan\", \"params\": {\"target\": \"10.0.0.1\"}},\n      {\"tool\": \"nuclei_scan\", \"params\": {\"target\": \"http://10.0.0.1\"}}\n    ]\n  }\n}\n```\n\nVariables: `$prev.text` (previous step output), `$step[N].text` (Nth step output).\nSubstitutions contain the full formatted text, not extracted targets; only pass them\nto parameters that accept that format. All steps honor dry-run, rate limits and scope.\n\nCampaigns extend workflows with **conditions**, **parallel fan-out**, **failure\nrecovery (`goto:`)**, **checkpointing**, **resume**, **cancellation**, and\n**playbook templates**. Every step executes through the same middleware chain\nas a direct `tools/call` (audit, auth, rate limits, scope, dry-run, approval,\nconcurrency limits).\n\n```\n{\n  \"method\": \"campaign/run\",\n  \"params\": {\n    \"id\": \"web-engage-1\",\n    \"name\": \"Web assessment\",\n    \"steps\": [\n      {\"id\": \"portscan\", \"tool\": \"nmap_port_scan\", \"params\": {\"target\": \"10.0.0.1\"}},\n      {\"id\": \"webscan\", \"tool\": \"nuclei_scan\", \"params\": {\"target\": \"http://10.0.0.1\"}},\n      {\"parallel\": [\n        {\"id\": \"nikto\", \"tool\": \"nikto_scan\", \"params\": {\"target\": \"http://10.0.0.1\"}},\n        {\"id\": \"tls\", \"tool\": \"testssl_scan\", \"params\": {\"target\": \"10.0.0.1:443\"}}\n      ], \"on_fail\": \"continue\"},\n      {\"id\": \"report\", \"tool\": \"loot_add\", \"params\": {\"description\": \"done\"}}\n    ]\n  }\n}\n```\n\n| Field | Description | \n|---|---|\n| `id` | Unique step identifier used by conditions and `${id...}` references | \n| `tool` /`params` | Tool name and JSON params (exactly like `tools/call` ) | \n| `parallel` | Array of sub-steps executed concurrently (≤16, no nesting) | \n| `condition` | Skip the step unless the condition holds | \n| `on_fail` | `stop` (default),`continue` , or`goto:<step_id>` recovery jump | \n\n```\n{\"condition\": {\"step\": \"portscan\", \"op\": \"json_gt\", \"path\": \"hosts.0.ports.0\", \"value\": \"0\"}}\n```\n\nOperators: `success`, `failure`, `contains`, `not_contains`, `equals`, `not_equals`,\nplus JSON-aware `json_exists`, `json_not_exists`, `json_equals`, `json_not_equals`,\n`json_contains`, `json_gt`, `json_lt` evaluated against a previous step's structured\noutput (`step` may be a step ID, `\"$prev\"`, or a zero-based index).\n\nPlaceholders can extract **fields** from prior results, not just whole text.\nTools emitting JSON (raw or in a markdown ``` json fence) are queryable by\ndot-path with numeric array indices:\n\n```\n$prev.text                     full text of the previous step\n$prev.json.findings.0.severity field extraction\n$step[2].json.hosts            whole array from step 2 (native type preserved)\n${portscan.json.hosts.0.ip}    reference by step ID\n```\n\nA placeholder that makes up an entire string value is substituted natively (numbers stay numbers, arrays stay arrays); placeholders embedded in a larger string are substituted as text. Unresolvable placeholders pass through untouched.\n\n`record` rules map JSON arrays in a step's output to target database entries,\nso campaigns build the host/service/credential/finding picture automatically:\n\n```\n{\n  \"id\": \"discover\",\n  \"tool\": \"kubedagger_k8s_discover\",\n  \"params\": {\"namespace\": \"default\"},\n  \"mitre\": [\"T1613\"],\n  \"record\": [\n    {\"type\": \"host\", \"path\": \"nodes\", \"fields\": {\"ip\": \"ip\", \"hostname\": \"name\", \"os\": \"os\"}},\n    {\"type\": \"host\", \"path\": \"pods\", \"fields\": {\"ip\": \"pod_ip\", \"hostname\": \"name\"}}\n  ]\n}\n```\n\nEntry types: `host`, `service`, `credential`, `finding`. Recorded entries are\ntagged `campaign:<workflow_id>` and become queryable via the `targetdb_*` tools\nand the attack graph. Recording failures warn in the step result without\nfailing the campaign.\n\nSteps accept `mitre: [\"T1613\", \"T1552.001\"]` technique tags. Campaign results\naggregate the unique techniques of executed steps as `mitre_techniques`, which\ncan be passed to `kubedagger_detection` (`action: \"generate\"`, `techniques` as\na comma-separated list) to produce matching Falco/Sigma/audit detection rules.\nThe shipped `k8s-recon-chain` playbook demonstrates recording and tagging end\nto end, including a final detection-rule generation step.\n\n| Method | Params | Description | \n|---|---|---|\n| `campaign/run` | steps or `template` +`vars` | Execute a campaign synchronously; checkpoints every step | \n| `campaign/start` | same as `campaign/run` | **Async** : with the Tasks extension declared, returns a`CreateTaskResult` (taskId, ttlMs, pollIntervalMs) and runs detached from the request; without it, identical to`campaign/run` . Idempotent: re-starting a running ID returns the live task | \n| `campaign/status` | `workflow_id` | Load persisted state | \n| `campaign/list` | — | List all saved campaigns | \n| `campaign/resume` | `workflow_id` | Continue a paused/cancelled campaign | \n| `campaign/cancel` | `workflow_id` | Cancel a running campaign (works cross-replica: the engine re-reads persisted state at each checkpoint) | \n| `campaign/templates` | — | List playbook templates | \n| `campaign/template/get` | `name` | Fetch one template | \n| `campaign/template/save` | template JSON | Validate and persist a playbook | \n| `tasks/get` | `taskId` | Poll a task: `working` /`input_required` /`completed` /`failed` /`cancelled` ; terminal states carry the result or error | \n| `tasks/cancel` | `taskId` | Cooperatively cancel a task (acks immediately) | \n| `tasks/update` | `taskId` ,`inputResponses` | Submit approval responses for a paused task ( `approval` for a sequential gate,`approval-<sub_step_id>` per gated sub-step inside a parallel group; unknown keys are acked and ignored) | \n\nCampaigns interrupted mid-step (cancellation or timeout) checkpoint as\n`paused` and re-run the interrupted step on resume. Every campaign is\nsingle-writer (an advisory flock per workflow ID): a duplicate start of a\nrunning campaign returns its live task instead of corrupting the checkpoint.\n\nTools that require operator approval (high-impact tools not listed in\n`REDHANDS_APPROVED_TOOLS`) no longer need to block. When the request declares\nthe Tasks extension, an approval-gated `tools/call` answers with\n`resultType: \"input_required\"` and an `elicitation/create` approval request;\nthe client re-issues the same call with `inputResponses: {\"approval\": {\"approved\": true}}` and the single call executes (audited as an approval\nbypass). Inside a task-tracked campaign, an approval-gated step pauses the\ntask (`input_required` via `tasks/get`), the response arrives through\n`tasks/update`, and `campaign/resume` re-runs the step. Requests without the\ncapability fail closed with the classic message. Responses never ride in\ntool arguments — only in the dedicated `inputResponses` field.\n\nParallel groups use the same machinery per sub-step instead of failing the\ngated sub-step outright: when one or more sub-steps of a group trip approval\ngates, the campaign pauses ONCE and `tasks/get` shows one inputRequest per\ngated sub-step, keyed `approval-<sub_step_id>`. Answer each individually\n(`tasks/update` with `inputResponses: {\"approval-<sub_step_id>\": {\"approved\": true}}`; unknown or stale keys are acked and ignored). On\n`campaign/resume` the group replays partially: sub-steps that already\ncompleted are not re-executed, sub-steps that failed for other reasons keep\ntheir recorded failure, approved sub-steps re-run once with their own\none-call bypass, denied sub-steps fail with `approval denied` and flow\nthrough the group's `on_fail` (stop/continue/goto), and unanswered gates\nre-trip with fresh request ids. A `goto` that re-enters a group is a fresh\nexecution — the per-run completion set resets and every sub-step re-runs.\nCapability-less requests keep the classic fail-closed behavior for group\nsub-steps too.\n\nPlaybooks are reusable, versioned campaign templates stored as JSON in\n`REDHANDS_WORKFLOW_TEMPLATES_DIR` (default `./playbooks/`). Shipped examples:\n`recon-to-vuln`, `web-assessment`, `k8s-recon-chain`, `ad-kerberoast-chain`,\n`firmware-bootkit-assessment`, `telecom-defense-monitoring`,\n`firmware-purple-team`. Point-and-shoot a playbook:\n\n```\n{\n  \"method\": \"campaign/run\",\n  \"params\": {\n    \"template\": \"recon-to-vuln\",\n    \"vars\": {\"domain\": \"target.example\", \"severity\": \"critical,high\"}\n  }\n}\n```\n\nCampaigns can bind to an engagement with the `engagement` parameter. The named\nengagement must exist and be the **active** engagement — the campaign fails\nfast instead of silently running against the wrong scope, and every step's\ntargets are checked against that engagement's scope by the middleware:\n\n```\n{\n  \"method\": \"campaign/run\",\n  \"params\": {\n    \"engagement\": \"lab-1\",\n    \"template\": \"web-assessment\",\n    \"vars\": {\"target\": \"https://target.example\"}\n  }\n}\n```\n\nBindings are persisted with the campaign state and re-validated on resume, so switching engagements between runs rejects a stale binding.\n\nLimits: 128 steps per campaign, 16 steps per parallel group, 64 `goto` recovery\njumps, 16 MiB cumulative output — mirroring workflow hard caps.\n\nBuilt-in parsers for common tool output formats:\n\n- **Nmap XML** — parses`-oX` output into structured hosts/ports/services\n- **Nuclei JSON** — parses JSONL findings into severity-grouped results\n- **Masscan JSON** — parses`-oJ` output into host/port pairs\n\nGenerate reports from workflow results:\n\n```\n{\n  \"method\": \"report/generate\",\n  \"params\": {\n    \"format\": \"markdown\",\n    \"title\": \"Assessment report\",\n    \"sections\": [{\"title\": \"Summary\", \"tool\": \"nmap_port_scan\", \"content\": \"Reviewed scan results\"}]\n  }\n}\n```\n\nFormats: `markdown` (.md) and `html` (self-contained with inline CSS).\n\nDefine custom tools via JSON without writing Go:\n\n```\n{\n  \"name\": \"custom_quick_scan\",\n  \"description\": \"Quick nmap top-100 scan\",\n  \"binary\": \"nmap\",\n  \"args_template\": [\"-sS\", \"--top-ports\", \"100\", \"{{.target}}\"],\n  \"input_schema\": {\n    \"type\": \"object\",\n    \"properties\": {\n      \"target\": {\"type\": \"string\", \"description\": \"Target IP or hostname\"}\n    },\n    \"required\": [\"target\"]\n  }\n}\n```\n\nDrop JSON files in `REDHANDS_PLUGINS_DIR` (default `./plugins/`) and they appear in `tools/list` automatically.\n\nAll settings via environment variables:\n\n| Variable | Default | Description | \n|---|---|---|\n| `REDHANDS_TOOLSETS` | (all) | Comma-separated toolsets to register (approval still applies) | \n| `REDHANDS_TIMEOUT` | `5m` | Execution timeout per tool call | \n| `REDHANDS_MAX_OUTPUT` | `10485760` | Max output bytes per execution (10MB) | \n| `REDHANDS_RATE_LIMIT` | `10` | Token bucket refill rate (requests/sec) | \n| `REDHANDS_RATE_BURST` | `20` | Token bucket burst capacity | \n| `REDHANDS_CACHE_TTL` | `5m` | Result cache TTL | \n| `REDHANDS_CACHE_SIZE` | `100` | Max pure-function results (oldest-expiry eviction) | \n| `REDHANDS_AUDIT_FILE` | `audit.jsonl` | Audit log file path | \n| `REDHANDS_TRANSPORT` | `stdio` | Transport mode: `stdio` ,`sse` , or`ws` | \n| `REDHANDS_SSE_ADDR` | `127.0.0.1:8080` | SSE HTTP listen address | \n| `REDHANDS_WS_ADDR` | `127.0.0.1:8081` | WebSocket listen address | \n| `REDHANDS_AUTH` | `none` | Auth mode: `none` ,`apikey` , or`mtls` | \n| `REDHANDS_API_KEY` | — | API key (required when auth=apikey) | \n| `REDHANDS_TLS_CERT` | — | TLS certificate path | \n| `REDHANDS_TLS_KEY` | — | TLS private key path | \n| `REDHANDS_TLS_CA` | — | CA certificate for mTLS client verification | \n| `REDHANDS_PLUGINS_DIR` | `./plugins` | Directory for JSON plugin definitions | \n| `REDHANDS_PLUGIN_POLL_INTERVAL` | `5s` | Plugin directory polling interval | \n| `REDHANDS_CREDSTORE_KEY` | — | Strong encryption key required for credential persistence | \n| `REDHANDS_CREDSTORE_FILE` | `credstore.enc` | Encrypted credential store file | \n| `REDHANDS_TARGETDB_FILE` | `targetdb.json` | Target database file | \n| `REDHANDS_TARGETDB_AUTOSAVE` | `true` | Persist target database changes immediately | \n| `REDHANDS_ENGAGEMENT_DIR` | `engagements` | Engagement metadata directory | \n| `REDHANDS_DRY_RUN` | `false` | Preview executions without running tools | \n| `REDHANDS_OPSEC_PROFILE` | — | OPSEC profile name (parsed; proxy routing not yet wired) | \n| `REDHANDS_IOC_FILE` | — | Indicator-of-compromise list file (parsed; matching not yet wired) | \n| `REDHANDS_TCP_ADDR` | — | TCP transport listen address; mTLS only (API-key headers are not supported over TCP) | \n| `REDHANDS_DASHBOARD_ADDR` | — | Dashboard HTTP listen address (parsed; dashboard not yet wired) | \n| `REDHANDS_GOPHISH_URL` | — | GoPhish API base URL (enables the phishing toolset) | \n| `REDHANDS_GOPHISH_API_KEY` | — | GoPhish API key | \n| `REDHANDS_MAX_CONCURRENT` | `4` | Maximum active tool calls across clients and workflows | \n| `REDHANDS_MAX_QUEUED` | `16` | Maximum queued calls; further requests fail without executing | \n| `REDHANDS_APPROVED_TOOLS` | — | Exact comma-separated names approved by the operator for high-impact/unclassified tools | \n| `REDHANDS_WORKFLOW_TIMEOUT` | `30m` | Total deadline for a sequential workflow or campaign | \n| `REDHANDS_WORKFLOW_STATE_DIR` | `workflow_state` | Campaign checkpoint directory | \n| `REDHANDS_WORKFLOW_TEMPLATES_DIR` | `playbooks` | Playbook template directory | \n| `REDHANDS_WORKFLOW_MAX_PARALLEL` | `4` | Max concurrent steps inside a campaign parallel group (≤32) | \n| `REDHANDS_EVIDENCE_DIR` | `evidence` | Artifact directory with persistent metadata index | \n| `REDHANDS_LOOT_DIR` | `loot` | Directory containing the atomic `loot.json` store | \n\nNon-loopback listeners require authentication **and TLS**. API keys are accepted only\nin the `X-API-Key` header. stdio uses local OS access controls, not API-key authentication.\nCaching is limited to pure MITRE/risk-score lookups, never scans or state-changing tools.\nHigh-impact, mixed-mode, and unclassified tools (including plugins) require explicit\noperator approval via `REDHANDS_APPROVED_TOOLS`. Dry-run previews do not require this\napproval and never execute tools. `tools/list` publishes policy metadata and MCP safety hints.\nSee [security and deployment notes](https://github.com/yasindce1998/RedHands/blob/main/docs/security-hardening.md) for HTTPS/mTLS setup,\nscope limitations, credential migration, and remaining release work.\n\nEvidence metadata persists in `REDHANDS_EVIDENCE_DIR/index.json`. Artifacts use random\nIDs rather than host/tool text in filenames, and are checked against recorded size and\nSHA-256 values when the store opens. Old files with no index remain untouched and are\nnot automatically listed. Corrupt metadata or missing/changed indexed artifacts stop\nstartup instead of silently losing their history.\n\nLoot writes are atomic, and malformed `loot.json` files fail startup. Both stores are\nsingle-process stores: do not point multiple servers at the same directories. Artifacts\nand loot are private files, **not encrypted storage**; protect their directories and backups.\n\n`evidence_screenshot` requires operator approval and `cutycapt` installed on PATH at\nstartup. It uses the shared executor, private staging, HTTP(S)-only URLs, and PNG\nvalidation. CutyCapt may require a display/headless environment; it is not bundled in\nthe current Docker image. Browser redirects and subresources still need network isolation.\n\nSee [evidence and loot recovery](https://github.com/yasindce1998/RedHands/blob/main/docs/evidence-storage.md) before moving stores,\nrepairing corrupt files, or handling legacy/unindexed artifacts.\n\nEnable only specific toolsets:\n\n```\n# AD/internal assessment\nexport REDHANDS_TOOLSETS=nmap,impacket,crackmapexec,certipy,sliver,crack\n\n# External web assessment\nexport REDHANDS_TOOLSETS=nmap,recon,web,fuzz,scan,vuln\n\n# Network analysis\nexport REDHANDS_TOOLSETS=nmap,scan,tshark,tunnel\n\n# Firmware + telecom research\nexport REDHANDS_TOOLSETS=barzakh,telecom,aegis\n\n# All tools (default when unset)\nexport REDHANDS_TOOLSETS=\n```\n\n- **Binary allowlist** — only known security tools can be executed\n- **Argument validation** — shell metacharacter rejection for external-tool arguments\n- **Target validation and scope** — explicit network targets checked against active engagement scope; not a complete network sandbox\n- **Destructive-capability posture** — tools that can destroy data or destroy\na machine (`aegis_offense_start` with`deadman_switch` or`wipe_bytecode` )\nare opt-in, approval-gated, and emit loud warnings in every result; read the\nwarnings in the[Aegis-Shadow](#aegis-shadow-toolset-aegis) and[Telecom](#telecom-toolset-telecom) sections before using the offense tools\n- **Output size cap** — 10MB per execution\n- **Execution timeout** — configurable per tool call\n- **Rate limiting** — token bucket prevents abuse\n- **Authentication** — API key or mTLS for remote transports\n- **Audit logging** — direct calls and workflow steps logged as JSONL; logging failures reported to stderr\n\n```\nmake build          # Build binary to bin/\nmake test           # Run tests with race detector\nmake lint           # Run golangci-lint\nmake docker         # Build Docker image\nmake install        # Install binary to /usr/local/bin\nmake install-tools  # Install security tools (PROFILE=minimal|web|network|ad|k8s|uefi|telecom|aegis|sbom|recon|all)\nmake check-deps     # Check which tools are available\n```\n\nAdditional regression checks:\n\n```\ngo vet ./...\npython3 -m unittest discover -s scripts -p 'test_*.py'\ngo run golang.org/x/vuln/cmd/govulncheck@v1.9.0 ./...\n```\n\nThe wrapper unit tests build argv strings but verify them only against a\n`MockExecutor`. When an upstream binary changes its CLI, nothing catches it —\nthe `tools/livecheck` suite does. It runs the **real** binaries and asserts\nthat the flags, subcommands and enum values the wrappers emit are still\naccepted (help-text assertions plus safe dry-parses terminated by\n`--help`/`--echo`; nothing scans a target or mutates state).\n\n```\nmake test-live\n# equivalent: go test -tags=livebin ./tools/livecheck/... -run TestLiveFlagSurface\n```\n\nNotes:\n\n- \nThe suite is gated behind the `livebin` build tag, so`go test ./...` and\nthe normal CI jobs are unaffected.\n- \nBinaries are discovered via `PATH` ; a binary that is not installed is\nreported as`SKIP ... binary not on PATH` , never as a failure. The suite is\nsafe to run on any machine.\n- \nA check can also skip with a `KNOWN CLI DRIFT` /`SKIPPED (distro quirk)` message when the pinned or distro binary genuinely rejects the wrapper's\nargv (e.g. Ubuntu ships core john without the jumbo-only`--list` , and a\nbroken whatweb package). Those skips are deliberate, printed in every run,\nand must lead to a wrapper fix or a dependency bump — never to deleting the\ncheck.\n- \nIn the Docker image (which ships ~25 pinned binaries but no Go toolchain), compile the suite on the host and run it inside the container, where the binaries live: \n\n```\nCGO_ENABLED=0 go test -tags=livebin -c -o livecheck.test ./tools/livecheck/\ndocker run --rm --network none -v \"$PWD/livecheck.test:/usr/local/bin/livecheck.test:ro\" \\\n  --entrypoint /usr/local/bin/livecheck.test redhands\n```\n\n The `live-binaries` CI job instead installs a minimal binary set on\nubuntu-latest (apt plus the checksum-verified pinned releases via`scripts/dependencies.py` ) and runs`go test -tags=livebin` directly.\n- \nWhen you change a wrapper's argv, update the matching entry in `tools/livecheck/table.go` so drift detection stays meaningful.\n\nTier 1 (`tools/livecheck`) proves binaries still *accept* the wrappers' argv.\nTier 2 (`testdata/` golden fixtures) proves output *shapes*. The\n`tools/e2e` suite (Tier 3) proves **real execution**: it drives JSON-RPC\n`tools/call` and `campaign/run` requests into a fully wired in-process\nserver — the same `BinaryExecutor` (allowlist from `binaries.Discover()`),\nthe same middleware chain (audit to a temp file, rate limits, engagement\nscope, approval gates, concurrency limiter), the same registry with builtin\ntool policies, and the same campaign recorder as `cmd/redhands` — and\nasserts on what the real binaries actually did.\n\n```\nmake test-e2e\n# equivalent: go test -tags=livee2e ./tools/e2e/...\n```\n\nScenarios (all skip cleanly when their binary is missing):\n\n- **Barzakh purple-team loop (offline, deterministic)** —`barzakh_corpus` generates a corpus into a temp dir,`barzakh_scan` scans one malicious\nsample (scanner exit 1 = bootkit detected must surface as a*result* with\nthe severity summary rendered),`barzakh_validate` validates the corpus.\n- **Campaign with real execution and record rules** — a`campaign/run` whose steps execute the real corpus+scan tools through the middleware\nchain; the scan step's finding record rule persists the scanner's real`findings` array into the target database, asserted via the store.\n- **nmap against a test-owned listener** — the suite opens a`127.0.0.1:0` listener and runs`nmap_port_scan` (connect scan; SYN\nneeds root) and`nmap_service_detect` against that exact port.\n- **nuclei with a test-authored template** — a minimal`http` -protocol\ntemplate (static word matcher on a body the local test server always\nserves, severity`info` ) is written to a temp file and passed via the`templates` parameter; nothing is downloaded.\n- **telecom_doctor** —`staticzero-defense --doctor --json` : asserts the\nDoctorReport renders with a checks array and the`ebpf_object` check\npasses (the release binary embeds the eBPF object); privilege failures\nare expected and fine.\n- **telecom_firmware_analyze** — a synthetic modem image (documented\nfixture generator with a fixed seed for the padding) analyzed with`modem-firmware analyze` ; asserts the vulnerability report, its findings\n(strcpy, weak ciphers, debug interfaces), and the written report file.\n- **kubedagger_k8s_discover against no cluster** — only asserts the call\nreturns a well-formed response without hanging (the wrapper's\nempty-stdout handling is intentionally not pinned).`HOME` is redirected\nso the client cannot pick up a developer's real kubeconfig.\n\nSafety rules enforced by the suite:\n\n- The only network targets are `127.0.0.1` /localhost listeners the test\nitself owns; there is no network egress beyond the local binaries' own\nstartup.\n- Everything deterministic: `:0` listeners, fixed seeds for synthetic\ninputs, temp dirs, bounded polling (no sleeps) for the async audit log.\n- Gated behind the `livee2e` build tag, so`go test ./...` and the normal\nCI jobs are unaffected.\n- Executing tools are pre-approved in the harness config exactly like a\nreviewed `REDHANDS_APPROVED_TOOLS` setup, so the approval middleware\nitself is exercised (not bypassed).\n\nThe `live-e2e` CI job installs the scenario binaries (nmap via apt; nuclei\nvia the pinned `go install`; barzakh, StaticZero, and KubeDagger binaries\nvia the checksum-verified pinned releases in `scripts/dependencies.json`)\nand runs `go test -tags=livee2e ./tools/e2e/...`. When you add a scenario\nthat needs a new binary, add it to that job's install steps.\n\n```\n# Build and run\ndocker build -t redhands .\ndocker run -i redhands\n\n# With Docker Compose (local stdio mode; no published ports)\ndocker compose run --rm -i redhands\n\n# With authentication\n# Requires tls/server.crt, tls/server.key, and a strong REDHANDS_API_KEY\ndocker compose --profile secure up redhands-secure\n```\n\nThe Docker image includes a subset of supported security tools (check dependencies before use; some tools require additional installation or privileges):\n\n- **apt/source** : nmap, masscan, tshark, hashcat, john, nikto, whatweb\n- **pip** : impacket, certipy-ad\n- **Go tools** : subfinder, httpx, nuclei, ffuf, katana, gobuster, gau, waybackurls\n- **Releases** : chisel, ligolo-ng, kubedagger (client, operator, server v0.5.0), barzakh (adversary, scanner, server v0.7.1), staticzero (defense, modem-firmware, sdr-bridge v0.5.0), aegis-shadow-defense (v0.2.0)\n\nMIT\n\nRedHands is provided for authorized security testing, education, and research purposes only. You are solely responsible for ensuring you have explicit, written permission before using this tool against any system, network, or application. Unauthorized access to computer systems is illegal and punishable under applicable law including the Computer Fraud and Abuse Act (CFAA), Computer Misuse Act, and equivalent legislation worldwide.\n\nThe authors and contributors of RedHands accept no liability for misuse or damage caused by this software. Use responsibly and ethically.", "url": "https://wpnews.pro/news/show-hn-redhands-mcp-for-multi-stage-offensive-security-tools", "canonical_source": "https://github.com/yasindce1998/redhands", "published_at": "2026-11-14 20:05:10+00:00", "updated_at": "2026-11-14 20:23:44.928510+00:00", "lang": "en", "topics": ["ai-agents", "agent-protocols", "ai-tools", "developer-tools"], "entities": ["RedHands", "Yasin D. C.", "Model Context Protocol", "Go", "Claude Code", "Cursor", "Visual Studio Code", "GitHub"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/show-hn-redhands-mcp-for-multi-stage-offensive-security-tools", "markdown": "https://wpnews.pro/news/show-hn-redhands-mcp-for-multi-stage-offensive-security-tools.md", "text": "https://wpnews.pro/news/show-hn-redhands-mcp-for-multi-stage-offensive-security-tools.txt", "jsonld": "https://wpnews.pro/news/show-hn-redhands-mcp-for-multi-stage-offensive-security-tools.jsonld"}}