<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    Windows WDM 驅動漏洞挖掘(上)

    VSole2022-07-02 10:55:04

    驅動程序中的每一個漏洞本質上都是Windows內核中的一個漏洞,因為每個驅動程序都共享內核的內存空間。擁有了在內核中運行代碼、從模型寄存器讀寫或復制特權訪問令牌的能力實際上是擁有了系統。本文將介紹在WDM驅動程序中發現漏洞的方法,然后通過kAFL利用內核模糊。大多數漏洞似乎都在WDM或KMDF中。

    在本博客的每一部分中,我們都將從基礎開始,比如熟悉相關的API和數據結構。

    WDM

    Windows驅動程序模型(WDM)是最古老的,也是最常用的驅動程序框架。每個驅動本質上都是一個WDM驅動;較新的框架WDF (Windows Driver framework)封裝了WDM,簡化了WDM的開發過程,解決了WDM的多種技術難題。在檢查WDM驅動程序時,我們關心的主要事情是如何與它們通信;幾乎驅動程序中的每個漏洞都涉及到一些從非特權用戶到驅動程序本身的通信。

    在示例中,這是名為“testy”的驅動程序的入口點:

    經典的DriverEntry代碼,注意,對IoCreateDevice的調用沒有FILE_DEVICE_SECURE_OPEN標志

    這段代碼是每個WDM驅動都有的DriverEntry函數的普通架構。第一個參數是DriverObject結構指針,用于設備創建和調度例程初始化。接下來,驅動程序有MajorFunction成員,它是一個函數指針數組,用于為不同的事件分配調度例程。此外,我們還有將在下一節中介紹的關鍵設備創建例程。

    設備創建和初始化

    驅動程序首先通過調用 IoCreateDevice 創建設備,這將在對象管理器中創建一個 DEVICE_OBJECT。在 Windows 中,設備對象表示驅動程序處理 I/O 請求的邏輯、虛擬或物理設備。所有這些聽起來都不錯,但如果我們希望它從普通用戶的角度進行交流,這還不夠;為此,我們調用 IoCreateSymbolicLink,它將在對象管理器中創建一個 DoS 設備名稱,使用戶能夠通過該設備與驅動程序進行通信。但是,有些設備沒有正常的名稱;它們具有自動生成的名稱(在 PDO 中完成)。對于沒有經驗的檢測人員來說,它們可能看起來很奇怪,所以如果你在你最喜歡的設備中第一次看到它們,請查看軟件,并在設備名稱列中查看 8 位十六進制。這些設備可以像其他所有命名設備一樣進行交互。

    展示 WinObjEx 設備命名空間

    在設備創建例程中要注意的最重要的事情是程序員是否為設備分配了 ACL 以及 DeviceCharacteristics 的值。

    不幸的是,IoCreateDevice方法不允許程序員指定任何ACL,這是不好的。因此,開發人員必須在注冊表或驅動程序的ini文件中定義一個ACL。如果他們不能這樣做,任何用戶都可以訪問設備。然而,使用IoCreateDeviceSecure方法可以緩解這種情況。

    除此之外,我們還需要查看第五個參數,即 DeviceCharacteristics 。如果 DeviceCharacteristics 的值沒有與 0x00000100 或 FILE_DEVICE_SECURE_OPEN 進行 OR 運算,我們可能會面臨安全漏洞(除非我們討論文件系統驅動程序或任何支持名稱結構的驅動程序)。這背后的原因是 Windows 對待設備的方式;每個設備都有自己的命名空間。設備命名空間中的名稱是以設備名稱開頭的路徑。對于名為 \Device\DeviceName 的設備,其命名空間由“\Device\DeviceName\anyfile”形式的任何名稱組成。

    如圖1所示,沒有FILE_DEVICE_SECURE_OPEN標志的IoCreateDevice調用意味著設備ACL不應用于打開設備命名空間內文件的文件請求。換句話說,即使我們在通過IoCreateDeviceSecure或其他方式創建設備時指定了強ACL,該ACL也不會應用于打開文件請求。結果,我們并沒有真正得到我們想要的,所以使用 \Device\testydrv 調用 CreateFile 會失敗,但使用“\device\testydrv\anyfile”調用會成功,因為 IoManager 沒有應用設備 ACL到創建請求(因為它假設它是一個文件系統驅動程序)。對于初學者來說,它被認為是一個值得修復的漏洞。此外,這將導致非管理員用戶嘗試讀/寫設備,執行 DeviceIoControl 請求等等,這通常是你不希望非管理員用戶做的事情。

    更好的用戶保護

    我們可以通過調用IoCreateDeviceSecure(或WdmlibIoCreateDeviceSecure;它是相同的函數),使用安全描述符防止非管理員用戶打開設備句柄,并在創建例程中使用FILE_DEVICE_SECURE_OPEN值。這也將為我們省去在注冊表中聲明設備權限的麻煩,就像我們在 IoCreateDevice 中需要的那樣。

    我們應該如何創建設備

    從尋找漏洞的角度來看,我們應該列舉系統中每一個可能的設備,然后嘗試用GENERIC_READ | GENERIC_WRITE打開它,這允許我們過濾掉不能與之通信的設備。

    調度方法

    創建設備很好,但僅僅與驅動程序通信是不夠的,還需要 IRP。驅動程序代表 IoManager 接收 IRP、I/O 請求數據包以用于特定觸發器。例如,如果應用程序嘗試打開設備句柄,IoManager 將調用分配給驅動程序對象的相關調度方法。因此,它允許每個驅動程序為其創建的每個設備支持多個不同的 MajorFunction。大約有 30 種不同的 MajorFunction。如果算上已棄用的 IRP_MJ_PNP_POWER,每個都代表不同的事件。我們將只關注其中兩個 MajorFunction 方法,并添加關于其余方法的簡短描述,這是我們在尋找漏洞時應該注意的地方。

    基本的驅動程序調度表分配

    調用IRP_MJ_CREATE

    在我們深入研究最有趣的目標之前,即 IRP_MJ_DEVICE_CONTROL,我們將從 IRP_MJ_CREATE 開始。每個內核模式驅動程序都必須在驅動程序調度回調函數中處理 IRP_MJ_CREATE。驅動程序必須實現 IRP_MJ_CREATE,因為沒有它,你將無法打開設備或文件對象的句柄。

    正如你可能猜到的,當你調用 NtCreateFile 或 ZwCreateFile 時會調用 IRP_MJ_CREATE 調度例程。在大多數情況下,它將是一個空存根,并根據設備的 ACL 返回一個帶有請求的 DesiredAccess 的句柄。

    典型的DistpachCreate強制方法

    但是,在某些情況下,會涉及更復雜的代碼,即使你滿足設備的 ACL 標準,你也可能會收到類似 STATUS_INVALID_PARAMETER 的狀態漏洞,因為你在調用 NtCreateFile 時使用了不正確的參數。

    不幸的是,這表明你不能盲目打開設備,希望通過DeviceIoControl與驅動程序通信;你首先需要了解它的預期參數。通常,DispatchCreate 需要一些 ExtendedAttributes(不能為此使用常規 CreateFile)或特定文件名(除了設備名稱)。因此,我們必須訪問 DispatchCreate 方法。

    顯示檢查是否存在名為“StorVsp-v2”的擴展屬性以及值字段的長度是否為 0x19 字節長。因此,驅動程序是 StorVsp.sys

    除了打開句柄之外,你還可以在DispatchCreate中查找漏洞。函數變得越復雜,內存分配和釋放漏洞的可能性就越高,特別是因為DispatchCreate并不經常被檢查。

    我們在尋找驅動程序中的漏洞時采取的一般方法是:

    • 枚舉每個設備對象:

    • 嘗試使用最寬松的 DesiredAccess 打開它;

    • 如果失敗,檢查狀態碼;如果不是 STATUS_ACCESS_DENIED,你可能仍然可以通過做一些手動工作并更改一些參數來打開句柄;

    通過遵循這個簡單的算法,我們將擁有一個包含大約 70 個設備的列表,我們可以從非管理員的角度與之交談。當然,這個數字會因不同的 Windows 設備而異,因為 OEM 驅動程序和許多類型的軟件也會安裝驅動程序。

    使用ioctls控制設備

    雖然ioctls很少讓你完全控制設備/驅動程序,但它實際上是應用程序與驅動程序通信的方式。驅動程序可以創建兩種ioctl調度例程:

    設備控制方法的典型用法

    唯一重要的方法是TestyDispatchIoctl,因為我們不能用任意參數發起對IoBuildDeviceIoControlRequest或IIoAllocateIrp的調用,這是觸發IRP_MJ_INTERNAL_DEVICE_CONTROL主函數的函數。如果是,那是因為內部調度方法很少經過適當的測試。

    與DriverObject的任何調度方法一樣,它從IoManager接收兩個參數。

    WDM驅動程序中的每個調度方法共享相同的函數簽名

    第一個是我們對其執行 CreateFile 操作的設備對象,第二個是指向 IRP 的指針。從漏洞研究的角度來看,IRP 封裝了用戶數據和我們并不真正關心的許多其他內容。我們在這里關心的主要是從用戶模式發送哪些參數。如果我們看一下 NtDeviceIoControlFile 的簽名,我們可以猜測在尋找驅動程序中的漏洞時我們關心哪些字段:

    DeviceIoControl API

    這種方法的主要問題是輸入/輸出緩沖區、它們的長度和Ioctl代碼本身。我們從Ioctl代碼開始,它是一個充當說明符的32位數字;它描述了緩沖區和長度如何被使用/復制到內核,所需的DesiredAccess(當你打開一個設備句柄時)和一個函數指示器。示例如下:

    FileTest.exe工具的圖像,顯示了32 Ioctl編號的位域

    我們可以看到ioctl代碼是0x1000,翻譯過來就是:

    • DeviceType:FileDevice_0:它與我們無關;
    • Function: 0:與我們無關;
    • Method:METHOD_NEITHER:它與我們相關,因為它描述了imanager如何將數據傳輸到內核;
    • Access:FILE_ANY_ACCESS:它與我們相關,因為它定義了你需要對句柄擁有的所需訪問權限。如果你沒有正確的訪問權限,那么 IoManager 將不允許調用發生并返回 AccessDenied。有四個不同的值:
    • FILE_ANY_ACCESS:無論 DesiredAccess 參數如何,你始終擁有設備句柄;
    • FILE_READ_DATA:你使用 GENERIC_READ 請求了一個句柄并獲得了一個有效的句柄;
    • FILE_WRITE_DATA:你使用 GENERIC_WRITE 請求了一個句柄并獲得了一個有效的句柄;FILE_READ_DATA | FILE_WRITE_DATA:不言自明;你需要這兩種權利;

    在 \Device\VfpExt 的句柄上運行此 DeviceIoControl 請求將導致 BSoD,無論你的權限級別如何,在理解了圖3中的Method字段之后,我們將看到其中的原因。

    Method/TransferType

    Method/TransferType被稱為萬惡之母,這聽起來有些夸大其詞,但不幸的是,事實確實如此。傳輸類型的方法,即ioctl 32位數中的兩個最低有效位,指示 IoManager 在內核中引用參數(緩沖區和長度)的方式。與訪問字段一樣,有四個不同的選項:

    (1) METHOD_NEITHER,兩個位都是打開的:IoManager 是惰性的,不對緩沖區及其長度進行檢查。緩沖區不會復制到驅動程序并駐留在用戶模式下。因此,用戶可以隨意操縱緩沖區的長度并釋放/分配他們的頁面,這將導致許多糟糕的事情:系統崩潰和權限提升,除非正確探測緩沖區。如果你看到一個驅動程序沒有探測緩沖區,而是使用METHOD_NEITHER,那肯定存在漏洞。

    (2) METHOD_BUFFERED,沒有一個位是打開的:IoManager將輸入/輸出緩沖區及其長度復制到內核,這使得它更加安全,因為用戶不能隨意換出緩沖區或更改它們的內容和長度。之后,輸入/輸出緩沖區指針被分配給IRP。

    (3) METHOD_IN_DIRECT和(4)METHOD_OUT_DIRECT兩個位中的一個是打開的:這兩個非常相似;imanager會像METHOD_BUFFERED那樣分配輸入緩沖區。對于輸出緩沖區,IoManager探測緩沖區并檢查虛擬地址在當前訪問模式下是否可寫或可讀。然后,它鎖定內存頁并將指針傳遞給 IRP。

    讓我們看看驅動程序如何訪問用戶模式緩沖區并查看一個快速漏洞,它說明了在驅動程序中沒有進行適當的安全檢查的漏洞。

    在這里我們可以看到我們應該如何關聯驅動程序中的每個緩沖區關于描述方法和傳輸類型的 Ioctl 代碼

    由于驅動程序通常可以支持多個 ioctl 代碼,因此對于每個不同的 ioctl 代碼,它都有一個大的 switch case,影響緩沖區在內存中的存儲位置。在下一節中,我們將看到如果我們不注意會發生什么。

    參考及來源:https://www.cyberark.com/resources/threat-research-blog/finding-bugs-in-windows-drivers-part-1-wdm

    文章來源:嘶吼專業版


    漏洞挖掘wdm
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    驅動程序中的每一個漏洞本質上都是Windows內核中的一個漏洞,因為每個驅動程序都共享內核的內存空間。擁有了在內核中運行代碼、從模型寄存器讀寫或復制特權訪問令牌的能力實際上是擁有了系統。
    【經典回顧系列】 Windows SMB Ghost CVE-2020-0796漏洞分析與利用(三)
    0x01 確定目標無目標隨便打,有沒有自己對應的SRC應急響應平臺不說,還往往會因為一開始沒有挖掘漏洞而隨意放棄,這樣往往不能挖掘到深層次的漏洞。所以在真的想要花點時間在SRC漏洞挖掘上的話,建議先選好目標。0x02 確認測試范圍前面說到確定測什么SRC,那么下面就要通過一些方法,獲取這個SRC的測試范圍,以免測偏。
    漏洞挖掘工具—afrog
    2023-03-20 10:20:07
    -t http://example.com -o result.html2、掃描多個目標 afrog -T urls.txt -o result.html例如:urls.txthttp://example.comhttp://test.comhttp://github.com3、測試單個 PoC 文件 afrog?-t http://example.com -P ./testing/poc-test.yaml -o result.html4、測試多個 PoC 文件 afrog?
    但又沒登錄怎么獲取的當前用戶的Access-Reset-Ticket真相只有一個,看看接口哪里獲取到的原來是在輸入要找回的用戶就會獲取當前用戶的Access-Reset-Ticket6到了,開發是我大哥嘗試修改可行,修改管理員賬號,然后起飛下機。漏洞已修復,廠商也修復了漏洞更新到了最新版本。
    漏洞挖掘是指對應用程序中未知漏洞的探索,通過綜合應用各種技術和工具,盡可能地找出其中的潛在漏洞。cookie的key為RememberMe,并對相關信息進行序列化,先使用aes加密,然后再使用base64編碼處理形成的。在網上關于Shiro反序列化的介紹很多,我這里就只簡單介紹一下,詳情各位可以看下大神們對其源碼的分析。
    這里建議doc文檔,圖片可以貼的詳細一些。爆破完好了,一樣的6。想給它一個清晰完整的定義其實是非常困難的。
    一、漏洞挖掘的前期–信息收集 雖然是前期,但是卻是我認為最重要的一部分; 很多人挖洞的時候說不知道如何入手,其實挖洞就是信息收集+常規owasp top 10+邏輯漏洞(重要的可能就是思路猥瑣一點),這些漏洞的測試方法本身不是特別復雜,一般混跡在安全圈子的人都能復現漏洞。接下來我就著重說一下我在信息收集方面的心得。
    針對被分析目標程序,手工構造特殊輸入條件,觀察輸出、目標狀態變化等,獲得漏洞的分析技術。輸入包括有效的和無效的輸入,輸出包括正常輸出和非正常輸出。安全公告或補丁發布說明書中一般不指明漏洞的準確位置和原因,黑客很難僅根據該聲明利用漏洞。代碼流分析主要是通過設置斷點動態跟蹤目標程序代碼流,以檢測有缺陷的函數調用及其參數。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类