Proposed procedure for using untrusted USB drives

This is a proposal for a procedure for using untrusted USB drives. I’m putting it in “user support” cause I’m looking for feedback on it. I am expecting many revisions. If we can get it into a solid working procedure, I’ll move it to “user support - guides”.

The situation:
You need to look at the contents of a USB flash drive that you found in the parking lot, or on your desk or whatever. The point is that we don’t trust the USB flash drive.

the rest of this post is a draft of a proposal

First, the AppVM one time setup procedure:
(do either the “easier version” or the “hardcore version”, not both)
Easier Version:

qvm-create --class AppVM --label gray --template debian-10  sys-usb-flashdrive-template
qvm-prefs sys-usb-flashdrive-template template_for_dispvms true

Hardcore version:

sudo qubes-dom0-update qubes-template-debian-minimal

qvm-create --class AppVM --label gray --template debian-minimal  sys-usb-flashdrive-template
qvm-prefs sys-usb-flashdrive-template template_for_dispvms true
(then apt-get install qubes-usb-proxy inside the debian-minimal template)

Next, the disposable VM one time setup procedure:

qvm-create -C DispVM -l red --template sys-usb-flashdrive-template disp-sys-usb-flashdrive
qvm-prefs disp-sys-usb-flashdrive virt_mode hvm
qvm-service disp-sys-usb-flashdrive meminfo-writer off
qvm-prefs disp-sys-usb-flashdrive autostart true
qvm-prefs disp-sys-usb-flashdrive netvm ''
qvm-prefs disp-sys-usb-flashdrive provides_network false
qvm-pci attach --persistent disp-sys-usb-flashdrive dom0:00_11.0
qvm-pci attach --persistent disp-sys-usb-flashdrive dom0:00_11.2

#qvm-features <sys-VMName> appmenus-dispvm ''

then add “disp-sys-usb-flashdrive $anyvm deny” as the first line of both these files:

/etc/qubes-rpc/policy/qubes.InputMouse
/etc/qubes-rpc/policy/qubes.InputKeyboard

Finally the procedure to use it:

  1. boot Qubes (without the flash drive in the USB socket)
  2. create a separate sys-usb2 for just that USB controller, leaving your other usb devices in a different sys-usb .
  3. set the policy for no keyboard and no mouse in sys-usb2 (probably somewhere in /etc/qubes-rpc/)
  4. start a disposable VM with no networking
  5. insert the USB flash drive into the correct usb socket to connect to sys-usb2 (note that the importance of doing this at this moment and not having the flash drive in at boot)
  6. Once the drive registers with qubes, then using the devices icon at the top, connect the flashdrive to the disposable VM
  7. use the disposable VM to view and interact with the files on the flash drive.
  8. when you are done, remove the flash drive from the USB socket
  9. destroy the disposable VM (by just closing it)
  10. then destroy disp-sys-usb-flashdrive (by shutting it down)

THE PROBLEM THAT IS STILL LEFT:
[Update: Several of the comments below argue that this won’t be a problem. See comments below for details]

However since many USB controllers forget to turn off the ability to reprogram the firmware, and if the flash drive can attack the firmware in the usb controller, then can’t the compromised USB controller itself act as a USB device during the next reboot in order to comprise dom0?

In the past I’ve attempted to find a USB controller card that gives some kind of guarantee that it has the ability to reprogram the controller disabled, but did not have luck.

Some references:

You can just make your sys-usb disposable and reboot it after usage with untrusted USB stick? I think it makes things much easier.

1 Like

Great idea. I’ll adjust the instructions

I agree.

You can just make your sys-usb disposable and reboot it after usage with untrusted USB stick? I think it makes things much easier.

I do this as standard, but go a little beyond that: use debian-minimal or fedora-minimal just with the minimal amount of required packages. So no usb mouse or usb keybord possible.
Then make a disposable VM template and then create a disposable sys-usb.

Of course, I do nor believe all this cancels the firmware attack issues at all, but may be wrong here.
Is there someone more knowledgeable than me that can elaborate on this?

