.git信息泄露漏洞,目前许多的web安全类书籍是没提的,强大的freebuf虽然有有关githack的文章,但对于.git信息泄露漏洞的原理并没有介绍,而百度上的其他资料原理的讲解又太理论化了,几乎把git的对象的形成原理都讲了,而我们只是利用而已,故写此简明原理文,献给一直照顾我的freebuf。
PS:本文仅用于技术研究与讨论,严禁用于非法用途,违者后果自负
故事的开始是因为我的xray扫描结果有那么个.git漏洞,
刚开始我还以为是github有泄露,原谅我有点萌。
但点了下目标链接才明白,这是一个跟源码泄露有关的漏洞
下载文件,打开后是一个路径
我便拼了下这个路径,可惜是404
另个文件一堆配置,感觉也没什么头绪
既然没头绪,就要去学习
虽然叫研究这么高大上,实际上就是问度娘,和查点资料
首先,我搞懂了.git文件夹是来自于git这个开源的分布式版本控制系统,
这个听起来有点高级,用我的脑子过滤下就是,你用你的电脑下载git这么个软件,然后简单运行下,软件会自动在其定义的根目录下,生成这么个文件夹(叫程序还是叫软件,能简单理解就好)
就这个git bash
下载git的方法请参考这个文章
https://blog.csdn.net/qq_32786873/article/details/80570783
我用的是window10下载的,很简单,打开安装包,选好下载路径就一直点next,就行了(当然这个作者写的比较详细,挺辛苦的,应该感谢下他)
不过记得在这个页面点下on the Desktop,这样桌面才有快捷图标
全部搞好后,就点击桌面上的这个图标,运行这个程序
然后,就会打开一个终端页面(我建议打开后先等5秒,因为这个第一次运行可能要点时间)
红框内的是我们当前执行命令的位置
行动1
使用命令
makedir git_one
先搞个新的目录文件夹,或者说一个新项目
行动2
使用命令
cd git_one/
进入我们创建文件的目录
行动3
使用命令
git init
初始化我们的这个项目(也就是这个目录)
行动123,也就初始化完成后就会自动产生.git目录(文件夹是透明的,表示还是个隐藏文件夹,管理员就有可能没注意到,从而产生漏洞),它就是我们今天的主角
现在该讲讲.git这个目录是干什么的了,这就是个类似于备份目录的东西
我们使用git的所有被追踪的操作和被操作的文件都会被记录,编码,并保存在这个目录里,以备引用,和防删除(当然,这不是对的解释,只是为了方便理解,各位有兴趣可以自己研究)
而且git是一个和代码保存管理有关的系统,所以这里如果有漏洞,我们可能能下载网站源码或重要的带密码的配置文件之类的
在git中有3种对象,分别是commit,tree和blob(tag就不介绍了)
然后,每个Git对象都有个哈希值来代表这个对象。哈希值是通过SHA算法计算出来的,长度为40个字符(40-digit)。
听不懂?讲的快?没事。跟我做就对了
先在我们的项目也就主目录git_one下创建个子目录bigson
mkdir bigson
再cd到bigson的目录下
cd bigson/
再创建个具体的文件
echo 'i am a man' >>atest.php
从这里开始,commit就代表我们项目的主目录即git_one
tree对象代表我们项目下的子目录bigson
blob对象就代表我们有代码的具体文件atest.php
(虽然commit,tree,blob对应的确实是个树形结构,但实际上commit代表的是个仓库,tree也不是专门对应于子目录的,这样也是为了好理解,有兴趣科普的大佬,欢迎在评论里赐教,我也不是很明白对应关系)
好了现在回过来,我们点开.git文件夹,发现里面有7个文件(每个文件夹算一个文件)
点开HEAD文件发现内容一样
那我们去找.git/refs/heads/,发现什么都没有
打开下.git/objects/文件夹,再点开pack和info,也什么都没有。
这时注意我之前的粗体字,‘’我们使用git的所有被追踪的操作和被操作的文件都会被记录’’,那我们追踪一下我们的这个文件
使用 git add 命令将内容写入暂存区。
git commit 命令将暂存区内容添加到本地仓库。(暂存区是什么东西的,别管,我们简明原理)
git add atest.php
git commit -m 'atestnote'
可以发现git commit命令错误了,please tell me who you are
我们可以用笔记本形式打开.git/config这个文件,在下面添加这段身份信息
[user]
name = onetest
email = [email protected]
也可以直接使用git命令配置全局身份(这里我就不用了)
git config --global user.eamil "[email protected]" git config --global user.name "xxxxx"
现在重新执行git commit命令,成功了
我们这是再次打开.git文件,发现有10个文件了
多出来的3个文件,我简单介绍下吧
Index文件:暂存区,一个二进制文件
logs文件夹:记录了操作git的地方
COMMIT_EDITMSG文件:追踪文件时git commit -n ‘xxxx’,那个xxxx的内容,有一定概率有帮助
好了,这回我们打开.git/refs/heads/文件夹,再看看,发现有东西了,点开master,是一串hash值,就我们之前提到的40位sha加密文
9e859e6e72aceb01362fd35df50628b1c96071f9
唉,前面搞了那么多铺垫,终于到了,讲利用了
所以这串hash值有什么用啊
这里我们就要介绍.git/objects/这个文件夹了
之前打开就两空文件夹,我们现在打开看看
多了几个文件夹,而且名字也有意思
第一个9e,和9e859e6e72aceb01362fd35df50628b1c96071f9这里的头两位是一样的
打开9e,我们看到有个文件的名字和这串hash值除去前两位一模一样
.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
(打码一波,别暴露客户了)
不过到哪去找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
这里我们得到的还是个tree对象的hash值(因为对应的是子文件名),只好再来波方法一样,
这里我们就获得blob对象的hash值(因为对应的是atest.php文件名虽然有个tree在前面),这时我们的请求就不需要再保存放到文件用hex打开了,直接decompress就行了,哈,成功得到目标文件
真是老母猪带胸罩,一套又一套的
接着回到前面的问题,最开始的hash怎么搞,搞到了一个commit的hash我们可以俄罗斯套娃,找下去,关键在于第一个hash到哪找?
我们先看看其他的.git信息泄露漏洞利用工具是如何找到第一个hash的
githack是最常用的工具,它是通过.git/index,找到第一个hash值的(不过是个tree hash),可惜它好像只会从index中去找,导致ctf中我删了index,学生就蒙了
githacker,我的使用是404,没看具体代码,好像比较全点
其他的工具像gittool,我直接无法使用,唉
这样看工具的路子就窄了
我个人总结了一些,如果有大佬发现有漏,希望能在评论区不吝啬赐教
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,并没有追踪,唉,又无功而返,有思路的表哥,可以教下我哦