Writing and Deploying Ducky Script Payloads

Gabriele BiondoGabriele Biondo
6 min read

For the largest part, developing a Ducky Script (from now on, DS) Payloads implies thinking out what stream of bytes depicts the actions that you would perform on the target system to obtain what you want.

These actions are to be described in the DS language, they are then compiled in a payload. The USB Stick will then inject this stream of bytes in the remote host.

Phew, the theory doesn't seem too difficult - and in fact, it isn't. DS is quite straightforward, because it only needs to specify basic actions. From now on, we will introduce more advanced operators directly with the payloads.

I am writing payloads for MacOS, because this website is mostly about MacOS security. Adapting the scripts to Windows, Linux, or Android should be quite straightforward for you.

Oldies goodies - the Hell o' world payload.

What do we want to achieve

We want a new TextEdit windows opening and writing the string "Hell o' world" in it. Easy Peasy.

How would I do it as an operator
  1. press COMMAND and SPACE at the same time.

  2. Spotlight shall open (see image below) and write in the dialog TextEdit.app followed by a carriage return character

  3. Wait for the system to open the application

  4. Write in the app's main window the string "Hell o' world!"

  5. Inflate a carriage return

  6. Write in the app's main window "Duck you, you ducking duck!" followed by a carriage return

  7. Write in the app "Especially you. Yes, you."

How do I write this payload?

Remember that in a previous article INSERT LINK HERE I introduced the payload studio? Exactly, now it's time to make use of it. So point your browser to https://payloadstudio.com/pro/ (or the community edition, if that was your choice).

Your browser will show the Hello World code we have discussed last time. Delete it all.

Now type the following in the editor:

ATTACKMODE HID STORAGE
DELAY 3000
COMMAND SPACE
STRING TextEdit.app
DELAY 500 
ENTER
STRINGLN Hell o' World
ENTER
DELAY 4000
STRING Duck you, 
STRING you ducking duck!
ENTER
ENTER
STRING Especially you. 
STRINGLN Yes, you

Now hit the Generate Payload button. If everything worked fine, you'll end up with the following

Hit the download button, now your payload is ready to be tested.

Just in case you're wondering, this is what I obtained:

The problem now becomes how do we test the payload, and in detail, how do we put the payload in the USB key.

Deploying the payload

Fortunately, deploying the payload is quite a simple process. We will come to this in much greater detail, but the essence is that you're about to copy the inject.bin file you generated in the Payload Studio in the root of the Rubber Ducky.

A cautionary note, tho. Rubber Ducky has several modes, mainly the attack mode and the storage mode. One switches between them by clicking the small button integrated in the chipset, it should be easy to identify in the image below:

Clicking that button toggles between the modes, so you may need to do this by some trials and errors. But it's just two clicks, in the worst case. In my case, it is easy: my AV tries to scan the volume when I mount it in storage mode.

Testing the Payload

We're up for failure, boys, but let's do it with style! I assume you have been able to deploy your inject.bin file in the stick - if not, well... I am not helping you! But if you were, you'd expect your shiny "Hello World" payload to work fine and...

... and if you did everything as expected, you obtained the following windows:

and

In fact, the system is trying to identify the keyboard (because this is how it sees the Rubber Ducky, after all) to configure it. Whatever the reason, this is everything but what we want to achieve, for it's not stealthy at all.

Fortunately, we can tweak our code and instruct the RD to tell the host system what kind of keyboard it is. This will add - at least - the stealth element to our attack. Hopefully.

Payload revision #1

Reopen the Payload studio and edit the payload so that it becomes

ATTACKMODE HID VID_05AC PID_021E
DELAY 10000
COMMAND SPACE
STRING TextEdit.app
DELAY 10000 
ENTER
STRINGLN Hell o' World
ENTER
DELAY 10000
STRING Duck you, 
STRING you ducking duck!
ENTER
ENTER
STRING Especially you. 
STRINGLN Yes, you

Again, compile and deploy. The VID parameter we declared stands for Vendor ID, and the PID stands for Product ID. We are basically telling our Mac that we plugged in a shiny Apple Keyboard. We will discuss more the Attack Modes in our next article.

I also changed the DELAYs. DELAY <k> waits for k milliseconds before continuing the flow of execution, so the effect of DELAY 10000 is just introducing a delay of 10 seconds. This will help us checking if everything is as we expect, especially in terms of stealth.

Copy the code, paste it into Payload Studio, compile it and download the corresponding inject.bin file. Deploy it into your USB Stick. Get ready for some more frustration.

Another debugging session

I assume you did exactly what I explained before, so that you can follow me. Upon inserting the USB key in, some things take place.

We immediately see that the Keyboard Setup Assistant doesn't show anymore. So the first change we did was successful.

We also see that having a long DELAY after typing TextEdit.app is detrimental for the stealth of the attack. Let's get rid of it, and perhaps decide if we need it somehow after the ENTER.

The TextEdit app starts with a File Open dialog. Fortunately this can be overridden with a quick COMMAND n.

Wrapping all these together:

ATTACKMODE HID VID_05AC PID_021E
DELAY 1000
COMMAND SPACE
STRING TextEdit.app 
ENTER
DELAY 1000
COMMAND n
STRINGLN Hell o' World
ENTER
DELAY 10000
STRING Duck you, 
STRING you ducking duck!
ENTER
ENTER
STRING Especially you. 
STRINGLN Yes, you

Build, Deploy, Quack.

Now it starts to work. One may or may not want to optimise it. I hadn't the slightest will to do it, so for the very moment, I am sharing a "functional, yet not perfect version" of this monstrosity. Have fun doing the tweaker/spippolator and make it perfect - to me, good enough is good enough.

ATTACKMODE HID VID_05AC PID_021E
DELAY 1000
COMMAND SPACE
STRING TextEdit.app 
ENTER
DELAY 250
COMMAND n
DELAY 1000
STRINGLN Hell World
ENTER
DELAY 1000
STRING Duck you, 
STRING you ducking duck!
ENTER
ENTER
STRING Especially you. 
STRINGLN Yes, you

Ok, this should have given you some taste of DS, and of how we can play around with these little, tiny sons of the USB. I meant, sons of the devil. See ya next time...

1
Subscribe to my newsletter

Read articles from Gabriele Biondo directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Gabriele Biondo
Gabriele Biondo

Math guy who's into Cryptography, into iOS/MacOS development, and obviously into hacking/pentesting. Writing stuff in C/C++/ObjectiveC/Swift/Python/Assembly.