My QubesOS computer is located somewhere that many people regularly pass by. It’s in a computer cage and motherboard bios password is set. Thus when the computer is off, I don’t have to worry about a quick fly by physical attack.
However, when QubesOS has already booted and the screen is locked and sys-usb is running with usb keyboard and mouse connected to it, can QubesOS be hacked merely by unplugging my usb keyboard and mouse out of my usb extension cable and placing a malicious keyboard or other malicious usb into my usb slot when the screen is locked? I always check the usb extension cable to make sure it hasn’t been tampered with before unlocking.
The qubes-os team should add a way to tell the lock screen that a usb device has changed, esp for situations without a sys-usb. Making a custom screen saver would add attack surface, but should be minimal.
I would stain or otherwise randomly mark the keyboard to make it harder to swap without you noticing. A splat of paint on a worn down sticker. Some hard to see scratches. Fuzzy coat or glitter nail polish over the screw holes. Or, if its safer, just keep your keyboard with you or somewhere else when not in use.
I don’t know what exactly you mean by hacked but generally anyone with a physical access can damage a system. It is not necessary that to be through malicious USB devices. I am thinking of powerful EM field, a cup of acid, a heater blower (or hair dryer), fine dust (especially metal) blown against the zone where the fans suck air, etc.
In regards to Qubes in particular, the OS will accept any USB keyboard by default (in case there is no PS/2 alternative configured). A possible attack is to switch to console mode, reboot the system, boot from a USB stick and all the rest of it.
If it’s in something like a rack in a data center, you could add a sensor reporting when it was opened, or cameras. You could also use your qubes os remotely through the network with sys-gui-vnc
I’m not convinced that for your threat model it’s enough to report about usb activity that happened on the system.
app-linux-input-proxyv1.0.44 (r4.3) app-linux-input-proxyv1.0.44 (r4.2)
A very interesting and exciting patch from security perspective. It is now possible to allow only certain USB input devices (Keyboards, Mice, Tablets) based on the vendor ID, Product ID or even the USB port it is connected to. This way, you could avoid most hardware keyboard loggers which usually could not fake the VID/PID (at the time of this post). This is very useful considering how such loggers have become so common these days everywhere and even open source implementations which could be easily implanted inside original devices are readily available. The only issue with this patch is that the documentation for it is not yet available. Tech-savvy users should not have problem to understand it and use it by reading the patch code and the related Github issue.
There’s githup page for it
I’m experimenting with it but only thing that I’ve achieved is that mouse pointer is not moving or keyboard don’t register special keys (CTRL, ALT) but mouse buttons still works and alphanumeric keys of keyboard also works - strange thing.
–
PS: OK, I have it, but it’s trial and error and I don’t know how to pull all relevant data
First, in a sys-usb terminal you need to list PCI devices to find usb controller to which mouse+keyboard is connected.
for me it’s
00:09.0 USB controller: Intel Corporation Alder Lake PCH USB 3.2 xHCI Host Controller (rev 01)
note device address - 00:09.0
Then you need devices vendor and product number - lsusb
mouse:
Bus 004 Device 018: ID 258a:0036 SINOWEALTH Wired Gaming Mouse
Vendor=258a Product=0036
keyboard:
Bus 004 Device 023: ID 0c45:8033 Microdia AK820MAX
Vendor=0c45 Product=8033
Then in dom0 in Qubes Policy Editor open 50-config-input.policy
default:
# THIS IS AN AUTOMATICALLY GENERATED POLICY FILE.
# Any changes made manually may be overwritten by Qubes Configuration Tools.
qubes.InputMouse * sys-usb @adminvm ask
qubes.InputKeyboard * sys-usb @adminvm ask
qubes.InputTablet * sys-usb @adminvm ask default_target=@adminvm
after changes (I’ve watched notification about mouse/keyboard denied in dom0):
# THIS IS AN AUTOMATICALLY GENERATED POLICY FILE.
# Any changes made manually may be overwritten by Qubes Configuration Tools.
qubes.InputMouse +usb-0000_00_09.0-1.4+3-258a-36-111 sys-usb @adminvm allow
qubes.InputKeyboard +usb-0000_00_09.0-1.3+3-c45-8033-110 sys-usb @adminvm allow
qubes.InputMouse +usb-0000_00_09.0-1.3+3-c45-8033-110 sys-usb @adminvm allow
qubes.InputTablet * sys-usb @adminvm ask default_target=@adminvm
+ is for one argument usb-0000_00_09.0 is from PCI list -1.4+3- and -1.3+3- dunno from where is taken 258a-36 and c45-8033 is from lsusb (leading zeros are omitted) -111 and -110 dunno from where are coming
But it works.
If I connect any other mouse/keyboard it shows notification about denied:inputMouse or denied:inputKeyboard
One thing - there was bug in qubes-app-linux-input-proxy package and it didn’t worked.
For this to work template must be upgraded to testing repository:
#!/bin/bash
#
# usb2sys - find lsusb device in /sys file system
#
die()
{
echo "$@"
exit 1
}
[[ $# -lt 1 ]] && die "need vendor and product ids (from lsusb) as dddd:dddd"
vendor=${1%:*}
product=${1##*:}
sys=/sys/bus/usb/devices/
cd $sys
for d in *; do
path=$sys$d
if [ -f $path/idProduct ]; then
prod=$( cat $path/idProduct )
vend=$( cat $path/idVendor )
if [ $prod = $product -a $vend = $vendor ]; then
echo prod = $prod
echo vend = $vend
echo /sys device is $path
fi
fi
done
If you have only a USB mouse connected to a USB qube, but the keyboard is connected directly to dom0 (using a PS/2 connector, for example), you simply need to lock the screen when you are away from your computer (assuming you don’t use the virtual keyboard of your screen locker). You must do this every time you leave your computer unattended, even if there no risk of anyone else having direct physical access to your computer. This is because you are guarding the system not only against anyone with local access, but also against possible malicious input from a potentially compromised USB qube.
If your keyboard is also connected to a USB qube, things are much harder. Locking the screen (with a traditional password) does not solve the problem, because the USB qube can simply sniff this password and later easily unlock the screen. One possibility is to set up the screen locker to require an additional step to unlock (i.e., two-factor authentication). One way to achieve this is to use a YubiKey, or some other hardware token, or even to manually enter a one-time password.
And what about laptops? I see that it says in Qubes Global Config that built-in keyboards are “usually not USB” so is there a list somewhere of laptops that are or aren’t? I don’t want to try it, only to go through the hassle of re-enabling it.
Macbook Pro’s use usb keyboards often with only one usb controller. So you can scrape that of your list
What’s confusing me is that if someone sticked in rubber ducky into the
the victim machine running Qubes, when you login doesn’t your sys-ub restart and flush all the bad stuff out? Or do you need anti evil maid for that?
This should be doable.
The PAM module pam_echo allows to present a file to the user before asking for the password. By adding the following line to the beginning of /etc/pam.d/xscreensaver, you will see the contents of the file /etc/loginmsg * with an OK button: auth optional pam_echo.so file=/etc/loginmsg
Then it is simply a matter of spotting suspect keyboard plug/unplug events, and putting them in the file. This is the tricky part, because it needs some kind of daemon to monitor usb activity …
I think xscreensaver-command -watch will allow to capture only events since the last screen lock event.
For the USB, I can think of either journalctl -f or some udev magic… **
Maybe someone more expert could advise. A log of HID changes seems like a useful addition for the more security conscious users. It might be nice to have it in /etc/issue, as well.
Notes:
* : /etc is the wrong place for such a file… probably it should be in /var
** : journalctl looks easier, but udev events are probably more correct.