Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    863537776

Contributors to this blog

  • HireHackking 16114

About this blog

Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.

如果你曾經將iPhone、iPad或iPod連接到Windows PC上,你可能會注意到,這些設備會根據你的操作顯示為不同類型的設備。例如,如果你正在給iPhone充電,它可能會顯示為“USB複合設備”,但如果你正在與iTunes同步音樂,它可能會顯示為“蘋果移動設備USB驅動程序”。你有沒有想過這是怎麼回事?事實證明,蘋果在Windows電腦上有一個USB低級過濾器,可以幫助他們控制操作系統使用哪些USB配置。

本文中,我們會首先介紹蘋果的USB低級過濾器是如何工作的,它是做什麼,以及無論是否安裝了蘋果軟件,它如何提供不同的體驗;其次,我們將研究為什麼當設備的WPD屬性WPD_DEVICE_PROTOCOL表明設備正在使用媒體傳輸協議(MTP)時,iphone的開箱操作如此有限。我們將深入研究諸如Windows便攜式設備(WPD),USB描述符和用戶模式驅動程序框架(UMDF)等話題。

初始化蘋果的USB低級過濾器蘋果設備將自己呈現為具有多個接口的複合設備,以確保它們的設備被正確識別,並加載所有必要的驅動程序。這是因為蘋果設備通常有多個接口,提供不同的功能,如音頻、視頻和控制。當我們將蘋果設備插入Windows設備時,總線適配器識別設備並向操作系統提供其hardwareid和compatibleid。這些id用於根據id的匹配質量在driver Store中搜索最佳驅動程序。

對於總線驅動器來說,要將該設備視為複合設備,必須滿足一定的要求。如果不滿足這些要求,操作系統將不會自動加載USB複合設備類驅動程序(usbccgp)。在這種情況下,我們需要提供一個INF來加載通用的父驅動程序,對於蘋果來說是文件AppleUSB.inf。

在iPhone的情況下,不滿足的要求是設備具有多個配置(bNumConfigurations==4)。

這個INF文件包含不同設備的各種設置配置(例如AppleUSB, AppleUsbHomePod和AppleUsbWatch)。對於iOS設備,HardwareId將完全匹配,因此操作系統將應用AppleUSB設置配置,這將復制AppleLowerFilter.sys,並將在設備特定的註冊表項下添加以下值:

1.png

OriginalConfigurationValue是一個可以在設備的硬件註冊表項中為Usbccgp.sys驅動程序設置的值。它確定複合設備的哪個配置應用作默認配置。首次插入複合設備時,系統讀取OriginalConfigurationValue並加載指定的配置。這對於具有多個配置的複合設備非常有用,其中一個配置可能是首選配置。

安裝驅動程序包後,微軟將詳細說明以下步驟。設備將重新啟動,重啟後,PnP管理器識別設備的功能驅動程序和任何可選的過濾器驅動程序,構建設備堆棧,在該樣本中,FDO是Usbccgp和LowerFiDO是AppleLowerFilter,並通過調用DriverEntry例程啟動設備,為任何尚未加載的所需驅動程序。然後為每個驅動程序調用AddDevice例程,從低過濾驅動程序開始,然後是函數驅動程序。如果需要,將分配資源,PnP管理器將IRP_MN_START_DEVICE發送給設備的驅動程序。

USB低級過濾器工作原理介紹了AppleLowerFilter的枚舉和安裝背後的理論之後,我們現在將仔細研究驅動程序是如何工作的,以及它在Windows設備上啟用Apple設備功能時所起的作用。

作為一個WDF驅動程序,PnP調用DriverEntry的第一步是初始化框架並綁定WDF版本(在本例中為WDF 1.15)。一旦完成,框架將調用我們的DriverEntry函數,在AppleLowerFilter的情況下,他們的驅動項將簡單地創建一個驅動對象,並在WDF_DRIVER_CONFIG中只設置一個AddDevice例程。 AppleLowerFilter的AddDevice例程將進行如下操作:

1.通過調用WdfFdoInitSetFilter將自己標識為FiDO;

2.為事件註冊PnP和電源管理回調:

EvtDevicePrepareHardware;

EvtDeviceReleaseHardware;

EvtDeviceD0Entry;

EvtDeviceD0Exit;

3.為IRP設置兩個IRP預處理回調:

IRP_MJ_PNP;

IRP_MJ_INTERNAL_DEVICE_CONTROL;

4.使用名為FILTER_EXTENSION(sizeof==0x50)的上下文類型信息創建一個DO;

本文不深入討論WDF框架的所有細節,但鼓勵每個人都深入研究Github上的源代碼。它是一個設計良好的軟件,使編寫驅動程序變得更加容易和直觀,因此研究代碼是一個很好的練習。

在上電序列( power-up sequence)中,下一步是為上電準備硬件,這意味著調用過濾器註冊的EvtDevicePrepareHardware回調。這可能是AppleLowerFilter中最有趣的步驟。

Callback的第一步是檢索USB描述符,這是通過被稱為GetUsbDeviceDescriptor的函數完成的。此函數用於檢索USB設備的USB設備描述符。這是通過為URB (USB請求塊)分配內存並使用URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE類型完成的,這是一個從USB設備檢索描述符的請求。被請求的描述符是USB_DEVICE_DESCRIPTOR_TYPE,它提供有關USB設備的信息,如其供應商和產品id、設備類和協議。該函數同步提交URB以檢索描述符。

對於大多數與USB相關的操作,蘋果使用usbdlib,這有點令人不可思議,因為這是一個WDF驅動程序,他們可以使用wdfusb標頭,簡化事情。

然後,驅動程序將bNumConfigurations存儲到FILTER_EXTENSION上下文中,並繼續調用我認為是該驅動程序的主要函數GetPreferredConfig。在描述其內部結構之前,先看一下這個函數的簡單偽代碼:

2.png

該函數將首先檢查設備的配置數是否為1。如果是,則將首選配置設置為1;如果沒有,代碼將發送一個URB來檢索首選配置;如果URB請求失敗,則首選配置為3。然後代碼在FilterCtx結構中設置DeviceConfig字段。然後,它檢查QueryAppleSoftwarePresent函數是否返回false(表示未安裝AppleSoftware),如果是,則將首選配置設置為1。然後,代碼檢查首選配置是否大於或等於設備描述符中指定的配置數;如果是,則將首選配置設置為最大配置數。最後,如果首選配置大於或等於5,則代碼返回5。

在這個函數中有幾個關鍵點,首先突出的是getdeviceconfigure函數,該函數將為URB分配內存,設置URB以發出特定於供應商的控制請求,然後將URB同步提交給USB驅動程序堆棧。正在進行的特定供應商請求是請求類型為69的控制傳輸和包含一個字節數據的傳輸緩衝區。

3.png

選擇首選配置的下一個關鍵點是QueryAppleSoftwarePresent函數,這個函數起著很大的作用,因為它的返回值將決定我們是否總是被限制為只有一個首選配置。這個函數將做以下事情:

4.png

回到GetPreferredConfig函數,這個值起著很大的作用,因為這個函數返回的數字將用於覆蓋設備註冊表項中的OriginalConfigurationValue。

注意:GetPreferredConfig返回的值將被減去1,因為OriginalConfigurationValue描述的註冊表值對應於usb定義的配置索引,由配置描述符(USB_CONFIGURATION_DESCRIPTOR)的bConfigurationValue成員指示,而不是由設備配置描述符中報告的bConfigurationNum值表示。

我們剛剛看到的是為什麼即使INF在OriginalConfigurationValue中寫入值2,如果你將iPhone插入沒有安裝iTunes的PC,你會在註冊表中看到以下內容:

5.jpg

在註冊表中設置OriginalConfigurationValue之後,EvtDevicePrepareHardware函數將調用wdfusbtargetdevicecrecreate來創建USB目標設備對象。 USB目標設備對象表示底層USB設備,並為驅動程序與設備通信提供了一種方式。

為了定期檢查首選配置,該函數設置了一個WDFTIMER。計時器的回調函數將被定期調用,以檢查首選配置是否已更改。如果首選配置已更改,則函數將調用WdfUsbTargetDeviceCyclePortSynchronously,以便意外刪除並重新枚舉設備,從而使用新配置進行加載。

計時器的周期設置為0,因此框架不會調用計時器。另一方面,過濾器將在計時器的回調函數和D0Entry回調中調用WdfTimerStart, DueTime為5s(相對於當前系統時間)。

現在讓我們看看這兩個IRP預處理回調,以獲得驅動程序工作流的全貌。 IRP的預處理允許驅動程序在將IRP發送到默認處理程序或堆棧中的另一個驅動程序之前修改或重定向IRP。

首先看一下內部設備控制請求的處理程序。該函數將檢查IRP是否為IOCTL_INTERNAL_USB_SUBMIT_URB請求,以選擇USB配置。如果是,函數將獲得設備的句柄,轉發IRP,然後檢索USB接口的管道句柄。 Interrupt、BulkIn和BulkOut的管道句柄將存儲在設備上下文中。

現在讓我們看一下PnP IRPs預處理的處理程序。在本文的示例中,句柄將處理兩種情況:IRP_MN_QUERY_DEVICE_RELATIONS 和IRP_MN_QUERY_ID。

QueryID IRP的情況非常簡單,函數將檢查FilterCtx-DeviceConfig(記住這個值是通過供應商特定的URB獲得的)是否被設置為1,如果是,函數將字符串RESTORE_MODE附加到BusQueryHardwareIDs和BusQueryDeviceID請求返回的信息中。

另一方面,querydevicerrelation更有趣一些。首先,這個處理程序只會在某個計時器沒有運行並且設備上安裝了Apple Software的情況下執行。它將只處理BusRelations IRP,它將同步轉發請求並檢查狀態是否成功。如果返回任何信息,它將在返回的設備對象列表中查找其CompatibleId包含USB\Class_06的設備。如果找到了,它會取消對這個DO的引用,然後將其從列表中刪除並更新設備計數,這樣即使usbccgp為WPD設備創建了PDO, PnP也不會看到這個DO,因為返回的列表中沒有它。不久,我們將看到低級過濾器如何處理這一點。

如果找到了類6的設備,那麼該函數將根據DbgPrints設置另一個WDF定時器,我們將其稱為PtpTimer,它在5秒後被觸發。當觸發回調時,將在deviceContext中設置一個標誌,因此QueryDeviceRelations處理程序不再處理請求,將檢查iTunes是否存在,如果存在,它將發送以下一組PTP/MTP操作請求包到USB設備。

OpenSession - OperationCode:0x1002;

vendoreextensionoperationcode:0x9008;

CloseSession - OperationCode:0x1003;

下面的USB數據包捕獲說明了這些操作的執行,注意它們是如何在該端口上捕獲大約5秒後發生的。

6.jpg

儘管嘗試了所有的手段來獲得操作0x9008的更多信息,但似乎沒有任何關於它的蘋果設備的信息。所能得到的最好結果是ChatGPT說“PTP/MTP數據包中的操作命令0x9008通常對應於“Apple Device Info”命令”。不幸的是,當要求提供證明這一點的文檔/引用時,而聊天給到的每個鏈接要么是無效的,要么是不可用的/廢棄的蘋果文檔。給定名稱“蘋果設備信息”,筆者認為它類似於PTP/MTP命令“GetDeviceInfo”,但在設備命令0x9008上嘗試的每個測試似乎都沒有數據階段,所以最好的猜測是,要么不是“設備信息”命令,要么蘋果設備不再響應該命令。

7.jpg

最後,在發送PTP/MTP請求後,PtpTimer將調用IoInvalidateDeviceRelations,其關係類型為BusRelation,這將觸發一個新的IRP QueryDeviceRelations,但由於這次計時器已經執行,處理程序不會從設備列表中刪除WPD設備。這次PnP管理器我們會看到WPD設備的PDO並開始為它構建堆棧。下圖顯示了通過將LowerFilter添加到堆棧中並跟踪Pre和Post捕獲的這種行為,IRP由AppleLowerFilter處理。

8.jpg

目前猜測是帶有operationCode0x9008的PTP包以某種方式,通知設備iTunes存在於主機上或這些行周圍的東西。除此之外,沒有註意到WPD設備在安裝iTunes或沒有安裝iTunes的情況下有任何不同的行為,除了WPD設備實際顯示需要5秒鐘。從設備的LowerFilters列表中刪除AppleLowerFilter似乎對WPD設備的行為沒有任何重大影響。

這幾乎就是AppleLowerFilter的行為方式,可以看到它主要在設備初始化期間工作,除了檢查活動配置的計時器每5秒在後台運行一次之外,查看端口時必須重新舉例。