新聞中心
?什么是模塊篡改保護(hù)?
模塊篡改保護(hù)是一種緩解措施,可防止對(duì)進(jìn)程主映像的早期修改,例如 IAT 掛鉤或進(jìn)程空心化。它一共使用了三個(gè) API:NtQueryVirtualMemory、NtQueryInformationProcess 和 NtMapViewOfSection。如果啟用,加載程序?qū)⒃谡{(diào)用入口點(diǎn)之前檢查主圖像標(biāo)頭和 IAT 頁(yè)面中的更改。它通過(guò)使用信息類(lèi) MemoryWorkingSetExInformation 調(diào)用 NtQueryVirtualMemory 來(lái)做到這一點(diǎn)。返回的結(jié)構(gòu)包含有關(guān)頁(yè)面共享狀態(tài)的信息,以及是否從其原始視圖修改。如果標(biāo)頭或 IAT 已從其原始映射修改。例如,如果主圖像已被取消映射,并且已在其位置映射了另一個(gè)圖像,則加載器將使用類(lèi) ProcessImageSection 調(diào)用 NtQueryInformationProcess 以獲取主圖像部分,然后將使用 NtMapViewOfSection 重新映射它。這樣,新部分將被使用,篡改的圖像副本將被忽略。

成都創(chuàng)新互聯(lián)是一家專(zhuān)業(yè)的成都網(wǎng)站建設(shè)公司,我們專(zhuān)注成都做網(wǎng)站、網(wǎng)站制作、網(wǎng)絡(luò)營(yíng)銷(xiāo)、企業(yè)網(wǎng)站建設(shè),友情鏈接,廣告投放平臺(tái)為企業(yè)客戶提供一站式建站解決方案,能帶給客戶新的互聯(lián)網(wǎng)理念。從網(wǎng)站結(jié)構(gòu)的規(guī)劃UI設(shè)計(jì)到用戶體驗(yàn)提高,創(chuàng)新互聯(lián)力求做到盡善盡美。
此緩解從 RS3 開(kāi)始可用,并且可以使用 PROCESS_CREATION_MITIGATION_POLICY2_MODULE_TAMPERING_PROTECTION_MASK 在進(jìn)程創(chuàng)建時(shí)啟用。
模塊篡改保護(hù)緩解措施是如何發(fā)現(xiàn)的
如果微軟從未宣布或記錄某些緩解措施,那人們?nèi)绾尾拍馨l(fā)現(xiàn)這些緩解措施?因此,一個(gè)值得關(guān)注的好地方是 EPROCESS 結(jié)構(gòu)中的各種 MitigationFlags 字段。目前存在三個(gè) MitigationFlags 字段(MitigationFlags、MitigationFlags2、MitigationsFlags3),每個(gè)字段包含 32 位。在前兩個(gè)中,整個(gè)32位已經(jīng)被使用,所以最近添加了MitigationFlags3,目前包含三個(gè)緩解措施,我相信很快會(huì)添加更多。這些標(biāo)志代表進(jìn)程中啟用的緩解措施。例如,我們可以使用 WinDbg 為當(dāng)前進(jìn)程打印 EPROCESS.MitigationFlags:
最后,在位 28 和 29 中,我們可以看到值 EnableModuleTamperingProtection 和 EnableModuleTamperingProtectionNoInherit。不幸的是,搜索這些名稱(chēng)并沒(méi)有得到任何好的結(jié)果。有幾個(gè)網(wǎng)站只顯示結(jié)構(gòu)而沒(méi)有解釋?zhuān)粋€(gè)模糊的堆棧溢出答案簡(jiǎn)要提到了 EnableModuleTamperingProtectionNoInherit 而沒(méi)有添加細(xì)節(jié),還有這條推文:
不出所料,最詳細(xì)的解釋是 Alex Ionescu 2017 年發(fā)布的一條推文。這雖并不是完整的文檔,但它是一個(gè)開(kāi)始。如果你已經(jīng)了解并理解構(gòu)成此緩解措施的概念,那么這一系列的推文可能會(huì)非常清楚地解釋有關(guān)該特性的所有內(nèi)容。
開(kāi)始搜索進(jìn)程緩解實(shí)現(xiàn)的第一個(gè)地方通常是內(nèi)核:ntoskrnl.exe。然而,這是一個(gè)巨大的二進(jìn)制文件,不容易搜索。似乎沒(méi)有與此緩解措施完全相關(guān)的函數(shù)名稱(chēng),所以沒(méi)有明顯的地方可以開(kāi)始。
相反,你可以嘗試不同的方法并嘗試找到對(duì) EPROCESS 的 MitigationFlags 字段的引用,并可以訪問(wèn)這兩個(gè)標(biāo)志中的一個(gè)。但除非你可以訪問(wèn) Windows 源代碼,否則沒(méi)有簡(jiǎn)單的方法可以做到這一點(diǎn)。但是,你可以做的是利用 EPROCESS 是一個(gè)大型結(jié)構(gòu)并且 MitigationFlags 存在于它的末尾,偏移量 0x9D0 的事實(shí)。一種非常粗暴但有效的方法是使用 IDA 搜索功能并搜索所有對(duì) 9D0h 的引用:
這會(huì)很慢,因?yàn)樗且粋€(gè)很大的二進(jìn)制文件,并且一些結(jié)果與 EPROCESS 結(jié)構(gòu)無(wú)關(guān),因此你必須手動(dòng)搜索結(jié)果。此外,僅查找對(duì)該字段的引用是不夠的,MitigationFlags 包含 32 位,其中只有兩個(gè)與當(dāng)前上下文相關(guān)。所以,你必須搜索所有的結(jié)果,找出以下情況:
0x9D0被用作EPROCESS結(jié)構(gòu)的偏移量——因?yàn)闊o(wú)法保證知道每種情況使用的結(jié)構(gòu)類(lèi)型,盡管對(duì)于較大的偏移量,只有少數(shù)選項(xiàng)可以是相關(guān)的,它主要可以通過(guò)函數(shù)名稱(chēng)和上下文來(lái)猜測(cè)。
比較或設(shè)置MitigationFlags字段為0x10000000 (EnableModuleTamperingProtection)或0x20000000 (EnableModuleTamperingProtectionNoInherit)?;蛘咄ㄟ^(guò)諸如bt或bts之類(lèi)的匯編指令,按位數(shù)測(cè)試或設(shè)置位28或位29。
運(yùn)行搜索后,結(jié)果看起來(lái)像這樣:
你現(xiàn)在可以瀏覽結(jié)果并了解內(nèi)核使用了哪些緩解標(biāo)志以及在哪些情況下使用。然后我會(huì)告訴你,這個(gè)努力完全沒(méi)有用,因?yàn)?EnableModuleTamperingProtection 在內(nèi)核中的一個(gè)地方被引用:PspApplyMitigationOptions,當(dāng)創(chuàng)建一個(gè)新進(jìn)程時(shí)調(diào)用:
因此,內(nèi)核會(huì)跟蹤是否啟用了此緩解措施,但從不對(duì)其進(jìn)行測(cè)試。這意味著緩解措施本身在其他地方實(shí)現(xiàn)。這種搜索可能對(duì)這種特定的緩解措施毫無(wú)用處,但它是找出緩解措施實(shí)現(xiàn)位置的幾種方法之一,并且對(duì)其他流程緩解措施很有用,所以我想提一下它。
現(xiàn)在讓我們回到模塊篡改保護(hù),有時(shí)會(huì)實(shí)現(xiàn)進(jìn)程緩解的第二個(gè)位置是 ntdll.dll,它是每個(gè)進(jìn)程中要加載的第一個(gè)用戶模式映像。此 DLL 包含所有進(jìn)程所需的加載程序、系統(tǒng)調(diào)用存根和許多其他基本組件。在這里實(shí)現(xiàn)這種緩解是有意義的,因?yàn)轭櫭剂x它與模塊加載有關(guān),這通過(guò) ntdll.dll 中的加載器發(fā)生。此外,這是一個(gè)包含 Alex 在他的推文中提到的功能的模塊。
即使我們沒(méi)有這條推文,只要打開(kāi) ntdll 并搜索“tampering”,我們就能很快找到一個(gè)結(jié)果:函數(shù) LdrpCheckPagesForTampering。尋找這個(gè)函數(shù)的調(diào)用者,我們看到它是從LdrpGetImportDescriptorForSnap調(diào)用的:
在截圖的第一行,我們可以看到兩個(gè)檢查:第一個(gè)驗(yàn)證當(dāng)前正在處理的條目是主圖像,因此該模塊被加載到主圖像模塊中。第二個(gè)檢查是 LdrSystemSllInitBlock.MitigationOptionsMap.Map中的兩個(gè)位。我們可以看到這里檢查的確切字段只是因?yàn)槲覍?duì) LdrSystemDllInitBlock 應(yīng)用了正確的類(lèi)型,如果你在沒(méi)有應(yīng)用正確類(lèi)型的情況下查看這個(gè)函數(shù),你會(huì)看到一些隨機(jī)的、未命名的內(nèi)存地址被引用。 LdrSystemDllInitBlock 是一個(gè)數(shù)據(jù)結(jié)構(gòu),包含加載程序所需的所有全局信息,例如進(jìn)程緩解選項(xiàng)。它沒(méi)有記錄,但具有符號(hào)中可用的 PS_SYSTEM_DLL_INIT_BLOCK 類(lèi)型,因此我們可以在此處使用它。請(qǐng)注意,雖然此結(jié)構(gòu)在 NTDLL 符號(hào)中不可用,而是你可以在 ole32.dll 和 combase.dll 的符號(hào)中找到它。 MitigationOptionsMap 字段只是三個(gè) ULONG64 的數(shù)組,其中包含標(biāo)記為此過(guò)程設(shè)置的緩解選項(xiàng)的位。我們可以在 WinBase.h 中找到所有緩解標(biāo)志的值。以下是模塊篡改保護(hù)的值:
這些值與 Map 頂部的 DWORD 相關(guān),因此模塊篡改保護(hù)位實(shí)際上位于 Map的第 44 位,在 Hex Rays 屏幕截圖中以及在 PspApplyMitigationOptions 中檢查的是相同位。
現(xiàn)在我們知道該緩解措施在哪里應(yīng)用了檢查,因此我們可以開(kāi)始查看實(shí)現(xiàn)并了解該緩解措施的作用。
實(shí)現(xiàn)細(xì)節(jié)
再次查看 LdrpGetImportDescriptorForSnap:在我們已經(jīng)看到的兩次檢查之后,該函數(shù)獲取主圖像的 NT 標(biāo)頭并調(diào)用 LdrpCheckPagesForTampering 兩次。第一次發(fā)送的地址是 imageNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT],圖像的導(dǎo)入表,大小為 8 個(gè)字節(jié)。第二次使用 NT 標(biāo)頭本身的地址和大小調(diào)用該函數(shù)。如果這些頁(yè)面中的一個(gè)被認(rèn)為被篡改了,LdrpMapCleanModuleView將被調(diào)用(根據(jù)名稱(chēng)判斷)映射主圖像模塊的一個(gè)干凈的視圖。
讓我們看看 LdrpCheckPagesForTampering 內(nèi)部,看看 NTDLL 如何判斷一個(gè)頁(yè)面是否被篡改:
首先,此函數(shù)計(jì)算請(qǐng)求的字節(jié)范圍內(nèi)的頁(yè)數(shù)(在本文的兩個(gè)示例中,該數(shù)字都是 1)。然后它分配內(nèi)存并使用 MemoryInformationClass == 4 (MemoryWorkingSetExInformation) 調(diào)用 ZwQueryVirtualMemory。這個(gè)系統(tǒng)調(diào)用和信息類(lèi)是安全人員可能不太經(jīng)??吹降?,工作集是一種基于物理內(nèi)存頁(yè)面當(dāng)前狀態(tài)來(lái)管理和優(yōu)先級(jí)排序的方法,因此大多數(shù)安全人員通常不感興趣。然而,工作集確實(shí)包含一些我們感興趣的屬性。具體來(lái)說(shuō),是“共享”標(biāo)志。
我不會(huì)在這里詳細(xì)介紹映射和共享內(nèi)存,因?yàn)樗鼈冊(cè)诤芏嗥渌胤蕉加薪忉尅5?jiǎn)而言之,系統(tǒng)盡量不復(fù)制內(nèi)存,因?yàn)檫@意味著物理內(nèi)存將很快被復(fù)制的頁(yè)面填滿,主要是那些屬于圖像和 DLL 的頁(yè)面, 像 ntdll.dll 或 kernel32.dll 的系統(tǒng) DLL被映射到大多數(shù)系統(tǒng)中的進(jìn)程,因此在物理內(nèi)存中為每個(gè)進(jìn)程單獨(dú)創(chuàng)建一個(gè)副本只是浪費(fèi)。因此,這些圖像頁(yè)面在所有進(jìn)程之間共享。也就是說(shuō),除非以任何方式修改圖像。圖像頁(yè)面使用一種稱(chēng)為“寫(xiě)時(shí)復(fù)制(copy-on-write)”的特殊保護(hù),它允許頁(yè)面可寫(xiě),但如果頁(yè)面被寫(xiě)入,則會(huì)在物理內(nèi)存中創(chuàng)建一個(gè)新副本。這意味著對(duì) DLL 的本地映射所做的任何更改(例如,用戶模式掛鉤的寫(xiě)入或任何數(shù)據(jù)更改)都只會(huì)影響當(dāng)前進(jìn)程中的 DLL。
這些設(shè)置保存為可以通過(guò) NtQueryVirtualMemory 查詢(xún)的標(biāo)志,這里使用的信息類(lèi):MemoryWorkingSetExInformation。它將在 MEMORY_WORKING_SET_EX_INFORMATION 結(jié)構(gòu)中返回有關(guān)查詢(xún)頁(yè)面的數(shù)據(jù):
這個(gè)結(jié)構(gòu)為你提供了被查詢(xún)的虛擬地址,以及包含頁(yè)面狀態(tài)信息的位,例如:它的有效性、保護(hù)以及它的共享狀態(tài)。有幾個(gè)不同的位與頁(yè)面的共享狀態(tài)相關(guān):
共享——頁(yè)面是可共享的嗎?這并不一定意味著該頁(yè)當(dāng)前與任何其他進(jìn)程共享,但是,例如,除非進(jìn)程特別請(qǐng)求,否則私有內(nèi)存不會(huì)被共享。
ShareCount——此字段告訴你此頁(yè)面存在多少映射。對(duì)于當(dāng)前未與任何其他進(jìn)程共享的頁(yè)面,這將是 1。對(duì)于與其他進(jìn)程共享的頁(yè)面,這通常會(huì)更高。
SharedOriginal ——該標(biāo)志會(huì)告訴你該頁(yè)面是否存在映射。因此,如果一個(gè)頁(yè)面被修改,導(dǎo)致在物理內(nèi)存中創(chuàng)建一個(gè)新副本,這將被設(shè)置為零,因?yàn)檫@不是頁(yè)面的原始映射。
此 SharedOriginal 位是由 LdrpCheckPagesForTampering 檢查的,以判斷此頁(yè)面是原始副本還是由于更改而創(chuàng)建的新副本。如果這不是原始副本,這意味著該頁(yè)面以某種方式被篡改,因此該函數(shù)將返回 TRUE。 LdrpCheckPagesForTampering 對(duì)正在查詢(xún)的每個(gè)頁(yè)面運(yùn)行此檢查,如果其中任何一個(gè)被篡改,則返回 TRUE。
如果函數(shù)對(duì)任何檢查范圍返回 TRUE,則調(diào)用 LdrpMapCleanModuleView:
這個(gè)函數(shù)簡(jiǎn)短而簡(jiǎn)單:它使用 InformationClass == 89 (ProcessImageSection) 調(diào)用 NtQueryInformationProcess 來(lái)獲取主圖像的部分句柄,然后使用 NtMapViewOfSection 重新映射它并關(guān)閉句柄。它將新部分的地址寫(xiě)入 DataTableEntry->SwitchBackContect,以代替原來(lái)的篡改映射。
為什么該特性特別選擇檢查這兩個(gè)范圍——導(dǎo)入表和 NT 標(biāo)頭?
這是因?yàn)檫@兩個(gè)地方經(jīng)常會(huì)成為試圖虛化進(jìn)程的攻擊者的目標(biāo)。如果主圖像未映射并被惡意圖像替換,則 NT 標(biāo)頭將不同并被視為已篡改。進(jìn)程空心化(Process hollowing)還可以篡改導(dǎo)入表,以指向與進(jìn)程預(yù)期不同的函數(shù)。所以,這主要是一個(gè)反空心化的功能,目標(biāo)是發(fā)現(xiàn)主圖像中的篡改企圖,并用一個(gè)沒(méi)有被篡改的新圖像副本替換它。
功能限制
不幸的是,此功能相對(duì)有限。你可以啟用或禁用它,僅此而已。實(shí)現(xiàn)緩解的函數(shù)是內(nèi)部調(diào)用,不能在外部調(diào)用。因此,例如,除非你自己編寫(xiě)代碼(并手動(dòng)映射模塊,因?yàn)檫@些部分的句柄不方便地存儲(chǔ)在任何地方),否則不可能將緩解擴(kuò)展到其他模塊。此外,此緩解不包含日志記錄或 ETW 事件。當(dāng)緩解通知在主圖像中被篡改時(shí),它會(huì)靜默映射并使用新副本,并且不會(huì)留下任何痕跡供安全產(chǎn)品或團(tuán)隊(duì)查找。唯一的提示是 NtMapViewOfSection 將再次為主圖像調(diào)用并生成 ETW 事件和內(nèi)核回調(diào)。但這很可能會(huì)被忽視,因?yàn)樗⒉灰欢ㄒ馕吨l(fā)生了不好的事情,并且可能不會(huì)導(dǎo)致任何警報(bào)或?qū)赡苁钦嬲墓舻闹卮笳{(diào)查。
從好的方面來(lái)說(shuō),這種緩解非常簡(jiǎn)單和有用,如果你想實(shí)現(xiàn)它,則很容易模仿,例如檢測(cè)放置在你的進(jìn)程上的鉤子并映射一個(gè)新的、未掛鉤的頁(yè)面副本以供使用。你可以這樣做,而不是使用直接系統(tǒng)調(diào)用!
該緩解措施有人使用過(guò)嗎?
在 WinDbg 中運(yùn)行查詢(xún),我沒(méi)有發(fā)現(xiàn)任何啟用模塊篡改保護(hù)的進(jìn)程的結(jié)果。經(jīng)過(guò)一番探索,我設(shè)法找到了一個(gè)啟用此功能的進(jìn)程:SystemSettingsAdminFlows.exe。此過(guò)程在你打開(kāi) Windows 設(shè)置菜單中的應(yīng)用程序->可選功能時(shí)執(zhí)行。我不知道為什么這個(gè)特定的進(jìn)程會(huì)使用這種緩解措施,或者為什么它是唯一一個(gè)這樣做的,但這是迄今為止我設(shè)法找到的唯一一個(gè)啟用模塊篡改保護(hù)的過(guò)程。
本文翻譯自:https://windows-internals.com/understanding-a-new-mitigation-module-tampering-protection/
網(wǎng)頁(yè)名稱(chēng):新的緩解措施:模塊篡改保護(hù)
新聞來(lái)源:http://fisionsoft.com.cn/article/dpjhsco.html


咨詢(xún)
建站咨詢(xún)