i have not tried the “minimal” distributions yet. Supposing there is a pdf on the flash drive, or whatever, does debian-minimal include a pdf viewer to view it with? (and probably libreoffice or something to view doc files)

the minimal template is for the sys-usb. then you can mount the block device in another (maybe standard template) dispVM

i have not tried the “minimal” distributions yet

there is a thread on the forum that is very useful as a starting point:

so you can give it a try. I thinh this is a very good approach for sys-net, sys-usb, sys-firewall …

ok, so still have the application VM. We are just making a way to auto-destroy the sys-usb. Sounds good

Of course, I do nor believe all this cancels the firmware attack issues at all, but may be wrong here.

You are not wrong.
If the USB has attacked the controller, that’s it done. All the Qubes usb
shenanigans is no help.
The only way to deal with this is to reserve a controller for untrusted
USB devices. If you have only one controller, don’t use untrusted devices
at all.

2 Likes

Or, you can use all your untrusted devices exclusively inside the disposable sys-usb and never connect them to other AppVMs.

If you only have one controller every device will end up being
untrusted, and should not be shared with other users.
Because the threat is at the firmware level, the use of a disposable
sys-usb is neither here nor there. That addresses a different class of
threats.

2 Likes

Are there any PCIe USB controller cards (and/or laptop USB controller cards) that are known to not have the firmware vulnerable to USB devices?
I believe we are talking about designers leaving the JTAG open.
Alternatively, if we are talking about the USB taking control of the sys-usb qube and rewriting the usb controllers firmware from the computer side, then are there any known USB controllers that use static ROMS and not flash, or entirely ram that must be loaded after boot ( which would not make sense for those trying to USB boot)

1 Like

Very interesting topic. I would like to revive it, because I have an idea of how to mitigate the threat to USB controller firmware without any additional hardware. It should even work with a single USB controller, to which a keyboard is attached (exactly my situation). I would like to hear your opinion about this idea.

