Download as pdf or txt
Download as pdf or txt
You are on page 1of 39

Buffer Overflow attack to control variables on stack

Project report submitted for


VII Semester Ethical Hacking course
in
Department of CSE

By,
Nitin Chandra (17100030)
M Krishna Chaitanya (17100026)
C Tarun Sai (17101015)

Department of CSE
Dr. Shyama Prasad Mukherjee
International Institute of Information Technology, Naya Raipur
(A Joint Initiative of Govt. of Chhattisgarh and NTPC)
Email: ​iiitnr@iiitnr.ac.in​, Tel: (0771) 2474040, Web: ​www.iiitnr.ac.in
CERTIFICATE

This is to certify that the project titled “​BUFFER OVERFLOW ATTACK TO


CONTROL VARIABLES ON STACK​” by “​NITIN CHANDRA, M KRISHNA
CHAITANYA, C TARUN SAI​” has been carried out under my/our supervision and
that this work has not been submitted elsewhere for a degree/diploma.
December, 2020

DECLARATION

I declare that this written submission represents my ideas in my own words and where
others' ideas or words have been included, I have adequately cited and referenced the
original sources. I also declare that I have adhered to all principles of academic
honesty and integrity and have not misrepresented or fabricated or falsified any
idea/data/fact/source in my submission. I understand that any violation of the above
will be cause for disciplinary action by the Institute and can also evoke penal action
from the sources which have thus not been properly cited or from whom proper
permission has not been taken when needed.

Signature: ___________________
Nitin Chandra
(17100030)
Signature: ___________________
M Krishna Chaitanya
(17100026)
Signature: ___________________
C Tarun Sai
(17101015)

Date : 5​th​ December, 2020


Plagiarism Report
Approval Sheet

This project report entitled “​BUFFER OVERFLOW ATTACK TO CONTROL


VARIABLES ON STACK​” by “​NITIN CHANDRA, M KRISHNA CHAITANYA, C
TARUN SAI​” is approved forVII​th​ Semester Ethical Hacking Project.

Signature: ________________________
Dr. Mahesh Patil

Signature: ________________________
Dr. Appala Naidu

Date: 5​th​ December, 2020.


Place: IIIT Naya Raipur.
TABLE OF CONTENTS
Buffer Overflow attack to control variables on stack 0

CERTIFICATE 1

Declaration 2

ABSTRACT 4
CHAPTER 1 6

INTRODUCTION 6
1.1 Application Memory: 6
1. Text Segment: 7
2. Initialized Data: 7
3. Uninitialized Data: 7
4. Stack: 7
5. Heap: 7
1.2 Buffer Overflow: 7
1.3 Buffer Overflow Attacks: 8
CHAPTER 2 9

LITERATURE SURVEY 9
CHAPTER 3 10

METHODOLOGY 10
1. Fuzzer: 10
2. Disassembler: 11
3. Debugger: 12
4. Exploit: 13
CHAPTER 4 14

IMPLEMENTATION 14
Analysis of 1st ELF file : 14
Fuzzing 14
Dissassembler 15
Debugger 17
Exploit 21
Analysis of 2nd ELF file : 22
Fuzzing 22
Dissassembler 23
Debugger 25
Exploit 28
Analysis of 3rd ELF file : 29
Fuzzing 29
Dissassembler 30
Debugger 32
Exploit 34
CHAPTER 5 35

CONCLUSION 35
CHAPTER 6 37

REFERENCES 37
ABSTRACT

Buffer overflow attacks have been the most common attacks from the past 10
years. With the help of these attacks, an anonymous attacker can gain either the
total or partial control over the program. Attackers can do many malicious
things with the help of buffer overflow attacks like Code Injection, Control the
variables on stack, Function calls etc. In this project, we will be focusing mainly
on how an attacker can control the variables of stack with the help of buffer
overflow attack by some examples and also the possible ways to control these
types of attacks. If these types of vulnerabilities could be eliminated, then a
large portion of the serious threats would also be eliminated.
CHAPTER 1
INTRODUCTION

1.1 Application Memory:


Application Memory, also known as storage Buffer. Whenever a program
execution takes place then some part of the physical memory (RAM) is assigned
to that particular program, this part is used by that particular program and this is
known as Buffer. In other words, it is the temporary memory storage location
used by the program while being executed. The Buffer or Application Memory
structure of a C program is as shown in the below figure:

Fig 1.1:​ Application Memory Structure of a Basic C Program.


