Keystroke injection attack platform
A worthy successor of the WiFi Ducky project
🐦 Twitter
| 📺 YouTube
| 🌍 spacehuhn.io
Support this project and become a patron on patreon.com/spacehuhn.
Also available: Stickers
!
This is a tool.
It's neither good nor bad.
Use it to do good, to study and to test.
Never use it to do harm or create damage!
The continuation of this project counts on you!
This open source project aims to provide a user-friendly tool to learn about
keystroke injection attacks.
A microcontroller acts as a USB keyboard that is programmable over WiFi.
It's using the Ducky Script language that Hak5
introduced with the USB Rubber Ducky.
A keyboard is trusted by most operating systems by default,
which enables for a variety of attacks.
Humans might not type very fast, but an automated device like this can.
It can open a terminal and mess with your computer in a matter of a milliseconds!
Changes since the WiFi Ducky predecessor:
- Support for multiple keyboard layouts, adjustable within the script
- No size limit per script (other than the physical limit)
- No line length limit for the
STRING
command - Faster typing speed
- Added RGB (Neopixel LED)
- Reworked web interface
- Replaced serial with i2c connection, to make debugging and flashing easy
This tool requires following hardware:
- An Atmega32u4 or Atsamd21 based board (for example: Arduino Leonardo, Arduino Pro Micro or Adafruit Trinked m0)
- An ESP8266 or ESP8285 (for example NodeMCU or Lolin/Wemos d1 mini)
- [Optional] A single Neopixel LED (WS2812b)
You will also need a computer, a working USB cable, patience and common sense.
If you're a beginner,
it's recommended you wire everything together on a breadboard first!
So get a breadboard with a couple of jumper wires.
If you wish to solder everything together to a small DIY gadget, you'll obviously need soldering equipment and a bit of experience using it.
Here's a map of the pins that need to be connected.
ESP8266 | Atmega32u4 |
---|---|
GPIO 5 or D1 |
SCL or D3 |
GPIO 4 or D2 |
SDA or D2 |
GND |
GND |
Atmega32u4 | Neopixel LED |
---|---|
D7 |
DI , Data or In |
GND |
GND |
Arduino IDE:
Latest ESP8266 Arduino Core:
Arduino Libraries:
Installing Arduino libraries is always the same procedure:
Download the repository, unzip it and move it inside the libraries folder.
If you need more information, here is a
tutorial with more information.
- Open
atmegaduck/atmega_duck.ino
with the Arduino IDE - Under
Tools->Board
select your board, for exampleAdafruit Trinket m0
.
You can also selectArduino Leonardo
if you use a 5V Atmega32u4 (used on DSTIKE board too) orLilyPad Arduino USB
if you use a 3.3V Atmega32u4 - Plug the board in and select its port under
Tools->Port
- Press the Upload button
- Open
esp_duck/esp_duck.ino
with the Arduino IDE - Under
Tools->Board
selectNodeMCU 1.0 (ESP-12E Module)
(or whatever corresponds best to your ESP8266/ESP8285 based board).
Be sure to use the latest ESP8266 Arduino Core, see requirements! - Under
Tools->Flash Size
select4M (3M SPIFFS)
(or1M (512K SPIFFS)
if you use a ESP-07 Module or ESP8285 based board). - Plug the board in and select its port under
Tools->Port
- Press the Upload button
If you like to support this project, Travis Lin sells a custom made board that ships preflashed!
It features a 8bit DIP-switch, making it easy for you to flash both the ESP8266 and the Atmega32u4:
Mode | DIP-switch | Image |
---|---|---|
Normal Work Mode (Default Operating Mode) | 10101101 | |
Atmega32u4 (Arduino Pro Micro) Flash Mode | 10101010 | |
ESP8266 (NodeMCU 1.0) Flash Mode | 01011101 |
You can purchase one here:
- Plug it in (a blue Neopixel LED tells you that the connection is working)
- Connect to the WiFi network
wifiduck
with the passwordwifiduck
- Open a browser and visit
192.168.4.1
- Click on Settings in the top right corner
- Change the SSID and password
The command line interface or CLI is accessible using a serial connection to the ESP8266 (115200 baud, Newline ending) or via the web interface at 192.168.4.1/terminal.html
.
Command | Description | Example |
---|---|---|
help | Returns all available commands | help |
ram | Returns available memory in bytes | ram |
settings | Returns list of settings | settings |
set -n/ame -v/alue | Sets value of a specific setting | set ssid "why fight duck" |
reset | Resets all settings to their default values | reset |
status | Returns status of i2c connection with Atmega32u4 | status |
run <...> | Starts executing a Ducky script | run example.txt |
stop <...> | Stops executing a Ducky script | stop example.txt |
Command | Description | Example |
---|---|---|
mem | Returns available, used and free memory of SPIFFS in bytes | mem |
format | Formats SPIFFS | format |
ls <...> | Returns list of files | ls / |
create <...> | Creates file | create example.duck |
remove <...> | Deletes file | remove example.duck |
cat <...> | Returns content of file | cat example.duck |
rename -fileA,a -fileB,b | Renames file | rename example.duck example.txt |
write -f/ile -c/ontent | Writes (appends) data to file | write example.txt "Hello World!" |
stream <...> | Opens file stream | stream example.txt |
close | Closes file stream | close |
read | Read and return the result from file stream | read |
If a stream is open, everything you type (except messages containing exactly close
or read
) will be written to the file until you type close
!
Command | Description | Example |
---|---|---|
REM |
Comment | REM Hello World! |
DEFAULTDELAY or DEFAULT_DELAY |
Time in ms between every command | DEFAULTDELAY 200 |
DELAY |
Delay in ms | DELAY 1000 |
STRING |
Types the following string | STRING Hello World! |
REPEAT or REPLAY |
Repeats the last command n times | REPEAT 3 |
LOCALE |
Sets the keyboard layout. Currently supported: DE , GB , US |
LOCALE DE |
KEYCODE |
Type specific key code (modifier, key1[, ..., key6]) in decimal or hexadecimal | KEYCODE 0x02 0x04 |
Key |
---|
a - z |
A - Z |
0 - 9 |
F1 - F12 |
Key |
---|
CTRL or CONTROL |
SHIFT |
ALT |
WINDOWS or GUI |
Key |
---|
ENTER |
MENU or APP |
DELETE |
HOME |
INSERT |
PAGEUP |
PAGEDOWN |
UP or UPARROW |
DOWN or DOWNARROW |
LEFT or LEFTARROW |
RIGHT or RIGHTARROW |
TAB |
END |
ESC or ESCAPE |
SPACE |
PAUSE or BREAK |
CAPSLOCK |
NUMLOCK |
PRINTSCREEN |
SCROLLLOCK |
REM Hello World for Windows PCs
DEFAULTDELAY 200
GUI r
STRING notepad
ENTER
STRING Hello World!
To properly debug, you need to have both the Atmega32u4 and the ESP8266 connected via USB to your computer.
That can be tricky when you only have a all in one board, so it might be useful you built one yourself. You don't need to solder it, for example you can use an Arduino Leonardo and a NodeMCU and connect them with jumper cables.
Now open 2 instances of Arduino (so they run as separate processes!), select the COM port and open the serial monitor for each device. You might need to reset the Atmega32u4 to see serial output. If that causes problems with the i2c connection, try to reset the ESP8266 too.
If you have a question, you can check out the issue section.
Use the search function to look up similar questions, be sure to check both open and closed issues!
Also watch this video by LiveOverflow on "How (not) to ask a technical question".
Flash the ESP8266 again,
but make sure that you select Erase Flash: Sketch + WiFi Settings
under Tools in the Arduino IDE.
If you would like to modify the web interface, you can!
The web/
folder contains all .html
, .css
, .js
files.
You can edit and test them locally as long as you're connected to the WiFi Duck
network thanks to the websocket connection handled by JavaScript in the background.
To get the new files onto the ESP8266, run python3 webconverter.py
in the
repository folder.
It gzips all files inside web/
, converts them into a hex array
and saves it in esp_duck/webfiles.h
.
Now you just need to flash the ESP8266 again.
Currently the supported keyboard layouts are:
All standard keys are defined in usb_hid_keys.h.
To translate a keyboard layout, you have to match each character on
your keyboard to the one(s) of a US keyboard.
This stuff is hard to explain in writing and requires a lot of manual work and testing.
- Copy one of the existing layouts files, like locale_us.h.
Preferably one that is close to your keyboard layout, it will save you time! - Rename the file and its variables to your language code.
For example:
locale_xx.h
->locale_de.h
,
ascii_xx
->ascii_de
,
locale_xx
->locale_de
,
extended_ascii_xx
->extended_ascii_de
,
utf8_xx
->utf8_de
. - Modify the ASCII array.
The ASCII array has a fixed size. Each row describes a key. First a modifier key likeKEY_MOD_LSHIFT
, then a character key. Some ASCII characters can't be typed or don't require a modifier, that's where you must placeKEY_NONE
. Check usb_hid_keys.h for the available keys.
If multiple modifiers are required, you must use a bitwise OR to connect them:KEY_MOD_RALT | KEY_MOD_LSHIFT
.
For example, in locale_de.hZ
is saved asKEY_MOD_LSHIFT, KEY_Y
.
This is because German keyboards use QWERTZ instead of the QWERTY layout and since the letter is uppercase, shift must be pressed as well.
Thankfully you don't have to trial and error everything, the Hak5 Community translated a lot of layouts already here. It's just written in a different syntax. For example,ASCII_20
(20 in hexadecimal) is the 32th character in our ascii array. - Modify or create the extended ASCII array.
The extended ASCII array doesn't have a fixed size and is only as long as you make it. First the character code. For example, ä has the index 132, or 84 in hex. It doesn't use a modifier and sits where the apostrophe key is on a US keyboard:0x84, KEY_NONE, KEY_APOSTROPHE, // ä
. - Modify or create the UTF-8 array.
The UTF-8 array is variable in length, too.
The first 4 bytes are the character code.
For example, Ä has the hex code c384 or 0xc3 0x84. The other 2 bytes are not used so we set them to 0. Because the letter is uppercase, we need to press the shift key and like before, the letter is typed by pressing the same key as the apostrophe key of a US keyboard:0xc3, 0x84, 0x00, 0x00, KEY_MOD_LSHIFT, KEY_APOSTROPHE, // Ä
. - Edit the hid_locale_t structure.
If you renamed all variables accordingly, there's nothing left to do. - Go to duckparser.cpp at
// LOCALE (-> change keyboard layout)
you can see a bunch of else if statements. You need to copy one for your layout.
Before adding GB layout:
if (compare(w->str, w->len, "US", CASE_SENSETIVE)) {
keyboard::setLocale(&locale_us);
} else if (compare(w->str, w->len, "DE", CASE_SENSETIVE)) {
keyboard::setLocale(&locale_de);
}
After adding GB layout:
if (compare(w->str, w->len, "US", CASE_SENSETIVE)) {
keyboard::setLocale(&locale_us);
} else if (compare(w->str, w->len, "DE", CASE_SENSETIVE)) {
keyboard::setLocale(&locale_de);
} else if (compare(w->str, w->len, "GB", CASE_SENSETIVE)) {
keyboard::setLocale(&locale_gb);
}
- Test your layout with a Ducky Script that contains all characters of your keyboard. For example:
LOCALE DE
STRING !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_abcdefghijklmnopqrstuvwxyz{|}~²³äöüÄÖÜ߀°§`
ENTER
- Add a link to your layout to this README and please feel free to improve this tutorial to help future translators!
- Create a Pull Request
This software is licensed under the MIT License. See the license file for details.