IY2840 Coursework 2: UNIX and Application Security
This is a blind submission, and submissions must be made in a ZIP compressed file on Moodle. This compressed file should include the coursework report and necessary source-code files. The report must be in file PDF format, other formats such as: .docx or .pages are not accepted. This coursework counts for 10% of your grade on this module and is worth 100 marks in total. We expect a good submission to be succinct and be less than six pages in length. Learning outcomes assessed are:
• Understanding of UNIX/Linux security and vulnerabilities.
• Understanding of UNIX/Linux Applications security and vulnerabilities.
• Understanding of how to exploit vulnerabilities and steps involved in their exploitation. • Understanding of the countermeasures and mitigation for protecting applications.
This coursework aims to have you reflect on Unix and Application security. To get started, it is important to review the lecture notes and lab materials, the course text, but also to investigate online resources. We are not after essays in this coursework. We are after concise and succinct responses to each question with some proof of implementation (code snippets and screenshots). Do share useful resources that you find with others on the Moodle forum, but do not give any answers away. Note: All the work you submit must be solely your own work. Submissions are routinely checked for plagiarism.
IMPORTANT:
• SEEDLab VM (https://seedsecuritylabs.org/lab_env.html) should be used to develop and test some solutions for this coursework, you can use the SEEDLab VM which is already installed in the lab machines.
• Use the source file attachment (source − files − coursework.zip) for Question 2.e and Question 3b & 3c.
• Keep in mind, all answers related to developing a program solution will be checked in the
SEEDLab VM, so it is important to make sure that your solutions being provided are
executable in this platform.
1
Questions
1. Question 1 (Total 25 marks):
(a) Briefly explain what these functions do in Linux: system(), popen(), and execve(). (3 marks)
(b) Briefly explain the name and the parameters of the execve() function. (2 marks)
(c) Write a small C program to show the /etc/passwd file using the execve() function with a Linux command and report the output of running the program (show as a screenshot). Briefly explain the program as comments in your code and submit the C program. (5 marks)
(d) If we change the file to the /etc/shadow file in the previous program and run it again. Briefly explain: what is the outcome? Why does this occur? Propose a solution to defeat this without having a root access [hint: you may need to do some investigation online to answer this question]. Briefly explain the commands used and provide the results of applying them (screenshots). Submit the C program.
(15 marks)
2. Question 2 (Total 35 marks): Below follows a simple C program that spawns a shell with
execve(). Note: it invokes /bin/sh without any arguments, with an empty environment.
#include
int main( ) {
char *name[2];
name[0] = “/bin/sh”;
name[1] = NULL;
execve(name[0], name, NULL);
}
(a) Briefly explain what /bin/sh is in your own words? (3 marks)
(b) Compile and run the above program and briefly explain the output. (2 marks)
(c) In order to use the above program in buffer-overflow exploitation, we need to disassemble the program to obtain its machine code. However, obtaining self-contained, reproducible assembly program, across different compilers from this C program, can be challenging and difficult if not done right. Therefore, it needs to be simplified (see the code below). Briefly explain what these simplifications are in the following code. Run the code and briefly explain the output to verify that it works as expected. (5 marks)
2
#include
int main(void) {
char buf[7 + 1 + 4 + 4] = “/bin/sh
*(buf + 7) = 0;
*((char**)(buf + 8)) = buf;
*((char**)(buf + 12)) = NULL;
syscall(11, buf + 0, buf + 8, buf + 12);
}
(d) When we disassemble the program above, we should get assembly code that resembles the code below:
1 main: movl $buf, %esi
2 mov %esi,0x8(%esi)
3 mov $0,%eax
4 mov %al,0x7(%esi)
5 mov %eax,0xc(%esi)
6 mov $11,%al
7 mov %esi,%ebx
8 lea 0x8(%esi),%ecx
9 lea 0xc(%esi),%edx
10 int $0x80
11 buf: .ascii “/bin/sh
Briefly explain what each line do? Justify your answer by matching each assembly-code line to the simplified version of C program (15 marks).
(e) Before you write your buffer overflow, you will need to make other changes to the previous assembly code. We already did changes to generate a new version of this program. Then, we converted it to an ASCII-coded program (opcode) to suite the C input data as shown in the SHELLCODE macro within the code below. See if you recognise those differences between the previous assembly program and the new one being generated. Briefly explain: Why are these arrangements required? You need to show how to reverse the value of SHELLCODE macro in the C program to assembly instructions in order to be able to perform the comparison. For more guide to answer this question, refer to Lab6 and the lecture notes. Finally, compile and run code.c, then briefly explain the output (screenshots) (10 marks)
3
#include
#include
#define SHELLCODE “\xeb\x18\x5e\x89\x76\x08\x31\xc0\x88\x46
\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e
\x08\x8d\x56\x0c\xcd\x80\xe8\xe3\xff\xff
\xff/bin/sh”
typedef void (*call)(void);
int main(void) {
unsigned char code[1024];
memcpy(code, SHELLCODE, strlen(SHELLCODE));
printf(“Before.\n”);
((call)code)();
printf(“After.\n”);
}
3. Question 3 (Total 40 marks):
(a) Briefly explain three countermeasures used in Linux to prevent stack-overflow attacks . Include in your answer how to enable them or how to check if they are already enabled. (10 marks)
(b) We have a C program (vulnerable.c) that is vulnerable to buffer-overflow (see the source file attachment). In order to take advantage of this vulnerability to spawn a shell, it is important to create an exploit program (see exploit.c). This program relies on some of the code and instructions from the previous question (e.g. SHELLCODE, execve(), etc.). However, this file becomes corrupted by having missing code and values which are indicated by a question mark sign (?).
i. Fix the exploit.c file by completing the missing parts of this file, in other words, replacing “?” with appropriate instructions or values to be able to compile and run the exploit program. However, you need beforehand to understand the buffer-overflow exploit program and how the shell code is injected to have such an successful attack [Hint: you may need to review the stack frame layout]. You may need to turn off the buffer-overflow countermeasure feature while compiling and running the program. Explain the entire program after fixing it and provide the output, justify your answer. To get the full mark of this part, the new exploit program must be executable, so include the amended exploit.c file in the submission. (18 marks)
ii. Briefly explain why the line below is desired for this particular exploitation. (2 marks)
memset(envbuf + 10, 0x90, ENV_BLOCK_SIZE – 10 – strlen(SHELLCODE));
4
(c) Turn on the countermeasure which is associated with the space address randomisation and run the exploit program again. Briefly explain the observation and provide a screenshot. Then, write a shell script to defeat this countermeasure. The shell script should also include a feature to display the cost of defeating using the metric of either the actual time (hh:mm:ss) or the number of runs. Briefly explain the scripts and provide a screenshot for the output. Also, include the shell script in the submission. Note: In order to answer this part, you should have already solved the previous question (Question 3a). (10 marks)
SD & JH 28 February 2020
5