您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關CVE-2020-1362之如何處理漏洞,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
WalletService 服務是 windows 上用來持有錢包客戶端所使用的對象的一個服務,只存在 windows 10 中。
CVE-2020-1362是 WalletService 在處理 CustomProperty 對象的過程中出現了越界讀寫,此漏洞可以導致攻擊者獲得管理員權限,漏洞評級為高危。
微軟在 2020 年 7 月更新對漏洞發布補丁。
1.復現環境:windows 10 專業版 1909 (內部版本號 18363.815)
2.設置 WalletService 服務啟動類型為自動
3.調試環境:windbg -psn WalletService 即可。
漏洞點是設置 CustomProperty 對象的 Group 的 get 方法和 set 方法沒有檢查邊界。
1.get 方法的 a2 參數沒有檢查邊界導致可以泄露堆上的一些地址。
2.set 方法的 a2 參數沒有檢查邊界,可以覆蓋到對象的虛表指針,從而控制程序流。
創建 CustomProperty 對象
WalletService 服務由 WalletService.dll 提供,WalletService.dll 實際上是一個動態鏈接庫形式的 Com 組件,由 svchost.exe 加載。我們可以在自己寫的程序(下面稱為客戶端)中使用 CoCreateInstance() 或者 CoGetClassObject() 等函數來創建對象,通過調用獲得的對象的類方法來使用服務提供的功能。
如何創建出漏洞函數對應的對象呢?最簡單的辦法是下載 msdn 的符號表,然后看函數名。
我們想要創建出 CustomProperty 對象,ida 搜索一下,發現有兩個創建該對象的函數:Wallet::WalletItem::CreateCustomProperty() 和 Wallet::WalletXItem::CreateCustomProperty()。
所以我們創建一個 CustomProperty 需要一個 WalletXItem 對象或者 WalletItem 對象,那么使用哪個呢?繼續用 ida 搜索 CreateWalletItem 或者 CreateWalletXItem,會發現只有 CreateWalletItem。
那到這里我們需要一個 WalletX 對象,繼續用 ida 搜索會發現找不到 CreateWalletX,但是如果搜索 WalletX,會發現有個 WalletXFactory::CreateInstance(),如果有過 Com 組件開發經驗的同學就會知道,這個是個工廠類創建接口類的函數,上面提到的 CoCreateInstance() 函數會使 WalletService 調用這個函數來創建出接口類返回給客戶端。
那么如何調用 WalletXFactory::CreateInstance() 并創建出 WalletX 對象呢?我們需要在客戶端使用 CoCreateInstance() 。
HRESULT CoCreateInstance( REFCLSID rclsid, // CLSID,用于找到工廠類 LPUNKNOWN pUnkOuter, // 設置為 NULL 即可 DWORD dwClsContext, // 設置為 CLSCTX_LOCAL_SERVER,一個宏 REFIID riid, // IID, 提供給工程類,用于創建接口類實例 LPVOID *ppv // 接口類實例指針的地址 );
1.首先,我們需要 WalletXFactory 的 CLSID,可以使用 OLEViewDotNet 這個工具查看。
2.其次,我們需要一個 WalletX 的 IID,這個可以用 ida 直接看 WalletXFactory::CreateInstance() 這個函數。
有了 WalletXFactory 的 CLSID 和 WalletX 的 IID,然后在客戶端調用 CoCreateInstance(),WalletService 就會調用 CLSID 對應的工廠類 WalletXFactory 的 CreateInstance(), 創建出 IID 對應的 WalletX 對象,并返回對象給客戶端。
然后按照上面的分析,使用 WalletX::CreateWalletItem() 創建出 WalletItem 對象,然后使用 WalletItem::CreateCustomProperty() 創建出 CustomProperty 對象。
對于上面的步驟有疑問的同學可以去學一學 Com 組件開發,尤其是進程外組件開發。
由于同一個動態庫,在不同的進程,它的加載基址也是一樣的,我們可以知道所有dll里面的函數的地址,所以可以獲得偽造的虛表里面的函數地址。
那么把虛表放哪里呢?直接想到的是放堆上。
但如果我們繼續分析,會發現,CustomProperty 類里面有一個 string 對象,并且可以使用 CustomProperty::SetLabel() 對 string 類進行修改,所以,我們可以通過修改 string 類里面的 beg 指針 和 end 指針,然后調用 CustomProperty::SetLabel() 做到任意地址寫。
有了任意地址寫,我們選擇把虛表放在 WalletService.dll 的 .data 節區,以避免放在堆上可能破壞堆上的數據導致程序崩潰。
使用偽造 vtable 并覆蓋虛表指針的辦法,我們可以通過調用虛函數控制 WalletService 的程序流到任意地址了。
那么怎么提權呢?在 windows 服務提權中,通常的辦法是把程序流控制到可以執行 LoadLibrary() 等函數來加載一個由我們自己編寫的動態鏈接庫,因為在加載 dll 的時候會執行 dll 里面的 DllMain(),這個方法是最強大的也是最實用的。
這里使用漏洞提交者的方法,把虛表的某個地址覆蓋成 dxgi.dll 里面的 ATL::CComObject\::`vector deleting destructor(),因為這個函數調用的 LoadLibraryExW() 會使用一個全局變量作為想要加載的 dll 的路徑。
我們可以通過上面的 SetLabel() 進行任意地址寫,修改上圖的全局變量 Src,使其指向我們自己實現的動態鏈接庫的路徑,然后調用對應的虛表函數,使程序流執行到 LoadLibrarExW() 即可。
在 DllMain() 里面寫上我們希望以高權限執行代碼,然后調用虛表里面對應的函數是 WalletService 的程序流運行到 LoadLibraryEx() 即可。
注意,因為 windows 服務運行在后臺,所以需要在 DllMain() 里面使用命名管道或者 socket 等技術來進行回顯或者交互,其次由于執行的是 LoadLibraryExW(),所以這里的 dll 路徑要使用寬字符。
在控制虛表函數程序流到 LoadLibraryExW() 時,需要繞過下面兩個 check。
第一個是需要設置 this+0x80 這個地址的值,使得下面的 and 操作為 true。
第二個是要調整 qword_C5E88 和 qword_C5E80 是下面的變量 v4 指向具有寫權限的內存。
可以獲得管理員權限
可以看到,打了補丁之后,get 方法和 set 方法都對 a2 參數添加了邊界檢測。
以上就是CVE-2020-1362之如何處理漏洞,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。