Duckyconvert

Table of Contents
  1. Background
  2. Usage
  3. Example
  4. Download

Background

The USB Rubber Ducky is a very interesting tool with many possibilities in the realm of physical hacking, but it's a little pricy for a keyboard HID. We can use a cheaper, programmable microcontroller to act as a keyboard HID and convert duckyscript to C code. duckyconvert can output code for Arduino, Teensy, or Digispark microcontrollers, but it is not able to replicate the Mass Storage Device feature that the USB Ducky has.

Out of the three types of microcontrollers that duckyconvert can output code for, I recommend the Teensy LC for its full keyboard HID capability and low price. But if you're looking for an extremely cheap option, then the Digispark ATtiny85 board can be bought for even cheaper, although the microcontroller uses software bit-banged USB and does not have a complete keyboard HID library, but should not be an issue for duckyscript commands.

While there may be numerous duckyscript to Arduino converters on the internet, none of them follow the specification properly, and some don't even work for some commands. Many of the converters were missing DEFAULT_DELAY, and modifier keys weren't being handled correctly. So, I wrote my own converter with a few extra features and a little optional extension on the specification to have it able to handle more keystrokes.

Usage

The duckyscript syntax specification can be viewed on GitHub.

Using duckyconvert:

python3 duckyconvert.py duckyfile.txt arduinocode.ino --led LED_BUILTIN

This will convert the duckyscript file duckyfile.txt into Arduino code to arduinocode.ino.

It also uses the default LED pin, LED_BUILTIN, as a status for what the HID is currently doing. The LED will blink rapidly while waiting for keyboard recognition, remain lit while typing the payload, and blink slowly when it is finished. Duckyconvert by default will not use the LED.

Note that Digispark ATtiny85 does not have LED_BUILTIN. The ATtiny85 I used had the LED pin as 1, so it would be used with the argument --led 1.

Example

An example that writes a text file onto the desktop of a Linux system:

python3 duckyconvert.py ducky.txt code.ino -l LED_BUILTIN

ducky.txt:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
DEFAULT_DELAY 25

REM spawn terminal
CTRL-ALT T
DELAY 300

REM move to bottom corner of screen
ALT F7
SHIFT DOWN
REPEAT 14
ENTER

REM payload
STRING echo "u dun got hecked, son" > ~/Desktop/hacked.txt
ENTER

REM exit
STRING exit
ENTER

code.ino:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
//Generated by DuckyConvert v1.1, written by WiLGYSeF

#include <stdarg.h>

#include <Keyboard.h>

#define KEY_SPACE ' '

#define KEY_PRINTSCREEN 0xce
#define KEY_SCROLL_LOCK 0xcf
#define KEY_PAUSE 0xd4
#define KEY_NUM_LOCK 0xdb
#define KEY_MENU 0xed

void setup()
{
	Keyboard.begin();

	pinMode(LED_BUILTIN, OUTPUT);

	//wait for keyboard initialization
	for (int i = 0; i < 13; i++)
	{
		digitalWrite(LED_BUILTIN, HIGH);
		delay(75);
		digitalWrite(LED_BUILTIN, LOW);
		delay(75);
	}

	delay(50);

	digitalWrite(LED_BUILTIN, HIGH);


	//spawn terminal
	keycombo('T', 2, KEY_LEFT_CTRL, KEY_LEFT_ALT);
	delay(25);
	delay(300);

	//move to bottom corner of screen
	keycombo(KEY_F7, 1, KEY_LEFT_ALT);
	delay(25);
	keycombo(KEY_DOWN_ARROW, 1, KEY_LEFT_SHIFT);
	delay(25);

	for (int _repeat = 0; _repeat < 14; _repeat++)
	{
		keycombo(KEY_DOWN_ARROW, 1, KEY_LEFT_SHIFT);
		delay(25);
	}

	typekey(KEY_RETURN);
	delay(25);

	//payload
	Keyboard.print("echo \"u dun got hecked, son\" > ~/Desktop/hacked.txt");
	delay(25);
	typekey(KEY_RETURN);
	delay(25);

	//exit
	Keyboard.print("exit");
	delay(25);
	typekey(KEY_RETURN);
	delay(25);

	Keyboard.end();
}

void loop()
{
	digitalWrite(LED_BUILTIN, HIGH);
	delay(500);
	digitalWrite(LED_BUILTIN, LOW);
	delay(500);
}

void keycombo(int key, int mcount, ...)
{
	va_list args;
	va_start(args, mcount);

	for (int i = 0; i < mcount; i++)
		Keyboard.press(va_arg(args, int));

	if(key != 0)
		Keyboard.press(key);

	Keyboard.releaseAll();
}

void typekey(int key)
{
	Keyboard.press(key);
	Keyboard.release(key);
}

Download

Download duckyconvert here.

You can find examples of payloads here.