The Memory structure contains several sections such as Text segment, Data
segment, Heap, Stack. All these sections are explained below:
1. Text Segment:
Text segment, also named as code segment. It is one the section, which is
present in the Application memory. Generally, all the executable instructions
are present in this section. The text segment is read-only, so as to prevent
accidental modifications of the program under execution.
2. Initialized Data:
Also known as Data Segment. It consists of all the static and global
variables, that are initialized by the programmer. This section is not read-only,
as the values of the variables can also be changed during execution (run-time).
3. Uninitialized Data:
Also known as BSS (Block Started by Symbol), named after an ancient
assembler operator. This segment also contains the static and global variables,
but which are just declared and not initialized by the programmer. The values of
these variables are set to default values by the kernel itself such as for int (0),
string (empty string) etc.
4. Stack:
It is a section of the application memory, which contains functions and all
the temporary variables used by the functions. Generally, the stack grows down
towards the low-address, shown in the above figure.
5. Heap:
The dynamic memory allocation takes place at the Heap. Heap section is
controlled by the malloc, realloc, free functions, which uses the system calls to
adjust the Heap size.

1.2 Buffer Overflow:


Buffer overflow occurs when the program uses (or) tries to use more
memory locations than the memory locations allocated to that particular
program. In such a case then the extra data overflows into other buffers, which
may result in overwriting or corrupting the data present in the other buffers.
There are two types of buffer-overflows, one is Stack based and the other is
Heap based. Heap based buffer overflow occurs when the program tries to use
the entire memory space reserved for that program. Stack based overflows are
more common than the heap based.
1.3 Buffer Overflow Attacks:
In Buffer Overflow attacks, the main vulnerability is the overflow of the
buffer, mainly due to the extra data. The attacker sends the extra data in the
form of instructions, and these instructions stop the current execution flow of
the program and do something else which is intended by the attacker to do. Here
the exploit is the extra data (instructions). The overflow(vulnerability) is
exploited by the extra data (exploit). Sometimes when the overflow happens
then the extra data is overwritten at some other locations (below locations). In
this way the attacker changes the variables present on the stack, with the
intended values. Apart from changing variables on stack, buffer overflow attack
can be used to:
1. crash the program
2. gain private information from the program
3. change the flow control of the program
4. run some part of the program which is not intended to be run
5. run some program of adversary’s choice

Fig 1.2: ​Showing the overwritten data at other locations.


CHAPTER 2

LITERATURE SURVEY

In this paper​[1]​, various versions of buffer overflow vulnerabilities and attacks


have been explored, and a brief study on the white-hat part of Buffer overflow
attacks i.e various techniques to protect against buffer overflow attack has been
presented. An experiment on various combinations of defense mechanisms have
been done and a report on which combinations perform better has also been
presented.
This paper​[2] is more of a survey where all the concepts related to buffer
overflow such as contents of a program, the stack, attacks where buffer
overflows can be used, their consequences, the sources and the defense
mechanisms have been discussed vividly. The objective of this paper was to
take one inside the buffer overflow attack and bridge the gap between the
“descriptive account” and the “technically intensive account”.
CHAPTER 3
METHODOLOGY
Our methodology contains 4 phases. They are:
1. Using a Fuzzer.
2. Using a Disassembler.
3. Using a Debugger.
4. Exploiting the vulnerability to change the variables on the stack.

Fig 3.1: ​Flowchart depicting the phases of the methodology used.

All these stages are explained in detail below:


1. Fuzzer:
A Fuzzer is generally used for generating the possible combinations of
test cases required to test the program. We used Radamsa Fuzzer, for generating
the test cases. We executed the program on all the generated test cases. With the
help of this tool, we come to know whether the program can be overflowed by
passing extra data (or) not, means whether the program can be cracked by the
buffer overflow attack or not.
Fig 3.2: ​Examples of test cases generated using Radamsa Fuzzer.

2. Disassembler:
Disassembler is a tool, which is used for reverse engineering the
programs. It generally displays the instructions in low level language
(machine-level). We used Cutter Disassembler, in order to perform the reverse
engineering.

Fig 3.3: ​Figure shows the example Graph of the Reverse Engineered Program.
For additional help in understanding the exact meaning of the code, we could
also use a decompiler and strings that appear in the code. These features are
readily available in Cutter.

3. Debugger:
At this stage, we will be using the GDB-PEDA debugger, in order to understand
the step wise low level language (assembly language) operations that are
happening while the program is under execution. By using the debugger we can
identify whether the variables present on the stack are getting affected by the
overflow attack or not.