Threat model:
After reviewing a number of published USB attack vectors, it seems that direct reprogramming of USB controller from a USB device has not been documented, demonstrated, or even suspected. At least I couldn’t find any references. If anyone knows about it, please let me know. Check this out: “Researchers from the Ben-Gurion University of the Negev in Israel have identified 29 ways in which attackers could use USB devices to compromise users’ computers” (https://www.bleepingcomputer.com/news/security/heres-a-list-of-29-different-types-of-usb-attacks/). Note, that none of the 29 attacks involve reprogramming USB controller directly from a USB device. Let’s put that threat aside.

An easier attack vector would be to exploit USB driver volnurability, OS volnurability, or trick the user to gain control over OS, and then use use that control to re-flash the USB controller. This is the attack vector I’m trying to mitigate.

Solution Summary:
sys-usb qube has USB controller attached to it, however sys-usb only binds keyboard/mouse drivers to USB devices (with user permission of course). All other devices are delegated to other disposable qubes, where they are bound to appropriate drivers. If the driver qube is penetrated, it will not be able to access USB controller firmware, because neither USB controller nor any other PCI controller is attached to it. Thus usb drivers are removed from the attack surface. We can now trust sys-usb qube more.

Implementation:
We don’t need to change much in the existing system (maybe some usability improvements). It should be able to handle it as it is right now.

Step 1: run this script from a terminal in sys-usb qube (taken from https://www.kernel.org/doc/Documentation/usb/authorization.txt)

for dev in /sys/bus/usb/devices/usb* 
do  
	echo 0 | sudo tee $dev/interface_authorized_default > /dev/null
done

From now on, any new USB device plugged into the computer will be looked at by the USB host controller driver, interfaces queried, but no device driver will be attached.

Step 2: Start a disposable qube and attach your device there using Qubes OS gui or command line.

The target qube now has full control of the USB device. If it was a memory stick it will automatically be mounted. The sys-usb qube on the other hand still doesn’t have a device driver attached to any of the USB device interfaces, and all the interfaces are still deauthorized.

Result:
All device drivers are moved to other qubes. The attack surface is significantly reduced.

Problem remaining:
USB host controller driver still operates in sys-usb qube, and it’s not without potential problems: https://www.nccgroup.com/globalassets/our-research/uk/whitepapers/usb_driver_vulnerabilities_whitepaper_v2.pdf

2 Likes

Interesting. I know that Qubes uses USBip for some of the USB forwarding. USBip documentation says:

The device driver for the exported USB device runs on the client machine

which you can read details of here:
https://www.kernel.org/doc/html/latest/usb/usbip_protocol.html

So it sounds like your proposal is already done for most cases. However, I think the drivers for the keyboard and mouse are in sys-usb. (You can check this by running a terminal in your sys-usb and do a lsmod, then compare with lsmod in dom0.) They probably did this to keep those drivers out of dom0 (which seems like a good idea).

Now you still have the USBip driver in sys-usb and I don’t know how big of a target the USBip driver is. Also, it’s only one driver for all your USB devices, so at minimum it has reduced attack surface.

Note that if you have a USB printer, you should be able to load the printer driver in a qube that is seperate from your qube with the documents you want to print with this:

So maybe you want to create new intermediate service qubes and forward the keyboard from sys-usb to sys-keyboard and the mouse from sys-usb to sys-mouse, then do the handoff to dom0? (note: in the future there can be a handoff to sys-gui-gpu instead)

I would suspect that disabling them like that would mean that they wouldn’t get handed off to remote devices anymore, but maybe someone who knows more about how sys-usb does the device forwarding could answer here?

If we could find a PCIe USB card whos firmware either cannot be updated, or gets loaded during the boot sequence (getting loaded during the boot sequence is unlikely because if you used it for a USB keyboard, the keyboard would not work till boot (which would deny you BIOS access)), and if the card was able to be reset when we reset sys-usb, then I think we’d have something.

However, if such products exist, it’s not obvious how to find them as searches don’t turn up much.

1 Like

I agree that once the device is forwarded, it’s driver is run in a client qube. However there is a substantial period of time before users forward the device (or after they disconnect it) that the device driver is running in sys-usb qube. That can be clearly seen by running lsusb command in sys-usb qube. This exposure will be removed by disabling USB interfaces. And no, it doesn’t prevent USB devices from being forwarded.

On the second thought, I wonder if USB device drivers run in sys-usb qube on my computer simply because it is configured with USB keyboard. Is it the same for computers with PS2 keyboards? Can someone test it?

I’m not concerned much about keyboard USB drivers, because if the keyboard is malicious, it’s game over. They might as well run in sys-usb qube.

With respect to finding a USB controller (or any other hardware) confirming to Joanna Rutkowska’s vision of stateless laptop, they will sure solve a lot of security problems, but I’m skeptical we going to get them soon.

The usb-qube recognizing the USB device enough to list it with lsusb is one thing. It probably needs to identify what the device is before it forwards it. Does the driver automatically load when you plug something in? you can check that with lsmod

A thought occurs. If the usb device happens to be a storage device that sys-usb probably loads a driver for it, as sys-usb allows it to pass through a partition which would imply sys-usb would need some kind of code to be able to handle that.

With disposable sys-usb the impact is limited to a single session.

If you have your keyboard & mouse in dom0 on a dedicated controller (assuming you trust them sufficiently), impact is limited to compromise of one USB device by another during that session.

And yes, parsing block devices requires a driver in sys-usb.

Btw usbguard might interest you.

Does anybody have any idea on how to audit or dump micro-controller firmware. Probably JTAG only stuff, but have no idea. Probably it is more complex than this, but… Anybody?
I think this is what is missing for the most paranoid.

Regards

1 Like

If interfaces are deauthorized (as above) then the driver is NOT loaded. We will not be able to see partitions in this case, and must forward the whole device to another qube for parsing. I used lsusb -t to see which drivers are bound to which devices.