Persistence Techniques on Embedded Devices
Getting onto a device is one thing; staying there across reboots and firmware updates is another. Persistence is how an attacker keeps access after the initial compromise, and on embedded systems it has its own shapes because the storage, the boot process, and the update mechanism differ from a PC. Understanding persistence matters for both attacking and defending a device.
Why Persistence Is the Real Goal
An attacker who has to re-exploit a device on every reboot has a fragile foothold. Persistence converts a one-time compromise into lasting control, surviving power cycles and, in the worst case, firmware updates meant to remove it. For anyone defending a fleet, persistence is what turns an incident into an ongoing breach.
On embedded devices persistence is often easier than on a hardened PC, because the same lack of integrity checking that let the attacker in lets them modify the system that boots. The flip side is that understanding where persistence hides tells a defender exactly what to protect and what to inspect when a device is suspected of compromise.
The Techniques at a Glance
Embedded persistence clusters into a handful of techniques, each at a different level of the stack and each with a matching way to detect it:
| Technique | Where it hides | How to detect |
|---|---|---|
| Startup script | An added line in init.d or rcS in the writable overlay | Diff scripts against the signed image |
| Cron job | A scheduled, often self-healing, re-install job | Inspect crontabs for unexpected entries |
| Modified binary | A trojanized BusyBox or patched daemon | Hash binaries against the golden image |
| Configuration | An added SSH key, malicious DNS, or U-Boot env | Check authorized_keys and the boot environment |
| Bootloader or below | A modified bootloader or a protected region | Verified boot; inspect the boot chain |
| Survives the update | Writable areas the update never resets | Updates that fully replace, verify, and reset |
The Writable Filesystem Question
The first thing that shapes persistence is whether the root filesystem is writable. Many embedded devices use a read-only SquashFS root with a small writable overlay for configuration, so an attacker has to land their persistence in the writable area, or find a way to modify the read-only image.
mount | grep -E 'squashfs|jffs2|ubifs|overlay'
/dev/mtdblock2 on / type squashfs (ro) /dev/mtdblock5 on /overlay type jffs2 (rw)
A read-only root with a writable JFFS2 overlay tells the attacker exactly where they can persist, the overlay and the scripts that live there. It also tells a defender that anything outside the overlay should match the signed image, which is the basis for detecting tampering.
Startup Scripts and Services
The most common persistence is the oldest: add or modify a startup script so the attacker’s code runs at every boot. The init system, a classic rcS, a set of init.d scripts, or a systemd unit, is the target, and the writable overlay is usually where the entry lands.
# an attacker's persistence appended to a writable startup script
cat /overlay/etc/init.d/rcS.local#!/bin/sh # legitimate config restore... /tmp/.sysmon & # <-- attacker's implant, launched every boot
A backdoor launched from a startup script runs with whatever privilege the init system has, usually root, on every boot. It is exactly what a defender should look for: an unexpected entry in a startup script, or a script that does not match the signed firmware, is a classic sign of compromise.
Cron and Scheduled Persistence
Where cron is available, a scheduled job gives persistence that also recovers itself: a job that re-installs the implant if it is removed, or that periodically phones home. Cron entries are easy to overlook, which makes them a favored hiding place.
crontab -l; cat /overlay/etc/crontabs/* 2>/dev/null
*/10 * * * * /tmp/.sysmon || cp /overlay/.backup/.sysmon /tmp/.sysmon
A cron job that re-deploys the implant if it is missing makes simple removal ineffective, because the implant comes back ten minutes later. This self-healing pattern is why incident response on a compromised device has to find and remove every persistence mechanism, not just the running process.
Modified Binaries and Configuration
Subtler persistence replaces or patches a legitimate binary so the malicious behavior rides along with normal operation, a trojanized BusyBox, a patched daemon, or a wrapped login program, with nothing obviously out of place in the process list. Detecting it requires comparing on-device binaries against the known-good signed image, because a modified binary looks normal by name and location, and a hash mismatch is a strong tamper signal.
Not all persistence is a binary, though. Configuration the device acts on can carry it: a malicious DNS server, an added SSH key, a startup command in a settings field, or a U-Boot environment variable that alters the boot.
cat /overlay/etc/dropbear/authorized_keys 2>/dev/null fw_printenv 2>/dev/null | grep -iE 'bootcmd|preboot'
ssh-rsa AAAAB3...attacker-key... # added key grants remote root preboot=run malicious_script # bootloader env hijack
An added SSH key grants remote access that survives reboots and looks like a legitimate key, and a hijacked bootloader environment runs attacker code before the OS even starts. Configuration-based persistence is among the hardest to spot precisely because it does not change any binary.
Bootloader, and Surviving the Update
The deepest persistence sits in the boot chain, where it survives even a firmware reflash of the application: a modified bootloader, or persistence in a region the update process does not overwrite, can re-infect the device after an update the owner believes cleaned it, the embedded equivalent of a bootkit. Defending against this is exactly what secure and verified boot are for, since if each stage verifies the next, a modified bootloader or kernel will not run.
The strongest persistence survives the update meant to remove it: if updates do not wipe the writable overlay, persistence there carries across; if the update does not verify and replace the whole image, a modified component can remain. This is the worst case for a defender, because the standard remediation, push a clean update, fails, which is why an update that fully replaces and verifies the image, and resets the writable areas where persistence hides, is what guarantees a compromised device can actually be cleaned.
Detecting and Designing against It
Detection comes down to comparing the device against its known-good state: hash the binaries against the signed image, inspect startup scripts and cron jobs for unexpected entries, check authorized-keys and configuration for additions, and verify the bootloader and boot environment.
# compare on-device files against the known-good firmware image
for f in $(find /overlay -type f); do
sha256sum "$f"
done > device_hashes.txt
diff device_hashes.txt golden_overlay_hashes.txt A diff against a golden baseline surfaces exactly what changed, and the prerequisite is having that baseline, the signed image and expected configuration, which is why a device designed with integrity verification in mind is also a device you can actually investigate when something goes wrong. The defenses follow the same theme: verified boot stops modified components from running, a read-only signed root limits where persistence can land, and an update process that fully replaces, verifies, and resets removes the survive-the-update case. Preventing persistence is mostly about integrity, the device should run only what it can verify and be able to return to a known-good state on demand, which is the difference between an incident and a breach.
Where This Fits
Assessing how an attacker would persist on a device, and whether the design can detect and remove that persistence, is part of a thorough product security assessment. If you want to know whether a compromise of your device could be made permanent, and survive your updates, that is the kind of work we do at Berkner Tech.



