Ce qui suit est un cas fictif. Le nom d'hôte, les hashes et l'opérateur sont inventés. La forme de l'intrusion, non. J'ai bâti des chronologies très semblables à celle-ci à partir de répertoires Prefetch sur des missions réelles, et les motifs se répètent.
L'intérêt du parcours est de montrer comment Prefetch se lit quand vous avez une vraie intrusion entre les mains et que les huit horodatages d'exécution sont la chose la plus fiable que vous ayez. Couplez chaque étape aux artefacts qui la corroborent ou l'étendent.
Le décor
Une petite société de services professionnels. Soixante stations et quatre serveurs. Vendredi soir, les partages sur FS01 deviennent inaccessibles. Une note de rançon apparaît à \\FS01\Shared\!!READ-ME!!.txt. Le lundi matin, le responsable IT a acquis des données de triage sur FS01, le jump host JH01, et trois stations dont le patient zéro, WS-ACCT-04.
Je récupère les répertoires Prefetch des cinq hôtes le mardi. Les canaux EVTX Security et Sysmon sont partiels. Certains ont été effacés, d'autres n'ont jamais eu Sysmon. Prefetch est en grande partie intact. C'est typique.
Ce que dit WS-ACCT-04
Commencez là où l'attaquant a commencé.
Parser C:\Windows\Prefetch\ sur WS-ACCT-04 avec PECmd renvoie 412 fichiers .pf. La plupart sont du bruit : binaires Office, navigateurs, composants antivirus, utilitaires Windows. Les intéressants émergent quand je filtre sur des chemins d'exécutable hors \Windows\ et \Program Files\, trie par NTFS Created décroissant, et regarde les trente premières lignes.
Les principaux hits, par ordre d'heure de création (arrondi pour le parcours) :
| Created | Filename | Exec path | Runs |
|---|---|---|---|
| Wed 14:02 | WINWORD.EXE-00B41B71.pf | C:\Program Files\Microsoft Office\Office16\WINWORD.EXE | 47 |
| Wed 14:03 | EQNEDT32.EXE-1F2E0AB2.pf | C:\Program Files\Common Files\Microsoft Shared\Equation\EQNEDT32.EXE | 1 |
| Wed 14:03 | MSHTA.EXE-2A1D9904.pf | C:\Windows\System32\mshta.exe | 1 |
| Wed 14:04 | POWERSHELL.EXE-3DD11E22.pf | C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe | 8 |
| Wed 14:05 | WMIPRVSE.EXE-XXXXXXXX.pf | C:\Windows\System32\wbem\WmiPrvSE.exe | (nombreuses) |
| Wed 14:06 | CMD.EXE-XXXXXXXX.pf | C:\Windows\System32\cmd.exe | (nombreuses) |
| Wed 14:11 | RUNDLL32.EXE-XXXXXXXX.pf | C:\Windows\System32\rundll32.exe | (nombreuses) |
| Wed 14:12 | UPDATE.EXE-77AAFF12.pf | C:\Users\Public\update.exe | 1 |
| Wed 14:14 | NLTEST.EXE-XXXXXXXX.pf | C:\Windows\System32\nltest.exe | 1 |
| Wed 14:14 | WHOAMI.EXE-XXXXXXXX.pf | C:\Windows\System32\whoami.exe | 1 |
| Wed 14:15 | PSEXEC.EXE-A1A1A1A1.pf | C:\Users\Public\psexec.exe | 3 |
| Wed 14:23 | 7Z.EXE-B2B2B2B2.pf | C:\Users\Public\7z.exe | 1 |
Voilà une chaîne d'intrusion complète en une vingtaine de minutes, reconstituée depuis le répertoire Prefetch d'un seul hôte.
Lu en clair :
- 14:02 : Word s'ouvre. (Exécution 47 sur 47, usage normal de Word sur cet hôte.)
- 14:03 :
EQNEDT32.EXEtourne pour la première fois sur cet hôte. Equation Editor. Vecteur d'exploit 2017 pour DOCX malveillant. Le.pfdeWINWORD.EXEa été mis à jour à 14:02, juste avant. Couplez avec les fichiers LNK et les artefacts du client mail. L'utilisateur a ouvert un document malveillant. - 14:03 :
MSHTA.EXEtourne pour la première fois. La liste de chargement (plus bas) montre un script dans un répertoire temp. L'exploit d'Equation Editor a déposé un payload HTA. - 14:04 : PowerShell démarre. La première de huit exécutions.
- 14:05 : Activité de
WmiPrvSE.exe. Possiblement des appels WMI distants ; vérifiez la liste de chargement et l'EVTX correspondant. - 14:11 :
rundll32.exetourne. Souvent un vecteur d'exécution de DLL. - 14:12 : Un binaire nommé
update.exetourne depuisC:\Users\Public\. Première et unique exécution. Pas unupdate.exelégitime ; le chemin est faux. Les octets de hash77AAFF12n'entreront en collision avec rien de bénin. - 14:14 :
nltest.exeetwhoami.exetournent, pour la première fois tous deux. Reconnaissance de domaine. - 14:15 :
psexec.exetourne depuisC:\Users\Public\. Trois exécutions, suggérant trois cibles de mouvement latéral. - 14:23 :
7z.exetourne depuisC:\Users\Public\. Archivage pour staging ou exfiltration.
Cet ordre est venu directement des horodatages Created de Prefetch plus du champ Last run par .pf. Ce n'est pas une supposition.
Ce que les listes de chargement confirment
Les entrées Prefetch me disent ce qui a tourné. Les listes de chargement me disent ce qu'a fait chaque binaire.
Liste de chargement de MSHTA.EXE-2A1D9904.pf, filtrée aux chemins non-système :
\DEVICE\HARDDISKVOLUME2\USERS\ALICE\APPDATA\LOCAL\TEMP\BACK.HTA
\DEVICE\HARDDISKVOLUME2\USERS\ALICE\APPDATA\LOCAL\TEMP\STG1.PS1
Cela situe le payload HTA (livré par l'exploit Equation Editor) à C:\Users\Alice\AppData\Local\Temp\back.hta, et un script PowerShell de suivi en stg1.ps1 dans le même répertoire.
Liste de chargement de POWERSHELL.EXE-3DD11E22.pf, filtrée :
\DEVICE\HARDDISKVOLUME2\USERS\ALICE\APPDATA\LOCAL\TEMP\STG1.PS1
\DEVICE\HARDDISKVOLUME2\USERS\ALICE\APPDATA\LOCAL\TEMP\STG2.DLL
\DEVICE\HARDDISKVOLUME2\USERS\PUBLIC\UPDATE.EXE
\DEVICE\HARDDISKVOLUME2\USERS\PUBLIC\PSEXEC.EXE
\DEVICE\HARDDISKVOLUME2\USERS\PUBLIC\7Z.EXE
PowerShell a chargé le script de stage 1, chargé une DLL stage 2, puis soit stagé soit invoqué l'outillage de mouvement latéral sous \Users\Public\. Le Prefetch ne me dit pas ce que PowerShell a fait de ces fichiers (lecture, exécution, copie), mais la présence de ces chemins dans la liste de chargement dit que PowerShell les a touchés.
Liste de chargement de UPDATE.EXE-77AAFF12.pf :
\DEVICE\HARDDISKVOLUME2\USERS\PUBLIC\UPDATE.EXE
\DEVICE\HARDDISKVOLUME2\PROGRAMDATA\STG\KEY.BIN
\DEVICE\HARDDISKVOLUME2\WINDOWS\SYSTEM32\BCRYPT.DLL
\DEVICE\HARDDISKVOLUME2\WINDOWS\SYSTEM32\BCRYPTPRIMITIVES.DLL
\DEVICE\HARDDISKVOLUME2\USERS\ALICE\DOCUMENTS\<de nombreux chemins .docx, .xlsx, .pdf>
update.exe est le chiffreur. Il a chargé un fichier de clé depuis \ProgramData\stg\key.bin. Il a chargé les primitives cryptographiques Windows. Et il a ouvert chaque document du répertoire Documents d'Alice.
Le plafond de la liste de chargement avoisine 1000 entrées. Sur un hôte riche en documents, on touche ce plafond. L'ensemble des chemins que vous voyez est une énumération partielle de ce qui a été touché.
Liste de chargement de PSEXEC.EXE-A1A1A1A1.pf :
\DEVICE\HARDDISKVOLUME2\USERS\PUBLIC\PSEXEC.EXE
\DEVICE\HARDDISKVOLUME2\USERS\PUBLIC\UPDATE.EXE
\DEVICE\HARDDISKVOLUME2\USERS\PUBLIC\PSEXEC.SYS
PsExec s'est chargé lui-même, le chiffreur (suggérant que psexec a été utilisé pour pousser update.exe vers d'autres hôtes) et son propre driver kernel. Le compteur d'exécutions à trois combiné à la liste de chargement suggère fortement trois poussées latérales du chiffreur.
Les huit horodatages me donnent la cadence
Pour PSEXEC.EXE-A1A1A1A1.pf, le tableau des huit horodatages contient trois horaires valides :
14:15:22
14:16:48
14:19:01
Cela me donne le rythme de l'attaque : environ 90 secondes entre poussées latérales. Sur FS01, le serveur de fichiers, je m'attends à trouver un UPDATE.EXE-XXXXXXXX.pf dont le premier horodatage est environ 14:15:30 plus quelques secondes, le push psexec au démarrage du chiffreur étant rapide.
Dans le répertoire Prefetch de FS01, je trouve UPDATE.EXE-77AAFF12.pf (mêmes octets de hash, même chemin C:\Users\Public\update.exe aussi sur FS01) avec un premier horodatage à 14:15:34. Cela confirme le mouvement latéral.
Le même update.exe apparaît sur deux autres hôtes, avec premiers horodatages à 14:16:55 et 14:19:08. Chacun est à quelques secondes du push psexec correspondant.
J'ai désormais, à partir du seul Prefetch, la chronologie complète du mouvement latéral du chiffreur sur quatre hôtes.
Ce que Prefetch ne m'a pas donné
Le Prefetch ne m'a pas donné la ligne de commande de ces exécutions. Pour ça il me faut Sysmon EID 1, présent sur deux des cinq hôtes. De là je récupère les arguments de PowerShell, le processus parent d'update.exe, et le contexte utilisateur.
Le Prefetch ne m'a pas donné la destination réseau du canal C2. Les fichiers back.hta et stg1.ps1 contiennent vraisemblablement cette information, mais ils ne sont pas dans le Prefetch, seuls leurs chemins le sont. Si les fichiers survivent sur disque, je les parse. S'ils ont été nettoyés, je regarde la RAM (si j'ai acquis une image mémoire), le pagefile, ou l'historique de navigation à la recherche de traces du domaine C2.
Le Prefetch ne m'a pas donné le contenu chiffré effectif ni les perspectives de récupération. Pour ça il me faut la MFT et le journal USN pour comprendre quels fichiers ont été touchés, dans quel ordre, et si des VSC ont survécu. La liste de chargement du chiffreur m'a dit quels répertoires ont été visés ; la MFT et l'USN m'ont dit ce qui est arrivé aux fichiers de ces répertoires.
Pourquoi Prefetch a été la colonne vertébrale de cette enquête
EVTX était incomplet. L'attaquant avait effacé le log Security sur FS01 (l'événement 1102 d'audit log effacé était présent, mais les entrées 4688 pertinentes avaient disparu). Sysmon n'était pas déployé partout. AmCache avait des hashes pour certains binaires mais pas tous (certains avaient été renommés avant exécution, et AmCache associe par métadonnées du binaire d'une façon qui rate parfois).
Prefetch traversait tout cela. Il est par machine, il écrit en continu, et il était complet sur quatre des cinq hôtes (un hôte avait redémarré assez de fois pour que les anciens .pf aient expiré, mais les récents étaient là). Le tableau de huit horodatages sur les .pf du chiffreur, croisé entre hôtes, a été le seul artefact me permettant de bâtir la chronologie de mouvement latéral avec confiance à la sous-minute.
Pour le rapport, j'ai cité les horodatages directement. La société d'IR défenseuse avec laquelle nous travaillions avait cité une chronologie EVTX-only qui ratait deux des quatre hôtes touchés (ceux où le chiffreur a tourné mais où le log Security avait été effacé et Sysmon n'était pas présent). Leur chronologie était incomplète d'une manière que Prefetch a corrigée.
Le motif en un paragraphe
Une vraie intrusion produit une signature Prefetch caractéristique : un cluster de premières exécutions d'utilitaires système (Equation Editor, MSHTA, rundll32, nltest, whoami) dans une fenêtre temporelle serrée, suivi de premières exécutions de binaires d'attaquant depuis des chemins inscriptibles par l'utilisateur (\Users\Public\, \AppData\Local\Temp\, \ProgramData\), suivi d'un petit nombre d'exécutions d'outils de mouvement latéral (PsExec, WMIC, parfois des outils légitimes comme des clients RDP), suivi du chiffreur lui-même. La séquence entière tient généralement en vingt à quatre-vingt-dix minutes. Le tableau de huit horodatages Prefetch par hôte épingle chaque étape à la seconde.
Quand vous parsez le répertoire Prefetch d'un hôte touché et que vous ne voyez pas cette signature, soit vous regardez un hôte qui n'a pas réellement été compromis, soit l'attaquant a été suffisamment sophistiqué pour nettoyer Prefetch, auquel cas les résidus de suppression dans la MFT et le journal USN sont l'endroit suivant à regarder.
Si vous voulez essayer le workflow contre votre propre répertoire Prefetch dans le navigateur, le parser de ce site charge des fichiers .pf localement et vous donne le tableau triable dont dépend le workflow ci-dessus.
Pour aller plus loin
- Eric Zimmerman, PECmd — parsez un répertoire en CSV et le workflow ci-dessus émerge naturellement.
- The DFIR Report, comptes rendus annuels — beaucoup incluent des preuves Prefetch présentées sous une forme proche.
- Microsoft, Mitigating Ransomware — contexte côté défenseur sur l'importance de tout cela.