看我如何進行Python對象注入利用

譯者:天鴿

預估稿費:130RMB

投稿方式:發送郵件至linwei#360.cn,或登陸網頁版在線投稿

簡介

在今天的 Defencely Lab 中,我們將詳細介紹和演示 Python 對象注入攻擊(Python Object Injection)的細節。整個演示將使用我們專門編寫的易受攻擊的應用程序和漏洞,源碼可以在這裡找到 - Github – Python Object Injection。

需要的基礎知識

了解基本的 OOP 概念

Python 類和對象簡介

什麼是類?

類是一個模板,你可以在其中存儲變數和方法。

什麼是對象?

對象可以是任何東西,一個類的實例,一個變數或者一個類中的函數。

讓我們來看一個實際的例子:

在這裡,你可以看到我們創建了一個名為 Test 的類實例,並將它分配給了一個名為 simpleapp 的變數,將變數 rony 的值傳遞給了該實例。

輸出如下:

simpleapp = Test(rony)n

當執行此代碼時,python 會創建一個對象,然後將我們的值傳遞給第一個參數。每當 python 創建一個對象時,__init__ 函數就會被調用。__init__ 像 python 中的構造函數一樣工作。

伴隨著我們的輸出,列印出了一個隨機的數字,這是因為我們直接列印出了實例分配的變數,以顯示 python 是如何對待一個對象的。

什麼是對象注入?

對象注入是一種應用程序級的安全漏洞,它允許攻擊者根據上下文執行嚴重的攻擊

Python 專門將某原生模塊命名為「Pickle」,它在特定情況下容易受到對象注入攻擊。

危險發生在當用戶控制的數據被傳遞時,Python 已經在其官方文檔中指出 pickle 是一個存在風險的模塊。

我們可以將「Pickle」模塊與 PHP 中的 serialize/unserialize() 原生函數進行比較,當存在用戶輸入時該 PHP 函數也容易受到對象注入攻擊。

在 Python 中,與 PHP 不同的是,我們不需要一個魔術方法作為注入到對象的條件。

在 python 中進行序列化和反序列化僅僅是對數據的 PicklingUnpickling

除非用戶輸入的數據被傳遞到 Unpickling 的過程中,否則,Python 中數據的 Unpickling 並不一定是危險的。

下面是 Python 中 Pickled 和 Unpickled 的數據的樣子:

檢測對象注入攻擊

要實現對象注入,你必須在應用程序上執行一個白盒 Pentest。因為每當你在複雜對象上 pickling 時,Python 中的序列化數據都會帶有類名、變數和值。

Pickle 模塊提供了四種簡單和快速 pickling 和 unpickling 的方法。

dump()

dumps()

load()

loads()

您可以在 Python 官方文檔中找到它們各自的功能。

正如我已經提到的,Unpickling 數據並不一定是危險的,但如果你是在後端處理,那麼 pickling 和 unpickling 用戶輸入的數據就是危險的。永遠不要相信用戶的輸入。

如果所提供的數據是由用戶控制的,那麼很明顯會被篡改。

因此,如果你看到 pickled 的數據正在通過 HTTP 方法傳輸,則可能存在對象注入。

了解易受攻擊應用程序的工作流

文件名:pickle.py

我們將研究上述代碼,並據此實現一個對象注入。

忽略上面代碼上寫的所有內容,讓我們集中精力在三件事情上。

在這裡,arg 變數是用戶的輸入。

類 simpleApp 中的 final_workout() 方法將運行一個 python 文件。

app.secureaApp() 方法用於 unpickling 輸入的數據。

現在,讓我們更深入地了解這些方法正在扮演的角色。

simpleApp() 類中的 secureApp() 方法:

我假設你已經閱讀了 Python 的官方文檔,並且知道了這篇文章使用的所有方法的輸入輸出。

方法:

dump()

dumps()

load()

loads()

secureApp() 方法所做的是將文件名作為參數。使用 pickle 模塊的 load() 方法 Unpickling 文件中的數據,並將 unpickled 的數據賦予變數 workDone。之後該變數會作為 final_workout() 方法的參數。

我們看看 final_workout() 方法的內容。

simpleApp() 類中的 final_workout() 方法:

該方法創建一個名為 code.py 的 python 文件,將 unpickled 的數據寫入文件並運行它。

我們來看看,當使用已經生成的序列化數據來運行易受攻擊的應用程序 pickle.py 時,會發生什麼。

正如我們看到的,它列印出了序列化數據的內容,並成功運行,列印出字元串。

下面我們將學習怎樣構造自己的序列化數據,以在相同的應用程序上成功地進行對象注入。

編寫漏洞利用

現在我們知道 pickle.py 正在使用序列化的數據,因此,我們將使用 dumps() 方法 pickle 我們構造的 payload。

文件名:exploit_pickle.py

我們將序列化一條包含了編碼後系統命令的代碼, 並在它工作時對其進行測試。

現在我們就成功地注入了自己精心構造的代碼。

推薦閱讀:

Python從零開始系列連載(10)——Python的基本運算和表達式(中)
Python課件的中文版
Python操作SQLite/MySQL/LMDB/LevelDB
讓彈幕飄一會兒的Python小實驗
Python學習如何下手?看完本文後你能明白60%

TAG:Python入门 | Python | Python教程 |