Python Pickle反序列化漏洞
Python序列化与反序列化
Python 的序列化和反序列化是将一个类对象向字节流转化从而进行存储和传输,然后使用的时候再将字节流转化回原始的对象的一个过程
几个重要函数
Pickle.dump():将Python对象序列化保存到本地的文件中。
Pickle.load():载入本地文件,将文件内容反序列化为Python对象。
Pickle.dumps():将Python对象序列化为字符串。
Pickle.loads():将字符串反序列化为Python对象。
序列化
这里通过pickle.dumps()
将Python对象序列化为字符串
1 | import pickle |
得到的字节流为
1 | b'\x80\x04\x95;\x00\x00\x00\x00\x00\x00\x00\x8c\x08__main__\x94\x8c\x06Person\x94\x93\x94)\x81\x94}\x94(\x8c\x04name\x94\x8c\x07ghtwf01\x94\x8c\x03age\x94\x8c\x0219\x94ub.' |
可序列化的对象
None
、True
和False
- 整数、浮点数、复数
- str、byte、bytearray
- 只包含可封存对象的集合,包括 tuple、list、set 和 dict
- 定义在模块最外层的函数(使用 def 定义,lambda 函数则不可以)
- 定义在模块最外层的内置函数
- 定义在模块最外层的类
__dict__
属性值或__getstate__()
函数的返回值可以被序列化的类(详见官方文档的Pickling Class Instances)
反序列化
这里通过Pickle.loads()
将字符串反序列化为Python对象
1 | import pickle |
Python Pickle反序列化漏洞实例
object.___reduce__()函数
__reduce__()
函数和php中的__wakeup__()
一样,都是当该类的对象被反序列化时调用,python要求__reduce__()
返回一个元组,选择栈上第一个对象作为函数、第二个对象作为参数(第二个参数必须为元组),然后调用该函数
漏洞利用实例
1 | import pickle |
[watevrCTF-2019] Pickle Store
抓包页面发现cookie是一段base64
根据题目标题知道可能是Python Pickle反序列化,所以再进行一次反序列化得到
可见这个网站将cookie进行base64解密后再进行Pickle反序列化,因为cookie是我们可控的,所以可以构造恶意的cookie执行命令,比如读取文件/反弹shell,因为我们不知道flag的文件名,所以就采用反弹shell
poc如下
1 | import base64 |
修改cookie成功反弹shell拿到flag
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 ghtwf01!