http://p6.qhimg.com/t013014897786498f37.png

近日,一名来自美国加利福尼亚州的黑客揭露了一种攻击方式,他可以通过这种方法入侵目标用户的Facebook账号,并获取到目标账号的完整访问权。


写在前面的话


在国外,学习如何破解Facebook账号是每一位信息安全初学者的一门必选课。一名来自美国加利福尼亚州的黑客(Gurkirat Singh)揭露了一种攻击方式,他可以通过这种方法入侵目标用户的Facebook账号,并获取到账号的完整访问权。他利用了Facebook密码重置机制中存在的漏洞,并能够成功入侵任何人的Facebook账号。


Gurkirat Singh为何能入侵大量的Facebook账号?


接下来,让我们来看一看攻击者到底是如何实现这种攻击的。目前,如果用户需要重置Facebook账号的密码,那么必须首先输入一个六位的数字密码。这也就意味着,六位数字密码总共有10^6=1000000种可能的组合。当用户申请进行密码重置时,Facebook会随机生成一个六位数字密码并发送给用户,但是用于生成密码的算法中存在严重的设计缺陷:当你通过mbasic.facebook.com页面申请进行密码重置时,系统虽然同样会给你提供一个随机密码,但是如果你没有使用这个密码的话,当你再次申请时,它是不会改变的。这也就意味着,如果有一百万名用户在很短的时间内同时申请进行密码重置,而这些人却不使用这些随机密码的话,那么第10000001个人所请求得到的随机密码肯定与之前那一百万人中某人分配得到的密码相同。

http://p8.qhimg.com/t01b2e8ec7d63be1637.png

如果短时间内出现超过一百万名用户申请进行密码重置的情况,那么这里只有两个选项可供Facebook选择:

(1)将用户分配所得的随机密码副本存储在数据库中,以便进行匹配测试;

(2)通过“某种技术”来确保每一位用户所分配到的随机密码是唯一的;

由于我不太清楚这里所说的“某种技术”到底有没有可能实现,所以我更倾向于选项(1)。

因此,这名黑客决定发送双倍数量的电子邮件,然后祈祷可以在接收邮件的这两百万名用户中找到使用相同随机密码的那个人,这也是“抽屉原理”的一个简单实现。接下来,他所要做的就是按照下面这段选取原则来选择一个随机密码:小于100000的整数密码出现的概率比较小,而300000到699999或者800000到999999之间的整数密码出现的概率较高。虽然这个简单的规则并不是什么所谓的“黄金原则”,但是这个原则在我们进行测试的过程中的确可以帮上不小的忙。那么现在,我们就可以选取一个随机密码了,然后我们将会通过“暴力破解”的方式来找出这两百万名用户中谁手上拿到的密码和我们手中的随机密码相同。

http://p7.qhimg.com/t01aff4e2cf49289996.png

可能你也发现了,这个漏洞其实并没有那么难以理解,但是由于这种攻击技术涉及范围较大,所以实现起来还是有一些难度的。

 

攻击者可以在短时间内发送两百万封密码重置邮件,为什么他的行为不会被系统屏蔽呢?


为了成功发送邮件,首先你需要得到这两百万名用户的Facebook用户名,接下来就是网页爬取技术“展示”自己的时间了。整个过程分成四大步骤:

第一步:

Facebook用户的ID长度通常为十五位(数字),所以黑客决定从ID为100000000000000的用户开始,通过Facebook Graph API来检查这一ID是否为有效的用户ID。由于Facebook对于访问公共数据的行为并没有进行频率限制,所以他还可以访问到目标用户账号的完整名称和资料图片。但是请等一下!Facebook Graph API貌似只允许经过授权的应用程序爬取Facebook用户的用户名啊,难道不是吗?没错,的确是这样。

在你确认了ID是有效的之后,你所要做的就是访问下面这条链接:

1
www.facebook.com/[用户ID]

访问之后,这条URL地址会自动将你重定向至其他的站点,然后将URL中的ID信息更换为目标用户的Facebook用户名。接下来,我们就可以将所有的数据转换为JSON格式。

注意:JSON数据中某些资料照片的URL地址已经失效了。

两百万Facebook用户名:点我下载(文件大小:536M)

第二步:

因为我们要发送两百万封密码重置邮件,所以我们只有不断地向Facebook发送请求才可以实现。但是这样一来,你的IP地址将有可能被Facebook拉黑。为了防止这种情况出现,你需要不断更换你的IP地址。这也就意味着,我们需要使用成千上万个不同的IP地址来模拟出真实的用户场景,用不同的IP地址来发送每一次请求,目前有很多运营商也在提供类似的功能。在我们所描述的这个攻击场景中,所有的网络流量都要流经一个代理服务器,这台服务器会监听所有的HTTP请求,然后为每一个请求分配一个IP地址。

第三步:

当请求到一个随机密码之后,你还需要模拟用户的操作行为。所以我们将需要使用PhantomJS[下载地址]来编写一个多线程的Java脚本,然后再利用这个脚本来为我们JSON文件中的每一位Facebook用户申请随机密码。

第四步:

申请免费试用Google计算引擎,然后将这个脚本托管在虚拟机中。我们可以在四个不同的区域分别架设八台虚拟机(每台配置:12核/20GB内存),然后每台虚拟机托管180个PhantomJS的实例,这样可以将CPU资源的利用率提升到最大化。

按理来说,我应该将这些虚拟机搭建成一个分布式计算系统,但是时间宝贵,这部分并不是关键点。

如下图所示,我们每秒钟可以向服务器端发送923次HTTP请求:

http://p3.qhimg.com/t017e1ac1292021a50f.png

整个攻击过程中最简单的部分:通过暴力破解的方式找出相匹配的随机密码

接下来,我们使用一个六位数字的随机密码(338625),并按照上述的规则来找出能够匹配上的用户ID。在这一过程中,我们需要向服务器端发送URL请求来进行暴力破解。其中,参数“u”中的值为用户ID,参数“n”的值为随机密码:

1
www.beta.facebook.com/recover/password?u=…&n…

接下来,你猜发生了什么?我找到了能够匹配随机密码(338625)的用户ID。在下图中,“Invalid Link”表示用户ID和随机密码匹配失败的情况:

http://p5.qhimg.com/t01262a9b03ac0bd863.png


获得重置密码所需的验证码之后怎么办?


我们需要再访问一次www.beta.facebook.com/recover/password?u=[用户ID]&n=338625,这一次系统将会把我们定向到如下图所示的页面:

http://p7.qhimg.com/t01bcc2bd40b039bf14.png

现在,我们就可以得到这名用户账号的完整访问权了。

Gurkirat Singh的感想和总结


首先,此次我所得到的漏洞奖励金额只有五百美金。因为Facebook认为这个漏洞只能允许他人得到某位用户账号的完整访问权限而已,所以这个漏洞并不是一个高危漏洞(虽然我也不知道他们为什么会这样认为)。