我们的 AI 引擎 Neutron 在加州大学伯克利分校的 CyberGym 基准测试中取得了 97.1% 的成绩。 了解更多

深度解析

深度解析

GoAhead:mTLS 接受已撤销的客户端证书(CVE-2026-115881)

GoAhead 加载了证书撤销列表却从不检查,已撤销的客户端证书因此通过 mTLS;已在 6.1.1 中修复,该版本于 8 月 2 日交付设备制造商。

要点速览

GoAhead 是一款嵌入式 Web 服务器,其制造商称其运行于数亿台设备中,它却默默忽略自己被配置为强制执行的证书撤销列表。

  • GoAhead 的 OpenSSL TLS 后端把配置的 CRL 加载进证书存储,但从不设置 X509_V_FLAG_CRL_CHECK,即 OpenSSL 在查阅该列表之前要求的标志。一个已撤销的客户端证书就像有效一样完成 mTLS 握手。CVE-2026-115881,CVSS v3.1 9.1(CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N),由 EmbedThis 评分;影响 GoAhead 3.4.5 至 6.1.0。
  • 同一份分析还伴随另外两个 TLS 漏洞。在 LibreSSL 传统验证器的构建上,关闭颁发者检查时超过 10 份证书上限的链被接受(CVE-2026-115884,7.4)。
  • 在 Mbed TLS 构建上,一个字节的 Diffie-Hellman 参数使被动观察者能解密 TLS 1.2 DHE_RSA 会话(5.9,无 CVE)。
  • 6.1.1 版本还修复了一个登录绕过:HTTP Basic 和表单认证对 Blowfish 格式哈希的用户接受任意密码(CVE-2026-115888,9.8,仅 6.1.0)。
  • GoAhead 6.1.1 于 2026 年 8 月 2 日交付设备制造商,修复了上述全部问题;其十一份公告于 10 月 12 日发布。截至 10 月 27 日没有攻击报告,是否有制造商已经交付修复也不得而知。
  • 设备所有者只有在制造商发布固件更新时才能获得修复。在此之前:识别您的 GoAhead 设备,并在受影响的构建上把管理访问限制在受信任的网络内。

我是否受影响?

暴露取决于 TLS 后端和编译进设备的设置,而所有者无法从外部读取。如果以下条件全部成立,您就受 CRL 漏洞影响:

  • 固件内嵌 GoAhead 3.4.5 至 6.1.0,使用 OpenSSL 后端构建(ME_COM_OPENSSL=1,项目的默认且首选后端)。Mbed TLS 构建不受影响,它们通过单独的代码路径检查撤销。
  • 启用了 mTLS:ME_GOAHEAD_SSL_VERIFY_PEER=1、受信任的 CA 捆绑包(ME_GOAHEAD_SSL_AUTHORITY)、颁发者验证(ME_GOAHEAD_SSL_VERIFY_ISSUER=1)和已配置的撤销列表(ME_GOAHEAD_SSL_REVOKE)。
  • 运维者依赖 CRL 拒绝已撤销的设备,这正是配置它的全部意义。
TLS 构建与漏洞 受影响版本 所需配置 修复
OpenSSL 后端,CRL 未强制(CVE-2026-115881,9.1) 3.4.5 至 6.1.0 启用颁发者验证并配置了 CRL 的 mTLS 6.1.1;公告中无临时选项
LibreSSL 传统验证器,链深度绕过(CVE-2026-115884,7.4) 6.1.0 及更早,基于 LibreSSL 3.2.x 或 3.3.2-3.3.6 VERIFY_PEER=1,VERIFY_ISSUER=0 6.1.1;或启用 VERIFY_ISSUER=1 并配受信任 CA 捆绑包,或使用 OpenSSL 或 LibreSSL 4.x
Mbed TLS,DH 参数截断(5.9,无 CVE) 4.0.2 至 6.1.0 与接受损坏参数的客户端协商出 TLS 1.2 DHE_RSA 6.1.1;或禁用有限域 DHE 套件,或使用 OpenSSL 后端
BF1 密码检查绕过(CVE-2026-115888,9.8) 仅 6.1.0 HTTP Basic 或表单认证,一个密码以 BF1 格式存储的已知用户名 6.1.1

要找出您环境中的 GoAhead 服务器,请使用 FoxIO 为 GoAhead 6.1.x 发布的 JA4Scan-TLS 指纹:

TLS 后端 库版本 JA4Scan-TLS 指纹
OpenSSL 3.6.2 03100h0s00sn_1fe27f6025fb_d06dc4648d2f_sr00ss537461
LibreSSL 3.3.6 03100h0s00s0_9d52559f55bc_c64486648d2f_sr00sc24603c
LibreSSL 4.3.1 03100h0r00s0_9d52559f55bc_c64486206461_sr00scc98ba1

匹配表明是这些库版本上的 GoAhead 6.1.x;不匹配并不能排除更早的 GoAhead 版本或其他构建。

对于 Mbed TLS 的 DH 漏洞,检查您的 TLS 会话日志(JA4S)是否包含任何 DHE_RSA 套件。FoxIO 的示例是 t120100_009f_1ca028f07214;下面的命令匹配其分析中列出的 25 个 DHE_RSA 套件代码,不区分大小写:

# Find DHE_RSA handshakes against a host in JA4S session records
grep -iE "_(001[456]|003[39]|0045|006[7b]|0088|009[aef]|00be|00c4|c04[45]|c05[23]|c07[cd]|c09[ef]|c0a[23]|ccaa)_" ja4s.log

对于您拥有或自行构建的固件,权威的检查是固件的构建配置和其中的 GoAhead 版本,而不是外部视图。

如何修复?

升级到 GoAhead 6.1.1,根据其发布说明,它修复全部十一份公告,且没有遗留的 Critical 或 High 发现。设备制造商针对它重新构建固件并交付更新;所有者只能通过该固件更新获得。升级后,EmbedThis 建议结束活动会话或重启服务器,并更改 BF1 用户的密码。

如果尚无法重新构建,每个漏洞都有部分临时措施:

  • 对于 LibreSSL 链深度漏洞,启用颁发者验证(ME_GOAHEAD_SSL_VERIFY_ISSUER=1)并配受信任的 CA 捆绑包,或使用 OpenSSL 或 LibreSSL 4.x 构建。
  • 对于 Mbed TLS 的 DH 漏洞,禁用有限域 DHE 套件,只协商 ECDHE 和 TLS 1.3,或切换到 OpenSSL 后端。
  • 对于 CRL 漏洞,公告中没有临时选项:在重新构建之前,把每个以前受信任、现已撤销的设备凭据视为仍然有效,并在网络层通过限制可以访问管理界面的来源来补偿。
  • 对于 BF1 登录绕过,攻击者只需要一个有效用户名:尽可能把 BF1 格式的密码改为其他格式,并监视这些用户的认证日志。

根本原因是什么?

三个 TLS 漏洞都是集成缺陷:GoAhead 以一种看起来已配置、实际未强制的方式调用 TLS 库的 API。

CRL 漏洞(CVE-2026-115881)。 在 src/openssl.c 的 sslOpen() 中,GoAhead 把配置的撤销列表加载进 OpenSSL 证书存储:

if (ME_GOAHEAD_SSL_REVOKE && *ME_GOAHEAD_SSL_REVOKE) {
    store = SSL_CTX_get_cert_store(sslctx);
    if (!X509_STORE_load_locations(store, ME_GOAHEAD_SSL_REVOKE, 0)) {
        error("Cannot load certificate revoke list: %s", ME_GOAHEAD_SSL_REVOKE);
        sslClose();
        return -1;
    }
}

X509_STORE_load_locations() 成功返回,启动时不报任何错误,因此配置了 CRL 的运维者有充分理由相信撤销已生效。但 OpenSSL 要求先设置 X509_V_FLAG_CRL_CHECK 标志,其 check_revocation() 才会查阅列表,而 GoAhead 从不设置它。没有该标志,OpenSSL 自己的检查在查看列表之前就返回成功:

