# [Hackvens 2024][Write Up – Reverse] Armazing

## **Reconnaissance**

Le binaire « armazing » qui est fourni est un exécutable linux aarch64.

![](https://cdn.prod.website-files.com/66b4f677818acbec83587b15/67507c472ebdd25526d2070d_armazing1.png align="left")

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

![La fonction main](https://cdn.prod.website-files.com/66b4f677818acbec83587b15/67507c560c1016c7d9b3427a_armazing2.png align="center")

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](https://cdn.prod.website-files.com/66b4f677818acbec83587b15/67507c846a663d2fe2f74c18_armazing3.png align="center")

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](https://cdn.prod.website-files.com/66b4f677818acbec83587b15/67507c94d241829c0a47c733_armazing4.png align="center")

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**

```javascript
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:

![](https://cdn.prod.website-files.com/66b4f677818acbec83587b15/67507cba6313e82126ae0b77_armazing5.png align="left")

*Le flag*

## **Le flag**

HACKVENS{CrC32\_1nt0\_rC4\_@aRch64}
