远程口头代码 Mac和Windows通杀! Git严重破绽
不得了了,家人们!
就在这几天,Git爆出了一个严重破绽,编号CVE-2024-32002,一个可以远程口头代码的RCE破绽!
攻打者精心预备一个Git名目,只需你尝试去Clone它,你的电脑就能口头攻打代码失陷。
比如上方这个GitHub上方的名目:
你可以口头一下上方的命令:
git clone --recursive git@github.com:amalmurali47/git_rce.git
不出异常的话,你的电脑将会弹出计算器程序:
能让你弹计算器,就能口头其余更风险的操作,比如给你种木马等等。
Git是我们程序员基本离不开的工具,这波破绽操作,失实是对程序员定向打击了。
接上去我们来理一理这个破绽的上班原理是怎样样的。
在引见攻打原理之前,得先来了解几个物品。
1、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的常识。
2、子模块
子模块是嵌套在一个 Git 仓库中的另一个 Git 仓库,可以让你在一个名目中蕴含其余名目,比如某个开源名目要依赖于其余的开源名目。
在这种状况下,主名目上方会存在一个.gitmodules文件,外面会记载该名目蕴含的其余Git名目的信息。
其中,path指定子模块寄存的位置,url指定子模块的Git仓库地址。
我们在口头git clone克隆名目的时刻,假设指定了一个递归的参数:--recursive,就会在拉取主名目之后,而后依据这个文件中的内容,递归的去拉取所依赖的其余子模块,而后放到对应的文件目录位置。
不只主名目有一个.git目录来记载名目相关的信息,子模块也有。你去上方这个path目录下去看,会发现这里也有一个.git,不过这个.git不是一个文件夹,而是一个文件,外面记载了这个子模块对应的真正的.git目录的位置。
这个位置普通在主名目.git目录下的modules文件夹上方。
3、符号链接
接上去了解与这个破绽相关的第三个常识点:符号链接。
在 Git 中,符号链接(symbolic link,简称 symlink)是指向另一个文件或目录的不凡类型的文件。符号链接自身不蕴含文件的内容,而是蕴含指向指标文件或目录的门路。当访问符号链接时,系统会智能重定向到其指向的指标。
便捷了解的话,这玩意儿有点像快捷模式。
4、破绽成因
好了,了解了上方这些常识背景,接上去,就要说说这个破绽的成因了。
刚才说过,钩子脚本位于.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目录下,被写入了攻打者的恶意钩子脚本,于是就口头了这个恶意脚本。
以上就是本次破绽的大抵环节了。
本次破绽受影响的版本有:
连忙来口头git --version看看你的版本有没有在上方的范围里,是的话连忙升个级吧!