abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · cve-2026-105221-gist-tls
gist RubyGem < 6.1.0 - defunkt
类别: TLS 验证绕过(凭据窃取) 触达方式: 远程(路径中间人)
http_connection 设置了 OpenSSL::SSL::VERIFY_NONE。发往 GitHub 的 HTTPS 流量仍会加密,但任何证书都会被接受。路径上的对端可以读取 CLI 发送的 OAuth 令牌,进而读取和修改受害者的 gist。
| ID | CVE-2026-105221 |
| 类别 | TLS 验证绕过(凭据窃取) |
| 触达方式 | 远程(路径中间人) |
| CWE | CWE-295 |
| CVSS | 高危:7.4 CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N(VulnCheck 4.0:9.1) |
| 产品 | gist |
| 受影响版本 | 4.0.0 至 6.0.0。实验环境固定为 6.0.0。已在 6.1.0 中修复(07ccc1a)。 |
| 认证 | 对 gist CLI 的路径中间人攻击 |
| 许可证 | GNU Affero GPL v3.0 |
| 实验环境 | 仅限 127.0.0.1 |
攻击者位于路径中间并窃取 GitHub 令牌。
CN=mitm.invalid 的自签名证书就足够了。Authorization: token ...。 登录(gist --login)以及 gist 的上传/列出/删除操作都经过 http_connection。~/.gist 中的令牌就通过该套接字传输。gist 作用域的 GitHub OAuth 凭据。可访问私有 gist、执行更新和删除。攻击者需要占据网络位置:恶意 Wi-Fi、代理、中间节点。这不是针对服务器的未认证远程 RCE。
6.1.0 设置了 VERIFY_PEER。同样的伪造证书会以 certificate verify failed (self-signed certificate) 失败,令牌永远不会离开客户端。
VulnCheck 发布了 CVE-2026-105221。Siyang Wu 报告了该漏洞。Issue 373 是公开工单。PR 374 更改了验证模式。我在实验环境中复现了这个公开 CVE。当时没有公开的 PoC。
lib/gist.rb 中 6.0.0 版本的 http_connection:
if uri.scheme == "https"
connection.use_ssl = true
connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
6.1.0 是 VERIFY_PEER。
回环实验环境是一个伪造的 GitHub Enterprise HTTPS 桩,使用自签名证书。GITHUB_URL=https://127.0.0.1:8443 使 gist 进入 GHE 模式(POST /api/v3/gists)。一个实验令牌 CVE-2026-105221-WITNESS 位于匹配的 ~/.gist.* 文件中。gist 6.0.0 完成 TLS 握手,桩捕获到 Authorization: token CVE-2026-105221-WITNESS 并写入见证记录。gist 6.1.0 针对同一桩则 TLS 失败。6.1.0 上的捕获计数保持为零。没有任何内容与 api.github.com 通信。
SUCCESS CVE-2026-105221 vuln-tls=ok token-captured=1 patched-tls=fail witness-written=yes CVE-2026-105221-WITNESS
已记录的误判:无。第一次 run.sh 打印了 SUCCESS。一个反向 shell。一场戏。真正的判据是 6.0.0 上捕获的实验室令牌,以及 6.1.0 上的自签名 TLS 错误。
cd lab
./run.sh
仅针对 https://127.0.0.1:18210(容器 8443)。run.sh 从 RubyGems 安装 gist 6.0.0 和 6.1.0,在容器内提供该 stub 服务,然后拆除整个栈。使用自签名证书。不涉及真实 GitHub。
将 gist gem 升级到 6.1.0 或更高版本。
lib/gist.rb v6.0.0 L466-L468