Git和Git文件导致源码泄露
参考文章
Git文件泄露漏洞:https://blog.csdn.net/qq_45521281/article/details/105767428
什么是Git
Git是目前世界上最先进的免费开源分布式版本控制系统,其诞生主要是为了高效管理像 Linux 内核这种规模的庞大项目
什么是版本控制系统
版本控制系统(Version Control System,VCS)是一种在软件开发过程中用于管理文件和项目版本的工具,可以记录文件内容的变化,让用户查看特定版本的文件内容,还能再不同版本之间进行切换,同时也方便团队成员协作开发
版本控制系统类型有:本地版本控制系统、集中式版本控制系统、分布式版本控制系统
本地版本控制系统
这种系统只在本地对文件的不同版本进行管理。它会在本地保存文件的多个版本,通过简单的数据库来记录文件的更新。例如 RCS(Revision Control System),它在本地磁盘上保存补丁集(文件修订前后的差异),通过应用这些补丁集来重现文件的各个版本。
集中式版本控制系统
该系统有一个集中管理的服务器,保存所有文件的修订版本,而协同工作的开发者们的客户端则从服务器获取最新的文件或者提交更新。SVN(Subversion)就是典型的集中式版本控制系统。其优点是方便管理员对版本库进行管理,缺点是依赖中央服务器,若服务器出现故障,团队成员就无法正常工作。
分布式版本控制系统
每个开发者的本地都有完整的版本库副本,包含所有的历史版本信息。Git 是分布式版本控制系统的代表。在分布式系统中,开发者可以在本地进行各种版本控制操作,如提交、创建分支等,不需要依赖网络连接到中央服务器。团队成员之间的协作可以通过推送和拉取操作在不同的本地仓库之间进行。
版本库、工作区和暂存区
版本库
版本库(Repository),也被称作仓库,是版本控制系统的核心组件,用于存储项目的所有文件及其历史版本信息,集中存储项目所有文件版本信息的地方,版本控制系统会对文件的每一次修改进行记录,包括修改的内容、时间、作者等,这些信息都被保存在版本库中。
版本库可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。
本地版本库
存在于开发者本地计算机中的版本库。开发者可以在本地对版本库进行各种操作,如提交、查看历史记录等,无需依赖网络连接。例如使用 Git 时,在项目目录下执行git init
命令就会在本地创建一个版本库。
远程版本库
存储在远程服务器上的版本库,通常用于团队协作开发。团队成员可以从远程版本库克隆项目到本地,进行开发后再将本地的修改推送到远程版本库,与其他成员共享。像 GitHub、GitLab 等平台提供的就是远程版本库服务。
工作区
工作区指的是你在本地计算机里实际操作的项目目录,就是你能够看到并进行文件编辑、创建、删除等操作的文件夹,简单的说就是电脑中看到的目录。
在工作区,你能自由修改文件内容,它独立于版本控制系统的其他部分。版本控制系统一开始并不会自动跟踪你在工作区的修改,只有当你执行特定操作时,这些修改才会被纳入版本控制流程。
假设你使用 Git 管理一个名为my_project
的项目,在本地磁盘上的C:\Users\Username\my_project
目录就是工作区。你可以在这个目录下使用文本编辑器打开文件进行修改,或者创建新文件。
暂存区
暂存区也被叫做索引(index),它是一个中间区域,用于准备要提交到本地仓库的文件修改。当你对工作区的文件进行修改后,可选择将部分或全部修改添加到暂存区。
暂存区再版本库里,版本库就是隐藏目录 .git
分支在实际中有什么用呢?假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。
现在有了分支,就不用怕了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。
.git文件导致的源码泄露
原理
开发人员再开发时,常常会先把源码提交到远程托管网站(如:github
),最后再从远程托管网站把源码pull到服务器的web目录下,如果忘记删除.git
文件,就会导致源码泄露,攻击者就可能会将.git
文件夹直接部署到线上环境,这就引起了git泄露漏洞
git的目录结构
在一个目录中初始化一个仓库以后,Git
会在该目录下创建一个名为.git
的隐藏目录(版本库),这个目录中包含了Git
仓库的所有元数据和对象数据库(就是这个仓库的所有版本等一系列信息),如下
1 |
|
一般来说一个git
仓库会存在以下俩文件
- README.md (项目介绍)
.gitignore
(配置在git进行文件跟踪的时候忽略掉哪些文件 , 从这个文件一般也可以得到一部分网站的目录结构 , 或者一些日志/配置文件等敏感文件)
一般情况下的开发流程
- 初始化仓库 , 并将仓库托管在
Coding
或者Github
上 , 便于远程协作/备份/部署 - 在本地进行网站开发 , 并定时提交
commit
,push
到远程托管网站 - 当一个阶段的开发差不多的时候 , 需要远程登陆服务器 , 通过托管网站再将发行版网站
pull
到Web
目录下 - 网站正常运行
这里当网站维护开发人员在从托管网站pull
代码的时候,也会将这个存储了所有版本信息的.git
文件夹下载到服务器的Web
目录下,因此攻击者就可以利用这个目录去下载git
文件夹,可以利用其中存储的版本控制信息,完全恢复网站后台的代码和目录结构
如何利用漏洞
利用爬虫
爬虫爬取整个git目录 (这个方法比较原始 , 需要具有一定的Git经验 , 和使用Githack
这个工具相比 , 有一个比较好的地方就是 , 可以完全模拟服务器上的代码环境 , 可以跟踪到git的每一次提交 , 但是Githack
好像只可以将源码恢复到最近的一次提交,这里的好处还有可以去查看git
的提交日志 , 这个日志信息中会有开发人员对每一次commit
的描述 , 比如某个BUG的修复等等 , 对于这些和BUG相关的地方 , 可以有针对性地进行白盒审计 , 有可能这个BUG修复了还不如没修复 , 可能会造成更大的漏洞)
具体思路
- 利用爬虫递归下载
.git
目录的所有文件 - 利用git命令对网站的commit历史进行查看
- 利用git命令对网站的源码进行恢复
具体操作
演示网站 : http://www.xxx.com/.git/
- 在虚拟机中利用
wget
对该目录进行递归下载(-r)
1 |
|
- 下载完成后 , 进入下载的网站目录
- 利用命令 :
git log
查看网站的提交记录 - 利用命令 :
git reset --hard [log hash]
恢复到指定版本号 (一般如果只需要得到源码的话就恢复到最近的一次提交)
如何防御
- 对.git目录的访问权限进行控制
- 在每次pull到web目录下之后删除.git文件夹
利用GitHack
脚本
GitHack
是一个.git
泄露利用脚本,通过泄露的.git
文件夹下的文件,还原重建工程源代码。
GitHack
脚本下载地址:https://github.com/lijiejie/GitHack
GitHack
脚本的工作原理
- 解析
.git/index
文件,找到工程中所有的: ( 文件名,文件sha1 ) - 去
.git/objects/
文件夹下下载对应的文件 - 使用
zlib
解压文件,按原始的目录结构写入源代码
使用方法
1 |
|
还原后的文件在 dist/
目录下
工作流程
- 尝试获取
packs
克隆 - 尝试目录遍历克隆
- 尝试从缓存文件(index)、commit记录中恢复
CTF做题实战
题目一
题目来源
看着是要SQL注入,但实际上是要进行.git
泄露,这里用GitHack
脚本进行泄露
1 |
|
可以看到源码下载到了这个hint.php
文件中了,源码如下
1 |
|
这里考查sprintf
漏洞,之后的见另一个笔记sprintf漏洞
题目二
题目来源
NSSCTF–git泄露
利用GitHack
脚本下载得到源码
1 |
|
源码如下
1 |
|