Skip to content

Services, Wiki-Artikel, Blog-Beiträge und Glossar-Einträge durchsuchen

↑↓NavigierenEnterÖffnenESCSchließen
Schwachstellenklassen Glossary

Buffer Overflow - Pufferüberlauf

A buffer overflow occurs when a program writes more data to a buffer than it can hold, causing adjacent memory areas to be overwritten. Buffer overflows enable stack-based overflows (overwriting the return address → arbitrary code), heap-based overflows, and format string attacks. Protection mechanisms: ASLR, stack canaries, NX bit/DEP, PIE, Fortify Source. Buffer overflows are one of the oldest classes of vulnerabilities and form the basis of many exploits.

Buffer overflows are over 40 years old—and still relevant today. The Morris Worm (1988) exploited a stack overflow in fingerd. OpenSSL Heartbleed (2014) was a heap buffer over-read. Log4Shell was facilitated by a buffer overflow in Java deserialization. C/C++ code without modern protection mechanisms remains vulnerable: embedded systems, network equipment, SCADA/OT systems, browser engines. A buffer overflow in the right place enables remote code execution with system privileges.

Stack-Based Buffer Overflow

Memory layout (x86, simplified) – the stack grows from high to low address:

[high address]
| Function arguments     |
| Return Address (RET)   |  ← Return address - critical!
| Saved Base Pointer     |
| Local variables       |  ← Buffer is located here
| ...                    |
[low address]

Normal function call (vulnerable C code):

void vulnerable(char *input) {
    char buffer[64];       // 64-byte stack buffer
    strcpy(buffer, input); // UNSAFE: no length check!
}

If input > 64 bytes: buffer overflows, overwriting Saved EBP and the return address.

Exploit flow (classic)

# Total payload:
python3 -c "import sys; sys.stdout.buffer.write(
    b'A' * 64 +         # Fill buffer
    b'B' * 4 +          # Overwrite Saved EBP
    b'\xef\xbe\xad\xde' +  # Return Address (little endian!)
    b'\x90' * 20 +      # NOP sled
    shellcode           # Actual shellcode
)" | ./vulnerable_program

Unsafe C Functions (always avoid)

FunctionProblem
gets()no length check, always unsafe
strcpy()no length check
strcat()no length check
sprintf()when format string is abused
scanf()%s without length specification

Safe Alternatives:

fgets(buffer, sizeof(buffer), stdin)  // with length check!
strncpy(dest, src, sizeof(dest)-1)    // with length check
strlcpy(dest, src, sizeof(dest))      // BSD extension
snprintf(buf, sizeof(buf), ...)       // safe

Protection Mechanisms

1. Stack Canaries

  • Compiler inserts a random value before the return address
  • Upon returning from a function: Check the value
  • If altered: Terminate the program
  • GCC: -fstack-protector-all
# Check if Canary is active:
checksec --file=./program
# Output: STACK CANARY: Enabled

Workaround: Format string → Stack leak → Read canary value → Insert into overflow → Passes check.

2. ASLR (Address Space Layout Randomization)

  • Operating system: Stack/heap/libraries different at every startup
  • Attacker does not know target address → Exploit more difficult
# Linux - Check status:
cat /proc/sys/kernel/randomize_va_space
# 0 = disabled, 2 = fully enabled

# Enable:
echo 2 > /proc/sys/kernel/randomize_va_space

Workarounds:

  • Information leak: Read program address via another bug
  • Brute force (32-bit: only 16-bit entropy → 65,536 attempts)
  • ret2libc: libc always at a predictable location (without PIE)

3. NX Bit / DEP (No-Execute / Data Execution Prevention)

  • Memory pages: either writable OR executable (not both!)
  • Shellcode on stack → not executable
  • Hardware: CPU NX bit (Intel XD, AMD NX)
  • OS: W^X (Write XOR Execute)
checksec --file=./program
# NX: Enabled

Workaround: Return-Oriented Programming (ROP) – uses existing code fragments (gadgets) in legitimate libraries without injecting custom code.

4. PIE (Position-Independent Executable)

  • Program loads itself at a random address (not just libraries)
  • Enhances ASLR: all addresses are unknown
  • GCC: -fPIE -pie

5. Fortify Source

  • Compile-time + runtime: buffer size known → check
  • GCC: -D_FORTIFY_SOURCE=2
  • Replaces strcpy__strcpy_chk (with size check!)

6. Control Flow Integrity (CFI)

  • Validates allowed jump targets
  • Return address must point to a known return location
  • Clang CFI, Microsoft Control Flow Guard (CFG)
  • Complicates ROP chains

> Stack Canaries + ASLR + NX + PIE + CFI together make exploit development very difficult (but not impossible!) - typically, multiple bugs are required: Info leak + Buffer overflow + CFI bypass.

Modern Variants

Heap-Based Buffer Overflow

Heap memory is dynamically allocated (malloc/new) – there is no return address on the heap, so other attack vectors are required.

Targets on the heap:

  • Heap metadata (free list, chunk headers) → tcache poisoning
  • Function pointers on the heap → overwrite → code execution
  • C++ vtable pointer → overwrite → call any method
// Example (Use-After-Free + Heap Overflow):
char *buf = malloc(16);    // 16 bytes allocated
read(0, buf, 256);         // Writes 256 bytes → Heap Overflow!
// → Overwrites neighboring chunk header

Format string vulnerability

printf(user_input);           // WRONG: user_input as format string!
printf("%s", user_input);     // CORRECT: fixed format

Attack:

  • user_input = "%x.%x.%x.%x" → reads stack values (Leak!)
  • user_input = "%n" → writes to memory (Code Execution!)
  • Attacker: reads canary value, addresses → ASLR bypass → classic buffer overflow with known addresses

Integer Overflow → Buffer Overflow

uint8_t size = user_provided_size;  // 0-255
size = size * 2;                    // Overflow! 200*2=400 → 400%256=144!
char *buf = malloc(size);           // Buffer too small!
memcpy(buf, src, user_provided_size * 2);  // Overflow!

Detection and Prevention

Static Analysis

flawfinder ./src/         # C/C++ vulnerability scanner
cppcheck --enable=all ./  # C++ static analysis
# CodeQL: github.com/github/codeql-action (CI/CD integration)

Dynamic Analysis

# AddressSanitizer (ASan):
# Compile with: -fsanitize=address → Detect heap/stack overflows

valgrind --tool=memcheck ./program  # Detect memory errors

# American Fuzzy Lop (AFL):
afl-fuzz -i inputs/ -o findings/ ./program

Compiler Flags Best Practices

CFLAGS="-Wall -Wextra -Werror \
        -fstack-protector-all \
        -D_FORTIFY_SOURCE=2 \
        -fPIE -pie \
        -Wl,-z,relro,-z,now \
        -fsanitize=address,undefined"
FlagEffect
-Wall -Wextra -WerrorTreat all warnings as errors
-fstack-protector-allStack Canaries
-D_FORTIFY_SOURCE=2Fortify
-fPIE -piePIE
-Wl,-z,relro,-z,nowRELRO
-fsanitize=address,undefinedASan + UBSan