Tool Family: domain
- Registration source:
tools/mcp_tools/domain.py:282 register_domain_tools(mcp, *, ctx)— auto-discovered. Domain-specific attack surface alongside IP tools; all domain-param tools use@require_allowlist("domain")(wildcard-aware). - Takeover & enumeration:
enumerate_subdomainsadds discoveries toEXPLOIT_DISCOVERED_TARGETSviaadd_discovered_targetso agent can attack without per-host config edits; lock preserved.
Tools Exported (5)
| Tool | Gate | Params | Result Shape | Notes |
|---|---|---|---|---|
resolve_domain | @require_allowlist("domain") | domain: str, record_types: str="A,AAAA,MX,NS,TXT,CNAME,SOA,CAA" (comma CSV) | DNS_RESULT: completed\nDOMAIN: ...\nNOTE?: ...\n A: ...\n MX: ... | Bridge primitive. is_fqdn(domain) validated; record_types split + uppercased defaulting to all 8. Uses dnspython when present (dns.resolver.resolve per type) else socket.getaddrinfo for A/AAAA only + note. Helper _dns_resolve_all (domain.py:237) + _stdlib_fetch (domain.py:204) for HTTP. |
enumerate_subdomains | @require_allowlist("domain") | domain, sources: str="crt_sh,dns_bruteforce" (`crt_sh | dns_bruteforce | subfinder |
dns_recon | @require_allowlist("domain") | domain, zone_transfer: bool=False | `DNS_RECON_RESULT: completed\nDOMAIN: ...\nA/AAAA/MX/NS/TXT/SPF/DMARC/SOA/CAA per-type\nDNSSEC: signed | unsigned |
vhost_enum | @require_allowlist() (target_ip param) | target_ip, port: int=80, domain: str (required), wordlist: str="" (CSV extra prefixes), timeout: int=300 | VHOST_RESULT: completed\nTARGET: ip:port\nDOMAIN: ...\nBASELINE_LENGTH/HASH ...\nVHOSTS_FOUND: N\nVHOSTS:\n vhost (status=..., len vs baseline, hash vs ...) + NOTE: HTTPS vhost uses Host header only; SNI not rotated when https | 28-word builtin + extra prefixes; capped max_probes = max(1, timeout//10) probes (10s each). Baseline Host: target_ip via _stdlib_fetch(base_url), SHA256 baseline; each w.domain probed with Host: w.domain; flagged when status or length or content hash differs. is_fqdn(domain) validated; scheme https for 443/8443. |
domain_whois | @require_allowlist("domain") | domain | `WHOIS_RESULT: completed\nDOMAIN: ...\nREGISTRAR: ...\nCREATION_DATE: ...\nEXPIRY_DATE: ...\nREGISTRANT_ORG: ...\nDNS_PROVIDER: Cloudflare | AWS Route53 |
Validation
- Domain tools validate
is_fqdn(dom)(wildcard*.allowed at input);vhost_enumvalidates ip viavalidate_target_or_ip. - Subdomain boundary via
is_subdomain_of(candidate, parent)(tools/validation_utils.py:430) — suffix.+ parent, preventsbadexample.comcollision. - Enumerated hosts auto-authorized via
add_discovered_target; still gated byis_target_in_allowliston next use.
Dependencies
tools/validation_utils.is_fqdn,resolve_target_to_ip,is_subdomain_of,validate_target_or_ip,is_target_in_allowlisttools/kernel/allowlist._allowed_target_list,add_discovered_target,check_targets_allowlisttools/mcp_shared._run_with_pgrp_timeout,_attempt_dir- Optional:
dnspython,python-whois,subfinder,amass,whoisbinary
Config
exploit.require_explicit_allowlist,exploit.allowed_targetsrecon.dns_zone_transfer: bool— gatesdns_reconAXFR (default false)- No per-tool wordlist config; builtin wordlist used.
Auditing
- Domain tools
@require_allowlist("domain")withtarget_param="domain"binding → audit records keyed bydomainstring. vhost_enumallowlist-gated ontarget_ip; writesstarted/completed|blocked.
Tests
tests/test_domain_mcp_tools.py—resolve_domain,enumerate_subdomains(crt.sh mock, bruteforce, takeover),dns_reconbranches,vhost_enumbaseline/hash diff,domain_whoisparsetests/test_domain_allowlist.py— wildcard + subdomain boundarytests/test_mcp_tool_registration.py— at least domain tools implicitly via total
Related Docs
docs/mcp/security.md— auto-authorization viaEXPLOIT_DISCOVERED_TARGETSdocs/mcp/tool-families/recon.md— IP recon counterpart
source: repo docs (build sync)Edit this page on GitHub →