详解 python pickle 中的反序列化漏洞
引言
今天我们来聊聊 Python 里的反序列化攻击。先来看看什么是序列化和反序列化。简单来说,序列化就是把数据结构转换成字节流,这样我们就可以把数据保存到文件里或者通过网络传输。反序列化则是把这些字节流再转换回原来的数据结构。
在 Python 里,常用的模块之一就是 Pickle。它可以帮我们很方便地进行序列化和反序列化操作。比如,你可以把一个复杂的 Python 对象序列化保存下来,等需要用的时候再反序列化回来。
反序列化攻击的概述
反序列化过程有漏洞:如果我们反序列化了一个不可信的数据源,那就可能引发反序列化攻击。攻击者可以在序列化的数据里嵌入恶意代码,当你反序列化这个数据时,这些恶意代码就会被执行,可能会导致数据泄露、系统崩溃,甚至让攻击者远程控制你的系统。
Python Pickle 模块概述
Pickle 的基本功能
Pickle 模块是 Python 自带的,它主要用来序列化和反序列化 Python 对象。你可以用 Pickle 把任何 Python 对象(包括复杂的数据结构)保存成字节流,然后在需要的时候再加载回来。
Pickle 的工作原理
Pickle 的工作原理其实很简单。序列化的时候,它会把 Python 对象转换成字节流,反序列化的时候,它会把字节流还原成 Python 对象。下面我们来看几个具体的例子。
Pickle 的序列化
序列化就是把 Python 对象转换成字节流。我们可以用 pickle.dump 和 pickle.dumps 来做这件事。pickle.dump 把对象序列化后写入文件,pickle.dumps 则返回一个字节流。
Pickle 的反序列化
反序列化就是把字节流还原成 Python 对象。我们可以用 pickle.load 和 pickle.loads 来做这件事。pickle.load 从文件中读取字节流并反序列化,pickle.loads 则直接反序列化一个字节流。
反序列化攻击的原理
攻击机制
现在我们来看看反序列化攻击是怎么回事。攻击者可以在序列化的数据里嵌入恶意代码,当你反序列化这个数据时,这些恶意代码就会被执行。换句话说,如果你从不可信的数据来源反序列化数据,就等于是给了攻击者在你系统里执行代码的机会。
攻击者可以做什么
攻击者可以利用反序列化漏洞执行任意命令、修改或窃取数据。
示例代码
为了更清楚地说明问题,我们来看一个简单的反序列化攻击示例。
在这个示例中,我们创建了一个名为 Malicious 的类。这个类的__reduce__方法返回一个元组,第一个元素是 os.system,第二个元素是要执行的命令。当我们反序列化这个对象时,os.system('echo Hacked!')会被执行,输出“Hacked!”。
详细解释
构造恶意代码:我们定义了一个 Malicious 类,并在__reduce__方法中指定要执行的命令。
序列化恶意对象:我们用 pickle.dumps 序列化这个恶意对象。
反序列化恶意对象:当我们用 pickle.loads 反序列化这个对象时,__reduce__方法会被调用,并执行指定的命令。
如何防范 Pickle 反序列化攻击
安全反序列化的原则
防范反序列化攻击的第一原则就是:避免从不可信来源反序列化。只有当你完全信任数据的来源时,才可以使用反序列化。
我们来看一些具体的防御方法和代码示例。
安全的反序列化代码示例
如果必须使用 Pickle 进行反序列化,可以考虑重载 find_class 来限定范围限制反序列化的对象类型:
在这个示例中,我们自定义了一个 RestrictedUnpickler 类,只允许反序列化某些安全的内置类型。
使用其他安全的序列化模块(如 JSON)
一个更安全的做法是使用 JSON 替代 Pickle 进行序列化和反序列化。JSON 只支持基本数据类型,不会执行任意代码,因而更安全。
总结
本文说明了什么是序列化和反序列化,以及 Python 中的 Pickle 模块。文中还详细解释了反序列化攻击的原理,并给出了攻击代码示例。最后讨论了如何防范 Pickle 反序列化攻击,并提供了一些具体的防御方法。如果你有任何问题,欢迎在评论区讨论!
作者:大鲸鱼 crush
链接:https://juejin.cn/post/7383342927508701235
评论