大家好!首先我做一下自我介绍。我叫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……不错,是吧?顺便说一句,安全小组的成员也写了一篇关于这事的文章。 欢迎加入黑客新闻进行讨论。 事件时间点 所有时间以格林威治标准时间。不重要的信息我就不提了。
原文链接: Reginaldo Silva 翻译: 伯乐在线 - smilesisi 译文链接: http://blog.jobbole.com/58179/ |