Ducky Script · Volume 2

Ducky Script Volume 2 — History & Generations

The 2010 origin, the Rubber Ducky hardware lineage, Ducky Script 1.0 → 3.0, and how the language spread across the device family

Contents

SectionTopic
1About this volume
22010 — the origin
3Ducky Script 1.0 — the macro language
4The hardware lineage — Mark I to Mark II
52022 — Ducky Script 3.0 and the redesign
6How the language spread — the device family
7The community and the encoder lineage
8Why the history matters operationally
9What the future may bring
10Resources

1. About this volume

Volume 1 established what Ducky Script is. This volume covers where it came from — because the history is not trivia, it is operationally load-bearing. The single biggest source of confusion for anyone working with Ducky Script is the gap between the 2010 language and the 2022 language, and between the hardware that runs each. A reader who knows the lineage knows, at a glance, whether a payload found online will run on their device, why a tutorial’s syntax looks wrong, and what a given device is and isn’t capable of.

The timeline in one line: 2010 origin → Ducky Script 1.0 → the Mark I hardware → twelve years of community tooling → 2022 Mark II hardware + Ducky Script 3.0 → the language as a family standard across the Bash Bunny, Key Croc, and O.MG.


2. 2010 — the origin

The USB Rubber Ducky was created by Darren Kitchen, founder of Hak5, in 2010. The origin is famously un-dramatic: Kitchen was a systems administrator, and the device was a labour-saving tool for automating mundane IT tasks — “fixing printers, network shares and the like.” Plugging in a device that types a known fix-it sequence into any machine, faster and more reliably than a human, was simply a better way to do a repetitive job.

The insight underneath it — that you could take USB hardware modified to pose as a standard keyboard and use it to send scripted commands to any computer — is what Hak5 named keystroke injection. The offensive-security community recognised the implications quickly, and the USB Rubber Ducky became, in Hak5’s own words, “a hacker culture icon, synonymous with the keystroke injection technique it pioneered.”

   The 2010 origin in context
   ════════════════════════════════════════════════════════

   the problem      "I am a sysadmin. I type the same fix-it
                     sequence into dozens of machines."

   the insight      "A USB device CAN be a keyboard. A keyboard
                     is trusted with no questions asked. So a
                     USB device can TYPE for me."

   the tool         USB Rubber Ducky — a 'flash drive' that is
                     actually a scripted keyboard.

   the language     Ducky Script — the script the keyboard types.

   what it became   the reference implementation of keystroke
                     injection; the thing every BadUSB tool since
                     is measured against or imitates.

Two framing points that the rest of the manual depends on:

  1. The technique predates the offensive-security framing. Keystroke injection is dual-use from birth — the exact same capability automates a help-desk task and drops a reverse shell. The device is neutral; Vol 16 (posture) is where the use is not.
  2. Hak5 owns the canonical line. Unlike, say, an open hardware standard, “the USB Rubber Ducky” and “Ducky Script” are Hak5’s — they define what the language is, and they have revised both the hardware and the language on their own schedule. That is why there is a clean “1.0” and “3.0” rather than a messy fork landscape (contrast the ESP32 firmware world in ../ESP32 Marauder Firmware/).

3. Ducky Script 1.0 — the macro language

Ducky Script 1.0, the 2010 language, is best understood as barely a language at all. It is a macro scripting language that sequentially processes one of two actions:

  1. Keystroke injection — type a set of keys.
  2. Delay — momentarily pause.

That is the whole language. There are no variables, no conditionals, no loops, no functions, no awareness of the target. A 1.0 payload is a flat, linear, top-to-bottom list of “type this” and “wait this long.” Its core commands — covered fully in Vol 3 — are essentially REM (a comment), STRING (type this text), DELAY (wait), ENTER/GUI/TAB/etc. (named keys and modifiers), and a couple of conveniences.

   A complete Ducky Script 1.0 payload — the canonical example
   ════════════════════════════════════════════════════════

   REM Open Run dialog and launch Notepad
   DELAY 1000
   GUI r
   DELAY 500
   STRING notepad
   ENTER

   ── that is the entire language on display. Type, wait,
      press a named key. Nothing branches. Nothing loops.
      Nothing checks whether it worked.

The strength of 1.0 is that it is trivial — anyone can read it, write it, and reason about it in minutes. The weakness is that it types completely blind: it has no way to know what OS it is on, whether the last command succeeded, whether a window has focus. A 1.0 payload that works perfectly on one machine can fail silently on the next because a dialog appeared 200 ms later than expected. Every robust-1.0-payload technique (generous DELAYs, ESCAPE spam to clear state, etc. — Vol 13) is a workaround for this blindness.


4. The hardware lineage — Mark I to Mark II

The language rides on hardware, and the hardware has two generations.

Mark I (2011)Mark II — “the New USB Rubber Ducky” (2022)
Erathe original production devicethe redesign, shipped with Ducky Script 3.0
MCU60 MHz 32-bit Atmel AT32UC3B1256a faster MCU (research-baseline — verify on the owned unit)
Onboard storage256 KB onboard flash(revised — verify)
Removable storagemicroSD card slotmicroSD card slot
ConnectorUSB-AUSB-C and USB-A (to attack desktop and mobile targets)
I/Oa button, a status LEDa button, a status LED
LanguageDucky Script 1.0 onlyDucky Script 3.0 (and runs 1.0 payloads unmodified)
Encode workflowthe Java duckencoder + community toolsPayload Studio + a modernised encoder

The Mark I established the form factor that became iconic: a device the size and shape of a USB flash drive, with the payload (inject.bin) on a removable microSD card, a button for triggering/selecting, and an LED for status. The MCU is a plain microcontroller — there is no operating system on a USB Rubber Ducky, which is exactly why it is fast and deterministic: the firmware does one thing, replay the encoded payload as HID reports, with nothing else competing for the processor.

The Mark II (2022) is a hardware refresh built around the new language. The headline practical change is connectors — USB-C and USB-A — so a single device can target a modern laptop, a desktop, and a phone. It is faster, and it ships with Ducky Script 3.0’s tooling. Crucially, it is backward compatible: every Mark I / Ducky Script 1.0 payload runs on it without modification.

[FIGURE SLOT — Vol 2, § 4] The USB Rubber Ducky (Mark II) — exterior showing the USB-C/A connectors, the button, the LED, the microSD slot. Source: shop.hak5.org product page (page extractor) or tjscientist’s own unit.

Research-baseline note. The exact Mark II microcontroller and storage figures are not published as prominently as the Mark I’s. The owned-unit doc-audit pass (see the project CLAUDE.md) should read them off the actual hardware and pin them.


5. 2022 — Ducky Script 3.0 and the redesign

Ducky Script 3.0, released in 2022 alongside the Mark II, is the language’s transformation from a macro format into a feature-rich, structured programming language. It includes everything 1.0 had, plus:

  • Control flowIF/THEN/ELSE/END_IF conditionals (Vol 4).
  • RepetitionWHILE loops (Vol 4).
  • FunctionsFUNCTION/END_FUNCTION with RETURN (Vol 4).
  • Variables and operatorsVAR (unsigned integers 0-65535), full math/comparison/logical/bitwise operator sets (Vol 4).
  • Extensions — a mechanism for shared, reusable language extensions.
  • Keystroke-injection-specific features that 1.0 could never express:
    • HID & Storage attack modesATTACKMODE (Vol 6), letting one device present as a keyboard, a flash drive, both, or neither, with spoofable VID/PID identity.
    • Keystroke Reflection — an exfiltration channel (Vol 6): the payload reads the host’s keyboard-lock-key LED state as a covert return path, so a device that can only “type” can also, indirectly, “read.”
    • Jitter and randomization (Vol 5) — deliberately irregular timing and randomised content, both to evade the “no human types this evenly” detection heuristic and to defeat naive signature matching.
    • OS and host-state detection (Vol 5) — $_OS and the lock-key-state waits, so a payload can finally stop typing blind.
   The 1.0 → 3.0 jump, conceptually
   ════════════════════════════════════════════════════════

   1.0 (2010)            3.0 (2022)
   ──────────            ──────────
   type ───┐             type
   wait    │  linear,    wait
   type    │  blind,     IF os == windows ──┐ branches
   wait    │  no logic     do windows thing │ on the target
   type ───┘                ELSE            │
                              do other thing┘
                            WHILE not done ──── loops
                              try again
                            EXFIL $data ─────── reads back
                            jitter on ───────── evades timing
                                                detection

   Same hardware lineage. Same backward-compatible syntax
   at the base. But 3.0 is a different *kind* of thing —
   a program, not a macro.

The redesign is the reason this manual splits the language across two volumes (3 and 4) and treats “smart payloads” (5) and “exfiltration” (6) as their own subjects. None of Vols 4-6 existed as concepts in the 1.0 world.


6. How the language spread — the device family

Ducky Script did not stay confined to the USB Rubber Ducky. As Hak5’s product line grew, the language became the family payload standard — but each device runs it as a dialect, shaped by what that hardware is.

DeviceRelationship to Ducky ScriptThe shaping factor
USB Rubber Duckythe canonical, reference implementationa bare microcontroller — the language is the device’s whole behaviour
Bash BunnyDucky Script via the QUACK command + inline; embedded inside a bash-based payload language with ATTACKMODEit is a Linux box — Ducky Script is one tool among many in a full bash environment (Vol 9)
Key CrocDucky Script commands for the injection part of its payloadsit is a keylogger — the injection is triggered by its pattern-match engine, not by being plugged in (Vol 10)
O.MG Cable/Plug/Adaptera DuckyScript dialect, authored and triggered through a web UIit is an ESP-based covert implant — payloads are pushed over Wi-Fi, stored in slots, triggered remotely or by geo-fence (Vol 11)

