# Holmes CTF 2025 - The Enduring Echo - Writeup [2/4]

Deuxième épreuve du CTF “Holmes CTF 2025”, suite de la [première partie](https://menta.re/holmes-ctf-2025-the-card-writeup)

## 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 :

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1759149431456/b10b6bd4-ddcc-4fb4-86ae-6eacb4f5359a.png align="center")

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 :

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1759149726662/f742cf5e-3729-47fe-a2ac-8d5d90f9c52d.png align="center")

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.

* Source : [https://www.crowdstrike.com/en-us/blog/how-to-detect-and-prevent-impackets-wmiexec/](https://www.crowdstrike.com/en-us/blog/how-to-detect-and-prevent-impackets-wmiexec/)
    

✅ 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 :

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1759150281400/290018ca-9e7d-4920-af6a-d5d5a95a17d5.png align="center")

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 :

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1759150444891/3ede815e-9a87-45ce-abb3-690da0a2be33.png align="center")

✅ 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 :

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1759150665800/7fce917b-59ab-45ea-8b1b-e8b5c3712e27.png align="center")

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.).

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1759153400915/f1f53984-bf22-4c55-8f86-1c58fff02a3d.png align="center")

✅ 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 :

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1759153833233/9daa6156-0a6e-4a25-b20a-eeedd849f7d8.png align="center")

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

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1759153887722/b9f5f16c-6aef-4afb-9cbd-e26dc232f375.png align="center")

Ajoute ce compte aux groupes `Administrators` et `Remote Desktop Users` :

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1759153914118/cd9eea35-623a-4d21-98ce-66d2ff78ac12.png align="center")

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`.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1759153933237/248adc31-1c36-4615-9289-3532f4595938.png align="center")

La liste des utilisateurs trouvés dans le script est :

* `svc_netupd`
    
* `svc_dns`
    
* `sys_helper`
    
* `WinTelemetry`
    
* `UpdaterSvc`
    

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` :

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1759154136524/c026c554-0773-44c5-bbac-591759eabfce.png align="center")

✅ 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.ps1` crée un utilisateur dont le mot de passe suit la convention :  
    `Watson_yyyyMMddHHmmss`
    
* Nous 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` :

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1759155118235/3c1f1244-62c3-40c6-89f0-8d3d5d142435.png align="center")

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.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1759155229006/4a01daf9-7ee4-48db-8f50-491fd3c74e37.png align="center")

✅ 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.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1759222546291/079fd911-2666-4a14-914a-2174da90387f.png align="center")

`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 :

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1759222651400/9848cd7e-3b34-4f37-93a6-5bb55ac75ed0.png align="center")

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/](https://adepts.of0x.cc/netsh-portproxy-code/))

On peut trouver la clé de registre via `RegistryExplorer` et le fichier `SYSTEM` :

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1759223195898/946fb3a7-2b67-4065-9b03-4caf32ea5c6a.png align="center")

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/](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` :

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1759223779399/842e62fb-b7a0-4552-b8ff-7bf147d25c2d.png align="center")

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