Posted on :: Tags: , , :: Difficulty:

Information and behavior

First we extract the file

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

Not stripped

After chmod +x baby_crypt, we execute the file and are presented with the problem:

smavl:/baby-crypt $ ./baby_crypt
Give me the key and I'll give you the flag: nono
Q
 [b')k
smavl:/baby-crypt $ ./baby_crypt
Give me the key and I'll give you the flag: fuck off
YVj=$c%babvpN'mN- iuf08

We notice that the depending on the input (nono and fuck off), the 'baby'-output varies.

We continue to investigate in ghidra.

Ghidra

The main function looks like this

undefined8 main(void)

{
  char *__s;
  long in_FS_OFFSET;
  int local_44;
  undefined8 local_38;
  undefined8 local_30;
  undefined8 local_28;
  undefined2 local_20;
  long local_10;
  
  local_10 = *(long *)(in_FS_OFFSET + 0x28);
  printf("Give me the key and I\'ll give you the flag: ");
  __s = (char *)malloc(4);
  fgets(__s,4,stdin);
  local_38 = 7999878687861597247;
  local_30 = 0x28130304026f0446;
  local_28 = 0x5000f4358280e52;
  local_20 = 0x4d56;
  local_44 = 0;
  while (local_44 < 0x1a) {
    *(byte *)((long)&local_38 + (long)local_44) =
         *(byte *)((long)&local_38 + (long)local_44) ^ __s[local_44 % 3];
    local_44 = local_44 + 1;
  }
  printf("%.26s\n",&local_38);
  if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return 0;
}

Due to my poor knowledge in C, i wasn't able to point the aparent logic to solve the problem.

However the local_xx = xxx didnt seem to exist without importance

The Great Oracle

After consulting a great oracle Hmm... i was enlightened

The fgets(_s,4,stdin) stdin means user imput 4 means the first 4 bytes of the line.

Loop

while (local_44 < 0x1a) {

loops 0x1a times

Array

In the loop the first 4 byte and such are getting done with the help of an array.

Xor

Hackernoon - Why XOR is imp....

The flag is XOR'ed through an array*

This is the reason why the the flag is becomming 'Baby-language'

However, due to the nature of XOR, we can work out the the key if we know some of the plaintext.

And we do. The first 4 bytes of the plaintext: HTB{

In that manner we can get the key, if we present the first 4 bytes of the plaintext as the key.

$ ./baby_crypt
Give me the key and I'll give you the flag: HTB{
w0wDM;L;@LWQ`L`

Effectively, we've manipulated the baby into giving out the key, which is w0wD:

Hence:

$ ./baby_crypt
Give me the key and I'll give you the flag: w0wDM
HTB{x0r_1s_us3d_by_h4x0r!}

Really cool box. Quite easy if you could grasp the C code and knew about the nature of XOR