Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
WEASEL — DNS-Covert-Channel-Implantat für Red Teams. | Kitploit
Tools/GitHubGitHub/facebookarchive/weasel
Verschlüsselungs-/EntschlüsselungstoolsPersistenzmechanismenPost-ExploitationPenetrationstestsCommand and ControlRed TeamingPayload-EntwicklungDNS-AnalyseArchived
GitHubfacebookarchive/weasel

WEASEL

DNS-Covert-Channel-Implantat für Red Teams.

73166vor 6 JahrenVon Kitploit geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen
Repository anzeigen

WEASEL: Ein leises DNS-Backdoor

WEASEL ist ein kleiner In-Memory-Implant, der Python 3 ohne Abhängigkeiten nutzt. Der Beacon-Client sendet eine kleine Menge identifizierender Informationen über seinen Host an eine DNS-Zone, die Sie kontrollieren. Der WEASEL-Server kann Clients beauftragen, vorgefertigte oder beliebige Befehle auszuführen.

WEASEL ist ein Stage-1-Payload, das schwer zu erkennen sein soll und nützlich ist, um wieder Zugriff zu erlangen, wenn Ihre lauten, vollwertigen Stages entdeckt wurden.

Status

  • Wurde bereits erfolgreich in einem Einsatz verwendet und hat Detektionen umgangen.
  • Client kann eine Sitzung mit dem Server aufbauen und eine bidirektionale Kommunikation herstellen.
  • Der Server verfügt über ein voll funktionsfähiges CLI.
  • Der Client unterstützt eine Reihe von Funktionen, die der Server beauftragen kann.
  • Der Client ist nach Minifizierung + Obfuskation 5,2 KB groß.
  • Die automatische Obfuskation ist mangelhaft und erfordert manuelle Nachbesserungen (siehe Einschränkungen im Client-README).
  • Der Server unterstützt kein Multi-Player (gleichzeitige Bedienung durch mehrere Operateure).

Beispiele

Siehe die Nutzung im Client-README und Server-README für spezifische Anweisungen.

Um den Server oder Client zu starten, führen Sie die Skripte direkt aus oder übergeben Sie sie dem Python-Interpreter.

Stellen Sie sicher, dass die C2-Domänen jeweils einen NS-Eintrag mit der IP-Adresse des Hosts haben, auf dem server.py ausgeführt wird.

Voraussetzungen

WEASEL benötigt Python 3.6+.

Der Client ist eigenständig und verwendet nur Standardbibliotheken, daher kann er auf macOS, Linux usw. ausgeführt werden.

Der Server hat einige Abhängigkeiten von pip, die in server/requirements.txt enthalten sind. Der Server sollte unter Linux ausgeführt werden, aber es spricht nichts dagegen, ihn unter macOS oder anderen *nix-Systemen zu betreiben.

Testen / Ausführen in der Entwicklung

Es ist in diesem Fall nicht nötig, den Beacon zu obfuskatieren und zu minimieren. Print-Anweisungen bleiben erhalten. Wie unter „Verwendung“ oben, stellen Sie sicher, dass NS-Einträge für die Domäne(n) in servers in beacon.py auf die IP-Adresse von server.py zeigen.

Auf dem Server-Host:

sudo python3 server.py

Auf dem Opfer-Host (kann derselbe wie der Server sein):

python3 beacon.py

Architektur

Sie müssen nichts davon verstehen, um WEASEL zu nutzen.

Beacon kommuniziert über DNS mit AAAA-Anfragen und -Antworten. Es verwendet keine TXT-Einträge, da diese dafür bekannt sind, von DNS-Malware und -Tunnel genutzt zu werden. Blue Teams haben oft DNS-Tunnel-Erkennungen, die bei großen TXT-Anfragen alarmieren.

Die Client-Seite benötigt keine Root-Rechte, verwendet keine Raw-Sockets und erstellt keine fehlerhaften DNS-Pakete. Es werden reguläre, vom System und der Sprache bereitgestellte Schnittstellen für DNS-Anfragen verwendet. Die Informationen sind in den Einträgen selbst kodiert + verschlüsselt.

  • Ein einzelner A-Eintrag (IPv4-Adresse) kann 4 Byte Informationen enthalten.
  • Ein einzelner AAAA-Eintrag (IPv6-Adresse) kann 16 Byte Informationen enthalten.
  • CNAME-Einträge und Hostnamen, die in Anfragen verwendet werden, können bis zu 64 Byte pro Subdomain enthalten und sollten laut RFC nicht länger als 255 Byte insgesamt sein. Die SANS-Richtlinien zur DNS-Erkennung besagen jedoch, dass Subdomains länger als 52 Zeichen verdächtig sind. Aus diesem Grund begrenzen wir Subdomains auf 52 Zeichen (im Code konfigurierbar) und versuchen, so wenige Subdomains und Anfragen wie nötig zu verwenden.
  • Eine Antwort kann mehrere Einträge enthalten, bis zur Größenbegrenzung eines UDP-Datagramms (65.507 Byte).

