我如何发现Facebook服务器中的远程代码执行漏洞:OpenID中的XML外部实体扩展漏洞

大家好!首先我做一下自我介绍。我叫Reginaldo Silva,是一名巴西籍的计算机工程师。最近我的工作与信息安全有关,尤其是在Web应用程序安全性的方面。如果可以的话,我很乐意给大家演示如何入侵网站和应用程序。我的主页上有一些相关信息,欢迎大家浏览。

今天,我想讲一下我发现一个影响Facebook的远程漏洞代码的过程。正如一般的故事开头那样,这一过程也是在很长时间以前就开始了(实际上仅仅是一年多,但我一然感觉很漫长)。如果你觉得这个话题很有趣,或者想让我帮你在你的(或你公司的)代码中做一些有关审查和渗透测试的安全问题,请发邮件给我。我的邮箱是reginaldo@ubercomp.com

2012年的9月22日对我来说是个特别的日子,因为那天我发现了一个XML外部实体扩展(XXE)漏洞,它能影响Drupal管理OpenID的那部分功能。XML外部实体的功能很强大,它能读文件系统中的所有文件,能连接任意网络。如果你想寻求刺激,你可以用billion laughs进行DoS攻击。

最开始我并没有在意其他人也存在这样的漏洞,当我发现时,我立即将其提交到CVE上。这是我的第一个贡献,所以从那以后我将这条信息写在了简历上(这条漏洞的编号是CVE-2012-4554)。五天后,我突然想到OpenID的应用很广,因此,其它地方也可能存在这样的漏洞。我检查了一下StackOverflow的登录方式,发现的确存在漏洞,而且可危及整个网站。

然后,我准备查找谷歌服务器中的OpenID 代码。虽然我无法打开文件,无法进行网络连接,但谷歌的应用引擎和博客平台都很容易受到DoS攻击。这个漏洞让我赚到了第一桶金,大约有500美元。

在向谷歌报告了这个漏洞后,我又测试了几个实例,最后发现,这个漏洞正在危及许多系统。这里就不列举具体内容了,但是用Java, C#, PHP, Ruby, Python, Perl等语言编写的运行库或多或少都存在问题。不公布的原因是因为这些系统实在太脆弱了。一个了解安全机制的人可以读取OpenID 和XML外部实体,然后就能一段恶意代码进行攻击。哎呀,我有些跑题了。

之后我联系了一些编写OpenID库的开发者,有些作者只把安全列表托管在了OpenID基金会上面,我又给他们发了一篇题为“一个可以掌控一切的漏洞:运用XML外部实体实现 OpenID中的脆弱性”的邮件来说明这一问题。我想大部分库作者都是列表中的成员,所以补丁将会发给他们每个人。我自以为做得很好了,事实上,我才走了一小步而已。

跟我经常交流的读者依然有这样的问题:Facebook的远程代码执行漏洞到底是什么?它竟然使我们做到这种程度。过去,Facebook使用OpenID进行登录。然而,当我在2012年第一次发现OpenID漏洞的时候,我就找不到任何能进入任意OpenID网址的终结点。以前可以在

e 动些手脚,现在consumer_helper.php节点已经关闭了。一年后我以为Facebook的安全性有所提高,但我又测试了一下忘记密码得到了这样的结果:

那时候我开始怀疑Facebook还是存在一年前我发现的那个漏洞的危害。然后我做了许多测试证明了这个猜想。简言之,如果你忘记密码了,你可以向Facebook说明你有一个@gmail.com的邮箱,然后登录自己邮箱后,把自己的信息提交给Facebook。这实际上是用邮箱登进Facebook的,这种登录方式就是基于OpenID的。到目前为止,一切都进展的不错,只是我自己遇到了些问题。我知道,由于工作的失误,OpenID的依赖方需要向已被控制的OpenID提供商(OP)发送一个Yadis发现请求,比如说http://www.ubercomp.com/。然后我的恶意提供商就会回复一个恶意的XML,它被依赖方解析,从而遭受XXE攻击。

因为我没有干预原始的OpenID请求(Facebook 与 Google之间的直接请求),实际上我没有机会进入在我控制下的作为OpenID标示符的网址,也没有让Facebook发送Yadis发现请求到这个网站。所以,我想这种错误应该不会发生了,除非我能获取谷歌到Facebook的那段恶意XML,而这种可能性极低。幸运的是,我错了。在仔细阅读了OpenID 2.0规范后,第11.2节验证发现的信息写到:

如果声明的标示符没有事先告诉依赖方(“openid标识”可以是“http://specs.openid.net/auth/2.0/identifier_select”,或是不同的标示符,或是OP发送的标识判断),依赖方必须提出来,以确保该OP有权对声称的身份标识做出判断。

我看了一下,openid标识果真是http://specs.openid.net/auth/2.0/identifier_select。实际上许多系统使用的都是这个。在几分钟后,我向 https://www.facebook.com/openid/receiver.php 发了一个请求,它可以让Facebook向一个被我控制的网站发送一个Yadis请求。之后会返回包含恶意XML的响应。 当我向Facebook服务器请求打开/dev/random,服务器不会返回响应,而且几分钟后请求会失效。即使如此,我还是不能打开任意文件。我尝试了许多XXE,包括各种组合和参数实体,但还是一无所获。然后我突然意识到在此过程中是存在一些问题的,改正之后……

没错,响应中包含了Facebook的/etc/passwd。现在,我们可以随意访问了。我觉得我发现了通向王国的道路。通过Facebook 服务器视图节点能够读取任意文件和进行网络连接,视图节点不需要代理,这可是 Facebook不惜高成本建立的。随后我又有了新想法,觉得应该将其形成一个完整远程执行程序。

网络中漏洞奖励计划是非常好的方式,它也有自己的规则:不管何时发现了漏洞,请不要犹豫。将其按程序提交,安全小组会全面考虑,并向支付相应的报酬。起初,我并不信任 Facebook的安全小组,并且认为他们不会把我提交的漏洞看做是远程代码执行漏洞。我不想造成误解,所以我决定立即提交,然后我申请了一个权限进行RCE升级。升级完毕后,它可以正常运行。我想这应该没什么问题了。因为大部分漏洞都需要花很长时间来处理,我有足够的时间升级RCE,同时我觉得我是一个优秀的白帽黑客。在写完漏洞报告后,我决定出去走走,顺便吃个午餐,回来之后继续工作。

然而,我又错了,因为这是一个严重的漏洞,吃过午饭后,我加快了速度。我把报告发出去不到2个小时,让我既难忘又难过,但因为我知道如何升级远程代码执行漏洞,我将如何修复告诉了安全小组。当他们测试攻击是否有效时,我很相信他们给出的结论。我为我的作为而高兴。在接到一些反馈和4封邮件后,安全小组确认我的攻击是安全的,我发现的RCE的确能影响他们的服务器。

所以这就是攻击的入口,即我迄今发现的第一个高冲击漏洞。它大概也是悬赏最高的漏洞之一。另外,我还可以吹牛说我攻入了Facebook……不错,是吧?顺便说一句,安全小组的成员也写了一篇关于这事的文章。

欢迎加入黑客新闻进行讨论。

事件时间点

所有时间以格林威治标准时间。不重要的信息我就不提了。

  •  2013-11-19 15:51: 写报告
  •  2013-11-19 17:37: 安全小组成员Godot感谢我的发现
  •  2013-11-19 17:46: 我得到了可以读任意文件的答复
  •  2013-11-19 19:31: 安全小组成员 Emrakul通知我短暂的修复将持续30分钟。
  •  2013-11-19 20:27: 我确信漏洞已被修复。
  •  2013-11-21 20:03: 获得酬金。安全小组说这是他们目前支付的最高金额。
  •  2013-11-22 2:13: 我发了封邮件,询问安全小组把漏洞看做是RCE还是仅仅是文件泄露。
  •  2013-11-23 1:17: 安全小组回复说,他们认为攻击不能升级到RCE。
  •  2013-11-23 19:54: 我解释说明如何进行升级
  •  2013-11-24 21:23: Facebook 回复说我的攻击起作用了,他们会进行处理的。
  •  2013-12-03 4:45:  Facebook 通知我说修复会持续一段时间,他们准备讨论一个新的报酬计划。
  •  2013-12-03 19:14: 我双手交叉,向他们表示感谢。
  •  2013-12-13 13:04: 我看到了一篇引自Ryan McGeehan的一篇文章,Ryan负责管理Facebook的事件响应部门,他说“如果有一个价值百万美元的漏洞,那么我们愿意支付”。然后又询问了一下他们是否有新消息。
  • 2013-12-30 4:45: Facebook通知我说漏洞已经成为了RCE,所以费用会更高。我不会透漏具体数额,你可以猜一猜,然后说出来。当然我也不会得到一百万那么多,我引用McGeehan的话仅仅是为了娱乐一下,不要当真。
收藏 评论

关于作者:smilesisi

简介还没来得及写 :) 个人主页 · 我的文章 · 2

相关文章

可能感兴趣的话题



直接登录
跳到底部
返回顶部