详解python pickle中的反序列化漏洞

简介: 今天我们来聊聊Python里的反序列化攻击。先来看看什么是序列化和反序列化。简单来说,序列化就是把数据结构转换成字节流,这样我们就可以把数据保存到文件里或者通过网络传输。反序列化则是把这些字节流再转换回原来的数据结构。在Python里,常用的模块之一就是Pickle。它可以帮我们很方便地进行序列化和反序列化操作。比如,你可以把一个复杂的Python对象序列化保存下来,等需要用的时候再反序列化回来。反序列化攻击的概述反序列化过程有漏洞:如果我们反序列化了一个不可信的数据源,那就可能引发反序列化攻击。攻击者可以在序列化的数据里嵌入恶意代码,当你反序列化这个数据时,这些恶意代码就会被执

今天我们来聊聊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则返回一个字节流。

import pickle
# 创建一个对象
data = {'name': 'Alice', 'age': 25, 'city': 'New York'}
# 序列化对象并写入文件
with open('data.pickle', 'wb') as file:
    pickle.dump(data, file)
# 或者返回一个字节流
data_bytes = pickle.dumps(data)

Pickle的反序列化

反序列化就是把字节流还原成Python对象。我们可以用pickle.load和pickle.loads来做这件事。pickle.load从文件中读取字节流并反序列化,pickle.loads则直接反序列化一个字节流。

import pickle
# 从文件中反序列化对象
with open('data.pickle', 'rb') as file:
    data = pickle.load(file)
# 或者直接反序列化一个字节流
data = pickle.loads(data_bytes)

反序列化攻击的原理

攻击机制

现在我们来看看反序列化攻击是怎么回事。攻击者可以在序列化的数据里嵌入恶意代码,当你反序列化这个数据时,这些恶意代码就会被执行。换句话说,如果你从不可信的数据来源反序列化数据,就等于是给了攻击者在你系统里执行代码的机会。


攻击者可以做什么

攻击者可以利用反序列化漏洞执行任意命令、修改或窃取数据。


示例代码

为了更清楚地说明问题,我们来看一个简单的反序列化攻击示例。

import pickle
import os
# 构造恶意代码
class Malicious:
    def __reduce__(self):
        return (os.system, ('echo Hacked!',))
# 序列化恶意对象
malicious_data = pickle.dumps(Malicious())
# 反序列化时执行恶意代码
pickle.loads(malicious_data)

在这个示例中,我们创建了一个名为Malicious的类。这个类的__reduce__方法返回一个元组,第一个元素是os.system,第二个元素是要执行的命令。当我们反序列化这个对象时,os.system('echo Hacked!')会被执行,输出“Hacked!”。


详细解释

  1. 构造恶意代码:我们定义了一个Malicious类,并在__reduce__方法中指定要执行的命令。
  2. 序列化恶意对象:我们用pickle.dumps序列化这个恶意对象。
  3. 反序列化恶意对象:当我们用pickle.loads反序列化这个对象时,__reduce__方法会被调用,并执行指定的命令。

如何防范Pickle反序列化攻击

安全反序列化的原则

防范反序列化攻击的第一原则就是:避免从不可信来源反序列化。只有当你完全信任数据的来源时,才可以使用反序列化。

我们来看一些具体的防御方法和代码示例。


安全的反序列化代码示例

如果必须使用Pickle进行反序列化,可以考虑重载find_class来限定范围限制反序列化的对象类型:

import pickle
import types
# 自定义Unpickler,限制可反序列化的类型
class RestrictedUnpickler(pickle.Unpickler):
    def find_class(self, module, name):
        if module == "builtins" and name in {"str", "list", "dict", "set", "int", "float", "bool"}:
            return getattr(__import__(module), name)
        raise pickle.UnpicklingError(f"global '{module}.{name}' is forbidden")
def restricted_loads(s):
    return RestrictedUnpickler(io.BytesIO(s)).load()

在这个示例中,我们自定义了一个RestrictedUnpickler类,只允许反序列化某些安全的内置类型。


使用其他安全的序列化模块(如JSON)

一个更安全的做法是使用JSON替代Pickle进行序列化和反序列化。JSON只支持基本数据类型,不会执行任意代码,因而更安全。

import json
# 序列化对象
data = {'name': 'Alice', 'age': 25, 'city': 'New York'}
data_json = json.dumps(data)
# 反序列化对象
data = json.loads(data_json)

总结

本文说明了什么是序列化和反序列化,以及Python中的Pickle模块。文中还详细解释了反序列化攻击的原理,并给出了攻击代码示例。最后讨论了如何防范Pickle反序列化攻击,并提供了一些具体的防御方法。如果你有任何问题,欢迎在评论区讨论!

相关文章
|
2月前
|
JSON 数据格式 索引
Python中序列化/反序列化JSON格式的数据
【11月更文挑战第4天】本文介绍了 Python 中使用 `json` 模块进行序列化和反序列化的操作。序列化是指将 Python 对象(如字典、列表)转换为 JSON 字符串,主要使用 `json.dumps` 方法。示例包括基本的字典和列表序列化,以及自定义类的序列化。反序列化则是将 JSON 字符串转换回 Python 对象,使用 `json.loads` 方法。文中还提供了具体的代码示例,展示了如何处理不同类型的 Python 对象。
|
3月前
|
安全 Java Python
基于python-django的Java网站全站漏洞检测系统
基于python-django的Java网站全站漏洞检测系统
41 0
|
3月前
|
存储 JSON 数据格式
Python 输入输出与文件处理: io、pickle、json、csv、os.path 模块详解
Python 输入输出与文件处理: io、pickle、json、csv、os.path 模块详解
46 0
|
5月前
|
安全 网络安全 开发者
探索Python中的装饰器:简化代码,增强功能网络安全与信息安全:从漏洞到防护
【8月更文挑战第30天】本文通过深入浅出的方式介绍了Python中装饰器的概念、用法和高级应用。我们将从基础的装饰器定义开始,逐步深入到如何利用装饰器来改进代码结构,最后探讨其在Web框架中的应用。适合有一定Python基础的开发者阅读,旨在帮助读者更好地理解并运用装饰器来优化他们的代码。
|
5月前
|
安全 应用服务中间件 网络安全
Python 渗透测试:漏洞的批量搜索与利用.(GlassFish 任意文件读取)
Python 渗透测试:漏洞的批量搜索与利用.(GlassFish 任意文件读取)
61 11
|
5月前
|
存储 Python
dill:Python中增强版的pickle
dill:Python中增强版的pickle
133 4
|
4月前
|
JSON 安全 数据格式
7-6|python报错TypeError: can't pickle _thread.RLock objects
7-6|python报错TypeError: can't pickle _thread.RLock objects
|
5月前
|
存储 JSON JavaScript
python序列化: json & pickle & shelve 模块
python序列化: json & pickle & shelve 模块
|
5月前
|
存储 算法 Python
【Leetcode刷题Python】297. 二叉树的序列化与反序列化
LeetCode第297题"二叉树的序列化与反序列化"的Python语言解决方案,包括序列化二叉树为字符串和反序列化字符串为二叉树的算法实现。
30 5
|
5月前
|
安全 网络安全 数据安全/隐私保护
探索Python中的异步编程:从基础到高级网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
【8月更文挑战第26天】在Python的世界中,异步编程是提高效率和性能的关键。本文将引导你了解异步编程的核心概念,通过实际代码示例深入探讨异步IO、协程、任务和异步库的使用。我们将一起构建一个简单的异步Web爬虫,并学习如何优化其性能。无论你是初学者还是有经验的开发者,这篇文章都将为你打开一扇通往高效异步编程世界的大门。