“绕过堆栈保护页”安全漏洞影响多个软件包

Public Date: June 30, 2017, 11:06
已更新 July 6, 2017, 12:01 - English(英语) Japanese
Resolved 状态
Important Impact

红帽产品安全团队已知晓一个会影响到 Linux 系统的安全漏洞,这个安全漏洞被分配了两个 CVE 名称:CVE-2017-1000364(针对于内核)和 CVE-2017-1000366(针对于 glibc)。此问题已在 2017 年 6 月 19 日被公开,它被定级为 Important(重要)

背景信息

Qualys 公布的一条安全公告显示,可以采用一些方法有效地绕过名为“stack guard page(堆栈保护页)”的漏洞防范机制。 在为用户空间二进制代码的堆栈分配内存的方法中存在一个缺陷。如果内存堆(或一个不同的内存区)和堆栈内存区相毗邻,攻击者就可以利用这个漏洞绕过堆栈保护页,造成进程堆栈或毗邻的内存区的受控内存被破坏,进而可以提升攻击者在这个系统中的权限。

什么是堆栈保护页?
堆栈保护页(stack guard page)作为一个防范“堆栈溢出攻击(stack overflow attack)”的机制添加到 Linux 内核中,它主要用来解决 CVE-2010-2240。访问堆栈保护页会触发一个陷阱(trap),因此它就可以作为一个堆栈内存区和进程地址空间中的其他内存区间的一个分隔器,从而使后续的堆栈访问无法影响到与此堆栈毗邻的其他内存空间(或对毗邻内存空间的后续访问不会影响到此堆栈)。
漏洞是什么?

最初,堆栈保护页被设计为后续访问内存的一个保护机制。此安全漏洞的报告方(Qualys)发现,通过一些方法可以在通用二进制代码中重新出现 CVE-2010-2240 中的问题。这些方法没有利用后续堆栈溢出(这会被堆栈保护页防范),而是利用了通用二进制代码中执行的堆栈内存分配的某些结构,“跳过”了堆栈保护页,从而在不会触发无效访问错误的情况下访问到毗邻的内存区。这就导致了堆栈和毗邻的内存区(通常是堆)的“重叠”,从而使堆栈内存访问可以影响到毗邻的堆(或对毗邻堆的访问影响到此堆栈)。

如何解决? 
为了避免堆栈保护页被跳过,每个堆栈分配的原语(primitive)都需要使用堆栈保护间隔的大小作为“颗粒”来实现全新的分配内存探测。使用已存在的 gcc -fstack-check 就应该可以达到这个目的,但是它当前存在一些问题,无法正常工作。在 gcc -fstack-check 存在的问题被解决,以及所有相关的二进制代码被重新构建前,我们可以通过使用特定的内核和 glibc 来解决与所报告的安全漏洞相关的问题:

  • 针对 CVE-2017-1000364 的内核修护程序把堆栈保护间隔大小由一个页增加到 1 MiB,这就使成功利用此安全漏洞进行攻击的难度增大。
  • 针对 CVE-2017-1000366 的 glibc 修护程序会在 AT_SECURE=1 程序中禁用 LD_LIBRARY_PATH。这相当于为内部 DSO 查询路径的构建进行了“输入消毒”,否则这个构建会执行一个带有部分填充的缓冲区的、非常大的 alloca() 。另外,处理 LD_AUDIT、LD_PRELOAD 和 LD_HWCAP_MASK 所执行的堆和堆栈分配的大小也被减少。在以前,它们可以被用来控制堆和堆栈的分配,在应用了这些改变后,这些将变得更加困难。

使用以上解决方案有什么负作用?

在编写此文档时,内核补丁程序中存在一个已知的问题:它会在 /proc/meminfo 中创建相互重叠的值。这个问题不会影响到系统应用的功能,也不会对内核所提供的保护功能造成影响。以后,可能会发布一个补丁程序来解决这个问题。

致谢

红帽借此机会感谢 Qualys Research Labs 报告了这个安全漏洞。

通过这个安全漏洞,攻击者可以提升自己的权限,并可能借此运行恶意代码。

红帽产品安全团队把此安全问题定级为 Important(重要)。    

