远程口头代码 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看看你的版本有没有在上方的范围里,是的话连忙升个级吧!

起源: 轩辕的编程宇宙

您可能还会对下面的文章感兴趣: