As is the go-to first project for any new language, your first introduction to DuckyScript will be a classic "Hello, World!" program. This lab will walk you through writing the program in the DuckyScript language, compiling it with Hak5's PayloadStudio, and arming the compiled binary onto a USB Rubber Ducky.

Part 1 - Writing, Compiling, & Arming

Writing

Once you know what steps your payload should take and your ready to begin writing it, you'll want to open either a text editor like Notepad, or Hak5's dedicated IDE and compiler, PayloadStudio.

Hak5 Payload Studio can be accessed online at https://payloadstudio.hak5.org/, once prompted to log in, click "Try Community Edition" to access the free version.

It is customary to start your payload with a declaration of the payload name, author, and a description. These lines are prepended with the REM keyword, short for remark, to denote the line as a comment.

Open a new file and start your payload by typing the header. Be sure to use your own name and provide a meaningful description.

REM Title: 
REM Author: 
REM Description:

Next, add the command to type the message, "Hello, World!" The STRING command takes a single string and will inject the necessary keystrokes to type it. This will automatically account for any capital letters or special characters by including a holding of the shift key while typing them.

With this change, your code should look like the following:

REM Title: Lab 0 - "Hello, World!"
REM Author: Victor E. Viking
REM Description: Types the string "Hello, World!" upon being plugged in.

STRING Hello, World!

Next, to make it easier to re-arm the Rubber Ducky after the script's execution without needing to take it apart, make it act as a USB Mass Storage device after execution has finished. The USB Rubber Ducky has 4 attack modes that can be set via the ATTACKMODE command:

With this change, your code shold look like the following:

REM Title: Lab 0 - "Hello, World!"
REM Author: Victor E. Viking
REM Description: Types the string "Hello, World!" upon being plugged in, then mount as a Mass Storage device.

STRING Hello, World!

REM Switch it to mount as a mass storage device after execution is finished.
ATTACKMODE STORAGE

Compiling