Fig 3.4​: The above figure shows the sample output of GDB-PEDA, It shows the
register values in the register section, Upcoming instructions in code section and
Stack content in the stack section.
4. Exploit:
At this stage, we will be sending the desired value as extra space (main cause
for the overflow) and the value present at the top of the current value in the
stack will be overwritten by this extra space. If the value of the variable is
changed then the sample program outputs “Cracked”, else the output will be
“Try Again”.

Fig 3.5​:​ ​The above figure shows the output, when the overflow doesn’t happen
and the value of the variable isn’t changed.

Fig 3.6​: The above figure shows the output, when the overflow happens and the
value of the variable is changed.
CHAPTER 4
IMPLEMENTATION

1. Analysis of 1st ELF file :


a. Fuzzing

Fig 4.1: Showing the randomly generated test cases using Radamsa tool.

The above figure shows the randomly generated test cases using Radamsa
Fuzzer. The program is cracked for some of the above inputs, where the length
of the string is greater than 64. Hence from this step we can say that this
program can be cracked using the Buffer overflow attack.
b. Dissassembler

Fig 4.2 : Dashboard for 1st object file

This is the Dashboard for the 1st object file in Cutter. It shows that it is an
ELF-32 bit file. It uses the x86 architecture instruction set. It runs on a Linux
machine. It has been compiled by a Ubuntu compiler (gcc). It has also guessed
that the programming language used might be C.
Fig 4.3 : Flow control for 1st object file

This is a graph which shows the control flow of the program 1.c and it is clear
that a conditional statement is present in it. Here, it says if eax==0, go to the
green part, else go to the red part. Either part is used to print some string. So, the
program says : 2 variables exist (1st an integer initialized to 0 and then a
character buffer). Some input is taken and stored onto the buffer. Then the value
of the integer is checked and based on whether it is 0 or not, the branching
depends.
c. Debugger

Fig 4.4 : When a modified variable is getting initialized.

Here we initialize an integer variable which is a local variable in the main


function with 0.
Fig 4.5 : When input is being taken.

Here a string is taken as input and it is getting stored in a buffer. Clearly the
integer variable is 64 bytes from the top stack. So, we can enter a 65 bytes string
to overflow the buffer.
Fig 4.6 : Checking the modified value != 0 or not.

The test instruction performs bitwise AND of the 2 operands and modifies zero
flag. If eax==0, then ZF is set to 1. Here depending on whether the integer
variable is changed or not the value of eax is 0 or another number. If ZF==1,
then “Cracked” is printed. Else “Try Again?” is printed.
Fig 4.7 : When the program is going to output Cracked.
d. Exploit

Fig 4.8 : Output when the program is not cracked.

The program runs smoothly if we give 64 times “a” as input. The value of the
variable (modified) will not be changed. The above figure shows the output of
the program, when 64 times “a” is given as input to the program.

Fig 4.9 : Output when the program is cracked.

The above program changes the modified variable value. The above figure
shows the output as “Cracked”, as the modified variable value is changed. Here
the input given is 64 times “a” + “bcde”. Hence the modified value becomes the
decimal ascii values of (“edcb”), as the modified variable is an integer variable.
2. Analysis of 2nd ELF file :
a. Fuzzing

Fig 4.10: Showing the randomly generated test cases using Radamsa tool.

The above figure shows the randomly generated test cases using Radamsa
Fuzzer. The program is cracked for some of the above inputs, where the length
of the string is greater than 64. Hence from this step we can say that this
program can be cracked using the Buffer overflow attack.
b. Dissassembler

Fig 4.11 : Dashboard for 2st object file

This is the Dashboard for the 2nd object file in Cutter. It shows that it is an
ELF-32 bit file. It uses the x86 architecture instruction set. It runs on a Linux
machine. It has been compiled by a Ubuntu compiler (gcc). It has also guessed
that the programming language used might be C.
Fig 4.12 : Flow control for 2nd object file

This is a graph which shows the control flow of the 2nd executable file.
Initially, it checks if arguments are present or not. If arguments are not present
then some string is printed. Then an integer variable is initialized to zero and a
buffer is filled with the string argument. The integer variable is compared with
0x61626364 and if they are equal, some string is printed. Else some other string
is printed.
c. Debugger

Fig 4.13 : Checking for command-line arguments

Here the number of command-line arguments are being checked. If there is no


