
Generiere Caddy-Redirector-Konfigurationen aus Cobalt Strike- oder Sliver C2-Profilen.
CaddySmith ist ein kleines Python-Skript, das ein Cobalt Strike- oder Sliver-C2-Profil einliest und daraus eine Caddy-Webserver-Konfiguration erstellt. Die generierte Caddyfile verwandelt eine gewöhnliche Linux-Box in einen Redirector: Legitimer Beacon-Traffic wird per Reverse-Proxy an deinen Team-Server weitergeleitet, alles andere (Scanner, Such-Bots, Blue-Team-Sonden, zufällige curl-Aufrufe) wird an eine Köder-URL weitergeleitet.
Ich habe das geschrieben, weil Caddy ein viel freundlicherer Webserver ist, um schnell aufzusetzen, als Apache: einzelnes statisches Binary, automatische Let's-Encrypt-Zertifikate, kein a2enmod-Tanz.
Nur für autorisierte Einsätze. Dies ist offensive Security-Software. Führe sie nur gegen Umgebungen aus, für die du eine schriftliche Erlaubnis hast.
CaddySmith erkennt das Format automatisch anhand des Dateiinhalts:
set uri "/foo"-Anweisungen. Jeder HTTP-GET/HTTP-POST-URI wird zu einer exakten Pfad-Route mit den Client-Headern des Profils.path /api* /static* /resources*) und eine Substring-Übereinstimmung mit der Chrome-Build-Nummer aus dem User-Agent durchgeführt wird (die Slivers plattformabhängige UA-Umschreibungen überlebt).Du kannst auch einen bestimmten Parser erzwingen mit --profile-type cobaltstrike oder --profile-type sliver.
Bei einem Profil-File extrahiert das Skript:
--server-name angibst)set host_stage)Dann erstellt es eine Caddyfile, die:
.env, /wp-admin, .php usw.)pip install erforderlich)python3 caddysmith.py my.profile \
--backend https://teamserver.internal:443 \
--decoy https://www.example.com/ \
--server-name redirector.example.com \
--email [email protected] \
--forbid-http \
-o redirector.caddy
Dies schreibt die generierte Konfiguration in redirector.caddy und gibt eine Zusammenfassung der Aktionen auf stderr aus.
Kopiere die generierte Datei auf den Redirector und führe Caddy damit aus. Du benötigst das Flag --adapter caddyfile, weil Caddy standardmäßig JSON-Konfiguration erwartet:
caddy run --config /etc/caddy/redirector.caddy --adapter caddyfile
Um eine laufende Instanz mit einer aktualisierten Konfiguration neu zu laden:
caddy reload --config /etc/caddy/redirector.caddy --adapter caddyfile
Wenn Caddy über Formatierungsinkonsistenzen warnt, bereinige sie mit:
caddy fmt --overwrite /etc/caddy/redirector.caddy
Lege die Datei in /etc/caddy/ ab und importiere sie aus deiner Haupt-Caddyfile:
# /etc/caddy/Caddyfile
import /etc/caddy/redirector.caddy
Wenn du --email angegeben hast (empfohlen), enthält der generierte Code bereits den globalen Optionsblock, sodass die Haupt-Caddyfile nur die import-Zeile benötigt. Wenn nicht, füge die E-Mail manuell in einem { }-Block oberhalb des Imports ein.
Dann validieren und neu laden:
sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy
Caddy stellt automatisch ein Let's-Encrypt-Zertifikat für die Domain in --server-name bereit, solange der A-Record auf den Redirector zeigt.
| Flag | Standard | Beschreibung |
|---|---|---|
profile | (erforderlich) | Pfad zur .profile-Datei |
--backend | https://teamserver.local:443 | Wohin passender Traffic weitergeleitet wird |
--decoy | https://www.example.com/ | Wohin nicht-passender Traffic umgeleitet wird |
--server-name | c2.example.com | Domain-Name deines Redirectors |
--policy | strict | strict, lax oder none |
--profile-type | auto | Erzwinge cobaltstrike oder sliver (Standard: automatisch) |
--extra-uri PATH | — | Zusätzlicher URI zum Proxying (mit UA-Prüfung). Wiederholbar. |
--lax-uri PATH | — | Zusätzlicher URI zum Proxying (ohne Prüfung). Wiederholbar. |
--allow-ua STRING | — | Zusätzlicher erlaubter User-Agent für --extra-uri-Routen. Wiederholbar. |
--forbid-http | aus | Gib 403 bei unverschlüsseltem HTTP zurück |
--email EMAIL | — | E-Mail für Let's-Encrypt-Registrierung und Verlängerungshinweise |
-o, --output FILE | stdout | Schreibe die Konfiguration in eine Datei |
Strict ist das, was du normalerweise willst. Lax ist nützlich, wenn du debuggen willst, warum ein echter Beacon sich nicht verbindet.
Angenommen, du hast ein Profil, das einen Amazon-Endpunkt imitiert, und du möchtest es auf redirector.0xtb.sh bereitstellen:
python3 caddysmith.py amazon.profile \
--backend https://10.1.1.10:443 \
--decoy https://www.amazon.com/ \
--server-name redirector.0xtb.sh \
--forbid-http \
--policy strict \
-o /etc/caddy/redirector.caddy
Die Zusammenfassung zeigt dir genau, welche Routen erstellt wurden, z.B.:
Routes built: 2
- [profile-get] /broadcast
- [profile-post] /1/events/com.amazon.csm.csa.prod
Wenn du neu generierst und keine Routen siehst, hat das Skript dein Profil wahrscheinlich nicht analysieren können – überprüfe die Warnungen auf stderr.
Für eine Sliver-Implantat-Konfiguration (JSON):
python3 caddysmith.py sliver-implant.json \
--backend https://10.1.1.10:443 \
--decoy https://www.amazon.com/ \
--server-name redirector.0xtb.sh \
--email [email protected] \
--forbid-http \
--policy strict \
-o /etc/caddy/redirector.caddy
Die Zusammenfassung teilt dir mit, dass Sliver erkannt wurde, und zeigt die Präfix-Route:
Profile type: sliver
Routes built: 1
- [sliver] /api /public /resources /services /static (prefix)
Da Sliver URIs zufällig aus Pfad × Datei × Erweiterung generiert, verwendet der generierte path-Matcher Präfix-Globs (path /api* /public* /resources* /services* /static*) anstelle exakter Pfade. Der User-Agent-Matcher verwendet einen Substring der Chrome-Build-Nummer (z.B. 3921.146), den Sliver über seine plattformabhängigen UA-Umschreibungen hinweg beibehält.
# Unverschlüsseltes HTTP sollte 403 zurückgeben (wenn du --forbid-http verwendet hast)
curl -I http://redirector.0xtb.sh/
# Bloßer Hostname sollte zur Köder-URL umleiten
curl -kI https://redirector.0xtb.sh/
# Böser User-Agent sollte ebenfalls umleiten
curl -kI -A "curl/8.4.0" https://redirector.0xtb.sh/broadcast
# Eine Anfrage mit dem richtigen UA + Pfad sollte durchproxyt werden (200)
# Du musst im strict-Modus auch alle Client-Header des Profils mitsenden.
set host_stage "true" hat (oder gar nicht setzt), warnt das Skript und überspringt Stager-URIs. Füge set host_stage "false"; zu deinem Profil hinzu oder gib die Stager-URIs explizit über --extra-uri an./api, /static usw. beginnt. Scanner-Sonden, die zufällig diese Präfixe verwenden (z.B. /api/.env), werden an den Team-Server gesendet, anstatt lokal blockiert zu werden – aber Slivers eigener HTTP-Transport authentifiziert über die Implantat-ID, sodass nicht autorisierte Anfragen auf der C2-Ebene abgewiesen werden. Die UA-Absicherung hält dennoch die meisten Scanner fern.--backend weiter. Wenn du mehrere Team-Server benötigst, führe das Skript mehrmals aus und führe die Ergebnisse manuell zusammen.set uri "/path1 /path2"; funktioniert (mehrere Pfade in einer Zeile), aber ungewöhnliche Formatierung könnte den Parser stören. Überprüfe die Routenliste in der Zusammenfassung zur Bestätigung.tls_insecure_skip_verify. Wenn dein Backend ein echtes Zertifikat hat, lösche diese Zeile aus der generierten Datei.Der Apache-basierte Malleable-Redirector war der Ausgangspunkt für das, was dieses Skript generiert: dasselbe Drei-Pfad-URI-Modell (Profil-URIs / Extra-URIs / Lax-URIs), dieselben Policy-Modi, dasselbe allgemeine Layout. CaddySmith übersetzt die Ausgabe lediglich in die Caddy-Syntax anstelle von Apache .htaccess.
MIT