Git信息泄露原理解析及利用总结

admin 2023年4月20日09:29:28Git信息泄露原理解析及利用总结已关闭评论26 views字数 3918阅读13分3秒阅读模式

前言

最近,在和一些人聊天的过程中发现,好多人可以很从容淡定的说出信息收集需要收集Git信息泄露,至于深入的去谈这个漏洞产生的原理时,貌似不太直到这个问题以及相关工具的原理是什么?但作为小白的我始终觉得,对于一个问题只有深入的了解它的原理,并且利用的核心思想才能更好的挖掘和利用它。(可能思想有些“吹毛求疵”了,欢迎大佬们来指教)

那这篇文章,我就尝试从原理上分析一下这个漏洞以及漏洞的利用思想吧!(当然,借鉴了很多前辈的文章,感谢前辈们的分享)

一、Git简介

官方给出的解释是:Git是一个开源的分布式版本控制系统 ,我们简单的理解为Git 是一个内容寻址文件系统,也就是说Git 的核心部分是键值对数据库。 当我们向 Git 仓库中插入任意类型的内容(开发者们在其中做的版本信息修改之类的操作),它会返回一个唯一的键,通过该键可以在任意时刻再次取回该内容

Git是一个可以实现有效控制应用版本的系统,但是在一旦在代码发布的时候,存在不规范的操作及配置,就很可能将源代码泄露出去。那么,一旦攻击者或者黑客发现这个问题之后,就可能利用其获取网站的源码、数据库等重要资源信息,进而造成严重的危害。

二、漏洞危害

正如简介所说,在配置不当的情况下,可能会将“.git”文件直接部署到线上环境,这就造成了git泄露问题。

攻击者利用该漏洞下载.git文件夹中的所有内容。如果文件夹中存在敏感信息(数据库账号密码、源码等),通过白盒的审计等方式就可能直接获得控制服务器的权限和机会!

三、Git的基本使用

1.git结构 

.git目录:使用git init初始化git仓库的时候,生成的隐藏目录,git会将所有的文件,目录,提交等转化为git对象,压缩存储在这个文件夹当中。

COMMIT_EDITMSG:保存最新的commit message,Git系统不会用到这个文件,用户一个参考文件

config:Git仓库的配置文件

description:仓库的描述信息,主要给gitweb等git托管系统使用

HEAD:这个文件包含了一个档期分支(branch)的引用,通过这个文件Git可以得到下一次commit的parent

hooks:这个目录存放一些shell脚本,可以设置特定的git命令后触发相应的脚本;在搭建gitweb系统或其他

git托管系统会经常用到hook script(钩子脚本)

index:这个文件就是我们前面提到的暂存区(stage),是一个二进制文件

info:包含仓库的一些信息

logs:保存所有更新的引用记录

objects:所有的Git对象都会存放在这个目录中,对象的SHA1哈希值的前两位是文件夹名称,后38位作为对象文件名

refs:这个目录一般包括三个子文件夹,heads、remotes和tags,heads中的文件标识了项目中的各个分支指向的当前commit

ORIG_HEAD:HEAD指针的前一个状态

2.git常用命令

git init 初始化一个git仓库

git add && git commit //git 添加文件和提交文件

git status 查看当前仓库状态和内存状态

git ls-files -u 显示冲突的文件,-s是显示标记为冲突已解决的文件

git diff 对比工作区和stage文件的差异

git diff -cached 对比stage和branch之间的差异

git ls-files -stage 检查保存在stage的文件

git log 显示到HEAD所指向的commit为止的所有commit记录

git reset -hard HEAD放弃工作区和index的改动,HEAD指针仍然指向当前的commit

3.git中文件的状态

git仓库中的文件存在三种状态:

①Untracked files:文件未被跟踪

②Changes to be commited:文件已暂存,指向下一次提交的内容

③Changes not staged for commit:已跟踪文件的内容发生了变化,但是还没有放到暂存区

4.Git的四种对象

commit:指向一个tree,它用来标记项目某个特定时间点的状态

一般包含以下信息:

①代表commit的哈希值

②指向tree对象的哈希值

③作者

④提交者

⑤注释

tree:可以简单的理解成这是一个对象关系树,用来管理一些tree和blob

一般包含以下信息:

①代表blob的哈希值

②指向tree对象的哈希值

blob:这种对象用来保存文件内容

tag:给某个提交增添的标记

(画一个比较简陋的对应图,稍微形象一点,哈哈哈,虽然很丑,但自我感觉这个图还是挺直观的)

1640137018_61c2813a5cf516a968612.png!small?1640137017965

5.git对象的哈希值对应关系

每个git对象都有个哈希值代表这个对象,也就是上面所说的键值对的对应形式。这个哈希值是通过SHA算法计算出来的,长度为40个字符。

那么,接下来我们就从实际案例出发,希望能帮助大家更清楚git的内存寻址思想!

首先,初始化一个git仓库:(这时候会产生一个隐藏的.git目录)

1640238267_61c40cbbcc1ecd4dc971a.png!small?1640238267921

观察初始化的时候生成的git目录的内容:(初始化的时候是八个文件)

1640137861_61c284854243899ac85df.png!small?1640137860880

