====== recon.sh – Vollständige Domain-Recon mit Shodan Free & Claude ======
Das Script führt eine vollständig passive Reconnaissance durch, kombiniert Shodan Free, crt.sh, nmap und ruft am Ende Claude automatisch zur Analyse auf.
===== Voraussetzungen =====
<code bash> pip install shodan shodan init DEIN_API_KEY
# Prüfen which nmap dig curl python3 jq openssl claude </code>
^ Tool ^ Zweck ^ Paket ^ | ''nmap'' | Port-Scan | ''nmap'' | | ''dig'' / ''host'' | DNS-Auflösung | ''bind-utils'' | | ''curl'' | crt.sh-Abfrage | ''curl'' | | ''openssl'' | TLS-Zertifikate | ''openssl'' | | ''python3'' | Shodan-API, JSON | ''python3'' | | ''claude'' | KI-Analyse | Claude Code | | ''shodan'' | Shodan CLI | ''pip install shodan'' |
===== Installation =====
<code bash> mkdir -p ~/hacking # Script ablegen (siehe unten) chmod +x ~/hacking/recon.sh </code>
===== Nutzung =====
<code bash> # Vollständig (alle Phasen inkl. nmap + Claude) ./recon.sh bgv.de
# Ohne nmap (rein passiv, schneller) ./recon.sh bgv.de --no-nmap
# Ohne Claude-Analyse (nur Rohdaten sammeln) ./recon.sh bgv.de --no-claude
# Nur Rohdaten, kein Scan, kein Claude ./recon.sh bgv.de --no-nmap --no-claude </code>
===== Was das Script macht =====
==== Phase 1 – Subdomains via crt.sh ====
Liest alle bekannten Subdomains aus den öffentlichen Certificate-Transparency-Logs. Kein Account, keine Credits nötig.
<code bash> curl -s "https://crt.sh/?q=%.bgv.de&output=json" | python3 ... </code>
Typisches Ergebnis: 50–150 Subdomains pro Unternehmens-Domain.
==== Phase 2 – DNS-Auflösung & IP-Klassifizierung ====
Löst alle Subdomains per ''dig'' auf und trennt automatisch: * **Externe IPs** → werden weiter gescannt * **Interne IPs** (RFC-1918: 10.x, 172.16–31.x, 192.168.x) → nur dokumentiert
==== Phase 3 – Shodan Free ====
Ohne Query Credits verfügbar:
^ Abfrage ^ Credits ^ Erkenntnisgewinn ^ | ''shodan count hostname:ziel.de'' | 0 | Gesamtanzahl indexierter Hosts | | ''shodan count hostname:ziel.de port:443'' | 0 | Port-Verteilung | | ''shodan count hostname:ziel.de port:27017'' | 0 | Offene DBs erkennbar | | ''shodan host <IP>'' | 1/IP | Details, CVEs (nur mit Credits) |
Mit 0 Credits: Das Script prüft automatisch via ''shodan info'', ob Credits vorhanden sind – nur dann werden host-Lookups durchgeführt.
==== Phase 4 – SSL/TLS Zertifikate ====
Liest für jede externe IP das TLS-Zertifikat via ''openssl s_client''. Daraus extrahierbar:
- Subject Alternative Names → weitere versteckte Subdomains
- Ablaufdaten → abgelaufene Zerts = Finding
- Aussteller → intern signierte Zerts = Hinweis auf interne PKI
==== Phase 5 – Nmap ====
Scannt externe IPs auf die wichtigsten Ports:
<code> 22, 80, 443, 8080, 8443, 3389, 21, 25, 587, 993, 995 </code>
Flags: ''-Pn -sV -sC --open -T4'' * ''-Pn'' → kein Ping, direkt scannen (Firewall umgehen) * ''-sV'' → Service-Version erkennen * ''-sC'' → Standard-Scripts (SSL-Cert, HTTP-Header usw.)
==== Phase 6 – Claude-Analyse ====
Alle gesammelten Rohdaten werden als strukturierter Prompt an Claude übergeben:
<code bash>
echo "$PROMPT" | claude -p \
--model sonnet \
--no-session-persistence \
> report.md
</code>
Claude erstellt automatisch: - Executive Summary - Angriffsflächen-Übersicht - Kritische Findings (priorisiert) - Bedeutung auffälliger Subdomains - Empfohlene nächste Pentest-Schritte - Relevante MITRE ATT&CK-Techniken
===== Output-Struktur =====
<code> ~/hacking/reports/bgv.de_20260319_141500/ ├── raw_data.txt ← komplette Konsolenausgabe ├── subdomains.txt ← alle gefundenen Subdomains ├── dns_map.txt ← Subdomain → IP Mapping ├── external_ips.txt ← externe IPs (dedupliziert) ├── internal_ips.txt ← interne RFC-1918 IPs ├── shodan.txt ← Shodan-Ergebnisse ├── ssl_certs.txt ← TLS-Zertifikat-Details ├── nmap.txt ← Nmap-Ergebnisse ├── summary_for_claude.txt ← Rohbericht (Claude-Input) └── report.md ← fertiger Claude-Analysebericht </code>
===== Vollständiges Script =====
<code bash> #!/bin/bash # ============================================================================= # recon.sh – Passive Domain Recon mit Shodan Free + Claude-Analyse # Nutzung: ./recon.sh <domain> [--no-nmap] [--no-claude] # =============================================================================
set -euo pipefail
RED='\033[0;31m'; YELLOW='\033[1;33m'; GREEN='\033[0;32m' CYAN='\033[0;36m'; BOLD='\033[1m'; RESET='\033[0m'
banner() { echo -e "\n${CYAN}${BOLD}━━━ $1 ━━━${RESET}"; }
ok() { echo -e "${GREEN}[+]${RESET} $1"; }
info() { echo -e "${YELLOW}[*]${RESET} $1"; }
err() { echo -e "${RED}[!]${RESET} $1"; }
DOMAIN="${1:-}"
RUN_NMAP=true
RUN_CLAUDE=true
for arg in "${@:2}"; do
[[ "$arg" == "--no-nmap" ]] && RUN_NMAP=false
[[ "$arg" == "--no-claude" ]] && RUN_CLAUDE=false
done
[[ -z "$DOMAIN" ]] && { echo "Nutzung: $0 <domain> [--no-nmap] [--no-claude]"; exit 1; }
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
OUTDIR="${HOME}/hacking/reports/${DOMAIN}_${TIMESTAMP}"
mkdir -p "$OUTDIR"
RAW_FILE="${OUTDIR}/raw_data.txt"
REPORT_FILE="${OUTDIR}/report.md"
exec > >(tee -a "$RAW_FILE") 2>&1
echo -e "${BOLD}"
echo "╔══════════════════════════════════════════════════════╗"
echo "║ RECON SCRIPT – Shodan Free + Claude ║"
echo "╚══════════════════════════════════════════════════════╝"
echo -e "${RESET}"
info "Ziel: $DOMAIN | Output: $OUTDIR | $(date)"
# --- Phase 1: crt.sh ----------------------------------------------------------
banner "PHASE 1: Subdomains via crt.sh"
SUBDOMAINS_FILE="${OUTDIR}/subdomains.txt"
curl -s "https://crt.sh/?q=%.${DOMAIN}&output=json" \
| python3 -c "
import sys, json
try:
data = json.load(sys.stdin)
names = set()
for e in data:
for n in e.get('name_value','').split('\n'):
n = n.strip().lstrip('*.')
if n and '.' in n: names.add(n.lower())
[print(n) for n in sorted(names)]
except Exception as ex:
print(f'Fehler: {ex}', file=sys.stderr)
" > "$SUBDOMAINS_FILE" 2>/dev/null || true
ok "$(wc -l < "$SUBDOMAINS_FILE") Subdomains gefunden"
cat "$SUBDOMAINS_FILE"
# --- Phase 2: DNS -------------------------------------------------------------
banner "PHASE 2: DNS-Auflösung"
EXT_IPS_FILE="${OUTDIR}/external_ips.txt"
INT_IPS_FILE="${OUTDIR}/internal_ips.txt"
DNS_MAP_FILE="${OUTDIR}/dns_map.txt"
> "$EXT_IPS_FILE"; > "$INT_IPS_FILE"; > "$DNS_MAP_FILE"
while IFS= read -r sub; do
ips=$(dig +short "$sub" A 2>/dev/null | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' || true)
if [[ -n "$ips" ]]; then
while IFS= read -r ip; do
echo "$sub -> $ip" | tee -a "$DNS_MAP_FILE"
if echo "$ip" | grep -qE '^(10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.)'; then
echo "$ip" >> "$INT_IPS_FILE"
else
echo "$ip" >> "$EXT_IPS_FILE"
fi
done <<< "$ips"
fi
done < "$SUBDOMAINS_FILE"
sort -u "$EXT_IPS_FILE" -o "$EXT_IPS_FILE" sort -u "$INT_IPS_FILE" -o "$INT_IPS_FILE" ok "$(wc -l < "$EXT_IPS_FILE") externe IPs | $(wc -l < "$INT_IPS_FILE") interne IPs"
# --- Phase 3: Shodan ----------------------------------------------------------
banner "PHASE 3: Shodan (Free)"
SHODAN_FILE="${OUTDIR}/shodan.txt"
> "$SHODAN_FILE"
API_KEY="${SHODAN_API_KEY:-$(cat ~/.shodan/api_key 2>/dev/null || echo '')}"
if [[ -z "$API_KEY" ]]; then
err "Kein SHODAN_API_KEY – Phase übersprungen"
else
COUNT_RESULT=$(shodan count "hostname:${DOMAIN}" 2>/dev/null || echo "0")
ok "Shodan indexiert: $COUNT_RESULT Hosts"
echo "shodan_count: $COUNT_RESULT" >> "$SHODAN_FILE"
for PORT in 22 80 443 3389 8080 8443 21 25 3306 5432 27017 6379 9200; do
CNT=$(shodan count "hostname:${DOMAIN} port:${PORT}" 2>/dev/null || echo "0")
[[ "$CNT" -gt 0 ]] && echo "port_${PORT}: $CNT hosts" | tee -a "$SHODAN_FILE"
done
QUERY_CREDITS=$(shodan info 2>/dev/null | grep "Query credits" | awk '{print $NF}' || echo "0")
info "Query Credits verfügbar: $QUERY_CREDITS"
if [[ "$QUERY_CREDITS" -gt 0 ]]; then
python3 - "$API_KEY" "$EXT_IPS_FILE" "$SHODAN_FILE" << 'PYEOF'
import shodan, sys
api = shodan.Shodan(sys.argv[1])
with open(sys.argv[2]) as f:
ips = [l.strip() for l in f if l.strip()]
with open(sys.argv[3], 'a') as out:
for ip in ips[:10]:
try:
h = api.host(ip)
out.write(f"\n=== {ip} ({h.get('org','-')}) ===\n")
out.write(f"Hostnames: {h.get('hostnames')}\n")
for s in h.get('data', []):
out.write(f" Port {s['port']} {s.get('product','')} {s.get('version','')}\n")
for cve in s.get('vulns', {}):
out.write(f" ⚠ {cve}\n")
print(f"[+] {ip} abgefragt")
except Exception as e:
print(f"[!] {ip}: {e}")
PYEOF
fi
fi
# --- Phase 4: SSL/TLS ---------------------------------------------------------
banner "PHASE 4: SSL/TLS Zertifikate"
SSL_FILE="${OUTDIR}/ssl_certs.txt"
> "$SSL_FILE"
while IFS= read -r ip; do
CERT=$(echo | timeout 5 openssl s_client -connect "${ip}:443" \
-servername "$DOMAIN" 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates -ext subjectAltName 2>/dev/null || true)
[[ -n "$CERT" ]] && { echo "--- $ip ---" | tee -a "$SSL_FILE"; echo "$CERT" | tee -a "$SSL_FILE"; }
done < "$EXT_IPS_FILE"
# --- Phase 5: Nmap ------------------------------------------------------------
if $RUN_NMAP; then
banner "PHASE 5: Nmap"
NMAP_FILE="${OUTDIR}/nmap.txt"
EXT_IP_LIST=$(tr '\n' ' ' < "$EXT_IPS_FILE" | head -c 1000)
if [[ -n "$EXT_IP_LIST" ]]; then
nmap -Pn -sV -sC -p 22,80,443,8080,8443,3389,21,25,587,993,995 \
--open -T4 --max-retries 1 -oN "$NMAP_FILE" $EXT_IP_LIST 2>/dev/null \
&& ok "Nmap → $NMAP_FILE" || err "Nmap teilweise fehlgeschlagen"
fi
fi
# --- Phase 6: Claude ----------------------------------------------------------
banner "PHASE 6: Claude-Analyse"
SUMMARY=$(printf "# Recon %s\nDatum: %s\n\n## Subdomains\n%s\n\n## DNS extern\n%s\n\n## Shodan\n%s\n\n## SSL\n%s\n\n## Nmap\n%s" \
"$DOMAIN" "$(date)" \
"$(cat "$SUBDOMAINS_FILE")" \
"$(grep -v '10\.\|172\.1[6-9]\.\|172\.2[0-9]\.\|172\.3[01]\.\|192\.168\.' "$DNS_MAP_FILE" 2>/dev/null)" \
"$(cat "$SHODAN_FILE" 2>/dev/null)" \
"$(cat "$SSL_FILE" 2>/dev/null)" \
"$(cat "${OUTDIR}/nmap.txt" 2>/dev/null || echo 'nicht durchgeführt')")
echo "$SUMMARY" > "${OUTDIR}/summary_for_claude.txt"
if $RUN_CLAUDE; then
printf "Du bist Ethical Hacker. Analysiere diese Recon-Daten für '%s'.\n\nErstelle einen strukturierten Sicherheitsbericht auf Deutsch:\n1. Executive Summary\n2. Angriffsfläche (exponierte
Dienste)\n3. Kritische Findings (priorisiert)\n4. Auffällige Subdomains\n5. Nächste Pentest-Schritte\n6. Relevante MITRE ATT&CK Techniken\n\nRohdaten:\n---\n%s\n---\n\nAusgabe als Markdown." \
"$DOMAIN" "$SUMMARY" \
| claude -p --model sonnet --no-session-persistence \
> "$REPORT_FILE" 2>/dev/null \
&& ok "Claude-Report → $REPORT_FILE" || err "Claude fehlgeschlagen"
echo ""; cat "$REPORT_FILE" fi
banner "ABGESCHLOSSEN"
ok "Ergebnisse: ${BOLD}$OUTDIR${RESET}"
ls -lh "$OUTDIR"
</code>
===== Shodan Free vs. Membership – was das Script nutzt =====
^ Phase ^ Free ^ Membership ^ | crt.sh Subdomains | ✓ | ✓ | | DNS-Auflösung | ✓ | ✓ | | shodan count | ✓ | ✓ | | Port-Statistiken | ✓ | ✓ | | shodan host <IP> | ✗ (0 Credits) | ✓ | | shodan search | ✗ | ✓ | | vuln: CVE-Filter | ✗ | ✓ | | SSL/TLS-Analyse | ✓ | ✓ | | nmap Port-Scan | ✓ | ✓ | | Claude-Analyse | ✓ | ✓ |
===== Nur im Hacker-Workspace nutzen =====
Das Script liegt unter ''~/hacking/'' mit eigener ''.claude/settings.json'':
<code bash> mkdir -p ~/hacking/.claude </code>
''~/hacking/.claude/settings.json'':
<code json>
{
"env": {
"SHODAN_API_KEY": "DEIN_API_KEY"
},
"permissions": {
"allow": [
"Bash(shodan:*)",
"Bash(nmap:*)",
"Bash(./recon.sh:*)",
"Bash(dig:*)",
"Bash(curl:*)",
"Bash(python3:*)",
"Bash(openssl:*)"
]
}
}
</code>
Start ausschließlich im Hacker-Kontext: <code bash> cd ~/hacking claude --profile hacker </code>
Shodan-Berechtigungen und das Script sind damit **nur in diesem Verzeichnis aktiv** – in anderen Projekten greift die globale ''settings.json'' ohne Shodan-Rechte.
===== Quellen =====
- MATHERLY, John, 2015. Complete Guide to Shodan. Shodan, LLC. https://leanpub.com/shodan
- SHODAN, 2024. Shodan API Reference. https://developer.shodan.io [Zugriff: 2026-03-19]
- MITRE, 2024. ATT&CK Framework. https://attack.mitre.org [Zugriff: 2026-03-19]
- ANTHROPIC, 2024. Claude Code CLI Reference. https://docs.anthropic.com/claude-code [Zugriff: 2026-03-19]
- CERTIFICATE TRANSPARENCY. crt.sh Search. https://crt.sh [Zugriff: 2026-03-19]
- –
Das Script liegt fertig unter ~/hacking/recon.sh. Direkt testen:
cd ~/hacking ./recon.sh bgv.de --no-nmap # schnell, rein passiv
