.git泄漏原理学习

在打某次比赛时碰到了.git 泄漏的利用,恰好当时没装GitHack 之类的工具。无计可施的同时觉得应该了解下此类工具的原理,遂有了本文。

GitHack

工具的工作原理大佬已经给出了:

  • 解析.git/index文件,找到工程中所有的: ( 文件名,文件sha1 )
  • 去.git/objects/ 文件夹下下载对应的文件
  • zlib解压文件,按原始的目录结构写入源代码

接下来要做的就是去了解下index 文件的格式,https://opensource.apple.com/source/Git/Git-26/src/git-htmldocs/technical/index-format.txt。为了便于理解,这里看下`GtiHack/.git/index` 的文件内容

image-20210918165630774

文件头

文件开始的4个字节为固定的DIRC ,再之后4个字节表示版本信息,此处为2.再之后4个字节表示的是文件索引个数。

image-20210918175438748

文件索引

前16个字节表示各种时间戳

1
2
3
4
5
6
7
8
9
10
11
32-bit ctime seconds, the last time a file's metadata changed
this is stat(2) data

32-bit ctime nanosecond fractions
this is stat(2) data

32-bit mtime seconds, the last time a file's data changed
this is stat(2) data

32-bit mtime nanosecond fractions
this is stat(2) data

之后的24个字节也可以先不用管

image-20210918194143713

再往后的20个字节便是关键的文件所对应的Object的信息,fe 表示在Object目录下的路径、后面的是fe 下的文件名

image-20210918194814201

image-20210918195051557

再往后是文件名长度、文件名,以及一串根据文件名长度计算出来的空字符

image-20210918195655832

空字符的计算方式根据GitHack 可以得到,大概是

1
8 - [(62 + namelen) % 8] or 8

个字节,之后便开始下一个文件直到所有文件被读完。

.git 中的文件是zlib 压缩过的,所以要先解压才可以正常查看

image-20210918200719926

或者是通过git 的命令来恢复原文件

1
git show -s --pretty=raw fe9f45c

image-20210922100617604

GIT对象模型

了解下GIT对象文件结构其实可以更容易的去理解

实际上我们可以通过.git/HEAD、.git/config、.git/packed-reds 获取到commit 对应的 sha值。

image-20210922104310203

然后根据tree 获取到文件信息,使用 git ls-tree 7365379

image-20210922110813860

最后再查看相关文件即可。

GIT打包

git 会时不时的把文件内容打包,或者是手动使用git gc 进行打包,打包后的文件结构如下

image-20210922111744104

可以看到,刚开始的fe/xxx 之类的文件不存在了,取而代之的则是pack文件,使用命令 git verify-pack -v .git/objects/pack/pack-6900a36da7d0d10d3d758195182ae0ba1427ac58.pack 可以查看文件结构

image-20210922112243291

而打包后的文件名可以通过 .git/objects/info/packs 获取到

1
2
3546 ± cat ./objects/info/packs
P pack-6900a36da7d0d10d3d758195182ae0ba1427ac58.pack

参考链接

https://www.leavesongs.com/PENETRATION/XDCTF-2015-WEB2-WRITEUP.html

http://gitbook.liuhui998.com/1_2.html

http://www.lijiejie.com/githack-a-git-disclosure-exploit/