The important conceptual point: the language is portable, the dialects are not fully interchangeable. A plain “type this” payload is portable across all four. A payload that uses ATTACKMODE ETHERNET is a Bash Bunny payload. A payload that depends on a MATCH trigger is a Key Croc payload. A payload that assumes a web-UI slot and geo-fence is an O.MG payload. Vol 12 (encode/deploy) and Vols 9-11 (the device volumes) draw the lines precisely; Vol 1’s “device discipline” rule — always say which device a device-specific claim applies to — exists because of this.

The Bash Bunny’s own documentation puts it cleanly: its payload language is “DuckyScript… consisting of simple commands specific to the Bash Bunny hardware, some helper functions and the full power of the Bash Unix shell.” That sentence is the template for how every non-Ducky device relates to the language: Ducky Script core + device-specific commands + the device’s native capabilities.


7. The community and the encoder lineage

For twelve years between 1.0 and 3.0, the USB Rubber Ducky had a large community, and that community’s work is part of the history:

  • Encoders. The original toolchain was a Java duckencoder that turned payload.txt into the inject.bin the device replays. Because it was simple and the format was understood, the community produced many alternative encoders — web-based, OS-native, scriptable. The Mark II era brought Hak5’s Payload Studio, a modern (web-based) authoring + encoding environment. Vol 12 covers the encode workflow across devices and eras.
  • The payload repositories. Hak5 maintains official payload repositories on GitHub (the USB Rubber Ducky payload repo, the Bash Bunny payload repo, the Key Croc payload repo), and there is a large body of community payloads — of varying quality and varying target-OS/target-version freshness. Vol 13 covers the payload landscape and the vetting discipline (a payload is code you are about to run, fast, on a machine — read it first).
  • Cross-generation drift. Because 1.0 ran for over a decade, an enormous amount of online material — tutorials, payload dumps, blog posts — is 1.0-era. It is mostly still valid (1.0 is a subset of 3.0) but it will not show you any of the 3.0 capabilities, and some of it targets OS versions that have since changed. The same cross-generation staleness problem applies to community payloads as applies to community modules in the WiFi Pineapple world.

8. Why the history matters operationally

Pulling §§ 2-7 together — the four operational reasons a working engineer needs the lineage in their head:

  1. Will this payload run on my device? A payload using VAR/IF/WHILE/ATTACKMODE is 3.0 — it needs a Mark II Rubber Ducky (or a Bash Bunny / Key Croc / O.MG that supports those constructs). A plain type-and-delay payload runs anywhere. Knowing the lineage is how you answer this at a glance.
  2. Why does this tutorial’s syntax look off? Because most online material is 1.0-era. It is not wrong; it is just old, and it is not showing you the modern language.
  3. What can this specific device actually do? “It runs Ducky Script” is true of all four devices and tells you almost nothing. Which dialect, on which hardware tells you everything — and that is a lineage question (§ 6).
  4. Why is there no firmware fork chaos here? Because Hak5 owns the canonical line. Unlike the ESP32 firmware ecosystem, there is one Ducky Script, versioned on Hak5’s schedule. That is a stability advantage — but it also means the language’s capabilities are whatever Hak5 ships, and the community builds payloads and encoders, not forks of the language.

9. What the future may bring

Forward-looking, explicitly speculative — flagged so a future doc-audit can correct it:

  • Language iteration. Ducky Script went 1.0 → (a 2.0 that existed briefly in the ecosystem) → 3.0. A future revision is plausible; the 3.0 extension mechanism is the most likely growth path — new capabilities as extensions rather than a wholesale version bump.
  • Hardware refreshes. The Mark II is the current Rubber Ducky; the Bash Bunny is on its Mark II; the O.MG line has tiered hardware (Basic/Elite) that Hak5/Grover iterate. Connector and speed bumps are the predictable axis.
  • Tighter Cloud C2 integration. Hak5 Cloud C2 already manages a fleet of Hak5 devices; deeper payload-deployment and result-collection integration for the keystroke-injection family is a natural direction (Vol 14 covers the current state).
  • The detection arms race. As USB device control and HID-injection detection mature (Vol 15), the language’s evasion features (jitter, randomization, VID/PID spoofing) are the part most likely to grow. This is the same dynamic as every offensive tool: the defensive side improves, the offensive side adds evasion, repeat.

10. Resources

History & language

Within this manual

  • Vol 1 — what Ducky Script is, and the device family
  • Vol 3 — the 1.0 language core in full
  • Vol 4 — the 3.0 language proper
  • Vols 8-11 — the four device families, each in depth
  • Vol 13 — the payload landscape and vetting

This is Volume 2 of an 18-volume series. Next: Vol 3 covers the language core — Ducky Script 1.0, the foundation every device and every payload is built on: syntax, STRING/STRINGLN, DELAY, REM, the key names, and the modifier keys.