DragonjarCTF2023 - Reto Criptografía

Como todos sabemos, la décima edición de la conferencia DragonJar Security ha concluido, dejándonos una gran cantidad de conocimientos. En este caso, nos tocó enfrentar alrededor de 5 desafíos. No puedo empezar sin mencionar que el conocimiento para resolver este CTF proviene del profesor José Moreno en la clase de Criptografía I.

Reto 1 - Reto Criptográfico (Fácil)

En este reto se nos planteó una situación hipotética en la que estábamos siendo atacados por una persona externa. El objetivo de este reto era encontrar la flag a partir de una cadena de caracteres.

“Eres la ciberseguridad de una empresa la cual fue atacada. Para llevar a cabo tu misión, hemos podido acceder al ordenador del principal sospechoso, y hemos encontrado unos datos que no sabemos interpretar. Podría ser una fotografía, texto ASCII o, incluso, una captura de red.

eNprYEouTk4sqNTLSaxMLSrWyzHici3JSC3iKmRIjk/OT0lNLuZKzQMxuAoZI+wZGBgO70dABjDgYHBlYNBgYGRgcGBTPNQcenjaoZbSegaggAiLAwMUBDApMBg5MTAUMkWwAbk5iSWZeYaFzG2FLEGFrK2FbEGF7BrujjftBF4Gc6X6gUBJIUeSHgB54y28

¿Podrías encontrar el país desde el que opera el fiscal corrupto? La flag del reto será: flag{país}, sustituyendo país por el nombre del país en inglés y escrito en minúsculas.”

Conocimientos Necesarios
  • Python

  • Base64

  • Cyberchef

Hora de Realizar el reto

Ahora sí, como quien diría por aquí, vamos al grano. A la hora de afrontar este reto, es de suma importancia reconocer a qué tipo de cadena nos estamos enfrentando. En este caso, podemos utilizar CyberChef para describir exactamente lo que estamos viendo. Puedes encontrarlo en el siguiente enlace:

https://gchq.github.io/CyberChef/

Lo primero que notamos al ingresar la cadena completa de caracteres es que se trata de una codificación Base64. El Base64 se utiliza comúnmente en aplicaciones de transferencia de datos en las que los datos binarios deben ser almacenados y transmitidos a través de canales que solo admiten texto, como el correo electrónico o las URL. La codificación Base64 toma secuencias de bytes y las convierte en una serie de caracteres ASCII legibles. Por lo tanto, debemos decodificar esta cadena de caracteres posteriormente.

Si profundizamos un poco más y consideramos que proviene de una codificación Base64, podemos notar que estamos tratando con una compresión Zlib Deflate.

Zlib es una biblioteca de software para la compresión de datos que se utiliza para comprimir y descomprimir datos en diversas aplicaciones y formatos de archivos.

Otra forma que podríamos utilizar para descubrir todo de manera más eficiente es empleando la herramienta “Magic” del panel de operaciones de CyberChef. Esta herramienta nos desglosará toda la información relacionada con el archivo.

Ahora que sabemos esto, podemos crear fácilmente un script en Python que descodifique la Base64 y, posteriormente, descomprima el Zlib. En este caso, mostraré el script completo y luego explicaré paso a paso cuál será el resultado de la flag.

from scapy.layers.inet import IP
from scapy.layers.l2 import *
import pickle
import zlib
import base64

data = b'eNprYEouTk4sqNTLSaxMLSrWyzHici3JSC3iKmRIjk/OT0lNLuZKzQMxuAoZI+wZGBgO70dABjDgYHBlYNBgYGRgcGBTPNQcenjaoZbSegaggAiLAwMUBDApMBg5MTAUMkWwAbk5iSWZeYaFzG2FLEGFrK2FbEGF7BrujjftBF4Gc6X6gUBJIUeSHgB54y28'

