Cobalt Strike C2 Reverse Proxy, der Blue Teams, AVs, EDRs und Scanner durch Paketinspektion und malleable Profile Correlation abwehrt.
(zuvor bekannt als proxy2's malleable_redirector Plugin)
Lasst uns die Messlatte für die IR-Resilienz von C2-Redirectoren höher legen, oder?

Die Red-Teaming-Branche hat mehrere verschiedene großartige Ideen gesehen, wie man Incident Responder bekämpfen und in die Irre führen kann, während man gleichzeitig ein widerstandsfähiges Netzwerk von C2-Redirectoren anbietet.
Dieses Projekt vereint viele dieser großartigen Ideen in einem einzigen, leichten Dienstprogramm, das in seinen Ursprüngen Apache2 nachahmt, ein einfacher HTTP(S)-Reverse-Proxy zu sein.
Die Kombination aus Verständnis von Malleable-C2-Profilen, Kenntnis der IP-Adresspools von schlechten Adressen und der Flexibilität, problemlos neue Inspektions- und Fehlleitungslogik hinzuzufügen – führte zu einem raffinierten Abwehrmittel für IR-Inspektionen.

Sollte ein ungültiges eingehendes Paket RedWarden erreichen – Sie können es redirect, reset oder einfach wegleiten!
proxyDieses Programm fungiert als HTTP/HTTPS-Reverse-Proxy mit mehreren Einschränkungen für eingehende C2-HTTP-Anfragen, die auswählen, welche Pakete an den Teamserver weitergeleitet und welche verworfen werden, ähnlich den .htaccess-Dateibeschränkungen, die in Apache2s mod_rewrite auferlegt werden.
RedWarden wurde entwickelt, um das Problem der Umgehung von IR/AV/EDRs/Sandboxes auf der C2-Redirector-Ebene zu lösen. Es soll die klassischen Apache2- + mod_rewrite-Setups ablösen, die für diesen Zweck verwendet werden.
Funktionen:
Der RedWarden nimmt als Eingabe ein Malleable-C2-Profil und die hostname:port des Teamservers entgegen. Er analysiert dann die bereitgestellten Malleable-Profilabschnitte, um den Vertrag zu verstehen und nur jene eingehenden Anfragen durchzulassen, die ihn erfüllen, während andere in die Irre geleitet werden.
Abschnitte wie http-stager, http-get, http-post und die dazugehörigen URIs, Header, Prepend/Append-Muster, User-Agent werden alle verwendet, um zwischen legitimen Beacon-Anfragen und nicht zusammenhängendem Internet-Rauschen oder IR/AV/EDRs-Out-of-Bound-Paketen zu unterscheiden.
Das Programm profitiert von den wunderbaren bekannten IP-Bereichen, die stammen von: curi0usJack und den anderen: https://gist.github.com/curi0usJack/971385e8334e189d93a6cb4671238b10
Die Verwendung von IP-Adressen-Blacklisting zusammen mit einer Suche nach bekannten schlechten Schlüsselwörtern durch Reverse-IP-DNS-Abfragen und HTTP-Header-Inspektion erhöht die Zuverlässigkeit, um die Widerstandsfähigkeit des Redirectors gegenüber unbefugten Peers, die die Angreiferinfrastrukturen untersuchen wollen, erheblich zu steigern.
Ungültige Pakete können gemäß drei Strategien fehlgeleitet werden:
Diese Konfiguration wird in der Konfigurationsdatei festgelegt:```yaml
drop_action: redirect
Das folgende Beispiel zeigt das Ergebnis von `redirect` zu `https://googole.com`:

Nutze es weise, bleib sicher.
### Voraussetzungen
Dieses Programm kann nur auf Linux-Systemen ausgeführt werden, da es fork verwendet, um mehrere Prozesse zu erzeugen.
Außerdem wird erwartet, dass der Systembefehl `openssl` installiert ist, da er zur Generierung von SSL-Zertifikaten verwendet wird.
Installiere abschließend alle Python3-PIP-Anforderungen ganz einfach mit:```shell
bash $ sudo pip3 install -r requirements.txt
Die minimale Konfigurationsdatei config.yaml von RedWarden könnte enthalten:```yaml port:
profile: jquery-c2.3.14.profile
ssl_cacert: /etc/letsencrypt/live/attacker.com/fullchain.pem ssl_cakey: /etc/letsencrypt/live/attacker.com/privkey.pem
teamserver_url:
drop_action: reset
Dann kann das Programm gestartet werden, indem man ihm einen Pfad zur Konfigurationsdatei gibt:```shell
bash$ sudo python3 RedWarden.py -c config.yaml
[INFO] 19:21:42: Loading 1 plugin...
[INFO] 19:21:42: Plugin "malleable_redirector" has been installed.
[INFO] 19:21:42: Preparing SSL certificates and keys for https traffic interception...
[INFO] 19:21:42: Using provided CA key file: ca-cert/ca.key
[INFO] 19:21:42: Using provided CA certificate file: ca-cert/ca.crt
[INFO] 19:21:42: Using provided Certificate key: ca-cert/cert.key
[INFO] 19:21:42: Serving http proxy on: 0.0.0.0, port: 80...
[INFO] 19:21:42: Serving https proxy on: 0.0.0.0, port: 443...
[INFO] 19:21:42: [REQUEST] GET /jquery-3.3.1.min.js
[INFO] 19:21:42: == Valid malleable http-get request inbound.
[INFO] 19:21:42: Plugin redirected request from [code.jquery.com] to [1.2.3.4:8080]
[INFO] 19:21:42: [RESPONSE] HTTP 200 OK, length: 5543
[INFO] 19:21:45: [REQUEST] GET /jquery-3.3.1.min.js
[INFO] 19:21:45: == Valid malleable http-get request inbound.
[INFO] 19:21:45: Plugin redirected request from [code.jquery.com] to [1.2.3.4:8080]
[INFO] 19:21:45: [RESPONSE] HTTP 200 OK, length: 5543
[INFO] 19:21:46: [REQUEST] GET /
[...]
[ERROR] 19:24:46: [DROP, reason:1] inbound User-Agent differs from the one defined in C2 profile.
[...]
[INFO] 19:24:46: [RESPONSE] HTTP 301 Moved Permanently, length: 212
[INFO] 19:24:48: [REQUEST] GET /jquery-3.3.1.min.js
[INFO] 19:24:48: == Valid malleable http-get request inbound.
[INFO] 19:24:48: Plugin redirected request from [code.jquery.com] to [1.2.3.4:8080]
[...]
Die obige Ausgabe enthält eine Zeile, die darauf hinweist, dass es eine unbefugte, nicht mit unserem C2-Profil konforme eingehende Anfrage gab, die aufgrund einer inkompatiblen User-Agent-Zeichenfolge verworfen wurde:``` [...] [DROP, reason:1] inbound User-Agent differs from the one defined in C2 profile. [...]
## Anwendungsfälle
### IP-Geolokalisierung auf Ihre Beacon-Traffic-Ursprünge anwenden
Sie haben Ihr Pre-Phishing und OSINT sehr gut durchgeführt. Sie wissen jetzt, wo Ihre Ziele leben, und haben Hinweise darauf, woher der Traffic stammen sollte, oder zumindest, wie Sie vollständig zusätzlichen Verkehr erkennen können.
Wie kann man IP-Geolokalisierung für Beacon-Anfragen an einem Redirector erzwingen?
RedWarden hilft!
Nehmen wir an, Sie möchten nur Verkehr akzeptieren, der aus Polen, Europa, stammt.
Ihre Pre-Phish-/OSINT-Ergebnisse zeigen, dass:
- `89.64.64.150` ist eine legitime IP eines Ihrer Ziele, die aus Polen stammt
- `59.99.140.76` hingegen ist keine solche und erreichte Ihre Systeme als gewöhnliches Internet-Rauschpaket.
Sie können das RedWarden-Dienstprogramm `lib/ipLookupHelper.py` verwenden, um IP-Geo-Metadaten zu diesen beiden Adressen zu sammeln:```shell
bash$ python3 ipLookupHelper.py
Usage: ./ipLookupHelper.py <ipaddress> [malleable-redirector-config]
Use this small utility to collect IP Lookup details on your target IPv4 address and verify whether
your 'ip_geolocation_requirements' section of proxy2 malleable-redirector-config.yaml would match that
IP address. If second param is not given - no
Ersteres bringt:```shell bash$ python3 ipLookupHelper.py 89.64.64.150 [dbg] Following IP Lookup providers will be used: ['ip_api_com', 'ipapi_co'] [.] Lookup of: 89.64.64.150 [dbg] Calling IP Lookup provider: ipapi_co [dbg] Calling IP Lookup provider: ip_api_com [dbg] New IP lookup entry cached: 89.64.64.150 [.] Output: { "organization": [ "UPC Polska Sp. z o.o.", "UPC.pl", "AS6830 Liberty Global B.V." ], "continent": "Europe", "continent_code": "EU", "country": "Poland", "country_code": "PL", "ip": "89.64.64.150", "city": "Warsaw", "timezone": "Europe/Warsaw", "fulldata": { "status": "success", "country": "Poland", "countryCode": "PL", "region": "14", "regionName": "Mazovia", "city": "Warsaw", "zip": "00-202", "lat": 52.2484, "lon": 21.0026, "timezone": "Europe/Warsaw", "isp": "UPC.pl", "org": "UPC Polska Sp. z o.o.", "as": "AS6830 Liberty Global B.V.", "query": "89.64.64.150" }, "reverse_ip": "89-64-64-150.dynamic.chello.pl" }
und Letzteres ergibt:```shell
bash$ python3 ipLookupHelper.py 59.99.140.76
[dbg] Following IP Lookup providers will be used: ['ip_api_com', 'ipapi_co']
[dbg] Read 1 cached entries from file.
[.] Lookup of: 59.99.140.76
[dbg] Calling IP Lookup provider: ip_api_com
[dbg] New IP lookup entry cached: 59.99.140.76
[.] Output:
{
"organization": [
"",
"BSNL Internet",
"AS9829 National Internet Backbone"
],
"continent": "Asia",
"continent_code": "AS",
"country": "India",
"country_code": "IN",
"ip": "59.99.140.76",
"city": "Palakkad",
"timezone": "Asia/Kolkata",
"fulldata": {
"status": "success",
"country": "India",
"countryCode": "IN",
"region": "KL",
"regionName": "Kerala",
"city": "Palakkad",
"zip": "678001",
"lat": 10.7739,
"lon": 76.6487,
"timezone": "Asia/Kolkata",
"isp": "BSNL Internet",
"org": "",
"as": "AS9829 National Internet Backbone",
"query": "59.99.140.76"
},
"reverse_ip": ""
}
Jetzt sehen Sie, dass der erste "country": "Poland" hatte, während der zweite "country": "India". Mit diesem Wissen sind wir bereit, unsere Einschränkungen in Form eines umfangreichen YAML-Wörterbuchs zu entwickeln:```yaml
ip_geolocation_requirements:
organization:
continent:
continent_code:
country:
- Poland
- PL
- Polska
country_code:
city:
timezone:
Jeder Eintrag dieses Wörterbuchs akzeptiert reguläre Ausdrücke, die mit bestimmten IP-Geo-Metadaten der IP-Adresse des eingehenden Peers abgeglichen werden.
Wir verwenden drei Einträge in der `country`-Eigenschaft, um Anfragen zu erlauben, die einen der angegebenen Werte haben.
Wenn Sie das in Ihrer Konfiguration eingestellt haben, können Sie mit dem Dienstprogramm `ipLookupHelper`, das einen zweiten Parameter akzeptiert, überprüfen, ob eine andere IP-Adresse den IP-Geolokalisierungs-Diskriminator von RedWarden passieren würde:

Die letzte Zeile sagt Ihnen, ob das Paket blockiert oder akzeptiert wird.
Und das war's! Konfigurieren Sie Ihre IP-Geolokalisierungs-Einschränkungen weise und sicher, überprüfen Sie die RedWarden-Protokolle sorgfältig auf IP-Geo-bezogene DROP-Einträge und halten Sie Ihren C2-Verkehr sauber und ordentlich!
### Reparieren manipulierter Beacon-Anfragen
Falls Sie Zwischensysteme wie AWS Lambda oder CloudFlare als Ihre Domain-Fronting-/Redirectoren verwenden, sind Sie sicherlich schon auf eine Situation gestoßen, in der einige Ihrer Pakete nicht vom Teamserver akzeptiert werden konnten, da sie vom vereinbarten Malleable-Vertrag abwichen. War es ein manipulierter oder entfernter HTTP-Header, neu geordnete Cookies oder etwas anderes – ich wette, das hat Ihnen viele Stunden Ihres Lebens gekostet.
Um Probleme beim Einrichtungsprozess von C2-Kanälen und Manipulationen durch Zwischensysteme zu bekämpfen, bietet RedWarden die Möglichkeit, Beacon-Pakete zu reparieren.
Dies geschieht, indem überprüft wird, was das Malleable-Profil von einem Paket erwartet, und es können konfigurierte HTTP-Header gemäß den Anforderungen des Profils auf ihre vereinbarten Werte zurückgesetzt werden.
Betrachten Sie das folgende einfache Profil:```
http-get {
set uri "/api/abc";
client {
header "Accept-Encoding" "gzip, deflate";
metadata {
base64url;
netbios;
base64url;
parameter "auth";
}
}
...
Sie sehen dieses Accept-Encoding? Jede Beacon-Anfrage muss diesen Header und diesen Wert enthalten. Was passiert, wenn Ihr Beacon auf CloudFlare-Systeme trifft und diese eine Anfrage ausgeben, die von diesem Header befreit wird oder stattdessen Accept-Encoding: gzip hat? Teamserver wird die Anfrage sofort ablehnen.
Indem Sie diesen Header im RedWarden-Konfigurationsabschnitt namens repair_these_headers setzen, können Sie Ihre Verbindung sichern.:```yaml
repair_these_headers:
### Problembehaftete Antwort-Header entfernen
Mit Cobalt Strike 4.7+ ist mir aufgefallen, dass der Teamserver den Content-Encoding-Header automatisch und ohne Benachrichtigung entfernt, wodurch unser malleable `http-(get|post).server`-Vertrag verletzt wird.
Da RedWarden dem Vertrag folgte, hat Beacon entweder Antworten verworfen oder sie falsch dekomprimiert.
Diese Option gibt an, welche Header aus Teamserver-Antworten entfernt werden sollen, bevor sie den Beacon-Prozess erreichen:```yaml
remove_these_response_headers:
- Content-Encoding
RedWarden entfernt nun standardmäßig den Content-Encoding-Header aus Teamserver-Antworten, um die Kompatibilität mit CS4.7+ Versionen zu gewährleisten.
Schauen wir uns die Ausgabe an, die der Proxy erzeugt.
Mit der Option verbose: True wird die Ausführlichkeit auf INFO gesetzt, die maximal akzeptierte Anfragen von abgelehnten unterscheidet.
Die Anfrage kann akzeptiert werden, wenn sie alle Kriterien erfüllt, die in der RedWarden-Konfigurationsdatei konfiguriert sind. Eine solche Situation wird mit einem [ALLOW, ...]-Eintrag im Log protokolliert:```
[INFO] 2021-04-24/17:30:48: [REQUEST] GET /js/scripts.js
[INFO] 2021-04-24/17:30:48: == Valid malleable http-get (variant: default) request inbound.
[INFO] 2021-04-24/17:30:48: [ALLOW, 2021-04-24/19:30:48, 111.222.223.224] "/js/scripts.js" - UA: "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"
[INFO] 2021-04-24/17:30:48: Connected peer sent 2 valid http-get and 0 valid http-post requests so far, out of 15/5 required to consider him temporarily trusted
[INFO] 2021-04-24/17:30:48: Plugin redirected request from [attacker.com] to [127.0.0.1:5555]
Sollte die Anfrage bei einer der Prüfungen, die RedWarden bei jeder Anfrage durchführt, fehlschlagen, wird die entsprechende `[DROP, ...]`-Zeile ausgegeben, die Informationen über den **Grund** des Drops enthält.:```
[INFO] 2021-04-24/16:48:28: [REQUEST] GET /
[ERROR] 2021-04-24/16:48:29: [DROP, 2021-04-24/18:48:28, reason:1, 128.14.211.186] inbound User-Agent differs from the one defined in C2 profile.
[INFO] 2021-04-24/16:48:29: [DROP, 2021-04-24/18:48:28, 128.14.211.186] "/" - UA: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36"
[ERROR] 2021-04-24/16:48:29: [REDIRECTING invalid request from 128.14.211.186 (zl-dal-us-gp3-wk107.internet-census.org)] GET /
Es gibt viele Gründe, die darüber entscheiden, ob eine Anfrage abgewiesen werden kann. Jede dieser Prüfungen kann je nach Anforderungen oder im Rahmen der Feinabstimmung oder Korrektur fehlerhafter Entscheidungen unabhängig ein- oder ausgeschaltet werden:
Auszug aus example-config.yaml:```yaml
policy:
allow_proxy_pass: True
allow_dynamic_peer_whitelisting: True
drop_invalid_useragent: True
drop_http_banned_header_names: True
drop_http_banned_header_value: True
drop_dangerous_ip_reverse_lookup: True
drop_ipgeo_metadata_containing_banned_keywords: True
drop_malleable_without_expected_header: True
drop_malleable_without_expected_header_value: True
drop_malleable_without_expected_request_section: True
drop_malleable_without_request_section_in_uri: True
drop_malleable_without_prepend_pattern: True
drop_malleable_without_apppend_pattern: True
drop_malleable_unknown_uris: True
drop_malleable_with_invalid_uri_append: True
Standardmäßig werden all diese Prüfungen durchgesetzt.
Die Aktivierung von `debug: True` wird Ihren Konsolenpuffer mit vielen Logzeilen überfluten, die jeden Schritt beschreiben, den RedWarden in seinem komplexen Entscheidungsprozess durchläuft.
Wenn Sie die vollständigen Körper Ihrer Anfragen und Antworten sehen möchten - setzen Sie `debug` und `trace` auf true und lassen Sie sich in der Logflut begraben!
## FAQ
**- Kann dieses Programm ohne Malleable Profile laufen?**
Ja, das kann es. Die Anfrageprüfungslogik wird jedoch deaktiviert, der Rest sollte einwandfrei funktionieren: IP-Geolokalisierungsdurchsetzung, Reverse-Lookup-Logik, Liste gesperrter IPs usw.
**- Kann dieses Programm leicht an andere C2-Frameworks angepasst werden? Wie Mythic, Covenant, etc?**
Einfach nein. Mit etwas Aufwand - ja. Wie ich unten beschrieben habe, ist das Tool schlecht geschrieben, was die Anpassung an andere C2s schmerzhaft macht. Das ist jedoch mit etwas Zeit und Mühe durchaus machbar.
**- Meine Pakete werden verworfen. Warum?**
Versuchen Sie, `debug: True` und `trace: True` zu aktivieren, um so viele Logs wie möglich zu sammeln. Dann müssten Sie die Logs durchgehen und prüfen, was los ist. Sehen die Pakete genau so aus, wie Sie es in Ihrem Malleable-Profil erwartet haben? Oder gab es vielleicht eine subtile Manipulation im Netzwerk, die dazu führt, dass RedWarden das Paket verwirft (und es könnte auch den Teamserver dazu bringen, es zu verwerfen?).
## Known Issues
- Es _kann_ einen leichten Overhead beim interaktiven Schlafdurchsatz verursachen
- Die ProxyPass-Verarbeitungslogik ist weit davon entfernt, perfekt zu sein, und ist _wirklich_ fehlerhaft (und oh Junge, sie ist hässlich!).
- Seltsame Formen von Konfigurationsdateien können den RedWarden-Parser aus der Bahn werfen und ihn zum Meckern bringen. Der einfachste Ansatz, dies zu umgehen, wäre, `example-config.yaml` zu kopieren und stattdessen daran zu arbeiten.
## Oh mein Gott, warum ist dieser Code so ein technisches Stück Scheiße?
Der Code ist _EIN VERDAMMT GROßES CHAOS_ - das gebe ich zu - und dafür gibt es auch einen ehrlichen Grund: Das Projekt wurde zu 90 % während echter Red-Team-Einsätze entwickelt. Wie wir alle wissen, bringen solche Einsätze so viele Dinge mit sich, dass kaum Zeit für eine ordentliche Entwicklung komplexer Tools bleibt. Ganz zu schweigen von der Kritikalität dieses Programms im Projektaufbau. Das Tool begann ursprünglich als einfaches Proxy-Skript in Python2, entwickelte sich dann zu einem Proxy mit Plugins, erhielt das Plugin `malleable_redirector` - und seitdem habe ich wirklich hart daran gearbeitet, die Abwärtskompatibilität von `proxy2` mit anderen Plugins, die ich dafür erstellt habe, zu erhalten (armer ich, ich war wie Microsoft!) und an seinem ursprünglichen Zweck festzuhalten.
Die Zeit ist jedoch gekommen, es loszulassen, neu zu brandmarken und damit zu beginnen, all die eingeführten schlechten Code-Riecher zu beheben.
Nach all dem gesagten, bitte zeigen Sie etwas Mitgefühl für mich, wenn Sie Probleme melden, Pull-Requests einreichen, und versuchen Sie zu helfen, anstatt zu urteilen! :-) Danke!
## TODO
- Erforschung der Möglichkeit, Threat Intelligence Feeds für schändliche Zwecke zu nutzen - wie zum Beispiel die Erkennung von Sicherheitsanbietern anhand von IPs
- Unterstützung für MaxMind GeoIP-Datenbank/API hinzufügen
- Implementierung von Unterstützung für JA3-Signaturen sowohl bei Erkennung & Blockierung als auch bei Identitätswechsel, um nginx/Apache2/benutzerdefinierte Setups vorzutäuschen.
- Hinzufügen einer eindeutigen Beacon-Tracking-Logik, um die Flexibilität zu bieten, Staging- und Kommunikationsprozesse nach eigenem Ermessen des Proxys zu verweigern.
- Einführung von Tageszeitbeschränkungen bei der Bereitstellung von Weiterleitungsfunktionen (_Proxy nur während der Geschäftszeiten_)
- Proxy-Authentifizierungs- und Autorisierungslogik für CONNECT/Relay hinzufügen.
- Gezielte Weiterleitung für mobile Benutzer hinzufügen
- Konfigurationsoptionen hinzufügen, um benutzerdefinierte HTTP-Header zu definieren, die eingefügt oder entfernt werden sollen
- Konfigurationsoptionen hinzufügen, um das Vorhandensein bestimmter HTTP-Header in Anfragen zu verlangen, die die ProxyPass-Kriterien erfüllen.
- Interaktive Schnittstelle, die es erlaubt, einfache Zeichen einzugeben, die die Ausgabe-Logging-Ausführlichkeit steuern, ähnlich wie bei Nmap
- Die Parserlogik für Malleable-Profile mit [pyMalleableC2](https://github.com/Porchetta-Industries/pyMalleableC2) umschreiben. Als ich anfing, meine eigene Parserlogik zu programmieren, gab es ein solches Toolkit noch nicht auf Github.
- Die gesamte Codebasis umstrukturieren
---
### ☕ Show Support ☕
Dieses und andere Projekte sind das Ergebnis schlafloser Nächte und **viel harter Arbeit**. Wenn Ihnen gefällt, was ich tue, und Sie schätzen, dass ich immer etwas an die Gemeinschaft zurückgebe, [überlegen Sie, mir einen Kaffee zu kaufen](https://github.com/sponsors/mgeeky) _(oder besser ein Bier)_, um einfach Danke zu sagen! 💪
---
## Author```
Mariusz Banach / mgeeky, '19-'21
<mb [at] binary-offensive.com>
(https://github.com/mgeeky)