浅析PYthon中Pickle的反序列化漏洞及实战
前言:
和php的反序列化漏洞相似;PYthon也是具有反序列化漏洞;并且相比较php的反序列化漏洞利用需要构造复杂的pop链;PYthon的反序列化漏洞相对简单;本文即将要讲的是Python pickle/cPickle库的反序列化漏洞;此类漏洞常会导致RCE,原因:和我们所提到的应用场景有关。语言需要从string去解析出自己的语言数据结构,必然要去从这个string中做固定格式的解析,然后在内部把解析出来的结果去eval一下;或者,为了保证解析出来的内容为被序列化时候的Object状态,要调用一下状态保存的函数__wakeup__
Pickle模块
pickle模块用来进行对Python对象进行序列化和反序列化;;这里pickle实际上是先把Python的对象(list dict class等等)转化为字符流;这个字符流包含反序列化所需要的所有数据;pickle.loads()反序列化数据;;pickle.dumps()序列化数据;我们来看以下的实例;
从这些个实例中我们可以证实pickle.xxxx的作用;
__reduce__
那么我们之前说到的rec任意代码执行的漏洞如何利用呢?这里要引入一个魔法函数__reduce__
,这个魔法函数如果了解php的话,我就这么讲;这个函数和php中的__wakeup__
很类似。可以理解成是一样的;会在反序列化的时候执行;具体的内容请参考python的官方文档库;其实并不只是只有这一个函数;官方文档里也说过pickle是个不安全的模块,永远别去反序列化不信任的数据;
利用
如果我们发现序列化的内容可控,那么我们就可以只需要将相应的代码写入我们的__reduce__
函数之下,那么就可以达到任意命令执行的效果;因为接收端在反序列化的时候就会自动执行;
我通过例子来说明:(在我的vps上面测试)
写入代码执行system("ls"),,代码和效果如下;
这里我们可以发现,在我们运行python pp的时候,服务器自动执行了我们的代码,具体原因就是因为我们的恶意代码在__reduce__
魔法函数之下,会导致执行;
实战
拿一道 watevrCTF 的题目来讲;考点就是pickle的反序列化漏洞;一般ctf里面,看到pickle基本都是考的pickle的反序列化漏洞;进入题目看到要买东西;发现钱不够;在看到cookie里面有可疑的数据;发现是pickle反序列化实锤了;
那么我们直接写一个类,类里面写入__reduce__
函数,然后在函数下写入反弹shell的语句,然后反弹shell;即可;
这里给出我的脚本;然后进行反弹shell就可以;
(后面专门出个wp)【这里简单写】
防御方法
1、用更高级的接口__getnewargs()
、__getstate__()
、__setstate__()
等代替__reduce__()
魔术方法;
2、进行反序列化操作之前,进行严格的过滤,若采用的是pickle库可采用装饰器实现。
结尾:
Python也还有个反序列化的库marshl;也存在相关漏洞,有兴趣的可以自行研究;
有的时候题目会ban掉pickle,这时候我们可以利用map进行绕过。