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:
0000000 - adress7f ... 00 - valuelike 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.
* areas and fill them with 0/^\d{7} $/ expression.
result.
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:
.dockerenv file/proc/1/cgroup. / for all hierarchies. /docker/<containerid>.
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
)