網絡安全滲透測試反序列化漏洞分析與復現工作
0x00 概述
GENESIS64軟件的多個版本存在反序列化漏洞,影響多個組件,例如:
根據CVE漏洞相關描述,下載對應GENESIS軟件版本搭建環境,進行漏洞分析與復現工作。
【一>所有資源獲取<一】
1、200份很多已經買不到的絕版電子書
2、30G安全大廠內部的視頻資料
3、100份src文檔
4、常見安全面試題
5、ctf大賽經典題目解析
6、全套工具包
7、應急響應筆記
8、網絡安全學習路線
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的反序列化漏洞的分析過程比較曲折,一方面沒有太多的資料可供參考,加之軟件程序十分龐大,系統開啟服務太多,漏洞分析過程中發現的坑點也很多,導致漏洞定位難度增大,但總的來說,整個漏洞的利用過程還是很有意思,個人收獲很大。
以上就是網絡安全滲透測試反序列化漏洞分析與復現工作的詳細內容,更多關於網絡安全滲透測試反序列化漏洞分析與復現的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- Request與Session的存值取值操作
- Python區塊鏈范圍結論及Genesis Block的添加教程
- .Net集成敏感詞組件的步驟
- 使用Filter過濾器中訪問getSession()要轉化
- Django session登陸並獲取值的實例