UPGDSED的分析與繞過PG和DSE的方式


大綱:

對UPGDSED源碼進行分析,並淺析其繞過PG和DSE方式。

   

小插曲:

(1)、要在內核搞事情,就必須加載驅動。加載驅動的道路充滿荊棘,先是有殺軟的加載驅動攔截,后是有MS的 PG 和 DSE 保護。殺軟那一關已經過了,但后面還有PG和DSE。

(2)、逐漸深入研究,發現FyyreEP_X0FF兩位大牛早已經繞過了,並且公布了UPGDSED源碼。在這里表示敬佩。

(3)、時間有限,接下來我能做的,就是分析UPGDSED源碼,和盡可能多得學習各種繞過的方法。所以UPGDSED源碼分析會先發布,而繞過PG和DSE方法會逐步更新。

(4)為Win10_1803做准備。(據說1803的PG發生了大變化)。

大牛請留下指導or繞過~:)

   

一、PatchGuard

隱藏驅動過PG:

https://github.com/Sqdwr/HideDriver

https://github.com/ZhuHuiBeiShaDiao/NewHideDriverEx

   

二、Driver Signature Enforcement

0day漏洞繞過DSE:

http://www.powerofcommunity.net/poc2012/mj0011.pdf

https://github.com/shjalayeri/DriveCrypt

   

吊銷正規簽名過DSE:

https://bbs.pediy.com/thread-187348.htm

   

白名單驅動繞過DSE:

http://www.kernelmode.info/forum/viewtopic.php?f=11&t=3322 

   

三、UPGDSED

EP_X0FF源碼:

參考資料:

https://github.com/hfiref0x/UPGDSED

http://www.kernelmode.info/forum/viewtopic.php?f=11&t=4707&p=30269&hilit=DSE#p30269

   

1、環境

以 win10_1709_16299.15 BIOS啟動為例分析:

   

   

2、UPGDSED的准備流程

主干簡單的述下:

(1)、PGDSED准備了兩種結構體,分別為 用作補丁的PATCH結構體 和 符號SYMBOL結構體。

(2)、PGDSED在修補內核文件時,有兩種找到目標函數的方式,分別為 通過符號查找 和 通過特征碼查找。

   

1、准備工作

PATCH結構體 SYMBOL結構體:

   

   

並定義一些修補函數的全局變量。

   

   

分別提取 "dbghelp.dll""symsrv.dll" 轉至目錄C:\Users\User\AppData\Local\Temp

   

   

   

   

加載Temp目錄下的"dbghelp.dll""symsrv.dll",並建立符號模型。

   

   

將C:\Windows\System32目錄下的"ntoskrnl.exe""winload.exe" 拷貝至C:\Users\User\AppData\Local\Temp目錄下,

並分別更名為"ntkrnlmp.exe""osloader.exe"

   

   

有兩個函數 ScanNtos() 和 ScanWinload() 會分別對"ntkrnlmp.exe" 和 "osloader.exe" 進行掃描修補。

這里以SeValidateImageData為例:

"ntkrnlmp.exe"映射進內存,並加載符號列表 和 初始化Symbol結構體數組

然后調用專門的函數,處理對應內核文件的函數字節。

   

介紹兩種找到目標修改點的方式。

通過符號查找 和 通過FindPattern特征碼查找。

   

Symbol查找:

判斷版本,通過Symbol數組,查找目標函數名,返回函數地址。

要修改函數的哪個位置,把位置的特征碼賦值給Pattern,並設置掃描大小ScanSize。

   

   

如果獲取符號失敗,則采用

FindPattern特征碼方式:

   

定位到"EGAP"區段。區段的大小即掃描大小。

   

   

賦值更長更確定的特征碼給Pattern。

   

   

設置跳過字節。

   

   

遍歷找到指定位置。

   

   

最后轉換文件偏移,Address加上SkipBytes,保存在PATCH全局變量。

   

   

3、ScanNtos() 和 ScanWinload() 分析(重點)

分析,並做出前后對比。

system32 "ntoskrnl.exe" -->> Temp "ntkrnlmp.exe"

   

SeValidateImageData:

FindPattern數據:

unsigned char ptSeValidateImageData_2_15063_16299[] = { 0xB8, 0x28, 0x04, 0x00, 0xC0, 0xEB };

SkipBytes字節:

#define ptSkipBytesSeValidateImageData_9600_16299 1

PatchData數據:

// Patch data for SeValidateImageData STATUS_SUCCESS

unsigned char pdSeValidateImageData[] = { 0x0, 0x0, 0x0, 0x0 };

   

修改前:

修改后:

   

CcInitializeBcbProfiler:

符號搜索:

Address = (ULONG_PTR)SymbolAddressFromName(TEXT("CcInitializeBcbProfiler"));

FindPattern數據:

//Windows 10+

unsigned char ptCcInitializeBcbProfiler_10240_16299[] = {

0x40, 0x55, 0x53, 0x56, 0x57, 0x41, 0x54, 0x41,

0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 0x8D, 0x6C,

0x24, 0xE1, 0x48, 0x81, 0xEC, 0xB8, 0x00, 0x00,

0x00

};

PatchData數據:

unsigned char pdCcInitializeBcbProfiler[] = { 0xB0, 0x01, 0xC3 };

   

修改前:

修改后:

   

KeInitAmd64SpecificState:

   

符號搜索:

Address = (ULONG_PTR)SymbolAddressFromName(TEXT("KeInitAmd64SpecificState"));

FindPattern數據:

//Windows 8/8.1/10 (TH1/TH2/RS1/RS2/RS3)

unsigned char ptKeInitAmd64SpecificState_9200_16299[] = { 0x48, 0x83, 0xEC, 0x28, 0x83, 0x3D };

PatchData數據:

unsigned char pdKeInitAmd64SpecificState[] = { 0x33, 0xC0, 0xC3 };

   

修改前:

修改后:

   

ExpLicenseWatchInitWorker:

符號搜索:

Address = (ULONG_PTR)SymbolAddressFromName(TEXT("ExpLicenseWatchInitWorker"));

FindPattern數據:

//Windows 8.1/10 TH1/TH2/RS1/RS3

unsigned char ptExpLicenseWatchInitWorker2[] = { 0x40, 0x53, 0x48, 0x83, 0xEC, 0x30, 0x48, 0x8B, 0x05 };

PatchData數據:

unsigned char pdExpLicenseWatchInitWorker[] = { 0x33, 0xC0, 0xC3 };

修改前:

修改后:

   

SepInitializeCodeIntegrity:

符號搜索:

ScanPtr = (PVOID)SymbolAddressFromName(TEXT("SepInitializeCodeIntegrity"));

FindPattern數據:

//Windows 10 RS3

unsigned char ptSepInitializeCodeIntegrity2_16299[] = {

0x48, 0x89, 0x5C, 0x24, 0x08, 0x57,

0x48, 0x83, 0xEC, 0x20, 0xBB, 0xC0,

0x00, 0x00, 0x00

};

&&-->>

unsigned char ptSepInitializeCodeIntegrity_16299[] = { 0x8B, 0xCF, 0xFF };

PatchData數據:

unsigned char pdSepInitializeCodeIntegrity[] = { 0x31, 0xC9 };

   

修改前:

修改后:

   

   

system32 "winload.exe" -->> Temp "osloader.exe"

   

ImgpValidateImageHash:

符號搜索:

// Invalid

Address = (ULONG_PTR)SymbolAddressFromName(TEXT("ImgpValidateImageHash"));

FindPattern數據:

unsigned char ptImgpValidateImageHash_16299[] = {

0x48, 0x8B, 0xC4, 0x4C, 0x89, 0x48, 0x20, 0x44, 0x89, 0x40, 0x18, 0x48, 0x89, 0x50, 0x10, 0x48,

0x89, 0x48, 0x08, 0x55, 0x53, 0x56, 0x57, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48,

0x8D, 0xA8, 0xA8, 0xFE, 0xFF, 0xFF

};

PatchData數據:

unsigned char pdImgpValidateImageHash[] = { 0x33, 0xC0, 0xC3 };

   

