Sys-usb kill switch, anti-tampering script and heuristic "attack detection"

why?

using USB devices are unavoidable sometimes this Is a way i found to make it even more secure trough mostly boredom and what If questions.
In no way I want to disregard the amazing work all the maintainers and developers of QubesOS have done, this is just a way I thought of making it even more secure at the cost of considerable ease of use I understand absolutely why this is not a thing by default
this approach has two big advantages:

1. using unknown/untrusted USBs as a direct hint to an attempt of unauthorized access
in this case we’d be using random unknown USB devices being plugged in as a heuristic sign of an attack since this script makes it easy for you to setup all your USB devices which saves each device as a different pattern for grep to ignore so none or all trusted devices and anywhere in-between can be plugged in at once so if any unknown device is plugged in the script would assume its an attacker shutting down your device (gracefully by default but can be easily changed) taking all encryption keys off of ram and massively decreasing attack surface to essentially hardware or encryption attacks which having your machine on all the time wouldn’t protect you from anyways so its way more desirable to have your system in this state if an attacker with physical access was trying to break into it.

2. minimizing damage from hardware USB keyloggers and making detection as best as a post disk passphrase service can
If an attacker plants a USB keylogger which are very inexpensive and easily available you’d probably would have no idea unless you physically check manually each time which is tiring, in this scenario you’d still would get your disk password compromised which is much worse than getting your user password compromised but would help you realize it as soon as possible..

disclaimer: this is currently in “beta” I’ve tested it myself which makes me confident enough to publish but this has not been thoroughly tested on any machine other than my own.
also if you have a USB keyboard you should add a second one into your trusted file so if your main keyboard breaks you won’t have to recover the system

how to do this?

it uses a simple bash script and a service in dom0 so we have access to qvm-usb to make sure we have a consistent output format from qvm-usb list and making sure we can shut off as soon as possible
create trusted db first
to create the trusted USBs “db” first plug in all USBs that you see yourself using regularly then run this command in dom0 (note this whole command is written inside the script verbatim if you want to copy it from there), this commands strips backend vm and devid + if its attached to any qube it will strip that text also to make sure you only get the actual device ID for the pattern matching in the script note what path you have your trust db in and edit it inside the script if its different

qvm-usb list | awk '{if ($NF ~ /\)$/) { $(NF-1)=""; $NF=""; sub(/ +/, " "); $1="" }print}' >>  trusted

now we must make the script which is meant to run as a file copy the code below into a file also in dom0

#!/usr/bin/env bash
set -o pipefail
trustedfile=/home/user/trusted # change here for wheres your trusted file 
# generate trusted file by running qvm-usb list | awk '{if ($NF ~ /\)$/) { $(NF-1)=""; $NF=""; sub(/ +/, " "); $1="" }print}' >>  trusted
trustdb_usbs=$(cat $trustedfile | tr '\n' '|' | sed 's/.$//' ) || exit 1
# change newlines to | instead so each entry in trusted will be a different pattern for grep
i=0
z="z"
#forever loop so it can be setup as a user service 
while true; do  
	sleep 1
	#make sure sys-usb is running every 10 iterations
	if ((i > 10)) || [[ "$z" = "z" ]] ;then
		i=0
		if ! qvm-check --running sys-usb &> /dev/null ;then 
			#sys-usb isnt running so sleep and check again later
			sleep 10
			z="z"
			continue
		else 
			#sys-usb is running so we unset z to make sure we dont keep running the test infinitely
			unset z
		fi
	fi 
	if qvm-usb list | grep -vE "$trustdb_usbs" ;then
		#untrusted usb has been plugged in
		notify-send -u critical "usb-killer" "USB PLUGGED SHUTTING DOWN.."
		systemctl poweroff --now
		echo "usbKillSwitch activated at $(date)" >> ~/.usbKill.log
		break
	fi
	((i++))
done

copy this to a file in /usbkill.sh (easier to type in dom0) then in dom0 run

qvm-run -p <source_domain> cat /usbkill.sh >  UsbKillSwitch.sh

