Table of Contents

前言

不会挖洞,选择找题填补知识点空缺,做题中遇到一个关于python反序列化的知识点,做下笔记 # python反序列化 有了php反序列化的基础,看一看这篇就足够了 参考:https://linuxeye.com/369.html 序列化: pickle.dump(文件) pickle.dumps(字符串) 反序列化: pickle.load(文件) pickle.loads(字符串)

序列化规则

这里参考K0rz3n师傅文章,里面讲的很详细,这里只是充当一下搬运工

PVM 的组成

PVM 由三个部分组成,引擎(或者叫指令分析器),栈区、还有一个 Memo (这个我也不知道怎么解释,我们姑且叫它 “标签区“) ### 1.引擎的作用 从头开始读取流中的操作码和参数,并对其进行处理,zai在这个过程中改变 栈区 和 标签区,处理结束后到达栈顶,形成并返回反序列化的对象 ### 2.栈区的作用 作为流数据处理过程中的暂存区,在不断的进出栈过程中完成对数据流的反序列化,并最终在栈上生成发序列化的结果 ### 3.标签区的作用 数据的一个索引或者标记 如图所示:

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/0adfa761-cc85-4a8a-9d71-0b4245b2eb6e/rId24.png

注意:PVM 指令的书写规范 (1)操作码是单字节的 (2)带参数的指令用换行符定界

PVM 操作码

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/2230550b-f268-4497-91b9-b2d3bbe409c1/rId26.png

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/527cb8bf-2843-46da-b1ca-c807f8daac36/rId27.png

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/1054daac-c573-428e-8c32-09a70704907d/rId28.png

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/7f5f27f6-3cbf-4553-8e06-98c9d1486593/rId29.png

这里面要重点关注几个

S : 后面跟的是字符串
( :作为命令执行到哪里的一个标记
t :将从 t 到标记的全部元素组合成一个元祖,然后放入栈中
c :定义模块名和类名(模块名和类名之间使用回车分隔)
R :从栈中取出可调用函数以及元祖形式的参数来执行,并把结果放回栈中
. :点号是结束符

反序列化时的代码执行缺陷

官方文档中说过,pickle是个不安全的模块,永远别去反序列化不信任的数据。

这一切都是因为__reduce__ 魔术方法,它在序列化的时候会完全改变被序列化的对象,这个方法相当的强大,官方建议不要直接操作这个方法,用更高级的接口 __getnewargs(), getstate() and setstate() 等代替。

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/30d88ae4-323e-4a88-bd55-60c6f45944b6/rId31.png