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:
- create the /tmp/hosts.deny.$$ file first
- wait for root to overwrite the file
- 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.