Holmes CTF 2025 - The Enduring Echo - Writeup [2/4]
Deuxième épreuve du CTF “Holmes CTF 2025”, suite de la première partie
The Enduring Echo
Description : LeStrade passes a disk image artifacts to Watson. It's one of the identified breach points, now showing abnormal CPU activity and anomalies in process logs.
Le challenge fournit un répertoire généré par KAPE, contenant plusieurs artefacts Windows fréquemment utilisés en forensic : journaux d’événements (.evtx), ruche(s) de registre (SAM, SYSTEM, NTUSER.DAT…), historiques de navigation, ainsi que des fichiers Prefetch et AmCache.
Difficulté : 🟩◻️◻️ - Easy
Questions
1 - What was the first (non cd) command executed by the attacker on the host? (string)
Pour commencer l’analyse, je me suis concentré sur les journaux d’événements Windows (.evtx) situés dans C:\Windows\System32\winevt\Logs. Ces fichiers permettent de tracer la création de processus, les connexions et autres actions système utiles pour reconstituer l’attaque.
Dans notre cas, celui qui nous intéresse principalement est security.etvx qui est le journal d’événement où l’on peut retrouver par exemple, les tentatives de connexion, les changements de mot de passe, les modifications de droits et de stratégies, ou encore la création de processus.
Les fichiers de logs evtx sont trouvable dans le répertoire : \C\Windows\System32\winevt\logs .
Une fois le fichier security.etvx ouvert, il y a beaucoup de logs avec des dates différentes, pour cela j’essaye de regarder pour chaque date, les eventID 4688 (Process Creation) qui vont souvent être parlant et permettre de voir des comportements suspects, et en cherchant on tombe rapidement sur ces logs :

On observe l’exécution de cmd.exe via WmiPrvSE.exe (WMI). La commande est lancée en mode silencieux et redirige sa sortie vers un fichier temporaire dans le partage ADMIN$. WMI (Windows Management Instrumentation) est une interface système qui permet d’interroger et de contrôler à distance ou localement des composants Windows (processus, services, registres, événements) via des scripts ou des commandes.
En continuant cette fois via CTRL+F à chercher le processus WmiPrvSE.exe , on peut retracer chronologiquement les commandes effectués :

Cela nous permet de trouver la réponse, la toute première command hors cd .
✅Réponse : systeminfo
2 - Which parent process (full path) spawned the attacker’s commands? (C:\FOLDER\PATH\FILE.ext)
Les entrées 4688 et la traçabilité des appels WMI confirment que les commandes ont été lancées via le service WMI. Le processus parent est :
✅ Réponse : C:\Windows\System32\wbem\WmiPrvSE.exe
3 - Which remote-execution tool was most likely used for the attack? (filename.ext)
La méthode d’exécution (WMI, exécution de commandes à distance via WmiPrvSE.exe) correspond au comportement d’un utilitaire bien connu de la suite Impacket.
✅ Réponse : wmiexec.py
4 - What was the attacker’s IP address? (IPv4 address)
En continuant de suivre la trace des commandes via WmiPrvSE.exe on arrive à trouver celle-ci :

On retrouve aussi cette adresse IP si on filtre les EventID 4624 (An account was successfully logged on) qui confirme que l’attaquant s’est connecté depuis cette adresse IP :

✅ Réponse : 10.129.242.110
5 - What is the first element in the attacker's sequence of persistence mechanisms? (string)
La question est un peu piégeuse : il faut comprendre quel identifiant l’attaquant a donné à son premier mécanisme de persistance, et non rechercher le type de mécanisme en soi.
En filtrant les EventID 4688 (Process Creation) et en suivant la chronologie des commandes, on voit la création d’une tâche planifiée nommée :

Cette tâche exécute un script PowerShell toutes les 2 minutes sous le compte SYSTEM il s’agit donc très probablement du premier mécanisme de persistance mis en place par l’attaquant.
✅ Réponse : SysHelper Update
6 - Identify the script executed by the persistence mechanism. (C:\FOLDER\PATH\FILE.ext)
La commande associée à la tâche planifiée montre explicitement le chemin du script PowerShell exécuté pour assurer la persistance. Le script est C:\Users\Werni\AppData\Local\JM.ps1
Ce fichier a également été collecté via KAPE, ce qui permet d’analyser son contenu (création d’utilisateur, exfiltration, modification du pare-feu, activation RDP, etc.).

✅ Réponse : C:\Users\Werni\AppData\Local\JM.ps1
7 - What local account did the attacker create? (string)
En analysant le contenu de JM.ps1, on constate que le script vérifie l’absence de plusieurs comptes préconfigurés :

Puis crée aléatoirement un compte local si nécessaire :

Ajoute ce compte aux groupes Administrators et Remote Desktop Users :

Enfin, le script active le RDP et ouvre la règle pare‑feu correspondante, ce qui donne un accès à distance persistant avec privilèges élevés. Enfin, le script exfiltre immédiatement le couple user|password encodé en Base64 vers http://NapoleonsBlackPearl.htb/Exchange.

