Get a Pentest and security assessment of your IT network.

Cyber Security

Fix C Buffer Overflow

TL;DR

Buffer overflows happen when a program tries to write more data into a memory area than it’s allowed. This can cause crashes or even let attackers take control of your system. We’ll show you how to find and fix these in C code, focusing on safe string handling.

Understanding Buffer Overflows

Imagine you have a box that can hold 10 apples. A buffer overflow is like trying to stuff 15 apples into that box – some will spill out (or overwrite other things!). In C, this often happens with strings and arrays.

How to Find Buffer Overflows

  1. Code Review: Carefully look at any code that copies data into a fixed-size buffer. Pay special attention to functions like strcpy, strcat, sprintf, and gets (avoid gets entirely!).
  2. Static Analysis Tools: Use tools like Coverity, PVS-Studio, or clang Static Analyzer. These can automatically detect potential buffer overflows in your code.
    clang -static-analyzer --analyze source_file.c
  3. Dynamic Testing (Fuzzing): Feed the program with lots of different inputs, including very long strings, to see if it crashes or behaves unexpectedly. Tools like AFL can help automate this.
    afl-fuzz -i input_dir -o output_dir ./your_program
  4. Debugging: Run the program in a debugger (like GDB) and step through the code to see where the overflow occurs. Watch the memory around your buffers.
    gdb ./your_program; break function_name; run

Fixing Buffer Overflows

  1. Use Safe String Functions: Replace unsafe functions with their safer counterparts:
    • Instead of strcpy(dest, src), use strncpy(dest, src, sizeof(dest) - 1); dest[sizeof(dest) - 1] = '';. The -1 is crucial to leave space for the null terminator.
    • Instead of strcat(dest, src), use strncat(dest, src, sizeof(dest) - strlen(dest) - 1);. Again, account for the null terminator.
    • Instead of sprintf(dest, format, ...), use snprintf(dest, sizeof(dest), format, ...);. This is generally preferred over vsprintf as well.
    • Never use gets(). Use fgets(dest, sizeof(dest), stdin) instead.
  2. Check Input Lengths: Before copying data, make sure the input string is not longer than the buffer can hold.
    if (strlen(src) >= sizeof(dest)) {
      // Handle error - e.g., truncate, reject input, or allocate more memory
    } else {
      strcpy(dest, src);
    }
  3. Allocate Enough Memory: If you need to store a string of unknown length, dynamically allocate enough memory using malloc(). Remember to free() the allocated memory when you’re finished with it.
    char *dest = malloc(strlen(src) + 1); // +1 for null terminator
    if (dest == NULL) {
      // Handle allocation error
    }
    strcpy(dest, src);
    free(dest);
    
  4. Stack Canaries: Compilers often provide stack canaries to detect buffer overflows. Make sure your compiler is using them (usually enabled by default with optimization).
  5. Address Space Layout Randomization (ASLR): ASLR makes it harder for attackers to predict the location of important data in memory.

Example Fix

Let’s say you have this vulnerable code:

#include <stdio.h>
#include <string.h>

int main() {
  char buffer[10];
  char input[20];

  printf("Enter some text: ");
  scanf("%s", input); // Vulnerable - no bounds checking!
  strcpy(buffer, input); // Vulnerable - can overflow buffer
  printf("You entered: %sn", buffer);
  return 0;
}

Here’s a fixed version:

#include <stdio.h>
#include <string.h>

int main() {
  char buffer[10];
  char input[20];

  printf("Enter some text: ");
  fgets(input, sizeof(input), stdin); // Safer - limits input length

  // Remove trailing newline if present
  size_t len = strlen(input);
  if (len > 0 && input[len-1] == 'n') {
    input[len-1] = '';
  }

  if (strlen(input) >= sizeof(buffer)) {
    printf("Input too long!n");
    return 1;
  } else {
    strcpy(buffer, input); // Now safe because of length check
    printf("You entered: %sn", buffer);
  }
  return 0;
}

Important Considerations

  • Always validate user input.
  • Be aware of the limitations of string functions.
  • Use a compiler with security features enabled.
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