修改前:

修改后:

   

另:

加命令行參數"-pf"啟動程序,將會忽略掉KeInitAmd64SpecificState 和 ExpLicenseWatchInitWorker,而選擇 KiFilterFiberContext 進行修補。

KiFilterFiberContext:

符號搜索:

Address = (ULONG_PTR)SymbolAddressFromName(TEXT("KiFilterFiberContext"));

FindPattern數據:

//Windows 10 RS3

unsigned char ptKiFilterFiberContext_16299[] = {

0x48, 0x89, 0x5C, 0x24, 0x08, 0x55, 0x56,

0x57, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56,

0x41, 0x57, 0x48, 0x8D, 0x6C, 0x24, 0xD9,

0x48, 0x81, 0xEC, 0x90, 0x00, 0x00, 0x00

};

PatchData數據:

unsigned char pdKiFilterFiberContext[] = { 0xB0, 0x01, 0xC3 };

   

修改前:

修改后:

   

   

4、后續修補及操作

逐個PATCH修改內核文件。

   

   

修正文件的校驗和。

   

   

將文件移至system32。

Temp "ntkrnlmp.exe" && Temp "osloader.exe" -->> system32

   

設置BCD條目。

   

   

cmd以下命令:

bcdedit.exe -create {71A3C7FC-F751-4982-AEC1-E958357E6813} -d "Patch Guard Disabled" -application OSLOADER

bcdedit.exe -set {71A3C7FC-F751-4982-AEC1-E958357E6813} device partition=C:

bcdedit.exe -set {71A3C7FC-F751-4982-AEC1-E958357E6813} osdevice partition=C:

bcdedit.exe -set {71A3C7FC-F751-4982-AEC1-E958357E6813} systemroot \Windows

bcdedit.exe -set {71A3C7FC-F751-4982-AEC1-E958357E6813} path \Windows\system32\osloader.exe

bcdedit.exe -set {71A3C7FC-F751-4982-AEC1-E958357E6813} kernel ntkrnlmp.exe

bcdedit.exe -set {71A3C7FC-F751-4982-AEC1-E958357E6813} recoveryenabled 0

bcdedit.exe -set {71A3C7FC-F751-4982-AEC1-E958357E6813} nx OptIn

bcdedit.exe -set {71A3C7FC-F751-4982-AEC1-E958357E6813} nointegritychecks 1

bcdedit.exe -set {71A3C7FC-F751-4982-AEC1-E958357E6813} inherit {bootloadersettings}

bcdedit.exe -displayorder {71A3C7FC-F751-4982-AEC1-E958357E6813} -addlast

bcdedit.exe -timeout 10

bcdedit.exe -set bootmenupolicy legacy

   

BCD加入的配置信息:

Windows 啟動加載器

-------------------

標識符 {71a3c7fc-f751-4982-aec1-e958357e6813}

device partition=C:

path \Windows\system32\osloader.exe

description Patch Guard Disabled

inherit {bootloadersettings}

recoveryenabled No

nointegritychecks Yes

osdevice partition=C:

systemroot \Windows

kernel ntkrnlmp.exe

nx OptIn

   

   

三、UPGDSED淺析

主要對(二 . 3)的探究,原理淺析。

源碼采用的是靜態繞過PG和DSE。

   

1、PG

資料准備中,很快更新。 

   

2、DSE

資料准備中,很快更新。 

 

參考資料:

原文:

https://www.symantec.com/content/dam/symantec/docs/security-center/white-papers/assessment-windows-vista-kernel-mode-06-en.pdf

譯文:

   

   

   

3、校驗修改

修改了ntoskrnl.exe就必須修改winload.exe ImgpValidateImageHash,因為ImgpValidateImageHash會對文件的數字簽名和文件的完整性進行校驗,修改頭部字節讓它返回STATUS_SUCCESS即可。

   

   

   

附言:

研究這些費了不少時間,而且研究MS Edge的保護也花了不少時間,等搞完后要好好研究內核的一些神操作。

還有,此篇文章未完待續,因為1803還沒搞定呢。

   

   

KID


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM