• 本文作者: chen, qin
  • |
  • 2016年2月19日
  • |
  • 原创翻译
  • |

Glibc’s DNS getaddrinfo 函数错误(CVE-2015-7547)

文/ 阿尔法实验室 陈钦

A.概述

Glibc被广泛使用在Debian,Red Hat,CentOS以及更多其它 Linux 发行版.漏洞可导致通过恶意构造的DNS包使linux主机或客户端被远程代码执行.

发现的过程如下:Google工程师发现他们的ssh客户端每次试图连接到一个特别的主机时都会段错误,通过深入的分析和与REDHAT工程师的合作.发现了这段2008年引入的错误代码。与2015年的Glibc的GHOST漏洞所在函数gethostbyname不同,这次的问题出在getaddrinfo函数.

topsec

 

B.成因和攻击界面

网络攻击界面由dns解析造成,当调用getaddrinfo查询dns时即可被触发.

在send_dg函数中,recvfrom函数并没有每次都使用创建的缓冲区,size大小的判断错误导致产生栈上的缓冲区溢出漏洞。

修复的版本中将大loop循环中的size每次接受后都更新,解决的相应问题。

recvfrom(pfd[0].fd, (char*)*thisansp, *thisanssizp,

-the recvfrom function uses the size from *thisanssizp which is wrong.

-it can be seen here that thisansp will contain the address of a newly created buffer, but the *thisanssizp, will contain the size from the aligned_resplen, instead of MAXPACKET.

u_char *newp = malloc (MAXPACKET);

if (newp != NULL) {

<*anssizp = MAXPACKET;> //去除

*thisanssizp = MAXPACKET;//添加

 

在gdb下可以控制rip和rsp.

(gdb) x/i $rip
=> 0x7fe156f0ccce <_nss_dns_gethostbyname4_r+398>: req

(gdb) x/a $rsp
0x7fff56fd8a48: 0×4242424242424242 0×4242424242420042

 

测试演示:

测试代码:https://github.com/fjserna/CVE-2015-7547

测试步骤:

1.将测试域名解析指向本机(案例中为google域名,即当调用getaddrinfo查询地址即出发漏掉)

echo “127.0.0.1 bar.foo.google.com”>>/etc/hosts

2.运行攻击脚本。Wget和curl都是受影响程序。

dos

C.修复

具体细节修复可见这里:https://www.gnu.org/software/libc/ .用户可更新到最新版本2.23即可。

笔者的几台服务器也都已经在日常操作中自动升级.

检测机器是否已修复可用如下命令:

ls -l /lib/i386-linux-gnu/libc.so.6

apt-cache show libc6

ldd –version

screenshot

参考:

1.https://www.gnu.org/software/libc/

2.http://news.wooyun.org/6c6e454262397856304f5a7447794631514a4d7864773d3d

3.http://arstechnica.com/security/2016/02/extremely-severe-bug-leaves-dizzying-number-of-apps-and-devices-vulnerable/

Written by chen, qin