Ducky Script · Volume 6

Ducky Script Volume 6 — Exfiltration & ATTACKMODE

Using the device as more than a typist — ATTACKMODE, USB identity spoofing, Keystroke Reflection, and HIDE_PAYLOAD

Contents

SectionTopic
1About this volume
2ATTACKMODE — what the device pretends to be
3USB identity spoofing — VID, PID, and friends
4SAVE_ATTACKMODE / RESTORE_ATTACKMODE
5Keystroke Reflection — the exfiltration channel
6EXFIL and loot.bin
7HIDE_PAYLOAD — concealing the device’s storage
8LED control and status
9The exfiltration picture across the device family
10Resources

1. About this volume

Vols 3-5 covered the device as a keyboard — typing, deciding, timing. This volume covers everything that makes a Ducky Script device more than a keyboard: presenting as a different kind of USB device entirely (ATTACKMODE), lying about its USB identity, and — the clever centrepiece — turning the three-bit lock-key back-channel from Vol 5 into a genuine exfiltration path (Keystroke Reflection).

These are 3.0 features on the USB Rubber Ducky. They are also where the USB Rubber Ducky starts to look like its bigger siblings — and §9 sets up the device volumes by showing how the Bash Bunny, Key Croc, and O.MG each take this further.


2. ATTACKMODE — what the device pretends to be

A USB device announces, at enumeration, what class of device it is. ATTACKMODE is the command that sets what a Ducky Script device announces:

ATTACKMODE HID                REM a keyboard — the default, for keystroke injection
ATTACKMODE STORAGE            REM a USB mass-storage device — a flash drive
ATTACKMODE HID STORAGE        REM both at once — keyboard AND flash drive
ATTACKMODE OFF                REM present as nothing — no HID, no storage

ATTACKMODE can be issued multiple times in one payload — the device can change what it presents as, mid-run. The operational uses:

ModeWhat it enables
HIDthe baseline — keystroke injection. Most payloads never need anything else.
STORAGEthe device shows up as a flash drive — so a payload can type a command that reads a file off the device itself, or the device can carry tools/output
HID STORAGEtype a command and have a drive present for that command to read from / write to — the basis of “type a loader that pulls the real payload off my own storage”
OFFpresent as nothing — used to hide (the device is connected but invisible as HID/storage), often paired with HIDE_PAYLOAD (§7)
   Why HID STORAGE is powerful
   ════════════════════════════════════════════════════════

   Problem:  typing a 500-line script keystroke-by-keystroke
             is slow and fragile (Vol 3).

   ATTACKMODE HID STORAGE solution:
     1. device presents as keyboard + flash drive
     2. the real payload/tool already sits on the drive
     3. the HID side just TYPES a short loader:
        "run the script on the drive that just appeared"
     4. one short reliable type, instead of 500 fragile ones

   The keyboard becomes a bootstrap; the storage carries
   the weight.

3. USB identity spoofing — VID, PID, and friends

Every USB device has identity strings: a Vendor ID (VID), a Product ID (PID), and human-readable manufacturer / product / serial strings. By default a Ducky Script device enumerates with Hak5’s identity — which is exactly what a USB-device-control defense (Vol 15) is watching for.

ATTACKMODE takes optional parameters that override every identity field:

ATTACKMODE HID VID_413C PID_2107 MAN_Dell PROD_Dell_USB_Keyboard
ParameterSets
VID_xxxxVendor ID (hex)
PID_xxxxProduct ID (hex)
MAN_...manufacturer string
PROD_...product string
SERIAL_...serial number string

And the _RANDOM variantsVID_RANDOM, PID_RANDOM, MAN_RANDOM, PROD_RANDOM, SERIAL_RANDOM — randomise the field each run.

The operational point: a Ducky Script device can present as a specific real keyboard — a Dell keyboard, a Logitech keyboard, whatever the target environment uses. Against a USB allow-list keyed on VID/PID (Vol 15), spoofing a permitted keyboard’s identity is the direct counter. Against logging-based detection, _RANDOM makes each insertion look like a different device so they don’t correlate. The internal variables $_CURRENT_VID, $_CURRENT_PID, $_CURRENT_ATTACKMODE let the payload read back its own current identity.

This is a genuine arms-race feature, and Vol 15 covers the defensive response (allow-lists keyed on more than VID/PID, behavioural detection that spoofing doesn’t touch).


4. SAVE_ATTACKMODE / RESTORE_ATTACKMODE

Because ATTACKMODE can change mid-payload, 3.0 gives you a stack-of-one to snapshot and restore it:

SAVE_ATTACKMODE          REM remember the current mode + identity
ATTACKMODE OFF           REM go invisible to do something quietly
REM ... do the quiet thing ...
RESTORE_ATTACKMODE       REM go back to exactly what we were

The use: a payload that needs to transiently change what the device presents as — drop to OFF to hide, flip to STORAGE to stage a file — without having to hard-code “what was I before.” It keeps multi-mode payloads clean.


5. Keystroke Reflection — the exfiltration channel

This is the centrepiece, and it is genuinely clever. The problem: a keyboard is (almost) one-way. It sends keystrokes. It cannot read the host. So how does a keystroke-injection device get data off the target?

The answer, from Vol 5 §4: the lock-key LED state is a host → device back-channel. The host broadcasts CAPS/NUM/SCROLL LED state to every keyboard. The device is a keyboard. So:

   Keystroke Reflection — exfil over three LEDs
   ════════════════════════════════════════════════════════

   1. The payload TYPES a script onto the host.
   2. That script reads the data you want (a file, a token,
      a result) and ENCODES it as a sequence of lock-key
      toggles — turning CAPS/NUM/SCROLL on and off in a
      pattern that represents the data.
   3. The host, doing what hosts do, BROADCASTS each lock-key
      change back to all keyboards — including the device.
   4. The device READS that stream of lock-key changes and
      DECODES it back into the original data.

   data ──typed script──► host ──lock-key LED toggles──► device

   The keyboard "read" the host. Through its own status LEDs.
   The technique is called KEYSTROKE REFLECTION — the host's
   data is reflected back through the keyboard-status channel.

It is slow — three bits per update, and you are limited by how fast lock-key state can be toggled and observed — so it is an exfil path for secrets, not bulk data: a credential, an API token, a config value, a short result. But it is real, it needs no network, no extra hardware, and no storage device to be mounted — it works through the keyboard interface alone, on a host where USB mass-storage is blocked. That is what makes it notable: it is exfiltration on a device class (HID) that defenders rarely think of as an exfiltration risk.

The enabling internal variable is $_EXFIL_MODE_ENABLED (TRUE/FALSE) — it turns on the device’s reading-and-decoding of the reflected lock-key stream.


6. EXFIL and loot.bin

Once Keystroke Reflection is decoding data, it has to go somewhere. The EXFIL command writes a variable’s data to loot.bin on the device’s storage:

$_EXFIL_MODE_ENABLED = TRUE
REM ... payload types a script that reflects data back ...
REM ... the reflected data is captured into a variable ...
EXFIL $captured_value

The model: the reflected data lands in the payload’s variables, and EXFIL persists it to loot.bin on the microSD card. After the engagement, the operator reads loot.bin off the card. It is the on-device counterpart to the host-side analysis the bigger devices do natively (§9).

loot.bin joins inject.bin (the encoded payload) and seed.bin (the randomization seed, Vol 5 §8) as the three meaningful files the SD-card workflow deals with — Vol 12 covers the file/SD-card workflow in full.


7. HIDE_PAYLOAD — concealing the device’s storage

When a Ducky Script device presents as STORAGE, an inquisitive target (or their endpoint software) can look at the drive — and find inject.bin, seed.bin, loot.bin sitting there, which is about as self-incriminating as it gets.

HIDE_PAYLOAD conceals those files; RESTORE_PAYLOAD brings them back:

HIDE_PAYLOAD       REM inject.bin / seed.bin become invisible on the storage
REM ... the device can still present as STORAGE for cover —
REM     a blank-looking flash drive — while the payload files hide
RESTORE_PAYLOAD    REM bring them back (e.g. so YOU can read loot.bin later)

HIDE_PAYLOAD requires the device to be in ATTACKMODE OFF or ATTACKMODE HID (you cannot hide the files while actively presenting the storage that contains them in a way that would expose them). The operational picture: the device can look like an ordinary empty flash drive — useful cover for a “found USB stick” scenario — with the incriminating payload files hidden, then restore them so the operator can retrieve loot.bin.

It is concealment, not encryption — a forensic examination of the storage still finds the data. It defeats a casual look, not a deliberate investigation (Vol 15, Vol 16).


8. LED control and status

Small but operationally real: the device’s status LED is payload-controllable.

LED_OFF       REM LED off
LED_R         REM red
LED_G         REM green

Plus internal variables governing whether the LED reflects system/storage/injecting activity ($_SYSTEM_LEDS_ENABLED, $_STORAGE_LEDS_ENABLED, $_INJECTING_LEDS_ENABLED) and lock-key state ($_LED_SHOW_CAPS, etc.).

Two uses: operator feedback — the LED tells you what phase the payload is in (red = working, green = done, so you know when to pull the device) — and, conversely, going darkLED_OFF and disabling the activity LEDs so a payload runs without a blinking light drawing a bystander’s eye. Which one you want is a posture decision (Vol 16).


9. The exfiltration picture across the device family

Everything above is the USB Rubber Ducky’s answer to “be more than a typist” — and it is an ingenious answer precisely because the Rubber Ducky has so little to work with: a microcontroller, an HID interface, optional mass storage, and three lock-key LEDs. Keystroke Reflection is what you invent when that is all you have.

The other three devices have far more, and the device volumes cover it — but here is the family picture so the contrast is clear from the start:

Device”More than a typist” capabilityVolume
USB Rubber DuckyATTACKMODE STORAGE, VID/PID spoofing, Keystroke Reflection exfil over lock keys, loot.binVol 8
Bash BunnyATTACKMODE emulates storage, serial, and full USB-ethernet — it can be a network adapter; a whole Linux userland to process/stage/exfil; far richer than the DuckyVol 9
Key Crocit is a keylogger — exfiltration is its native mode; logs keystrokes to its 8 GB SSD, streams them, and has Wi-Fi and remote accessVol 10
O.MGWi-Fi — payloads, triggering, and results all flow over the device’s own Wi-Fi to a web UI; exfil is a network operation, not a lock-key trickVol 11

So: Keystroke Reflection is the clever-because-constrained technique; the bigger devices simply have a network (or are the keylogger). When you reach Vols 8-11, the throughline is “how does this device, given its actual hardware, solve the get-data-off-the-host problem” — and the Rubber Ducky’s answer in this volume is the baseline the others are measured against.


10. Resources

This is Volume 6 of an 18-volume series. Next: Vol 7 closes Part I with keyboard layouts — the cross-locale problem that is the single most common cause of a payload that “ran but typed garbage,” and the discipline for writing payloads that survive being run on a keyboard layout you did not encode for.