PowerShell-Profil-Persistenz erkennen: Autostart in der Shell

Kurzfassung: Jede PowerShell-Sitzung lädt beim Start automatisch ein Profil-Skript - wenn es existiert. Genau das macht sich ein Angreifer zunutze: Code im Profil läuft ab jetzt bei jedem Start einer Shell, unauffällig und ohne neuen Autostart-Eintrag in der Registry. PowerShell Profile Persistence hinterlässt aber eine klare Spur, nämlich den Schreibzugriff auf eine profile.ps1. Dieser Beitrag zeigt, wo diese Dateien liegen, wie der Schreibzugriff im Log aussieht und wie drei sigma-cli-validierte Sigma-Regeln ihn fassen. Dazu Härtung und der Test im Lab. Serie "Angriff erkennen".

PowerShell kennt mehrere Profil-Skripte, die beim Start einer Sitzung automatisch ausgeführt werden. Gedacht sind sie für Komfort: eigene Funktionen, Aliase, ein angepasster Prompt. Legt ein Angreifer in ein solches Profil seinen eigenen Code, läuft dieser fortan bei jedem PowerShell-Start des betroffenen Benutzers - oder, beim systemweiten Profil, bei jedem Benutzer. Das ist leise, überlebt den Neustart und braucht weder einen Dienst noch eine geplante Aufgabe. Für den Verteidiger ist die gute Nachricht: Das Profil muss geschrieben werden, und dieser Schreibzugriff ist sichtbar. Dieser Beitrag bleibt auf der Erkennungsseite und zeigt kein Vorgehen zum Missbrauch.

Einordnung in ATT&CK: PowerShell Profile (T1546.013), eine Untertechnik von Event Triggered Execution. ATT&CK führt sie unter Persistence und Privilege Escalation; in dieser Serie steht sie in der Spalte Persistence, weil der Fokus hier auf dem dauerhaften Wiederkehren des Codes liegt. Sie grenzt sich von anderen Autostart-Wegen wie Registry-Run-Keys, geplanten Aufgaben oder WMI-Abonnements dadurch ab, dass der Auslöser der Start einer PowerShell-Sitzung ist.

Was der Angreifer tut

Der Missbrauch folgt - auf der Ebene des Prinzips, nicht als Anleitung - einem einfachen Gedanken: an eine Stelle schreiben, die PowerShell von allein liest.

  • Ein Profil wählen. PowerShell lädt je nach Sitzung mehrere Profile. Es gibt benutzerbezogene Profile im Documents-Ordner und ein systemweites Profil unterhalb der Windows-Verzeichnisse; letzteres gilt für alle Benutzer.
  • Code hinterlegen. In das gewählte Profil wird der eigene Code geschrieben - neu angelegt, wenn noch kein Profil existiert, oder an ein bestehendes angehängt, um nicht aufzufallen.
  • Auf den Start warten. Ab jetzt genügt eine beliebige PowerShell-Sitzung des Benutzers, damit der Code läuft - ausgelöst durch Admins, Skripte oder andere Werkzeuge, die PowerShell starten.
  • Unauffällig bleiben. Es entsteht kein neuer Dienst und kein klassischer Autostart-Eintrag; wer nur dort sucht, übersieht das Profil.

Für die Erkennung zählt die Erkenntnis: Egal welches Profil gewählt wird, es muss eine Datei namens profile.ps1 oder Microsoft.PowerShell_profile.ps1 angelegt oder verändert werden. Dieser Schreibzugriff ist der Angelpunkt der Erkennung.

Welche Logquellen die Technik zeigt

  • Dateianlage zuerst. Sysmon Event 11 (FileCreate) zeigt das Anlegen oder Überschreiben einer Profildatei samt Zielpfad und schreibendem Prozess - die direkteste Quelle für diese Technik.
  • Prozess-Telemetrie. Event 4688 erfasst, wenn ein Profil über die Kommandozeile beschrieben wird, etwa per Add-Content, Set-Content, Out-File oder per Umleitung - mit vollständiger Befehlszeile und Elternprozess.
  • Pfad-Kontext. Die bekannten Profilpfade sind überschaubar; ein Schreibzugriff genau dorthin ist aussagekräftig, besonders beim systemweiten Profil, das im Alltag kaum angefasst wird.
  • Werkzeug-Kontext. Wird das Profil von einem untypischen Prozess geschrieben - nicht von einem Editor oder von PowerShell selbst -, ist das ein starkes Signal; Grundlagen zum Missbrauch mitgelieferter Bordmittel unter Living off the Land.

Das Muster im Log

