systemd-Unit-Dateien: Dienst-Persistenz unter Linux
systemd-Service-, Timer- und Drop-in-Dateien, Aktivierungs-Symlinks, Generatoren und Lingering: wo Linux-Dienste definiert sind und wie sie Persistenz verraten.
- Speicherort
- /etc/systemd/system/
- Belegt
- Welche Dienste und Timer zum Start konfiguriert sind, was sie ausführen und wann die Unit installiert oder geändert wurde
- Zeitstempel
- mtime/ctime/crtime der Dateien; Journal-Einträge in Mikrosekunden seit der Unix-Epoche (UTC)
- Zugriff
- root für System-Units; jeder Benutzer für das eigene ~/.config/systemd/user
- Aufbewahrung
- Bis zur Löschung; Units unter /run gehen beim Neustart verloren; Start-/Stopp-Ereignisse folgen den Journal-Limits
- Sicherung
- UAC, Velociraptor, cp -a, journalctl
- systemctlCLI · in Linux enthalten
- systemd-analyzeCLI · in Linux enthalten
- VelociraptorPlattform · Open Source
- UACCLI · Open Source
Was es ist
systemd startet und überwacht auf einem modernen Linux-Host fast alles. Jeder Dienst, Timer, Socket, Mount oder Path-Watcher ist eine Unit-Datei im INI-Format, und systemd führt Units aus einer Liste von Suchverzeichnissen, Drop-in-Override-Dateien und beim Boot generierten Units zusammen. Ein Angreifer, der eine kleine .service-Datei und einen Symlink schreibt, erhält bei jedem Boot Codeausführung, oft als root (MITRE ATT&CK T1543.002).
Da systemd eine strikte Rangfolge anwendet, ist die Unit, die tatsächlich läuft, nicht unbedingt die, die Sie zuerst finden. Nur das Sichern aller Suchpfade ist verlässlich.
Wo es liegt
Suchpfade des System-Managers, höchste Priorität zuerst (aus systemd.unit(5)):
| Pfad | Zweck |
|---|---|
/etc/systemd/system.control/, /run/systemd/system.control/ | Einstellungen über systemctl set-property |
/run/systemd/transient/ | Transiente Units (zum Beispiel systemd-run) |
/run/systemd/generator.early/ | Generator-Ausgabe, hohe Priorität |
/etc/systemd/system/ | Units des Administrators, Overrides und *.wants/-Symlinks |
/run/systemd/system/ | Laufzeit-Units, nach Neustart verschwunden |
/run/systemd/generator/ | Generator-Ausgabe, mittlere Priorität |
/usr/local/lib/systemd/system/ | Lokal installierte Units |
/usr/lib/systemd/system/ | Paket-Units (RHEL/Fedora; neuere Debian/Ubuntu) |
/lib/systemd/system/ | Paket-Units auf älteren Debian- und Ubuntu-Releases |
/run/systemd/generator.late/ | Generator-Ausgabe, niedrige Priorität |
Zu den Pfaden des User-Managers gehören ~/.config/systemd/user/, ~/.local/share/systemd/user/, /etc/systemd/user/, /etc/xdg/systemd/user/, /usr/local/lib/systemd/user/ und /usr/lib/systemd/user/.
Weitere relevante Orte:
| Pfad | Warum |
|---|---|
<unit>.d/*.conf, service.d/*.conf | Drop-ins, die nach der Hauptdatei eingelesen werden; ein service.d auf oberster Ebene gilt für jeden Dienst |
<target>.wants/, <target>.requires/ | Von systemctl enable angelegte Symlinks |
/etc/systemd/system-generators/, /usr/local/lib/systemd/system-generators/, /usr/lib/systemd/system-generators/ (und user-generators) | Programme, die bei jedem Boot und jedem daemon-reload laufen |
/var/lib/systemd/linger/<user> | Leere Datei: Der Manager dieses Benutzers startet beim Boot |
/var/lib/systemd/timers/stamp-*.timer | Letzte Auslösung persistenter Timer |
Was es belegt
- Welche Dienste, Timer und Sockets definiert und aktiviert sind und was genau sie ausführen.
- Dass eine Paket-Unit geändert oder überschrieben wurde (Drop-in oder gleichnamige Kopie in
/etc/systemd/system). - Wann eine Unit gestartet, gestoppt oder fehlgeschlagen ist, anhand von Journal-Ereignissen.
- Dass bei einem Benutzer Dienste liefen, ohne dass er angemeldet war (Lingering).
- Nicht belegt: Eine Unit-Datei auf der Platte wurde womöglich nie geladen. Suchen Sie im Journal nach Startereignissen und beachten Sie, dass deaktivierte Units nur laufen, wenn etwas anderes sie nachzieht.
Wichtige Felder
| Direktive | Abschnitt | Forensische Bedeutung |
|---|---|---|
ExecStart=, ExecStartPre=, ExecStartPost=, ExecStop=, ExecReload= | [Service] | Ausgeführte Befehle; ein vorangestelltes - ignoriert Fehlschläge |
User=, Group=, DynamicUser= | [Service] | Ausführungsidentität (Standard bei System-Units ist root) |
Environment=, EnvironmentFile= | [Service] | Können LD_PRELOAD oder Proxy-Einstellungen einschleusen |
Restart=, RestartSec= | [Service] | Widerstandsfähigkeit einer Hintertür |
Type= | [Service] | oneshot oder forking deuten auf Skripte und Daemons hin |
WantedBy=, RequiredBy=, Alias= | [Install] | Wo enable den Symlink anlegt |
Description=, Documentation= | [Unit] | Freitext; Angreifer kopieren echte Beschreibungen |
OnCalendar=, OnBootSec=, Unit= | [Timer] | Geplante Aktivierung (siehe Cron und Timer) |
Journal-Felder für Unit-Ereignisse: UNIT= (oder USER_UNIT=), MESSAGE_ID=, _PID=, INVOCATION_ID=. Nützliche Katalog-IDs: 7d4958e842da4a758f6c1cdc7b36dcc5 (Startjob begonnen), 39f53479d3a045ac8e11786248231fbf (Start abgeschlossen), be02cf6855d2428ba40df7e9d022f03d (Start fehlgeschlagen), 98e322203f7a4ed290d09fe03c09fe15 (Unit-Prozess beendet).
Zeitstempel
Unit-Dateien enthalten keine internen Zeitstempel; nutzen Sie die Dateisystemzeiten. Eine Unit aus einem Paket hat normalerweise eine mtime, die zum Paket-Build passt, und eine ctime nahe dem Installationszeitpunkt; bei einer handgeschriebenen Unit liegen mtime und ctime dicht beieinander. ext4 und XFS v5 speichern zudem eine Erstellungszeit (siehe ext4-Zeitstempel). Der Symlink in *.wants/ hat eigene Zeiten, die das enable datieren. Journal-Ereignisse verwenden Mikrosekunden seit 1970-01-01 UTC.
journalctl -D /mnt/evidence/var/log/journal -u suspicious.service -o short-iso-precise
Aufbewahrung
Unit-Dateien bleiben bis zur Entfernung bestehen; Inhalte unter /run und transiente Units verschwinden beim Neustart. Beim Entfernen eines Pakets werden dessen Units gelöscht, nicht aber Dateien, die ein Administrator oder Angreifer angelegt hat. Meldungen zum Lebenszyklus von Units überdauern nur so lange, wie das Journal (oder syslog) sie aufbewahrt.
Sicherung
Das systemd-Artefakt von UAC sammelt /etc/systemd, /lib/systemd/system, /usr/lib/systemd, /usr/local/lib/systemd, /run/systemd/system, transiente Units sowie pro Benutzer ~/.config/systemd und ~/.local/share/systemd. Auf einem laufenden Host speichert es zusätzlich systemctl list-units, list-unit-files, list-timers --all und den Timer-Status. Velociraptors Linux.Sys.Services wertet systemctl list-units --type=service auf dem Endpunkt aus.
# live: what systemd actually loaded, including drop-ins
systemctl cat suspicious.service
systemctl list-unit-files --state=enabled
systemctl show suspicious.service -p FragmentPath,DropInPaths,ExecStart
# dead box
tar -C /mnt/evidence -czf systemd.tgz etc/systemd usr/lib/systemd lib/systemd \
usr/local/lib/systemd var/lib/systemd home/*/.config/systemd root/.config/systemd 2>/dev/null
Auswertung
R=/mnt/evidence
systemctl --root="$R" list-unit-files # enablement read from disk
find "$R"/etc/systemd "$R"/usr/lib/systemd "$R"/home/*/.config/systemd -xdev \
\( -type f -o -type l \) -printf '%C+ %M %u %p -> %l\n' 2>/dev/null | sort
grep -rhoE '^(ExecStart[A-Za-z]*|Environment(File)?|User)=.*' "$R"/etc/systemd | sort | uniq -c | sort -n
systemd-analyze --root="$R" verify <unit> meldet unbekannte Direktiven und ExecStart=-Programme, die nicht existieren. Prüfen Sie die Paketzugehörigkeit mit dpkg -S oder rpm -qf (siehe Paketmanager-Logs).
Tipps für die Untersuchung
- Angreifer bevorzugen Namen, die echte Dienste imitieren (
dbus-org.freedesktop.helper.service). Beurteilen Sie den Pfad inExecStart=, nicht den Namen. - Prüfen Sie jede
*.d/override.conf: Ein Drop-in, dasExecStart=einer vertrauenswürdigen Unit leert und neu setzt, ist gut versteckt. - Suchen Sie in
*.wants/nach Symlinks, die auf Dateien außerhalb der Unit-Pfade zeigen oder auf Units, die zu keinem Paket gehören. - Ein Generator in
/etc/systemd/system-generators/läuft bei jedem Boot noch vor dem Laden der Units, was auf Servern selten vorkommt. - Benutzer-Units zusammen mit
/var/lib/systemd/linger/<user>ergeben Persistenz ohne root, die eine Abmeldung übersteht; häufig bei Kryptominern. Environment=LD_PRELOAD=in einer Unit ist eine gezielte Form des Hijackings des dynamischen Linkers.- systemd protokolliert bei jedem
daemon-reloadeine Reload-Meldung; eine solche kurz vor dem ersten Start einer neuen Unit hilft, die Installation zu datieren.
Siehe auch
Verwandte Artefakte
Ausführliche Leitfäden
Glossar
- systemd Journal (journald)Englisch
- UAC (Unix-like Artifacts Collector)Englisch