OpenSSL被曝出拒绝服务漏洞“HollowByte”,攻击者仅需11字节的ClientHello有效载荷即可迫使服务器预分配大量内存并造成碎片化,最终耗尽内存导致服务崩溃。该漏洞影响Apache、NGINX、Node.js等广泛依赖OpenSSL的软件,已在OpenSSL 4.0.1等版本中修复。
新披露的一个漏洞提醒我们,我们的数字基础设施对基础库的依赖程度有多深。
Okta 红队最近发现了 OpenSSL 中的一个拒绝服务 (DoS) 漏洞“HollowByte”,该漏洞允许远程未经身份验证的攻击者使用仅 11 字节长的有效载荷,强制服务器在任何安全握手开始之前分配不成比例的内存块。
TLS握手以一个封装在记录中的ClientHello消息开始。每个握手消息都包含一个4字节的头部,用于指示传入消息体的大小。
OpenSSL拒绝服务漏洞
旧版本的 OpenSSL 会在任何数据实际到达之前,根据攻击者声明的长度分配接收缓冲区。当恶意 11 字节有效载荷到达时,TLS 状态机读取头部信息,并根据其 3 字节长度声明触发未经验证的预分配:
Read Header → grow_init_buf() → OPENSSL_clear_realloc() → malloc(attacker_size)
由于此时没有进行有效载荷验证,malloc() 函数仅根据不受信任数据包的声明就分配了高达 131 KB 的内存。然后,工作线程会无限期地阻塞,等待永远不会到达的数据。
保持连接打开以耗尽线程是一种经典技巧,类似于 Slowloris。HollowByte 在此基础上增加了一个更糟糕的副作用,其根源在于 glibc 处理内存的方式。
当连接断开时,OpenSSL 会释放缓冲区,但 glibc 不会立即将中小尺寸的分配空间返回给操作系统;它会保留这些空间以供将来可能重用。
攻击者通过发起大量大小随机的连接,阻止内存分配器重用已释放的内存块。堆内存严重碎片化,服务器的常驻内存集大小(RSS)持续增长。
即使攻击者断开连接,服务器仍然占用大量内存;唯一的解决办法是终止该进程。在 NGINX 下测试未打补丁和已打补丁的 OpenSSL 实例,揭示了威胁的严重程度。在 1 GB 内存环境下,未打补丁的服务器在占用 547 MB 冻结且碎片化的内存后,因内存不足而被终止。
在 16 GB RAM 环境下,该攻击锁定了 25% 的系统总内存,同时连接数保持在正常上限以下,这意味着标准的连接限制防御措施无法阻止它。
由于 OpenSSL 的应用非常广泛,因此该缺陷会影响 Web 服务器(Apache、NGINX)、语言运行时(Node.js、Python、Ruby、PHP)和数据库(MySQL、PostgreSQL)。
OpenSSL 通过切换到增量缓冲区增长解决了这个问题,该修复已通过 PR #30792、#30793 和 #30794 合并。该修复程序已在 OpenSSL v4.0.1 中静默发布,并向后移植到 3.6.3、3.5.7、3.4.6 和 3.0.21 版本。
OpenSSL 现在不再直接信任声明的头部大小,而是仅在实际收到字节时才扩展缓冲区,因此空声明不会给服务器带来任何负担。值得注意的是,OpenSSL 将此归类为安全加固修复,而非发布正式的 CVE 漏洞公告。
无论如何,安全团队应优先立即升级其 OpenSSL 软件包,尤其是在面向互联网的服务器上,因为仅靠限制连接数无法抵御这种攻击。
原文始发于微信公众号(安全圈的那点事儿):OpenSSL DoS 漏洞允许远程攻击者使用 11 字节有效载荷耗尽服务器内存
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-


评论