Once your payload is written, if necessary, paste or open your code in Hak5 Payload Studio (https://payloadstudio.hak5.org/) and click the "Generate Payload" button to compile.

If your code compiles successfully you will be given a button to download the compiled binary, inject.bin, along with a timestamp of its compellation and a checksum.

If the compellation fails, you will get a notice that "payload.txt failed to compile" and a console reporting any errors that occurred in compellation. If necessary, review these errors and correct your code as needed.

Click the button to download your inject.bin

Arming

To make the Rubber Ducky follow the instructions you wrote in your payload, you must place the compiled binary, inject.bin, at the root of the Rubber Ducky's MicroSD Card's file system.

If your Rubber Ducky is configured with a payload that exposes the MicroSD's storage via ATTACKMODE STORAGE, you may be able to simply plug in the USB Rubber Ducky. If the Rubber Ducky is not configured to use ATTACKMODE STORAGE, or is programed to preform some other actions you don't want to preform you'll need to remove the device from it's casing to access the MicroSD Card.

To open the Rubber Ducky's Casing, first remove the metal swivel by spreading it wider than the notches on the case. Now, squeeze the top of the case, near the USB Type-C connector and, using your fingernail, separate the two halves from the gap formed by squeezing the casing.

With it open, remove the MicroSD card by pushing up on it from the gap at the bottom of the MicroSD.

Connect the MicroSD Card to your computer using an adapter if necessary.

Once you have access to the MicroSD Card's filesystem, simply copy or move the compiled binary, inject.bin, to its root. In order to be read, it must be a valid DuckyScript binary and must be named `inject.bin.

With the file on the MicroSD, eject it from the computer and, if necessary, insert the MicroSD Card back into the Rubber Ducky and reassemble its casing if convenient. Your Rubber Ducky should be armed with your payload and should run it upon being plugged into a computer.

Part 2 - Testing & Revising

Now to test the payload!

All it is programed to do is type a string, so first give it somewhere to type so that you may observe these keystrokes. Opening notepad and ensure it's the focused window, that is when you type, it appears in notepad.

Now, plug in the armed USB Rubber Ducky and observe what happens. Don't worry if it doesn't behave as you expect, we'll take a look at potential problems with this script in a moment.

Result

You may have observed one of the following:

This is because of a process known as device enumeration. Once you plug a new device into your computer, like a keyboard or Rubber Ducky, your computer must go through the process of downloading and installing any necessary drivers for the device. Even subsequent times you plug it in some time may occur between the device receiving power and the computer being ready to receive input from it.

The Rubber Ducky begins running through its script as soon as it is plugged in, therefor it may have typed some or all of the string before the computer was ready to receive and process its keystrokes. It's also possible, though unlikely, that the enumeration process finished before the Rubber Ducky's first keystroke and the full message managed to be typed successfully.

Solution

The simplest solution is to simply have the Rubber Ducky wait some time before starting. This can be achieved with the DELAY command. DELAY accepts a single parameter of an unsigned 16-bit integer (in the range of [0-65535]) to express how many milliseconds to wait before preceding to the next step.

Enumeration for a keyboard, as the computer believes the Rubber Ducky to be, should not take more than a couple seconds on even a slow computer, though results may vary. In general, 2 seconds should be a sufficient delay for most computers.

Revise your code to include an enumeration delay of about 2 seconds before typing

REM Title: Lab 0 - "Hello, World!"
REM Author: Victor E. Viking
REM Description: Types the string "Hello, World!" upon being plugged in, then mount as a Mass Storage device.

REM Enumeration delay of 2000ms (2 seconds)
DELAY 2000

STRING Hello, World!

REM Switch it to mount as a mass storage device after execution is finished.
ATTACKMODE STORAGE

Recompile your code and arm your Rubber Ducky with the updated payload. Remember, with the ATTACKMODE STORAGE command at the end of your script the MicroSD storage is mounted just by plugging in the Rubber Ducky; there is no need to disassemble the case and remove the MicroSD Card.

With the Rubber Ducky armed with the new payload and plug it back in to your computer with Notepad opened and in focus. You should find that after 2 seconds the Rubber Ducky should be successful in typing the full string "Hello, World!" If the full string is not typed you may need to add more time to the delay to accommodate a slower computer.

Part 3 - Improving

Now you should have a USB Rubber Ducky armed with a payload that simply types "Hello, World!" before switching to act like a flash drive. •This string could of course be anything such as a web address to visit, a command to issue etc.

So far, we have assumed that the computer would be ready to receive the text being typed and opened Notepad before plugging it in, however it would be better if the Rubber Ducky could open Notepad itself before typing.

Think about how you opened Notepad. You may have moved your mouse cursor to the Start Menu icon, clicked it searched up the Notepad program and pressed enter. The Rubber Ducky can't use the mouse, only the keyboard. You could substitute the first step for a press of the Windows Key rather than clicking the Start Menu icon and it should work on most versions of Windows since Windows Vista, however there is a more reliable way.

Since Windows 95, the Windows Run program has existed and can be opened by pressing the Windows Key and R allowing you to open a program by typing its name.

The Windows key can be pressed in DuckyScript via the GUI command, and this can be pressed along with the R key via GUI r command. A small delay will be needed between any awaited change in the GUI such as waiting for a new window to open.

Another feature offered as off DuckyScript 3.0 is constants. Constants are strings that can be defined once via the DEFINE keyword and called upon later in the script by a STRING command. The example below defines a constant called MESSAGE containing the string "Hello, World!" and then uses the constant to type the message.

DEFINE MESSAGE Hello, World!

REM Code to open Notepad ommited

STRING MESSAGE

It is best practice when writing a payload that calls external resources that may vary based on the operator or need (i.e. a web address, reverse shell address, etc) it is best to DEFINE these as constants at the top of the payload so that they may be easily changed and configured as needed. A constant may be named with letters, numbers, and underscores, but may not begin with a number. Constant names should be short but descriptive, is inadvisable to name constants with existing commands or internal variable names.

Revise your code to use Run to open Notepad before typing the message and so that the message typed is defined in a constant.

Part 4 - Adapting for a new objective

By now you should have created a payload that opens a program and interacts with it, in this case, specifically opening Notepad and typing a message.

Now, adapt this approach to preform the following tasks instead:

  1. Open Command Prompt or PowerShell and ping Google's DNS server 10 times (8.8.8.8)
  2. Open the calculator and solve the Pythagorean theorem for c when a=3 and b=4 (a²+b²=c²)
  3. Take a screenshot, open Paint, paste the screenshot, and save it to the USB Rubber Ducky's Storage there by exfiltrating a screenshot of the device at the moment the Rubber Ducky was plugged in.

DuckyScript 1.0 offers

Some of the more advanced functionalities introduced in later versions of DuckyScript include: