Binary Exploitation
Medium
250 points

GOT Intro

Recuite 2025 - HCMUS
6 tháng 10, 2025
GOT Overwrite
Arbitrary Write
Partial RELRO
Recuite 2025 - HCMUS
Binary Exploitation

GOT Intro - Writeup#

Thông tin Challenge#

  • Thể loại: Pwn
  • Độ khó: Intro / Easy
  • Protections: PIE Disabled, NX, Canary, Partial RELRO, IBT/SHSTK

Phân tích#

Hành vi chương trình#

  1. In thông báo nói về "most powerful write primitive"
  2. Hỏi địa chỉ: Address to be written:
  3. Hỏi giá trị: Value:
  4. Ghi giá trị vào địa chỉArbitrary write!
  5. Gọi exit(0)

Những điểm quan trọng#

Primitive ghi tuỳ ý (Arbitrary Write)#

c
long *address;
long value;
scanf("%lx", &address);  // Đọc address (định dạng hex!)
scanf("%lx", address);   // Ghi value vào *address

Chú ý: Dùng %lx (hex), không phải %ld (decimal)!

Hàm win#

Hàm win nằm ở địa chỉ 0x401216:

asm
win:
    ...
    lea rax, [rip+0xdd0]  # "/bin/sh"
    ...
    call execve            # execve("/bin/sh", ...)

Partial RELRO#

  • GOT (Global Offset Table) còn có thể ghi được → có thể overwrite GOT entry

No PIE#

Địa chỉ cố định:

  • win: 0x401216
  • exit@GOT: 0x404038

Chiến lược tấn công#

GOT Overwrite (ghi đè GOT):

  1. Ghi địa chỉ win vào entry exit@GOT
  2. Khi chương trình gọi exit(), sẽ nhảy tới win() thay vì rời chương trình
  3. win() spawn shell
  4. Lấy flag bằng cat flag.txt

Tại sao chọn exit@GOT?#

  • exit() được gọi ở cuối chương trình (sau khi primitive đã được cấp)
  • Các hàm khác (printf, scanf, ...) đã được resolve trước, không cần can thiệp
  • exit() là mục tiêu lý tưởng vì được gọi sau bước ghi

Triển khai#

Payload (ý tưởng)#

text
# Address to write: exit@GOT (0x404038)
# Value to write: win (0x401216)

Lưu ý quan trọng#

  • scanf("%lx", ...) → gửi chuỗi hex!
  • Không cần tiền tố 0x khi gửi (đã dùng %lx)
  • IBT enabled → chỉ có thể nhảy đến các địa chỉ chứa endbr64 (tuy nhiên gọi hàm nội bộ win không bị IBT cản)

Các bước exploit#

  1. Kết nối tới service
  2. Gửi địa chỉ exit@GOT (ví dụ gửi 404038) dưới dạng hex
  3. Gửi giá trị win (ví dụ gửi 401216) dưới dạng hex
  4. Chương trình sẽ ghi win vào exit@GOT
  5. Khi chương trình gọi exit() → sẽ thực thi win() → có shell
  6. Gửi cat flag.txt để đọc flag

Flag#

BPCTF{potential_target_when_you_have_write_primitive_200616be4e4236ecdec118a6098755c8}

Những bài học rút ra#

Về GOT (Global Offset Table)#

  • GOT lưu địa chỉ của các hàm thư viện động (dynamic symbols)

Partial RELRO#

  • Với Partial RELRO, GOT vẫn có thể bị ghi đè (không giống Full RELRO)

Về Arbitrary Write#

  • Khả năng ghi bất kỳ giá trị vào bất kỳ địa chỉ nào là primitive cực kỳ mạnh

Bài học cụ thể#

  1. Khi có arbitrary write, GOT là mục tiêu hàng đầu nếu chương trình dùng Partial RELRO.
  2. Chọn hàm mục tiêu là hàm sẽ được gọi sau khi bạn đã có primitive.
  3. Luôn kiểm tra định dạng input (ví dụ %lx vs %ld) — một sai khác nhỏ có thể làm thay đổi exploitation.
  4. Kết hợp No PIE + Partial RELRO thường làm cho overwrite GOT trở nên rất đơn giản.
250
Points
Medium
Difficulty
Binary Exploitation
Category