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

Challenge Information

  • Category: Pwn
  • Difficulty: Intro / Easy
  • Protections: PIE Disabled, NX, Canary, Partial RELRO, IBT/SHSTK

Analysis

Program Behavior

  1. Prints message about "most powerful write primitive"
  2. Asks for address: Address to be written:
  3. Asks for value: Value:
  4. Writes value to addressArbitrary write!
  5. Calls exit(0)

Key Points

Arbitrary Write Primitive

long *address;
long value;
scanf("%lx", &address);  // Read address (hex format!)
scanf("%lx", address);   // Write value to *address

Note: Uses %lx (hex), not %ld (decimal)!

Win Function

Function win is at address 0x401216:

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

Partial RELRO

  • GOT (Global Offset Table) is writable → can overwrite GOT entry

No PIE

Fixed addresses:

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

Attack Strategy

GOT Overwrite:

  1. Write win address into exit@GOT entry
  2. When program calls exit(), it jumps to win() instead of exiting
  3. win() spawns shell
  4. Get flag using cat flag.txt

Why choose exit@GOT?

  • exit() is called at the end of program (after primitive is granted)
  • Other functions (printf, scanf, ...) are resolved before, no need to interfere
  • exit() is the ideal target as it is called after the write step

Implementation

Payload (Ideal)

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

Important Notes

  • scanf("%lx", ...) → send hex string!
  • No 0x prefix needed when sending (already uses %lx)
  • IBT enabled → can only jump to addresses with endbr64 (however internal function call win might not be blocked by IBT if branched directly, or win starts with endbr64)

Exploit Steps

  1. Connect to service
  2. Send address exit@GOT (e.g. send 404038) as hex
  3. Send value win (e.g. send 401216) as hex
  4. Program writes win to exit@GOT
  5. When program calls exit() → executes win() → shell spawned
  6. Send cat flag.txt to read flag

Flag

BPCTF{potential_target_when_you_have_write_primitive_200616be4e4236ecdec118a6098755c8}

Key Takeaways

About GOT (Global Offset Table)

  • GOT stores addresses of dynamic library functions (dynamic symbols)

Partial RELRO

  • With Partial RELRO, GOT can still be overwritten (unlike Full RELRO)

About Arbitrary Write

  • Ability to write any value to any address is an extremely powerful primitive

Specific Lessons

  1. When you have arbitrary write, GOT is a top target if program uses Partial RELRO.
  2. Choose target function that will be called after you have the primitive.
  3. Always check input format (e.g. %lx vs %ld) — a small difference can change exploitation.
  4. Combining No PIE + Partial RELRO often makes GOT overwrite very simple.
250
Points
Medium
Difficulty
Binary Exploitation
Category