Hello, dear friend, you can consult us at any time if you have any questions, add WeChat: daixieit

FIT3173 Software Security Assignment-1 (S1 2023)

Total Marks 50

Due on April 07, 2023, Friday midnight, 11:59:59 pm

1 Overview

The learning objective of this assignment is for you to gain a first-hand experience on how to exploit the buffer overflow vulnerability and how operating system countermeasures work. All tasks in this assignment can be done on“SeedVM”as used in labs. Please refer to Section 2for submission notes.

2 Submission

You need to submit a lab report (one single PDF file) to describe what you have done and what you have observed with screenshots whenever necessary; you also need to provide explanation or codes to the obser- vations that are interesting or surprising. In your report, you need to answer all the questions listed in this manual. Please answer each question using at most 100 words. Typeset your report into .pdf format (make sure it can be opened with Adobe Reader) and name it as the format: [Your Name]-[Student ID]-FIT3173- Assignment, e.g., HarryPotter-12345678-FIT3173-Assignment.pdf.

All source code, if required, should be embedded in your report. In addition, if a demonstration video is required, you should record your screen demonstration with your voice explanation and upload the video to your Monash Google Drive or any online service which allows you to share videos.  The shared URL of the video should be mentioned in your report wherever required. You can use this free tool to make the video:https://monash-panopto.aarnet.edu.au/ ; other tools are also fine. Then, please upload the PDF file to Moodle. Note: the assignment is due on April 07, 2023, Friday midnight, 11:59:59 pm.

Late submission penalty: 10 points deduction per day. If you require a special consideration, the application should be submitted and notified at least three days in advance. Special Considerations are handled by and approved by the faculty and not by the teaching team (unless the special consideration is for a small time period extension of one or two days).

Zero tolerance on plagiarism: If you are found cheating, penalties will be applied, i.e., a zero grade for the unit. University polices can be found at https://www.monash.edu/students/academic/ policies/academic-integrity

3 Buffer Overflow Vulnerability [50 Marks]

The learning objective of this part is for you to gain the first-hand experience on buffer-overflow vulnerability by putting what you have learned from labs into action.  Buffer overflow is defined as the condition in which a program attempts to write data beyond the boundaries of pre-allocated fixed length buffers. This vulnerability can be utilised by an attacker to alter the flow control of the program, even execute arbitrary pieces of code to enable remote access attacks. This vulnerability arises due to the mixing of the storage for data (e.g. buffers) and the storage for controls (e.g. return addresses): an overflow in the data part can affect the control flow of the program, because an overflow can change the return address.

In this part, you will be given a program with a buffer-overflow vulnerability; the task is to develop a scheme to exploit the vulnerability and finally send a remote access to an attacker. In addition to the attacks, you will be guided to walk through several protection schemes that have been implemented in the operating system to counter against the buffer overflow. You need to evaluate whether the schemes work or not and explain why.

Note: if you’re using cloud VM, please use -m32 flag for all gcc commands below.

3.1 Initial setup

You can execute the tasks using our pre-built Ubuntu virtual machines.  Ubuntu and other Linux dis- tributions have implemented several security mechanisms to make the buffer-overflow attack difficult. To simplify our attacks, we need to disable them first.

Address Space Randomisation. Ubuntu and several other Linux-based systems uses address space ran- domisation to randomise the starting address of heap and stack. This makes guessing the exact addresses difficult; guessing addresses is one of the critical steps of buffer-overflow attacks. In this part, we disable these features using the following commands:

$  su  root

Password:   (enter  root  password  "seedubuntu")

#  sysctl  -w  kernel .randomize_va_space=0

#  exit

The StackGuard Protection Scheme. The GCC compiler implements a security mechanism called“Stack Guard”to prevent buffer overflows. In the presence of this protection, buffer overflow will not work. You can disable this protection if you compile the program using the -fno-stack-protector switch. For example, to compile a program example.c with Stack Guard disabled, you may use the following command:

$  gcc  -fno-stack-protector  example .c

Non-Executable Stack. Ubuntu used to allow executable stacks, but this has now changed: 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 automatically by the recent versions of gcc, and by default, the stack is set to be non-executable. To change that, use the following option when compiling programs:

For  executable  stack:

$  gcc  - z  execstack    -o  test  test .c

For  non-executable  stack:

$  gcc  - z  noexecstack    -o  test  test .c

3.2 Warm Up: Shellcode Practice

Before you start the attack, we want you to exercise with a shellcode example. A shellcode is the code to launch a shell. It is a list of carefully crafted instructions created by malicious users/attackers so that it can be executed once the code is injected into a vulnerable program.  Therefore, it has to be loaded into the memory so that we can force the vulnerable program to jump to it. Consider the following program:

#include  

int  main(  )  {

char  *name[2];

name[0]  =   ‘‘/bin/sh’’;

name[1]  =  NULL;

execve(name[0],  name,  NULL);

}

The shellcode that we use is the assembly version of the above program. The following program shows you how to launch a shell by executing a shellcode stored in a buffer.

Practice Task: Please compile and run the following code, and see whether a shell is invoked.

