UP | HOME

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

Author: rick

Email: rick@gnous.eu

Created: 2025-05-11 dim. 23:24

Validate