Andrey Konovalov Turns a Hacked Lenovo ThinkPad Laptop Into a Flexible USB Device Emulator
By breaking into the BIOS and enabling Intel'x xDCI, Konovalov has turned a laptop into a USB emulator — no external hardware needed.
Security researcher and software engineer Andrey Konovalov has taught an old dog new tricks, turning a Lenovo ThinkPad laptop into a tool for emulating the USB device of his choice — by playing around with the Extensible Device Controller Interface (xDCI) controller.
"I figured out a way to turn my ThinkPad X1 Carbon 6th Gen. laptop into a programmable USB device by enabling the xDCI controller," Konovalov explains. "As a result, the laptop can now be used to emulate arbitrary USB devices such as keyboards or storage drives. Or to fuzz USB hosts with the help of Raw Gadget and syzkaller. Or to even run Facedancer with the help of the Raw Gadget–based backend. And do all this without any external hardware."
Having an easily-portable tool to do all of that is handy, but it wasn't exactly a plug-and-play operation. "The journey of enabling xDCI included fiddling with Linux kernel drivers, xHCI, DWC3, ACPI, BIOS/UEFI, Boot Guard, TPM, NVRAM, PCH, PMC, PSF, IOSF, and P2SB," Konovalov says, "and making a custom USB cable."
The Extensible Device Controller Interface (xDCI), Intel's implementation of a USB 3.0 Device Controller, allows something that would typically operate as a USB Host — in this case, a ThinkPad laptop — to act as a USB Device instead. In Konovalov's laptop the xDCI controller is present but disabled, with no option in the UEFI configuration to enable it. Searching through a firmware dump revealed the setting was present, but hidden — so Konovalov replaced the motherboard's SPI flash with a socketed version, providing an easy way to experiment.
With a modified firmware, the UEFI configuration provided access to a previously-hidden "Intel Advanced Menu" with xDCI support. Konovalov then booted into Linux and flipped a port into USB Device mode — figuring out which physical port it was by plugging a USB stick into each until finding the one that didn't work. With a hand-made USB Type-A to Type-A cable, that port could then be connected to another laptop and configured to emulate almost any USB device.
"The next thing I wanted to test was Raw Gadget," Konovalov writes, referring to a kernel module designed for greater flexibility in USB emulation. "Running Raw Gadget with xDCI for the first time was very exciting, as my desire to work on Raw Gadget on my laptop without external hardware was what conceived this project." With a small patch, Raw Gadget worked too —as did syzkaller, a Raw Gadget-based tool for "fuzzing" USB — sending unexpected data to see what happens. Facedancer, a Python USB emulation framework, also proved compatible.
"I suspect enabling xDCI should also be possible on other PCs," Konovalov says of the project's broader applicability. "In the simplest case, this might be as easy as turning on xDCI in BIOS settings. This should just work if there's proper ACPI and role-switching support and the xDCI-enabled port is wired to the external casing. I also believe it should be possible to enable xDCI purely via software. Even though I failed to do it by reconfiguring PCH, there are other approaches."
Konovalov's full write-up is available on his website.
Freelance journalist, technical author, hacker, tinkerer, erstwhile sysadmin. For hire: freelance@halfacree.co.uk.