提醒!Python 的 pickle 模块可能导致命令执行

Python七号

共 1034字,需浏览 3分钟

 ·

2022-05-16 15:37

你好,我是征哥,提到 Python 的 pickle 模块,我经常用它保存运行时的对象,以便重启程序后可以恢复到之前的状态。今天发现了它在恢复 Python 对象时存在远程命令执行的安全问题,所以后面如果你的数据来自用户输入,那最好不用 pickle,用 json,官方文档也有警告和建议:

接下来来看一下它是如何导致命令执行的。

Python 的 pickle 可以很方便的把 Python 的对象以二进制的形式保存在文件中(封存),也很容易恢复(解封):

import pickle 

x = [1,2,3]
pickle.dump(x,open("test.pkl","wb"))
y = pickle.load(open("test.pkl","rb"))
assert x == y

上面的代码 x 是一个列表,它是安全的,假如 x 是黑客在浏览器端发送的数据,他可以精心构造出这样一个类 Exp,里面可能有各种危险的命令,假如是一个 ls -l 这样的信息收集:

class Exp(object):
    def __reduce__(self):
        return (os.system,('ls -l',))

x = Exp()
pickle.dump(x,open("test.pkl","wb"))
y = pickle.load(open("test.pkl","rb"))
assert x == y

执行上面的代码,就会发现 ls -l 已经执行:

这里来解释一下魔法函数 __reduce__:

首先来看一下官方的函数说明:

其中红色框里面是本例子中用到的情形,要注意的是,魔法函数__reduce__ 会在 unpickling(解封) 时调用,用于自定义对象的解封方式,如果返回的是元组,那第一个必须是函数,第二个就是函数的参数,而且这个函数会被调用。

因此 os.system('ls -l') 被执行。

最后的话

Python 标准库的漏洞还真的不多,vulhub[1] 上关于 Python 标准库的漏洞也就 3 个:PIL 2 个,Pickle 1 个,感兴趣可以研究下。本文分享了 Pickle 的安全问题,希望给你写代码的时候提个醒,如有帮助,还请关注一下,欢迎留言讨论

参考资料

[1]

vulhub: https://github.com/vulhub/vulhub/tree/master/python


浏览 32
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报