Get a Pentest and security assessment of your IT network.

Cyber Security

Fixing Bufferoverflows

TL;DR

A buffer overflow happens when a program tries to write more data into a memory area than it’s allowed. This can overwrite important information, potentially letting attackers take control of your system. We’ll focus on fixing overflows where the return address is overwritten.

Understanding the Problem

Imagine you have a box that can hold 10 apples. If someone tries to put 15 apples in it, some will spill over and mess up things around the box. In computers, this ‘box’ is a memory buffer, and the ‘apples’ are data. The ‘spilling over’ overwrites other parts of your program’s memory.

Fixing Bufferoverflows: Step-by-Step

  1. Identify Vulnerable Code: Look for places where user input is copied into a fixed-size buffer without checking its length. Common functions include strcpy, strcat, and gets. These are often the culprits.
    • Example vulnerable code (C):
    • char buffer[16];
      strcpy(buffer, userInput); // No bounds checking!
  2. Use Safe Alternatives: Replace unsafe functions with their safer counterparts. These alternatives limit the amount of data copied.
    • strncpy: Copies a maximum number of characters. Always null-terminate manually if strncpy doesn’t add one.
      char buffer[16];
      sncpy(buffer, userInput, sizeof(buffer) - 1); // Copy at most 15 chars
      buffer[sizeof(buffer) - 1] = ''; // Ensure null termination
    • strncat: Appends a maximum number of characters to a string.
      char buffer[32];
      strncat(buffer, userInput, sizeof(buffer) - strlen(buffer) - 1); // Append safely
    • fgets: Reads input from a stream with a maximum length.
      char buffer[32];
      fgets(buffer, sizeof(buffer), stdin); // Read up to 31 chars from standard input
  3. Input Validation: Check the length of user input *before* copying it. This is a crucial defense.
    • Example (C):
    • char buffer[16];
      if (strlen(userInput) < sizeof(buffer)) {
        strcpy(buffer, userInput);
      } else {
        // Handle the error - print a message, truncate input, etc.
        printf("Input too long!n");
      }
      
  4. Stack Canaries: Compilers can insert ‘canary’ values onto the stack before the return address. If an overflow overwrites the canary, the program detects it and terminates.
    • Enable this feature during compilation (e.g., with GCC use -fstack-protector).
      gcc -fstack-protector your_program.c -o your_program
  5. Address Space Layout Randomization (ASLR): Randomizes the memory addresses of key program components, making it harder for attackers to predict where to jump.
    • Most modern operating systems enable ASLR by default. Ensure it’s active on your system.
  6. Data Execution Prevention (DEP) / No-Execute (NX): Marks certain memory regions as non-executable, preventing attackers from running malicious code injected into the buffer.
    • Most modern operating systems enable DEP/NX by default. Ensure it’s active on your system.

Testing Your Fix

After applying these fixes, thoroughly test your code with various inputs, including very long strings, to ensure the overflow is prevented and the program behaves as expected.

Related posts
Cyber Security

Zip Codes & PII: Are They Personal Data?

Cyber Security

Zero-Day Vulnerabilities: User Defence Guide

Cyber Security

Zero Knowledge Voting with Trusted Server

Cyber Security

ZeroNet: 51% Attack Risks & Mitigation