CS155: Computer and Network Security

CS155: Homework #1

Spring 2020

Due: Thursday, Apr. 30, 11:59pm PT


Problem 1: jump-oriented programming

Elizabeth is attacking a buggy application. She has found a vulnerability that allows her to control the values of the registers ecx, edx, and eip, and also allows her to control the contents of memory locations 0x9000 to 0x9014. She wants to use return-oriented programming, but discovers that the application was compiled without any ret instructions! Nonetheless, by analyzing the application, she learns that the application has the following code fragments (gadgets) in memory:

0x3000: add edx, 4      ; edx = edx + 4
        jmp [edx]       ; jump to *edx

0x4000: add edx, 4      ; edx = edx + 4
        mov eax, [edx]  ; eax = *edx
        jmp ecx         ; jump to ecx

0x5000: mov ebx, eax    ; ebx = eax
        jmp ecx         ; jump to ecx

0x6000: mov [eax], ebx  ; *eax = ebx
        ...             ; don't worry about what happens after this

Show how Elizabeth can set the values of the registers and memory so that the vulnerable application writes the value 0x2222 to memory address 0x8888.

Recall that eip is the instruction pointer. It holds the address of the next instruction to execute. ecx and edx are general purpose registers.


Problem 2: ASLR random offset extraction

Explain how the technique discussed in lecture 3 for canary extraction (slide 26) can be similarly used to extract the ASLR random offset for a shared library like libc. You may assume that the attacker has found a heap overflow in a fixed size buffer that is always allocated next to a function pointer that points to a fixed loation in libc. You may also assume that jumping into a location in libc that is not a valid function entry point will crash the program.


Problem 3: memory management

The iOS   _MALLOC(size_t size, int type, int flags) function allocates size bytes on the heap. Internally blocks are represented as a length field followed by a data field:

    struct _mhead {
      size_t  mlen;
      char    dat[0];  }
The mlen field is used by the free() function to determine how much space needs to be freed. In iOS 4.x the _MALLOC function was implemented as follows:
1   void * _MALLOC(size_t size, int type, int flags)  {
2     struct _mhead  *hdr;
3     size_t memsize = sizeof (*hdr) + size;
4     hdr = (void *)kalloc(memsize);  // allocate memory
5     hdr->mlen = memsize;
6     return  (hdr->dat);
7   }
In iOS 5.x the following two lines were added after line 3:
    int o = memsize < size ? 1 : 0;
    if (o)  return (NULL);
Why were these lines added in iOS5.x? Briefly describe an attack that may be possible without these lines.

Problem 4: Reducing privileges with setuid

Jackson is building a new web server. To ensure that an attacker cannot gain root privileges if there's a bug, he sets the Effective UID of each process to the user www-data, after executing the code that requires root privileges. To try and prevent an attacker from being able to call setuid and regain privleges, he additionally sets the process Saved User ID (SUID) to www-data. You can assume that the user www-data has the UID 100 and exists, and that the process initially is executed as the root user.

if (fork() == 0) {
    int socket = socket(":80");
    if (socket == -1) {
       perror("unable to open socket: ");
 	   exit(-1);
    }
    // don't change Real User ID so we know who started the process
    setresuid(-1, 100, 100);
    serve(socket);
}
  1. Dawn claims that an attacker can still open a root shell if there's a vulnerability in serve. Who is correct? Why? If Dawn is correct, what changes would you make to the code to secure it against a privilege escalation attack?
  2. Instead of starting the process as root, Jackson decides he wants to instead use the Linux CAP_NET_BIND_SERVICE capability. If there were to be bug in serve, what can an attacker do that they would not have been able to if the web server were run without any additional capabilities.

Problem 5: Android

In Android, each app runs in a separate process using a separate user id. From a security standpoint, what is the advantage of assigning separate UIDs instead of using the same UID for all apps?


Problem 6: File permissions

After discovering a vulnerability in the passwd utility, the Linux developers have decided that it is too dangerous to conintue to run the utility as root (through setuid). Unfortuantely, there's no Linux capability that lets a process specifically edit /etc/shadow, the file that Linux uses to store password data.

Note: This problem incorrectly stated /etc/passwd instead of /etc/shadow when released. UNIX originally stored password data in /etc/passwd but this was later changed to /etc/shadow. The high-level idea of your solution should not change and we'll accept answers assuming password data is stored in /etc/passwd or /etc/shadow.

  1. The kernel developers have asked you to devise a new mechanism where the passwd command no longer runs as root, but users can only change their own password and can't change any other users' passwords. Your solution can't change the Linux kernel itself (e.g., introduce a new capability), but the developers have created a new service account passwd that you can use. If you change the ownership, permissions, or setuid bit on any files, you should note the new values in your solution.
  2. What's the worst damage that an attacker can do if a new vulnerability were to be found in passwd?
  3. Does changing who runs the passwd utility meaningfully increase the security of the system? Hint: Think about the contents of the /etc/shadow file.

Problem 7: race-conditions

Consider the following code snippet:
  if (!stat("file.dat", buf)) return;   // abort if file exists
  sleep(10);                            // sleep for 10 seconds
  fp = fopen("file.dat", "w" );         // open file for write
  fprintf(fp, "Hello world" );
  close(fp);
  1. Suppose this code is running as a setuid root program. Give an example of how this code can lead to unexpected behavior that could cause a security problem. Hint: try using symbolic links.
  2. Suppose the sleep(10) is removed from the code above. Could the problem you identified in part (a) still occur? Please explain.
  3. How would you fix the code to prevent the problem from part (a)?