Detect Ready - Smarter Initial Delays for Keystroke Injection Attacks with the USB Rubber Ducky

Pwned in Milliseconds

Since the beginning of Keystroke Injection attacks, dating back to the origins of DuckyScript 1.0 over a decade ago, conventional wisdom has been to always begin a payload with the simple line: DELAY 3000.

Why wait 3000 ms?

TL;DR: If you've ever plugged in a keyboard and started pressing keys until you saw them appear - this is the nearly arbitrary delay we are trying to solve for.

Simply put, the USB Rubber Ducky is capable of injecting keystrokes faster than the target is ready to accept them in a usable fashion. While the USB Rubber Ducky boots, processes, and starts running its payload almost instantly, the target must enumerate and set up the new USB HID device as necessary.

On very old computers, USB device setup could be as much as 1 to 2 seconds. Therefore, a 3000 ms delay would in the majority of cases ensure that your payload would execute more reliably across varying targets.

But what about modern, fast computers? Why wait so long? Further complicating the problem; many systems will offer up the communication channel with the USB Rubber Ducky at the protocol level before the operating system itself starts accepting usable input.

While faster, omitting a "better safe than sorry" (better slow than broken) DELAY at the beginning of the your payload can often result in an "ello, World!" rather than a "Hello, World!". For a payload as simple as the above example it may not be the end of the world; but for your 5 second Mr Robot Style hack while on an engagement — it very well could be the difference between success and a very alarm bell ringing failure.

Even going as far as to custom tailor a finely tuned boot DELAY for your payload and the exact target system you'll find that the variance between USB Rubber Ducky "boots" (or payload runs) is enough to put you right back into the ballpark of +/- 1000ms. Considering many actual flash drives take significantly longer to enumerate on some systems, we're full circle back to "Just add a DELAY 3000" for any hope of near 100% reliability and call it a day. Until...

Work smarter not harder

Because DuckyScript 3.0 includes the logic necessary to make programmatic decisions, as well as awareness of the Lock Key states (that we abuse in our Keystroke Reflection attack) we can instruct our payload to DELAY only for as long as is necessary before reliably injecting meaningful keystrokes. That's exactly what we've done with the EXTENSION DETECT_READY.

Simply by being added to the top of your payload, this extension waits for the defined response delay until either the state of CAPSLOCK has been confirmed on, or the defined iteration limit has been reached. The minimum response DELAY is set to a default of 25 ms; a value we have found to be optimized. In our testing across a broad range of systems, this is the lowest value which produces the fastest results without additional unnecessary iteration.

In more detail


This means one of three things has happened before the rest of your payload runs;

  1. The USB Rubber Ducky has successfully sent a keystroke that it can confirm the operating system has fully acknowledged.
  2. The target system already had CAPSLOCK turned on - $_CAPSLOCK_ON == TRUE being a side effect of the operating system syncing the current CAPSLOCK state to the newly connected keyboard: the USB Rubber Ducky. While this is not a full circle confirmation like the first possible outcome, it is sufficient enough indication that the host will accept further keystrokes from the USB Rubber Ducky.
  3. All else has failed and we have fallen back to the old best practice of DELAY 3000

     

Seeing it in action

We put the DETECT_READY extension to the test by adding some debugging instrumentation. In this case, by importing the TRANSLATE extension, we are able to type out how long after connection and enumeration the target took to be ready for reliable keystroke injection.

Windows 10

This bare metal Dell XPS 13 machine is running on modern Intel i7 hardware.
Result: 25 milliseconds! 99.17% reduction

Kali Linux

Similarly, our Linux example is also running on the same hardware in a VM
Result: 100ms; a 96.67% reduction

Windows XP

How about something ancient? For this test we dusted off an old ASUS Eee PC 701 — a 2007 era netbook with a Intel Celeron CPU underclocked to 630 MHz!

Result: ~400ms; a 86.67% reduction

Caveats

Mobile targets such as iOS and Android need extra attention. While the DETECT_READY extension will only DELAY so long as the target is not prepared to accept keystrokes, in our experience mobile devices still require extra time to close their on-screen keyboards once a physical keyboard has been recognized by the OS.

Additionally MacOS traditionally does not sync or reflect lock key states; The iteration limit built into the extension by default ensures that the payload continues after a maximum DELAY of 3000 ms, the previously held conventional wisdom, which in experience is sufficient for most targets. The value may be increased to achieve the highest possible compatibility in the case that the target requires a very slow driver download and installation — something that may be possible when brute forcing VID and PID values. That said, this is very unlikely for most known keyboard identifiers in our experience.

How to use this in your payload

By using the extension architecture of DuckyScript 3.0, all payload authors benefit from the DETECT_READY capabilities while having the flexibility to modify it to their specific requirements.

The DETECT_READY extension can be found from the USB Rubber Ducky payload repository at https://github.com/hak5/usbrubberducky-payloads/tree/master/payloads/extensions

To implement DETECT_READY in your own payload, simply begin typing EXTENSION DELAY_READY and select the auto-complete suggestion from within PayloadStudio; it will automatically include the latest version.

Placing this at the top of your payload in lieu of the traditional DELAY 3000 will produce the results mentioned above. Get ready to enjoy both faster and more reliable payload execution!

Passively Detected in 25 milliseconds

Considering that Apple operating systems are the main flavor of target that won't take advantage of the enhanced functionality provided by DETECT_READY, why not continue to improve within the scope where it is already applicable? If you've followed along so far you might have taken note that many operating systems that do reflect lock keys also (generally) sync lock states on connection of a new keyboard. This being part of what we can consider to be the setup process, it should be both faster and entirely passive to detect ready on these systems simply by detecting the initial update of the lock states. Thus PASSIVE_DETECT_READY is born.

Windows Passively Detected in 25 milliseconds

We're already detecting either the first usable input, or the end of the setup process...

Conveniently, the USB Rubber Ducky also happens to implement a novel, entirely passive, driver level, Windows detection - instantly during the setup process; not only can this process reliably become EVEN FASTER on Windows targets - we can also make a very simple yet powerful OS determination at the exact same time... PASSIVE_WINDOWS_DETECT does exactly this for you.

 

Authors: Dallas Winger, Darren Kitchen



Also in USB Rubber Ducky

Keystroke Reflection - Side-Channel Exfiltration for the USB Rubber Ducky
Keystroke Reflection - Side-Channel Exfiltration for the USB Rubber Ducky

Keystroke reflection exploits the defacto standard keyboard-computer architecture implemented by all IBM-PC compatibles since 1984 and adopted in usb-hid to provide a side-channel exfiltration pathway that impacts nearly all personal computers from the last 4 decades.
What is the best security awareness payload for the Rubber Ducky?
What is the best security awareness payload for the Rubber Ducky?

A two second HID attack against Windows and Mac that launches the website of your choosing. That's by far the most effective security awareness payload for the USB Rubber Ducky.

The 3 Second Reverse Shell with a USB Rubber Ducky
The 3 Second Reverse Shell with a USB Rubber Ducky

A reverse shell is a type of shell where the victim computer calls back to an attacker’s computer. The attacking computer typically listens on a specific port. When it receives the connection it is then able to execute commands on the victim computer. In essence it’s remote control of a computer.