SVN和GIT信息泄漏利用原理及现状

1,google hack

svn 搜索技巧
图1
git 搜索技巧
图2

2,svn信息利用原理

2.1 svn<=1.6

从svn的结构图可以看到一个目录text-base,这里有我们源文件的备份,比如要下载somedomain/phpinfo.php,直接访问目录somedomain/.svn/text-base/phpinfo.php.text-base,一般的服务器既不会阻止该目录也不会解释该后缀,我们就可以直接读到本地来。现在只是访问最顶层的文件信息,那怎么遍历呢?这里面就有.svn/entries,这个文件包含着该基础目录下所有的文件和目录,直接递推查找就行。

2.2 svn>1.6

svn在1.6之后引入了wc.db来管理文件,该文件位于.svn/wc.db。普通文件位置:somedomain/.svn/pristine/“XX”/“CHECKSUM”.svn-base,CHECKSUM是文件的sha1值,xx则是他的前两位。那这个CHECKSUM去哪找呢?就是我们刚才提到的wc.db,这是一个sqlite数据库。数据库的大体结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
$ sqlite3 wc.db .tables
ACTUAL_NODE NODES PRISTINE WC_LOCK
EXTERNALS NODES_BASE REPOSITORY WORK_QUEUE
LOCK NODES_CURRENT WCROOT
$ sqlite3 wc.db 'select local_relpath, checksum from NODES'
index.php|$sha1$4e6a225331f9ae872db25a8f85ae7be05cea6d51
scripts/menu.js|$sha1$fabeb3ba6a96cf0cbcad1308abdbe0c2427eeebf
style/style.js|$sha1$2cc5590e0ba024c3db77a13896da09b39ea74799
$ sqlite3 wc.db 'select local_relpath, ".svn/pristine/" || substr(checksum,7,2) || "/" || substr(checksum,7) || ".svn-base" as alpha from NODES;'
index.php|.svn/pristine/4e/4e6a225331f9ae872db25a8f85ae7be05cea6d51.svn-base
scripts/menu.js|.svn/pristine/fa/fabeb3ba6a96cf0cbcad1308abdbe0c2427eeebf.svn-base
style/style.js|.svn/pristine/2s/2cc5590e0ba024c3db77a13896da09b39ea74799.svn-base

第一步下载wc.db,然后从NODES表中找到文件名和其sha1值,最后构造下载链接。

3,git 信息利用原理

首先从git/config信息里面可以得到仓库地址

1
2
3
4
5
6
7
8
9
10
11
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
url = git@git.jingdigital.net:root/pcb001.git
[branch "master"]
remote = origin
merge = refs/heads/master

基本上三步走:
(1)下载.git/index文件,这是一种git特有的格式,在该文件中包含着文件名和文件SHA1值。
(2)根据该文件SHA1值到objects目录下载相应文件,具体路径somedomain/.git/objects/“XX”/“CHECKSUM”
(3)zlib解压文件,按照原始目录写入源代码。

4,对国内80端口的简单扫描

有了前面这些基础,就可以通过泄漏的信息来还原代码,能还原代码的话就可以干很多事了。最常见就是代码中泄漏email地址,数据库连接方式,调试接口,一些第三方key的泄漏。另外还可以对你感兴趣的目标进行代码审计,发现注入,命令执行等等。

4.1 扫描实现

(1)从文件读取80ip段数据,设最大并发16,最大连接数60,这个时候的带宽基本控制在600KB,利用周末时间跑了一天即可跑完。
(2)设置pycurl的一些参数,如PROXY,MAXREDIRS=0,这样就不跳转了,nosignal=1 这个参数必须为1,这是pycurl的一个bug,中间测试的过程中就是因为参数未加,导致跑了半天结果中途挂了。
(3)请求/.git/config信息,如果200,返回的类型为text/plain并且存在repositoryformatversion字段。请求/.svn/entries,如果200,Content-Type为text/plain,并且dir存在于返回值。其实这个是有误的,因为在svn大于1.6的情况下,在返回值中只有一个简单的数字,并不存在dir,所以扫描结果中基本上没有1.6以上的结果。

4.2 结果过滤

在扫描的结果中分析出现的url,有些.svn/entries返回200,但是首页确是有问题,还有发现某些ip不在中国。于是写了脚本去请求这些url的首页,并且从一个ip查询网站去查询ip地址归属。

4.3 初步结果

在525万80端口数据中,跑出6000条结果,相当于千分之一的概率,另外还未包括前面对svn 1.6判断有误的分析,所以这个概率还是很高的。
简单的分析了git信息的泄漏,总共有接近600条数据,去除在国外的和首页不正常的,能达到250多,其中差不多一半的都是在阿里云的ip上,这些公司一般都是创业公司。在这些泄漏的代码中sql注入一般很少。
svn的话,一般都是一些比较老的网站,这主要可能还是我前面的判断逻辑有点小问题。注入问题比较严重。