/ crypto

breizhctf2k16 - Crypto or Not ?

Problem : SaxX doesn't listen to me and decides to create a new encryption algo .... prove him he's wrong by discovering what it hides!
Files :
cryptoTr0llOrN0t.py
out.enc

Ouvrons le fichier python :

enc = lambda FLAG: [oct(_) for _ in map(ord, "".join([chr(( (x & 0b10101010) ^ ord(y) ) % (2**8-1)) for x,y in enumerate(FLAG)]))]
print enc('SaxXounetPrendsDesCoursDeCryptoAvecMmeMichu')

Le programme est composé d'une unique fonction lambda écrite en oneline.Cette fonction à première vue semble effectuer plusieurs modifications sur le flag.

Regardons à quoi ressemble le résultat donné dans le fichier out.enc :

['0102', '0122', '0107', '0113', '0132', '0110', '0101', '0126', '0116', '0163', '0131', '071', '0155', '0145', '077', '0125', '0144', '064', '0166', '0135', '0123', '0141', '0172', '0132', '0127', '0140', '0153', '0174', '0155', '0146', '055', '0176', '0177', '0146', '0115', '0120', '0123', '0101', '0111', '0107', '0167', '0161', '031', '0136', '0167', '0175', '0115', '0115', '0114', '0131', '0175', '0162', '0131', '0124', '0112', '0115', '0106', '0167', '032', '0104', '033', '0144', '0103', '0104', '063', '0162', '043', '043', '041', '0175']

Déchiffrons la fonction lambda étape par étape :

for x,y in enumerate(FLAG)

Ici la fonction enumerate() renvoie l'index x et la lettre correspondante y pour chaque lettre du flag.

"".join([chr(( (x & 0b10101010) ^ ord(y) ) % (2**8-1)) ... ])

Pour chaque valeur de x et y récupérée précedemment
la fonction concatène les caractères correspondant au reste de la division par 2**8-1 de x "et logique" 10101010 xor valeur décimale de y.

[oct(_) for _ in map(ord, ...)]

Puis la fonction convertit tous les caractères récupérés précédemment en décimal puis en octal.

Maintenant que l'on connait la manière dont le flag a été encodé, écrivons un script qui réalise tout simplement l'inverse :

cipher = ['0102', '0122', '0107', '0113', '0132', '0110', '0101', '0126', '0116', '0163', '0131', '071', '0155', '0145', '077', '0125', '0144', '064', '0166', '0135', '0123', '0141', '0172', '0132', '0127', '0140', '0153', '0174', '0155', '0146', '055', '0176', '0177', '0146', '0115', '0120', '0123', '0101', '0111', '0107', '0167', '0161', '031', '0136', '0167', '0175', '0115', '0115', '0114', '0131', '0175', '0162', '0131', '0124', '0112', '0115', '0106', '0167', '032', '0104', '033', '0144', '0103', '0104', '063', '0162', '043', '043', '041', '0175']

temp1=[]
temp2=""
flag=""
for elem in cipher:
	temp1.append(int(elem,8)) #conversion octal -> décimal
for nb in temp1:
	temp2+=chr(nb)
for x,y in enumerate(temp2):
	flag+=chr((x & 0b10101010 ^ ord(y))%(2**8-1))

print flag
BREIZHCTF{S3em5_d4t_SaxX_haven't_Forsake_Y3t_Uggly_Python_0n3Lin3r!!!}