In early 2015 we were startled by the "Ghost" vulnerability (CVE-2015-0235). Now, it's time for a similar DNS-based remote code execution vulnerability, split into 2 vulnerabilities: CVE-2015-7547 & CVE-2015-5229.
This vulnerability was discovered by Google’s security team.
What’s the vulnerability?
Red Hat has updated details on the vulnerability.
A stack-based buffer overflow was found in the way the libresolv library
performed dual A/AAAA DNS queries. A remote attacker could create a
specially crafted DNS response which could cause libresolv to crash or,
potentially, execute code with the permissions of the user running the
library. Note: this issue is only exposed when libresolv is called from the
nss_dns NSS service module. (CVE-2015-7547)
It was discovered that the calloc implementation in glibc could return
memory areas which contain non-zero bytes. This could result in unexpected
application behavior such as hangs or crashes. (CVE-2015-5229)
The Ghost vulnerability from early 2015 targeted a different, but also DNS related, vulnerability in glibc.
Proof of concept denial-of-service code is available on Github.
The technical explanation of the exploit
This is best provided by Google’s security team themselves.
glibc reserves 2048 bytes in the stack through alloca() for the DNS answer at _nss_dns_gethostbyname4_r() for hosting responses to a DNS query.
Later on, at send_dg() and send_vc(), if the response is larger than 2048 bytes, a new buffer is allocated from the heap and all the information (buffer pointer, new buffer size and response size) is updated.
Under certain conditions a mismatch between the stack buffer and the new heap allocation will happen. The final effect is that the stack buffer will be used to store the DNS response, even though the response is larger than the stack buffer and a heap buffer was allocated. This behavior leads to the stack buffer overflow.
The vectors to trigger this buffer overflow are very common and can include ssh, sudo, and curl. We are confident that the exploitation vectors are diverse and widespread; we have not attempted to enumerate these vectors further.
Quite a lof systems are potentially vulnerable to this exploit:
- Red Hat Enterprise Linux 6 & CentOS 6: RHSA-2016:0175-1
- Red Hat Enterprise Linux 7 & CentOS 7: RHSA-2016:0176-1
- Debian Squeeze, Wheezy, Jessy & Stretch: CVE-2015-7547
- Ubuntu 12.04 & 14.04: CVE-2015-7547
Even though the actual exploit isn’t easy due to technologies like ASLR (Address space layout randomization), it’s not impossible for this exploit to wreck havoc.
Possible attack vectors
DNS requests, which are the root of the problem in this case, are caused by a lot of seemingly innocent actions on a server. Each of these, if the DNS server responds with a maliciously crafted response, could trigger the exploit.
- SSH logins: reverse DNS lookups are performed on each login
- Mailservers: incoming connections are checked for reverse DNS, DNS blacklists, SPF records are checked, …
- Curl requests on a server: if an application allows user-input that triggers HTTP(s) fetches, this could trigger the exploit. This means ‘pingback’ services like WordPress offers could be vulnerable, too.
Anything else that does DNS requests is a potential target.
Patching your servers
For Red Hat Enterprise Linux, the packages are already available and can be updated via yum.
For CentOS, we’re still awaiting the packages to be synced to all mirrors.
CentOS packages are also available. Everyone can/should update now!.
If the package is available, run the following:
$ yum clean all $ yum update glibc
After the update, you’re best rebooting your system, as a lot of running services (like SSH, mailservers, …) load the gblic libraries on their startup (1).
If that’s not an option, restart every public-facing service after you’ve updated glibc.
For Red Hat Enterprise Linux 7 and CentOS 7, it should be sufficient to reload systemd after the glibc update.
$ systemctl daemon-reexec
On RHEL 6 / CentOS 6, systemd isn’t present.
(1) If applications are statically linked against glibc, they get their ‘own’ copy of the libraries and need to be restarted. If they use shared libraries (which would be the default) they use glibc as is and do not need to be restarted.
If you’re up for it, here are some follow-up links.