.NET高級代碼審計(第一課)XmlSerializer反序列化漏洞

来源:https://www.cnblogs.com/Ivan1ee/archive/2019/03/09/10499842.html
-Advertisement-
Play Games

0X00 前言 在.NET 框架中的 XmlSerializer 類是一種很棒的工具,它是將高度結構化的 XML 數據映射為 .NET 對象。XmlSerializer類在程式中通過單個 API 調用來執行 XML 文檔和對象之間的轉換。轉換的映射規則在 .NET 類中通過元數據屬性來表示,如果程式 ...


0X00 前言

在.NET 框架中的 XmlSerializer 類是一種很棒的工具,它是將高度結構化的 XML 數據映射為 .NET 對象。XmlSerializer類在程式中通過單個 API 調用來執行 XML 文檔和對象之間的轉換。轉換的映射規則在 .NET 類中通過元數據屬性來表示,如果程式開發人員使用Type類的靜態方法獲取外界數據,並調用Deserialize反序列化xml數據就會觸發反序列化漏洞攻擊(例如DotNetNuke 任意代碼執行漏洞 CVE-2017-9822),本文筆者從原理和代碼審計的視角做了相關腦圖介紹和復現。

圖片1.png

0X01 XmlSerializer序列化

.NET 框架中 System.Xml.Serialization 命名空間下的XmlSerializer類可以將 XML 文檔綁定到 .NET 類的實例,有一點需要註意它只能把對象的公共屬性和公共欄位轉換為XML元素或屬性,並且由兩個方法組成:Serialize() 用於從對象實例生成 XML;Deserialize() 用於將 XML 文檔分析成對象圖,被序列化的數據可以是數據、欄位、數組、以及XmlElement和XmlAttribute對象格式的內嵌XML。具體看下麵demo

圖片2.png

XmlElement指定屬性要序列化為元素,XmlAttribute指定屬性要序列化為特性,XmlRoot特性指定類要序列化為根元素;通過特性類型的屬性、影響要生成的名稱、名稱空間和類型。再創建一個TestClass類的實例填充其屬性序列化為文件,XmlSerializer.Serialize方法重載可以接受Stream、TextWrite、XmlWrite類,最終生成的XML文件列出了TestClass元素、Classname特性和其它存儲為元素的屬性:

圖片3.png

0x02 XmlSerialize反序列化

反序列過程:將xml文件轉換為對象是通過創建一個新對象的方式調用XmlSerializer.Deserialize方法實現的,在序列化最關鍵的一環當屬new XmlSerializer構造方法里所傳的參數,這個參數來自System.Type類,通過這個類可以訪問關於任意數據類型的信息,指向任何給定類型的Type引用有以下三種方式。

2.1、typeof

實例化XmlSerializer傳入的typeof(TestClass) 表示獲取TestClass類的Type,typeof是C#中的運算符,所傳的參數只能是類型的名稱,而不能是實例化的對象,如下Demo

圖片4.png

通過typeof獲取到Type之後就能得到該類中所有的Methods、Members等信息。下圖運行Debug時,彈出消息對話框顯示當前成員Name的值。

圖片5.png

2.2、object.Type

在.NET里所有的類最終都派生自System.Object,在Object類中定義了許多公有和受保護的成員方法,這些方法可用於自己定義的所有其他類中,GetType方法就是其中的一個,該方法返回從System.Type派生的類的一個實例,因為可以提供對象成員所屬類的信息,包括基本類型、方法、屬性等,上述案例中實例化TestClass,再獲取當前實例的Type,如下Demo

圖片6.png

2.3、Type.GetType

第三種方法是Type類的靜態方法GetType,這個方法允許外界傳入字元串,這是重大利好,只需要傳入全限定名就可以調用該類中的方法、屬性等

圖片7.png

Type.GetType傳入的參數也是反序列化產生的漏洞污染點,接下來就是要去尋找可以被用來攻擊使用的類。

 

0X03 打造攻擊鏈

首先放上攻擊鏈打造成功後的完整Demo,這段Demo可以復用在任意地方(這裡不涉及.NET Core、MVC),如下圖

圖片8.png

只要XmlSerializer存在反序列化漏洞就可用下麵Demo中的內容,涉及到三個主要的技術點,以下分別來介紹原理。

 

3.1、ObjectDataProvider

ObjectDataProvider類,它位於System.Windows.Data命名空間下,可以調用任意被引用類中的方法,提供成員ObjectInstance用類似實例化類、成員MethodName

調用指定類型的方法的名稱、成員MethodParameters表示傳遞給方法的參數,參考下圖

圖片9.png

再給TestClass類定義一個ClassMethod方法,代碼實現調用System.Diagnostics.Process.Start啟動新的進程彈出計算器。如果用XmlSerializer直接序列化會拋出異常,因為在序列化過程中ObjectInstance這個成員類型未知,不過可以使用ExpandedWrapper擴展類在系統內部預先載入相關實體的查詢來避免異常錯誤,改寫Demo

圖片10.png

生成data.xml內容如下:

圖片11.png

攻擊鏈第一步就算完成,但美中不足的是因筆者在測試環境下新建的TestClass類存在漏洞,但在生產情況下是非常複雜的,需要尋求Web程式中存在脆弱的攻擊點,為了使攻擊成本降低肯定得調用系統類去達到命令執行,所以需要引入下麵的知識。

 

3.2、ResourceDictionary

ResourceDictionary,也稱為資源字典通常出現在WPF或UWP應用程式中用來在多個程式集間共用靜態資源。既然是WPF程式,必然設計到前端UI設計語言XAML。 XAML全稱Extensible Application Markup Language (可擴展應用程式標記語言) 基於XML的,且XAML是以一個樹形結構作為整體,如果對XML瞭解的話,就能很快的掌握,例如看下麵Demo

圖片12.png

  • 第一個標簽ResourceDictionary,xmlns:Runtime表示讀取System.Diagnostics命令空間的名稱起個別名為Runtime

  • 第二個標簽ObjectDataProvider指定了三個屬性,x:key便於條件檢索,意義不大但必須得定義;ObjectType 用來獲取或設置要創建其實例的對象的類型,並使用了XAML擴展;x:Type相當於C#中typeof運算符功能,這裡傳遞的值是System.Diagnostics.Process;MethodName用來獲取或設置要調用的方法的名稱,傳遞的值為System.Diagnostics.Process.Start方法用來啟動一個進程。

  • 第三個標簽ObjectDataProvider.MethodParameters內嵌了兩個方法參數標簽,通過System:String分別指定了啟動文件和啟動時所帶參數供Start方法使用。

介紹完攻擊鏈中ResourceDictionary後,攻擊的Payload主體已經完成,接下來通過XamlReader這個系統類所提供的XML解析器來實現攻擊。

 

3.3、XamlReader

XamlReader位於System.Windows.Markup空間下,顧名思義就是用來讀取XAML文件,它是預設的XAML讀取器,通過Load讀取Stream流中的XAML數據,並返回作為根對象,而另外一個Parse方法讀取指定字元串中的XAML輸入,也同樣返回作為根對象,自然Parse方法是我們關心和尋求的。

 

圖片13.png

只需使用ObjectDataProvider的ObjectInstance方法實例化XamlReader,再指定MethodName為Parse,並且給MethodParameters傳遞序列化之後的資源字典數據,這樣就可以完成XmlSerializer反序列化攻擊鏈的打造。

 

0x04 代碼審計視角

從代碼審計的角度其實很容易找到漏洞的污染點,通過前面幾個小節的知識能發現序列化需要滿足一個關鍵條件Type.GetType,程式必須通過Type類的靜態方法GetType,例如以下demo

圖片14.png

首先創建XmlDocument對象載入xml,變數typeName通過Xpath獲取到Item節點的type屬性的值,並傳給了Type.GetType,緊接著讀取Item節點內的所有Xml數據,最終交給Deserialize方法反序列化,這是一個近乎完美的利用點。再來看筆者在github上收集到的XmlSerializer反序列化類:XmlSerializeUtil.cs

圖片15.png

此處值參數類型為Type,代碼本身沒有問題,問題在於程式開發者可能會先定義一個字元串變數來接受傳遞的type值,通過Type.GetType(string)返回 Type對象再傳遞進DeserializeXml,在代碼審計的過程中也需要關註此處type的來源。

 

0x05 案例復盤

最後再通過下麵案例來複盤整個過程,全程展示在VS里調試里通過反序列化漏洞彈出計算器。

  1.輸入http://localhost:5651/Default?node=root&value=type載入了遠程的(192.168.231.135)1.xml文件

圖片16.png

2.    通過xmlHelper.GetValue得到root節點下的所有XML數據

圖片17.png

 

3. 這步最關鍵,得到root節點的type屬性,並提供給GetType方法,XmlSerializer對象實例化成功

圖片18.png

 

4.    XmlSerializer.Deserialize(xmlReader)成功調出計算器

圖片19.png

 

最後附上動圖

 

0x06 總結

由於XmlSerializer是系統預設的反序列類,所以在實際開發中使用率還是比較高的,攻擊者發現污染點可控的時候,可以從兩個維度去尋找利用的點,第一從Web應用程式中尋求可以執行命令或者寫WebShell的類和方法;第二就是本文中所說的利用ObjectDataProvider、ResourceDictionary、XamlReader組成的攻擊鏈去執行命令或者反彈Shell ,最後.NET反序列化系列課程筆者會同步到 https://github.com/Ivan1ee/、https://ivan1ee.gitbook.io/,後續筆者將陸續推出高質量的.NET反序列化漏洞文章,大致課程大綱如下圖

image.png


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ASP.NET編寫的網站程式,在網站編寫完成所有流程都測試通過後,需要將網站發佈到IIS的Web伺服器上,此文將介紹發佈的流程以及IIS相關設置過程,幫助讀者瞭解網站發佈的流程。 一、首先在Visual Studio中選擇網站項目,然後右鍵中有個發佈。 二、進入發佈界面後,首先設置好相應的配置文件, ...
  • 相關名詞 1. .NET Framework 2. MFC - MircoSoft Foundation Class,微軟基礎類庫 3. COM - Component Object Model,組件對象模型 4. CLR - Common Language Runtime,公共語言運行庫 5. B ...
  • SharpZipLib是一個開源的C#壓縮解壓庫,應用非常廣泛。就像用ADO.NET操作資料庫要打開連接、執行命令、關閉連接等多個步驟一樣,用SharpZipLib進行壓縮和解壓也需要多個步驟。SharpZipLib功能比較強大,在很多C#的應用中,都有它的身影,我們可以通過引入SharpZipLi ...
  • 索引: 目錄索引 一.API 列表 .DeepClone() 用於 Model / Entity / ... ... 等引用類型對象的深度克隆 特性說明 1.不需要對對象做任何特殊處理,直接 .DeepClone() 即可得到該對象的深度克隆 2.不受對象層次深度限制,均可實現深度克隆(下麵會給出幾 ...
  • 目錄 1,前言 2,安裝虛擬串口軟體 3,新建項目,加入 flyfire.CustomSerialPort 4,flyfire.CustomSerialPort 說明 5,開始使用 flyfire.CustomSerialPort 6,實現把數據寫入串口 7,實現監聽串口消息、多設備進行通訊 8,M ...
  • @[toc] 初識Identity並添加身份驗證管理頁面 前言 在 "使用ASP.NET Core2.2創建WebApp" 這篇教程中,我們使用 命令創建了一個沒有身份驗證管理的WebApp,通常情況下是無法滿足我們對敏感頁面控制的要求,典型的安全使用場景就是後臺管理。 在這一篇中,我們將通過命令嘗 ...
  • ASP.NET Forms 認證 Forms認證基礎 1. HTTP是無狀態的協議,也就是說用戶的每次請求對伺服器來說都是一次全新的請求,伺服器不能識別這個請求是哪個用戶發送的。 2. 那伺服器如何去判斷一個用戶的請求呢? 3. 答案是在每次請求發送時,附帶一些其他的信息來識別用戶的請求 4. 對於 ...
  • 前端就有了對 headless 瀏覽器的需求,最多的應用場景有兩個UI 自動化測試:擺脫手工瀏覽點擊頁面確認功能模式爬蟲:解決頁面內容非同步載入等問題也就有了很多傑出的實現,前端經常使用的莫過於 PhantomJS 和 selenium-webdriver,但兩個庫有一個共性——難用!環境安裝複雜,A... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...