Overview Memory Layout Techniques Tools Demo Detection Prevention Legal Resources

Buffer Overflow Guide

What is a Buffer Overflow?

A buffer overflow (or buffer overrun) is a software vulnerability where a program writes more data to a fixed-size block of memory (buffer) than it can hold, causing excess data to overflow into adjacent memory locations. This memory corruption can lead to program crashes, data corruption, denial of service, or—most critically—arbitrary code execution (ACE). Buffer overflows are one of the oldest and most dangerous software vulnerabilities, responsible for major worms (Morris Worm 1988, Code Red 2001, SQL Slammer 2003) and zero-day exploits.

Historical Significance: The Morris Worm (1988) exploited a buffer overflow in the fingerd service (CVE-1999-0103), infecting ~6,000 systems (10% of internet at the time). Code Red (2001) exploited buffer overflow in Microsoft IIS (CVE-2001-0500), infecting 359,000+ systems in 14 hours. Buffer overflows remain a top memory corruption vulnerability despite modern mitigations (ASLR, DEP, stack canaries).

20+%
C/C++ Vulnerabilities (Buffer Overflow)
#1
Memory Corruption Type
1988
First Major Exploit (Morris Worm)

Common vulnerable functions in C/C++ (unsafe string/memory operations):

How Buffer Overflows Work (Stack Memory Layout)

// Stack memory layout (x86 architecture) ┌─────────────────────────────┐ High addresses │ Return Address │ ← EBP+4 (saved EIP) ├─────────────────────────────┤ │ Saved EBP (frame ptr) │ ← EBP ├─────────────────────────────┤ │ Local Variables (buffer) │ ← EBP-64 (buffer[64]) ├─────────────────────────────┤ │ Canary (stack guard) │ ← Optional (stack protector) └─────────────────────────────┘ Low addresses // Vulnerable C code example void vulnerable(char *user_input) { char buffer[64]; // Fixed-size buffer on stack strcpy(buffer, user_input); // No bounds checking - buffer overflow! } // Attacker input: "A" * 64 + "BBBB" + "CCCC" + shellcode // 64 bytes fill buffer, 4 bytes overwrite saved EBP, 4 bytes overwrite return address // Return address overwritten -> instruction pointer jumps to shellcode

Stack-Based Buffer Overflow

Overwrites local variables, saved return address (EIP/RIP), and stack frame pointer (EBP/RBP) on call stack. Most common type. Attacker overwrites return address to point to malicious shellcode. Control hijacked when function returns (ret instruction).

Most Common

Heap-Based Buffer Overflow

Overwrites memory allocated on heap (malloc, new). Harder to exploit due to unpredictable heap layout. Can overwrite function pointers, vtable pointers (C++), or adjacent heap metadata. Used in browser exploits (Heartbleed - heap overflow).

Heap Corruption

Integer Overflow Leading to Buffer Overflow

Integer overflow/underflow in size calculation (e.g., size+1 overflow to 0). Leads to insufficient buffer allocation. Example: (len + 1) where len = UINT_MAX → wraps to 0 → small buffer allocated.

Indirect Overflow

Off-by-One Buffer Overflow

Overwrites one byte beyond buffer boundary. Can corrupt adjacent memory (e.g., overwriting frame pointer LSB, function pointer). Limited but still dangerous.

Precision Overflow

Format String + Buffer Overflow

Combining format string vulnerability (%n writes number of bytes to arbitrary address) with buffer overflow for write-what-where capability.

Chained Exploit
// Stack-based buffer overflow exploitation (x86) // Vulnerable function void echo(char *input) { char buffer[64]; strcpy(buffer, input); // No bounds check! printf("You entered: %s\n", buffer); } // Attacker's payload (buffer overflow) // buffer[64] + saved EBP (4 bytes) + return address (4 bytes) + shellcode char payload[128]; memset(payload, 'A', 64); // Fill buffer *(uint32_t*)(payload+64) = 0x41414141; // Overwrite EBP (AAAA) *(uint32_t*)(payload+68) = shellcode_addr; // Overwrite return address strcpy(payload+72, shellcode); // Append shellcode (32 bytes) // When function returns, EIP = shellcode_addr → shellcode executes // Example shellcode (x86 Linux execve /bin/sh) char shellcode[] = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50" "\x53\x89\xe1\xb0\x0b\xcd\x80"; // 25 bytes // With modern mitigations (ASLR + DEP + stack canary) - harder but not impossible // ROP (Return-Oriented Programming) chains bypass NX/DEP

Buffer Overflow Exploitation Techniques

Return-to-libc (ret2libc)

Bypasses NX/DEP (Data Execution Prevention) by returning to existing libc functions (system(), execve()). Overwrites return address with address of system() and arranges arguments on stack. Calls system("/bin/sh") instead of shellcode.

Return-Oriented Programming (ROP)

Chains small instruction sequences (gadgets) ending in "ret" instruction from existing binaries (libc, executable). Bypasses NX/DEP, ASLR (with info leak), and stack canaries. Each gadget performs small operation (pop reg; ret).

Advanced

JOP (Jump-Oriented Programming)

Similar to ROP but uses indirect jumps (jmp reg) instead of returns. Bypasses ret-based detection (ROP defense).

Sigreturn-Oriented Programming (SROP)

Uses sigreturn syscall to restore registers from stack. Can bypass ASLR, NX, and stack canaries. Works on Linux with signal handler.

Buffer Overflow Tools & Debuggers (Educational Context)

GDB (GNU Debugger) + PEDA/gef

Linux debugger for analyzing memory corruption, buffer overflows, and developing exploits. PEDA/gef extensions add pattern generation (pattern_create), cyclic offsets, and exploit automation.

Immunity Debugger

Windows GUI debugger with mona.py plugin for buffer overflow exploitation. Features: pattern creation, exploit development, heap analysis, and ROP gadget search.

Metasploit (MSFpayload + Pattern_create)

Metasploit Framework includes pattern_create.rb, pattern_offset.rb for finding buffer overflow offsets. MSFpayload generates shellcode (windows/shell_reverse_tcp). MSFvenom for custom payloads.

Valgrind (Memcheck)

Memory debugging tool detecting buffer overflows, uninitialized memory, memory leaks (defensive). Used for identifying vulnerabilities in source code.

AddressSanitizer (ASan) - Clang/GCC

Compiler instrumentation detecting buffer overflows (stack, heap, global), use-after-free, and memory leaks. Defensive tool for developers.

Buffer Overflow Simulation (Stack Overflow)

This demonstration simulates a stack-based buffer overflow overwriting the return address to execute arbitrary code:

Click "Simulate Buffer Overflow" to see memory corruption and return address overwrite

This is a simulated demonstration for educational purposes. Real buffer overflows can overwrite return addresses to execute arbitrary shellcode (reverse shell, bind shell, privilege escalation). Modern mitigations (ASLR, DEP, stack canaries, CFG) make exploitation harder but not impossible.

Detecting Buffer Overflows

Compiler Defenses (Stack Canaries)

GCC/Clang -fstack-protector (Stack Guard) inserts canary value before return address. Canary corruption detected at function exit → program aborts, preventing exploit. Canary types: terminator canary, random canary, XOR canary.

AddressSanitizer (ASan) Runtime

ASan detects buffer overflows (heap, stack, global) at runtime with detailed reports (shadow memory, stack trace). Used in fuzzing and testing.

Fuzzing (AFL, libFuzzer)

Automated fuzzing generates malformed inputs to trigger buffer overflows (crashes). Fuzzers detect memory corruption (segmentation faults, heap corruption).

Preventing Buffer Overflows (Secure Coding)

Use Safe String Functions

Replace unsafe functions (strcpy, strcat, sprintf, gets) with safe alternatives: strncpy (with NUL termination), strncat, snprintf, fgets. Always specify buffer size.

Coding Practice

Compiler Protections (Stack Canary, ASLR, DEP)

Enable compiler protections: -fstack-protector-strong (Stack Canary), -fPIE + -pie (Position Independent Executable - ASLR), -z noexecstack (DEP/NX). Reduces exploit success rate.

Use Memory-Safe Languages (Rust, Go, Python, Java)

Memory-safe languages (Rust, Go, Python, Java, C#) have built-in bounds checking, preventing buffer overflows. Rust enforces memory safety at compile time (ownership model).

Static Analysis (Coverity, Clang Static Analyzer)

Static analysis tools detect unsafe string operations (strcpy, gets, sprintf) and potential buffer overflows before runtime.

Best Practice - Defense-in-Depth for Buffer Overflows: Use memory-safe languages (Rust, Go, Python, Java, C#) instead of C/C++ where possible. If C/C++ required: use safe string functions (strncpy, snprintf), enable compiler protections (-fstack-protector -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security), enable ASLR and DEP/NX at OS level, conduct regular fuzzing (AFL, libFuzzer), and use static analysis tools (Coverity, Clang Analyzer).

Further Buffer Overflow Resources & Information

Shellcoder's Handbook (Book)

Definitive buffer overflow exploitation guide: discovering vulnerabilities, crafting shellcode, bypassing mitigations (ASLR, DEP, stack canaries), and return-oriented programming (ROP).

Corelan Team (Buffer Overflow Tutorials)

Free Windows buffer overflow exploitation tutorials (Immunity Debugger, mona.py, pattern creation, SEH overwrites). Industry standard for exploit development training.

protostar (Exploit Education)

Free Linux buffer overflow challenges (stack0-stack7, heap0-heap3, format string). Learn memory corruption exploitation in controlled VM environment.

← Back to Knowledge Base