cw3_handout_2425
cw3_handout_2425
The goal of this coursework is to gain practical experience with attacks that exploit software vulnera-
bilities, in particular buffer overruns. A buffer overrun occurs when a program attempts to read or write
data beyond the bounds of a fixed-length buffer—this can be exploited to alter the flow of the program,
and even execute arbitrary code.
You are given five exploitable programs, which are installed within the virtual machine provided for
this coursework. Each of you will work on slightly different exploitable programs. You will find the
four programs you need to work on in the /task{1-5}/[yourUUN] directories on the provided virtual
machine, with setuid for a respective user set. In each case, a secret should be extracted by exploiting
the program in some way, by supplying it maliciously crafted inputs, either to spawn a shell, or extract
the secret directly.
1
2 Shellcode
In task 3 you will have to deploy some shellcode, and while we do not ask you to come up with this
yourself, we will briefly elaborate what this code does. These are x86 instructions, that, when executed,
have the same effect as executing the following C function:
int main ( ) {
char ∗name [ 2 ] ;
name [ 0 ] = " / b i n / sh " ;
name [ 1 ] = NULL;
setreuid ( geteuid () , geteuid ( ) ) ;
e x e c v e ( name [ 0 ] , name , NULL ) ;
}
This program does two things: First, it sets the current user id to the effective user ID. This ensures
that the shell does not drop privileges when it is started, i.e. reverting to an unprivileged user. In
particular, bash does this, which supplies /bin/sh in our VM. Second, it executes /bin/sh directly.
Good shellcode does not contain NULL bytes, as these will not typically be copied by C programs—for
this reason just compiling the above is usually not sufficient. We provide the below shellcode, and in
task 3, this is already available in the task script.
" \ x31 \ xc0 " // xor %eax , %eax ;
" \ x50 " // push %eax ;
" \ x68 // sh " // push $0x68732f2f ;
" \ x68 / b i n " // push $0x6e69622f ;
" \ x89 \ xe3 " // mov %ebx , %esp ;
" \ x50 " // push %eax ;
" \ x53 " // push %ebx ;
" \ x89 \ xe1 " // mov %ecx , %esp ;
" \ xb0 \ x0b " // mov %al , $0xb ;
" \ xcd \ x80 " // int $0x80 ;
Task 1. This is just a warm-up. The program in /task1/[yourUUN]/vuln waits for a password (stored
in /task1/password.txt), and if the correct password is entered by the user, it prints the secret. The
program has a buffer overflow vulnerability, making it possible – without knowing the password – to
allow it to log in.
Important: the real password will be changed for marking! The pidgeon and rooster variables will
not. [20 marks]
Task 2. The program in /task2/[yourUUN]/vuln takes the user’s name as a command line argument,
copies it to a buffer, and then welcomes the user. This program is vulnerable to a buffer overflow attack.
Your attack script should call this program with a carefully crafted argument, such that it overwrites the
return address on the stack, and returns to the read_secret function, instead of back to main. Stack
canaries are not enabled in this task. [20 marks]
Task 3. For the program in /task3/[yourUUN]/vuln, there is no helpful function for extracting in-
formation, meaning you must inject your own shellcode, jump to this on-stack instead of a pre-existing
function. Furthermore, from this task on, the program is compiled with GCC’s stack protection enabled,
which inserts stack canaries after the return address on stack. Your attack script will input a malicious
argument, such that the program loads and jumps into your shellcode, while avoiding these canaries.
The template provided already contains some boilerplate code to then read the secret from this shell.
[20 marks]
2
Task 4. The program in /task4/[yourUUN]/vuln functions similarly to the previous one, however
execution of code on the stack has been disabled! Instead, you should perform a return-to-libc
attack. In particular, you should overwrite the stack such that execution returns into the libc function
system(), and make this function believe it received "/bin/sh" as an argument. For this purpose,
you’ll need to find the locations of these in memory, and analyse how calls to system() would ordinarily
function. Your program should use this return technique to spawn a shell – in this case the program
itself forces that the real uid is set, ensuring the shell will be as the root user. [20 marks]
Task 5. For task 5 you are not given access to the source of the executables. You will find them in
/task5/[yourUUN]/vuln. You can use Ghidra. Ghidra is a an open source reverse engineering tool
developed by the NSA. With this task you will see how it is possible to bypass ASLR, so you will need
to enable ASLR. The automarker will test your attack scripts for this task with ASLR enable. To enable
ASLR in the current session, use the following command:
echo 2 | tee / proc / sys / kernel / randomize_va_space
To make change permanent (across reboots), use the following command:
echo " kernel . randomize_va_space = 2 " >> / etc / sysctl . d /01 - disable - aslr . conf
Important Note. This last question is substantially more challenging than the previous ones, and may
require a considerable amount of time, creativity, further reading to complete. It is intended to challenge
students who already feel solid on the basic material in the course, and want to go further. Do not
attempt this question unless you have completed all the previous questions, and are sure that you’ve
done a good job on those. Also, do not attempt this question if you have personally spent 12 or more
hours on the assignment already. Unless you really whizzed through the earlier questions, please stop
now and spend your time and energy revising other course materials or getting more sleep. Both are
likely to have a much bigger impact on your final mark.
4 Submission Instructions
Once you have completed your exploits, you should first test them against a clean VM. To retrieve your
attack scripts task{1-5} from the VM you just need to change the settings Devices ,→ Shared Folders
,→ Shared Folders Settings. If you are satisfied, and want to submit, you go on Learn. Under “Course
Content”, you will find in the “Assessment” folder, the “CW3 - Binary exploits” box. Learn does not
support .sh files. You will need to create a zip archive with your attack scripts (create an archive of
your shell script files rather than an directory), and you will name it <UUN>.zip which you will be able
to submit. You will find further guidance on how to submit here: https://edin.ac/47ddcYY
The submission deadline is 22nd November, at 12:00. Please be aware: The actual marking
will generate new random secrets, different for every student. Your secrets must therefore come from
executing the attack on your exploitable programs specifically, and not, for instance, reading them with
root and simply echoing them!
3
to
/disk/scratch/software_security/tmp/sXXXXXX/VirtualBoxVMs/
(you may need to create the directory /disk/scratch/software_security/tmp/sXXXXXX first). The
import operation can take several minutes and need about 17G of disk space per machine.
On DICE machines the virtual disk has to be stored on the local disk. That means that you will not
be able to access the virtual machine on any other DICE computer than the one you did this setup on.
If you want to use your virtual machine from another computer you will have to log in to the machine
using ssh -X <computername>, or copy the disk files to another machine with scp; so make sure you
remember the name of the computer you used!
3. Run VirtualBox.
4. Select File ,→ Import Appliance and select the file BO_2425.ova.