Want to learn more about BadUSBs? Check out our online course: learnbadusb.com
This open-source project aims to provide a user-friendly tool to learn about keystroke injection attacks and 'BadUSBs'.
By emulating a USB keyboard, tools like this can gain full access to any computer with a USB port in a matter of seconds!
This is made possible by the fact that keyboards are trusted by computers. You can have full control over a computer with just a keyboard.
A BadUSB pretends to be a keyboard to the computer to send keystrokes.
But unlike a human, it can type hundreds of characters per second.
By using a simple scripting language, it's easy to make BadUSBs type whatever you want.
With the WiFi Duck, you can simply connect via WiFi to manage all scripts from within a web interface. This means that, unlike other BadUSBs, you don't need to install an app, log in, compile or copy scripts to an SD card.
wifiduck
with the password wifiduck
192.168.4.1
Settings
(top right corner) and update SSID and passwordHelp I forgot the password:
Flash the ESP8266, but make sure that you select Erase Flash: Sketch + WiFi Settings
under Tools in the Arduino IDE.
If you have further questions, check out the issue section.
Hey, do you like this kind of project?
It took a huge amount of effort to create!
To make sure we can keep working on free and open-source projects like this,
please consider becoming a :heart: Sponsor or support us via :coffee: Ko-fi.
Visit spacehuhn.com to learn more about us. :chicken:
A nicely encased, inconspicuous looking BadUSB by Maltronics.
Having USB-A and USB-C makes it compatible with all kind of devices.
It comes flashed with the WiFi Duck firmware and works plug and play.
ℹ️ Documentation can be found here
A custom designed development board which comes preflashed with this software by Travis Lin.
You can update the ESP8266 over the air and flash the Atmega32u4 via Arduino, all while enclosed in its neat little case.
📺 Watch the How to Update Tutorial here.
If you wish to develop your own software or help improve this one, the 8-bit DIP-switch makes it easy for you to access the Atmega32u4 or ESP8266 independently. For more info see Flash Software.
Mode | Atmega32u4 | ESP8266 | DIP-switch | Image |
---|---|---|---|---|
Default Operating Mode | USB | On | 10101101 | ![]() |
Atmega32u4 Flash Mode | USB | Off | 10101010 | ![]() |
ESP8266 Flash Mode | Off | USB | 01011101 | ![]() |
To build a WiFi Duck yourself, you need the following hardware:
To flash the microcontrollers you need a computer and USB cable.
If you're a beginner, it's recommended you wire everything together on a breadboard first!
In this case, you'd also need a breadboard with a couple of jumper wires.
If you wish to solder everything together into a small gadget, you also need soldering equipment.
You can use any Atmega32u4 or ESP8266 based development board,
but if you have no idea where to start, here's a list.
:warning: Keep in mind that you will need both microcontrollers!
The Atmega32u4 to act as USB keyboard, and the ESP8266 for WiFi.
:bangbang: DIGISPARK or other ATTINY85 based development boards, are NOT supported! :bangbang:
A map of pins that need to be connected.
ESP8266 | Atmega32u4 |
---|---|
D1 alias GPIO 5 |
3 alias SCL |
D2 alias GPIO 4 |
2 alias SDA |
GND |
GND |
Ideally, you want the Atmega32u4 to power the ESP8266, so it can run on one USB connection, instead of having to always plug in both.
To share power between both chips, you need a voltage regulator that takes 5V and turns it into 3.3V.
That's because USB runs on 5V, but the ESP8266 only takes 3.3V. Luckily most development boards have such a regulator on board.
DO NOT CONNECT ESP8266 VCC to the ATMEGA32u4 VCC, it will kill the ESP826. Instead look for the 5V
or VIN
pin on your dev board, as those will be connected to the regulator.
ESP8266 Dev Board | Atmega32u4 |
---|---|
5V or VIN |
RAW , 5V or VIN |
To add a Neopixel (WS2812b) LED:
Atmega32u4 | Neopixel LED |
---|---|
7 * |
DI alias Data , In |
5V alias VCC |
5V alias VCC |
GND |
GND |
* The Data pin can be changed later on in the software, pin 7 is just an example.
To make the DIY process easier, I designed a little PCB.
You solder a Pro Micro board on one side and a Wemos d1 mini or NodeMCU board (depending on the PCB) on the other side.
That's it. You don't even have to solder all pins,
just the ones mentioned in Connections, excluding the LED.
Design Files:
You can also order them on OSHPark:
File
> Preferences
.https://raw.githubusercontent.com/SpacehuhnTech/arduino/main/package_spacehuhn_index.json
. You can add multiple URLs, separating them with commas.Tools
> Board
> Board Manager
, search for wifi duck
and install WiFi Duck AVR Boards
and WiFi Duck ESP8266 Boards
.If you can't find the COM port of ESP8266 board, then you're probably missing the right drivers. Here are links to drivers of the 2 most used UART chips on ESP8266 development boards:
atmegaduck/atmega_duck.ino
with the Arduino IDE.Tools
> Board
in the WiFi Duck AVR
section, select your board;
for example, Sparkfun Pro Micro
.Tools
> Port
.Tools
you can enable the LED and set its pin.
You can also change the USB ID to make it appear as a certain type of keyboard.esp_duck/esp_duck.ino
with the Arduino IDE.Tools
> Board
in the WiFi Duck ESP8266
section, select your board.
For example NodeMCU 1.0 (ESP-12E Module)
.Tools
> Port
.Pro Tip: If the ESP8266 is already running this software
and you just want to update it, you don't have to connect it via USB.
You can update it over the air! Simply connect to the wifiduck
network (default password is wifiduck
).
Then in Arduino at Tools
> Port
you should now see a network port.
Select it and press Upload
.
Note: After the initial flashing, the ESP8266 has to format its memory, so it might take a minute until it's fully ready.
If you connected the RGB LED:
If you flashed your Atmega32u4 board with the wrong bootloader,
it will no longer appear in the port selection after you connect it.
To solve this, you need to:
RST
to ground GND
.
Preferably with a jumper wires, because you need to be able to disconnect it quickly. atmegaduck/atmega_duck.ino
or an empty sketch.Tools
> Board
!Upload
and as soon as you see Compiling...
turn to Uploading...
, disconnect the wire. Now it should flash the sketch and the correct bootloader.
Keys are separated by a single space.
Everything written in a single line gets pressed and released at the same time.
To write text, use the STRING function.
It's compatible to Ducky Script, which was developed by the wonderful people at Hak5.
Example | Explanation |
---|---|
WINDOWS r |
Type the Windows key and then the r key |
WINDOWS r | Press the Windows key and the r key simultaneously |
STRING WINDOWS r | Write WINDOWS r |
Command | Example | Description |
---|---|---|
REM |
REM Hello World! |
Comment |
DEFAULTDELAY or DEFAULT_DELAY |
DEFAULTDELAY 200 |
Time in ms between every command |
DELAY |
DELAY 1000 |
Delay in ms |
STRING |
STRING Hello World! |
Types the following string |
REPEAT or REPLAY |
REPEAT 3 |
Repeats the last command n times |
LOCALE |
LOCALE DE |
Sets the keyboard layout. List |
KEYCODE |
KEYCODE 0x02 0x04 |
Types a specific key code (modifier, key1[, ..., key6]) in decimal or hexadecimal |
LED |
LED 40 20 10 |
Changes the color of the LED in decimal RGB values (0-255) |
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 |
Key |
---|
NUM_0 - NUM_9 |
NUM_ASTERIX |
NUM_ENTER |
NUM_MINUS |
NUM_DOT |
NUM_PLUS |
REM Hello World for Windows PCs
DEFAULTDELAY 200
GUI r
STRING notepad
ENTER
STRING Hello World!
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 |
version | Returns version number | version |
settings | Returns list of settings | settings |
set -n/ame |
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 |
Renames file | rename example.duck example.txt |
write -f/ile |
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
!
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 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 supported keyboard layouts:
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.
#include "locale_xx.h"
to the end of the locales.h file.locale_xx.h
-> locale_de.h
,ascii_xx
-> ascii_de
,locale_xx
-> locale_de
,utf8_xx
-> utf8_de
.combinations_xx
-> combinations_de
, KEY_MOD_LSHIFT
, then a character key.
Some ASCII characters can't be typed or don't require a modifier,
that's where you must place KEY_NONE
.
Check usb_hid_keys.h for the available keys.KEY_MOD_RALT | KEY_MOD_LSHIFT
.Z
is saved as KEY_MOD_LSHIFT, KEY_Y
.ASCII_20
(20 in hexadecimal) is the 32th character in our ascii array. 0x84, KEY_NONE, KEY_APOSTROPHE, // ä
.~~ 0xc3, 0x84, 0x00, 0x00, KEY_MOD_LSHIFT, KEY_APOSTROPHE, // Ä
. // 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);
}
LOCALE DE
STRING !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}~²³äöüÄÖÜ߀°§`
ENTER
This tool is intended to be used for testing, training, and educational purposes only.
Never use it to do harm or create damage!
The continuation of this project counts on you!
This software is licensed under the MIT License. See the license file for details.
Software libraries used in this project: