Your First Payload
Writing a successful payload is a process of continuously researching, writing, encoding, testing and optimizing. Often times a payload involves re-writing the ducky script, encoding the inject.bin and deploying the payload on a test machine several times until the desired result is achieved. For this reason it’s important to become familiar with the payload development process and and encoding tools.
Let’s begin by defining our objective. In this example, we’ll assume that steps 0-2 (pre-engagement interactions, reconnaissance and targeting) have resulted in an objective of: Type the historic “Hello World” words into the Windows notepad program. How devious!
If our payload is to type “Hello World” into Windows notepad, we must first figure out the best way to open that program using just the keyboard. On Windows there are a variety of ways to open notepad. On modern versions one may press the GUI or Windows key and begin typing “notepad” and pressing enter.
While this may suffice, our objective hasn’t specified the version we’re targeting – so we’ll want to use a technique with the widest possible support. Older versions of Windows don’t include the ability to search programs from the start menu just by typing. All versions since Windows 95 however include the keyboard combination Win+R. This powerful shortcut opens the Windows Run dialog, which states “Type the name of a program, folder, document or Internet resource, and Windows will open it for you.”
Since notepad.exe resides in c:\windows by default, we could simple type “c:\windows\notepad.exe” then press enter and notepad would open. On most machines it only takes a brief moment for the small program to open, and when it does it will be the active window. Keep this in mind, because we will always be typing into the active window, and anytime we change a GUI element we must wait for the computer to respond. It may seem like notepad opens instantly to us humans, but to a computerized keyboard that types over 9000 characters per minute, that millisecond counts.
Finally, with notepad open we should be able to simple type the words “Hello World”.
From our target test machine, be it a Windows Virtual Machine or bare metal, test this theory by manually entering in what we’ll later instruct the USB Rubber Ducky payload to type. Does it work? Great! Let’s move on to writing the ducky script.
Since ducky script can be written in any standard ASCII text editor, open your favorite – be it gedit, nano, vi, emacs, or even notepad (how ironic in this case?). Don’t worry – I won’t judge you for using vim.
We’ll begin our payload with a remark, a comment stating what the payload does, it’s intended target and the author. This won’t be processed by our duck encoder later on, but it will be helpful if we ever share this payload with the community.
REM Type Hello World into Windows notepad. Target: Windows 95 and beyond. Author: Darren
Our next line should delay for at least one full second. The purpose of this delay is to allow the target computer to enumerate the USB Rubber Ducky as a keyboard and load the generic HID keyboard drivers. On much older machines, consider a slightly longer delay. In my experience no more than three seconds are necessary. This delay is important since the USB Rubber Ducky has the capability of injecting keystrokes as soon as it receives power from the bus, and while USB is capable of receiving the keystroke frames, the operating system may not be ready to process them. Try plugging in a USB keyboard into any computer while jamming on the keys and you’ll notice a moment is necessary before any interaction begins.
Next we’ll issue our favorite keyboard combination, Windows key + R to bring up the Run dialog.
Typically the Run dialog appears near instantly to us humans, however to a USB Rubber Ducky with a clock speed of 60,000 cycles per second, that instant is an eternity. For this reason we’ll need to issue a short delay – perhaps just one tenth of a second.
Now with the Run dialog as the active window we’re ready to type our notepad command.
The STRING command processes the following characters case sensitive. Meaning STRING C will type a capital letter C. Obviously our keyboards don’t have separate keys for lowercase and capital letters, so our payload actually interprets this as a combination of both the SHIFT key and the letter c – just as you, the human, type. It’s nice to know that the STRING command handles this for you. It does not however end each line of text with a carriage return or enter key, so for that we’ll need to explicitly specify the key.
As before whenever a GUI element changes we’ll need to wait, albeit briefly, for the window to appear and take focus as the active window. Depending on the speed of the computer and the complexity of the program we’ll want to adjust the delay accordingly. In this example we’ll be extremely conservative and wait for a full second before typing.
Finally with notepad open and set as our active window we can finish off our ducky script with the historic words.
STRING Hello World
At this point our text file should look like the following:
REM Type Hello World into Windows notepad. Target: Windows 95 and beyond. Author: Darren DELAY 1000 GUI r DELAY 100 STRING c:\windows\notepad.exe ENTER DELAY 1000 STRING Hello World
Save this text file as helloworld.txt in the same directory as the duck encoder.
While ducky script is a simple, human readable format easily modified and shared, it isn’t actually processed by the USB Rubber Ducky. Rather, the inject.bin is derived from it using an encoder. Being an open source project, there are many encoders available on most platform from a range of programming languages. There are even online encoders which will convert your ducky script to an inject.bin without installing any software. This section will cover the basics of encoding a ducky script into an inject.bin file ready for deployment on the USB Rubber Ducky.
There are two primary ways to encode Ducky Script, either with the Java command line encoder, or the JS Ducky Encoder.
JS Ducky Encoder
This is the best way to get started encoding ducky script as it will work on most modern operating systems and browsers without the need for additional command line tools.
Java Based Command Line Encoder
For advanced users, or those wishing to incorporate the encoder into a script or existing workflow, the java command line encoder may be ideal.
The standard encoder is a cross-platform java command line tool. It has been greatly enhanced by the community, with many contributions from user midnitesnake. Download it from the resources section of usbrubberducky.com and save it in a convenient directory along with your helloworld.txt ducky script from the previous step. The Java runtime environment is required in order to run the duckencoder.jar file. If Java isn’t already installed, it can be found for most operating systems from java.com/download.
From a command prompt, navigate to this directory and run the jar file with java.
java -jar duckencoder.jar
The usage, arguments and script commands will display. The standard usage is to specify an input file, and output file and optionally a language. Encode the helloworld.txt into an inject.bin with the following:
java -jar duckencoder.jar -i helloworld.txt -o inject.bin
With the ducky script encoded into an inject.bin file, we’re ready to test the payload. Copy the inject.bin file to the root of the Micro SD card. Insert the Micro SD card into the USB Rubber Ducky. Now sneak up to the target test machine and plug in the USB Rubber Ducky.
The first time you ever plug the USB Rubber Ducky into a computer it will take a moment, typically just a second, to enumerate it as a HID keyboard and load the generic drivers. For this reason we’ve added a one second delay to the beginning of our payload. If the test is not successful on the first attempt, it may be because the target test machine has not yet successfully loaded the generic keyboard drivers. To replay the payload, press the button or unplug and replug the USB Rubber Ducky. This test payload should be successful against all recent version of Windows.
If the test were unsuccessful, note where things went awry and tweak the ducky script accordingly. Re-encode the inject.bin file, copy it to the Micro SD card (replacing the current file) and re-test.
Lather, rinse, repeat as necessary.
With our Hello World payload successfully running against our target test machine, we’re ready to optimize, and optionally obfuscate. This process is covered in greater detail later. Suffice it to say, in this example we can speed up the payload by reducing the number of keystrokes quite easily. Since notepad is an executable we may omit the .exe part of the STRING command. Likewise, since notepad by default resides in a path directory (c:\windows\) we can also omit this part of the STRING command as well. Our new STRING command should be the following:
At this point we’ve successfully researched, written, encoded, tested and optimized our simple “Hello World” payload. It’s now ready for deployment! Go forth and duck ‘em!