Binary Exploitation 01 — Introduction

Silaghi Fineas
Cyber Dacians
Published in
4 min readMar 31, 2020

GREETINGS FELLOW HACKERS!
It’s been a while since our last post, but this is because we’ve prepared something for you: a multi episodes Binary Exploitation Series. Without further ado, let’s get started.

What is Memory Corruption?
It might sound familiar, but what does it really mean?
Memory Corruption is a vast area which we will explore more along this series, but for now, it is important to remember that it refers to the action of “modifying a binary’s memory in a way that was not intended”. Basically any kind of system-level exploit involves some kind of memory corruption.

Let’s have a look at an example:

We will consider the following program. A short program that asks for user input. If the input matches Admin’s secret Password, we will be granted Admin privileges, otherwise we will be a normal User.
How can we become an Admin without knowing the Password?
One solution is to brute-force the password. This approach might work for a short password, but for a 32bytes password, it’s useless. Then what can we do? Let’s play with random input values:

“Welcome Admin”, what just happened? Let’s take a closer look at the memory level, using a debugger, and understand why we became Admin.

We can see that the INPUT we enter will be loaded on the stack (“A stack is an area of memory for storing data temporarily”) at RBP-0x30 and the AUTH variable is located on the stack at RBP-0x4.

Another aspect we can observe is that the “gets” function has no limit for the number of characters it reads.

Thus, we can enter more than 32 characters. This will lead to a so called: Buffer Overflow.

As we can see, our input ( ‘A’*32 + ‘a’*16) will overflow the user_input buffer and overwrite the auth variable, thus giving us Admin privileges.

Think this is cool? Just wait, there’s even more.

We have seen that by performing buffer overflows we can overwrite variables on the stack. But is that all we can really do? Let’s have a quick look into how functions work.

Whenever a function is called, we can see that a value is pushed to the stack. That value is what we call a “return address”. After the function finishes executing, it can return to the function that called it using the “return address”.
So if the return address is placed on the stack and we can perform a buffer overflow, can we overwrite it? Let’s try.

Running the program with big input

As we can see, the program returned a “Segmentation Fault” because, when the main function finished executing it tried to use the “return address”, but the return address was overwritten with A’s by out input.

So what does this mean? This means that we can take over the execution flow by overwriting the “return address” with an address of another function. Let’s try to redirect the execution of the program to the takeover_the_world() function.
The function is located at address: 0x00000000004005c7 (one way we can find this is us the command: objdump -d program_name).

Putting things together we get the following input (payload):
‘A’*32 + ‘a’*16 + ‘\xc7\x05\x40\x00\x00\x00\x00\x00’

And we got a shell. Hurray!

Concluding this first part, I hope I have aroused your curiosity and interest in this wonderful topic. Buffer overflows are one of the many ways memory corruption can be achieved. In the upcoming episodes we will explore more techniques and strategies.

Until next time!

--

--