ossec/ossec-hids — pull request #290 by jrossi (2014-09-09 02:01:42+00:00)
Title: Fix for CVE-2014-5284 which allows for root escalation via temp files

This includes a fix for the Security Issue identified by Jeff Petersen
of Roka Security LLC. Full details of the issue are attached to this
commit message.

This correct will create the temp file for the hosts deny file in
/var/ossec and will use mktemp where available to create NON-predictable
temp file name. In cases where mktemp is not available we have written a
*BAD* version of mktemp, but should be a little better then just process id.

=============================
Researcher Info
=============================

Jeff Petersen
Roka Security LLC
jpetersen@rokasecurity.com

OSSEC 0.5 (released 11/2005) - 2.8

Affected code: All know version

SHA1 checksum:
1d72a8cd347379ef7a533ba9633231c5bfedfa1a ossec-hids-2.8.tar.gz

OSSEC v2.8 provides a utility named "host-deny.sh" which may be used to
add and remove IP addresses from the /etc/hosts.deny file. For example,
too many unsuccessful attempts to log into the shell as root via sshd
can trigger an automatic block of the offending IP address if the
"active response" system is enabled (the default configuration option
has it enabled). The IP address is then automatically removed after the
block has expired (default is 600 seconds). The logic for the removal
can be found in ossec-hids-2.8/active-response/host-deny.sh and is as
follows:

```
111 # Deleting from hosts.deny
112 elif [ "x${ACTION}" = "xdelete" ]; then
113 lock;
114 if [ "X$UNAME" = "XFreeBSD" ]; then
115 cat /etc/hosts.allow | grep -v "ALL : ${IP} : deny$"> /tmp/hosts.deny.$$
116 mv /tmp/hosts.deny.$$ /etc/hosts.allow
117 else
118 cat /etc/hosts.deny | grep -v "ALL:${IP}$"> /tmp/hosts.deny.$$
119 cat /tmp/hosts.deny.$$ > /etc/hosts.deny
120 rm /tmp/hosts.deny.$$
121 fi
[???]
```
As shown above on lines 115 and 118, a predictable filename is written
to the /tmp directory in the format of "/tmp/hosts.deny." followed by
the process ID. Then the contents of the file are copied back to the
/etc/hosts.deny file. This presents a race condition that any local
user can perform:

1) create the /tmp/hosts.deny.$$ file first
2) wait for root to overwrite the file
3) write your own data to the file before it is copied to /etc/hosts.deny

Though the window of attack is very small, this attack has been 100%
reliable on a test system by monitoring the file via inotify(7).

In addition to the previous information that was sent, it should be
noted that this vulnerability can result in command execution as the
root user via the "twist" option (see hosts_options(5) for more info).

An example from my proof of concept is below.

```
# [user@host ~]$ ./ossec2root.pl
# Creating /tmp/hosts.deny.300 through /tmp/hosts.deny.65536 ...done
# Monitoring /tmp ...
#
# (ssh root@host a few times with an incorrect password)
# (10 minutes pass???)
#
# [user@host ~]$ cat /etc/hosts.deny
# cat /etc/hosts.deny
# sshd : ALL : twist id | wall
#
```
Now whenever anyone connects to sshd on the host, the command "id | wall"
will be executed as root.