Python pickle 中的 POP 指令码

本文探讨了Python pickle模块中POP指令的作用,主要防止无限递归构造对象。当Pickler检测到递归时,通过POP放弃中间对象并利用memo中的实例,而Unpickler如何处理POP指令来完成反序列化。同时,文章分析了为何Pickler不优化指令序列的原因。
摘要由CSDN通过智能技术生成

事情起源于笔者 2019 年的一篇文章:

从零开始python反序列化攻击:pickle原理解析 & 不用reduce的RCE姿势

前言 不经意间就起了这么长一个题目。昨晚用了4h左右的时间看皮ckle源码(主要是_Unpickler部分),发掘出了几种新的漏洞利用方式,目前网上暂未见资料,因此我们决定写一篇文章分享一下。本文详细介绍了pyckle.l...

正在上传…重新上传取消​知乎专栏阮行止上海洛谷网络科技有限公司 讲师

文中提到,注入恶意对象引发 RCE 之后,常常由于返回的反序列化对象不符合业务代码的预期,造成程序 crash。解决方案是使用 POP 指令码(字节码是数字 )把恶意对象弹出,再压一个正常的对象进去,这样 返回的就是普通的对象,以达成无副作用 RCE 的目的。如下图所示:0pickle.dumps

▲ 先构造恶意对象,再弹出,最后压入正常对象。绿色框内为恶意对象

然后今天收到私信,问 POP 这个指令码有什么用。

这个问题笔者当年确实没有想过。今天翻了一下源码,发现 POP 指令主要是为了防止无限递归构造对象的。下面我们根据 源码进行说明。pickler

0x00 Unpickler 对 POP 的处理方式

首先,我们知道 Unpickler 是一个图灵完备的虚拟机。它的指令编码方式如下:先是一个字节的 op code,然后紧跟操作数。至于操作数的表示方式,也是首先用一个字节表示类型,然后紧跟着操作数。这个虚拟机的语言大体上是一个 LL(1) 型文法,所以 Unpickler 仅通过简单地重复执行「读入一个字节的操作数 - 调用对应 handler」,就可以完成反序列化工作。

Unpickler 每次读入操作数,就查表找到 handler 并调用,handler 会吃掉一些字符,构造一个对象或进行其他操作。具体的 pickle 虚

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值