Skip to content

Baby-rev


Description

Write Up : Gwendal
Créateur : 4rm44n
Difficulté : Facile
Points : 100
Format du flag : BITSCTF{password}

Enoncé

anita max wyinn
Pièce(s) jointe(s): - N/A


Solution détaillée

Reconnaissance

On commence ici par utiliser l'utilitaire file afin d'avoir une première vue sur notre binaire :

$ file baby-rev 
baby-rev: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=995dafe783aef67cc95910e4f3c2a0152eeb34c0, for GNU/Linux 3.2.0, not stripped

En exécutant le programme, on se rend compte qu'on nous demande d'entrer une chaîne de caractères, on va alors ouvrir ghidra pour vérifier s'il est facilement posssible pour nous d'identifier le moment où on doit saisir cette chaîne :

  printf("Enter a string: ");
  fgets(userInput,32,stdin);
  sVar1 = strlen(userInput);
  if (sVar1 == 24) {
    myfunc(userInput);
  }
  else {
    puts(":P\n");

On remarque alors directement que si on entre une chaîne de caractères qui est de 24 caractères, la fonction "myfunc()" prenant notre input est appelée. Il nous faut alors analyser cette fonction qui sans doute gère la comparaison de notre input avec la chaîne attendue :

void myfunc(char *inputStr)
{
  if (*inputStr == 'B') {
    if (((((((inputStr[4] == 'C') && (inputStr[13] == 'm')) && (inputStr[19] == 'r')) &&
          (((inputStr[3] == 'S' && (inputStr[10] == 'l')) &&
           ((inputStr[2] == 'T' && ((inputStr[14] == 'e' && (inputStr[17] == '0')))))))) &&
         ((inputStr[22] == '}' &&
          (((inputStr[7] == '{' && (inputStr[5] == 'T')) && (inputStr[15] == '_')))))) &&
        (((inputStr[1] == 'I' && (inputStr[21] == 'v')) &&
         (((inputStr[8] == 'w' && ((inputStr[11] == 'c' && (inputStr[6] == 'F')))) &&
          (inputStr[20] == '3')))))) &&
       ((((inputStr[9] == '3' && (inputStr[12] == '0')) && (inputStr[16] == 't')) &&
        (inputStr[18] == '_')))) {
      puts("Yippee :3\n");
    }
  }
  else {
    puts(":PP\n");
  }
  return;
}

Exploitation

Pour ce qui est de l'exploitation, c'est assez simple. à partir de là il est clair que c'est la fonction qui gère la comparaison des chaînes et qu'il faut alors la reverse afin de trouver le mot de passe qui nous mènera au flag.

Pour cela, on peut soit déduire le mot de passe manuellement, car c'est lisible facilement grâce aux index de inputStr, soit rédiger un petit script python. Dans les deux cas, c'est très simple de reconstruire le mot de passe permettant d'obtenir notre flag.

Flag: BITSCTF{w3lc...v}