Null Ahmedabad April 2023 CTF Redacción

May 01 2023
La comunidad conocida como Null Ahmedabad fue fundada por un grupo de cuatro personas. El 18 de febrero de 2018, celebraron su reunión inaugural, que fue posible gracias a la asistencia de la Universidad de Ganpat.

La comunidad conocida como Null Ahmedabad fue fundada por un grupo de cuatro personas. El 18 de febrero de 2018, celebraron su reunión inaugural, que fue posible gracias a la asistencia de la Universidad de Ganpat. Su evento principal es una reunión mensual donde los participantes se reúnen para participar en debates sobre seguridad y CTF (desafíos prácticos). A medida que pasa el tiempo, Null Ahmedabad continúa expandiendo su alcance ofreciendo formatos de reuniones y talleres adicionales. Para cualquier persona interesada en la seguridad de la información, ya sea estudiante, entusiasta o profesional, Null Ahmedabad es una comunidad ideal para conectarse con otros piratas informáticos y profesionales en el área de Ahmedabad.

En abril de 2023, Null Ahmedabad organizó una competencia CTF, en la que logré asegurar el tercer lugar. Como resultado de este logro, decidí redactar un artículo.

Para explorar la comunidad nula, haga clic en:https://null.community/chapters/17-ahmedabad

Foto de Alex Chumak en Unsplash

1. ¿Acceso denegado?

El mensaje del Desafío dice:

¡Null Ahmedabad está lanzando su tienda de ropa en línea por primera vez! Sin embargo, tememos que pueda haber algunas vulnerabilidades en nuestro código. Como miembro de la comunidad de seguridad abierta, tiene la tarea de encontrar y enviar cualquier vulnerabilidad (banderas) que pueda encontrar.

Nuestra tienda está en:http://nullahm.kuldeep.io:5000/

¡Feliz compra! :)

Empecé a explorar el sitio web; tiene una función de inicio de sesión y registro.

Registré mi cuenta e inicié sesión. Empecé a investigar el código JavaScript y encontré un punto final de graphql.

Si está familiarizado con graphql, probablemente sepa que admite consultas de introspección, que generalmente están prohibidas por razones de seguridad.

Así que traté de activar la consulta de introspección y funcionó.

Inspeccioné el resultado y encontré un campo llamado `allUsers`.

Intenté acceder al nodo `allUsers` y ahora puedo acceder a los datos de todos los usuarios.

Y encontré la bandera.

2. Ataduras

El mensaje de desafío dice:

Estoy seguro de que no dejé ningún secreto en este binario, pero mi gerente aún duda de mí. ¿Puedes comprobar el binario y demostrar que está equivocado?

Tiene un binario ejecutable para descargar.

Descargué el binario y sus estadísticas de metadatos son:

Ejecutable circular LSB de 64 bits ELF, x86–64, versión 1 (SYSV), vinculado dinámicamente, intérprete /lib64/ld-linux-x86–64.so.2, BuildID[sha1]=9b34236e59bfcdbdb606def64c05cdfdbce9753b, para GNU/Linux 4.4. 0, no despojado

Parece un desafío de la vieja escuela; Sé que el formato de la bandera es "nullahm". Así que intenté usar cadenas contra el binario.

cadenas -n 7 -tx chal | grep nullahm

Secreto encontrado en el binario.

3. Históricamente inseguro

Mensaje de desafío dice:

Decodifica esto y obtén la bandera: ubsshot{d4f_700_345f}

Parece una bandera pero está encriptada como dice el aviso. Si comparo la bandera encriptada con el formato de la bandera, es decir, "nullahm", parece que es Vigenère Cipher.

Vigenère Cipher es vulnerable a ataques de texto sin formato conocidos. Tengo una parte de texto sin formato conocido, es decir, ubsshot = nullahm.

Así que escribí un pequeño script para extraer la clave:

def solve_historically_insecure(ciphertext, plaintext):

    ciphertext = ciphertext.upper()
    plaintext = plaintext.upper()
    key = ""
    for i in range(len(plaintext)):
        key += chr(((ord(ciphertext[i]) - ord(plaintext[i])) % 26) + ord('A'))
    return key
ciphertext = "ubsshot"
plaintext = "nullahm"
key = solve_historically_insecure(ciphertext, plaintext)
print("Key : ",key)

Ahora puedo usar la clave contra el texto cifrado,

def vigenere_decode(ciphertext, key):
    plaintext = ''
    key_len = len(key)
    for i in range(len(ciphertext)):
        shift = ord(key[i % key_len]) - 65
        if ciphertext[i].isupper():
            plaintext += chr((ord(ciphertext[i]) - shift - 65) % 26 + 65)
        elif ciphertext[i].islower():
            plaintext += chr((ord(ciphertext[i]) - shift - 97) % 26 + 97)
        else:
            plaintext += ciphertext[i]
    return plaintext

ciphertext = "ubsshot{d4f_700_345f}"
key = solve_historically_insecure(ciphertext, plaintext)
plaintext = vigenere_decode(ciphertext, key)
print("Plain Text : ",plaintext)

      
                

Gracias por tomarse el tiempo de leer este artículo.