Rev0x02

Flag: StarHack{G00d_J0B_78e8ezrzr9}

Challenge

file-archive
4KB
circle-info

Description


Il faut un clé de licence pour activer le programme!

nc 35.180.44.229 1234

circle-exclamation

Solution

Commençons par la décompilation de la fonction main, voici le pseudo code sortie par Ghidra avec quelques modifications :

int main() {
  char *licence;
  bool check1_success;
  unsigned int n1;
  unsigned int n2;
  unsigned int n3;
  unsigned int n4;
  unsigned int sum;
  unsigned int licence_part;
  bool check2_success;
  bool check3_success;
  
  licence = (char *)malloc(0x18);
  printf("Bonjour Bonjour reverseur.\n Bienvenue dans m...");
  scanf("%s",licence);
  
  check1_success = check1(licence);
  if (check1_success == 0) {
    puts("Vous essayez d\'utiliser mon programme gratuitement. Allez acheter une licence.");
  } else {
    licence_part = cut(licence,0x4);
    n1 = licence_part;
    licence_part = cut(licence + 0x5,0x4);
    n2 = licence_part;
    licence_part = cut(licence + 0xa,0x4);
    n3 = licence_part;
    licence_part = cut(licence + 0xf,0x4);
    n4 = licence_part;
    licence_part = cut(licence + 0x14,0x4);
    sum = checksum(n1,n2,n3,n4);
    if (licence_part == sum) {
      check2_success = check2(n1,n2,n3,n4);
      if (check2_success == 0) {
        puts("Vous essayez d\'utiliser mon programme gratuitement. Allez acheter une licence.");
      } else {
        check3_success = check3(n1 << 0x10 | n2, licence_part * 0xc0de, n3 << 0x10 | n4);
        if (check3_success == 0) {
          puts("Vous essayez d\'utiliser mon programme gratuitement. Allez acheter une licence.");
        } else {
          puts("Bon travail, mais je pense qu'il n'y a rien...");
          win();
        }
      }
    } else {
      puts("Vous essayez d\'utiliser mon programme gratuitement. Allez acheter une licence.");
    }
  }
  return 0x0;
}

L'objectif est de passer les 3 fonctions check. Commençons par la première :

Check1

Elle vérifie que notre licence à le format XXXX-XXXX-XXXX-XXXX-XXXX où les X sont un caractère dans [0-9A-F] (hexa en majuscule).

Checksum

Ensuite, notre licence est découpée en fonction des blocs qu'elle forme, puis l'hexa décimal est interprété en tant que nombre, on a donc 5 entiers. Par exemple si notre licence est DEAD-BEAF-C0FE-BABE-1337, cela correspond à [57005, 48815, 49406, 47806, 4919].

Les 4 premiers nombres servent à calculer le 5ᵉ. C'est la fonction checksum qui permet cela.

Check3

On passe directement au 3ᵉ check pour s'éviter des problèmes. Elle prend trois paramètres notés p1, p2 et p3 et qui sont calculés comme suit :

Résolution avec z3

Maintenant que l'on connaît les conditions, on va créer des contraintes pour réduire le nombre de licences possibles, puis les tester une à une. Pour ça, on utilise z3.

  • n1 jusqu'à n5 représente nos blocs

  • p1, p2 et p3 sont les paramètres passés à check3

Unintended way

La clé 0000-0000-0000-0000-0000 fonctionnait.

Mis à jour