Bébé nageur

Grégoire Frémion · May 12, 2024

Résolution

Il s’agit d’un chiffrement affine, on est donc face à un problème du type c(x) = ax+b [n], où a et b sont les clés de notre chiffre. On peut effectuer un brute-force sur a et b (les valeurs possibles étant très restreintes). L’autre façon de faire est de récupérer a et b en faisant une attaque à clair connu. En effet, le format du flag est 404CTF{ ... }. De plus, on a la correspondance entre les caractères et leur représentation numérique. En prennant les deux premiers caractères du flag, on a un système du type :

ax1 + b = y1 et ax2 + b = y2

Qui est équivalent à

a = (y2 - y1) * (x2 - x1) ^(-1) [n]
b = y1 - ax1 [n] 

On en déduit a et b, on déchiffre ensuite avec la fonction : f(y) = a^(-1)*(y-b) [n]

Solution implémentée en python3 :

# 404CTF 2024
# Challenge : Bébé nageur, intro
# Authors : acmo0 & Little_endi4ne

encrypted = "-4-c57T5fUq9UdO0lOqiMqS4Hy0lqM4ekq-0vqwiNoqzUq5O9tyYoUq2_"
charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789{}_-!"
n = len(charset)

y1 = charset.index(encrypted[0])
y2 = charset.index(encrypted[1])

x1 = charset.index("4")
x2 = charset.index("0")

# a*x1 + b = y1
# a*x2 + b = y2
# <=>
# a*x1 + b = y1
# a = (y2 - y1)*(x2 - x1)^(-1)

a = ((y2 - y1)%n)*pow((x2-x1)%n,-1,n)%n
b = (y1 - a*x1)%n

def f_inv(x,a,b,n):
	return ((x-b)%n)*pow(a,-1,n)%n

def decrypt(message,a,b,n):
	decrypted = ""
	for char in message:
		x = charset.index(char)
		x = f_inv(x,a,b,n)
		decrypted += charset[x]
	return decrypted
print(decrypt(encrypted,a,b,n))

# Dumb solution


for a in range(2,n-1):
	for b in range(1,n-1):
		d = decrypt(encrypted,a,b,n)
		if "404CTF" in d:
			print(d)

Twitter, Facebook