Drei Signale tragen. Das erste ist der Schreibzugriff auf ein benutzerbezogenes Profil im Documents-Ordner. Das zweite ist das Beschreiben eines Profils über die Kommandozeile, erkennbar an einem Schreib-Cmdlet oder einer Umleitung zusammen mit profile.ps1 oder der Variable $PROFILE. Das dritte ist der Schreibzugriff auf das systemweite Profil unterhalb der Windows-Verzeichnisse - selten und deshalb besonders ernst zu nehmen. Legitime Treffer stammen von Entwicklern und Administratoren, die ihr eigenes Profil pflegen, sowie von Setup-Skripten. Auffällig wird es, wenn das Profil von einem ungewöhnlichen Prozess geschrieben wird, von einem Konto, das sonst keine Profile anfasst, oder kurz nach verdächtiger Aktivität wie einem Nachladen. Der Blick auf schreibenden Prozess, Konto und Pfad trennt den Alltag vom Angriff.

Drei Sigma-Regeln

Die Regeln sind mit sigma-cli geprüft und nehmen die drei Signale: den Schreibzugriff auf ein benutzerbezogenes Profil, das Beschreiben über die Kommandozeile und den Schreibzugriff auf das systemweite Profil. Zwei werten die Dateianlage aus, eine die Prozess-Telemetrie.

1. Schreibzugriff auf ein benutzerbezogenes PowerShell-Profil (T1546.013). Anlegen oder Verändern von Microsoft.PowerShell_profile.ps1 im Documents-Ordner. Die Regel steht auf level: medium.

Sigma
title: Schreibzugriff auf ein benutzerbezogenes PowerShell-Profil
id: 3f7a1c62-9b84-4e51-a2d7-6c1e9f4b8a30
status: experimental
description: |
  Erkennt das Anlegen oder Veraendern eines benutzerbezogenen PowerShell-Profils (Microsoft.PowerShell_profile.ps1
  oder Microsoft.PowerShellISE_profile.ps1 im Documents-Verzeichnis). Angreifer hinterlegen hier Code, der bei
  jedem Start einer PowerShell-Sitzung des Benutzers automatisch ausgefuehrt wird (PowerShell Profile Persistence).
references:
  - https://attack.mitre.org/techniques/T1546/013/
author: blue-team.net
tags:
  - attack.persistence
  - attack.t1546.013
logsource:
  product: windows
  category: file_event
detection:
  sel:
    TargetFilename|contains: '\Documents\'
    TargetFilename|endswith:
      - '\Microsoft.PowerShell_profile.ps1'
      - '\Microsoft.PowerShellISE_profile.ps1'
  condition: sel
falsepositives:
  - Entwickler und Administratoren pflegen eigene PowerShell-Profile - bekannte Nutzer und Verwaltungswerkzeuge als Baseline ausnehmen
level: medium

2. Beschreiben eines Profils über die Kommandozeile (T1546.013). Ein Schreib-Cmdlet oder eine Umleitung zusammen mit profile.ps1 oder $PROFILE. Ebenfalls level: medium.

Sigma
title: Beschreiben eines PowerShell-Profils ueber die Kommandozeile
id: 5a2e8d41-7c93-4b62-9f18-3d6a1b7e4c25
status: experimental
description: |
  Erkennt das Beschreiben eines PowerShell-Profils ueber die Kommandozeile - etwa wenn Inhalt per Add-Content,
  Set-Content, Out-File, New-Item oder per Umleitung in profile.ps1 oder in die Variable $PROFILE geschrieben wird.
  Dieser Weg legt Autostart-Code fuer kommende PowerShell-Sitzungen ab (PowerShell Profile Persistence).
references:
  - https://attack.mitre.org/techniques/T1546/013/
author: blue-team.net
tags:
  - attack.persistence
  - attack.t1546.013
logsource:
  product: windows
  category: process_creation
detection:
  sel_target:
    CommandLine|contains:
      - 'profile.ps1'
      - '$PROFILE'
  sel_write:
    CommandLine|contains:
      - 'Add-Content'
      - 'Set-Content'
      - 'Out-File'
      - 'Tee-Object'
      - 'New-Item'
      - '>>'
  condition: sel_target and sel_write
falsepositives:
  - Setup-Skripte und Profilverwaltung schreiben legitim in Profile - bekannte Skripte und Konten als Baseline ausnehmen
level: medium

3. Schreibzugriff auf ein systemweites PowerShell-Profil (T1546.013). profile.ps1 unterhalb der WindowsPowerShell-Systemverzeichnisse oder im PowerShell-Installationspfad. Wegen der Seltenheit auf level: high.

Sigma
title: Schreibzugriff auf ein systemweites PowerShell-Profil
id: 7c4b9e28-2a61-4d83-b5f9-1e8d3a6c7b42
status: experimental
description: |
  Erkennt das Anlegen oder Veraendern eines systemweiten PowerShell-Profils (profile.ps1 unterhalb der
  WindowsPowerShell-Systemverzeichnisse oder im PowerShell-Installationspfad). Ein systemweites Profil gilt fuer
  alle Benutzer und Sitzungen, wird im Alltag kaum angefasst und ist daher ein starkes Persistenz-Signal.
references:
  - https://attack.mitre.org/techniques/T1546/013/
author: blue-team.net
tags:
  - attack.persistence
  - attack.t1546.013
logsource:
  product: windows
  category: file_event
detection:
  sel:
    TargetFilename|endswith: '\profile.ps1'
    TargetFilename|contains:
      - '\System32\WindowsPowerShell\'
      - '\SysWOW64\WindowsPowerShell\'
      - '\Program Files\PowerShell\'
  condition: sel
falsepositives:
  - Softwareverteilung oder ein bewusst gepflegtes systemweites Profil - solche Rollouts als Baseline dokumentieren und ausnehmen
level: high

Härtung: der Angriff, der ins Leere läuft

  • Skriptausführung einhegen. PowerShell mit Constrained Language Mode betreiben und per AppLocker oder WDAC steuern, welcher Skriptcode überhaupt laufen darf - ein manipuliertes Profil läuft dann ins Leere.
  • Script Block Logging aktivieren. So wird der im Profil hinterlegte Code beim Ausführen sichtbar, selbst wenn der Schreibzugriff einmal durchrutscht.
  • Profilpfade überwachen. Die bekannten Profilpfade gezielt per Dateiüberwachung im Blick behalten - besonders das systemweite Profil, das sich im Betrieb kaum ändert.
  • Befehlszeile protokollieren. Prozess-Befehlszeile (Event 4688 mit Command-Line-Auditing oder Sysmon) zuverlässig erfassen, damit das Beschreiben über die Kommandozeile nicht im Verborgenen bleibt.

Der Test

Die Erkennung lässt sich im Lab gefahrlos prüfen, auf einem isolierten System mit aktivem Sysmon und Command-Line-Auditing - mit harmlosem Inhalt, etwa einer Kommentarzeile:

  • Für Regel 1 eine harmlose Zeile in das eigene Benutzerprofil im Documents-Ordner schreiben und prüfen, dass Sysmon Event 11 den Schreibzugriff zeigt.
  • Für Regel 2 denselben Inhalt per Add-Content oder Out-File über die Kommandozeile setzen und kontrollieren, dass Event 4688 den Aufruf samt Befehlszeile erfasst.
  • Für Regel 3 eine Testdatei im systemweiten Profilpfad anlegen (und wieder entfernen) und prüfen, dass die Regel auf high auslöst.
  • Breiter wird der Test mit den Fällen zu T1546.013 aus Atomic Red Team.

Fehlalarme und Tuning

  • Entwickler und Administratoren. Wer PowerShell intensiv nutzt, pflegt oft ein eigenes Profil. Bekannte Nutzer und ihre Arbeitsplätze als Baseline aufnehmen, damit Regel 1 und 2 im Alltag ruhig bleiben.
  • Setup- und Verteilungssoftware. Rollouts können Profile legitim anfassen. Solche Prozesse und Zeitfenster dokumentieren und ausnehmen, statt pauschal stummzuschalten.
  • Systemweites Profil ernst nehmen. Regel 3 steht bewusst auf high - ein Schreibzugriff dorthin ist selten und sollte außerhalb eines bekannten Rollouts immer geprüft werden.
  • Schreibenden Prozess prüfen. Ein Profil, das von einem Editor oder von PowerShell selbst geschrieben wird, ist Alltag; derselbe Schreibzugriff aus einem Office-Programm oder einem nachgeladenen Prozess ist es nicht - nach dem Kontext priorisieren.

Fazit

PowerShell Profile Persistence ist eine leise, wirksame Methode, Code dauerhaft wiederkehren zu lassen: Er läuft bei jedem Start einer Sitzung, ohne neuen Dienst und ohne klassischen Autostart-Eintrag. Der Angelpunkt der Erkennung ist der Schreibzugriff auf eine Profildatei - benutzerbezogen im Documents-Ordner, über die Kommandozeile oder systemweit unterhalb der Windows-Verzeichnisse. Die verlässlichen Signale liefern Sysmon Event 11 und die Prozess-Befehlszeile. Die wirksamste Härtung sind eingehegte Skriptausführung, aktives Script Block Logging und eine gezielte Überwachung der bekannten Profilpfade. 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.