Write-up Sha25 - Jour 2

Pour le jour 2 du SHA25, du reverse-engineering.
Ici, pas question de score a améliorer, il faut être le premier à comprendre comment marche cette fonction, afin de trouver le mot de passe du jour

_Sujet du jour 2

Pour commencer, j’ai regardé la fonction qui vérifie si le code rentré correspond à l’attendu, toute la boucle au dessus permettant simplement d’encoder l’input.
ipt correspondant à notre input, grâce au bout de code suivant, nous savons que le mot de passe doit contenir 33 caractères.

len(ipt) == 11*len(str(1.))

En effet len(str(1.)) est égal à 3 et 3x11 = 33.
Avant même d’essayer de comprendre tout le mécanisme de chiffrage, je décide de modifier légèrement cette fonction pour qu’elle m’affiche le résultat de sum(mem). _Premiers tests
Après quelques essais, j’ai d’abord pensé qu’il fallait des lettres de fortes valeurs, ce qui a été démonté par mon dernier test rempli de “y”.
Je me suis donc dit que le résultat devait simplement diminuer en fonction des lettres saisies.

J’ai donc effectué quelques modification, afin de m’afficher le contenu de la variable mem. Il s’agissait d’un tableau, de taille 30000, dont seuls les 33 premiers slots ne sont pas égaux à 0. Ils sont égaux à la liste suivante pour 33 “a”

55, 55, 55, 251, 243, 248, 0, 239, 31, 65, 252, 239, 242, 244, 65, 252, 244, 242, 238, 65, 239, 242, 251, 65, 232, 253, 0, 252, 239, 65, 237, 252, 26

et à celle-ci pour 33 “b”

56, 56, 56, 252, 244, 249, 1, 240, 32, 66, 253, 240, 243, 245, 66, 253, 245, 243, 239, 66, 240, 243, 252, 66, 233, 254, 1, 253, 240, 66, 238, 253, 27

A partir de là, le résultat était pour moi assez clair, chaque valeur de mem était plus ou moins élevé en fonction de la distance entre le caractère rentré et le caractère attendu en valeur ascii. Avec seulement 255 caractères dans la table ascii, on peut imaginer que si on devait atteindre 256 on aurait en réalité le 0 recherché.
J’ai donc pris le partie de créer un petit programme qui me calculerait le caractère attendu pour chaque position, avant de m’afficher la chaine entière en alphanumérique.

a_array = [55, 55, 55, 251, 243, 248, 0, 239, 31, 65, 252, 239, 242, 244, 65, 252, 244, 242, 238, 65, 239, 242, 251, 65, 232, 253, 0, 252, 239, 65, 237, 252, 26]
res = []

for c in a_array:
	if 97 - c > 0:
		res.append(chr(97-c))
	else:
		res.append(chr(256-c+97))
print(''.join(res)) 

Ici, si 97 (la valeur ascii de a) - la valeur de la liste est supérieur à 0, j’ajoute simplement mon résultat. Sinon je calcule la distance entre 256 (le retour à 0) et ma valeur dans la liste, que j’ajoute à 97. Cela me rempli res des valeurs ascii de chaque caractères, que j’affiche ensuite.
Le résultat de cette fonction m’affiche

***fniarB erom emos rof ydaer teG

Problème étant que ce résultat … Ne valide pas la fonction de base.
C’est en jetant un oeil au if final que je me suis rendu compte qu’il y avait un petit ipt[::-1] qui trainaît. Petite modification à mon code pour afficher la chaîne à l’envers :

print(''.join(res)[::-1])

Get ready for some more Brainf***
le flag est trouvé, l’exercice du jour validé et ma 14ème place, sécurisée !

Ce jour-ci, j’aurais pu faire un bien meilleur temps. Je m’y suis pris tard et la complexité de la fonction principale, que je n’ai au final même pas eu à décortiquer, m’ayant effrayée, je n’ai pas du tout pris le problème dans le bon sens et j’ai passé beaucoup trop de temps à essayer de suivre les transformations de mem. Ce n’est qu’ensuite que j’ai eu l’idée de départ de ce write-up, afficher le résultat final avec un input bidon et que tout s’est débloqué

Written on May 8, 2020