GnuTLS 修补内存管理不善的错误 – 立即更新!

源节点: 1603833

开源世界中最著名的密码库几乎可以肯定是 OpenSSL的.

首先,它是使用最广泛的一种,以至于大多数平台上的大多数开发人员都听说过它,即使他们没有直接使用它。

其次,它可能是最广为人知的,可悲的是因为一个相当讨厌的错误被称为 心脏出血漏洞 这是八年前发现的。

尽管已及时修补(尽管对于无法或不会快速更新其易受攻击的 OpenSSL 版本的开发人员来说,存在可靠的解决方法),Heartbleed 仍然是一种“展示”错误,尤其是因为它是最早出现的错误之一被其发现者变成了一种激进的公关工具。

Heartbleed 凭借令人印象深刻的名称、专属的徽标和专门的网站,迅速成为全球网络安全公司 超级故事,而且,无论好坏,都与提到这个名字有着千丝万缕的联系 OpenSSL的,就好像这个 bug 的危险在它被从代码中删除之后仍然存在。

超越 OpenSSL 的生活

但是还有其他几个开源加密库与 OpenSSL 一样或代替 OpenSSL 被广泛使用,特别是包括 Mozilla 的 新高中 (短缺 网络安全服务) 和 GNU 项目的 的GnuTLS 图书馆。

碰巧的是,GnuTLS 刚刚修补了一个名为 CVE-2022-2509, 在项目的报告中 安全咨询 GNUTLS-SA-2022-07-07.

此补丁修复了内存管理不善错误,称为 双重自由.

双免解释

简单地说,当程序员要求操作系统分配一块内存来临时使用时,就会产生双重释放漏洞……

……然后交还给它,这样它就可以从借出块列表中删除,以供程序的其他部分使用……

…然后意外地要求系统重新释放相同的内存块。

理想情况下,内存分配软件会检测到该块不再属于“返回”它的程序部分,会发现有问题的块已经被回收,并且不会再次释放它,从而回避再次“释放”它的风险。

温和地处理主动检测到的双重释放是一个棘手的问题。 交回内存的 C 函数原型为 void free(void *ptr); 这样您就可以传递要释放的块的地址,但不要返回返回码。 (交流功能与 void 返回值是其他编程语言所说的 procedure:它为你做了一些事情,但它没有办法报告结果。)因此,即使是精心编写的 C 代码也没有标准的方法来检测出现问题的地方 free(),因此无法通过尝试正常关闭来处理错误。 单方面终止有问题的程序是系统唯一安全的解决方案。

但是如果内存分配器没有意识到(也许是因为同一个块已经被分发给同一个程序的另一个部分,所以它以与以前完全相同的形式回到“外借”列表中) ,那么很可能会发生不好的事情。

值得注意的是,内存管理器可能会不经意和意外地从现在合法使用它的代码中“没收”双重释放块,并将其重新分配给程序的另一部分,甚至可能是攻击者精心计时以利用的恶意代码的管理不善。

因此,您最终可能会使用同一程序的两个部分来操作同一块内存。

程序的一部分假设它可以隐式信任内存内容,因为它认为自己是块的合法“所有者”。

同时,程序的另一部分知道它可以弄乱数据(或者可以被欺骗弄乱它),以便故意使第一部分跳闸。

做错事做对事

具有讽刺意味的是,GnuTLS 的证书验证码中存在 CVE-2022-2509 漏洞。

(具有讽刺意味的是,如果您想知道,通常是不安全的软件,因为它不费心检查可信赖的 TLS 连接,但不受此特定安全漏洞的影响。)

例如,当您访问受 TLS 保护的网站(或其他类型的服务器)时,另一端通常会向您发送一个 Web 证书,该证书断言该服务器确实由您期望的组织拥有和运营。

当然,鉴于任何人都可以以他们喜欢的任何名称创建证书,原始证书本身并不能告诉您太多信息,因此证书所有者通常会由您的浏览器已经信任的公司对其进行数字签名。

在实践中,证书通常由证书签名,而证书又由浏览器信任的证书签名,但最终结果是所谓的 信任链 可以安全地追溯到已安装在所谓的列表中的证书 受信任的权威,也被称为 ,由您的浏览器或操作系统管理。

为了简化和加快验证证书链的过程,许多服务器不只是发送自己的证书并将其留给浏览器以“追逐链”到受信任的根。

服务器通常包括它所依赖的信任链,它只需要构建一次,以便您的浏览器或任何验证证书的软件可以简单地检查该链是否在数字上有效,然后验证最后一个证书在链中匹配一个已经信任的。

在这种情况下,GnuTLS 将正确且安全地验证提供的证书,然后释放刚刚用于存储它的内存块。

但是如果另一端不提供预先生成的证书链,从而让 GnuTLS 自行创建和检查该链,那么 GnuTLS 代码会在启动链之前意外释放用于存储所提供证书的内存 -检查过程…

…然后在检查完成后再次释放它。

这会导致双重释放事故,这可能会导致内存损坏,进而导致程序崩溃。

引导崩溃以植入恶意软件

通常,或者至少经常,崩溃会导致操作系统检测到有问题的程序已经失去对程序执行流程的控制的任性行为——例如,如果程序跳到一个随机内存地址并试图从一个根本没有分配的内存块。

在这种情况下,崩溃会引发系统错误,尽管这种错误可能会被滥用于所谓的 拒绝服务 (DoS)攻击,整个目标只是破坏被攻击的程序,它不会导致 远程代码执行 (RCE),而不是触发不受信任和不需要的软件代码。

但是,只要有攻击者可以根据他们自己提供的不受信任的数据随意引发的程序崩溃,总是存在这样的风险,即崩溃可能会被引导,从而误导崩溃的​​程序,使其跳转到提供的可执行代码由攻击者。

可以想象,攻击者通常可以利用此类漏洞临时或永久植入恶意软件,因为他们可以将不受信任的代码注入您的计算机,而不会产生任何弹出警告,要求首先获得许可。

怎么办呢?

更新到 最新版本 GnuTLS,即 3.7.7 在撰写本文时。

(这个错误显然是在 GnuTLS 3.6.0 中引入的,并且存在于从那时起的每个版本中,直到并包括 3.7.6。)

请注意,许多流行的应用程序和编程工具包都包含或可能构建为使用 GnuTLS,即使您可能不知道它,包括但不限于:FFmpeg、GnuPG、Mplayer、QEMU、Rdesktop、Samba、 Wget、Wireshark 和 Zlib。

许多使用 GnuTLS 的 Linux 或 *BSD 软件包将依赖于由您的发行版本身管理的中央版本,因此请确保在您的发行版提供此版本后立即更新。

快乐修补!


时间戳记:

更多来自 裸体安全