[code] Bluetooth Dead Man's Switch

202 views
Skip to first unread message

Andrew B

unread,
Apr 13, 2014, 11:27:53 PM4/13/14
to qubes...@googlegroups.com
I thought it might be a nice idea to have a dead man's switch in Qubes for cases of theft while the computer is running with the disk encrypted. The proposed solution in trac to apply the tresor kernel patches is a good one, but doesn't save the user from having their memory carved after a cold-boot attack.

Instead, my idea is to use a Bluetooth device as a sort of dead man's switch: when a certain Bluetooth device is near the computer and detectable, the dead man's switch is 'armed'. If that device disappears, the dead man's switch is 'triggered'. If the device doesn't reappear within a few minutes, the dead man's switch is 'paniced'. When the dead man's switch is 'paniced', a Dom0 agent [0) locks the screen,] 1) kills all running VMs, 2) syncs the disks, 3) luksSuspend's the crypto devices, 4) wipes memory, and [5) reboots (hopefully into some BIOS diagnostics that do an even more thorough memory test)].

So I have a proof-of-concept here, but it is lacking in a number of ways:
1) Without Dom0 kexec support, it's difficult to wipe _all_ memory. Ideally we would do what Liberte Linux does, which is kexec a new kernel and overwrite all physical memory.
2) There's no graphical interface or configuration
3) There are no packages (I'm not sure how to make Fedora packages and I'm not particularly interested in learning how right this moment)
4) There is likely a non-negligible battery life drain
5) In some cases the Bluetooth device is attached to a USB controller along with some external ports--those ports will not be attachable to any other AppVM

However, it has a number of benefits, including:
1) Any Bluetooth device can be used; it only needs to be detectable. It does not need to implement any functionality.
2) Assuming cryptsetup properly implements luksSuspend, crypto keys are quickly erased
3) (Most) free memory is overwritten
4) The lack of graphical configuration or notifications makes it somewhat 'invisible'
5) With a little more generalization, more than one dead man's switch can be used; the trigger condition could be if *any* switches fail (e.g., accelerometer indicates last 10s integrated gives displacement greater than some threshhold)

The idea is this: we have two components, or monitoring processes. One runs in Dom0 and is responsible for actually responding to the trigger. The other runs in an AppVM, which must have the computer's Bluetooth device attached, and is responsible for scanning for the target dead man's switch device. The only communication required between these two domains is for the Dom0 monitor to check if the contents of a file match a predetermined string (via qvm-run), and there is essentially no parsing needed. The AppVM monitor implements a simple finite state machine (stated in words in the second paragraph above), which uses bluez (and pybluez) to discover_devices() and check if the target dead man's switch device is among them. I chose the NetVM for this duty, since it is started at boot and is already responsible for isolating buggy network stacks.

The one known issue is that if the Dom0 monitor is started by cron or XFCE autostart, the lock screen functionality works, but qubes-guid has to be manually started for each AppVM domain (no idea why). If I launch the scripts with "nohup ... &", then there is no need to manually launch qubes-guid, but the screen locking does not work. Suggestions for fixing this are appreciated. I am quite sure I am not implementing the autostart features correctly! Also, the reboot functionality isn't included, but I think one can handle that with some sysrq magic (patches welcome...).



Now, here's how one can manually test these scripts on their own machine:
1) Install bluez and pybluez (and maybe the -devel package, too) onto the NetVM template. Attach the Bluetooth device to the NetVM.
2) Create a new folder in the NetVM called 'bluetooth'
3) Copy bt-dms-fsm.py and domU-dms-mon.sh to that folder; chmod +x them.
4) Edit bt-dms-fsm.py and insert your target dead man's switch device's Bluetooth address to target_address
5) Edit your NetVM's /rw/config/rc.local script and make it execute /home/user/bluetooth/domU-dms-mon.sh
6) Compile wiper-stage0.c on a trusted AppVM (or write your own; it's trivial to make one that writes rdrand data with Intel's provided rdrand library, but I won't post my version because I don't want to deal with licensing issues)
7) Copy the compiled wiper-stage0 and dom0-dms-mon.sh into a 'bin/' subdirectory of your Dom0 home directory; mark them executable
8) Edit the dom0-dms-mon.sh and replace the path to wiper-stage0 with the correct one
9) Copy the qubes-dms-mon.desktop file to /etc/xdg/autostart in Dom0
10) Edit the /etc/xdg/autostart/qubes-dms-mon.desktop file and replace the path to dom0-dms-mon.sh with the correct one.

