An update on GHOST

Picked up from the Openwall advisory and nicely formulated into coherent and easy to understand paragraphs by Robert Graham over at erratasec it appears that it is not as vulnerable as it seems.

Most things aren’t vulnerable. Modern software uses getaddrinfo() instead. Software that uses gethostbyname() often does so in a way that can’t be exploited, such as checking inet_addr() first. Therefore, even though software uses the vulnerable function doesn’t mean it’s actually vulnerable.

 

Most vulnerable things aren’t exploitable. This bug is hard to exploit, only overwriting a few bytes. Most of the time, hackers will only be able to crash a program, not gain code execution.

 

Many exploits are local-only. It needs a domain-name of a thousand zeroes. The advisory identified many SUID programs (which give root when exploited) that accept such names on the command-line. However, it’s really hard to generate such names remotely, especially for servers.

 

Is this another Heartbleed? Maybe, but even Heartbleed wasn’t a Heartbleed. This class of bugs (Heartbleed, Shellshock, Ghost) are hard to exploit. The reason we care is because they are pervasive, in old software often going back for more than a decade, in components used by other software, and impossible to stamp out completely. With that said, hackers are far more likely to be able to exploit Shellshock and Heartbleed than Ghost. This can change quickly, though, if hackers release exploits.

 

Should I panic? No. This is a chronic bug that’ll annoy you over the next several years, but not something terribly exploitable that you need to rush to fix right now.

 

Beware dynamic and statically linked libraries. Most software dynamically links glibc, which means you update it once, and it fixes all software (after a reboot). However, some software links statically, using it’s own private copy of glibc instead of the system copy. This software needs to be updated individually.

 

There’s no easy way to scan for it. You could scan for bugs like Heartbleed quickly, because they were remote facing. Since this bug isn’t, it’d be hard to scan for. Right now, about the only practical thing to scan for would be Exim on port 25. Robust vulnerability scanners will often miss vulnerable systems, either because they can’t log on locally, or because while they can check for dynamic glibc libraries, they can’t find static ones. This makes this bug hard to eradicate — but luckily it’s not terribly exploitable (as mentioned above).

 

You probably have to reboot. This post is a great discussion about the real-world difficulties of patching. The message is that restarting services may not be enough — you may need to reboot.

 

You can run a quick script to check for vulnerability. In the advisory, and described here, there is a quick program you can run to check if the dynamic glibc library is vulnerable. It’s probably something good to add to a regression suite. Over time, you’ll be re-deploying old VM images, for example, that will still be vulnerable. Therefore, you’ll need to keep re-checking for this bug over and over again.

 

It’s a Vulnerability-of-Things. A year after Heartbleed, over 200,000 web servers are still vulnerable to it. That’s because they aren’t traditional web-servers, but web interfaces built into devices and appliances — “things”. In the Internet-of-Things (IoT), things tend not to be patched, and will remain vulnerable for years.

 

This bug doesn’t bypass ASLR or NX. Qualys was able to exploit this bug in Exim, despite ASLR and NX. This is a property of Exim, not GHOST. Somewhere in Exim is the ability to run an arbitrary command-line string. That’s the code being executed, not native x86 code that you’d expect from the typical buffer-overflow, so NX bit doesn’t apply. This vuln reaches the strings Exim produces in response, so the hacker can find where the “run” command is, thus defeating ASLR.

 

I ain’t afraid of no GHOST (CVE-2015-0235)

Ghost

 

The first big vulnerability of this year is out and what is it’s name? GHOST! Discovered by Qualys it is exploiting a serious weakness in the glibc library which then allows a Threat agent to compromise a system and gain full remote access to the target without any prior knowledge of system credentials.

Qualys have worked closely with Linux distribution vendors and have released the advisory in the link above yesterday. Patches are available for all distributions as of yesterday the 27th of January.

This vulnerability actually goes back as far as glibc-2.2 which was released on November 10, 2000. Yet another OLD vulnerability which is 15 years old. Once the automated scripts start to scan you better make sure that you are patched. It is only a matter of time really.

So what is GHOST?

It’s a ‘buffer overflow’ bug which affects the gethostbyname() and gethostbyname2() function calls in the glibc library. This then allows the Threat agent to make an application call to either of these functions and execute arbitrary code with the permissions of the user running the application.

Why is it called GHOST?

Nobody is going to call it CVE-2015-0235 are they? Well I might, but most people outside of our world may not understand so by giving it a sexy name and nice logo a new media friendly vulnerability is born. Oh and the vulnerability can be triggered by the GetHOST functions, drop the “et” and that leaves.. yep, GHOST!

How does it work?

Simply put, in order to exploit this the gethostbyname() function calls which are used for resolving DNS have a buffer overflow triggered by supplying an invalid hostname argument to an application that performs a DNS resolution.

What now?

Remediate and make sure all your systems are up to date in order to mitigate this Threat to your network.

We shouldn’t be using gethostbyname() anyway!

gethostbyname() is a Sockets API function from the early 1980’s and getaddrinfo() should be used instead as put by Robert Graham in the link above.

Testing if your RHEL system is vulnerable or not can be checked with the following script:

#!/bin/bash
# rhel-GHOST-test.sh –  GHOST vulnerability tester. Only for CentOS/RHEL based servers.  #
# Credit : Red Hat, Inc – https://access.redhat.com/labs/ghost/ #
vercomp () {
   if [[ $1 == $2 ]]
   then
       return 0
   fi
   local IFS=.
   local i ver1=($1) ver2=($2)
   # fill empty fields in ver1 with zeros
   for ((i=${#ver1[@]}; i<${#ver2[@]}; i++))
   do
       ver1[i]=0
   done
   for ((i=0; i<${#ver1[@]}; i++))
   do
       if [[ -z ${ver2[i]} ]]
       then
           # fill empty fields in ver2 with zeros
           ver2[i]=0
       fi
       if ((10#${ver1[i]} > 10#${ver2[i]}))
       then
           return 1
       fi
       if ((10#${ver1[i]} < 10#${ver2[i]}))
       then
           return 2
       fi
   done
   return 0
}

glibc_vulnerable_version=2.17
glibc_vulnerable_revision=54
glibc_vulnerable_version2=2.5
glibc_vulnerable_revision2=122
glibc_vulnerable_version3=2.12
glibc_vulnerable_revision3=148
echo “Vulnerable glibc version <=” $glibc_vulnerable_version“-“$glibc_vulnerable_revision
echo “Vulnerable glibc version <=” $glibc_vulnerable_version2“-“$glibc_vulnerable_revision2
echo “Vulnerable glibc version <=” $glibc_vulnerable_version3“-1.”$glibc_vulnerable_revision3

glibc_version=$(rpm -q glibc | awk -F“[-.]” ‘{print $2″.”$3}’ | sort -u)
if [[ $glibc_version == $glibc_vulnerable_version3 ]]
then
   glibc_revision=$(rpm -q glibc | awk -F“[-.]” ‘{print $5}’ | sort -u)
else
   glibc_revision=$(rpm -q glibc | awk -F“[-.]” ‘{print $4}’ | sort -u)
fi
echo “Detected glibc version” $glibc_version” revision “$glibc_revision

vulnerable_text=$“This system is vulnerable to CVE-2015-0235. <https://access.redhat.com/security/cve/CVE-2015-0235>
Please refer to <https://access.redhat.com/articles/1332213> for remediation steps”

if [[ $glibc_version == $glibc_vulnerable_version ]]
then
   vercomp $glibc_vulnerable_revision $glibc_revision
elif [[ $glibc_version == $glibc_vulnerable_version2 ]]
then
   vercomp $glibc_vulnerable_revision2 $glibc_revision
elif [[ $glibc_version == $glibc_vulnerable_version3 ]]
then
   vercomp $glibc_vulnerable_revision3 $glibc_revision
else
   vercomp $glibc_vulnerable_version $glibc_version
fi

case $? in
   0) echo “$vulnerable_text”;;
   1) echo “$vulnerable_text”;;
   2) echo “Not Vulnerable.”;;
esac

If vulnerable you will then see the following output below:

Testing_script

 

Checking to see what applications or packages depend upon the vulnerable glibc can be checked with the following command:

lsof | grep libc | awk '{print $1}' | sort | uniq

Check to see if you are running the correct version of glibc:

ldd –version

References:

Qualys Advisory:

https://community.qualys.com/blogs/laws-of-vulnerabilities/2015/01/27/the-ghost-vulnerability

Test your system:

http://www.cyberciti.biz/faq/cve-2015-0235-patch-ghost-on-debian-ubuntu-fedora-centos-rhel-linux/

RHEL (Patching Information and test scripts):

https://access.redhat.com/articles/1332213

US-Cert:

https://www.us-cert.gov/ncas/current-activity/2015/01/27/Linux-Ghost-Remote-Code-Execution-Vulnerability

ErrataSecurity:

http://blog.erratasec.com/