Cover Image

CAF 2023 - Babyrev


Dans cet article, nous allons explorer le déroulement pas à pas (walkthrough) du challenge Reverse ‘BabyRev’ proposé lors du CTF Cyber Africa Forum 2023.

Nous avons à notre disposition le binaire suivant qui est téléchargeable ici.

Utilisons notre outil préféré IDA Free pour décompiler le binaire. Ici ce que je vais faire, c’est de me faciliter le travail en utilisant la feature Generate PseudoCode de IDA.

Dans la fonction main() nous avons le code suivant:

__int64 __fastcall main(int a1, char **a2, char **a3)
{
  char v4[58]; // [rsp+6h] [rbp-42Ah] BYREF
  char v5[1000]; // [rsp+40h] [rbp-3F0h] BYREF
  unsigned __int64 v6; // [rsp+428h] [rbp-8h]

  v6 = __readfsqword(0x28u);
  strcpy(&v4[10], "lQsgGDW4k+uOMRezzlftzfou4uT>^bAbmsPEe");
  strcpy(v4, "xorcaf123");
  sub_1189(&v4[10], v4, v5);
  printf("Ciphertext: %s\n", v5);
  return 0LL;
}

Ce pseudocode C est un programme qui chiffre un texte en utilisant une clé et affiche le texte chiffré. Il y a deux tableaux de caractères, v4 et v5. Le tableau v4 contient la clé de chiffrement et le texte à chiffrer. Ensuite, le programme appelle la fonction sub_1189() pour chiffrer le texte en utilisant la clé. Le texte chiffré est stocké dans le tableau v5. Finalement, le programme affiche le texte chiffré à l’écran.

Allons voir ce que fait la fonction sub_1189():

_BYTE *__fastcall sub_1189(const char *a1, const char *a2, __int64 a3)
{
  _BYTE *result; // rax
  int i; // [rsp+24h] [rbp-Ch]
  int v6; // [rsp+28h] [rbp-8h]
  int v7; // [rsp+2Ch] [rbp-4h]

  v6 = strlen(a1);
  v7 = strlen(a2);
  for ( i = 0; i < v6; ++i )
    *(_BYTE *)(i + a3) = a1[i] ^ a2[i % v7];
  result = (_BYTE *)(i + a3);
  *result = 0;
  return result;
}

La fonction sub_1189() prend en entrée trois arguments : const char *a1 (le texte à chiffrer), const char *a2 (la clé de chiffrement) et __int64 a3 (l’adresse du tableau où stocker le texte chiffré). Cette fonction effectue un chiffrement XOR simple en combinant les caractères du texte à chiffrer avec les caractères de la clé.

Pour les pythonistes d’entre vous, voici l’équivalent en python:

def sub_1189(a1, a2):
    v6 = len(a1)
    v7 = len(a2)
    result = []

    for i in range(v6):
        xor_result = ord(a1[i]) ^ ord(a2[i % v7])
        result.append(chr(xor_result))

    return ''.join(result)

key = "xorcaf123"
ciphertext = "lQsgGDW4k+uOMRezzlftzfou4uT>^bAbmsPEe"
plaintext = sub_1189(ciphertext, key)
print("Plaintext:", plaintext)

Ce qui est intrigant ici c’est que le ciphertext n’est même pas xoré, donc il s’agit d’un autre encodage ou chiffrement.

Je fais un tour sur Cyberchef:

J’utilise l’option “Magic”, et puis le texte était déjà déchiffré, il s’agissait tout simplement de base85.

Donc le flag est CAF_{x0r_1s_n0t_much_c0mpl3x}