.git信息泄露漏洞-简明原理及利用方法 – 作者:老哥和学习额

一. 说明

.git信息泄露漏洞,目前许多的web安全类书籍是没提的,强大的freebuf虽然有有关githack的文章,但对于.git信息泄露漏洞的原理并没有介绍,而百度上的其他资料原理的讲解又太理论化了,几乎把git的对象的形成原理都讲了,而我们只是利用而已,故写此简明原理文,献给一直照顾我的freebuf。

1616675588_605c8304b6d6a74d0545d.png!small?1616675590252

PS:本文仅用于技术研究与讨论,严禁用于非法用途,违者后果自负

二. 附加背景

故事的开始是因为我的xray扫描结果有那么个.git漏洞,

刚开始我还以为是github有泄露,原谅我有点萌。

1616598585_605b56399592ce12c3e2c.png!small?1616598588015

但点了下目标链接才明白,这是一个跟源码泄露有关的漏洞

1616598951_605b57a76b955ec29f19a.png!small?1616598954275

下载文件,打开后是一个路径

1616599048_605b5808c305c32cac22d.png!small?1616599051071

我便拼了下这个路径,可惜是404

1616599282_605b58f228c6a9bec921a.png!small?1616599284523

另个文件一堆配置,感觉也没什么头绪

1616675728_605c83906a722901b3077.png!small?1616675730094

三. 开始研究这种漏洞

既然没头绪,就要去学习

1616675604_605c831441d4961f987b8.png!small?1616675605751

虽然叫研究这么高大上,实际上就是问度娘,和查点资料

首先,我搞懂了.git文件夹是来自于git这个开源的分布式版本控制系统,

这个听起来有点高级,用我的脑子过滤下就是,你用你的电脑下载git这么个软件,然后简单运行下,软件会自动在其定义的根目录下,生成这么个文件夹(叫程序还是叫软件,能简单理解就好)

就这个git bash

1616600012_605b5bcc7536b8429de07.png!small?1616600014768

下载git的方法请参考这个文章

https://blog.csdn.net/qq_32786873/article/details/80570783

我用的是window10下载的,很简单,打开安装包,选好下载路径就一直点next,就行了(当然这个作者写的比较详细,挺辛苦的,应该感谢下他)

不过记得在这个页面点下on the Desktop,这样桌面才有快捷图标

1616600529_605b5dd11adba2eaf74ae.png!small?1616600531572

全部搞好后,就点击桌面上的这个图标,运行这个程序

1616600722_605b5e928c115e84f2a4d.png!small?1616600724801

然后,就会打开一个终端页面(我建议打开后先等5秒,因为这个第一次运行可能要点时间)

1616600817_605b5ef1b56c134eac18d.png!small?1616600820134

红框内的是我们当前执行命令的位置

1616601096_605b6008808fee1e2e7b8.png!small?1616601098787

行动1

使用命令

makedir git_one

先搞个新的目录文件夹,或者说一个新项目

1616672867_605c786345a305d1373c0.png!small?1616672869021

行动2

使用命令

cd git_one/

进入我们创建文件的目录

1616672873_605c7869ef0394dd5581d.png!small?1616672875746

行动3

使用命令

git init

初始化我们的这个项目(也就是这个目录)

1616672881_605c78710cbc148982561.png!small?1616672882842

行动123,也就初始化完成后就会自动产生.git目录(文件夹是透明的,表示还是个隐藏文件夹,管理员就有可能没注意到,从而产生漏洞),它就是我们今天的主角

1616672891_605c787b4ead029056b08.png!small?1616672893922

现在该讲讲.git这个目录是干什么的了,这就是个类似于备份目录的东西

我们使用git的所有被追踪的操作和被操作的文件都会被记录,编码,并保存在这个目录里,以备引用,和防删除(当然,这不是对的解释,只是为了方便理解,各位有兴趣可以自己研究)

而且git是一个和代码保存管理有关的系统,所以这里如果有漏洞,我们可能能下载网站源码或重要的带密码的配置文件之类的

1616676617_605c8709bc8c8c04b2b95.png!small?1616676619318

在git中有3种对象,分别是commit,tree和blob(tag就不介绍了)

然后,每个Git对象都有个哈希值来代表这个对象。哈希值是通过SHA算法计算出来的,长度为40个字符(40-digit)。

听不懂?讲的快?没事。跟我做就对了

先在我们的项目也就主目录git_one下创建个子目录bigson

mkdir bigson

1616672982_605c78d6e804d98a4c4fd.png!small?1616672984692

再cd到bigson的目录下

cd bigson/

再创建个具体的文件

echo 'i am a man' >>atest.php

1616672997_605c78e56be1ca5609d32.png!small?1616672999338

从这里开始,commit就代表我们项目的主目录即git_one

tree对象代表我们项目下的子目录bigson

blob对象就代表我们有代码的具体文件atest.php

(虽然commit,tree,blob对应的确实是个树形结构,但实际上commit代表的是个仓库,tree也不是专门对应于子目录的,这样也是为了好理解,有兴趣科普的大佬,欢迎在评论里赐教,我也不是很明白对应关系)

好了现在回过来,我们点开.git文件夹,发现里面有7个文件(每个文件夹算一个文件)

1616673046_605c791676a0de3072f55.png!small?1616673048236

点开HEAD文件发现内容一样

1616673054_605c791eb80521cf2f411.png!small?1616673056672

那我们去找.git/refs/heads/,发现什么都没有

1616673097_605c79491e04edb14e543.png!small?1616673098678

打开下.git/objects/文件夹,再点开pack和info,也什么都没有。

1616673105_605c79519ec34462722cc.png!small?1616673107322

1616673112_605c7958d1d4022746410.png!small?1616673114573

1616673119_605c795fbc576756a7244.png!small?1616673121562

这时注意我之前的粗体字,‘’我们使用git的所有被追踪的操作和被操作的文件都会被记录’’,那我们追踪一下我们的这个文件

使用 git add 命令将内容写入暂存区。

git commit 命令将暂存区内容添加到本地仓库。(暂存区是什么东西的,别管,我们简明原理)

git add atest.php
git commit -m 'atestnote'

1616673165_605c798d05f9e9983aaaf.png!small?1616673167166

可以发现git commit命令错误了,please tell me who you are

我们可以用笔记本形式打开.git/config这个文件,在下面添加这段身份信息

[user]
name = onetest
email = [email protected]

1616673194_605c79aa6cf32535fd2c2.png!small?1616673196295

也可以直接使用git命令配置全局身份(这里我就不用了)

git config --global user.eamil "[email protected]"
git config --global user.name "xxxxx"

现在重新执行git commit命令,成功了

1616673205_605c79b5c92c97110bf5d.png!small?1616673207337

我们这是再次打开.git文件,发现有10个文件了

1616673224_605c79c82ec9d2b0bc9fc.png!small?1616673226017

多出来的3个文件,我简单介绍下吧

Index文件:暂存区,一个二进制文件

logs文件夹:记录了操作git的地方

COMMIT_EDITMSG文件:追踪文件时git commit -n ‘xxxx’,那个xxxx的内容,有一定概率有帮助

好了,这回我们打开.git/refs/heads/文件夹,再看看,发现有东西了,点开master,是一串hash值,就我们之前提到的40位sha加密文

1616673253_605c79e59d9a0ff2f06bb.png!small?1616673255179

1616673313_605c7a2155509da7e17a8.png!small?1616673314966

9e859e6e72aceb01362fd35df50628b1c96071f9

四. 漏洞的具体利用

唉,前面搞了那么多铺垫,终于到了,讲利用了

所以这串hash值有什么用啊

这里我们就要介绍.git/objects/这个文件夹了

之前打开就两空文件夹,我们现在打开看看

1616673563_605c7b1b6d9643c7f93c4.png!small?1616673565415

多了几个文件夹,而且名字也有意思

第一个9e,和9e859e6e72aceb01362fd35df50628b1c96071f9这里的头两位是一样的

打开9e,我们看到有个文件的名字和这串hash值除去前两位一模一样

1616673571_605c7b237ad72c965b99e.png!small?1616673573386

.git下的objects文件夹是用来存放所有被追踪的git对象的,每个git对象所对应的hash值的头两位会变为文件夹,剩下的变为文件名,保存在这里

我们想下载源码,文件,都是通过这个文件夹,但前提是我们知道目标文件的hash值,这样才能在objects下找到目标文件

下载很简单,就在浏览器上输上url地址会自动下载的

http://xxxxx.com/.git/object/9e/859e6e72aceb01362fd35df50628b1c96071f9

不过会是乱码的,建议用python的zlib库解码下

