Cron- und systemd-Persistenz erkennen: zeitgesteuerte Hintertüren unter Linux

Kurzfassung: Cron und systemd sind die beiden Stellen, an denen Linux Code zeitgesteuert oder beim Start ausführt - und damit die beliebtesten Orte für Persistenz. Ein Angreifer legt einen Cron-Eintrag, einen systemd-Dienst oder einen Timer an, der seinen Code über Neustarts hinweg immer wieder startet. Erkennung aus Verteidigersicht: Dateiänderungen in den Cron- und systemd-Verzeichnissen über auditd-Dateiwatches und Sysmon for Linux Event 11, der Dienst- und Timer-Start in journald und der crontab-Aufruf in der Prozess-Telemetrie. Drei sigma-cli-validierte Sigma-Regeln, Härtung, eine Analysten-Checkliste und der Test im Lab. Serie "Angriff erkennen".

Cron- und systemd-Persistenz erkennen heißt, die wenigen Stellen zu überwachen, an denen Linux geplante und automatische Ausführung verankert. Nach dem ersten Zugriff über eine Unix-Shell ist die nächste Frage des Angreifers, wie er den Zugang behält, wenn der Prozess beendet oder das System neu gestartet wird. Cron und systemd beantworten sie zuverlässig und unauffällig, weil beide auf jedem Linux-System vorhanden und im Alltag ständig im Einsatz sind. Dieser Beitrag aus der Serie "Angriff erkennen" zeigt aus Verteidigersicht, wo diese Persistenz Spuren hinterlässt, mit Logquellen, drei Sigma-Regeln, der Härtung, einer Checkliste und dem Test. Die Telemetrie-Grundlagen stehen unter Linux-Sicherheitsmonitoring.

Einordnung in ATT&CK: MITRE führt geplante Ausführung per Cron als T1053.003 (Cron), systemd-Timer als T1053.006 (Systemd Timers) und systemd-Dienste als T1543.002 (Systemd Service). Alle drei gehören zur Taktik Persistence (und dienen zugleich der Execution und der Privilege Escalation). In dieser Serie steht der Beitrag in der Spalte Persistence. Die Sigma-Regeln sind entsprechend mit attack.persistence, attack.t1053.003, attack.t1053.006 und attack.t1543.002 getaggt.

Was der Angreifer tut

Die Wege sind wenige und gut bekannt. Bewusst auf der Ebene des Prinzips, nicht als Anleitung:

  • Cron-Eintrag. Ein neuer Eintrag in einer system-weiten Cron-Datei (/etc/crontab, /etc/cron.d/, /etc/cron.daily/) oder in der Benutzer-Crontab (/var/spool/cron/) startet den Code in festem Takt. Ein @reboot-Eintrag sorgt zusätzlich für Start nach jedem Neustart.
  • systemd-Dienst. Eine eigene Unit-Datei mit einem ExecStart auf das Schadprogramm, per systemctl enable aktiviert, startet den Code beim Hochfahren und nach Abstürzen automatisch neu.
  • systemd-Timer. Ein Timer mit OnCalendar oder OnBootSec übernimmt die Rolle von Cron und ruft eine zugehörige Service-Unit zeitgesteuert auf - unauffälliger als ein Cron-Eintrag, weil seltener kontrolliert.
  • Benutzerkontext ohne Root. Auch ohne Root reichen die Benutzer-Crontab und ein User-Timer unter ~/.config/systemd/user/ für Persistenz im Kontext des kompromittierten Kontos.

Der gemeinsame Nenner ist eine neue oder geänderte Datei an einer dieser wenigen, gut bekannten Stellen. Genau daran setzen die Regeln an.

Welche Logquellen die Technik zeigt

  • auditd (die wichtigste Quelle). Datei-Watches auf die relevanten Verzeichnisse machen jede Änderung sichtbar, etwa -w /etc/cron.d/ -p wa -k cron und -w /etc/systemd/system/ -p wa -k systemd. Der PATH-Datensatz nennt die betroffene Datei, der SYSCALL-Datensatz das schreibende Programm und Konto.
  • Sysmon for Linux. Event 11 (FileCreate) zeigt neu angelegte Dateien in den Cron- und systemd-Verzeichnissen mit dem erzeugenden Prozess.
  • journald. Der CRON-Eintrag protokolliert jede Ausführung mit Konto und Befehl, systemd meldet das Laden neuer Units (Reloading, Started) und das Scharfschalten eines Timers. Das ist die zweite, unabhängige Spur neben der Dateiebene.
  • Prozess-Telemetrie. Der Aufruf von crontab oder systemctl erscheint in auditd (execve) und in Sysmon for Linux Event 1 - wertvoll, wenn der Aufruf aus einem Dienst- oder Nicht-Login-Kontext kommt.

