flipperdevices / flipperzero-firmware

Flipper Zero firmware source code
https://flipperzero.one
GNU General Public License v3.0
12.42k stars 2.67k forks source link

A way to change the USB device ID when doing Bad USB #1018

Closed orangeglo101 closed 2 years ago

orangeglo101 commented 2 years ago

It would be really nice if we could configure the virtual device id for the Bad USB keyboard. For example, this would let us bypass the Apple "Keyboard Setup Assistant" that pops up when you connect a non-apple keyboard. It would be super useful!

skotopes commented 2 years ago

I'll add it to backlog. We'll return to this ticket after RPC refactoring

zhovner commented 2 years ago

Can you please tell more about this. What VID/PID can bypass Apple Keyboard Setup Assistant?

orangeglo101 commented 2 years ago

Can you please tell more about this. What VID/PID can bypass Apple Keyboard Setup Assistant?

Well I was researching how the Hak5 Rubber Ducky 2.1 does it. Looks like they have a firmware where you can set the VID/PID. I read that using the VID/PID from an Apple keyboard would bypass the setup screen. I found the list of VID/PIDs to use with the Hak5 Rubber Ducky here on github. It would be super useful to choose whatever VID/PID we want in order to pretend to be any USB HID device!

Thanks!

ynadji commented 2 years ago

I'm interested in tackling this, but could use some pointers to help me get started.

First, I need to see where the VID/PID are set. These two fields are part of the usb_device_descriptor struct. Looking for where these get set in the code, I see hid_device_desc and the values seem reasonable based on the USB ID repository (Logitech Keyboard & Mice). Later, usb_hid is defined in the FuriHalUsbInterface struct. Finally, FuriHalUsbInterface appears in bad_usb_app, but this is where my "understanding" breaks down. Some questions:

Second, how can I get user input? Can you recommend some code to read for this? Both values are uint16_t specified in hex. Is there a reduced keyboard that's just 0-f? Or just use the normal keyboard?

Would love any pointers in the right direction! If my read on this is close to accurate, it seems like a good first contribution.

skotopes commented 2 years ago

@ynadji @orangeglo101 please tag @nminaylov to get answers )

nminaylov commented 2 years ago

@ynadji Each USB device mode in flipper is described by FuriHalUsbInterface structure, which contains some basic device information (device, configuration, string descriptors) and callbacks. VID/PID pairs are located in device descriptors, also there are 3 string descriptors for manufacturer name, device name and serial. You shouldn't directly access FuriHalUsbInterface structure fields from application code, also most of device descriptors now are const and can't be changed on-the-fly.

In BadUSB and most other apps furi_hal_usb_set_config is called twice: on app start and app stop. First time it's called to change USB mode to new mode, second time - to restore previous mode (which was got by furi_hal_usb_get_config). usb_mode_prev is just a temporary pointer to store previous USB mode struct.

Which type of user input do you need? HID device code currently supports sending keybord key presses, mouse moves and consumer control events. For sending keyboard presses you can use furi_hal_hid_kb_press/furi_hal_hid_kb_release/furi_hal_hid_kb_release_all. Keyboard is standard 101-key. You can look for keyboard keys/modifiers codes in furi_hal_usb_hid.h

ynadji commented 2 years ago

Thanks @nminaylov, that was very helpful! I'll just define a new FuriHalUsbInterface struct that gets around this particular issue and it'll be easy to add others if there's reason to do so. This will make the user input problem easier as well, since it'll just be from a fixed selection of possible devices to emulate.

ynadji commented 2 years ago

Just as an update, I've managed to find the right set of options to bypass the keyboard assistant on my branch. Once I figure out how to choose which FuriHalUsbInterface to use from the UI I'll open a PR.

skotopes commented 2 years ago

Implemented in 0.52.0