[Hackvens 2024][Write Up – Reverse] Armazing
![[Hackvens 2024][Write Up – Reverse] Armazing](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1754312027145%2F07531fef-0200-4e0f-be70-4a23b940c7e2.jpeg&w=3840&q=75)
Reconnaissance
Le binaire « armazing » qui est fourni est un exécutable linux aarch64.

L’objectif est de trouver le mot de passe pour déchiffrer le flag.

La fonction main
(1) La première partie demande un mot de passe en premier argument et vérifie que sa longueur est de taille 32.
(2) Ensuite, une fonction est appelée sur les caractères deux à deux, et une vérification est faite par rapport à un bloc de données en mémoire (DAT_00412100).
(3) Enfin, si toutes les conditions sont remplies (les 16 valid_checks), le flag est déchiffré depuis un bloc de données en mémoire (DAT_00412140), puis est affiché.
Penchons nous sur la fonction check:

La fonction check
La variable globale counter est incrémentée à chaque passage de boucle.
Une variable locale (carry) est calculée avec des opérations de xor, shift et de et.
La valeur de retour (carry) dépend d’une valeur calculée par la fonction FUN_00400ab8.
Enfin, dans FUN_00400ab8:

La fonction FUN_00400ab8
On remarque qu’à la première itération, counter vaut 1, et comme sa valeur est remise à 0 à la fin de la fonction, sa valeur sera toujours de 1 au moment de la condition.
La valeur est donc constante, et dépend du bloc de données DAT_00412058.
La vulnérabilité
Comme les tests de vérification sont effectués sur deux bytes par deux bytes, il est possible de bruteforce les 256*256 possibilités sur les 32 checks.
Le script de solution
to_compare = b'''\x1aV\xdd\xed\xd6\xbb\xf8\xc0[\\3k\xd64\x89-RE\x96\x1e\xa7,\xb2"\x05\xcc\xd1\x1d;\x0b\xbc>\x8c\x04\xb1\xa7\x02\x0b\xc0\xa83r+\xec<p\x0es}\xdb\xe9\x01\xab\xaa\xf5\xe4\x945p\x9eV\xa2\x12'''
to_compare = [int.from_bytes(to_compare[4*i:4*(i+1)],'little') for i in range(len(to_compare)//4)]
datas = b'''\xd4\xc3\xb2\xa1\x8c}n_-\x1c\x0b\x9akZO>xV4\x12\xef\xcd\xab\x90\x09\xba\xdc\xfe\xe0\xach$\xdf\x9bW\x13\xdd\xcc\xbb\xaaD3"\x11\x88wfU\xcc\xbb\xaa\x99\xcc\xdd\xee\xffUD3"\x99\x88wf\xef\xbe\xad\xde\xb5\x00k\xb1\xbe\xba\xfe\xca\x0d\xf0\xad\x8b\xde\xc0\xad\x0b\x01\xef\xcd\xab\x07;\x1d\xac\x80p`PM<+\x1a\x8bzo^.\x1d\x0c\x9bl]N?:\x1d\xad\xab\x90xV42Tv\x984\x12\xdc\xfe\xab\x89gE#\x01\xef\xcd\xef\xcd\xab\x89gE#\x01\xef\xcd\xab\x89xV4\x12\x102Tv\x98\xba\xdc\xfe\xad\xfb\xca\xde\xfe\xca\xef\xbe\x1aV\xdd\xed\xd6\xbb\xf8\xc0[\\3k\xd64\x89-RE\x96\x1e\xa7 ,\xb2"\x05\xcc\xd1\x1d;\x0b\xbc>\x8c\x04\xb1\xa7\x02\x0b\xc0\xa83r+\xec<p\x0es}\xdb\xe9\x01\xab\xaa\xf5\xe4\x945p\x9eV\xa2\x12'''
datas = [int.from_bytes(datas[4*i:4*(i+1)],'little') for i in range(len(datas)//4)]
def FUN_00400ab8():
return datas[1+0xf]^datas[(1+10)*2] ^ datas[0x1a+2] ^ 0x34a51bf2
def calc_next(x):
carry = 0xffffffff
val = FUN_00400ab8()
for i in x:
carry ^= i
for j in range(7, -1, -1):
carry = (carry >> 1) ^ (val & -(carry&1))
return (-carry-1)% 0x100000000
res = b''
for p in to_compare:
for i in range(256):
for j in range(256):
z = calc_next(bytes([i,j]))
if(z == p):
res += bytes([i, j])
print(res)
Ce qui nous donne la valeur ‘7$FqR#5wdx!LnPz8&mT9Uj@3XkH^Vo2r’.Lorsqu’on le met en argument du programme, on obtient alors le flag:

Le flag
Le flag
HACKVENS{CrC32_1nt0_rC4_@aRch64}






