Buffer Overflow Abusing EIP Control

Mr R3b00t
6 min readOct 12, 2021

A Buffer overflow occurs when a program or a process attempts to write extra data to a fixed-length block of memory referred to as a buffer. By sending carefully crafted input to an application, an attacker can cause the application to execute arbitrary code, possibly taking over the machine.

several methods exist for detecting initial buffer overflow in applications, ranging from manually reading the code to automated testing using fuzzing techniques. For this blog, We are going to use a simple C program that has a vulnerable function and an unused function. The source code for the program is as shown be

#include <stdio.h>
#include <unistd.h>
int helper() {
system(“touch pwnd.txt”);
}
int overflow() {
char buffer[500];
i nt userinput;
userinput = read(0, buffer, 700);
printf(“\nUser provided %d bytes. Buffer content is: %s\n”, userinput, buffer);
return 0;
}
int main (int argc, char * argv[]) {
overflow();
return 0;
}

The main function calls the overflow function that has a buffer size of 500 bytes. However, a user is allowed to write more than what is declared in the buffer, which is up to 700 bytes. There is also an unused function. This is a piece of code within a program that is not used, which may happen, e.g., due to a developer’s error of not removing unused functions. It’s called dead code and it simply creates a file on the system called “pwned.txt”. This blog post demonstrates how to exploit the EIP register to execute this dead code. For this demonstration, we are going to disabled protective measures, like Address Space Layout Randomization (ASLR), that may interfere with a clear demonstration of the buffer overflow issue. There are ways to bypass these measures which we are going to cover in the coming articles. To compile to program and disable ASLR;

Compile: gcc smasher.c -o smasher -fno-stack-protector -m32
Disable ASLR: echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

If you cannot compiile to 32-bit (64-bit binary is still okay), please install the following package :

sudo apt install gcc-multilib

The compiled binary is a 32-bit Linux executable (elf file), when executed it waits for user input and displays it.

Now the code has been compiled and the smasher program was created, let's fire up gdb, the Linux command line debugger. If you are unfamiliar with gdb the remainder of this article will probably seem pretty intimidating. I promise it’s not nearly as scary and alien as it seems, gdb is a debugger like any other. let start by listing all functions using info functions command

program functions

The three key functions as explained earlier are as shown above. Even if you do not know the source code, it is possible to find and disassemble the “helper” function. From the dump, the buffer variable is pushed onto the stack before the call to System(). This is performed via moving the address of [eax-0x1ff8] to the EDX (lea instruction), and then pushing it onto the stack as an argument to the system() function (push edx). As the arguments are set up, system() is called. The memory address of the helper function can be printed using p helper command.

helper function

One rule of the thump when it comes to reverse engineering and assembly is NOT to analyze code line by line but to concentrate more on function calls, stack operations and file write/read.

when we feed the program with junk characters, i.e values that exceed the buffer size, it crushes as the extra character overflow to the adjustment EIP register replacing its contents. i created test character using python;

python -c “print(‘A’*800)” > input.txt

EIP with new address

The segmentation fault error is an error the CPU produces when a program tries to access a part of the memory it should not be accessing. It didn’t happen because a piece of memory was overwritten, it happened because the return address was overwritten with 0x41414141 (hex for ‘A’). There’s nothing at address 0x41414141 and if there is, it does not belong to the program so it is not allowed to read it. This produces the segmentation fault.

This means that we can control EIP and run any code or call any function that we want since EIP always contains the address of the next instruction to be executed. Meanwhile, we still need to know the exact number of junk characters that are needed to cause the crash. We would then be able to precisely overwrite the EIP with our controlled data. There are various methods to calculate the offset from the beginning of the buffer to the EIP. we will use metasploit pattern_create.rb and pattern_offset.rb tools to achieve this. to create test characters, open linux terminal and run;

/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 800 > junk.txt

when the generated pattern is fed to the program, it fails again with segmentation fault and overwrites EIP register with an memory address. using metasploit pattern_offset.rb. The generated value is the exact number of characters that are needed to cause a crash, in this case 516 as show below;

offset address
offset value

with this in mind, we are finally going to build an exploit to replace the EIP address with the address of the helper function (identified earlier). To meet the requirements of the memory storage format, we need to send helper function address (0x565561b9) to the buffer in reverse order: b9 61 55 56.

developed exploit
Address in EIP to be executed next
helper function created file

Just as we expected, the helper function address was loaded to the EIP and got executed to create a file pwnd.txt as shown above. Since we supplied an additional address 0x43434343, the program crashed again with a segmentation fault, however, this is just for demonstration purposes you can as well run it without including this additional address and you will not experience the scary segmentation fault.

In the next article, we will be generating and injecting a shellcode that will spawn /bin/bash whenever EIP control is abused.

References

M, L. (2021). INE. Retrieved 12 October 2021, from https://my.ine.com/path/019938d9-11cf-459b-b8ee-e662e10515f2

Mentor, T. (2021). Buffer Overflows Made Easy — TCM Security. Retrieved 12 October 2021, from https://tcm-sec.com/buffer-overflows-made-easy/

m, R. (2021). Retrieved 12 October 2021, from https://repo.zenk-security.com/Techniques%20d.attaques%20%20.%20%20Failles/Exploit-writing-tutorial-part6-Bypassing-Stack-Cookies-SafeSeh-SEHOP-HW-DEP-and-ASLR.pdf

--

--

Mr R3b00t

I am a cybersecurity professional with a strong interest in malware analysis, malware development and ethical hacking.