Notes - ECS235 - October 22, 2007 Daryl Posnett Janus was developed initially by David Wagner. Tal Garfinkel continued development. Many problems with Janus are related to multi threaded applications. Problems with Janus: 1) Race Conditions -argument race First an incorrect (bad) example as fd is on the stack (call by value) and can't be modified by a malicious thread. int fd; close(fd); Now a slightly better example but still incorrect as the string is not modifiable. open("/etc/passwd"); Finally we have: char filename[] open(filename); This can be affected by time of check/time of use as the attacker can modify filename between checks by Janus and the open call of the o.s. Solutions: 1) Let the kernel copy the argument 2) Make argument read only 3) Prevent shared memory -File system information Processes open files relative to the current working directory. Threads share current directory information so this can be modified (by another thread) between check by Janus and open by O.S. Solution: Make sure that Janus and the kernel see the same file name by breaking the file name into component parts. -Sym link races if /home/foo is mapped to /tmp/foo the attacker can modify the symlink to point to /etc/passwd. Although this is an argument race it is not caught by Janus as the filename is not a string inside the program. Solutions: Prevent following symlink using O.S. flag (NOFOLLOW). This only works for the last element in the path however so there is still a problem if, for example, home is a symlink. 2) Incorrectly replicating the O.S. state. -Data replication Suppose the security policy does not allow binding UDP to port 80. An attacker might use the following: fd = socket(..., TCP, ...) fd2 = socket(...., UDP, ...) close(fd) dup(fd2) find(fd2, 80, ...); Janus tracks O.S. state, however, it does not correctly track the state through the dup call. -Code replication We briefly discussed that file name canonicalisation was an example of incorrect code replication. Solution: Query the O.S. for this data despite the high performance cost. This is a typical cache consistency problem. Detour: IDS Where do we put the monitor? -Assuming that we trust the o.s., we can put the monitor there (Janus). However, if the o.s.has been compromised, i.e. untrusted. -VM? The VM can't do everything that the o.s. monitor can. e.g. can't see system calls. The security policy is specified in terms of system calls. We could let the VM determine state from O.S. memory, but, again we are duplicating state of the O.S. We could place hooks in the O.S. to call the monitor, but, we don't trust the O.S. Solution: We can let the monitor call the O.S. however this changes the O.S. state. To fix this we take a snapshot of the O.S. state, call into it to obtain information, then restore the snapshot. 3) Side effects Janus kills the process on detection of attack. An issue with Janus is that the config files are complicated we discussed the following idea as a potential solution to simplify or eliminate config files. What if we relax confidentiality, that is, we are only concerned with integrity? If we decide that anything can be read but writes cannot be compromised then we can use process virtualization applied to the file system space to provide assurance that the O.S. state is not compromised. Solution : We write a local copy per process. If we use a copy on write approach then we don't need to replicate the entire file system for each process. This is called one-way isolation. At the file system level: -Allow read -Copy on write Issues : How do processes share files? Merging data?