Level 8

The internet is a dangerous place.

Solution

Here we go. We have some encoded structure. Let's take first row:

0000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00

This is definitive a hex. So we have:

like in any file if we open it with hex editor.

But what file type this is?

The first bytes 45 4c 46 stands for ELF(Executable and Linkable Format). So this is a binary.

Let's convert it back with any online hex editor.

  1. We need to remove * areas and fill them with 0
  2. Now we don't need addresses any more.
    Remove them with /^\d{7} $/ expression. result.
  3. Paste it into the editor.
  4. Save as > Any place on your computer.

Now we have the binary.

Now we can run it. But the closer you get the more dangerous things will be.

Let's figure out what this code does. I used hooper ( alt: cutter ) disassembler.
The result of decompilation is shown below.

int main() {
  stack[-8] = r12;
  stack[-16] = rbp;
  stack[-24] = rbx;
  rbx = 0x0;
  rsp = rsp - 0xaa8;
  var_908 = rep intrinsic_movsd(var_908, *0x400b40);
  var_6F4 = rep intrinsic_movsd(var_6F4, *0x400d80);
  do {
    rdi = *(int32_t *)(rsp + rbx + 0x3b4);
    rdi = rdi ^ *(int32_t *)(rsp + rbx + 0x1a0);
    rbx = rbx + 0x4;
    putchar(rdi);
  } while (rbx != 0x214);
  putchar(0x20);
  getline(&var_AA8, &var_AA0, *stdin@@GLIBC_2.2.5);
  if (strcmp(0x400b04, var_AA8) != 0x0) {
    puts("You selected no. Quitting.");
  }
  else {
    var_A98 = rep intrinsic_movsd(var_A98, *0x400fc0);
    rbx = 0x0;
    var_9D0 = rep intrinsic_movsd(var_9D0, *0x4010c0);
    rbp = malloc(0x32);
    do {
      rdi = rbp + rbx;
      rbx = rbx + 0x1;
      sprintf(rdi, 0x400b22);
    } while (rbx != 0x32);
    rbx = 0xa;
    rbp = system(rbp);
    printf("Deleting all files...");
    fflush(*stdout@@GLIBC_2.2.5);
    do {
      sleep(0x1);
      putchar(0x2e);
      fflush(*stdout@@GLIBC_2.2.5);
      rbx = rbx - 0x1;
    } while (rbx != 0x0);
    rbx = 0x64;
    do {
      usleep(0x4e20);
      putchar(0x2e);
      fflush(*stdout@@GLIBC_2.2.5);
      rbx = rbx - 0x1;
    } while (rbx != 0x0);
    COND = rbp == 0x0;
    rbx = &var_4E0;
    rbp = &var_27C;
    if (!COND) {
      *(int32_t *)rbx = rep intrinsic_movsd(*(int32_t *)rbx, *0x4011c0);
      r12 = 0x0;
      *(int32_t *)rbp = rep intrinsic_movsd(*(int32_t *)rbp, *0x4013c0);
      do {
        rdi = *(int32_t *)(rbp + r12);
        rdi = rdi ^ *(int32_t *)(rbx + r12);
        r12 = r12 + 0x4;
        putchar(rdi);
      } while (r12 != 0x1d4);
    }
    else {
      *(int32_t *)rbx = rep intrinsic_movsd(*(int32_t *)rbx, *0x4015c0);
      r12 = 0x0;
      *(int32_t *)rbp = rep intrinsic_movsd(*(int32_t *)rbp, *0x401840);
      do {
        rdi = *(int32_t *)(rbp + r12);
        rdi = rdi ^ *(int32_t *)(rbx + r12);
        r12 = r12 + 0x4;
        putchar(rdi);
      } while (r12 != 0x264);
    }
  }
  return 0x0;
}
In the code we see:
if (!COND) {
  ....
}
else {
  ....
}

So else can never been executed. We also see that the programm will try to delete all our files:

....
rbp = system(rbp);
printf("Deleting all files...");
fflush(*stdout@@GLIBC_2.2.5);
....

So let's run it on the empty virtual server. I had one, so I used it:

The anwser is read this point in the code:

getline(&var_AA8, &var_AA0, *stdin@@GLIBC_2.2.5);

And will exit if we choose no

if (strcmp(0x400b04, var_AA8) != 0x0) {
  puts("You selected no. Quitting.");
}

If we choose yes we still have unexecuted fragment:

else {
  *(int32_t *)rbx = rep intrinsic_movsd(*(int32_t *)rbx, *0x4015c0);
  r12 = 0x0;
  *(int32_t *)rbp = rep intrinsic_movsd(*(int32_t *)rbp, *0x401840);
  do {
    rdi = *(int32_t *)(rbp + r12);
    rdi = rdi ^ *(int32_t *)(rbx + r12);
    r12 = r12 + 0x4;
    putchar(rdi);
  } while (r12 != 0x264);
}

So we need to change the binary. I decided to change the condition in if so we will always jump to the else section of the code.

With help of hooper I found where the if locates and changed it.
So if will be coded as je (jump if equal) assembler command.
This cheatsheet says it will be coded as 0x74.
We need to change it to unconditional jump - jmp (jump directly to).
According to the cheatsheet - it will be BE.
So here is diff:

142c142
< 00 00 EB 3B BE C0 11 40 00 B9 75 00 00 00 48 89
---
> 00 00 74 3B BE C0 11 40 00 B9 75 00 00 00 48 89

If you are interested: modified hex, modified binary.

The anwser is printed in the console - /whalespotting-of-a-different-kind

Let's run it again and see what hides inside the code:

Well, since we are inside a container, we skipped the deletion. 🙂 Docker FTW!
To solve this level, go to '/inside-the-docker-matrix'. See you there!

Fuck. So we just need to execute it inside the docker. Ok. Cool.

If you interested how they check if the code is inside the docker, there are minimum two ways:

So our result url will be:
http://18.198.170.188:80/inside-the-docker-matrix

If we go to this url we will see
congratulations page whith the link to the Level 9 ( task / solution )

Back