Overthewire.org - Behemoth 0 -> 1

Today we're going to attack another reverse engineering challenge, this time from the Behemoth series.

This wargame deals with a lot of regular vulnerabilities found commonly 'out in the wild'. While the game makes no attempts at emulating a real environment it will teach you how to exploit several of the most common coding mistakes including buffer overflows, race conditions and privilege escalation.

Sounds fun, so let's jump straight into the unknown!


This time, we are given only a binary file, so no more viewing the source code.

[email protected]:~$ cd /behemoth/
[email protected]:/behemoth$ ./behemoth0
Password: password
Access denied..

We have to somehow get the password which may result in spawning a shell. Our best friend - gdb can help us with getting some better information about how we should approach this challenge.

[email protected]:/behemoth$ gdb ./behemoth0
(gdb) disas main

This code looks really interesting. Most of the functions are known from C, but what is memfrob?

Dump of assembler code for function main:
0x080485a2 <+0>: push %ebp
0x080485a3 <+1>: mov %esp,%ebp
0x080485a5 <+3>: and $0xfffffff0,%esp
0x080485a8 <+6>: sub $0x70,%esp
0x080485ab <+9>: mov %gs:0x14,%eax
0x080485b1 <+15>: mov %eax,0x6c(%esp)
0x080485b5 <+19>: xor %eax,%eax
0x080485b7 <+21>: movl $0x475e4b4f,0x1f(%esp)
0x080485bf <+29>: movl $0x45425953,0x23(%esp)
0x080485c7 <+37>: movl $0x595e58,0x27(%esp)
0x080485cf <+45>: movl $0x8048720,0x10(%esp)
0x080485d7 <+53>: movl $0x8048738,0x14(%esp)
0x080485df <+61>: movl $0x804874d,0x18(%esp)
0x080485e7 <+69>: movl $0x8048761,(%esp)
0x080485ee <+76>: call 0x8048400 <printf@plt>
0x080485f3 <+81>: lea 0x2b(%esp),%eax
0x080485f7 <+85>: mov %eax,0x4(%esp)
0x080485fb <+89>: movl $0x804876c,(%esp)
0x08048602 <+96>: call 0x8048470 <__isoc99_scanf@plt>
0x08048607 <+101>: lea 0x1f(%esp),%eax
0x0804860b <+105>: mov %eax,(%esp)
0x0804860e <+108>: call 0x8048440 <strlen@plt>
0x08048613 <+113>: mov %eax,0x4(%esp)
0x08048617 <+117>: lea 0x1f(%esp),%eax
0x0804861b <+121>: mov %eax,(%esp)
0x0804861e <+124>: call 0x804857d <memfrob>
0x08048623 <+129>: lea 0x1f(%esp),%eax
0x08048627 <+133>: mov %eax,0x4(%esp)
0x0804862b <+137>: lea 0x2b(%esp),%eax
0x0804862f <+141>: mov %eax,(%esp)
0x08048632 <+144>: call 0x80483f0 <strcmp@plt>
0x08048637 <+149>: test %eax,%eax
0x08048639 <+151>: jne 0x8048665 <main+195>
0x0804863b <+153>: movl $0x8048771,(%esp)
0x08048642 <+160>: call 0x8048420 <puts@plt>
0x08048647 <+165>: movl $0x0,0x8(%esp)
---Type <return> to continue, or q <return> to quit---
0x0804864f <+173>: movl $0x8048782,0x4(%esp)
0x08048657 <+181>: movl $0x8048785,(%esp)
0x0804865e <+188>: call 0x8048460 <execl@plt>
0x08048663 <+193>: jmp 0x8048671 <main+207>
0x08048665 <+195>: movl $0x804878d,(%esp)
0x0804866c <+202>: call 0x8048420 <puts@plt>
0x08048671 <+207>: mov $0x0,%eax
0x08048676 <+212>: mov 0x6c(%esp),%edx
0x0804867a <+216>: xor %gs:0x14,%edx
0x08048681 <+223>: je 0x8048688 <main+230>
0x08048683 <+225>: call 0x8048410 <__stack_chk_fail@plt>
0x08048688 <+230>: leave
0x08048689 <+231>: ret
End of assembler dump.

Let's take a look at the man pages description.

The memfrob() function encrypts the first n bytes of the memory area s by exclusive-ORing each character with the number 42. The effect can be reversed by using memfrob() on the encrypted memory area.

Note that this function is not a proper encryption routine as the XOR constant is fixed, and is suitable only for hiding strings.

That looks like a good thing to exploit, but I have another idea. Firstly, we will have to set a breakpoint at the strcmp function.

(gdb) break *0x08048632
Breakpoint 1 at 0x8048632
(gdb) run
Starting program: /games/behemoth/behemoth0
Password: AAAAAAA

Breakpoint 1, 0x08048632 in main ()

Now let's take a look at the 0x0804862f address. This line copies the value from %eax to the location in memory that %esp points to. Maybe we can view what %eax is storing inside?

(gdb) x/s $eax
0xffffd67b: "AAAAAAA"

Wow, that's the password we have entered just seconds ago! So maybe %esp will be our desired password?

(gdb) x/s $esp
0xffffd650: "{\326\377\377o\326\377\377p\326\377\377\322\202\004\b \207\004\b8\207\004\bM\207\004\bFw\353eatmyshorts"

This string at the end looks quite suspicious, maybe we should check that?

[email protected]:/behemoth$ ./behemoth0
Password: eatmyshorts
Access granted..
$ cat /etc/behemoth_pass/behemoth1

It was the password!


I'm definitely going to continue Behemoth wargame, as from the beginning challenges are really fun and intriguing. Thanks OverTheWire!

Keep learning and stay safe! ~ W3ndige