import zlib
import requests

urla = "http://127.0.0.1:8080/.git/objects/9e/859e6e72aceb01362fd35df50628b1c96071f9"

re = requests.get(urla)
ss = re.content
word = zlib.decompress(ss)

print word

1616673998_605c7cceb37fafdb5b15c.png!small?1616674001309

(打码一波,别暴露客户了)

不过到哪去找hash值?这才是技术点

不过在这之前,先学下,如何利用已经找到的hash值。

注意之前在.git/refs/heads/master找到的是一个commit对象的hash值,而commit对象hash值对应的文件,也就是解码后的那样的。文件里包含了一个tree对象的hash值(cc44ac04da4ef14239cc6013ec1062e64dc8c1d1),和文件的身份作者(就我们之前添加的onetest,[email protected]

我们现在可以用tree的hash值去,得到这个tree对象文件的内容,这里有点不同,要将内容保存到文件,再用burp的repeater打开这个文件,并用hex表示,最后的40位码,即为hash值。

import zlib
import requests

urla = "http://127.0.0.1:8080/.git/objects/cc/44ac04da4ef14239cc6013ec1062e64dc8c1d1"
# cc/44ac04da4ef14239cc6013ec1062e64dc8c1d1
# 9e/859e6e72aceb01362fd35df50628b1c96071f9
re = requests.get(urla)
ss = re.content
word = zlib.decompress(ss)

f = open('./treetest','a+')
f.write(word)
f.close()

print word

1616737103_605d734feb119e39793bb.png!small

1616674099_605c7d3376de6615b2467.png!small?1616674101255

这里我们得到的还是个tree对象的hash值(因为对应的是子文件名),只好再来波方法一样,

1616674302_605c7dfeeebef144b2211.png!small?1616674304536

这里我们就获得blob对象的hash值(因为对应的是atest.php文件名虽然有个tree在前面),这时我们的请求就不需要再保存放到文件用hex打开了,直接decompress就行了,哈,成功得到目标文件

1616737181_605d739d795f323965722.png!small

真是老母猪带胸罩,一套又一套的

1616675359_605c821fddc726b247090.png!small?1616675361926

接着回到前面的问题,最开始的hash怎么搞,搞到了一个commit的hash我们可以俄罗斯套娃,找下去,关键在于第一个hash到哪找?

1616675418_605c825a349d22428ce64.png!small?1616675419950

我们先看看其他的.git信息泄露漏洞利用工具是如何找到第一个hash的

githack是最常用的工具,它是通过.git/index,找到第一个hash值的(不过是个tree hash),可惜它好像只会从index中去找,导致ctf中我删了index,学生就蒙了

githacker,我的使用是404,没看具体代码,好像比较全点

其他的工具像gittool,我直接无法使用,唉

五. 找hash的小总结

这样看工具的路子就窄了

1616675696_605c8370603cff59bbf46.png!small?1616675698267

我个人总结了一些,如果有大佬发现有漏,希望能在评论区不吝啬赐教

1,

.git/logs/

你可以在这里的.git/logs/HEAD中明文找到hash

也可以在.git/logs/refs/heads/master找到明文hash

2,

.git/refs/

这里我建议直接将.git/refs/heads/下的文件爆破一遍,因为有些是不止master一个分支的(分支的内容因为简明,没介绍,抱歉,有兴趣可以百度下)

.git/refs/heads/master就是明文的hash在里面

.git/refs/stash也会有

.git/refs/tags不清楚

3,

.git/HEAD

.git/Index

这两个也就那样,head文件保存引用的,非直接保存hash

index文件是个暂存区,会有大概率出现commit 或 tree 或 blob对象的hash,要hex打开

4,

.git/COMMIT_EDITMSG

有可能有有价值的备注

.git/config

里面如果有身份信息,可以社工一波

两个都不是专门保存hash的地方,但也会有有用的信息

六. 最后

回到我的xray,我们之前在没追踪文件前.git文件夹下有7个文件,追踪后多了三个,index,logs,COMMIT_EDITMSG,我对这三个都访问,返回404,再加上,其他文件夹下的东西也是404,所以我推测客户可能只是git init,并没有追踪,唉,又无功而返,有思路的表哥,可以教下我哦

1616675672_605c8358771f6147e203c.png!small?1616675674048

来源:freebuf.com 2021-03-25 20:38:07 by: 老哥和学习额

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论