/ *  call_shellcode .c    */

/ *A  program  that  creates  a  file  containing  code  for  launching  shell */

#include  

#include  

#include  

const char code[]  =

"\x31\xc0"

/ * Line

1:

xorl

%eax,%eax

*/

"\x50"

/ * Line

2:

pushl

%eax

*/

"\x68""//sh"

/ * Line

3:

pushl

$0x68732f2f

*/

"\x68""/bin"

/ * Line

4:

pushl

$0x6e69622f

*/

"\x89\xe3"

/ * Line

5:

movl

%esp,%ebx

*/

"\x50"

/ * Line

6:

pushl

%eax

*/

"\x53"

/ * Line

7:

pushl

%ebx

*/

"\x89\xe1"

/ * Line

8:

movl

%esp,%ecx

*/

"\x99"

/ * Line

9:

cdq

*/

"\xb0\x0b"

/ * Line

10:

movb

$0x0b,%al

*/

"\xcd\x80"

/ * Line

11:

int

$0x80

*/

;

int  main(int  argc,  char  **argv)

{

char  buf[sizeof(code)];

strcpy(buf,  code);

((void( *)(  ))buf)(  );

}

Please use the following command to compile the code (don’t forget the execstack option): $  gcc  - z  execstack  -g  -o  call_shellcode  call_shellcode .c

The shellcode is stored in the variable code in the above program. A few places in this shellcode are worth mentioning. First, the third instruction pushes“//sh”, rather than“/sh”into the stack. This is because we need a 32-bit number here, and“/sh”has only 24 bits. Fortunately,“//”is equivalent to“/”, so we can get away with a double slash symbol. Second, before calling the execve() system call, we need to store name[0] (the address of the string), name (the address of the array), and NULL to the %ebx, %ecx, and %edx registers, respectively. Line 5 stores name[0] to %ebx; Line 8 stores name to %ecx; Line 9 sets %edx to zero. There are other ways to set %edx to zero (e.g., xorl  %edx,  %edx); the one (cdq) used here is simply a shorter instruction: it copies the sign (bit 31) of the value in the EAX register (which is 0 at this point) into every bit position in the EDX register, basically setting %edx to 0. Third, the system call execve() is called when we set %al to 11, and execute“int  $0x80”.

3.3 The Vulnerable Program

/ *  stack .c  */

/ *  This  program  has  a  buffer  overflow  vulnerability .  */

/ *  Our  task  is  to  exploit  this  vulnerability  */

#include  

#include  

#include  

int  bof(char  *str,int  studentID)

{

int  bufSize;

int  a  =  12;

int  b  =  18;

bufSize  =  12  +  studentID%32;

char  buffer[bufSize];

strcpy(buffer,  str);

return  1;

}

int  main(int  argc,  char  **argv[])

{

if(argc  < 2) {

printf("Usage:  %s  \n",  argv[0]);

exit(0);

}

int  studentID  =  ;  //ENTER  YOUR  STUDENT  ID  HERE

bof(argv[1],studentID);

printf("Returned  Properly\n");

return  1;

}

You need to enter your student ID to the variable studentId. Then, compile the above vulnerable program and make it set-root-uid. You can achieve this by compiling it in the root account and chmod the executable to 4755 (don’t forget to include the execstack and -fno-stack-protector options to turn off the non-executable stack and StackGuard protections):

$  su  root

Password   (enter  root  password  "seedubuntu")

#  gcc  -g  -o  stack  - z  execstack  -fno-stack-protector  stack .c

#  chmod  4755  stack

#  exit

The above program has a buffer overflow vulnerability. It takes input from the terminal which is under user’s control.

3.4 Task 1: Exploiting the Vulnerability [30 Marks]

The objective of this task is to exploit buffer overflow vulnerability in the above provided code (stack .c) and receive a reverse-shell. You need to read Appendix A.1to investigate how to create a reverse-shell code. Then, you also need to study how to simulate an attacker, who is listening at a specific address/port and waiting for the shell. We refer you to Appendix A.2for this simulation.

You will need to generate a reverse-shell code using msfvenom and create a the payload. Then run the vulnerable program stack with your payload. If your exploit is implemented correctly, the attacker should be able to get the reverse shell.

You will be overflowing the buffer in stack .c, which is compiled with the Stack Guard protection disabled.

$ . /stack     {PAYLOAD}         //  launch  the  attack  by  running  the  vulnerable  program

If the attacker obtains the shell successfully, her terminal should be as follows (assuming that she is listening at the port 4444, and the program stack is running at the address 10.0.2.15).

$[02/01/20]seed@VM:˜$  nc  -lvp  4444  //  listening  at  the  port  4444 Listening  on   [ 0.0.0.0 ]   (family  0,  port  4444)

Connection  from   [ 10.0.2.15 ]  port  4444   [tcp/ *]  accepted

Once the attacker obtains the shell, she can remotely manipulate all the current files where the program stack runs.

Q1 (30 marks): Provide your video demonstration evidence to support and verify that you have performed the attack and it worked successfully. You need to embed the vidoe link to your report so that the teaching team can view and verify your works.  In the video, you need to demonstrate following key points:

• The buffer overflow happens and the attacker receives the shell when the victim executes the vulnerable program stack.  (10 marks if the attack works during your demonstration video)

• Debug the program stack to investigate the return memory address and local variables (high- light them in your video demo) in the function bof(). (10 marks for the debug demonstra- tion and memory analysis)

• Explain clearly the payload used for exploiting the buffer, i.e. how many NOPs were used and why, how the return address was selected etc..(10 marks for your explanation during the demonstration video)

Please note that providing incorrect student ID will result 0 mark for this task. The full marks only given if you have solid explanation with supporting memory address analysis.

3.5 Task 2: Address Randomisation [5 Marks]

Now, we turn on the Ubuntu’s address randomisation. We run the same attack developed in the above task.

Can you get a shell? If not, what is the problem? How does the address randomisation make your attacks difficult? You can use the following instructions to turn on the address randomisation:

$  su  root

Password:   (enter  root  password  "seedubuntu")

#  /sbin/sysctl  -w  kernel .randomize_va_space=2

If running the vulnerable code once does not get you the root shell, how about running it for many times? You can run . /stack in the following loop , and see what will happen. If your exploit program is designed properly, you should be able to get the root shell after a while. You can modify your exploit program to increase the probability of success (i.e., reduce the time that you have to wait).

$  sh  -c  "while   [  1  ];  do   . /stack  {PAYLOAD};  done;"

Q2 (5 marks): Follow the above steps, and answer the highlight questions.  You should describe your observation and explanation briefly. Furthermore, try whether you can obtain root shell again.

[Marking scheme: 2 marks for the screenshot and 3 marks for the explanation and solutions].

3.6 Task 3: Stack Guard [5 Marks]

Before working on this task, remember to turn off the address randomisation first, or you will not know which protection helps achieve the protection.

In our previous tasks, we disabled the “Stack Guard” protection mechanism in GCC when compiling the programs. In this task, you may consider repeating the above task in the presence of Stack Guard. To do that, you should compile the program without the -fno-stack-protector’ option. For this task, you will recompile the vulnerable program, stack.c, to use GCC’s Stack Guard, execute the stack program again, and report your observations. You may report any error messages you observe.

In the GCC 4.3.3 and newer versions, Stack Guard is enabled by default. Therefore, you have to disable Stack Guard using the switch mentioned before. In earlier versions, it was disabled by default. If you use an older GCC version, you may not have to disable Stack Guard.

Q3 (5 marks): Follow the above steps, and report your observations. [Marking scheme: 2 marks for the screenshot and 3 marks for the explanation and solutions]

3.7 Task 4: Non-executable Stack [5 Marks]

Before working on this task, remember to turn off the address randomisation first, or you will not know which protection helps achieve the protection.

In our previous tasks, we intentionally make stacks executable. In this task, we recompile our vulnerable program using the noexecstack option, and repeat the attack in the above task. Can you get a shell? If not, what is the problem? How does this protection scheme make your attacks difficult. You can use the following instructions to turn on the non-executable stack protection.

#  gcc  -o  stack  -fno-stack-protector  - z  noexecstack  stack .c

It should be noted that non-executable stack only makes it impossible to run shellcode on the stack, but it does not prevent buffer-overflow attacks, because there are other ways to run malicious code after exploiting a buffer-overflow vulnerability.

If you are using our SeedVM, whether the non-executable stack protection works or not depends on the CPU and the setting of your virtual machine, because this protection depends on the hardware feature that is provided by CPU. If you find that the non-executable stack protection does not work, check our document (“Notes on Non-Executable Stack”) that is linked to the course web page, and see whether the instruction in the document can help solve your problem. If not, then you may need to figure out the problem yourself.

Q4 (5 marks): Follow the above steps, and answer the highlight questions. You should describe your observation and explanation briefly. [Marking scheme: 2 marks for the screenshot and 3 marks for the explanation and solutions]

3.8 Task 5: Report Completion [5 Marks]

Please include all payloads, stack.c file and video URLs in the PDF report. Full marks can only be obtained if the report is complete and appropriately formatted.

Acknowledgement

This assignment are based on the SEED project (Developing Instructional Laboratories for Computer SE- curity EDucation) at the website http://www.cis.syr.edu/ ˜wedu/seed/index.html.

A Appendix

A.1 Reverse Shell Creation

A reverse-shell enables the connection from the target machine to the attacker’s machine. In this situation, the attacker’s machine acts as a server. It opens a communication on a port and waits for incoming connec- tions. The target machine acts as a client connecting to that listener, and then finally the attacker receives the shell. These attacks are dangerous because they give an attacker an interactive shell on the target machine, allowing the attacker to manipulate file system/data.

In this assignment, we use msfvenom module in Metasploit to generate the reverse shellcode. Metas- ploit is one of the most powerful and widely used tools for exploring/testing the vulnerability of computer systems or to break into remote systems. You first install Metasploit by openning a terminal and entering the following command. Note that the command is one-line command without line breaks.