regreSSHion:发现 OpenSSH 中的 CVE-2024-6387 - 一个严重漏洞

admin 2024年8月26日23:03:09评论37 views字数 5710阅读19分2秒阅读模式

OpenSSH 是几乎所有类 Unix 和 Linux 系统上默认安装的应用程序,最近由于Qualys发现的一个严重漏洞而受到严格审查。

该漏洞被命名为CVE-2024-6387,并被恰当地命名为“regreSSHion”,它使 Linux 环境面临远程未经身份验证的代码执行风险。该漏洞的影响深远,可能会影响全球无数的服务器和基础设施组件。

在这篇博文中,Splunk 威胁研究团队将剖析 CVE-2024-6387 的技术复杂性,探讨其对受影响系统的潜在影响,并提供检测机会和缓解策略。

关于 CVE-2024-6387 的要点:

  • 漏洞:远程未经身份验证的代码执行(CVE-2024-6387)
  • 受影响版本: OpenSSH 8.5p1 至 9.8p1
  • 架构: 32 位 (x86)、64 位 (amd64) 的主要 PoC 理论上存在漏洞
  • 系统:基于 glibc 的 Linux 发行版
  • 影响:若被利用则可获得根级访问权限
  • 复杂度:高(需要精确计时、多次尝试)
  • 状态:补丁可用(OpenSSH 9.8p1)

技术细节

漏洞

CVE-2024-6387 源自 OpenSSH 中的信号处理程序竞争条件,影响基于 glibc 的 Linux 系统上的 8.5p1 至 9.8p1 版本。该漏洞是旧漏洞 (CVE-2006-5051) 的回归,允许远程攻击者以 root 身份执行任意代码,从而导致整个系统被攻陷。

信号处理程序竞争条件的性质:该漏洞发生在 OpenSSH 服务器 (sshd) 处理 SIGALRM 信号时。在受影响的版本中,SIGALRM 处理程序会调用非异步信号安全的函数,例如 syslog()。这会产生竞争条件,信号处理程序可能会中断代码的关键部分,从而可能导致系统处于不一致状态。攻击者可以利用这种不一致性来操纵内存并执行任意代码。

与旧版 CVE-2006-5051 的关系:有趣的是,此漏洞是 CVE-2006-5051 的回归,该漏洞最初于 2006 年得到修补。旧漏洞也是 OpenSSH 中的信号处理程序竞争条件。实施的修复程序在 2020 年 10 月对 OpenSSH 8.5p1 中的日志记录基础结构进行更改时无意中引入了新的漏洞。

这种回归凸显了长期维护复杂软件系统的安全性所面临的挑战。

利用的具体条件:利用此漏洞需要满足几个条件:

  • 目标必须在基于 glibc 的 Linux 系统上运行易受攻击的 OpenSSH 版本(8.5p1 到 9.8p1)。
  • 攻击者需要精准把握攻击时机,以达到竞争条件窗口。
  • 由于竞争条件的性质,通常需要多次尝试。
  • 该漏洞利用了 glibc 内存分配器的特定行为,使其主要在 Linux 系统上有效。

此漏洞的复杂性意味着,虽然漏洞十分严重,但成功的攻击需要高水平的技能和毅力。尽管如此,以 root 权限执行远程代码的可能性使此漏洞成为所有受影响系统的关键问题。

漏洞利用机制

GitHub上发布的“regreSSHion”概念验证漏洞利用了复杂的竞争条件,需要精确的时间安排,并且可能需要数千次尝试才能成功。让我们分解一下关键方面:

时机和持续时间。漏洞利用的成功取决于能否在非常短的时间内完成。根据 Qualys 的研究:

  • 平均而言,需要大约 10,000 次尝试才能赢得竞争条件。
  • 每 120 秒 (LoginGraceTime) 接受 100 个连接 (MaxStartups),赢得竞争条件大约需要 3-4 小时。
  • 考虑到 ASLR(地址空间布局随机化)绕过,全面利用漏洞平均需要 6-8 小时才能获得远程 root shell。

这个时机至关重要,因为漏洞必须在恰当的时刻中断特定操作才能操纵系统的内存状态。

操作系统和架构。PoC 主要针对 32 位 (x86) 系统,但 64 位 (amd64) 版本的开发工作正在进行中。要点:

  • 该漏洞在基于 Debian 的系统上进行了测试,特别是针对基于 glibc 的 Linux 发行版。
  • 32 位版本利用了 ASLR 实现中的弱点,使得猜测内存地址变得更加容易。
  • 由于 ASLR 更强,64 位版本会更具挑战性,但研究人员认为这是可行的。

概念验证中的关键函数。 让我们来看看概念验证漏洞利用中的两个关键函数。

a)prepare_heap():

此功能类似于设置复杂的多米诺骨牌图案。它以非常特定的方式排列计算机的内存(堆),为漏洞利用创造完美的条件。它的作用如下:

  • 首先,它会创建 10 个小内存块并立即释放它们。这就像在我们的图案的开头放置 10 块小多米诺骨牌。
  • 然后,它会创建 27 对内存块 - 一大(约 8KB),一小(320 字节)。这就像以特定模式设置 27 对大小多米诺骨牌。
  • 它用特定数据填充这些内存块。这就像在多米诺骨牌上标记我们以后会识别的特殊图案一样。

