Killjoy
NOTE: this tool is experimental, disruptive, and it can cause data losses. You use at your own risk!
Killjoy is a simple emergency and tamper-response utility for your Linux computer. For more context on the threats this tool tries to address, refer to our post When Things Go Sideways: Resisting Device Seizures.
DOWNLOADKilljoy monitors for changes in peripherals, such as plugging of USB, FireWire, Thunderbolt devices, or removal of Power Supply. Additionally it can also watch for manual triggers, for example from a keyboard shortcut, or trigger after a period of inactivity. The idea is to protect the computer from tampering when separated from the user, as well as give the user the opportunity to execute an emergency sequence in case of need. Killjoy aims to provide an additional layer of security when all else fails.
This tool tries to address two scenarios:
-
Your computer is seized locked but powered on. The adversary attempts to perform an attack through some external programmable device (such as FireWire or Thunderbolt), abuse Direct Memory Access and leverage unmediated access to the computer's memory in order to unlock it or steal encryption keys. Modern systems are much more resistant to DMA attacks thanks to IOMMU, which brokers and restricts devices' access to the computer physical memory. However, occasionally vulnerabilities emerge that bypass these protections.
-
Your computer is seized from you unlocked. The adversary does not have root privileges, but attempts to plug in an external device such as a USB storage to copy files off to, or a Rubber Ducky to automate some malicious actions, or a Mouse Jiggler to prevent the computer from locking while it is being transported away. With Full-Disk Encryption protected by a strong passphrase, these days adversaries are particularly incentivized to attempt to separate your laptop from you in this state, and online reports describe cases just like this.
With killjoy running, you can instruct your computer to execute a pre-configured set of emergency commands when triggered. Perhaps you might want to trigger an immediate poweroff in order to restore the device to a fully encrypted state and reduce chances of data recovery.
Security Design
To prevent operational mistakes, it is important to understand the capabilities and limitations of killjoy, and what it does and does not try to protect against. For the sake of clarity, we will use the following terms as described:
- user, the legitimate operator of the device and of killjoy.
- system, the operating system in use by the user on the device.
- adversary, any ill-motivated actor with an interest in tampering with the system and obtaining access to its data.
Assumptions
- The system employs Full-Disk Encryption (FDE), with a strong passphrase.
- The user is able to run commands as root (administrator), or through sudo, protected by a strong passphrase.
- The adversary is not able to intercept either passphrases. The user is cautious with potential capture of the passphrases through hardware/software keyloggers, hidden cameras, coercion, or other means.
- The system is not already compromised, and the adversary does not currently have any form of access to it.
Design Choices
- Killjoy considers Full-Disk Encryption (FDE) a strict security requirement. Because the attack vector killjoy attempts to address involves physical access to the computer, lack of FDE would provide unfettered access to the data at rest, in most circumstances rendering killjoy superfluous.
- Killjoy considers a lock screen a soft security requirement. If the adversary obtains access to the system unlocked with limited user privileges, killjoy should resist tampering. While its core functionality could be implemented with user privileges only, killjoy is designed to execute as root in order to take advantage of this separation of privileges as a foundational self-protection mechanism.
- Configuration files, scripts and commands used by killjoy should only be modifiable and executable by root. Killjoy should not introduce any additional avenue for privilege escalation. Of course, if other software installed on the system expose privilege escalation vulnerabilities, killjoy could be defeated.
- Killjoy considers root privileges a strict security requirement. If an adversary is able to obtain root access to the system, killjoy is considered defeated.
Getting Started
You can download a compiled binary for x86-64 Linux from Codeberg. You check the hash by downloading the .sha256 file and running:
$ sha256sum -c killjoy_X.X.sha256
And check with our PGP key by downloading the .sig file and running:
$ gpg --verify killjoy_X.X.sig
You can run the downloaded binary from wherever you like, but we suggest you move it to /usr/local/bin/:
$ sudo mv ~/Downloads/killjoy /usr/local/bin/
Now you can check if killjoy is available:
$ killjoy
▌ ▘▜ ▜ ▘
▙▘▌▐ ▐ ▌▛▌▌▌
▛▖▌▐▖▐▖ ▌▙▌▙▌
▙▌ ▄▌
https://codeberg.org/breakout/killjoy
Usage: killjoy [COMMAND]
Commands:
init Generate a default TOML config file at /etc/killjoy/config.toml
install Install killjoy as a service
uninstall Uninstall killjoy service
status Check whether killjoy is running or not
start Start the killjoy service
stop Stop the killjoy service
restart Restart the killjoy service
dry-run Launch killjoy service in foreground in dry-run mode (will not execute configured commands)
trigger Manually trigger killjoy, for example with a keyboard shortcut
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help
-V, --version Print version
Install and Start
Killjoy requires a configuration file to launch. You can run the command sudo killjoy init and it will create a default configuration file at /etc/killjoy/config.toml like the following:
[devices]
# Enable device monitoring. If this is is false, of course all following options
# in this section have no bearing.
enabled = true
# Monitor for events concerning USB devices.
monitor_usb = true
# Monitor for events concerning Human Interface Devices (HID), such as mouse,
# keyboards, touchscreens, and other physical interfaces.
monitor_hid = true
# Monitor for events concerning PCI devices, such as network cards, sound cards,
# graphic cards, etc.
monitor_pci = true
# Monitor for events concerning Network devices.
monitor_net = true
# Monitor for events concerning Input devices, such as mouse, touchpads.
monitor_input = true
# Monitor for events concerning devices connecting via Firewire, such as drives,
# cameras, printers, scanners, etc.
monitor_firewire = true
# Monitor for events concerning devices connecting via Thunderbolt.
monitor_thunderbolt = true
# Monitor for changes in the power supply.
monitor_powersupply = true
# Exclude specific subsystem / device type combinations.
[devices.exclude_device_types]
# Default exclusion for net/wireguard.
net = "wireguard"
# Enable monitoring for manual triggers invoked with the 'trigger' command.
[manual]
enabled = false
# Enable monitoring for inactivity. This attempts to detect whenever the
# computer's screen is locked, and if the screen is not unlocked before
# the configured timeout is over, a trigger event is sent.
[inactivity]
enabled = false
# Timeout in seconds.
timeout = 3600
[execute]
# Run the configured commands only at the first detected event.
# Skip any following runs.
run_only_once = false
# List of commands to execute when killjoy is triggered.
commands = ["systemctl poweroff"]
Before exiting, it will offer to edit the same file.
TECHNICAL DETAILS: killjoy only loads the configuration file from the location
/etc/killjoy/config.toml. Additionally, when killjoy is started it ensures the configuration file is owned by root and only root can modify it. This is a design choice to prevent an unprivileged user from modifying the configuration and abusing it to escalate privileges through killjoy.
The only required configuration is a list of commands to execute, whenever a relevant event is detected. Note that these commands will be executed as root. A basic use case would be to immediately poweroff the computer in order to restore the protection guarantees that FDE provides. Killjoy sets systemctl poweroff as a default.
In most cases, you can leave the [devices] section unchanged. The one option you might want to consider modifying is monitor_powersupply. While power supply doesn't really constitute an attack vector, killjoy provides support for it as an emergency response mechanism. For example, if an adversary bursts into your location leaving you little time to respond, unplugging the power supply from your laptop will trigger your configured command (such as a poweroff).
However, because power supply connectors and software monitoring might be fragile, it could lead to accidental triggers. You might want to test this out on your device and determine whether it is safer (or necessary) to disable power supply monitoring by changing monitor_powersupply to false in your config file.
Killjoy also allows to explicitly ignore subsystem / device type combinations. By default net + wireguard is excluded. If you do not use WireGuard, you can comment out these lines.
The [manual] section includes an enabled option you can turn to true if you want the ability to trigger killjoy manually by invoking the killjoy trigger command. This command is designed to not require root privileges, so you are able to configure your window manager (like GNOME, KDE, i3, sway, etc.) to launch with a keyboard shortcut. Refer to your window manager's documentation on how to do so.
Killjoy also supports an inactivity monitor that can be enabled and configured in the [inactivity] section. If enabled, killjoy will watch if the screen gets locked and start a timer. If the screen isn't unlocked before the configurable timeout is over, a trigger event is sent. So, if you don't expect the computer to be left locked and unattended for an extended period of time, this option can provide an additional layer of protection by ensuring your emergency commands are executed in case the computer is seized and held against your will.
TECHNICAL DETAILS: Window managers like GNOME or Plasma report to logind the screen lock status, but lighter window managers don't always do so. Killjoy monitors the logind
LockedHintproperty but also watches for the presence of lockers likei3lock,swaylock,hyprlockand others in order to address this.
Before proceeding to install killjoy as a service, you can ensure your configuration works as intended with the dry-run command.
After creating the configuration you need to proceed installing the killjoy service with:
$ sudo killjoy install
Note that this command requires a configuration at /etc/killjoy/config.toml to be already available. With this command you install the systemd unit file for killjoy. Now you can start and stop killjoy as you like.
To start, run with the start command.
$ sudo killjoy start && sudo -k
Note the sudo -k. This is to ensure the sudo session is reset and no window of time is left open for an adversary to deactivate killjoy (you should consider disabling the timeout altogether, adding Defaults timestamp_timeout=0 to your /etc/sudoers file). Similarly, while you are operating your device while killjoy is enabled you should make sure to terminate any root or sudo terminal session as soon as you are done with it.
Monitor Status and Events
You can check whether killjoy is activated with the status command (it does not require root privileges):
$ killjoy status
running
The running service will log events in the file /var/log/killjoy.log. You can monitor that for events, actions and errors.
Stop killjoy
You can stop killjoy at any time with:
$ sudo killjoy stop
Note that the service configuration will remain in place, so you can start the service again whenever you like.
You can uninstall killjoy with the following command:
$ sudo killjoy uninstall
This will remove the service unit. You can specify an optional --purge which additionally removes the configuration directory at /etc/killjoy and the log file at /var/log/killjoy.log.
Limitations
Beyond the security requirements laid out previously, killjoy comes with some limitations you should be aware of:
-
Currently it is a terminal application only. We are exploring GUI options, but it will take some time.
-
It does require root privileges to be enabled and disabled. This is a hard requirement we will not be able to get rid of.
-
Currently, killjoy requires to be manually enabled each time. It can be configured to automatically start at boot, but this could have the unintended side-effect of causing accidental triggers if the user is not conscious that killjoy is active. Any feedback on this is welcome.