every *2shell, one place
← all bugs

GHOST

aka glibc gethostbyname overflow
Product
GNU glibc
CVE
CVE-2015-0235
Disclosed
2015-01-27
CVSS
—
Auth
pre-auth
CISA KEV
no
Affected
glibc 2.2 through 2.17 (fixed upstream in 2.18 in May 2013, but not backported by long-term distros such as RHEL 5-7, Debian 7, Ubuntu 12.04).
Fixed
glibc 2.18+ and distro backports released January 2015.

Summary

A heap overflow in glibc's gethostbyname*() functions found by Qualys, named GHOST because it is triggered through GetHOSTbyname. Qualys showed remote code execution against the Exim mail server just by sending a crafted HELO hostname.

Root cause

__nss_hostname_digits_dots() miscalculates the buffer size needed when the hostname is an all-digit/dot string, omitting the size of one pointer (sizeof(char *)). This lets up to 4 or 8 bytes overflow a heap buffer, enough for Qualys to overwrite heap metadata and Exim's configuration in memory to get command execution.

Impact

Remote code execution in any network service that passes attacker-supplied names to gethostbyname() (demonstrated against Exim with helo_verify enabled).

Public PoC

#define CANARY "in_the_coal_mine"
struct { char buffer[1024]; char canary[sizeof(CANARY)]; }
  temp = { "buffer", CANARY };

int main(void) {
  struct hostent resbuf; struct hostent *result; int herrno;
  size_t len = sizeof(temp.buffer) - 16*sizeof(unsigned char) - 2*sizeof(char *) - 1;
  char name[sizeof(temp.buffer)];
  memset(name, '0', len); name[len] = '\0';
  gethostbyname_r(name, &resbuf, temp.buffer, sizeof(temp.buffer), &result, &herrno);
  if (strcmp(temp.canary, CANARY) != 0) { puts("vulnerable"); exit(EXIT_SUCCESS); }
  puts("not vulnerable");
}

Source: Qualys advisory - GHOST test program

Detection

ldd --version; distro advisories (RHSA-2015:0090, DSA-3142, USN-2485-1). Qualys published a small C test program (ghost.c) that reports 'vulnerable' or 'not vulnerable'.

Mitigation

Update glibc and restart all services (or reboot) so the patched library is loaded.

References