Das Muster im Log

Auf einem stabilen Server ändern sich Cron- und systemd-Dateien selten, und wenn, dann im Rahmen einer Paketinstallation oder eines Deployments. Verdächtig ist eine Änderung außerhalb dieser Fenster, besonders wenn der Inhalt auf eine Shell, ein curl oder wget, einen Pfad in /tmp oder einen base64-Blob zeigt, wenn ein @reboot gesetzt ist oder wenn ein Timer und seine Service-Unit frisch zusammen auftauchen. Wer die Dateiänderung mit dem erzeugenden Prozess und dem Konto zusammenbringt, trennt das Deployment vom Angriff. Eine Baseline der vorhandenen Cron-Einträge, Dienste und Timer macht jede Abweichung sofort sichtbar.

Drei Sigma-Regeln

Die Regeln sind mit sigma-cli validiert und nutzen die Linux-Logquellen file_event und process_creation. Die erste fängt Änderungen an Cron-Dateien, die zweite neue systemd-Units und Timer, die dritte den crontab-Aufruf für ein fremdes Konto. Die Übersetzung ins SIEM steht unter Sigma-Regeln.

1. Änderung an einer Cron-Konfiguration (T1053.003). Jede Schreiboperation in den Cron-Verzeichnissen ist ein Prüffall.

Sigma
title: Aenderung an einer Cron-Konfiguration
id: a514dbe2-c799-42ed-941b-b6b8c4a65fc2
status: experimental
description: Erkennt das Anlegen oder Aendern von Cron-Dateien in den System- und
  Benutzer-Cron-Verzeichnissen. Angreifer legen hier einen Eintrag ab, der ihren
  Code zeitgesteuert und ueber Neustarts hinweg ausfuehrt (Persistenz per Cron).
references:
  - https://attack.mitre.org/techniques/T1053/003/
author: blue-team.net
tags:
  - attack.persistence
  - attack.t1053.003
logsource:
  product: linux
  category: file_event
detection:
  selection:
    TargetFilename|contains:
      - '/etc/cron'
      - '/var/spool/cron/'
  condition: selection
falsepositives:
  - Paketinstallationen und Konfigurationsmanagement (apt, Ansible), die legitim Cron-Eintraege anlegen
level: medium

2. Neue systemd-Unit oder Timer-Datei (T1543.002, T1053.006). Eine neue .service- oder .timer-Datei in einem Unit-Verzeichnis ist das systemd-Gegenstück zum Cron-Eintrag.

Sigma
title: Neue systemd-Unit oder Timer-Datei angelegt
id: ff0fa70f-7003-4922-825e-7beef704327d
status: experimental
description: Erkennt das Anlegen einer systemd-Service- oder Timer-Datei in den
  System- oder Benutzer-Unit-Verzeichnissen. Angreifer hinterlegen damit einen
  Dienst oder Timer, der ihren Code beim Start oder zeitgesteuert ausfuehrt
  (Persistenz per systemd-Service oder -Timer).
references:
  - https://attack.mitre.org/techniques/T1543/002/
  - https://attack.mitre.org/techniques/T1053/006/
author: blue-team.net
tags:
  - attack.persistence
  - attack.t1543.002
  - attack.t1053.006
logsource:
  product: linux
  category: file_event
detection:
  selection_dir:
    TargetFilename|contains:
      - '/etc/systemd/system/'
      - '/lib/systemd/system/'
      - '/.config/systemd/user/'
  selection_ext:
    TargetFilename|endswith:
      - '.service'
      - '.timer'
  condition: selection_dir and selection_ext
falsepositives:
  - Paketinstallationen und Konfigurationsmanagement, die legitim Units anlegen
level: medium

3. crontab-Bearbeitung eines fremden Kontos (T1053.003). Ein crontab-Aufruf mit -u für einen anderen Benutzer oder -e aus einem untypischen Kontext deutet auf eingerichtete Persistenz hin.

Sigma
title: crontab-Bearbeitung eines anderen Benutzers oder per Datei
id: b67588a2-14ed-43de-aed2-0b367eaf9a07
status: experimental
description: Erkennt den Aufruf von crontab zum Bearbeiten (-e) oder Installieren
  einer Crontab, besonders fuer einen anderen Benutzer (-u). Angreifer richten so
  nach einer Rechteausweitung Persistenz im Namen eines anderen Kontos ein. Der
  Aufruf aus einem Dienst- oder Nicht-Login-Kontext ist besonders verdaechtig.
references:
  - https://attack.mitre.org/techniques/T1053/003/
author: blue-team.net
tags:
  - attack.persistence
  - attack.t1053.003
logsource:
  product: linux
  category: process_creation
detection:
  selection_img:
    Image|endswith: '/crontab'
  selection_arg:
    CommandLine|contains:
      - ' -u '
      - ' -e'
  condition: selection_img and selection_arg
falsepositives:
  - Administratoren, die regulaer Crontabs pflegen - bekannte Konten als Baseline ausnehmen
level: medium

Härtung

  • Dateiintegrität überwachen. Ein FIM-Werkzeug wie AIDE auf den Cron- und systemd-Verzeichnissen meldet jede unerwartete Änderung - die wirksamste Einzelmaßnahme neben der auditd-Überwachung.
  • Rechte begrenzen. Schreibrechte auf die Cron- und Unit-Verzeichnisse eng halten und per-Benutzer-Crontab über cron.allow und cron.deny dort abschalten, wo sie nicht gebraucht wird.
  • Regelmäßig inventarisieren. systemctl list-timers, systemctl list-unit-files und eine Zusammenstellung aller Cron-Einträge gehören ins regelmäßige Threat Hunting; neue Einträge gegen die Baseline prüfen.
  • Änderungen an Deployments koppeln. Legitime Änderungen kommen aus Paketen und Konfigurationsmanagement. Wer deren Wartungsfenster kennt, kann jede Änderung außerhalb davon als Alarm werten.

Der Test

Die Erkennung lässt sich im Lab gefahrlos prüfen, auf einer isolierten VM mit auditd-Dateiwatches und Sysmon for Linux:

  • Für Regel 1 eine harmlose Testdatei in /etc/cron.d/ anlegen oder mit crontab -e einen Eintrag setzen. Der auditd-PATH-Datensatz und Sysmon for Linux Event 11 müssen die Änderung zeigen.
  • Für Regel 2 eine Test-Unit und einen Timer in /etc/systemd/system/ anlegen und mit systemctl daemon-reload laden. Die Dateierstellung muss die Regel auslösen, journald den Timer melden.
  • Für Regel 3 crontab -u testuser -e aufrufen und den Treffer in der Prozess-Telemetrie prüfen.
  • Breiter wird der Test mit den Fällen zu T1053.003, T1053.006 und T1543.002 aus Atomic Red Team.

Fehlalarme und Tuning

  • Paketinstallationen. apt, dnf und yum legen beim Installieren legitim Cron-Einträge und Units an. Diese Änderungen fallen in bekannte Wartungsfenster und lassen sich über den auslösenden Paketmanager-Prozess zuordnen.
  • Konfigurationsmanagement. Ansible, Puppet und Chef schreiben regelmäßig Cron- und Unit-Dateien. Deren Konten und Prozesse gehören als Baseline hinterlegt, nicht die Regel entschärft.
  • Entwicklungssysteme. Auf Build- und Testsystemen ändern sich Timer und Dienste häufiger. Dort hilft eine engere Baseline pro Host statt einer pauschalen Ausnahme.
  • Inhalt entscheidet. Ein Eintrag, der auf eine Shell, /tmp oder einen Download zeigt, wiegt schwerer als ein Pfad in /usr/bin aus einem bekannten Paket.

Analysten-Checkliste

  • Welche Datei und welches Verzeichnis wurde geändert (Cron, systemd-System, systemd-User)?
  • Inhalt prüfen: Shell, curl/wget, Pfad in /tmp, base64 oder @reboot enthalten?
  • Wer hat die Datei angelegt (erzeugender Prozess, Konto)? Dienstkonto oder Admin?
  • Passt die Änderung zu einem Deployment- oder Paket-Fenster?
  • Gibt es ein frisches Timer-und-Service-Paar oder einen einzelnen, isolierten Eintrag?
  • Folgeaktivität prüfen: startet der Eintrag eine Shell oder eine ausgehende Verbindung?

Fazit

Cron und systemd sind die naheliegendsten Orte für Linux-Persistenz und zugleich gut überschaubar: Es sind wenige Verzeichnisse, die sich auf einem Server selten ändern. Wer sie mit auditd-Dateiwatches und Sysmon for Linux Event 11 überwacht, eine Baseline der vorhandenen Einträge pflegt und jede Änderung gegen die Deployment-Fenster prüft, entdeckt die Hintertür, bevor sie beim nächsten Neustart wieder zuschlägt. Der Weg dorthin führt meist über eine Unix-Shell, eine weitere beliebte Persistenz über SSH authorized_keys. Weitere Techniken dieser Taktik führt das Lexikon nach Taktik unter Persistence.

NH

$ whoami

Norbert Hofmann

Cyber Defense Analyst im Security Operations Center eines Managed Security Service Providers. Red und Blue Teaming, Malware-Analyse, Incident Response und Security-Awareness-Trainings. Finalist bei „Deutschlands bester Hacker“ 2022, mehrere CVE-Einträge für WordPress-Plugins.