首頁 > 軟體

網路安全滲透測試反序列化漏洞分析與復現工作

2022-02-19 19:17:30

0x00 概述

GENESIS64軟體的多個版本存在反序列化漏洞,影響多個元件,例如:

根據CVE漏洞相關描述,下載對應GENESIS軟體版本搭建環境,進行漏洞分析與復現工作。

0x01 服務分析

安裝完成後對整個系統進行熟悉,發現Web程式介面使用Silverlight進行資料互動,因此需要找到相關功能檔案進行分析。經過一些時間查詢,找到系統服務開啟的組態檔,在組態檔中定義了存取介面資訊以及呼叫的相關組態檔資訊:

經過多方分析找到FwxServer類,類中定義了重要服務的啟動與註冊設定,跟進一下StartAsyncServer()進行檢視:

StartAsyncServer()函數裡對設定項進行處理,載入設定項裡的設定,在後面有一個FwxServerBase()函數處理了很多的引數,繼續跟進:

FwxServerBase()函數裡只是對組態檔裡的設定做了一些設定,但此處發現繼承了AsyncServer,再次跟進AsyncServer:

AsyncServer()函數最後完成設定相關引數並進行啟動。到這裡就完成整個服務的建立與啟動,當然這裡只看了一個啟動專案,其他的服務註冊與啟動都差不多:

0x02 漏洞分析

基於前期的服務啟動流程以及設定項的分析,最後定位到Asyncserver裡處理提交請求的介面中,此介面中定義了幾個介面,均為提交請求的處理,於是就用這個作為分析的突破口。

下圖中定義了一個服務契約,在服務契約裡面有多個處理提交請求的操作契約:

我們來對相關引數做一個簡單的分析,因為這裡只有PutRequests是處理提交請求的,所以先來看看它。這裡是判斷提交過來的資料裡的Session是否失效,失效返回false,如果Session未失效則進入第二層處理Request:

在下圖可以看到Request()函數對我們提交過來的資料進行了處理:

主要的SOAP封包標籤頭:

標籤裡的cat標籤對應了下面的幾種提交型別,幾種型別對應了相關的處理方式:

其他的標籤處理大同小異。來到PutRequest()函數,此函數裡有一個a函數處理session,跟進分析一下:

a()函數裡,判斷了標籤Actor和使用者提交的資料A_1,跟進a(A_1)過載函數:

可以看到a(A_1)過載函數裡只是一個值選項判斷,再次回到之前,跟進a(A_0)過載函數:

a(A_0)過載函數處理了Session相關資料,也沒什麼可分析的,接著往下看:

接下來看到存在一個if判斷,對標籤PointName和PointHandle做了值判斷,因為一般情況下都會有值,因此這個地方流程一般不會進入,進入else分支分析:

在else分支裡面進行了一系列的標籤值判斷,下面程式碼對提交的資料進行了處理

PointManager.ValidationResult validationResult = this.a(session, request, out pointManagerWrapper, out pointHint);

只要validationResult的值不為Invalid和Unknown,則不會進行處理request資料,否則處理完成後進行返回:

繼續往下看,這裡呼叫了IsRequestAllowed()函數,這個函數是屬於ISecurityManager介面的,跟進看一下處理:

在IsRequestAllowed()函數中,也對相關標籤值進行了判斷,這裡判斷了cat標籤值是否為4以及InParams的值是否為SubscribeProcedureInParams;接著判斷了Session資訊是否失效,後面判斷了PointName的值是否為“cfg:”開頭的,如果是則進入tj.a()函數裡,跟進tj.a()函數:

函數根據cat標籤的值進行處理,如果我們提交了cat的值為4且InParams的值為SubscribeProcedureInParams的話,就會進入case 4分支處理,再次跟進tj.a()過載處理常式看看:

這裡首先進行了一次判斷,使用的是RepositoryIdentifier類,跟進RepositoryIdentifier.TryParse()函數:

這裡把使用者提交過來的PointName資料用”|”進行分割,加到list變數裡面:

在處理完資料後,判斷了資料的格式是否正常,這裡主要判斷了資料的長度,Guid.值,“rpt:“, “ctx:” ,“tag:”,隨後處理了”tag:”標籤,可以看到這裡將”tag:”標籤Base64解密後進行了反序列化的操作,跟進Deserialize()函數:

反序列化呼叫了DataContractSerializer進行序列化操作:

分析上圖程式碼,可知程式碼裡面存在一個坑:程式碼對使用者提交過來序列化的資料進行自定義處理,固不能直接生成POC,須預先做一個處理才能被利用。進入Deserialize()函數後,函數首先獲取序列化資料的前4個位元組,然後以前4個位元組作為長度讀取序列化資料,所以我們須在前面加上長度,否則無法反序列化成功,因為在前面的GetType獲取中就讀取錯了資料。

我們可以看到在DataContractSerializer()函數中,GetType的引數是可以控制的,分析一下對type的處理過程:首先使用工具生成一個測試poc,然後帶入函數進行處理:

看到函數已經對資料進行了處理,處理完資料之後我們發現,取出的變數值並不完整

接下來帶入系統進行查詢型別:

最後返回的type結果為null,也就是沒有找到所屬的型別,自然就會反序列化失敗:

這裡的序列化型別的清單均置於list清單裡,System.Security.Principal.WindowsPrincipal是在list裡面的,但卻沒有找到,就是因為資料存在格式問題:

根據按照序列化處理程式碼對POC進行刪減構造,即可成功獲取type:

0x03 POC構造

根據上節的漏洞分析,我們可以構造出漏洞利用POC,並使用DataContractSerializer()作為反序列化的載體進行利用測試:

通過抓包可以看到請求的資料,在封包中可以看到,標籤cat為4,type為0,但是Inparams還不是SubscribeProcedureInParams,借用抓到的封包構造POC,刪除封包中一些不必要的資料並新增一些能夠讓漏洞觸發的資料:

封包構造完成後,使用工具生成POC,此處使用ysoserial.NET,把漏洞利用POC修改後新增到封包裡面即可成功利用:

0x04 總結

這個GENESIS64 .NET的反序列化漏洞的分析過程比較曲折,一方面沒有太多的資料可供參考,加之軟體程式十分龐大,系統開啟服務太多,漏洞分析過程中發現的坑點也很多,導致漏洞定位難度增大,但總的來說,整個漏洞的利用過程還是很有意思,個人收穫很大。

以上就是網路安全滲透測試反序列化漏洞分析與復現工作的詳細內容,更多關於網路安全滲透測試反序列化漏洞分析與復現的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com