La liste des utilisateurs trouvés dans le script est :
svc_netupdsvc_dnssys_helperWinTelemetryUpdaterSvc
En croisant avec les événements EventID 4720 (A user account was created) dans security.evtx, on trouve qu’un seul compte a été créé le 25/08/2025 :

✅ Réponse : svc_netupd
8 - What domain name did the attacker use for credential exfiltration? (domain)
Le domaine vers lequel le script exfiltre immédiatement le couple user:password (encodé en Base64) est visible à la fois dans JM.ps1 et dans les logs security.evtx :
✅ Réponse : NapoleonsBlackPearl.htb
9 - What password did the attacker's script generate for the newly created user? (string)
Cette question est piégeuse à cause des fuseaux horaires : la date/heure relevée dans les logs peut varier selon l’environnement du joueur, il faut donc être attentif à la source temporelle utilisée pour reconstruire le mot de passe.
Contexte et stratégie :
Le script
JM.ps1crée un utilisateur dont le mot de passe suit la convention :
Watson_yyyyMMddHHmmssNous connaissons le nom de l’utilisateur créé :
svc_netupd.En croisant les métadonnées (
$MFT) et les logs, la date de création pertinente est le 24/08/2025.Il restait donc à trouver l’heure exacte (HHmmss) utilisée lors de la génération du mot de passe.
Plutôt que d’essayer d’inférer l’heure depuis des timestamps ambigus, j’ai extrait le NTLM hash du compte local depuis les fichiers SAM et SYSTEM, puis j’ai bruteforcé la portion horaire du mot de passe avec hashcat.
Extraction du hash NTLM :
À partir des fichiers SAM et SYSTEM (récupérés par KAPE), j’ai utilisé la suite Impacket pour dumper les hashes via impacket-secretsdump -sam ./SAM -system ./SYSTEM LOCAL :

Dans la sortie, le hash NTLM du compte svc_netupd est : 532303a6fa70b02c905f950b60d7da51 (J’ai placé ce hash dans un fichier hash.txt pour la suite.)
Bruteforce de la partie horaire avec hashcat
Le format du mot de passe connu : Watson_20250824HHmmss → 6 chiffres inconnus.
J’utilise donc hashcat en mode bruteforce numérique pour ces 6 positions :
hashcat -m 1000 -a 3 hash.txt 'Watson_20250824?d?d?d?d?d?d'
Le masque ?d force la recherche sur les chiffres 0-9. La recherche s’est terminée très rapidement et a révélé le mot de passe complet.

✅ Réponse : Watson_20250824160509
10 - What was the IP address of the internal system the attacker pivoted to? (IPv4 address)
En poursuivant l’analyse des EventID 4688 et des invocations de WmiPrvSE.exe, on tombe sur une invocation de netsh qui met en place une redirection TCP locale.

netsh est un utilitaire en ligne de commande Windows qui permet de visualiser et configurer les paramètres réseau (interfaces, adresses IP, pare-feu, profils Wi-Fi, forwarding/portproxy, etc.). Si on cherche dans les processus créer par netsh on peut tomber sur ça :

La commande crée une règle qui écoute sur toutes les interfaces au port 9999 et qui relaie le trafic vers l’adresse 192.168.11.101 sur le port 22 (SSH). On en déduit que l’attaquant a pivoté vers :
✅ Réponse : 192.168.11.101
11 - Which TCP port on the victim was forwarded to enable the pivot? (port 0-65565)
La redirection netsh sur la machine victime écoute localement sur le port 9999, qui est donc le port forwarded utilisé pour le pivot.
✅ Réponse : 9999
12 - What is the full registry path that stores persistent IPv4→IPv4 TCP listener-to-target mappings? (HKLM......)
D’après les traces et la documentation sur netsh portproxy, les mappings persistants sont stockés dans la ruche SYSTEM sous la clé PortProxy\v4tov4\tcp. (https://adepts.of0x.cc/netsh-portproxy-code/)
On peut trouver la clé de registre via RegistryExplorer et le fichier SYSTEM :

L’instance attendue par le challenge utilise CurrentControlSet (plutôt que un ControlSet numéroté), donc la clé complète est :
✅ Réponse : HKLM\System\CurrentControlSet\Services\PortProxy\v4tov4\tc
13 - What is the MITRE ATT&CK ID associated with the previous technique used by the attacker to pivot to the internal system? (Txxxx.xxx)
La technique correspondante (port forwarding / proxying pour redirection de connexions) est listée sous la sous-technique Proxy (T1090) : Internal Proxy. (https://attack.mitre.org/techniques/T1090/001/)
L’identifiant exact attendu est :
✅Réponse : T1090.001
14 - Before the attack, the administrator configured Windows to capture command line details in the event logs. What command did they run to achieve this? (command)
Les commandes PowerShell de l’administrateur sont visibles dans C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt. On y trouve la commande qui active l’inclusion de la ligne de commande complète dans les événements de création de processus (EventID 4688) via la valeur de registre ProcessCreationIncludeCmdLine_Enabled :

✅ Réponse : reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" /v ProcessCreationIncludeCmdLine_Enabled /t REG_DWORD /d 1 /f


