On Jan. 27, Qualys released a security advisory for what it termed the “GHOST” vulnerability. This was a few hours after the vulnerability was mistakenly leaked by a public relations agency on a French mailing list, possibly forcing the company’s hand to release the advisory before it had planned to.
The vulnerability is a buffer overflow vulnerability within the __nss_hostname_digits_dots() function of the GNU C Library (glibc). The buffer overflow can be triggered within the gethostbyname*() functions, which return IPv4 addresses for given Domain Name System hostnames. MITRE assigned this vulnerability with the CVE-2015-0235 identifier. The glibc library defines the system calls for C programs running on Linux-type systems.
Affected Programming Languages
The C programming language first appeared in 1972. It is still widely used today in many types of software, such as operating systems, Web browsers and other programming languages. Some of the programming languages using C as an implementation language include C++, Perl, Python, Java, PHP, Ruby, Rust and Go. These programming languages may also use the vulnerable gethostbyname*() glibc functions. Sucuri first confirmed the vulnerability affected PHP’s gethostbyname() function. It is easy to verify this by using a few simple commands on an unpatched Ubuntu 12.04 machine.
By executing the following proof-of-concept command released by Sucuri, PHP crashes with a segmentation fault — a clear sign the payload corrupted the system’s memory:
$ php -r '$e="0";for($i=0;$i<2500;$i++){$e="0$e";} gethostbyname($e);'
Segmentation fault (core dumped)
To investigate this further, we can run PHP with the payload in a debugger to be able to view the error’s full stack trace:
$ gdb php
(gdb) r -r '$e="0";for($i=0;$i<2500;$i++){$e="0$e";} gethostbyname($e);'
Starting program: /usr/bin/php -r '$e="0";for($i=0;$i<2500;$i++){$e="0$e";} gethostbyname($e);'
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff4274700 (LWP 2204)]
[Thread 0x7ffff4274700 (LWP 2204) exited]
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff5bb1d75 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) bt full
#0 0x00007ffff5bb1d75 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
No symbol table info available.
#1 0x00007ffff5bb2b29 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
No symbol table info available.
#2 0x00000000006ba561 in ?? ()
No symbol table info available.
#3 0x00000000006474f0 in php_request_shutdown ()
No symbol table info available.
#4 0x000000000042baa5 in ?? ()
No symbol table info available.
#5 0x00007ffff5b5476d in __libc_start_main () from /lib/x86_64-linux-gnu/libc.so.6
No symbol table info available.
#6 0x000000000042c9b5 in _start ()
No symbol table info available.
As we can see from the stack trace above the segmentation, fault happened within the libc.so.6 file, the GNU C Library (glibc). This confirms the bug also exists within PHP’s gethostbyname() function, but it does not mean it is necessarily exploitable.
Doing a similar test against the Ruby programming language shows Ruby 2.0.0 correctly validates the length of the hostname:
$ ruby -e "require 'socket'; Socket.gethostbyname('0' * 2500)"
-e:1:in `gethostbyname': hostname too long (2500) (ArgumentError)
from -e:1:in `<main>'
The Python programming language also seems to handle large hostnames correctly:
$ python -c "import socket; print socket.gethostbyname('o' * 2500)"
0.0.0.0
Exploitation
At this time, no exploit has been publicly released for the GHOST vulnerability. According to Qualys, it has a working exploit for the GHOST vulnerability but will only release it once 50 percent of machines have been updated. I suspect there are many skilled people independently working on writing an exploit, and we may see one released before Qualys officially releases its own.
Because PHP’s gethostbyname() function is vulnerable to the GHOST vulnerability, any application written in PHP that uses this function may also be vulnerable. All that is required is for user-controlled input, known as a source, to reach the vulnerable function, known as a sink.
WordPress
According to Matt Mullenweg, 23 percent of the Web runs on the software he founded, WordPress. Although hinted before by Sucuri, Trustwave SpiderLabs successfully showed that the GHOST vulnerability could be triggered within WordPress by a remote unauthenticated attacker.
To do this, the WordPress XML-RPC pingback application programming interface (API) is used to send an overly large hostname, resulting in the process handling the request to crash. This could mean that when someone finally releases an exploit, any Web servers running WordPress may also be exploitable. A Metasploit module has also been released that can check whether a system is vulnerable to the GHOST vulnerability by using the WordPress pingback API.
GHOST Vulnerability Mitigation
I suspect that WordPress will attempt to prevent this vulnerability from being exploited in its latest release. One way of doing this is by ensuring the hostname passed to the pingback API is fewer than 256 bytes long. This would be in accordance with RFC 1123.
It has also been found that there are many popular WordPress plugins that rely on the vulnerable gethostbyname() function. Even if WordPress does release a patch, your installation may still be vulnerable through one of its affected plugins.
If you have not patched your system yet, I would highly recommend doing it as soon as possible. If you are running WordPress, you may also be able to take other mitigating actions. The following are some suggestions:
- Disable the XML-RPC functionality.
- Uninstall unnecessary plugins.
- Keep your plugins updated.
- Keep WordPress updated.
- Install a Web application firewall.
Freelance Security Consultant