Bombs landed

Can you find the password?  
Enter the password as flag in the following form: HTB{passwordhere}

==> For this challenge we get a single executable file:

file BombsLanded 
BombsLanded: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.32, BuildID[sha1]=53d6c985990fd9b8ed4f1caf10ce7d64e14b2121, dynamically linked, interpreter /lib/ld-linux.so.2, no section header

we see that the strings command returns very little information just like executing the file:

./BombsLanded 
Bad luck dude.

so we can go on and fire up ghidra –> we get the following mainfunction:


/* WARNING: Function: __i686.get_pc_thunk.bx replaced with injection: get_pc_thunk_bx */
/* WARNING: Globals starting with '_' overlap smaller symbols at the same address */

undefined4 main(int param_1)

{
  int iVar1;
  undefined4 *__s;
  uint uVar2;
  undefined4 *puVar3;
  undefined4 *puVar4;
  byte bVar5;
  uint local_24;
  
  bVar5 = 0;
  _DAT_10091348 = &__DT_PLTGOT;
  _DAT_1009134c = _DAT_1009134c + 1;
  _DAT_10091338 = _DAT_10091338 + -1;
  _DAT_1009133c = _DAT_1009133c + 1;
  _DAT_10091340 = _DAT_10091340 + -1;
  if ((_DAT_1009134c <= _DAT_1009133c) && (4 < param_1)) {
    __s = (undefined4 *)mmap((void *)0x0,0x1000,7,0x22,-1,0);
    memset(__s,0xc3,0x1000);
    *__s = _DAT_100911a0;
    *(undefined4 *)((int)__s + 0x193) = _DAT_10091333;
    iVar1 = (int)__s - (int)(undefined4 *)((uint)(__s + 1) & 0xfffffffc);
    puVar3 = (undefined4 *)(&DAT_100911a0 + -iVar1);
    puVar4 = (undefined4 *)((uint)(__s + 1) & 0xfffffffc);
    for (uVar2 = iVar1 + 0x197U >> 2; uVar2 != 0; uVar2 = uVar2 - 1) {
      *puVar4 = *puVar3;
      puVar3 = puVar3 + (uint)bVar5 * -2 + 1;
      puVar4 = puVar4 + (uint)bVar5 * -2 + 1;
    }
    for (local_24 = 0; local_24 < 0x197; local_24 = local_24 + 1) {
      *(byte *)((int)__s + local_24) = *(byte *)((int)__s + local_24) ^ 99;
    }
    (*(code *)__s)();
    memset(__s,0,0x197);
                    /* WARNING: Subroutine does not return */
    exit(0);
  }
  if (3 < param_1) {
    printf((char *)0x10090c70);
    iVar1 = getchar();
    if ((char)iVar1 == 'X') {
      (*(code *)0xc3)();
      __isoc99_scanf(0x10090c81);
    }
  }
  puts((char *)0x10090c93);
  return 0;
}

and we see that a whole lot is happening in terms of obfuscation. From the last few lines

  if (3 < param_1) {
    printf((char *)0x10090c70);
    iVar1 = getchar();
    if ((char)iVar1 == 'X') {
      (*(code *)0xc3)();
      __isoc99_scanf(0x10090c81);
    }
  }
  puts((char *)0x10090c93);

we can assume that this is the part that is asking us for the password while the last line is the one printing Bad luck dude.. However, this part never seems to get executed and this is probably linked to the param_1variable.

==> To handle the standard input, run it using:

gnome-terminal -- edb --run ./BombsLanded

==> We can then open the file in edb to trace the execution –> we can go to the mainaddress and we can get it from Ghidra and use:

CTRL + G --> Goto expression: 0x08048937
Add a breakpoint using F2
Run until the breakpoint at main

we can now get the address of the comparison from ghidra:

if ((_DAT_1009134c <= _DAT_1009133c) && (4 < param_1)) {

and it is: 0x080489ba –> next go to this expression and add a breakpoints there before running the code again. We then see that the conditions aren’t met as a red arrow indicates that it wants to jump over the next instruction:

image

we can then change the value of the Z flagand now it turns black and stepping into the next step we actually get to the next instruction

==> We can now do the same for the next comparison:

if ((_DAT_1009134c <= _DAT_1009133c) && (4 < param_1)) {

and it is located at address: 0x080489bf–> we can then add a breakpoint and run the program until then –> we then see again a very big jump that is this time gray and that we want red –> we can change the value of the S flagto 1 and it works. Now stepping once more we make the jump!

==> We then have the following 2 commands :

__s = (undefined4 *)mmap((void *)0x0,0x1000,7,0x22,-1,0);
memset(__s,0xc3,0x1000)

which will allocate 1000 bytes of memory and fill them with c3addresses –> in ebp, we can see the mmapcommand, set a breakpoint and run there, same for the memsetcommand. Once at this address, we see on the stack the size allocated and the value:

image

we can then follow the address 0xf7f8a000in memory using:

Right click on it --> follow in memory dump
See only 0s in address
Step to the next function after memset
See all c3

==> We can then follow the execution of the second forloop as it is what interests us:

for (local_24 = 0; local_24 < 0x197; local_24 = local_24 + 1) {
  *(byte *)((int)__s + local_24) = *(byte *)((int)__s + local_24) ^ 99;
}

we can then take its address and go there in edb: 0x08048aae and set a breakpoint there and run the code!

After the first for loop, we have all of our previous memory dump filled with random values –> we see that then for every time in the loop values of the dump will change –> we can then add a breakpoint after the for loop. And after executing this, we see the following bytes in memory

and we see that the first one is 55which probably indicates a function. A bit below we see the call: call eaxand moving there we see that it is calling our address 0xf7f8a000

==> Since this is done dynamically, ghidracannot decompile this function –> we can then step intothe function and a bit further down we see another function that will be used for input password: 0xf7f8a0df–> going there, we can now input a password.

==> We can now finally check the strncmpfunction and especially this part:

while( true ) {
  sVar2 = strlen(__s2);
  if (sVar2 <= local_10) break;
  __s[local_10] = __s2[local_10] ^ 10;
  local_10 = local_10 + 1;
}

we can get its address: 08048b66 and go there using Edb–> now run the cycles and we see a string appearing in the stack:

and the password is: younevergoingtofindme

==> HTB{younevergoingtofindme}