Shared Secrets writeup

Descripción

A message was encrypted using a shared secret… but it looks like one side of the exchange leaked something. Can you piece together the secret and get the flag?

Download the message. And source code

Shared Secrets solución

Descargamos ambos archivos y examinamos el código:

codium encryption.py

Dentro del archivo veremos lo siguiente:

from Crypto.Util.number import getPrime
from random import randint

# Public parameters
g = 2
p = getPrime(1048)

# Server's secret
a = randint(2, p-2)
A = pow(g, a, p)

# Client secret
b = '???'  

B = pow(g, b, p)

# Shared key
shared = pow(A, b, p)

# Encrypt flag
flag = b"picoCTF{...}"
enc = bytes([x ^ (shared % 256) for x in flag])

# Write challenge info
with open("file.txt", "w") as f:
    f.write(f"g = {g}\n")
    f.write(f"p = {p}\n")
    f.write(f"A = {A}\n")
    f.write(f"b = {b} \n")
    f.write(f"enc = {enc.hex()}\n")

Por los parámetros (g y p) y por la operación que se realiza con ellos (A = ga mod p) y (B = gb mod p), podemos ver que se está calculando el secreto compartido (shared = Ab mod p) del algoritmo de intercambio de claves ‘Diffie-Hellman’. Sin embargo, en este caso, en lugar de usarse para intercambiar claves, se ha usado para realizar una operación XOR sobre el texto en plano de la flag ‘enc = bytes([x ^ (shared % 256) for x in flag])‘.

Si vemos ahora el archivo message.txt

cat message.txt

Veremos que tenemos ‘g’, ‘p’, ‘A’ y ‘b’. En este caso, no deberíamos de tener ‘b’, dado que es el secreto privado del cliente (usado como potencia en el algoritmo).

Con esto, dado que XOR es una operación reversible si se hace con la misma clave y tenemos todo lo necesario para generar la clave usada para cifrar la flag, podemos generar un archivo llamado decryption.py para deshacer paso a paso lo generado por este algoritmo:

data = {}

#Primero, abrimos el archivo message.txt para obtener todos los datos proporcionados en el CTF
with open("message.txt") as f:
    for line in f:
        key, value = line.strip().split(" = ", 1)
        data[key] = value.replace(" ", "")

p = int(data["p"])
A = int(data["A"])
b = int(data["b"])

#El texto cifrado lo tenemos que transformar de hexadecimal antes de trabajar con él
#Original: enc = bytes([x ^ (shared % 256) for x in flag])
enc = bytes.fromhex(data["enc"])

#Calculamos el secreto
shared = pow(A, b, p)

#Obtenemos la clave
key = shared % 256

#Deshacemos el XOR que se ha realizado con la clave
flag = bytes(c ^ key for c in enc)

print(flag.decode())

Al ejecutar este código obtendremos la flag.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *