最近闲着无聊,本着生命在于折腾的本质,用 Digispark 做个 BadUSB 玩玩。
Digispark 长这样:

简单介绍下 Digispark 这个小玩意儿:
Digispark USB Development Board 是一块基于 ATTiny85 微控制器的开发板,便宜小巧携带方便,某宝上十块包邮,相比于 BadUSB 的老前辈 USB Rubber Ducky 简直是便宜到家了好吗,性价比真的超高。绝不承认不买 Rubber Ducky 是没钱,哼!
关于 BadUSB,网上很多人都觉得只是含有有害程序的 U 盘,并以为可以通过格式化、禁止 U 盘自启动来阻止 BadUSB 的攻击。但其实它更像是没有按键的键盘,靠着烧录进去的程序来模拟人类输入,计算机是无法识别出 BadUSB 和人类正常输入的区别的。所以大家记得一定不要随便在自己或公司的电脑上插来历不明的 U 盘!
配置 Digispark 开发环境
要使用 Digispark 制作 BadUSB,首先要安装开发环境,在这里选择 Arduino。我的开发环境是 macOS,所以后续介绍以 macOS 为准。
可以在 Arduino 官网上选择适配自己开发环境的安装版本。
安装好 Arduino 后,在 Preferences -> Additional Boards Manager URLs 处输入:
http://digistump.com/package_digistump_index.json
接下来在 Tools -> Board -> Boards Manager,安装 Digistump AVR Boards 包。
等待安装好,选择 Tools -> Board -> Digistump AVR Boards -> Digispark(Default - 16.5 Mhz),此时 Arduino IDE 就可以成功识别 Digispark 开发板了。居然没有出现驱动方面的问题,撒花
编写一份 helloworld 吧!
既然是第一次玩 Digispark 开发板,怎么能不写一份 hello world 呢:
#include "DigiKeyboard.h"
void setup() {
// put your setup code here, to run once:
DigiKeyboard.sendKeyStroke(0);
DigiKeyboard.delay(2000);
DigiKeyboard.sendKeyStroke(KEY_R, MOD_GUI_LEFT); //GUI 键在 macOS 下是 ⌘ 键,在 Windows 下是徽标键
DigiKeyboard.delay(300);
DigiKeyboard.println("notepad");
DigiKeyboard.delay(300);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(300);
DigiKeyboard.println("hello, world!");
DigiKeyboard.delay(300);
}
void loop() {
// put your main code here, to run repeatedly
}
点击 Verify 验证一下代码以防出错,然后就……报错了……
此处 Error 信息:
fork/exec ~/Library/Arduino15/packages/arduino/tools/avr-gcc/4.8.1-arduino5/bin/avr-g++: bad CPU type in executable
Error compiling for board Digispark (Default - 16.5mhz).
STFW 找到了原因:从 macOS Catalina 开始,不再支持 32 位程序,所以需要替换掉 Digispark 自带的 32 位 AVR 编译工具。
在 terminal 里运行:
cd ~/Library/Arduino15/packages/arduino/tools/avr-gcc
mv 4.8.1-arduino5 orig.4.8.1
ln -s /Applications/Arduino.app/Contents/Java/hardware/tools/avr 4.8.1-arduino5
再次验证,提示已经成功编译。
烧录代码
现在就可以上传代码到硬件上了,点击 Upload,在 60 秒内插入 Digispark 开发板完成上传。
Running Digispark Uploader...
Plug in device now... (will timeout in 60 seconds)
> Please plug in the device ...
> Press CTRL+C to terminate the program.
> Device is found!
connecting: 16% complete
connecting: 22% complete
connecting: 28% complete
connecting: 33% complete
> Device has firmware version 2.2
> Device signature: 0x1e930b
> Available space for user applications: 6522 bytes
> Suggested sleep time between sending pages: 7ms
> Whole page count: 102 page size: 64
> Erase function sleep duration: 714ms
parsing: 50% complete
> Erasing the memory ...
erasing: 55% complete
erasing: 60% complete
erasing: 65% complete
> Starting to upload ...
writing: 70% complete
writing: 75% complete
writing: 80% complete
> Starting the user app ...
running: 100% complete
>> Micronucleus done. Thank you!
将板子插入受害者朋友的 Windows 设备上,就可以看到运行 notepad 并输出 hello world 了。
更进一步
现在可以尝试自己写一个 payload 了。
其实利用 BadUSB 的攻击过程,就是将 Digispark 开发板伪装成为一个 HID(Human Interface Device)。
HID(Human Interface Device)人机接口设备类别是 Windows 最早支持的USB类别。由其名称可以了解 HID 设备是计算机直接
与人交互的设备,例如键盘、鼠标和游戏杆等。不过 HID 设备不一定要有人机接口,只要符合 HID 类别规范,就都是 HID 设备。
可以通过添加、修改注册表项,下载执行脚本,执行命令,结束进程等达到一系列我们想要实现的结果。 现在网上给 BadUSB 准备的脚本多为给 Rubber Ducky 准备的,还好我们可以进行转换,其实原理都是一样的,只不过实现代码不同。 Rubber Ducky 的代码长这样:
DELAY 600
REM Linux run dialog
ALT F2
DELAY 200
REM Mac OS run dialog
GUI SPACE
DELAY 200
REM On Windows this changes the input language, so press 3 times
GUI SPACE
DELAY 200
GUI SPACE
DELAY 200
GUI r
DELAY 200
REM On another OS, this could have typed " r". Backspace 4 times.
DELETE
REPEAT 4
REM Type in URL and open page!
STRING http://example.com/
ENTER
以上脚本是模拟键盘在各种操作系统上的打开指定网页的操作。
可以使用 dckunio.js 来在线转换,也可以使用 duck2spark 脚本来进行转换。
上面的脚本转换好了长这样:
/*
* Generated with <3 by Dckuino.js, an open source project !
*/
#include <avr/pgmspace.h>
#include "DigiKeyboard.h"
const char line1[] PROGMEM = "http://example.com/";
char buffer[256];
#define GetPsz(x) (strncpy_P(buffer, (char*)x, 256))
#define KEY_UP_ARROW 0x52
#define KEY_DOWN_ARROW 0x51
#define KEY_LEFT_ARROW 0x50
#define KEY_RIGHT_ARROW 0x4F
#define KEY_LEFT_GUI 0xE3
#define KEY_ESC 0x29
#define KEY_TAB 0x2B
void digiBegin() {
DigiKeyboard.sendKeyStroke(0,0);
DigiKeyboard.delay(50);
}
void digiEnd() {
const int led=1;
pinMode(led, OUTPUT);
while (1) {
digitalWrite(led, !digitalRead(led));
DigiKeyboard.delay(1000);
}
}
void printText(char *txt) {
DigiKeyboard.print(txt);
DigiKeyboard.update();
}
void setup() {
digiBegin();
DigiKeyboard.delay(600);
// Linux run dialog
DigiKeyboard.sendKeyStroke(KEY_F2,MOD_ALT_LEFT);
DigiKeyboard.delay(200);
// Mac OS run dialog
DigiKeyboard.sendKeyStroke(KEY_SPACE,MOD_GUI_LEFT);
DigiKeyboard.delay(200);
// On Windows this changes the input language, so press 3 times
DigiKeyboard.sendKeyStroke(KEY_SPACE,MOD_GUI_LEFT);
DigiKeyboard.delay(200);
DigiKeyboard.sendKeyStroke(KEY_SPACE,MOD_GUI_LEFT);
DigiKeyboard.delay(200);
DigiKeyboard.sendKeyStroke(KEY_R,MOD_GUI_LEFT);
DigiKeyboard.delay(200);
// On another OS, this could have typed " r". Backspace 4 times.
for(int i = 0; i < 4; i++) {
DigiKeyboard.sendKeyStroke(KEY_DELETE);
}
// Type in URL and open page!
// http://example.com/
printText(GetPsz(line1));
DigiKeyboard.sendKeyStroke(KEY_ENTER);
digiEnd();
}
/* Unused endless loop */
void loop() {}
首次烧录完,插入受攻击的设备没能正常实现功能,可能是驱动问题(部分情况耐心等待即可)、中文输入法问题(可以通过大写锁定键进行绕过)、不同操作系统快捷功能键不同,找到出现问题的步骤进行调试即可。
如果不会编写 Rubber Ducky 脚本或者 Digispark 脚本,可以根据自己的攻击思路在 DuckToolkit 生成 Rubber Ducky 的 Payload,然后进行转换即可。
另外,Digispark 开发版元件都是直接暴露出来的,这样容易造成短路等物理损坏。可以用热缩管将开发板隔离一下,或者是 3D 打印个 U 盘的外壳来进行伪装。用这个来做 BadUSB 搞社工成本还是很低的,只要在目标公司附近摆个「扫码领 U 盘」的活动就可以了,毕竟人才是最脆弱的安全系统。
参考: