前两天抗疫ctf有道pickle反序列化的题,印象里好多次碰见这个知识点了,但也就是大概了解,因为感觉上就是比赛会见到。但总之总结一下吧,还是挺有意思的。
和php或者java类似,python的序列化也是把类对象转化为字符串储存下来,方便传输保存等等,最开始接触这个功能是做模型训练的时候,也没想会有什么安全问题。主要是反序列化的过程,可能导致修改类或者命令执行的问题。
先写一个正常的类序列化过程:
1 | import pickle |
这里看到python2和python3的dumps方法生成的字符串是不一样的。这是因为dumps时用的协议不同,py2的是0号协议,py3默认是3号协议,可以通过给dumps函数加一个protocol参数来自己改变,但py2只能用2以下的。这个协议可以向前兼容,也就是说我们可以手写0号类型的字符串,因为这种可读性最强。简单介绍一下序列化的原理和用到的指令码:
序列化的过程其实就是维护一个栈和另一个memo(其实也是个栈,不是一定会用到)。
有几个指令码是入栈的,直接举例:
cos\nsystem:向栈中压入os模块的system方法,和i操作符类似。原理是调用self.find_class(modname, name)
(:向栈中压入一个标志,弹栈时使用
S’whoami’:向栈中压入一个字符串whoami,和V操作符类似
I10:向栈中压入一个数字10
}:向栈中压入一个空dict
g0:将memo中0号元素移至栈顶
还有几个指令码是出栈的:
0:弹出栈顶元素
t:将mark和t之间的内容转化为一个tuple
l:将mark和l之间的内容转化为一个list
s:将}和s之间的内容转化为一个dict,一次s操作只能得到一个键值对
u:将}(和u之间的内容转化为一个dict,相当于多个s操作,和d相同
p0:将栈顶元素移至memo中0号
b:记录栈顶state然后弹栈,记录当前栈顶inst然后弹栈,用state来更新inst然后把得到的结果压栈。更新实例的方式是call __setstate__ or __dict__.update(),build之后内存中的内容就已经改写。
R:记录栈顶args然后弹栈,记录当前栈顶f然后弹栈,执行f(args)然后把得到的结果压栈
用最简单的数据类型举例,看的比较清楚:
1 | b"(S'hello'\nS'bye'\nl.") pickle.loads( |
手写比较麻烦的化还可以用https://xz.aliyun.com/t/7012这个工具
所以我们就可以修改类的属性和值,直接替换对应的部分就可以了,比如给上面那个People类改个属性名再改个值:
1 | ser2 = '''(i__main__ |
这是直接修改为字符串的,其实也可以调用其他模块的内容,比如同目录有个secret.py,内容是name=’testsecret’,那么修改PVM码:
1 | ser2 = '''(i__main__ |
很直观
命令执行的原理,是python中的类有一个__reduce__魔术方法,在序列化的时候使用就可以让这个类根据我们在__reduce__中指定的方式进行序列化。先走一遍正常的流程:
1 | class People: |
可以看到当一个类加入reduce方法后,dumps生成的内容就给类没有关系了,只和reduce方法中的返回值有关,可以把R操作符看作reduce方法的特征。所以只要把loads的内容改成上边这种形式就可以命令执行。
当然这是python3,因为reduce方法是新式类才拥有的,py2中需要用class People(object),定义时继承object类才是新式类。
这种只能执行一行代码,如果想执行比较复杂的代码可以用marshal类,py2正常,py3可能有bug
1 | import marshal |
命令执行还有其他方法,比如重写__setstate__方法等等
1 | ser3 = b"c__main__\nPeople\n)\x81}(S'__setstate__'\ncos\nsystem\nubS'whoami'\nb." |
pickle反序列化相关的内容大概就这些,题目一般是修改实例内容满足判断条件,或者配合绕沙盒来命令执行,绕沙盒的部分太灵活就不太好总结了。
参考链接
https://media.blackhat.com/bh-us-11/Slaviero/BH_US_11_Slaviero_Sour_Pickles_Slides.pdf
https://zhuanlan.zhihu.com/p/89132768
https://www.anquanke.com/post/id/188981
https://xz.aliyun.com/t/7012
https://www.smi1e.top/%E4%BB%8Ebalsn-ctf-pyshv%E5%AD%A6%E4%B9%A0python%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/
https://xz.aliyun.com/t/7436