Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Implements external attack surface management (EASM) using Shodan, Censys, and ProjectDiscovery tools (subfinder, httpx, nuclei) for asset discovery, subdomain enumeration, service fingerprinting, and exposure scoring. Includes a weighted risk scoring algorithm based on OWASP attack surface analysis methodology and the Relative Attack Surface Quotient (RSQ). Use when building continuous ASM programs or performing external reconnaissance for security assessments.
.claude/skills/implementing-attack-surface-management/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-16 | ✗→✓ | ▲ Improved | — | — |
| case-15 | ✗→✓ | ▲ Improved | — | — |
| case-14 | ✗→✓ | ▲ Improved | — | — |
| case-17 | ✗→✓ | ▲ Improved | — | — |
| case-01 | ✓→✓ | = Same ✓ | — | — |
Use subfinder for passive subdomain discovery leveraging dozens of data sources including certificate transparency logs, DNS datasets, and search engines.
bash# Install ProjectDiscovery tools go install -v github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest go install -v github.com/projectdiscovery/httpx/cmd/httpx@latest go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest # Basic subdomain enumeration subfinder -d example.com -o subdomains.txt # Verbose with all sources and recursive enumeration subfinder -d example.com -all -recursive -o subdomains_full.txt # Multi-domain enumeration from file subfinder -dL domains.txt -o all_subdomains.txt # Using OWASP Amass for deeper enumeration amass enum -d example.com -passive -o amass_subdomains.txt # Merge and deduplicate results cat subdomains.txt amass_subdomains.txt | sort -u > combined_subdomains.txt
Probe discovered subdomains to identify live hosts, technologies, and services.
bash# HTTP probing with technology detection cat combined_subdomains.txt | httpx -sc -cl -ct -title -tech-detect \ -follow-redirects -json -o httpx_results.json # Detailed service fingerprinting cat combined_subdomains.txt | httpx -sc -cl -ct -title -tech-detect \ -favicon -hash sha256 -jarm -cdn -cname \ -follow-redirects -json -o httpx_detailed.json
Query Shodan for exposed services, open ports, and known vulnerabilities associated with discovered assets.
pythonimport shodan api = shodan.Shodan("YOUR_SHODAN_API_KEY") # Search by organization results = api.search("org:\"Example Corp\"") for service in results["matches"]: print(f"{service['ip_str']}:{service['port']} - {service.get('product', 'unknown')}") if service.get("vulns"): for cve in service["vulns"]: print(f" CVE: {cve}") # Search by hostname results = api.search("hostname:example.com") # Search by SSL certificate results = api.search("ssl.cert.subject.cn:example.com") # Get host details with all services host = api.host("93.184.216.34") print(f"IP: {host['ip_str']}") print(f"Ports: {host['ports']}") print(f"Vulns: {host.get('vulns', [])}")
Use Censys to discover internet-facing assets through certificate and host search.
pythonfrom censys.search import CensysHosts, CensysCerts # Host search hosts = CensysHosts() query = hosts.search("services.tls.certificates.leaf.subject.common_name: example.com") for page in query: for host in page: print(f"IP: {host['ip']}") for service in host.get("services", []): print(f" Port: {service['port']} Protocol: {service['transport_protocol']}") print(f" Service: {service.get('service_name', 'unknown')}") # Certificate transparency search certs = CensysCerts() query = certs.search("parsed.names: example.com") for page in query: for cert in page: print(f"Fingerprint: {cert['fingerprint_sha256']}") print(f"Names: {cert.get('parsed', {}).get('names', [])}")
Run targeted vulnerability scans against discovered assets using Nuclei templates.
bash# Update nuclei templates nuclei -ut # Scan with all templates cat combined_subdomains.txt | httpx -silent | nuclei -o nuclei_results.txt # Scan with specific severity cat combined_subdomains.txt | httpx -silent | \ nuclei -severity critical,high -o critical_findings.txt # Scan with specific template categories cat combined_subdomains.txt | httpx -silent | \ nuclei -tags cve,misconfig,exposure -o categorized_findings.txt # Scan for exposed panels and sensitive files cat combined_subdomains.txt | httpx -silent | \ nuclei -tags panel,exposure,config -o exposed_panels.txt
Score each asset based on OWASP attack surface analysis principles, using a weighted formula derived from the Relative Attack Surface Quotient (RSQ) and damage-potential-to-effort ratio.
The scoring algorithm considers:
python# Exposure Score = sum of weighted factors, normalized to 0-100 # See agent.py for the full implementation
bash# Run complete ASM pipeline against a target domain python agent.py \ --domain example.com \ --action full_scan \ --shodan-key YOUR_KEY \ --censys-id YOUR_ID \ --censys-secret YOUR_SECRET \ --output asm_report.json # Subdomain enumeration only python agent.py \ --domain example.com \ --action enumerate \ --output subdomains.json # Exposure scoring on previously discovered assets python agent.py \ --domain example.com \ --action score \ --input previous_scan.json \ --output scored_assets.json # Multi-domain scan from file python agent.py \ --domain-list targets.txt \ --action full_scan \ --output multi_domain_report.json
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-11 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-23 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +17 percentage points is the difference between those two pass rates over the 23 comparable cases.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
Other measured skills in the registry, with their headline benchmark lift.