after you’ve looked at the code and it looks good to you save the file and set it as executable with chmod +x killswitch.sh. also remember to change the trusted file path if its different in your machine

now we should make a service to have our killswitch running on the background all the time

mkdir -p ~/.config/systemd/user/ && nano ~/.config/systemd/user/usb_Kill_Switch.service

then paste the following (I don’t have much experience with systemd services please correct me if I’m doing something wrong)

[Unit]
Description=shutdown system if any untrusted usb is plugged in 

[Service]
ExecStart=/home/user/UsbKillSwitch.sh #adjust change path if needed
Restart=on-failure
RestartSec=5

[Install]
WantedBy=default.target

then enable your service

systemctl --user enable --now usb_Kill_Switch.service

now antime a usb gets plugged in which Isn’t inside your trusted file the system will automatically shutdown!
please let me know if I’m missing something or something could’ve been done better this was a hobby project for me I thought I’d share with the community, pretty niche but I hope this would be to some use to someone…

2 Likes

taking all encryption keys off of ram

What encryption keys exist in sys-usb?

shut off as soon as possible

Could you explain why this is necessary?

now antime a usb gets plugged in which Isn’t inside your trusted file the system will automatically shutdown!

On a system with USB keyboard, this makes it practically a requirement to always have a spare one that must be added as trusted beforehand, otherwise a broken keyboard will result in an unusable system. Have you thought about this?

1 Like

now antime a usb gets plugged in which Isn’t inside your trusted file the system will automatically shutdown!

You could just use usbguard to deny that device.

2 Likes

What encryption keys exist in sys-usb?
the disk encryption keys in dom0 and any other encryption keys in any other running VMs this is supposed to run in dom0 which would shut down the whole system.

“shut off as soon as possible”
Could you explain why this is necessary?
In this case we’d be using a random untrusted USB as an attack detection since the script since you’re probably not plugging in a USB because you were the one that set all of this up so it assumes its an attacker and gracefully shuts down the system which reduces attack surface to next to nothing which is ideal if an attacker is really trying to get in and has physical access to your device

On a system with USB keyboard, this makes it practically a requirement to always have a spare one that must be added as trusted beforehand, otherwise a broken keyboard will result in an unusable system. Have you thought about this?
this is a edge case I have not thought of, I guess you could get the same keyboard again and make it work or set init to bash in grub kernel opts and delete the service but thats still not ideal I’ll update the guide to include a disclaimer for that, thanks for the feedback!

this is probably best option for 99% of people but this was basically a “would be pretty cool if it could do that” kind of project and I’m pretty happy with the results and wanted to share.

@null1

What encryption keys exist in sys-usb?
the disk encryption keys in dom0 and any other encryption keys in any other running VMs this is supposed to run in dom0 which would shut down the whole system.

I am asking explicitly about sys-usb as no USB device gets connected to any other qube without explicit approval, i.e. everything is limited to sys-usb and its memory. It is not possible sys-usb to read anything from dom0 or any other qube. I hope you can review the question.

shut off as soon as possible
Could you explain why this is necessary?
In this case we’d be using a random untrusted USB as an attack detection since the script since you’re probably not plugging in a USB because you were the one that set all of this up so it assumes its an attacker and gracefully shuts down the system which reduces attack surface to next to nothing which is ideal if an attacker is really trying to get in and has physical access to your device

I really don’t understand why dom0 must be shut down if an unknown USB device gets plugged in. If that is really necessary, then the very existence of sys-usb is futile and we should assume Qubes is just as vulnerable as conventional bare-metal Linux.

Detecting an unknown USB device may be a valid attack indicator for @null1 .
It’s not a question of “what can they steal/copy from sys-usb”, it’s an answer to the question: “are we being cooked?”, in @null1’s threat model.

Right. I hope you do now.

1 Like

Your answer is valid if you want to prevent unknown USB devices from being connected… BUT… @null1 tries to achieve something else. See my previous reply in this thread: Post #7

1 Like