Numpy反序列化命令執行(CVE-2019-6446)淺析
0x01 前言
NumPy是一個功能強大的Python庫,主要用於對多維數組執行計算。NumPy提供了大量的庫函數和操作,可以幫助程序員輕鬆地進行數值計算。這類數值計算廣泛用於以下任務:
機器學習模型
:在編寫機器學習演算法時,需要對矩陣進行各種數值計算。例如矩陣乘法、換位、加法等。NumPy提供了一個非常好的庫,用於簡單(在編寫代碼方面)和快速(在速度方面)計算。NumPy數組用於存儲訓練數據和機器學習模型的參數。圖像處理和計算機圖形學
:計算機中的圖像表示為多維數字數組。NumPy成為同樣情況下最自然的選擇。實際上,NumPy提供了一些優秀的庫函數來快速處理圖像。例如,鏡像圖像、按特定角度旋轉圖像等。
數學任務
:NumPy對於執行各種數學任務非常有用,如數值積分、微分、內插、外推等。因此,當涉及到數學任務時,它形成了一種基於Python的MATLAB的快速替代。0x02 影響範圍及利用條件
NumPy <=1.16.0
用戶載入惡意數據源造成命令執行。
0x03 漏洞分析
我們以ubuntu最新版pip源下載的numpy 1.16.0版本為例進行分析。漏洞點位於npyio.py的第268行,file字元串對象經過格式驗證,如果不滿足默認的numpy以及zip格式,將會嘗試使用序列化的方式進行讀取文件。如果是老司機的話,估計大概知道是什麼問題了。
我們順著pickle.load函數繼續跟進看看。最終會發現他會逐位元組的去讀取命令。
如下圖,pickle默認支持很多命令語句。
有了這些數據,我們就開始構造命令執行了。在構造命令執行之前,我們得先導入我們所需要的包,以及一個可以執行反射的函數。通過代碼檢索,發現pickle的操作符號「c」和操作符「R」,分別代表著導入和調用兩個操作。
那接下來我們開始構造執行「ls」的命令函數了。
通過上面的操作符號,我們編寫出對應的命令,熟悉彙編的同學就看出來了,左邊是命令符號,右邊是數據。
然後我們把這個數據轉化成pickle能夠理解的語言。
cposixsystemp0(S"ls"p1tp2Rp3.
然後我們把這個payload文件,用numpy.load函數讀取一下。
就看到對應的效果了。
0x04 修復方案
2019年1月15日,官方在issue中確認了該漏洞,並準備在下一個小版本中修復
暫時緩解措施,將默認支持allow_pickle函數去掉。
參考鏈接
https://github.com/numpy/numpy/commit/a2bd3a7eabfe053d6d16a2130fdcad9e5211f6bb
https://bugzilla.suse.com/show_bug.cgi?id=1122208
*本文原創作者:nancyy,本文屬FreeBuf原創獎勵計劃,未經許可禁止轉載
※BOTCHAIN:第一個基於比特幣協議的功能齊全的殭屍網路
※Struts2-005遠程代碼執行漏洞分析
TAG:FreeBuf |