sprung is a small script with a single obsession: confirm a specific USB device is still present and still the same device, and if that identity check fails, slam the system into a forced reboot using a Magic SysRq trigger.
Not “log an alert.” Not “send a notification.” Not “ask politely.”
Just:if the talisman disappears, the ritual completes.
In classic terms, anti-forensics is anything that reduces, distorts, or denies the availability of forensic artifacts. sprung does that in a blunt, mechanical way: it ties the machine’s continued uptime to the presence of a specific hardware token, and forces an immediate reboot the moment the token is missing or its identity can’t be verified.
What sprung is actually doing (no incense, just Linux)
The core idea
Your OS can tell you a lot about a block device via udev. For a thumb drive attached as /dev/sdb, you can query:
udevadm info /dev/sdb
And you’ll see lines like:
ID_SERIAL=Lexar_USB_Flash_Drive_...ID_SERIAL_SHORT=AAZK98GWCSAYYIV9- vendor/model fields, bus info, etc.
sprung uses that output as its “identity oracle.” It watches for two broad failure modes:
- Device missing (unplugged, dead, controller freakout, etc.)
- Identity mismatch (something changed, you got swapped, or you’re reading the wrong device)
Either one means: panic button time.
How it checks whether the device exists
The script runs udevadm info <device> in a loop and inspects stderr.
When the device is gone, udevadm typically emits an error that contains "No such device" (on stderr), which is a convenient “corpse detection” string.
In the snippet:
device_info = subprocess.Popen(
['/usr/bin/udevadm', 'info', self.device],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
if "No such device" in device_info.stderr.readline().decode():
found = False
So the moment /dev/sdb stops meaning anything, found=False, the loop can break, and the system is reset.
How it checks whether the device is the right device
Next, it reads stdout lines and searches for the serial:
for line in device_info.stdout.readlines():
line = line.decode()
device_serial_number = re.search('(?<=ID_USB_SERIAL_SHORT=).*', line)
if device_serial_number is not None:
if device_serial_number.group(0) == self.serial_number:
found = True
continue_loop = True
else:
found = False
So if the current device’s “short serial” doesn’t match the hardcoded expected serial, it treats that as a failure condition.
The “reboot” part: Magic SysRq as a guillotine switch 🪓
When sprung decides the device is missing or wrong, it calls:
def panic(self):
cmd = 'echo b > /proc/sysrq-trigger'
subprocess.check_output(cmd, shell=True)
That writes b into /proc/sysrq-trigger, which triggers an immediate reboot (no sync, no graceful shutdown). It’s intentionally brutal.
Why use SysRq?
Because it works even when the system is half-on-fire.
If your threat model includes:
- a hostile user yanking the token
- a compromised process trying to interfere
- UI lockups where “normal reboot” isn’t dependable
SysRq is the “break glass” tool.
But be honest: it’s a hard reset
SysRq b is not a polite reboot. It’s a table-flip reboot. Use it only if “the machine staying up” is a worse outcome than “the machine losing whatever it was doing.”
This can corrupt data. It can eat filesystems if you’re unlucky. That’s the point: it prioritizes state denial over state preservation.
What this is good for (and what it isn’t)
Good fits
- “token present” enforcement for a workstation you don’t want running unattended
- dead-man switch behavior for lab boxes, kiosks, or sensitive sessions
- cheap tamper response: if the USB key disappears, the host goes down
Not a silver bullet
- If an attacker already has root, they can potentially disable sysrq, kill the process, spoof udev output, or replace your script.
- If
/dev/sdbchanges to/dev/sdcbecause you plugged in another device, you can false-trigger unless you resolve by stable path (/dev/disk/by-id/...).
Downloads
GitHub: sprung
git clone https://github.com/ultros/sprung