1. 概述

Linux系统中的GNU C库(glibc)被爆出存在一个缓冲区溢出漏洞,可能导致本地及远程执行任意代码。该漏洞是Qualys公司的研究人员在对glibc做代码审计的过程中发现的。由于漏洞可以通过glibc中的 gethostbyname*()函数来利用,所以被命名为Ghost漏洞,中文名字叫幽灵漏洞。这个漏洞影响当前大部分的linux系统。

2. 漏洞编号

CVE-2015-0235

3. 影响范围

Glibc<=2.17

漏洞从2000年发布glibc-2.2版本中就存在,到2013年5月份21日得到了修补(在2.17至2.18之间发行的版本),但是由于开发者并未将其定义为安全漏洞,导致系统中自带的稳定发行版本并未得到及时的升级。

4. 详细信息

4.1  漏洞详情

漏洞存在于glibc库__nss_hostname_digits_dots函数中,该函数用于校验主机名是否IPv4或IPv6地址,如果是则跳过DNS查询以加快程序的运行速度。__nss_hostname_digits_dots函数中定义了HOST_ADDR,h_addr_ptrs,h_alias_ptr ,和hostname四个实体的存储指针,但是在计算存储缓冲区大小时仅计算了HOST_ADDR,h_addr_ptrs和name(hostname)漏掉了计算h_alias_ptr的大小,这导致之后的strcpy(hostname,name)操作可能存在缓冲溢出的可能。这个漏洞可以通过glibc库中的gethostbyname *()函数来触发。由于能用的缓冲溢出参数为hostname,导致缓冲区能被覆盖的位数为32位系统上4个字节,64位系统8个字节,并且相关参数需要满足如下条件:

  1. 它的第一个字符必须是数字。
  2. 它的最后一个字符不能是点 “.”。
  3. 它必须只包含数字和点。
  4. 它必须足够长以溢出缓冲区。例如,非重入的gethostbyname *()函数最开始就会通过调用malloc (1024)来分配自己的缓冲区 (申请 “1 KB”) 。
  5. 地址必须成功地解析为IPv4地址或作为inet_pton IPv6地址()。

4.2  验证方法

方法一:您可以通过如下命令来查看系统上的glibc版本:

ldd –version

方法二:

Qualys公司提供如下的测试程序来检查系统是否存在漏洞:

Ghost.c程序

#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’;

  retval = gethostbyname_r(name, &resbuf, temp.buffer, sizeof(temp.buffer), &result, &herrno);

  if (strcmp(temp.canary, CANARY) != 0) {
    puts(“vulnerable”);
    exit(EXIT_SUCCESS);
  }
  if (retval == ERANGE) {
    puts(“not vulnerable”);
    exit(EXIT_SUCCESS);
  }
  puts(“should not happen”);
  exit(EXIT_FAILURE);
}

将上述程序保存为ghost.c并执行下列命令:

gcc ghost.c –o ghost

./ghost

如果运行后显示

Vulnerable (表示存在漏洞)

Not vulnerable (表示不存在漏洞)

 

4.3  风险评估

系统中有诸多的服务调用了glibc库中的gethostbyname *()函数,由于漏洞利用有诸多的限制,并不是所有调用了这些函数的服务(如ping、arping 、mount.nfs、mtr)都可以利用,但是依然有部分的服务(如clockdiff、procmail、ms-dns、pppd等)可以被本地及远程利用。

目前Qualys公司已经实现了对Exim SMTP邮件服务器的远程攻击,只需向服务器发送一封特制的电子邮件就行!

 

5. 安全建议

5.1  补丁更新

升级系统上glibc库版本,方法如下:

Readhat/Centos系统执行如下命令

yum update glibc

Debian/ubuntu系统执行如下命令

apt-get update glibc

由于glibc是众多服务的基础支持库,在更新glibc后需要重新启动才能保证相关服务的正常运行,你可以通过重新启动系统来保证相关服务正常运行,如果您的系统无法重启,你可以通过下面的命令来确认需要glibc库支持服务,并逐一重启这些服务,命令如下:

lsof | grep libc | awk ‘{print $1}’ | sort | uniq

5.2  临时解决办法

暂无临时解决办法

6. 参考信息

 

PDF版下载查看