当前目录创建一个文件并写入内容,并利用git add .命令,将更改写入到.git/index文件中,然后再观察.git文件夹的变化(这个步骤相当于“通知”git,我对版本信息做了修改了!麻烦你记录一下哈!--粗浅的理解)

1640238474_61c40d8a38ac54f0d1199.png!small?1640238474329

这时候,对比一下初始化的目录结构,我们可以很清晰的发现多了一个index文件(对应的是二进制文件),我们用winhex等二进制工具打开看看,index文件里面存储的内容是什么?

1640138417_61c286b1bf6b6fb86cb5e.png!small?1640138417423

发现其中存储了,我们刚刚新创建的文件,那么,我们直到git中存储的都是对象信息,那么我们刚才创建的文件也就自然而然在git系统中会以对象的形式被存储,这时候我们去看看对应存储对象的目录中去看看:

1640138583_61c2875753d27c0f1f479.png!small?1640138582957

这时候,我们发现当前目录下多了一个19文件夹,对比刚才index的内容,很轻易的发现,index文件中不仅存储了我们创建的文件名,还有文件在git存储中对应的对象信息:

1640138672_61c287b062f95b1327b06.png!small?1640138672033

而19文件夹打开后发现里面存储的是对应除去开头19的对象对应的“地址”信息:

1640138839_61c2885777e3810a46fdb.png!small?1640138839154

在git中,这些对象存储文件都是通过zlib进行压缩的,所以我们可以使用zlib将其解压出来,来看看这个文件里面存储的内容是什么:

解压代码如下:

import zlib
import requests
urla = "解压文件地址"
re = requests.get(urla)
ss = re.content
word = zlib.decompress(ss)
print(word)

1640143588_61c29ae442a4b2ccc0eee.png!small?1640143587816

解压之后,发现objects对应文件标记了是blob对象,存储的是新建的test.txt文件的内容。

由上面一个简单的过程,就可以很形象的直到git在解析存储版本信息的时候,利用的是内存地址寻址的方式分布式存储版本信息的。

那么,一旦这个.git文件夹泄露,我们就可以通过zlib解压的方式获取到网站的相关版本信息等,进而进行代码审计等操作,分析应用的漏洞以及社工等。

四、Git信息泄露利用总结

首先,我们需要对应的授权站点是否存在这个漏洞:

①可以先观察一下站点是否有醒目地指出Git,如果有的话,那就说明站点很大可能是存在这个问题的

②如果站点没有醒目的提示的话,可以利用dirsearch这类扫描工具,如果存在./git泄露的问题的话,会被扫描出来的,哈哈

③最直观的方式,就是直接通过网页访问.git目录,如果能访问就说明存在

当确认存在这个漏洞之后,就可以通过工具来下载git泄露的全部源码(工具例如:GitHack等等)

关于具体怎么利用,我们就直接利用buuctf中的[GXYCTF2019]禁止套娃来演示一下吧:

1640241525_61c4197592fc07c29d5dd.png!small?1640241525699

1640241636_61c419e4cc37e6aeea77b.png!small?1640241636965

1640242423_61c41cf70199946ea2421.png!small?1640242423596

1640242422_61c41cf6e8e3a42c231e1.png!small?1640242423597

1640242423_61c41cf774f71db89e00b.png!small?1640242423600

通过分析源码发现preg_match()函数过滤传参中的一些关键字,通过解析可以推导出来,允许传入的参数值格式是:A(B(C(…))),这种很明显是函数模式,那么就好说了,我们首先思考一下我们需要做的是什么?

查看目录里面的所有文件,那么php中恰好就有一个函数scandir()浏览目录内的所有文件;--vardump(scandir("."))

我们直到.是代表当前目录的意思,那么也就是说我们要满足scandir中接收的参数是".",而PHP中localeconv() 函数可返回一包含本地数字及货币格式信息的数组 --vardump(scandir(localecnov())))

然后,我们就只需要让指针指向这个数组内的第一个值就好了

exp=vardump(scandir(current(localecnov()))));

尝试访问上面构造的payload:http://586fb95a-e475-4ebb-afe0-2d9a2e8fdcd1.node4.buuoj.cn:81/?exp=vardump(scandir(current(localecnov()))));

1640243525_61c42145e725a48df91af.png!small?1640243526067

这时候,我们可以成功看到有一个flag.php文件

接下来,我们就需要想办法把该文件的内容读取出来:

next() 函数将内部指针指向数组中的下一个元素,并输出。

array_reverse() 函数返回翻转顺序的数组。

exp=show_source(next(array_reverse(scandir(current(localeconv())))));

这段代码是什么意思呢?就还是利用scandir()函数查看当前目录的文件,然后利用next()函数和array_reverse()函数将文件中的内容读取出来,最后调用show_source()函数将内容展示到页面上

1640244075_61c4236bb6bd8b8854914.png!small?1640244075803

这样,这道题就解出来了。。。

五、总结

好了,这个基础的文章就先写到这,关于git泄露如果还有什么奇淫技巧,欢迎大佬们指教。。。哈哈

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年4月20日09:29:28
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Git信息泄露原理解析及利用总结http://cn-sec.com/archives/1681242.html