Ipzz281 Full _top_ ★
Title: IPZZ‑281 Full
4. Exploitation Strategy
The binary has the following mitigations:
| Mitigation | Status | |------------|--------| | NX (non‑executable stack) | Enabled | | PIE | Disabled (binary has a fixed base address) | | Full RELRO | Enabled (GOT entries are read‑only) | | Canary | Not present (no stack canary)** |
Because NX is present we cannot inject shellcode onto the stack. Instead we will perform a Return‑Oriented Programming (ROP) attack using gadgets found inside the binary and libc. ipzz281 full
The goal is to call system("/bin/cat flag.txt"). Two options:
- Reuse the existing
systemcall – afterchecksucceeds the binary already callssystem. If we can forcecheckto return 1 without providing the correct secret phrase, we get the flag automatically. - Build our own ROP chain that invokes
systemwith the required argument and then exits cleanly.
The easier route is Option 2, because we can simply overflow the return address to point to a ROP chain that does:
pop rdi ; ret ; load address of "/bin/cat flag.txt"
<addr_of_string>
system ; call libc's system
exit ; clean termination
2. Environment & Setup
| Item | Value |
|------|-------|
| OS | Ubuntu 20.04 (64‑bit) |
| Architecture | x86‑64 |
| Toolchain | gcc 9.3.0, gdb 9.2, pwndbg, radare2, objdump, readelf |
| libc | glibc 2.31 (the version shipped with Ubuntu 20.04) |
| Exploit language | Python 3 (pwntools) |
| Debugger | gdb with pwndbg / gef | Title: IPZZ‑281 Full
The binary is provided as ipzz281. It is not PIE‑enabled, but has full RELRO and a non‑executable stack.
$ file ipzz281
ipzz281: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, \
interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=..., \
stripped
Note: Even though the file reports “stripped”, the challenge name “full” tells us that a debug build (with symbols) is also supplied. In the write‑up we will use the version with symbols because it makes the analysis clearer.
Write‑up – “ipzz281 full”
Challenge type: Binary exploitation / Reverse‑Engineering
Points: 350 (typical mid‑range CTF)
Difficulty: Medium–Hard
Author: (original author of the challenge)
Category tags:pwn,x86‑64,ASLR,RELRO,PIE,ROP,libcReuse the existing system call – after check
3.2. check function
int check(const char *s)
const char *magic = "ipzz281";
if (strncmp(s, magic, 8) != 0) return 0;
/* more checks … */
if (strcmp(s+8, "full") == 0) return 1;
return 0;
-
The function simply validates the string format. The flag itself is not hidden in the binary; it is printed by
system("/bin/cat flag.txt")after the check succeeds. -
Because the
readoverflow is before the call tocheck, we cannot bypass the check directly – we must either:- Supply a correct phrase (
ipzz281full) – but the flag is unknown, and the challenge expects exploitation, or - Take control of execution after
checkreturns 1, and force the program to callsystemourselves (or any other code that reveals the flag).
- Supply a correct phrase (