Assignment Chef icon Assignment Chef
All English tutorials

Programming lesson

Stack and Heap Exploitation: Building Exploit Primitives for Arbitrary Code Execution

Learn how to exploit stack-based and heap-based vulnerabilities in binary exploitation, building primitives toward arbitrary code execution. This tutorial covers return-oriented programming, use-after-free, double-free, and bypassing modern mitigations like ASLR and NX, with timely examples from gam

stack exploitation heap exploitation arbitrary code execution return-oriented programming use-after-free double-free binary exploitation tutorial pwntools CTF exploitation ASLR bypass NX bypass Intel HEX parser vulnerability buffer overflow exploit ROP chain example heap feng shui exploit primitives

Introduction to Binary Exploitation

Binary exploitation is a core skill in cybersecurity, especially for capture-the-flag (CTF) competitions and real-world vulnerability research. In this tutorial, we explore stack-based and heap-based exploitation techniques, focusing on building exploit primitives that lead to arbitrary code execution. We'll draw analogies from popular trends like the Elden Ring game's difficulty scaling or AI model fine-tuning — each step builds on the previous one, unlocking new capabilities.

Understanding the Intel HEX Parser Vulnerability

The assignment involves a binary that parses Intel HEX format files. Intel HEX is a text-based format for representing binary data, commonly used in microcontroller programming. A vulnerability in the parser — such as a buffer overflow in handling record lengths — can be exploited for stack-based attacks. Think of it like a viral AI chatbot that crashes when given a specially crafted prompt: the input triggers unexpected behavior.

Stack-Based Exploitation: Subproblem 1

The first objective is to crash the program reliably. By sending a malformed HEX record with an oversized data field, we overflow a local buffer on the stack. This overwrites the saved return address. Using pwntools, we can send a pattern to identify the offset. Once we control EIP/RIP, we can redirect execution to a function that prints a flag or spawns a shell. This is analogous to a speedrun in a game — knowing exactly where to jump to skip levels.

from pwn import *

p = remote('localhost', 1337)
payload = b'A' * 64 + p32(0x08048444)  # address of win function
p.sendline(payload)
p.interactive()

Return-Oriented Programming (ROP) for Arbitrary Code Execution

Modern binaries have NX (non-executable stack) enabled, so we cannot jump to shellcode on the stack. Instead, we use ROP — chaining small snippets of existing code (gadgets) to call system functions. This is like assembling a custom AI model from pre-trained components: each gadget does one small job. For example, we can find a gadget that sets EAX to 0x0b (execve syscall number) and another that calls int 0x80.

rop = ROP(binary)
rop.call('system', [next(binary.search(b'/bin/sh'))])
payload = b'A' * offset + rop.chain()

Heap Exploitation: Use-After-Free and Double-Free

Heap vulnerabilities are more complex. The assignment includes two binaries with similar functionality but different mitigations (e.g., tcache or glibc 2.27 vs 2.31). A use-after-free (UAF) occurs when we free a chunk but still hold a pointer to it. By allocating a new chunk that overlaps the freed one, we can corrupt metadata. This is like a finance app that reuses memory without clearing sensitive data — a classic bug.

Building Primitives: Arbitrary Write

From UAF, we can achieve an arbitrary write primitive. For example, by controlling the freed chunk's fd pointer, we can make malloc return a pointer to a target location (like __free_hook). Then overwriting __free_hook with the address of system allows us to execute commands when free is called. This step-by-step approach mirrors leveling up in a battle royale game — each primitive unlocks the next.

# Assuming tcache poisoning
payload = p64(target_addr)
p.sendlineafter('>', '1')  # allocate chunk A
p.sendlineafter('>', '2')  # free chunk A
p.sendlineafter('>', '1')  # allocate chunk B with payload
p.sendlineafter('>', '2')  # free triggers system

Bypassing Mitigations: ASLR and Tcache Double-Free

ASLR randomizes addresses, but we can leak a libc address via UAF (e.g., read freed chunk's fd if it points to unsorted bin). Then we calculate libc base. For double-free, we need to avoid glibc's checks. In tcache, double-free is easy before glibc 2.29; after that, we use a house of spirit technique. This is akin to AI model jailbreaking — finding the loophole in the defense.

Connecting to Current Trends

In 2026, binary exploitation skills are highly sought after in automotive security (exploiting ECUs) and cloud gaming (escaping sandboxes). The techniques you learn here — stack pivoting, heap feng shui — are used in real-world exploits. Even AI safety research borrows concepts from exploitation: adversarial inputs cause models to misbehave, similar to buffer overflows.

Conclusion

Mastering stack and heap exploitation requires practice. Start with simple buffer overflows, then progress to ROP and heap attacks. Use tools like pwntools, gdb, and one_gadget. Remember: each subproblem in the assignment is a stepping stone. By building primitives methodically, you'll achieve arbitrary code execution. Good luck!