Dieser Beacon ist als langsam und leise mit geringer Bandbreite konzipiert. Er soll uns mitteilen, auf welchen Hosts er sich befindet, und uns eine Möglichkeit geben, bei Bedarf weitere Stages zu starten – und nicht mehr. Obwohl er beliebige Befehle unterstützt, ist er nicht als reguläre interaktive Shell oder Kommunikationskanal gedacht.

WEASEL ist eine Stage 1, die Sie laufen lassen, um dauerhaften Zugriff zu gewährleisten, während Ihre vollwertigen (und daher lauteren) Stages entdeckt werden.

Persistenz

WEASEL war ursprünglich für Server mit hoher Betriebszeit gedacht, bei denen wir einen zuverlässigen Fußpunkt/Ausnutzungsvektor hatten. Die Umgehung forensischer Untersuchungen hatte hohe Priorität. Daher verfügt es über keine nativen Persistenzfunktionen.

Sie können es persistent machen, indem Sie seine Ausführung zu Ihrer bevorzugten Persistenztechnik hinzufügen – dies bleibt dem Leser als Übung überlassen :)

Protokoll und Nachrichtenformat

Client-Anfrage

Eine Anfrage (vom Client) ist eine einzelne AAAA-Abfrage für einen Namen, der wie folgt formatiert ist:

<Präambel><Daten>.<Stream>.<Sitzung>.domain.tld

Die Präambel ist 2 Byte lang. Präambel[0] ist die Sequenznummer dieses Pakets. Präambel[1] ist die Gesamtanzahl der Pakete in diesem Stream.

Daten sind auf 50 Byte (konfigurierbar) begrenzt und enthalten die Nutzlast. Die Nutzlast ist mit einem benutzerdefinierten Alphabet base32-kodiert.

Nutzlastkodierung

Zuerst werden alle 'w'-Zeichen durch '-' ersetzt.

Als nächstes wird das Padding-Zeichen von '=' zu 'w' geändert, um dem DNS-Zeichensatz [a-z0-9] und [-] zu entsprechen.

Wir ersetzen '=' nicht direkt durch '-', da das Padding immer am Ende der Zeichenkette steht und ein Hostname, der auf '---' endet, sowohl verdächtig als auch nicht RFC-konform ist. Auf diese Weise endet eine Zeichenkette mit Padding auf 'www', was weniger verdächtig und RFC-konform ist.

Server-Antwort

Eine Antwort (vom Server) besteht aus einem oder mehreren AAAA-Antworten.

Jede AAAA-Antwort ist eine 16 Byte lange verschlüsselte Nutzlast, die als IPv6-Adresse mit socket.inet_ntop dargestellt wird. Antworten in einer DNS-Antwort behalten ihre Reihenfolge während der Übertragung nicht bei, daher werden sie wie die Client-Anfragen sequenziert und wieder zusammengesetzt.

Die Transportnutzlast ist eine Zeichenkette von Datenelementen, die durch ein ^-Zeichen getrennt sind.

Transportformat

Anfragen und Antworten folgen diesem Format:

<Typ>|<Daten>

Sitzungen

Sitzungen sind langlebig: Ein Client initiiert eine Sitzung, wenn der Beacon zum ersten Mal ausgeführt wird, und diese Sitzung sollte für die gesamte Zeit bestehen bleiben, in der der Beacon auf diesem Client aktiv ist. Beachten Sie, dass die Sitzungsdaten, da der Beacon im Speicher und nicht persistent ist, im Speicher des Python-Prozesses gespeichert werden. Jeder neue Aufruf des Beacons initiiert eine neue Sitzung.

Die Initiierung einer Sitzung beinhaltet, dass der Client eine Nachricht mit einer eindeutig identifizierenden Nicht-Daten-Präambel erstellt (um dem Server zu signalisieren, dass dies eine neue Sitzung ist): die Verkettung eines 32 Byte langen Diffie-Hellman-öffentlichen Schlüssels und eines 16 Byte langen zufälligen AES-IV.

Der Server empfängt dies und antwortet mit seinem eigenen 32 Byte langen öffentlichen Schlüssel. An diesem Punkt haben Client und Server einen gemeinsamen Sitzungsschlüssel etabliert, der für die Lebensdauer dieser Sitzung verwendet wird, um Daten-Nutzlasten mit AES-128 im CTR-Modus zu verschlüsseln. Der ephemerale Diffie-Hellman-Austausch stellt sicher, dass jede Client-Server-Verbindung einen eindeutigen Sitzungsschlüssel mit perfekter Vorwärtssicherheit verwendet.

Verschlüsselungsmängel

Die Kryptographie ist aus mehreren Gründen absichtlich schlecht:

  • Wir ahmen echte Angreifer nach, die im Allgemeinen wenig Ahnung haben, wie man robuste Kryptosysteme baut, und gerne eigene entwickeln
  • Die Bandbreite des Beacons ist so gering wie möglich, daher muss unser DHE-Austausch sehr klein gehalten werden
  • Nicht-Zuschreibbarkeit ist wichtig; wir authentifizieren den Server nicht
  • Es macht für Responder weniger Spaß, wenn wir hochmoderne Kryptographie verwenden, die sie nicht zu knacken hoffen können

