不得了了,重漏家人们 !洞远 就在这几天,程执Git爆出了一个严重漏洞,行代编号CVE-2024-32002
,通杀一个可以远程执行代码的重漏RCE漏洞
! 攻击者精心准备一个Git项目
,洞远只要你尝试去Clone它
,程执你的行代电脑就能执行攻击代码沦陷 。 比如下面这个GitHub上面的通杀项目: 你可以执行一下下面的命令
: git clone --recursive git@github.com:amalmurali47/git_rce.git 不出意外的话 ,你的重漏电脑将会弹出计算器程序: 能让你弹计算器,源码下载就能执行其他更危险的洞远操作,比如给你种木马等等 。程执 Git是行代我们程序员基本离不开的工具,这波漏洞操作
,通杀属实是对程序员定向打击了
。 接下来我们来理一理这个漏洞的工作原理是怎么样的。 在介绍攻击原理之前,得先来了解几个东西
。 在Git里面有一个HOOK的机制,就是钩子的意思。不过这个HOOK不是咱们二进制安全攻击中的那个HOOK
。 Git中的钩子是一些脚本,这些脚本在Git的特定事件发生时自动执行 。钩子允许你在Git操作的不同阶段执行自定义操作,如代码格式化、服务器租用测试运行、通知发送等。 Git 设计 hooks(钩子)的初衷是为了让用户能够在特定的 Git 事件发生时自动执行自定义脚本或操作。这些钩子提供了一种机制
,可以在 Git 操作的各个阶段插入用户自定义的逻辑 ,以便实现更强大的自动化和定制化流程
。 Git钩子分为服务端和客户端钩子,在咱们程序员使用的Git客户端中,有下面这几个钩子: 那这些钩子脚本是存放在哪里的呢
?就是在那个神秘的.git目录下。 大家可以去看一下自己电脑上,不管是从GitHub克隆的项目,还是从公司的git服务器克隆的项目 ,你们的香港云服务器代码目录下 ,都有一个叫.git的文件夹,它的目录结构大致是下面这样的: 当我们创建一个新的Git项目时 ,执行完git init后,git就会为我们创建一个.git目录。 而我们刚才说的钩子脚本 ,就放在.git/hooks里面,git默认为我们提供了一些钩子脚本的示例。 你可以在这里面添加一些自己的脚本程序
,这样当你在执行对应的git命令操作时,对应的脚本程序就会得到执行
。 要注意,.git目录下的内容
,是git程序自己在维护
,不会受到Git项目里的内容的影响
。你在上传代码的时候,.git目录也不会被传到服务器上去
。 所以,正常情况下,你从服务器克隆一个项目的时候,只是把项目拉到本地,不用担心执行恶意的HOOK脚本 ,因为.git目录是你本地的git客户端程序创建的 ,除非你手动去把钩子脚本放到里面去 ,否则里面是不会有恶意钩子脚本的
。 但是,我要说但是了
,这一次漏洞的操作就很骚,骚在哪里呢?骚就骚在,它巧妙的利用了一个特性,把攻击脚本给写到.git目录下面去了
! 这是怎么办到的呢?这需要了解另一个Git的知识。 子模块是嵌套在一个 Git 仓库中的另一个 Git 仓库 ,可以让你在一个项目中包含其他项目
,比如某个开源项目要依赖于其他的开源项目 。 在这种情况下
,主项目下面会存在一个.gitmodules文件
,里面会记录该项目包含的其他Git项目的信息。 其中
,path指定子模块存放的位置 ,url指定子模块的Git仓库地址
。 我们在执行git clone克隆项目的时候 ,如果指定了一个递归的参数:--recursive
,就会在拉取主项目之后,然后根据这个文件中的内容,递归的去拉取所依赖的其他子模块,然后放到对应的文件目录位置
。 不仅主项目有一个.git目录来记录项目相关的信息
,子模块也有
。你去上面这个path目录下去看
,会发现这里也有一个.git,不过这个.git不是一个文件夹,而是一个文件 ,里面记录了这个子模块对应的真正的.git目录的位置
。 这个位置一般在主项目.git目录下的modules文件夹下面。 接下来了解与这个漏洞相关的第三个知识点:符号链接。 在 Git 中,符号链接(symbolic link,简称 symlink)是指向另一个文件或目录的特殊类型的文件。符号链接本身不包含文件的内容,而是包含指向目标文件或目录的路径。当访问符号链接时 ,系统会自动重定向到其指向的目标
。 简单理解的话,这玩意儿有点像快捷方式
。 好了,了解了上面这些知识背景 ,接下来,就要说说这个漏洞的成因了。 刚才说过
,钩子脚本位于.git目录中,而这个目录是与项目本身的内容无关的,它的内容是git客户端在维护 ,除非你手动放置脚本程序到hooks目录中,否则项目中的内容是不会跑到.git目录中的。 而这次漏洞就采用了一个骚操作: 攻击者准备一个Git项目 ,在这个Git项目中,又依赖一个子项目。当采用--recursive参数的时候,递归去拉取对应的子项目
,放到对应的位置 。 就像上面这样 ,它指示git
,把url中的项目拉下来放到A/modules/x目录中。 然后骚操作来了 :在这个项目下,有一个名字叫a的符号链接 ,并且让它指向了.git目录 。 因为Windows和Mac平台的文件和目录名称是大小写不敏感 ,注意这点很重要,导致在放置子模块到A/modules/x的时候,实际上就是放到了.git/modules/x目录下去了。 Git项目内容写到.git目录下了
!事情就出在这里了
!.git目录是git程序的私家花园,被项目内容闯了进来! 你可能会问,一定要大小写不一样吗,我直接在.gitmodules文件里面指定让它写到小写的a/modules/x路径下不行吗? 还真不行,我试过了 ,git直接报错了
: 看来,git基本的检查工作还是做了的,只是疏漏了大小写不一样的情况。 继续我们刚刚的分析,.git目录这个git程序的私家花园,被人给闯进来了
。 而且关键是它闯进来的位置是在.git/modules/x下面,前面说过,这个目录下面,是子模块所属的.git目录
,然后这个闯进来的家伙,还按照.git目录的结构,里面放置一个hooks文件夹
,里面放上相关的钩子脚本,等下git clone完成的时候,就会去执行这里的脚本程序了。 克隆完成之后的整个目录结构变成了这样
: 我用procmon抓了一下执行下面这条克隆命令到弹出计算器进程中间的过程:git clone --recursive git@github.com:amalmurali47/git_rce.git 大家从进程的父子关系树和进程的命令行参数 ,就能看到这条攻击链路了
: 最后总结一下: 1
、攻击者精心构造了一个Git项目,这个项目依赖一个子项目 ,并且指定了这个子项目存储的路径为A 。 2
、在这个Git项目下,有一个名为a的符号链接 ,指向了.git目录。 3、子项目里面构造了一个hooks目录
,攻击脚本存放在里面
。 4
、最后,递归克隆项目的时候 ,因为目录大小写不敏感的原因 ,子项目实际上被写到了.git目录下。 5、相关的克隆动作
,触发了post-checkout钩子的执行,而现在的hooks目录下 ,被写入了攻击者的恶意钩子脚本,于是就执行了这个恶意脚本
。 Windows: Mac: 以上就是本次漏洞的大致过程了
。 本次漏洞受影响的版本有 : 赶紧来执行git --version看看你的版本有没有在上面的范围里,是的话赶紧升个级吧!
图片
图片1
、模板下载Git 钩子
图片
图片2
、子模块
图片3 、符号链接
4、漏洞成因
图片
图片
图片
图片
图片
图片
图片
图片
图片
图片