Exploit Lab - Simplified Buffer Overflow simulation

   Buffer Overflow - Simplified

A buffer overflow is a type of software vulnerability that happens when a program writes more data to a buffer (a temporary data storage area in memory, usually a variable) than it can hold.

A buffer is a fixed-size block of memory used to store data temporarily (like user input, strings, or files).

When a program doesn’t properly check the size of the input before copying it into the buffer, extra data can “overflow” into adjacent memory locations.

This overflow can corrupt data, crash the program.

This Software vulnerability can allow attackers to execute malicious code, after overflowing the buffer.

Example: 
Let’s say a program allocates a buffer for 8 characters:
char buffer[8]; gets(buffer); // reads user input

If the user enters AAAAAAAAAAAAAAAA (16 A’s), the extra 8 characters go beyond the intended memory space, overflowing into other parts of memory.

Attackers can exploit this to Overwrite function return addresses, making the program jump to malicious code they inserted and Gain control of the system (common in older systems without protection).

Types of buffer overflows

  • Stack-based (stack buffer overflow) — overflow of a local variable on the stack; can corrupt saved frame pointer and return address. OWASP

  • Heap-based — overflow of heap-allocated memory (malloc/new); can corrupt allocator metadata or object fields. CWE

  • Off-by-one — write 1 byte past end causing subtle corruption.

  • Integer overflow → buffer size miscalc — arithmetic bugs that cause allocation smaller than expected.

  • Environment/config-driven overflows — e.g., long env vars or file inputs. OWASP

Demo

In this Demo we are going to make use of a very simple & known buffer overflow vulnerability, which is stack based.

The makefile: A Makefile is a configuration file used by the `make` tool to automate the process of compiling and building programs, especially in languages like C or C++. It defines rules that specify how to build targets (like executables) from their dependencies (such as source files) using specific commands, typically compiler instructions. This allows developers to compile projects efficiently, as `make` only rebuilds parts of the program that have changed, saving time and reducing errors compared to manual compilation.

Inside the rootme.c vulnerable program we have:
  • printf("[debug] mid stack address is :%p\n", (void *)mid); 👉 leaks a stack address. defeats ASLR-like protections and makes it far easier for an attacker to compute exact addresses needed to hijack control flow. Any runtime pointer/address printed to untrusted output is an information disclosure vulnerability.

  • fgets(buffer, 1000, stdin); 👉requests up to 999 bytes (plus null) but buffer is only 512 bytes. That lets input overwrite memory past buffer on the stack (saved registers, saved base pointer, return address, adjacent locals) which is an obvious stack-based overflow.

You will need compiler and build tools to compile the C program using the makefile file we have.


I already have it installed onto my ubuntu vm. 


A quick look into the makefile configuration which is disabling ASLR and setting suid. It would make the program vulnerable to privilege escalation, and it will restart the ASLR, upon execution.

ASLR (Address Space Layout Randomization) is a security feature that makes the memory addresses used by a process unpredictable by randomizing the locations of key memory regions such as the stack, heap, shared libraries, and the program’s code each time a program runs. By scattering those regions at different addresses, ASLR makes it much harder for an attacker to guess where to jump to or where to place malicious data, significantly raising the difficulty of exploiting memory-corruption bugs like buffer overflows. 

Although, It’s not a silver bullet (attackers can sometimes bypass it with information leaks or use techniques like ROP), but combined with NX/DEP, stack canaries, and compiler hardening it greatly reduces exploitability. But, these topics are beyond the scope of this blog post. 


We compile using one of the tool we installed to build/compile programs.

We get a rootme file in red font which tells us that this vulnerable executable has a SID set bit for special linux permissions that allows us to run as root. 



We execute this file to check the output, we already have access to its source code so we can already tell how it will go. 


The information disclosure is visible by informing us of the mid stack address, which is provided to us in this demo in hexadecimal value. 

We need to build an exploit upon it. Thankfully with this demo that is provided by tcm security academy, they have us hooked with a python exploit. 

The exploit build itself is outside the scope of this demonstration.

The exploit needs the mid stack address.


After executing the exploit in python and providing the hexadecimal value of the mid stack address that we got it from the information disclosure of the C program, it had written a payload.

We need to use this payload while executing the vulnerable C program to overflow the buffer and overwrite the memory to execute our shellcode.

" cat exploit - | ./rootme " 👉 runs cat to send the contents of the file exploit followed by whatever cat reads from its standard input (the hyphen here  - means “read from stdin”) into the pipe.

The pipe feeds that combined stream into ./rootme’s stdin.

Practically this means ./rootme will first receive the bytes from exploit.

And just like that we have overflow the memory buffer, and executed the shellcode(included inside the payload, the exploit.py script that has built for us) into the memory and received a privileged interactive shell onto the host. 

To download this demo click here , you will need a linux machine with its essential build tools that we went through. 

Thanks for reading.


Comments

Popular posts from this blog

Common Network Commands: IP R

Junior Security Analyst Intro

Example of A Day in the Life of a Junior (Associate) Security Analyst