command line argument some string is being printed.
Fig 4.14 : A integer variable is being initialized

A local variable which is pushed onto the stack is being initialized to 0.


Fig 4.15 : Integer variable is loaded onto eax.

Here the integer variable is loaded onto eax and compared with a hex number
0x61626364. So, probably if the overflowed part is this number, we might get
the “Cracked” string as output.

Fig 4.16 : Checking the character for corresponding ASCII values

Here we check the characters whose ascii values are 61,62,63,64. We append
this string after 64 bytes in reverse order so that the integer variable will contain
the value 0x61626364.
Fig 4.17 : “Cracked” string gets printed

d. Exploit

Fig 4.18 : Output when the program is not cracked.

The program runs smoothly if we give 64 times “a” as input. The value of the
variable (modified) will not be changed. The above figure shows the output of
the program, when 64 times “a” is given as input to the program.
Fig 4.19 : Output when the program is cracked.

The above program changes the modified variable value. The above figure
shows the output as “Cracked”, as the modified variable value is changed. Here
the input given is 64 times “a” + “dcba”. Hence the modified value becomes the
decimal ascii values of (“abcd”), as the modified variable is an integer variable.

3. Analysis of 3rd ELF file :


a. Fuzzing

Fig 4.20: Showing the randomly generated test cases using Radamsa tool.

The above figure shows the randomly generated test cases using Radamsa
Fuzzer. The program is cracked for some of the above inputs, where the length
of the string is greater than 64. Hence from this step we can say that this
program can be cracked using the Buffer overflow attack.
b. Dissassembler

Fig 4.21 : Dashboard for 3st object file

This is the Dashboard for the 3rd object file in Cutter. It shows that it is an
ELF-32 bit file. It uses the x86 architecture instruction set. It runs on a Linux
machine. It has been compiled by a Ubuntu compiler (gcc). It has also guessed
that the programming language used might be C.
Fig 4.22 : Flow control for 3rd object file

This is a graph which shows the control flow of the 3rd executable file. Here an
environment variable is taken and it’s value is compared to 0. If it is zero, some
string is printed. An integer variable is taken and is initialized to 0. Then the
value of the environment variable is copied into some buffer. Now if the value
of the integer variable is 0x0d0a0d0a then some string is printed. Else some
other string is printed.
c. Debugger

Fig 4.23 : The “GREENIE” string is pushed onto the stack

The GREENIE environment variable is pushed onto the stack because it is the
argument for the function getenv().
Fig 4.24 : Initialize the integer variable to 0

Fig 4.25 : Comparing the integer variable to 0xd0a0d0a0

Here the integer variable is compared to 0xd0a0d0a0 and it matches probably


“Cracked” would be printed.
Fig 4.26 : “Cracked” gets printed

d. Exploit

Fig 4.27 : Output when the program is not cracked.

The program runs smoothly if we give 64 times “a” as input. The value of the
variable (modified) will not be changed. The above figure shows the output of
the program, when 64 times “a” is given as input to the program.
Fig 4.28 : Output when the program is cracked.

The above program changes the modified variable value. The above figure
shows the output as “Cracked”, as the modified variable value is changed. Here
the input given is 64 times “a” + “\r\n\r\n”. Hence the modified value becomes
the decimal ascii values of (“\n\r\n\r”), as the modified variable is an integer
variable.

CHAPTER 5
CONCLUSION

From the above, we can conclude that attackers can easily gain the control over
variables that are present on the stack. Apart from modifying variables,
attackers can do a variety of tasks through buffer overflow attack. They can
access private information, change the flow control of the program and also the
most dangerous task of running a program of attacker’s choice.
In order to prevent these kinds of attacks, various defense mechanisms can be
used.
1. Primarily good and safe programming techniques should be used such as
input data validation
2. Good choice of safe programming languages should be made
3. Features of OS and compilers which provide security against buffer
overflow attacks such as Stack canaries, Non-executable data, Address
space layout randomization (ASLR), Control flow Integrity etc., are to be
used.
CHAPTER 6
REFERENCES

1. “Buffer Overflows: Attacks and Defenses for the Vulnerability of the


Decade” By Crispin Cowan, Perry Wagle, Calton Pu, Steve Beattie, and
Jonathan Walpole
2. “Buffer Overflow Attack” By Samanvay Gupta
3. https://www.geeksforgeeks.org/buffer-overflow-attack-with-example
4. https://www.geeksforgeeks.org/memory-layout-of-c-program/

You might also like