Warning message

This translation is outdated. For the most up-to-date information, please refer to the English version.

严重安全漏洞:glibc 里基于栈的缓冲在 getaddrinfo() 里溢出(CVE-2015-7547)

已更新 -

glibc 软件包包含系统上多个程序使用的标准库。为了节省磁盘空间和内存且更易于升级,我们将常用的代码放在同一个地方并在程序间共享。这个软件包包含了链接所有 GNU/Linux 程序的标准的 C 语言库。libresolv 库附带 glibc,它提供转换主机名和 IP 地址的功能。nss_dns 是一个 glibc 组件,它提供使用 libresolv 执行 DNS 查找的命名服务转换(Name Service Switch,NSS)服务。

背景

我们在执行 A/AAAA DNS 查询的代码的 libresolv 里发现了基于栈的缓冲溢出。远程攻击者可以创建特制的 DNS 响应,它会导致 libresolv 崩溃或可能用运行库的用户的权限执行代码。缓冲溢出发生在 libresolv 里的 send_dg(对于 UDP 查询)和 send_vc(对于 TCP 查询)。这个漏洞已经分配为 CVE-2015-7547

除了 Red Hat Enterprise Linux 6.4,用 AF_UNSPEC 地址族调用 getaddrinfo 的应用程序会受到影响,如果使用 AF_INET6 地址族,应用程序也会受到影响。只使用旧的 gethostbyname 函数或 libresolv 函数(如 res_search,非 getaddrinfo)的应用程序则不会受到影响。

这个问题不会影响 Red Hat Enterprise Linux 5 或之前版本附带的 glibc。这个问题只影响 Red Hat Enterprise Linux 6 和 7 附带的 glibc。

影响

Red Hat 产品安全部门已将这个问题评级为 Critical

缓和

在默认的 libresolv 配置里,我们通过在信任网络上使用可信的、兼容协议的 DNS 解析器来减轻基于 UDP 的矢量。兼容的解析器不会产生这种利用漏洞所必需的过大的响应信息,因为在默认情况下,glibc 解析器不会启用 EDNS0 也不会请求大型响应信息。

基于 TCP 的矢量可以用可信网络上的可信递归解析器来减轻,它限制单个 DNS 响应信息的大小为 1023 字节或更少。然而,这样的容量在 DNS 解析器实现了并不常见,因为它违背了 DNS 协议(多数解析器提供的缓冲大小配置选项仅适用于 UDP 而非 TCP)。拒绝 AAAA 响应而不限制 A 响应的大小不会迁移这个漏洞。

禁用受影响的系统上的 IPv6 支持不会减轻这个漏洞的影响,因为即使系统缺乏 IPv6 支持也会执行双重 A/AAAA 查找。

受影响的产品及解决办法

Red Hat Enterprise Linux 6 和 7 附带的所有 glibc 版本都会受到这个漏洞的影响。请参考下表里修复这个漏洞的各自的安全建议:

解决办法

产品 安全建议
Red Hat Enterprise Linux 6 RHSA-2016:0175
Red Hat Enterprise Linux 7 RHSA-2016:0176
Red Hat Enterprise Linux 6.2 Advanced Update Support RHSA-2016:0225
Red Hat Enterprise Linux 6.4 Advanced Update Support RHSA-2016:0225
Red Hat Enterprise Linux 6.5 Advanced Update Support RHSA-2016:0225
Red Hat Enterprise Linux 6.6 Extended Update Support RHSA-2016:0225
Red Hat Enterprise Linux 7.1 Extended Update Support RHSA-2016:0225


应用升级后,您需要重启系统或重启所有受影响的服务:

因为这个漏洞影响了系统上大量的应用程序,我们所推荐的、最安全的确保应用程序更新的 glibc 软件包的方法是重启系统。

如果在应用更新后您无法重启整个系统,请执行下列命令列出仍使用旧的 glibc(in-memory)版本的所有运行的进程(不只限于服务)。

lsof +c0 -d DEL | awk 'NR==1 || /libc-/ {print $2,$1,$4,$NF}' | column -t

从结果列表里,确定面向公众的服务并重启它们。但这个过程只能作为变通办法,Red Hat 也不提供支持服务;在出现问题时,在我们进行故障解除之前,您会被要求重启系统。

常见问题解答

1. SELinux 会阻止这个安全漏洞吗?
合适的 SELinux 策略可以包含

但 DNS 被许多应用程序和系统组件使用,所以 SELinux 策略

2. 可信的 DNS 解析器可以防范这个漏洞吗?
默认的兼容协议的配置的可信的解析器无法减轻这个问题,因为潜在的攻击可以利用符合语法规则的 DNS 响应信息。如果使用受影响的glibc的递归解析器和客户端之间的网络是可信的环境,则把响应接收大小限制为1023比特可以缓和此漏洞。此时,攻击者没有办法欺骗递归解析器的源地址。响应包大小限制需设置在递归解析器生成响应包时,而不是在从网络接收的响应包大小上。此类包大小的限制违反一些DNS相关的服务,包括DNSSEC。除了修改包大小以外,没有其他方法可以让DNS工具发现并且阻止攻击。

3.仅升级面向网络的DNS服务器和递归解析器是否足以解决问题?
不可以,所有主机(服务器和客户端)上的glibc 包都需要被更新。

4.在/etc/resolv.conf 文件中不启用TCP模式,系统仍然受这个漏洞影响吗?
如果响应包大小超过UDP缓存的大小(默认是512字节),解析器会自动切换为TCP。因此,即使没有明确说明启用TCP,系统也暴露在基于TCP的攻击。

5.是否可以避免双重的 A/AAAA DNS 查询?
一些应用有参数把双重的查询AF_UNSPEC)切换 为仅IPv4(AF_INET,A记录)查询或者仅IPv6 (AF_INET6,AAAA 记录)查询。特别的,命令行参数为-4 和 -6。这样的减轻方法可用于单独的应用里。目前,没有整体的把 AF_UNSPEC 查询切换成A记录或者AAAA记录查询的方法。single-request和single-request-reopen参数不提供此功能。

6.是否能够通过/etc/nssswitch.conf 文件减轻攻击?
如果dns服务模块没有被列在/etc/nsswitch.conf 中,系统不会被暴露在外。然而,此时无法使用标准的glibc名字解析功能执行DNS查询。因此,这种减轻策略基本没有益处。

7.如果系统只连接被信任的DNS服务器这个漏洞是否能被减轻?
理论上是可行的。但是一旦系统联网,就可能不小心使用意想不到的名字进行DNS查询,此时有可能从不被信任的DNS服务器(通过已配置的递归解析器)上获取数据。

8. 静态链接的二进制文件会受这个漏洞影响吗?
Red Hat 不支持 glibc 的静态链接。然而,如果客户使用 glibc-static软件包构建了静态链接的应用程序,这些应用程序仍将使用 系统中的nss_dns 和 libresolv,安装已修复的 glibc 软件包将解决这个漏洞问题。

致谢

这个漏洞是 Google 安全团队和 Red Hat 发现的。