unlockme
crackmes.one (pranav)
Le main de ce crackme ressemble à ça. Il a été légèrement modifié pour faciliter sa compréhension:
checker[0] = 9; checker[1] = 0x35; checker[2] = 0x23; checker[3] = 9; checker[4] = 0x3f; checker[5] = 0x25; checker[6] = 0x13; checker[7] = 0x22; checker[8] = 0x31; checker[9] = 0x33; checker[10] = 0x3b; checker[0xb] = 0x35; checker[0xc] = 0x34; checker[0xd] = 0x1d; checker[0xe] = 0x35; checker[0xf] = 0; flag = argv[1]; if (argc != 2) { printf("Input method: <appname> <password>"); return -2; } ret = str_len(flag); if (ret == 0x1d) { flag_00 = encrypt_flag(0x50,flag); bVar2 = check_flag(flag_00,(char *)checker); if (bVar2 == 0) { free(flag_00); goto LAB_0010089b; } copy_str((char *)(checker + 0x10),"You have done it"); free(flag_00); } else { LAB_0010089b: copy_str((char *)(checker + 0x10),"You have failed..."); }
On voit une suite de caractères entrée dans un tableau. L'argument
rentré (notre flag) est mis dans la variable flag
avant d'être
chiffré. Ce mot chiffré est ensuite comparé avec le tableau précédent.
Si on regarde la fonction de chiffrement, elle est extrêment
simple. Il s'agit d'un bête XOR avec un byte passé en paramètre. Il
s'agit du byte 0x50
. Il s'arrête au dernier caractère de la chaine,
le \00
, sans le chiffrer.
char * encrypt_flag(char param_1,char *flag) { char curr_char; char *dest; int i; char *tmp; dest = (char *)malloc(0x10); copy_str(dest,flag); curr_char = *dest; if (curr_char != '\0') { i = 0; tmp = dest; do { curr_char = curr_char ^ param_1; *tmp = curr_char; i = i + 1; tmp = dest + i; curr_char = *tmp; } while (curr_char != '\0'); } return dest; }
La fonction pour vérifier le flag est extrêment simple, elle vérifie juste si les caractères dans le tableau sont égaux aux nouveaux caractères "chiffrés" du flag.
bool check_flag(char *flag,char *checker) { int i; i = 0; while(true) { if (flag[i] == '\0') { return checker[i] == '\0'; } if (checker[i] != flag[i]) break; i = i + 1; } return false; }
Pour défaire un XOR, il suffit de le refaire à l'envers, on prend dans un tableau les caractères finaux, on prend le caractère utilisé pour les chiffrer et on opère.
buffer = '\x09\x35\x23\x09\x3f\x25\x13\x22\x31\x33\x3b\x35\x34\x1d\x35' byte = 0x50 flag = [] for i in buffer: flag += chr(ord(i) ^ byte) print("{}".format(''.join(flag)))