Due Date: M April 4, 2011 at 11:59pm.
In this assignment, you will use an extension to your LSM to collect possible attacks on system call execution and design defenses for these attacks.
The system call interface raises potential vulnerabilities because the system's state is ambiguous to the process. We identify three types of ambiguities: (1) the filesystem namespace's mapping to actual inodes may be ambiguous (e.g., due to links or where files already exist); (2) two system calls may assume that a file name refers to the same file in both invocations, but that mapping may be changed by an adversary between the two calls; and (3) a process may assume that the files accessed at an interface are all integrity-protected when they are not. Despite these types of problems being well-known, programmers continue to make errors that lead to these vulnerabilities. The question we explore in this project is whether mandatory access control and the current system call interface are sufficient to prevent such vulnerabilities in general.
In this project, you are to view the program as a set of interfaces to an opaque program. That is, you can see the interfaces, but not how the program handles the input (i.e., you cannot tell if the program is written correctly). For this program, the task is to identify: (1) an individual program interface that is susceptible to each type of system call attack listed below (one per vulnerability type); (2) a concrete instance of an attack for that particular interface; and (3) a proposed defense for that attack. Defenses may use MAC permissions or the system call interface options only. Changes the program code beyond the system call are not allowed. In this assignment, the more difficult the attack is to defend the better. That is, you may find that there is not an adequate defense for a particular attack (besides coding correctly, which not an option in this case).
The types of attacks to find a solution for are listed below.
Search path vulnerability
Directory traversal ("..")
Untrusted input at unexpected interface
To find the mapping between system calls and files used at those interfaces, you will extend your LSM module (from project 2) in two ways (you may "purchase" my LSM module for 7 points): (1) add labels that identify the objects (files) that may be modified by untrusted parties and (2) log the program locations where such files are accessed. First, you need to build a target.perms for your program that grants access to all the files that it needs. In doing this, you will label inputs as untrusted initially (SAMPLE_UNTRUSTED labels). Second, we will supply you with runtime logging code that you can use to find the specific instructions that your program uses to access this data. These instructions form the attack surface for your target program.
Follow these instructions:
Add program logging: Integrate this code into your sample.c LSM module from Project 2. This new code provides a new function: record_trace, which logs stack traces upon request. Adding this patch to your current code may not be possible as a patch (things may not be in the same format in your LSM module, but you will need to add each of the patched components to your file. If you want you may use my LSM module, but it will "cost" you 7 points to this project.
In addition to integrating this code, you need to modify your module to log (call record_trace) when it accesses an object that can be modified by an attacker. I have included two labels (SAMPLE_UNTRUSTED_READ and SAMPLE_UNTRUSTED_RW) for you to use for these objects. You must determine where to add these calls, and you must determine which files to give these labels. Please add the code to sample.c, but we need to modify the kernel configuration before it will build properly.
Build updated kernel: We need to enable a kernel configuration option CONFIG_STACKTRACE before we can build our modified module. In order to turn this configuration on, a number others must be enabled. If you run 'make menuconfig', you will see that STACKTRACE (search using '/') requires LOCKDEP, DEBUG_KERNEL, TRACE_IRQFLAGS_SUPPORT, STACKTRACE_SUPPORT, LOCKDEP_SUPPORT, and FAULT_INJECTION_DEBUG_FS. Also, you may be able to use my config file or use it as a guide.
Most of these are 'on' by default (LOCKDEP_SUPPORT, STACKTRACE_SUPPORT, TRACE_IRQFLAGS_SUPPORT), but some you will (may) need to go through the configuration and set (LOCKDEP, DEBUG_KERNEL, FAULT_INJECTION_DEBUG_FS). The idea is that for each, you search for their definitions (using '/' in menuconfig) and then set them on. Some you can set directly (FAULT_INJECTION_DEBUG_FS and DEBUG_KERNEL), but LOCKDEP is set indirectly by setting others.
Collect your data: Now, you can build and run your modified sample module. You can label an object (any for testing) to verify that logging is being done. Log entries are printed in a debugfs file. To set this up:
Turn off VDSO: sudo sh -c 'echo 0 > /proc/sys/vm/vdso_enabled'
Add directory /mnt/debug.
Mount it as a debugfs file system: mount -t debugfs none /mnt/debugfs
Start your module
After running your target program (and generating data): cat /mnt/debug/wall_interfaces0 to a file of your choice (may have interfaces1 or more if you have multiple CPUs)
Then, you can remove your module.
Display your entries: If you "cat" your output to a file, we have script that make the entries a little easier to view. Add your target program's path to execs-path.txt and run stack_parse_ip.py (must have python installed). This script will even tell you the exact line number in the source code for your interfaces if you build your target program from source and compile for debugging.
Collect data: You then need to run your program to collect its use of those files (must be labeled SAMPLE_UNTRUSTED) to gather the specific interfaces for your target, using the scripts.
Create your attacks and defenses: For each interface and the objects read, you can then determine which attacks to propose at which interfaces (please justify). The goal is to identify one attack per type (not per interface), but the attacks should be as difficult as possible. The student with the best attack(s) will get a 10 point bonus on this project. For each attack, assess how you would use MAC permissions and/or the system call options to prevent the attack.
Submit the following: (1) your modified sample.c; (2) your target program's target.perms; (3) a description of your runtime test procedure used to study the target program; (4) your set of attacks and defenses and associated interface; and (5) answers to the questions below.
How could you use the SELinux policy to identify the untrusted files on your system?
Why is this runtime logging approach unsuitable for finding a complete attack surface?
Which integrity model do you find most effective for expressing the integrity of your target program given your experiences? Explain.
You are to complete this on your own. Any sharing of code or help during the coding of this project is expressly forbidden. Do not discuss this project with anyone.