try:
    decodificado_base64 = base64.b64decode(data)
    print(decodificado_base64)
    print("\n")
    decodificado_zlib = zlib.decompress(decodificado_base64)
    print(decodificado_zlib)
    print("\n")
    deserializado_pickle = pickle.loads(decodificado_zlib)
    print(deserializado_pickle)
    print("\n")
    decodificado_scapy_ip = IP(decodificado_zlib)
    decodificado_scapy_ether = Ether(decodificado_zlib)
    print(decodificado_scapy_ether.show())
except zlib.error:
    print("No se pudo descomprimir el dato zlib")%

Este script hace lo siguiente: primero asigna el valor de la cadena Base64 a una variable llamada ‘data_comprimida’, la decodifica y luego la descomprime utilizando la biblioteca zlib. Si todo sale bien, deberíamos obtener dos nuevas cadenas de caracteres. La primera es la ‘data_comprimida’ decodificada desde Base64, y la segunda es la cadena que nos devuelve zlib.

5

Como podemos notar, esta cadena está relacionada con redes, posiblemente se trate de un paquete. ¿Por qué decimos esto? Bueno, existen ciertos indicios que lo sugieren. En primer lugar, observamos que contiene ‘scapy.layer.l2’. Scapy es una biblioteca de Python que se utiliza para interactuar con el tráfico de red, manipular paquetes de red y realizar análisis de protocolos de red. Pero eso no es todo, si prestamos atención a la salida, podemos notar que encontramos ‘\x80\x02’, lo cual es un indicio de que se trata de un objeto serializado con pickle. Pickle es un módulo en Python que se utiliza para la serialización y deserialización de objetos Python. La serialización es el proceso de convertir un objeto Python en una secuencia de bytes, lo que facilita su almacenamiento en archivos o su transmisión a través de la red.

Para deserializar la cadena, tendremos que utilizar pickle.load y pasarle la cadena descomprimida de zlib. También es importante mencionar que debemos importar las clases IP de Scapy y el módulo pickle. Sabiendo que se trata de un objeto serializado con pickle y que utiliza Scapy.

Si observamos la salida de la imagen anterior, nos proporcionará una dirección IP.

Ether / IP / TCP 85.214.132.117:ftp_data > 127.0.0.1:1088 S

Cosas que podemos analizar de esta cadena simple.

Ether: Esto nos indica que se trata de un paquete Ethernet, lo que sugiere que es un paquete de red.

La IP: Indica que el paquete contiene un encabezado IP, lo que nos dice que se trata de un paquete de red a nivel del Protocolo de Internet, también conocido como IP.

TCP: Indica que el paquete contiene un encabezado TCP, lo que nos lleva a pensar que se trata de un paquete del protocolo de control de transmisión, que se utiliza para la comunicación a través de conexiones TCP.

85.214.132.117:ftp_data > 127.0.0.1:1088 describe las direcciones y puertos de origen y destino del paquete. En este caso, el paquete se originó en la dirección IP 85.214.132.117 en el puerto ftp_data y se envió al destino con la dirección IP 127.0.0.1 en el puerto 1088.

La ‘S’ generalmente se refiere a la bandera “S” en TCP, que significa “SYN” (synchronize). Esto indica el inicio de una conexión TCP.

Por lo tanto, si observamos los requisitos de la flag en el enunciado del CTF, nos dice que: “La flag del reto será: flag{país}”, sustituyendo ‘país’ por el nombre del país en inglés y escrito en minúsculas. Para esto, ya tenemos la dirección IP del atacante en este caso, 85.214.132.117.

Para descubrir exactamente el país de origen del ataque, podemos buscar la ubicación de esta dirección IP. En este sentido, utilizaremos la página https://www.iplocation.net/. Colocamos nuestra dirección IP y vemos que está localizada en Alemania, Berlín, con latitud 52.5245 y longitud 13.4100.

Con esto llegamos a la conclusión que la flag es *flag{germany}.*