Hier sind einige bekannte Probleme mit dem Kryptoschema:

  1. Der Diffie-Hellman-Modul p ist RFC 3526 Group 5, abgeschnitten auf die ersten 32 Byte. Dies begrenzt nicht nur die öffentlichen und privaten Schlüssel auf 32 Byte, sondern Group 5 ist bereits veraltet und wird nicht mehr empfohlen. Ich nenne diese schlechte Entscheidung "Group 1".
  2. Wir verwenden random.randint() für den Exponenten a anstelle eines CSPRNG.
  3. Wir verwenden eine kleine Menge Daten von os.urandom() für die Sitzungs-ID und die Stream-ID-Generierung anstelle einer UUID, was Kollisionen wahrscheinlich macht. Wir gleichen dies aus, indem wir es erneut versuchen, bis wir eine ID erhalten, die nicht verwendet wird.
  4. Die AES-CTR-Chiffre wird für jeden Stream mit demselben IV (der genauso langlebig ist wie der Sitzungsschlüssel) neu initialisiert. Dies bedeutet, dass derselbe Klartext an derselben Position über verschiedene Streams hinweg denselben Chiffretext erzeugt.
  5. Bei AES-CTR wird der IV korrekt als Nonce bezeichnet, aber in unserer Implementierung verwenden wir die Zahl nicht nur einmal, daher wäre es etwas unhöflich, sie so zu nennen.

Streams

Jede zwischen einem Client und einem Server gesendete Nachricht muss in Pakete von maximal 50 Byte aufgeteilt werden, um unter der 52-Byte-Grenze für gängige DNS-Covert-Channel-Erkennungen zu bleiben. Alle Pakete für eine bestimmte Nachricht gehören zum selben Stream. Nachricht == Stream.

Streams werden mit einer 2 Byte großen zufälligen Hex-Zahl identifiziert. Erinnern Sie sich an das Format der Client-Anfrage: <Präambel><Daten>.<Stream>.<Sitzung>.domain.tld

Die 2 Byte große Präambel jedes Pakets im Stream enthält eine Sequenznummer und die Gesamtanzahl der Pakete in diesem Stream. Dies ermöglicht es dem Server zu wissen, wann alles angekommen ist.

Da dies alles über UDP erfolgt, das keine Garantien für die Reihenfolge des Eintreffens von Datagrammen bietet, muss WEASEL die Sequenzierung, Wiederzusammensetzung und Verfolgung mehrerer Streams von vielen Beacons berücksichtigen.

Jeder Stream initialisiert eine global gemeinsam genutzte AES-128-CTR-Chiffre neu, um Nutzlasten zu verschlüsseln/zu entschlüsseln.

Die Nutzlast kann erst entschlüsselt werden, wenn ein Stream vollständig ist (alle Pakete sind angekommen). Wenn es nicht base32 gäbe, könnten wir das, was wir von der Nachricht haben, auch dann entschlüsseln, wenn Pakete fehlen (da AES-CTR eine Stromchiffre ist), aber wir können keine partiellen Streams base32-dekodieren. Schade. Aufgrund der Natur von DNS-Clients werden Anfragen mehrmals (im Allgemeinen 2- oder 4-mal) gesendet, bis eine Antwort empfangen wird, sodass wir eine gute Wahrscheinlichkeit haben, alle Pakete in einem Stream zu empfangen, da jedes Paket vom Client mindestens zweimal gesendet werden sollte. Wenn wir Pakete oder Streams verlieren, ist das kein großes Problem; der Beacon wird sich später wieder melden und dann wahrscheinlich mehr Glück haben.

Treten Sie der WEASEL-Community bei

Siehe die Datei CONTRIBUTING für Informationen, wie Sie helfen können.

Lizenz

WEASEL ist unter der MIT-Lizenz lizenziert, wie in der Datei LICENSE zu finden.

Tool herunterladen
TypBedeutung (Absender)AKADaten
0BestätigtACKZufälliges Hex
1Checkt ein (Client)PINGZufälliges Hex
2Beende dich selbst (Server), Beende mich selbst (Client)FIN
3Initialisierungsnachricht (Client)SYNVersion|Hostname|Kernel
4Wieder verbinden (Server)RST
5Callback-Intervall setzen (Server)Sekunden
6Netzwerkschnittstellendaten abrufeneth0 1.2.3.4/24\neth1 fe80:::/64\n...
8Beliebigen Python3-Code bis 666 Byte ausführen (Server), die ersten 400 Byte der Ausgabe zurückgeben (Client)EVALPython3-One-Liner-Skript
9Beliebigen Befehl bis 666 Byte ausführen (Server), die ersten 400 Byte der Ausgabe zurückgeben (Client)EXECBash-Befehl