CS155: Computer and Network Security

CS155: Homework #1

Spring 2014

Due: Thursday, May 1st

Problem 1: Control hijacking

A proposal for preventing stack buffer overflow attacks is based on making a backup copy of the return address when a function starts. The backup copy is written to a shadow stack located at some random location L on the heap. In the function epilog, just before the function is about to return, the backup copy of the return address is compared to the return address on the stack and if they differ the program exits. Otherwise, the return instruction is executed normally.

(a) Explain why this mechanism can make it harder to mount a stack buffer overflow attack.

(b) Give sample code that is vulnerable to a stack buffer overflow even if this mechanism is used.

Problem 2: 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);
  1. Why were these lines added in iOS5.x? Briefly describe an attack that may be possible without these lines.
  2. In iOS the kernel heap is divided into zones. When the zone allocator is called it allocates a new zone in a random location in kernel space. What security purpose does randomization serve in this context?

Problem 3: Fuzzing

Suppose Microsoft Word worked in the following way:

  • When Word is first installed on the system it generates a private key and public key for a signature system. It contacts the Microsoft servers and sends them its valid activation code (supplied by the user to activate the application) and the public key it just generated. The Microsoft servers respond with a certificate on Word's public key.
  • Whenever Word saves a .docx file it uses its signing key to sign the file. Word then embeds the signature, its pubic key, and its certificate in the file.
  • Whenever Word loads a .docx file it first verifies the signature and certificate in the file. If either of them do not verify, Word refuses to open the file.
Assuming Word works as above, can a third party fuzz test deep parts of the Word application? If so explain what steps are needed to fuzz test Word. If not, explain why not.

Problem 4: Soundness and completeness for static code analysis

In lecture 4, we discussed these two terms briefly:

Soundness: If the analysis tool does not report an error, then the program does not contain any of the kind of errors it is configured to look for.

Completeness: If the program does not contain an error, the analysis tool will not report any errors.

  1. A false alarm occurs when a tool reports an error, but the program the tool is analyzing does not contain an error. Can a tool that reports a false alarm be sound? Complete?
  2. Suppose a company sets up an Android app marketplace for its employees. The company is going to use an analysis tool to check apps for security vulnerabilities before it promotes them to its employees. Which tool property is critical to the company for this purpose: soundness or completeness?
  3. Theoretically, suppose a tool is both sound and complete. When the tool is used to analyze the following code that may contain a vulnerability, what property of the loop determines whether the tool will report an error?
          int main()
            int x = 0;
            while ( x < 10 ) { /* loop while x is less than 10 */
                 ...  /* do some stuff that is secure but might change the value of x  */
            ... /* do something insecure */;

Problem 5: Unix access control

In Unix, every process has a real user id (ruid), an effective user id (euid), and a saved user id (suid). Processes with an euid of 0 have special root privileges.
  1. If a process with user id n forks to create another process, what user id does the new process have? (Hint: it's the same answer for euid, ruid, and suid.)
  2. If a process with euid n makes a setuid system call, what possible euids can the process run with after the call, in each of the following situations:
    1. Before: euid = n > 0, saved user id suid=m and real user id ruid = m. After:?
    2. Before: n=0 After:?
  3. In qmail, most modules run under separate user ids. Similarly, each Android application 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? Explain.
  4. Why should the separate uids be non-zero?
  5. The Android zygote process that creates new processes runs as root. After forking to create a new process, setuid is normally called. Explain why it is important to call setuid? What security purpose does this serve?
  6. In most modern UNIX systems only root is allows to execute the ’chown’ command. You might wonder why: if Alice wants to transfer ownership of her file to Bob, why should this be prohibited? Describe the risks associated with the ’chown’ command and give a practical example of an attack that would have been possible if a user were allowed to arbitrarily change the owner of her files.

Problem 6: TOCTOU

Consider the following code snippet:

  if (access("./file.dat", W_OK) != 0) return;   // check that the real user can write to the file
  sleep(10);                                     // Sleep for 10 seconds.
  fd = open("./file.dat", O_WRONLY);
  write(fd, buf, sizeof(buf));
  1. Suppose this code is running as a setuid root program. The call to access checks that real user who executed the setuid program is allowed to write the file (i.e., access checks the real userid rather than effective userid). Give an example of how this code can lead to unexpected behavior that could cause a security problem. (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)?