Git是目前世界上最先进的分布式版本控制系统(没有之一)。
Git有什么特点?简单来说就是:高端大气上档次!
那什么是版本控制系统?
如果你用Microsoft Word写过长篇大论,那你一定有这样的经历:
想删除一个段落,又怕将来想恢复找不回来怎么办?有办法,先把当前文件“另存为……”一个新的Word文件,再接着改,改到一定程度,再“另存为……”一个新文件,这样一直改下去,最后你的Word文档变成了这样:
过了一周,你想找回被删除的文字,但是已经记不清删除前保存在哪个文件里了,只好一个一个文件去找,真麻烦。
看着一堆乱七八糟的文件,想保留最新的一个,然后把其他的删掉,又怕哪天会用上,还不敢删,真郁闷。
更要命的是,有些部分需要你的财务同事帮助填写,于是你把文件Copy到U盘里给她(也可能通过Email发送一份给她),然后,你继续修改Word文件。一天后,同事再把Word文件传给你,此时,你必须想想,发给她之后到你收到她的文件期间,你作了哪些改动,得把你的改动和她的部分合并,真困难。
于是你想,如果有一个软件,不但能自动帮我记录每次文件的改动,还可以让同事协作编辑,这样就不用自己管理一堆类似的文件了,也不需要把文件传来传去。如果想查看某次改动,只需要在软件里瞄一眼就可以,岂不是很方便?
这个软件用起来就应该像这个样子,能记录每次文件的改动:
版本 | 文件名 | 用户 | 说明 | 日期 |
---|---|---|---|---|
1 | service.doc | 张三 | 删除了软件服务条款5 | 7/12 10:38 |
2 | service.doc | 张三 | 增加了License人数限制 | 7/12 18:09 |
3 | service.doc | 李四 | 财务部门调整了合同金额 | 7/13 9:51 |
4 | service.doc | 张三 | 延长了免费升级周期 | 7/14 15:17 |
这样,你就结束了手动管理多个“版本”的史前时代,进入到版本控制的20世纪。
其实经常会用到git,例如在用hexo+github pages搭建博客的时候就用到了git,又如在linux下载一些工具的时候,用到的git clone。
git:分布式版本控制系统。
首先,何为版本控制系统?以git的诞生故事来解释,linus在开发linux的时候,有世界广大热心的志愿者的帮助,最开始都是志愿者把源码down下来改了后在发给linus,linus再手工合成。当然linux源码大了后自然很不方便,又由于CVS、SVN(集中式版本控制系统)慢且需联网,又经历了一些事件后,linus用C语言开发了git,此后,源码的每次改动都会有记录,即每个版本都有记录。其实可以类比gitbub的功能。
何为分布式?分布式即与集中式对立,集中式是有一个中央服务器来存储源码,用户每次修改源码都需要从中央服务器把源码down下来,修改后再提交到中央服务器。而分布式则是每个人电脑里都有完整的版本库。
先说集中式版本控制系统,版本库是集中存放在中央服务器的,而干活的时候,用的都是自己的电脑,所以要先从中央服务器取得最新的版本,然后开始干活,干完活了,再把自己的活推送给中央服务器。中央服务器就好比是一个图书馆,你要改一本书,必须先从图书馆借出来,然后回到家自己改,改完了,再放回图书馆。
集中式版本控制系统最大的毛病就是必须联网才能工作,如果在局域网内还好,带宽够大,速度够快,可如果在互联网上,遇到网速慢的话,可能提交一个10M的文件就需要5分钟,这还不得把人给憋死啊。
那分布式版本控制系统与集中式版本控制系统有何不同呢?首先,分布式版本控制系统根本没有“中央服务器”,每个人的电脑上都是一个完整的版本库,这样,你工作的时候,就不需要联网了,因为版本库就在你自己的电脑上。既然每个人电脑上都有一个完整的版本库,那多个人如何协作呢?比方说你在自己电脑上改了文件A,你的同事也在他的电脑上改了文件A,这时,你们俩之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。
和集中式版本控制系统相比,分布式版本控制系统的安全性要高很多,因为每个人电脑里都有完整的版本库,某一个人的电脑坏掉了不要紧,随便从其他人那里复制一个就可以了。而集中式版本控制系统的中央服务器要是出了问题,所有人都没法干活了。
在实际使用分布式版本控制系统的时候,其实很少在两人之间的电脑上推送版本库的修改,因为可能你们俩不在一个局域网内,两台电脑互相访问不了,也可能今天你的同事病了,他的电脑压根没有开机。因此,分布式版本控制系统通常也有一台充当“中央服务器”的电脑,但这个服务器的作用仅仅是用来方便“交换”大家的修改,没有它大家也一样干活,只是交换修改不方便而已。
版本库:
什么是版本库呢?版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。
对理解git工作原理的重要知识点:工作区和暂存区
工作区就是电脑里看到的目录。
暂存区在版本库里,版本库就是隐藏目录.git。一张图明了。stage是暂存区,master是分支,我觉得就是所有文件存储的地方。
分支就是科幻电影里面的平行宇宙,当你正在电脑前努力学习Git的时候,另一个你正在另一个平行宇宙里努力学习SVN。
如果两个平行宇宙互不干扰,那对现在的你也没啥影响。不过,在某个时间点,两个平行宇宙合并了,结果,你既学会了Git又学会了SVN!
分支在实际中有什么用呢?假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。
现在有了分支,就不用怕了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。
我们把文件往git版本库添加的时候,分两步:
1、git add :文件添加到暂存区
2、git commit :暂存区的所有文件添加到master
该回到正题了…
开发人员在开发时,常常会先把源码提交到远程托管网站(如github),最后再从远程托管网站把源码pull到服务器的web目录下,如果忘记把.git文件删除,就造成此漏洞。利用.git文件恢复网站的源码,而源码里可能会有数据库的信息。
当前大量开发人员使用git进行版本控制,对站点自动部署。 如果配置不当,可能会将.git文件夹直接部署到线上环境,这就引起了git泄露漏洞。
在一个目录中初始化一个仓库以后 , 会在这个目录下产生一个名叫 .git
的隐藏文件夹(版本库)这个文件夹里面保存了这个仓库的所有版本等一系列信息
后记 : (一般来说 , 一个git仓库还存在这两个文件 : )
- README.md (项目介绍)
- .gitignore (配置在git进行文件跟踪的时候忽略掉哪些文件 , 从这个文件一般也可以得到一部分网站的目录结构 , 或者一些日志/配置文件等敏感文件)
一般情况下 , 开发人员为了让版本控制和网站部署比较方便 , 在开发的时候就会走这样的流程
1.初始化仓库 , 并将仓库托管在Coding或者Github上 , 便于远程协作/备份/部署
2.在本地进行网站开发 , 并定时提交commit , push到远程托管网站
3.当一个阶段的开发差不多的时候 , 需要远程登陆服务器 , 通过托管网站再将发行版网站pull到Web目录下
4.网站正常运行
这里当网站维护(开发)人员在从托管网站pull代码的时候 , 也会将这个储存了所有的版本信息的.git
文件夹下载到服务器的Web目录下 , 这样的话 , 攻击者就可以利用这个目录 , 去下载git文件夹 , 就可以利用其中储存的版本控制信息,完全恢复网站后台的代码和目录结构 , 当然 , 一般网站都会涉及到数据库操作 , 而一般来说 , 需要链接数据库就需要用户名/密码/端口/库名等信息 , 而这些信息肯定会在网站后台的源码里面又体现 , 因此这种情况是极其危险的 , 还有 , 一旦服务器开放了数据库的远程连接功能 , 攻击者就可以利用从源码中找到的数据库用户名和密码对远程数据库进行登陆 , 危险性不言而喻。
(1) GitHack是一个.git泄露利用脚本,通过泄露的.git文件夹下的文件,还原重建工程源代码。渗透测试人员、攻击者,可以进一步审计代码,挖掘:文件上传,SQL注射等安全漏洞。
脚本的工作原理:
- 解析.git/index文件,找到工程中所有的: ( 文件名,文件sha1 )
- 去.git/objects/ 文件夹下下载对应的文件
- 使用zlib解压文件,按原始的目录结构写入源代码
(2) 爬虫爬取整个git目录 (这个方法比较原始 , 需要具有一定的Git经验 , 这里先重点介绍这种方法 , 但是这种方法和使用githack这个工具相比 , 有一个比较好的地方就是 , 可以完全模拟服务器上的代码环境 , 可以跟踪到git的每一次提交 , 但是githack好像只可以将源码恢复到最近的一次提交,这里的好处还有可以去查看git的提交日志 , 这个日志信息中会有开发人员对每一次commit的描述 , 比如某个BUG的修复等等 , 对于这些和BUG相关的地方 , 可以有针对性地进行白盒审计 , 有可能这个BUG修复了还不如没修复 , 可能会造成更大的漏洞)
具体利用思路 :
- 利用爬虫递归下载.git目录的所有文件
- 利用git命令对网站的commit历史进行查看
- 利用git命令对网站的源码进行恢复
具体操作 :
演示网站 : http://www.xxx.com/.git/
1.在虚拟机中利用wget对该目录进行递归下载(-r)wget -r -p -np -k http://www.xxx.com/.git/ --recursive(递归) -k, --convert-links(转换链接) -p, --page-requisites(页面必需元素) -np, --no-parent(不追溯至父级)
2.下载完成后 , 进入下载的网站目录
3.利用命令 :git log
查看网站的提交记录
4.利用命令 :git reset --hard [log hash]
恢复到指定版本号 (一般如果只需要得到源码的话就恢复到最近的一次提交)
GitHack
.git
泄漏利用工具,可还原历史版本
使用前需确保 git 在 环境变量中
python GitHack.py http://www.example.com/.git/ #别忘了最后的.git
还原后的文件在 dist/
目录下
packs
克隆首先进入题目的页面。发现页面挺像git的的,Git有什么特点?简单来说就是:高端大气上档次!
说是猜对相应个数的数字拿到相应的钱。
按其要求登录。然后看到以下界面。
还说让我们买这个flag,应该是买到手之后就能拿到flag,可是钱不够啊
御剑扫描目录,发现了robots.txt (robots协议) ,进入查看
很明显是.git泄露了
也可以直接用dirsearch目录扫描器直接把/.git/给扫出来
进入.git/目录,用神器 GitHack 下载源码。
提取.git泄露的源码,得到许多文件:
应该是买到手之后就能拿到flag,如果是这个flag就在.git里,那就好办了,尝试配合grep命令在这些文件中查找flag,并没有结果,要想有钱买flag,首页就给我们提供了一个方法:
买彩票猜数就行了,但是怎么能猜对?这就要审计一下代码,找找漏洞了。
经过一番审计,猜数字对应的函数在api.php中:
说明: 结合源码可知,就是把你的数字与$win_numbers的数字一位一位的比较。
我们要绕过这个$win_numbers
,$win_numbers
我们是无法控制的,毕竟函数在人家服务器上运行,我们只能输入数字,那么就只能在输入上做文章了,89行判断相等的数字个数时,用的是==,这不就是个弱类型漏洞吗,bool类型的true是可以和任何数据弱类型相等的,于是输入,抓包改包来不停地repeater刷钱:
burp改包,构造{“0”:true,”1”:true,”2”:true,”3”:true,”4”:true,”5”:true,”6”:true}来使恒等:( 或者[true,true,true,true,true,true,true] )
刷钱就是爽。。。钱够之后去买flag即可: