Sat 4 Jun @ 23:59 Wed 8 Jun @ 23:59

In this assignment, you’ll examine some of the software security features that we discussed in the first module of the course.

Tip

I’ve fixed a typo in the stack dump for Q6: the string should read "Hello, world!\n", not "Hello, students".

  1. Why is the best answer to the question, "is my system secure?" simply "no"?

  2. Give an example of a security policy that might be required when developing a software system to track students' progress through the Engineering program.

  3. Explain the following terms, using an example for each (not one I gave in class):

    1. Threat

    2. Vulnerability

    3. Adversary

    4. Attack

  4. Give an example other than one given in the course notes of a leaky abstraction.

  5. Explain, with reference to a diagram (which may be hand-drawn or computer-generated) how return-oriented programming can be used to defeat the W^X policy.

  6. Assume the following C program has been compiled:

    #include <stdio.h>
    #include <string.h>
    
    void foo(const int data[], int len)
    {
    	printf("data len: %d\n", len);
    	printf("data: %d %d\n", data[0], data[1]);
    }
    
    void bar(const char *buffer, int len)
    {
    	const int *integers = (int*) buffer;
    
    	foo(integers, len / 4);
    }
    
    int main()
    {
    	char message[16];
    	strcpy(message, "Hello, world!\n");
    	int len = strnlen(message, sizeof(message));
    
    	bar(message, len);
    
    	return 0;
    }

    yielding the following symbols as revealed by nm(1):

    0000000000201670 T _start
    00000000002019f0 T bar
    00000000002019b0 T foo
    0000000000201960 T main

    This program is then executed in a debugger, with execution paused at the beginning of the bar function. At that point, the contents of (a portion of) the stack are:

    0x7fffffffe900: 60 e9 ff ff 04 00 00 00 60 e9 ff ff ff 7f 00 00  `.......`.......
    0x7fffffffe910: 40 e9 ff ff ff 7f 00 00 dd 19 20 00 00 00 00 00  @......... .....
    0x7fffffffe920: 30 2b 20 00 00 00 00 00 60 e9 ff ff ff 7f 00 00  0+ .....`.......
    0x7fffffffe930: 30 2b 20 00 10 00 00 00 60 e9 ff ff ff 7f 00 00  0+ .....`.......
    0x7fffffffe940: 80 e9 ff ff ff 7f 00 00 99 19 20 00 00 00 00 00  .......... .....
    0x7fffffffe950: e8 e9 ff ff ff 7f 00 00 60 e9 ff ff ff 7f 00 00  ........`.......
    0x7fffffffe960: 48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21 0a 00 00  Hello, world!...
    0x7fffffffe970: e8 e9 ff ff ff 7f 00 00 01 00 00 00 00 00 00 00  ................
    0x7fffffffe980: c0 e9 ff ff ff 7f 00 00 70 17 20 00 00 00 00 00  ........p. .....
    1. What is the address of buffer?

    2. To what address will the program return when leaving bar?

    3. If buffer were to be overflowed, which function’s return would be affected?

    4. How many integers could foo write into data without overwriting any return addresses?

ENGI 9807 only

  1. Explain, with reference to a diagram, one mechanism that can be used to defend against stack smashing.

  2. The file vulnerable.c describes a program that loads a data file, checks to see whether a user can prove their identity with a password [1] and then, if access is granted, reports the sum of the bytes in the file. You can compile this file with debugging information and stack canaries, then run it with an input data file, using the following Unix commands:

    $ cc -g -fstack-protector-all vulnerable.c -o hackme
    $ echo "hi" > stuff.dat
    $ ./hackme stuff.dat
    1. Using the nm(1) program, identify the addresses of the main, login and sum_bytes functions, as well as the static SECRET variable declared in login.

    2. Using your favourite debugger, pause the execution of the program just before the fread(3) call within sum_bytes. Identify the contents of the stack from the main function’s argc and argv down to the local variables of sum_bytes (using, e.g., mem read $sp $sp+0x100 in LLDB). Visualize these results using an image of your stack similar to that seen in lecture 3.

    3. Repeat the stack memory printing from the above question in a fresh execution of the hackme program. Compare the stack contents from the two executions (e.g., using a combination of wdiff and colordiff, or a graphical tool such as MELD), paying particular attention to the memory between the stack frames of sum_bytes_ and main, as well as between main and the code that invokes it. What is the value of the stack canary used in each invocation?

    4. Suppose that an attacker needed to find a ROP gadget to pop a value from the stack into the register rbp (opcode: 5d). Find an instance of such a gadget (5d followed by a ret instruction, i.e., opcode c3) within your hackme binary. Explain how you found it.


1. The approach to password validation in this example is terrible! We will learn about how passwords should actually be validated in the next module on host security.