Hack This Newsletter: Stack-Based Buffer Overflows
Let's explore the very basics of pwn: stack-based buffer overflows.
Welcome to Hack This Newsletter, where we learn to break stuff!
I wanted to write about something basic as my first post. We’re gonna be talking about stack-based buffer overflows! Although old news, stack-based buffer overflows are a staple of binary exploitation and serve as a great foundation.
I’m writing a brief explanation of what a buffer overflow is and how it can be exploited, some other learning resources, and finally, some challenges to test your knowledge.
Prerequisites
GDB
x86 Assembly
What is a Buffer Overflow?
A buffer overflow is simply when too much data is placed in a buffer of a fixed size.
You can think of a buffer as an array: a consecutive series of memory addresses that can be individually addressed. They’re used for many things; thus, there are many kinds of buffers.
We’ll be focusing on stack-based buffers. These buffers exist on the stack, where you’d find other essential control data like variables, return addresses, base pointers, etc.
Consider the following program:
#include <stdio.h>
#include <string.h>
int main() {
char buf[10]
strcpy(buf, "This is a buffer");
printf("%s", buf);
}
When the buffer buf
is declared above, it exists on the stack and will cease to exist when the function finishes.
If you run this program after compiling it with no special flags, this is the happy text that will greet you:
*** stack smashing detected ***: terminated
The stack smashing detected error is a pretty metal way of saying you’re writing on the stack where you shouldn’t be. Simply put, our buffer was 10 characters long, and we tried to put 17 characters in it (16 + a null character to denote the end of the string). It’s a buffer ovERFLOW!!11!
How can we Break Things Even More?
The example I just used is pretty dull. That’s because we can’t really control how that buffer is overflown.
Imagine some code that would overflow a buffer with user-controlled data. Instead of overflowing a buffer with useless data, we can replace and change certain things on the stack.
With stack-based buffer overflows, we can change local variables and pointers, return addresses, and base pointers. Let’s break down some of these attacks:
Changing local variables: Since local variables and pointers scoped to the current function are on the stack, you’ll be able to change them! Sometimes this can lead to other vulnerabilities but generally not that useful compared to the other attacks.
Changing return addresses: This is the primary goal of exploiting most bugs. Changing a return address allows you to force the program to jump to some mapped address. You can use this to jump to libc, build a ROP chain, or execute shellcode.
Changing base pointers: You can perform a stack-pivot if you manage to construct a “fake” stack somewhere else in memory. When the function returns, the saved base pointer is used to return the stack to its previous address.
Today there are mitigations in place for detecting and preventing the exploitation of buffer overflows, including stack canaries, NX, ASLR, and PIE. When you need to, you can look these up yourself. Remember, learning to find and learn new things is part of being a hacker (trust me, I promise I’m not just being lazy ;).
Resources for Learning
Here’s a list of resources for learning how to both trigger and exploit buffer overflows:
Another general description of buffer overflows from Cloudflare
The legendary phrack article from Aleph One: Smashing the Stack for Fun and Profit
Excellent Hands-on walk-through of Stack-based buffer overflows by Rapid7
Liveoverflow’s video on placing and executing shellcode on the stack via a buffer overflow
The Art of Exploitation has lots of material on exploiting simple buffer overflows
Challenges
Difficulty: 1/10
A straightforward challenge. A great introduction to buffer overflows and how they can affect stack memory.
Difficulty: 2/10
Another easy challenge modifying a stack variable, though some reversing or GDB-foo is required.
picoCTF: Cutter-overflow (Search it up on picoCTF) Video Writeup
Difficulty: 2/10
An easy and playful challenge that requires minor reversing. Also, an active picoGym challenge.
Difficulty: 2/10
A step up from changing stack variables to changing return addresses.
Difficulty: 3/10
A challenge that involves placing shellcode on the stack and jumping to it.
Don’t forget to subscribe if you haven’t already, happy hacking!