Tools · Linux command line for security · 25 / 28
Auditing systemd services and timers for persistence
List enabled units and timers, find unit files outside package control, inspect user-level units, and read what a unit actually runs.
List what starts
systemctl list-unit-files --state=enabled shows every unit set to start. systemctl list-timers --all shows timers and their next run. Unit files live in /usr/lib/systemd/system for packages, /etc/systemd/system for local administrators, and ~/.config/systemd/user for per-user services that start when the user logs in or lingers.
Attackers favor /etc/systemd/system and user directories because they look like ordinary local customization.
systemctl list-unit-files --state=enabled --type=service systemctl list-timers --all ls -la /etc/systemd/system /etc/systemd/system/*.wants loginctl list-users; ls /var/lib/systemd/linger 2>/dev/null
Read what a unit runs
systemctl cat name shows the unit file and all drop-ins. Look at ExecStart, ExecStartPre, User, and Restart. A unit named like a system component, such as dbus-helper.service, that runs a binary from /var/tmp is suspicious. So is Restart=always on a script that opens a network connection.
Compare local units against package ownership with dpkg -S or rpm -qf. A unit file no package owns was created by an administrator or someone else.
systemctl cat suspicious.service for f in /etc/systemd/system/*.service; do dpkg -S "$f" >/dev/null 2>&1 || echo "unowned: $f"; done
Lab: create, find, and remove a fake unit
Create a service in /etc/systemd/system named network-sync.service that runs /usr/bin/sleep from a copy in /opt/.cache, enable it, and reboot. Then hunt for it: list enabled units, look for unowned files, and check modification times. Disable it, delete it, and run systemctl daemon-reload.
Also create a user-level unit for a test account with loginctl enable-linger, since those run without the user logged in and are easy to overlook.
sudo find /etc/systemd/system /home/*/.config/systemd -name "*.service" -newer /etc/hostname -ls 2>/dev/null sudo systemctl disable --now network-sync.service sudo rm /etc/systemd/system/network-sync.service && sudo systemctl daemon-reload
Defensive controls
Watch /etc/systemd/system and user unit directories with auditd or AIDE. Log systemctl enable events through the journal. Baseline enabled units per server role and diff regularly.
Use unit hardening options such as ProtectSystem=strict and NoNewPrivileges=yes for your own services, which limits what a compromised service can do.
Diagram
Hunting a persistent unit
- List
Enabled services and all timers.
systemctl list-unit-files --state=enabled
- Attribute
Find unit files no package owns.
- Read
systemctl cat to see ExecStart and User.
- Include users
Check lingering users’ ~/.config/systemd/user.
Check yourself
1. Which command shows every timer and its next run?
2. Where do administrators and attackers usually add custom units?
3. Why check users with lingering enabled?