// OpenSSL 3.6.2 crypto/x509/x509_vfy.c, check_revocation()
int crl_check_enabled = (ctx->param->flags & X509_V_FLAG_CRL_CHECK) != 0;
...
if (!crl_check_enabled && !ocsp_check_enabled)
    return 1;

FoxIO 在 OpenSSL 3.6.2 的 GoAhead 6.1.0 上演示了结果:一份已撤销、CA 签名的客户端证书在开启颁发者验证的情况下完成了 mTLS 握手,验证回调在整个链上报告错误 0。

Mbed TLS 的 DH 漏洞。 在 src/mbedtls.c 中,GoAhead 配置 RFC 3526 的 2048 位 Diffie-Hellman 组,却把生成元的长度当作模的长度传入:

cuchar dhm_p[] = MBEDTLS_DHM_RFC3526_MODP_2048_P_BIN;  // 256 bytes
cuchar dhm_g[] = MBEDTLS_DHM_RFC3526_MODP_2048_G_BIN; // 1 byte: 0x02
...
if ((rc = mbedtls_ssl_conf_dh_param_bin(conf, dhm_p, sizeof(dhm_g), dhm_g, sizeof(dhm_g))) < 0) {

sizeof(dhm_g) 只有一个字节,因此 Mbed TLS 只读取模的第一个字节 0xFF。ServerKeyExchange 宣告一个值为 255 的单字节 DH 参数。共享秘密只有八种可能取值,观察者可以对录制的流量逐一尝试;FoxIO 在五次尝试后复现了共享秘密,并在带外解密了会话。这个笔误于 2018 年迁移到二进制参数 API 期间进入,并在 2024 年 4 月的 TLS 重构中幸存。测试的 OpenSSL 客户端以 DH_check_params_ex: modulus too small 拒绝了这些参数;没有最小尺寸检查的宽松客户端接受它们。

LibreSSL 的链深度漏洞(CVE-2026-115884)。 GoAhead 用 SSL_CTX_set_verify_depth() 设置 10 份证书的上限,其验证回调只在验证器尚未报告其他错误时才赋予超深错误:

// src/openssl.c
if (ok && VERIFY_DEPTH < depth) {
    if (error == 0) {
        error = X509_V_ERR_CERT_CHAIN_TOO_LONG;
    }
}

回调拒绝错误 22 CERT_CHAIN_TOO_LONG,但在颁发者检查被禁用时容忍错误 20 UNABLE_TO_GET_ISSUER_CERT_LOCALLY。LibreSSL 3.2.x 和 3.3.2-3.3.6 的传统验证器停止构建超深链而不记录深度错误,转而报告被容忍的错误 20。在 LibreSSL 3.3.6 的 GoAhead 6.1.0 上,一条根植于攻击者控制的自签名 CA 的 17 份证书链完成了握手并获得 HTTP 200;同一源码在 LibreSSL 4.3.1 下报告错误 22 并被拒绝。

BF1 登录绕过(CVE-2026-115888),同一版本中修复的伴生缺陷。 在 websVerifyPasswordFromFile() 中,BF1 分支正确计算 bcrypt 结果,存入局部变量,然后用存储的哈希覆盖提交的凭据,使函数共享的常数时间比较器把存储的哈希与自身比较。对于密码以较新的 Blowfish(BF1:)格式存储的用户,任意密码都被接受;表单登录是 GoAhead 内置管理页面的推荐方案和默认值。

如何被利用?

CRL 漏洞不需要任何新工具:攻击者出示一份有效签发、现已撤销的证书,例如被盗、退役或已失陷设备的凭据,并以该身份完成 mTLS 握手。攻击本身不可见,因为服务器自己的验证报告成功。

Mbed TLS 漏洞是被动的。录下了客户端接受单字节参数的 TLS 1.2 DHE_RSA 会话的观察者,对录制的握手和应用记录尝试八种可能的共享秘密值,找出能解密的那一个并读取会话。捕获之后不需要与服务器交互。

LibreSSL 漏洞需要一条伪造的证书链:超过 10 份证书,根植于任何位置,呈现给要求客户端证书且关闭颁发者检查的构建。该链被当作已认证的客户端接受。

BF1 绕过只需要一个已知或猜中的 BF1 格式密码用户的用户名和任意密码字符串,作用于 Basic 认证的 URL 或表单登录端点。

攻击链如何展开?

CRL 漏洞,从已撤销的设备凭据到获得授权的访问,共四步:

flowchart LR A["攻击者出示已撤销的
客户端证书"] --> B["GoAhead 启动时把 CRL
加载进 OpenSSL 存储"] B --> C["X509_V_FLAG_CRL_CHECK
从未被设置"] C --> D["check_revocation() 不读列表
就返回成功"] D --> E["mTLS 握手以已撤销的
身份完成"] style C fill:#f8d7da

攻击者能做什么?

CRL 漏洞恢复已撤销设备凭据原本享有的一切访问权限:该证书保护的管理页面、API 或设备控制。对于有意执行撤销的部署(例如设备被盗或密钥泄露之后),它的影响最大,而且缺口在服务器上不可见,因为日志记录的是一次成功验证。

Mbed TLS 漏洞使录制的会话可读,包括其中发送的凭据和命令,但仅当客户端接受了损坏的参数:主流客户端拒绝单字节模数,永远不会完成这样的会话。没有最小尺寸检查的定制和嵌入式客户端是暴露群体。ECDHE 和 TLS 1.3 会话不受影响。

LibreSSL 漏洞在完全没有任何受信任密钥的情况下把攻击者认证为客户端,但只在所列的传统 LibreSSL 构建且关闭颁发者检查时发生,该配置本来就已接受自签名客户端;要求受信任客户端 CA 的部署会拒绝它。

BF1 绕过让攻击者以目标用户的权限登录设备管理界面。它只影响 2025 年 11 月 3 日发布的 GoAhead 6.1.0,且只影响密码被迁移到 BF1 格式的用户。

修复为什么有效?

CRL 和 DH 漏洞的修复都是单行更正,6.1.1 的每项修复都完全关闭其漏洞而不是收窄它。对于 CRL 漏洞,加载列表之后立即给存储设置标志:

     if (!X509_STORE_load_locations(store, ME_GOAHEAD_SSL_REVOKE, 0)) {
         error("Cannot load certificate revoke list: %s", ME_GOAHEAD_SSL_REVOKE);
         sslClose();
         return -1;
     }
+    /*
+        Enable CRL checking on the leaf certificate. Without this flag OpenSSL loads the CRL but
+        never consults it, silently accepting revoked client certificates.
+     */
+    X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK);

对于 DH 漏洞,模的长度现在是模本身的长度:

- if ((rc = mbedtls_ssl_conf_dh_param_bin(conf, dhm_p, sizeof(dhm_g), dhm_g, sizeof(dhm_g))) < 0) {
+ if ((rc = mbedtls_ssl_conf_dh_param_bin(conf, dhm_p, sizeof(dhm_p), dhm_g, sizeof(dhm_g))) < 0) {

完整传输 2048 位模后,共享秘密不再是八个候选之一,录制的会话无法被暴力破解。对于 LibreSSL 链深度漏洞,6.1.1 在检查任何错误码之前无条件执行深度上限,因此无论验证器报告什么错误,超深链都会被拒绝;FoxIO 验证了同一源码在 LibreSSL 4.3.1 下已报告错误 22 并拒绝 17 份证书的链。

对于 BF1 绕过,公告中的补丁把 websVerifyPasswordFromFile() 拆分为三个互相独立的分支,每个分支只设置一次结果,并且不再用存储的哈希覆盖提交的密码:

  • 对于 BF1 用户,bcrypt 的结果是最终判定。
  • 对于 Digest 认证,客户端的摘要与存储的哈希进行比较。
  • 对于传统 MD5 格式的用户,编码后的密码以常数时间进行比较。

发布说明还列出了同一内部审计带来的相关加固,该审计共解决十一份公告和另外 31 项内部发现:BF1 存储哈希与 Digest 认证的组合现在被显式拒绝,会话标识符在每次登录时轮换。

如何检查是否已被入侵?

由于没有攻击报告,没有发布攻击指标。改为检查后果:

  • 对于 CRL 漏洞,把自部署以来在每个 GoAhead 服务器上完成认证的客户端证书与当前 CRL 内容对比。撤销列表中任何在撤销日期之后仍通过认证的证书,都意味着该漏洞影响到了您,无论是在服务器端还是在访问日志中。
  • 对于 Mbed TLS 漏洞,在录制的流量中搜索携带单字节 DH 参数的 TLS 1.2 DHE_RSA 握手,即 ServerKeyExchange 字节 00 01 ff,并把这些会话视为可解密;FoxIO 的 JA4S 套件列表可缩小搜索范围。
  • 对于 BF1 绕过,审查 6.1.0 设备上来自意外来源的 BF1 格式用户成功登录的认证日志,并将这些凭据视为已被窃取。

时间线

  • 2018 年:根据 FoxIO 的代码历史,Mbed TLS 的 DH 长度笔误在迁移到二进制参数 API 期间进入;它在 2024 年 4 月的 TLS 重构中幸存。
  • 2025-11-03:GoAhead 6.1.0 发布;BF1 登录绕过随其新密码格式一起引入。
  • 2026-08-02:GoAhead 6.1.1 这一关闭十一份公告和另外 31 项审计发现的安全版本交付设备制造商。
  • 2026-10-12:EmbedThis 发布十一份公告,CVE 已申请;截至 10 月 27 日它们尚未出现在公开的 CVE 和 NVD 数据库中。
  • 2026-10-26:FoxIO 发布三项 TLS 漏洞分析,附带概念验证代码和 JA4Scan 指纹。
  • 2026-10-27:Alan Coopersmith 在 oss-security 上转发 FoxIO 的三个 TLS 漏洞及其公告;The Hacker News 报道没有已知攻击,与 EmbedThis 在漏洞被利用时提前发布的政策一致。
  • 2026-10-29:本文发布。

设备制造商在 8 月 2 日收到修复;公告直到 10 月 12 日才公开
图 1:GoAhead 6.1.1 于 2026 年 8 月 2 日到达设备制造商,但十一份公告直到 10 月 12 日才公开,FoxIO 的分析和指纹则在 10 月 26 日公开。来源:EmbedThis GoAhead v6.1.1 发布说明和公告、FoxIO、oss-security,核查于 2026 年 10 月 29 日

常见问题

我的设备还没有收到固件更新。今天能做什么?

您无法重新构建他人的固件。识别您的 GoAhead 设备,向制造商确认其构建是否受影响以及何时交付 6.1.1,在此之前把管理访问限制在受信任的网络,使有缺陷的 TLS 检查不是唯一的屏障。对于 Mbed TLS 漏洞,禁用 DHE 套件只在您自己的构建中可行。

主流客户端受 Diffie-Hellman 漏洞影响吗?

不。FoxIO 测试的 OpenSSL 客户端直接拒绝单字节模数,当前的 Go、Java 和主流浏览器同样拒绝,因此会话永远不会完成。没有最小尺寸检查的定制和嵌入式客户端是暴露群体,录下其流量就足以事后解密。

怎么知道设备用的是哪个 TLS 后端?

从外部无法得知;后端和验证设置是编译时选择。FoxIO 的 JA4Scan 指纹可识别可从互联网访问的 GoAhead 服务器的后端,而您自己固件的构建配置是权威答案。

有人被攻击吗?

截至 2026 年 10 月 27 日,没有来源报告攻击。EmbedThis 的披露政策是在漏洞被利用或被他人披露时解除禁运并提前发布,因此 10 月 12 日的协调发布与没有已知攻击一致;这并不能证明没有攻击,且受影响群体尚未确立。

6.1.1 还修复了其他值得关心的问题吗?

是。该版本共关闭十一份公告,包括通过 .bat 和 .cmd 目标的 Windows CGI 命令注入(9.8,暂无 CVE)、CGI ISINDEX 参数注入(CVE-2026-115880,8.1)、httpoxy 式的 HTTP_PROXY 注入(CVE-2026-115882,8.1)、两个 HTTP 请求走私向量、Digest nonce 中的 masterSecret 泄露和会话固定,另外还有 31 项内部发现的缺陷,每一项都带回归测试。

用 Ostorlab 发现 GoAhead 设备

使用 Ostorlab Attack Surface Discovery 盘点您拥有的互联网暴露主机,这样其中的 GoAhead 设备、其管理接口及其 TLS 指纹在等待制造商固件更新之前就已经掌握。

参考资料

  • FoxIO,Sébastien Féry,《Choose Your Backend: Three TLS Bugs in GoAhead》,2026 年 10 月 26 日:三个根本原因及源码引用、验证回调轨迹、ServerKeyExchange 字节、JA4Scan 指纹和 DHE_RSA 套件列表:https://foxio.io/blog/choose-your-backend-three-tls-bugs-in-goahead (核查于 2026 年 10 月 29 日)
  • EmbedThis GoAhead 安全公告,2026 年 10 月 12 日发布:GHSA-5m75-xq69-c3c5(OpenSSL CRL 未强制,CVE-2026-115881,9.1,影响 GoAhead 3.4.5 至 6.1.0):https://github.com/embedthis/goahead/security/advisories/GHSA-5m75-xq69-c3c5 (核查于 2026 年 10 月 29 日)
  • GHSA-r392-vqwx-3r4g,LibreSSL 传统验证器构建上的 mTLS 客户端证书链深度绕过,CVE-2026-115884,7.4:https://github.com/embedthis/goahead/security/advisories/GHSA-r392-vqwx-3r4g (核查于 2026 年 10 月 29 日)
  • GHSA-fmvx-2xfx-2gq4,MbedTLS DH 参数截断,5.9,未分配 CVE:https://github.com/embedthis/goahead/security/advisories/GHSA-fmvx-2xfx-2gq4 (核查于 2026 年 10 月 29 日)
  • GHSA-qj3g-66fp-rhhr,BF1 哈希用户的认证绕过,CVE-2026-115888,9.8,仅影响 GoAhead 6.1.0,已在 6.1.1 中修复:https://github.com/embedthis/goahead/security/advisories/GHSA-qj3g-66fp-rhhr (核查于 2026 年 10 月 29 日)
  • GoAhead v6.1.1 发布说明:2026 年 8 月 2 日交付设备制造商,10 月 12 日发布公告;解决十一份公告和另外 31 项修复,无遗留 Critical 或 High 发现:https://github.com/embedthis/goahead/releases/tag/v6.1.1 (核查于 2026 年 10 月 29 日)
  • 6.1.1 的其余公告,包括 Windows CGI 命令注入(GHSA-584w-ph2x-4gfq,9.8)、ISINDEX CGI 注入(GHSA-c7w3-26wq-mjc3,CVE-2026-115880,8.1)和 HTTP_PROXY 注入(GHSA-w3p3-6x8p-vrjr,CVE-2026-115882,8.1):https://github.com/embedthis/goahead/security/advisories (核查于 2026 年 10 月 29 日)
  • Alan Coopersmith 在 oss-security 上,《Three TLS Bugs in GoAhead web server prior to 6.1.1》,2026 年 10 月 27 日(消息日期为 2026 年 10 月 27 日 17:17 UTC-7,归档于 10 月 28 日):https://www.openwall.com/lists/oss-security/2026/10/28/1 (核查于 2026 年 10 月 29 日)
  • The Hacker News,《GoAhead TLS Flaws Allow Revoked Client Certificates and Enable Session Decryption》,2026 年 10 月 27 日:无已知攻击的状态、EmbedThis 的披露政策、CVE 数据库滞后和升级后的建议:https://thehackernews.com/2026/10/goahead-tls-flaws-allow-revoked-client.html (核查于 2026 年 10 月 29 日)