其目标是在计算机内存中创建一个可预测的布局,以便漏洞利用者稍后可以利用它。

void prepare_heap(int sock) { 
    // 数据包 a:分配并释放 tcache 块
    for (int i = 0; i < 10; i++) { 
        unsigned char tcache_chunk[64]; 
        memset(tcache_chunk, 'A', sizeof(tcache_chunk)); 
        send_packet(sock, 5, tcache_chunk, sizeof(tcache_chunk)); 
    } 
   
    // 数据包 b:创建 27 对大(~8KB)和小(320B)孔
    for (int i = 0; i < 27; i++) { 
        unsigned char large_hole[8192]; 
        memset(large_hole, 'B', sizeof(large_hole)); 
        send_packet(sock, 5, large_hole, sizeof(large_hole)); 
 
        unsigned char small_hole[320]; 
        memset(small_hole, 'C', sizeof(small_hole)); 
        send_packet(sock, 5, small_hole, sizeof(small_hole)); 
    } 
    // ...更多堆操作 ... 
}

b)尝试竞争条件():

此函数是实际漏洞利用尝试发生的地方。这就像试图在恰当的时机推倒多米诺骨牌图案以产生特定效果。它的工作原理如下:

  • 它准备了一个特制的数据包(就像一个完美重量的球来推倒我们的多米诺骨牌)。
  • 它将数据包中除最后一个字节之外的所有字节都发送到服务器。这就像让我们的球准备好滚动一样。
  • 然后,它会等待一个非常精确的时刻 - 仅在服务器预计连接超时(SIGALRM)之前 1 毫秒。这个时间至关重要。
  • 就在那一刻,它发送了数据包的最后一个字节。这就像在恰当的时机释放我们的球来推倒多米诺骨牌。
  • 最后,它通过查看服务器的响应来检查漏洞是否成功。

该漏洞的工作原理是试图在特定时刻中断服务器的正常运行。如果时间安排正确,它可以操纵服务器的内存,使攻击者能够以高级(root)权限运行自己的代码。

int attempt_race_condition(int sock, double parsing_time, uint64_t glibc_base) { 
    unsigned char final_packet[MAX_PACKET_SIZE]; 
    create_public_key_packet(final_packet, sizeof(final_packet), glibc_base); 
 
    // 发送除最后一个字节之外的所有字节
    if (send(sock, final_packet, sizeof(final_packet) - 1, 0) < 0) { 
        perror("send final packet"); 
        return 0; 
    } 
 
    // 最后一个字节的精确计时
    struct timespec start, current; 
    clock_gettime(CLOCK_MONOTONIC, &start); 
 
    while (1) { 
        clock_gettime(CLOCK_MONOTONIC, ¤t); 
        double elapsed = (current.tv_sec - start.tv_sec) 
                         + (current.tv_nsec - start.tv_nsec) / 1e9; 
        if (elapsed >= (LOGIN_GRACE_TIME - parsing_time - 0.001)) { // SIGALRM 前 1ms 
            if (send(sock, &final_packet[sizeof(final_packet) - 1], 1, 0) < 0) { 
                perror("发送最后一个字节"); 
                return 0; 
            } 
            break; 
        } 
    } 
    // ... 检查是否成功利用 ... 
}

这个过程非常精确,需要多次尝试才能成功。这就像在坐过山车时穿针引线一样——可能需要尝试数千次才能成功。但如果成功,攻击者就完全控制了服务器。

由于复杂性和精确度要求,这种漏洞在现实条件下很难实现。但是,如果成功,其潜在影响将非常严重,因为它可能允许攻击者在无需任何登录凭据的情况下完全控制系统。因此,系统管理员必须更新其 OpenSSH 安装并实施其他安全措施来防范此类攻击。


捍卫者可以做什么?

Splunk 威胁研究团队开发了一系列 Linux 分析案例,这些案例与后利用行为相关的活动相一致,为防御者提供了针对 Linux 环境的强大检测功能。该系列中有四个关键案例脱颖而出:

  • Linux Living Off The Land,重点关注滥用原生 Linux 二进制文件和实用程序进行恶意用途
  • Linux 权限提升,涵盖攻击者用来提升系统权限的技术
  • Linux 持久性技术,解决用于维持对受感染系统的长期访问的方法
  • Linux Rootkit,它解决了识别复杂 rootkit 的艰巨任务

这些故事涵盖了从异常检测到特定 TTP(策略、技术和程序)的各种检测技术,均符合 MITRE ATT&CK 框架。通过实施这些分析故事,组织可以显著增强其在后利用活动的各个阶段检测、调查和应对针对其 Linux 基础架构的高级威胁的能力。

OpenSSH 清单

为了进行清单搜索并验证 Ubuntu 主机上安装的 OpenSSH 版本是否容易受到特定漏洞或攻击,我们可以创建一个 Splunk 搜索查询。此查询将分析包审计日志以识别我们生产网络中安装的 OpenSSH 版本。

通过利用软件包审计日志,我们可以系统地跟踪和审计 OpenSSH 安装的所有实例。这种方法确保我们全面了解正在使用的软件版本。因此,我们可以快速识别任何容易受到已知漏洞影响的版本。

以下是我们针对该库存创建的简单搜索:

索引 = unix 源 = 包名称 =“*openssh*” 
| rex 字段 =VERSION“^1:(?<ssh_version>d+.d+)” 
| eval ssh_version_number = tonumber(ssh_version)
| evalvulnerable_ssh_version = if(ssh_version_number >= 8.5 AND ssh_version_number < 9.8,“易受攻击的 SSH 版本”,“SSH 版本不易受攻击”)
| 按名称供应商 ssh_version ssh_version_number 版本脆弱性统计
regreSSHion:发现 OpenSSH 中的 CVE-2024-6387 - 一个严重漏洞
img

(Splunk 查询识别 OpenSSH 包,Splunk 2024)

在运行未打补丁版本的主机上,查找 sshd 中“身份验证前超时”日志的增加率。或者,如果网络监控到位,则查找大量新连接,因为攻击需要反复尝试新登录。

sourcetype=journald 或 sourcetype=linux:auth 或 TERM(sshd) 或 TERM(ssh) 
TERM(超时) TERM(身份验证) “身份验证前超时” 
| 主机的时间图计数
regreSSHion:发现 OpenSSH 中的 CVE-2024-6387 - 一个严重漏洞
img

(Splunk 查询识别身份验证前超时,Splunk 2024)

缓解策略

虽然修补是最有效的解决方案,但组织可以采用多种缓解策略来降低 CVE-2024-6387 漏洞的风险:

补丁管理

  • 更新至 OpenSSH 版本 9.8p1 或更高版本,其中包含针对此漏洞的修复。
  • 如果无法立即修补,请实施以下缓解措施以限制暴露。

访问控制

  • 使用防火墙规则将 SSH 访问限制为仅必要的 IP 地址和网络。
  • 实施跳转主机或堡垒服务器以提供额外的访问控制层。

基于主机的入侵防御

  • 部署基于主机的软件包(例如fail2ban)来识别和阻止潜在的攻击尝试。
  • 配置 fail2ban 来监控 SSH 日志并自动阻止表现出可疑行为的 IP 地址。

SSH 配置强化

调整 sshd_config 中的以下设置以限制攻击者的有效性:

  • 登录宽限时间:
  • 将LoginGraceTime设置为0即可避免该漏洞。
  • 警告:这可能会占用系统资源,因为它会消除身份验证尝试的超时时间。
  • MaxStartups:
    • 减少 MaxStartups 以限制未经身份验证的连接数量。
    • 请注意,如果攻击者很激进或者主机上的用户数量很多,则将此值设置得太低可能会阻止合法用户。
    • 示例:MaxStartups 10:30:100(从 10 开始拒绝连接;当有 10-100 个未经身份验证的客户端时拒绝 30% 的连接)
  • 每源最大启动次数:
    • 将其设置为较小的数字,以限制来自单个源 IP 的并发未经身份验证的连接。
    • 这是对 MaxStartups 的补充,使用较低的限制。
    • 示例:PerSourceMaxStartups 5

    网络分段

    • 实施严格的网络分段以限制成功攻击的潜在影响。
    • 使用 VLAN 或网络区域隔离需要 SSH 访问的关键系统。

    多因素身份验证 (MFA): 为 SSH 访问实施 MFA 作为额外的安全层。这并不能阻止初始攻击,但可以限制攻击者利用被盗凭证的能力。

    监控和警报

    • 为 SSH 服务实施强大的日志记录和监控。
    • 设置针对异常 SSH 活动(例如大量失败的登录尝试或具有可疑时间模式的连接)的警报。

    替代访问方法:对于关键系统,请考虑实施不依赖 SSH 的替代安全远程访问方法,例如具有强身份验证的 VPN 解决方案。

    Snort:网络防御者还可以利用基于签名的检测。思科 Talos 发布了 Snort 签名(SID: 63659)来检测 CVE-2024-6387 的利用尝试。这为在其安全基础设施中使用 Snort 的组织提供了额外的保护层。

    请记住,这些缓解措施应是纵深防御策略的一部分。没有任何一项措施是万无一失的,最有效的保护来自于结合多个安全层。定期审查和更新您的安全措施,以应对新出现的威胁和漏洞。

    原文始发于微信公众号(红云谈安全):regreSSHion:发现 OpenSSH 中的 CVE-2024-6387 - 一个严重漏洞

    免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
    • 左青龙
    • 微信扫一扫
    • weinxin
    • 右白虎
    • 微信扫一扫
    • weinxin
    admin
    • 本文由 发表于 2024年8月26日23:03:09
    • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                     regreSSHion:发现 OpenSSH 中的 CVE-2024-6387 - 一个严重漏洞https://cn-sec.com/archives/3098719.html
                    免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

    发表评论

    匿名网友 填写信息