我们知道现在各大语言都有其序列化数据和反序列的方式,

比如php的serialize和unserialize函数

Python当然也有,官方库里提供了一个叫做pickle的库

字符串的序列化解释

import pickle

x = "yuaneuro"
y = pickle.dumps(x) # 序列化
print(y)

上面例子中pickle序列化python的一个字符串

运行结果:
b'\x80\x03X\x08\x00\x00\x00yuaneuroq\x00.'

解释:

最前面的b' ' 表示这是一个 bytes 对象
第一个字符\x80是一个操作码,是识别pickle协议
\x03就代表了pickle版本为第三版(python3实现的版本是第三版)
\x08\x00\x00\x00,值为8,表示后面的utf8编码的字符串的长度为8,即yuaneuro的长度为8
在后面接yuaneuro
再往后是q\x00,给参数做索引用
最后的.代表结束


元组(tuple)的序列化解释

import pickle

x = ('bar','foo')
y = pickle.dumps(x) # 序列化
print(y)

上面例子中pickle序列化python的一个元组

运行结果:
b'\x80\x03X\x03\x00\x00\x00barq\x00X\x03\x00\x00\x00fooq\x01\x86q\x02.''

解释:

前面的字符串的序列化一样
在两个字符串的结尾加了\x86操作码,意思是"利用栈顶的两个元素(即bar和foo)建立一个元组
q\x02标识该元组在memo的索引


列表(list)的序列化解释

import pickle

x = ['bar','foo']
y = pickle.dumps(x) # 序列化
print(y)

上面例子中pickle序列化python的一个列表

运行结果:
b'\x80\x03]q\x00(X\x03\x00\x00\x00barq\x01X\x03\x00\x00\x00fooq\x02e.'

解释:

在\x03的后面是一个]操作符,意思是在栈上建立一个空list
q\x00是这个列表在memo的索引
(开始到e操作符前面的内容用来构建list


字典(dict)的序列化解释

import pickle

x = {'name':'yuaneuro', 'age':'20'}
y = pickle.dumps(x) # 序列化
print(y)

上面例子中pickle序列化python的一个字典

运行结果:
b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x08\x00\x00\x00yuaneuroq\x02X\x03\x00\x00\x00ageq\x03X\x02\x00\x00\x0020q\x04u.'

解释:

在\x03的后面是一个}操作符,意思是在栈上建立一个空dict
q\x00表明了这个dict在memo区的索引
}开始到u操作符前面的内容用来构建dict


类(class)的序列化解释

import pickle

class Student(object):
    name = 'yuaneuro'
    age = '20'

y = pickle.dumps(Student())
print(y)

上面例子中pickle序列化python的一个

运行结果:
b'\x80\x03c__main__\nStudent\nq\x00)\x81q\x01.'

解释:

c操作符,用来导入模块中的标识符,模块和标识符之间用\n隔开
那么这里的意思就是导入了main模块中的Student
q\x00代表了Student类在memo的索引
随后是)在栈上建立一个新的元组,这个元组存储的是新建对象时需要提供的参数,因为本例中不需要参数,所以这个元组为空
\x81操作符,该操作符调用cls.__new__方法来建立对象,该方法接受前面元组中的参数


介绍完这些,我将在下一篇博客中介绍反序列化漏洞及其任意代码执行

python反序列化漏洞 任意代码执行

最后修改:2022 年 03 月 11 日
如果觉得我的文章对你有用,请随意赞赏