mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-09-03 06:50:51 +03:00
Add folder anatomy (scripts/agent.py + references/api-reference.md) for 648 cybersecurity skills
Complete skill folder anatomy across all cybersecurity skills: - scripts/agent.py: 80-150 line Python agents using real libraries (impacket, boto3, azure-mgmt-*, kubernetes, pefile, yara, scapy, shodan, stix2, etc.) - references/api-reference.md: real API documentation with method signatures - LICENSE: MIT license for all skill folders
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Anthropic Agent Skills Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,63 @@
|
||||
# API Reference: Performing DNS Enumeration and Zone Transfer
|
||||
|
||||
## dnspython Library
|
||||
|
||||
| Function/Class | Description |
|
||||
|----------------|-------------|
|
||||
| `dns.resolver.resolve(domain, rdtype)` | Query DNS records by type |
|
||||
| `dns.zone.from_xfr(xfr_response)` | Parse zone transfer response |
|
||||
| `dns.query.xfr(nameserver, domain)` | Perform AXFR zone transfer |
|
||||
| `dns.rdatatype.to_text(rdtype)` | Convert record type to string |
|
||||
| `dns.resolver.Resolver()` | Custom resolver with timeout settings |
|
||||
|
||||
## DNS Record Types
|
||||
|
||||
| Type | Description |
|
||||
|------|-------------|
|
||||
| A | IPv4 address record |
|
||||
| AAAA | IPv6 address record |
|
||||
| MX | Mail exchange server |
|
||||
| NS | Authoritative nameserver |
|
||||
| TXT | Text record (SPF, DKIM, DMARC) |
|
||||
| SOA | Start of Authority |
|
||||
| CNAME | Canonical name alias |
|
||||
| SRV | Service location record |
|
||||
| CAA | Certificate Authority Authorization |
|
||||
| AXFR | Full zone transfer request |
|
||||
|
||||
## Email Security Records
|
||||
|
||||
| Record | Location | Description |
|
||||
|--------|----------|-------------|
|
||||
| SPF | `domain TXT` | Authorized mail sender IPs |
|
||||
| DMARC | `_dmarc.domain TXT` | Email authentication policy |
|
||||
| DKIM | `selector._domainkey.domain TXT` | Email signing public key |
|
||||
|
||||
## Key Libraries
|
||||
|
||||
- **dnspython** (`pip install dnspython`): Full-featured DNS toolkit for Python
|
||||
- **python-nmap** (optional): Network port scanning for DNS services
|
||||
- **sublist3r** (optional): Subdomain enumeration using search engines
|
||||
|
||||
## Configuration
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| Target domain | Authorized target domain for enumeration |
|
||||
| Resolver timeout | DNS query timeout (default 3 seconds) |
|
||||
| Wordlist | Subdomain brute-force dictionary |
|
||||
|
||||
## Common Subdomain Wordlists
|
||||
|
||||
| Source | Description |
|
||||
|--------|-------------|
|
||||
| SecLists DNS | `Discovery/DNS/subdomains-top1million-5000.txt` |
|
||||
| Assetnote | Best-DNS-Wordlist from Assetnote |
|
||||
| Custom | Industry-specific subdomain patterns |
|
||||
|
||||
## References
|
||||
|
||||
- [dnspython Documentation](https://dnspython.readthedocs.io/)
|
||||
- [OWASP DNS Enumeration](https://owasp.org/www-community/attacks/DNS_Enumeration)
|
||||
- [SecLists](https://github.com/danielmiessler/SecLists)
|
||||
- [Amass OWASP](https://github.com/owasp-amass/amass)
|
||||
@@ -0,0 +1,251 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
DNS Enumeration and Zone Transfer Agent — AUTHORIZED TESTING ONLY
|
||||
Performs DNS reconnaissance including record enumeration, zone transfer
|
||||
attempts, and subdomain discovery using dnspython.
|
||||
|
||||
WARNING: Only use with explicit written authorization for the target domain.
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
from datetime import datetime, timezone
|
||||
|
||||
import dns.resolver
|
||||
import dns.zone
|
||||
import dns.query
|
||||
import dns.rdatatype
|
||||
|
||||
|
||||
def enumerate_dns_records(domain: str) -> dict:
|
||||
"""Enumerate common DNS record types for a domain."""
|
||||
record_types = ["A", "AAAA", "MX", "NS", "TXT", "SOA", "CNAME", "SRV", "CAA"]
|
||||
results = {}
|
||||
|
||||
for rtype in record_types:
|
||||
try:
|
||||
answers = dns.resolver.resolve(domain, rtype)
|
||||
records = []
|
||||
for rdata in answers:
|
||||
records.append(str(rdata))
|
||||
results[rtype] = records
|
||||
except (dns.resolver.NoAnswer, dns.resolver.NXDOMAIN):
|
||||
results[rtype] = []
|
||||
except dns.exception.DNSException:
|
||||
results[rtype] = []
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def get_nameservers(domain: str) -> list[str]:
|
||||
"""Resolve authoritative nameservers for a domain."""
|
||||
nameservers = []
|
||||
try:
|
||||
ns_records = dns.resolver.resolve(domain, "NS")
|
||||
for ns in ns_records:
|
||||
ns_name = str(ns).rstrip(".")
|
||||
try:
|
||||
a_records = dns.resolver.resolve(ns_name, "A")
|
||||
for a in a_records:
|
||||
nameservers.append({"name": ns_name, "ip": str(a)})
|
||||
except dns.exception.DNSException:
|
||||
nameservers.append({"name": ns_name, "ip": "unresolved"})
|
||||
except dns.exception.DNSException as e:
|
||||
nameservers.append({"error": str(e)})
|
||||
|
||||
return nameservers
|
||||
|
||||
|
||||
def attempt_zone_transfer(domain: str, nameservers: list[dict]) -> dict:
|
||||
"""Attempt AXFR zone transfer against each nameserver."""
|
||||
results = {"vulnerable": False, "records": [], "tested_servers": []}
|
||||
|
||||
for ns in nameservers:
|
||||
ns_ip = ns.get("ip", "")
|
||||
ns_name = ns.get("name", "")
|
||||
if ns_ip == "unresolved" or "error" in ns:
|
||||
continue
|
||||
|
||||
server_result = {"nameserver": ns_name, "ip": ns_ip, "transfer_allowed": False}
|
||||
|
||||
try:
|
||||
zone = dns.zone.from_xfr(dns.query.xfr(ns_ip, domain, timeout=10))
|
||||
server_result["transfer_allowed"] = True
|
||||
results["vulnerable"] = True
|
||||
|
||||
for name, node in zone.nodes.items():
|
||||
for rdataset in node.rdatasets:
|
||||
for rdata in rdataset:
|
||||
results["records"].append({
|
||||
"name": str(name),
|
||||
"type": dns.rdatatype.to_text(rdataset.rdtype),
|
||||
"ttl": rdataset.ttl,
|
||||
"data": str(rdata),
|
||||
})
|
||||
|
||||
except dns.exception.FormError:
|
||||
server_result["error"] = "Transfer refused (FORMERR)"
|
||||
except dns.xfr.TransferError:
|
||||
server_result["error"] = "Transfer refused"
|
||||
except dns.exception.DNSException as e:
|
||||
server_result["error"] = str(e)
|
||||
except Exception as e:
|
||||
server_result["error"] = str(e)
|
||||
|
||||
results["tested_servers"].append(server_result)
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def check_email_security(domain: str) -> dict:
|
||||
"""Check SPF, DKIM, and DMARC DNS records."""
|
||||
security = {"spf": None, "dmarc": None, "dkim_selectors": []}
|
||||
|
||||
try:
|
||||
txt_records = dns.resolver.resolve(domain, "TXT")
|
||||
for txt in txt_records:
|
||||
txt_str = str(txt).strip('"')
|
||||
if txt_str.startswith("v=spf1"):
|
||||
security["spf"] = txt_str
|
||||
except dns.exception.DNSException:
|
||||
pass
|
||||
|
||||
try:
|
||||
dmarc = dns.resolver.resolve(f"_dmarc.{domain}", "TXT")
|
||||
for txt in dmarc:
|
||||
txt_str = str(txt).strip('"')
|
||||
if "v=DMARC1" in txt_str:
|
||||
security["dmarc"] = txt_str
|
||||
except dns.exception.DNSException:
|
||||
pass
|
||||
|
||||
common_selectors = ["default", "google", "selector1", "selector2", "s1", "s2", "mail", "k1"]
|
||||
for selector in common_selectors:
|
||||
try:
|
||||
dkim = dns.resolver.resolve(f"{selector}._domainkey.{domain}", "TXT")
|
||||
for txt in dkim:
|
||||
security["dkim_selectors"].append({
|
||||
"selector": selector,
|
||||
"record": str(txt).strip('"')[:100],
|
||||
})
|
||||
except dns.exception.DNSException:
|
||||
pass
|
||||
|
||||
return security
|
||||
|
||||
|
||||
def brute_force_subdomains(domain: str, wordlist: list[str] = None) -> list[dict]:
|
||||
"""Brute-force subdomain discovery via DNS resolution."""
|
||||
if wordlist is None:
|
||||
wordlist = [
|
||||
"www", "mail", "ftp", "admin", "api", "dev", "staging",
|
||||
"test", "vpn", "portal", "app", "login", "secure",
|
||||
"m", "blog", "shop", "cdn", "ns1", "ns2", "mx",
|
||||
"remote", "gateway", "intranet", "extranet", "webmail",
|
||||
"owa", "autodiscover", "sso", "auth", "git", "ci",
|
||||
]
|
||||
|
||||
found = []
|
||||
resolver = dns.resolver.Resolver()
|
||||
resolver.timeout = 3
|
||||
resolver.lifetime = 3
|
||||
|
||||
for sub in wordlist:
|
||||
fqdn = f"{sub}.{domain}"
|
||||
try:
|
||||
answers = resolver.resolve(fqdn, "A")
|
||||
ips = [str(a) for a in answers]
|
||||
found.append({"subdomain": fqdn, "ips": ips, "record_type": "A"})
|
||||
except dns.exception.DNSException:
|
||||
pass
|
||||
|
||||
try:
|
||||
answers = resolver.resolve(fqdn, "CNAME")
|
||||
cnames = [str(c) for c in answers]
|
||||
found.append({"subdomain": fqdn, "cnames": cnames, "record_type": "CNAME"})
|
||||
except dns.exception.DNSException:
|
||||
pass
|
||||
|
||||
return found
|
||||
|
||||
|
||||
def generate_report(
|
||||
domain: str, records: dict, nameservers: list, zone_transfer: dict,
|
||||
email_security: dict, subdomains: list,
|
||||
) -> str:
|
||||
"""Generate DNS enumeration report."""
|
||||
lines = [
|
||||
"DNS ENUMERATION AND ZONE TRANSFER REPORT — AUTHORIZED TESTING ONLY",
|
||||
"=" * 65,
|
||||
f"Target Domain: {domain}",
|
||||
f"Date: {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M UTC')}",
|
||||
"",
|
||||
"DNS RECORDS:",
|
||||
]
|
||||
for rtype, recs in records.items():
|
||||
if recs:
|
||||
lines.append(f" {rtype}: {', '.join(recs[:5])}")
|
||||
|
||||
lines.extend([
|
||||
"",
|
||||
f"NAMESERVERS ({len(nameservers)}):",
|
||||
])
|
||||
for ns in nameservers:
|
||||
if "error" not in ns:
|
||||
lines.append(f" {ns['name']} ({ns['ip']})")
|
||||
|
||||
vuln = "VULNERABLE" if zone_transfer["vulnerable"] else "NOT VULNERABLE"
|
||||
lines.extend([
|
||||
"",
|
||||
f"ZONE TRANSFER: {vuln}",
|
||||
f" Records Leaked: {len(zone_transfer['records'])}",
|
||||
])
|
||||
|
||||
lines.extend([
|
||||
"",
|
||||
"EMAIL SECURITY:",
|
||||
f" SPF: {'Present' if email_security['spf'] else 'MISSING'}",
|
||||
f" DMARC: {'Present' if email_security['dmarc'] else 'MISSING'}",
|
||||
f" DKIM Selectors Found: {len(email_security['dkim_selectors'])}",
|
||||
"",
|
||||
f"SUBDOMAINS DISCOVERED: {len(subdomains)}",
|
||||
])
|
||||
for sub in subdomains[:15]:
|
||||
ips = sub.get("ips", sub.get("cnames", []))
|
||||
lines.append(f" {sub['subdomain']} -> {', '.join(ips)}")
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("[!] DNS ENUMERATION — AUTHORIZED TESTING ONLY\n")
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print(f"Usage: {sys.argv[0]} <target_domain>")
|
||||
sys.exit(1)
|
||||
|
||||
domain = sys.argv[1]
|
||||
|
||||
print(f"[*] Enumerating DNS records for {domain}...")
|
||||
records = enumerate_dns_records(domain)
|
||||
|
||||
print("[*] Resolving nameservers...")
|
||||
nameservers = get_nameservers(domain)
|
||||
|
||||
print("[*] Attempting zone transfer...")
|
||||
zone_transfer = attempt_zone_transfer(domain, nameservers)
|
||||
|
||||
print("[*] Checking email security records...")
|
||||
email_security = check_email_security(domain)
|
||||
|
||||
print("[*] Brute-forcing subdomains...")
|
||||
subdomains = brute_force_subdomains(domain)
|
||||
|
||||
report = generate_report(domain, records, nameservers, zone_transfer, email_security, subdomains)
|
||||
print(report)
|
||||
|
||||
output = f"dns_enum_{domain.replace('.', '_')}_{datetime.now(timezone.utc).strftime('%Y%m%d')}.json"
|
||||
with open(output, "w") as f:
|
||||
json.dump({"records": records, "nameservers": nameservers, "zone_transfer": zone_transfer,
|
||||
"email_security": email_security, "subdomains": subdomains}, f, indent=2)
|
||||
print(f"\n[*] Results saved to {output}")
|
||||
Reference in New Issue
Block a user