The code can definitely use a lot of improvement and refinement. For example, is it better to have the two monitors communicate over a vchan instead of qvm-run'ing something in the NetVM every 10s? Does it provide a meaningful security benefit if users *can* have a TOTP-like auth code system, so that users with modifiable dead man's switch devices can have some protection from attackers who spoof Bluetooth addresses in order to fool the DMS? How can we fix the lockscreen issue? Should we make more of an effort to verify Bluetooth state in the monitor scripts? And many more questions might be asked...


Sorry for the essay. I hope this is useful to someone, and maybe if it gets (a lot) more polished it could become an (or probably two) official Qubes package(s).
Andrew
bt-dms-fsm.py
domU-dms-mon.sh
wiper-stage0.c
qubes-dms-mon.desktop
dom0-dms-mon.sh
0xB364F63E.asc
signature.asc

Joanna Rutkowska

unread,
Apr 14, 2014, 4:23:58 AM4/14/14
to Andrew B, qubes...@googlegroups.com
Hi Andrew,

This looks pretty cool and I'm glad you decided to split your code into
two parts, so that the one with the stinkin' bluez code is kept outside
of dom0 :) You should definitely replace you "qvm-run -p" call with a
simple qrexec service -- in that case you would not need to constantly
poll for the magic state file changes in the VM, but instead write a
trivial script that would just receive the info in Dom0 when your
monitoring code sends something to it. You can read more about how to
write qrexec code e.g. here:

http://theinvisiblethings.blogspot.com/2013/02/converting-untrusted-pdfs-into-trusted.html

As you write I think it would also be nice to have (perhaps as an
option) a somehow more robust BT device authentication mechanism. I
recall somebody on the list was trying to write support for token based
login authentication (so, a similar thing to your essentially: a program
in a select usbvm handles the token device, and sends the OTP password
to the dom0 via qrexec, the dom0 then pipes it to (perhaps)
gdm/screenlocker). It would be nice to combine those two efforts.
However, for using this to unlock the screenlocker in Dom0, the decision
should be made by Dom0, not by the monitor running in some AppVM. So,
just like written above, the monitor should only be sending out the OTP
password via qrexec to Dom0 process.

Of course various usual comments about coding style apply, such as:
don't hardcode e.g. appvm name in the code, adhere to our indent policy,
etc. Generally, please follow this:

http://wiki.qubes-os.org/trac/wiki/CodingStyle

Cheers,
joanna.

signature.asc

Tim hobbs

unread,
Apr 15, 2014, 1:36:11 PM4/15/14
to qubes...@googlegroups.com, Andrew B
If you place a peice of copper tape across your laptop's touchpad towards the place where you rest your hand while typing, you will be able to use the "fingure touching mouse pad" signal as a deadman's switch.  Simply lifting your hand from the keyboard would trigger a whipe.

Tim

Andrew B

unread,
Apr 17, 2014, 12:16:21 AM4/17/14
to Tim hobbs, qubes...@googlegroups.com
Sure you can, but that seems to be more of a literal _dead_ man's switch--I'm thinking this is more useful for casual coffee shops theft, mugging, etc.
It's not realistic to assume the user has their hands on the keyboard the whole time. Plus, that's not very stealthy... But, if you really want to do that,
just have the AppVM with the sensor attached run a monitor process that, when the hand moves off the strip, runs:
"/usr/lib/qubes/qrexec-client-vm dom0 qubes.DeadMansSwitch /bin/echo 1"
and set the appropriate policy in dom0's /etc/qubes-rpc/policy/qubes.DeadMansSwitch.
Thanks for the tips. The new, much-improved attached version (mostly) follows the coding guidelines, implements a qrexec RPC service, correctly locks the screen, uses config files for tunable parameters, and reboots the machine after the memory wipe. This memory wipe could be made even more thorough if the kernel were compiled with CONFIG_MEMTEST=y and a user enabled it in the boot parameters. Dom0 kexec support would accomplish the same goal, but more quickly.

TOTP/HOTP is not implemented, but it could be fairly easily. Of course dom0 would probably use oathtool for the authentication. Anyone want to make a TOTP Bluetooth heartbeat Android app? I'm OK with the idea of integrating this with a login service, but I don't particularly want to do the Android coding.

Installation instructions are quite different now, and are included in the archive. I'm still not so keen on making a proper package...

Best,
Andrew

bluetooth-dms.tgz
0xB364F63E.asc
signature.asc
Reply all
Reply to author
Forward
0 new messages