受影响的产品

以下版本的产品会受到影响:

  • Red Hat Enterprise Linux 5
  • Red Hat Enterprise Linux 6
  • Red Hat Enterprise Linux 7
  • Red Hat Enterprise MRG 2.5
  • Red Hat Virtualization
  • RHEL Atomic Host

诊断您的系统


确定您的系统是否有漏洞

使用以下脚本来检查您的系统是否因为这个安全漏洞而存在安全隐患。 您可以下载 GPG 签名来验证这个脚本的真实性。这个脚本的当前版本是 1.0。

采取行动

我们强烈推荐所有运行受影响产品的红帽用户,在相关的补丁程序可用时尽快对系统进行更新。受影响的软件包详情在以下列出。为了使内核更新起作用,系统需要在更新后重启。

运行 Red Hat Enterprise Linux 7.2 或更新版本的用户可以获得一个 kpatch。如需获得这个 kpatch,请创建一个支持问题单。

如需了解什么是 kpatch,请参阅 Is live kernel patching (kpatch) supported in RHEL 7?


产品软件包公告/更新
Red Hat Enterprise Linux 7内核RHSA-2017:1484
Red Hat Enterprise Linux 7kernel-rt待发布
Red Hat Enterprise Linux 7glibcRHSA-2017:1481
Red Hat Enterprise Linux 7.2 Extended Update Support**内核RHSA-2017:1485
Red Hat Enterprise Linux 7.2 Extended Update Support**glibcRHSA-2017:1479
Red Hat Enterprise Linux 6内核RHSA-2017:1486
Red Hat Enterprise Linux 6glibcRHSA-2017:1480
Red Hat Enterprise Linux 6.7 Extended Update Support**内核RHSA-2017:1487
Red Hat Enterprise Linux 6.7 Extended Update Support**glibcRHSA-2017:1479
Red Hat Enterprise Linux 6.6 Advanced Update Support***内核RHSA-2017:1488
Red Hat Enterprise Linux 6.6 Advanced Update Support***glibcRHSA-2017:1479
Red Hat Enterprise Linux 6.5 Advanced Update Support***内核RHSA-2017:1489
Red Hat Enterprise Linux 6.5 Advanced Update Support***glibcRHSA-2017:1479
Red Hat Enterprise Linux 6.4 Advanced Update Support***内核RHSA-2017:1490
Red Hat Enterprise Linux 6.4 Advanced Update Support***glibcRHSA-2017:1479
Red Hat Enterprise Linux 6.2 Advanced Update Support***内核RHSA-2017:1491
Red Hat Enterprise Linux 5 ELS*内核RHSA-2017:1482
Red Hat Enterprise Linux 5 ELS*glibcRHSA-2017:1479
Red Hat Enterprise Linux 5.9 Advanced Update Support***内核RHSA-2017:1483
Red Hat Enterprise Linux 5.9 Advanced Update Support***glibcRHSA-2017:1479
RHEL Atomic Host内核待发布
Red Hat Enterprise MRG 2kernel-rt待发布
Red Hat Virtualization (RHEV-H/RHV-H)内核待发布


* 为了获得这个补丁程序,需要一个活跃的 ELS 订阅

如果您还没有活跃的 ELS 订阅,请联系红帽的销售人员,或您专门的销售代表。

** 为了获得这个补丁程序,需要一个活跃的 EUS 订阅

如果您还没有活跃的 EUS 订阅,请联系红帽的销售人员,或您专门的销售代表。

什么是 Red Hat Enterprise Linux Extended Update Support 订阅?

*** 为了在 RHEL AUS 中获得这个补丁程序,需要一个活跃的 AUS 订阅

Ansible Playbook

有可用的 Ansible  playbook

playbook 在运行时使用一个名为 HOSTS 的变量来指定主机,它通过以下形式被调用(假设 'hostname' 已在 inventory 文件中定义):

# ansible-playbook -e HOSTS=hostname cve-2017-1000366.yml

这个 playbook 需要 root 权限,因此,如果没有在 inventory 文件中为 'hostname' 定义,您可能需要使用 --become。

Comments