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

   

二、Dedicated Support Engineer

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启动为例分析:

   

UPGDSED的分析与绕过PG和DSE的方式_第1张图片

   

2、UPGDSED的准备流程

主干简单的述下:

(1)、PGDSED准备了两种结构体,分别为 用作补丁的PATCH结构体 和 符号SYMBOL结构体。

(2)、PGDSED在修补内核文件时,有两种找到目标函数的方式,分别为 通过符号查找 和 通过特征码查找。

   

1、准备工作

PATCH结构体 SYMBOL结构体:

   

UPGDSED的分析与绕过PG和DSE的方式_第2张图片

UPGDSED的分析与绕过PG和DSE的方式_第3张图片

   

并定义一些修补函数的全局变量。

   

UPGDSED的分析与绕过PG和DSE的方式_第4张图片

UPGDSED的分析与绕过PG和DSE的方式_第5张图片

   

分别提取 "dbghelp.dll""symsrv.dll" 转至目录C:\Users\User\AppData\Local\Temp

   

UPGDSED的分析与绕过PG和DSE的方式_第6张图片

   

UPGDSED的分析与绕过PG和DSE的方式_第7张图片

UPGDSED的分析与绕过PG和DSE的方式_第8张图片

   

   

加载Temp目录下的"dbghelp.dll""symsrv.dll",并建立符号模型。

   

UPGDSED的分析与绕过PG和DSE的方式_第9张图片

UPGDSED的分析与绕过PG和DSE的方式_第10张图片

   

将C:\Windows\System32目录下的"ntoskrnl.exe""winload.exe" 拷贝至C:\Users\User\AppData\Local\Temp目录下,

并分别更名为"ntkrnlmp.exe""osloader.exe"

UPGDSED的分析与绕过PG和DSE的方式_第11张图片

   

   

有两个函数 ScanNtos() 和 ScanWinload() 会分别对"ntkrnlmp.exe" 和 "osloader.exe" 进行扫描修补。

这里以SeValidateImageData为例:

"ntkrnlmp.exe"映射进内存,并加载符号列表 和 初始化Symbol结构体数组

然后调用专门的函数,处理对应内核文件的函数字节。

UPGDSED的分析与绕过PG和DSE的方式_第12张图片

   

介绍两种找到目标修改点的方式。

通过符号查找 和 通过FindPattern特征码查找。

   

Symbol查找:

判断版本,通过Symbol数组,查找目标函数名,返回函数地址。

要修改函数的哪个位置,把位置的特征码赋值给Pattern,并设置扫描大小ScanSize。

   

UPGDSED的分析与绕过PG和DSE的方式_第13张图片

UPGDSED的分析与绕过PG和DSE的方式_第14张图片

   

如果获取符号失败,则采用

FindPattern特征码方式:

   

定位到"EGAP"区段。区段的大小即扫描大小。

   

UPGDSED的分析与绕过PG和DSE的方式_第15张图片

   

赋值更长更确定的特征码给Pattern。

   

UPGDSED的分析与绕过PG和DSE的方式_第16张图片

   

设置跳过字节。

   

   

遍历找到指定位置。

   

UPGDSED的分析与绕过PG和DSE的方式_第17张图片

   

最后转换文件偏移,Address加上SkipBytes,保存在PATCH全局变量。

   

UPGDSED的分析与绕过PG和DSE的方式_第18张图片

   

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 };

   

修改前:

修改后:

UPGDSED的分析与绕过PG和DSE的方式_第19张图片

   

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 };

   

修改前:

修改后:

UPGDSED的分析与绕过PG和DSE的方式_第20张图片

   

另:

加命令行参数"-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修改内核文件。

   

UPGDSED的分析与绕过PG和DSE的方式_第21张图片

   

修正文件的校验和。

   

UPGDSED的分析与绕过PG和DSE的方式_第22张图片

UPGDSED的分析与绕过PG和DSE的方式_第23张图片

   

将文件移至system32。

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

   

设置BCD条目。

   

UPGDSED的分析与绕过PG和DSE的方式_第24张图片

   

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

转载于:https://www.cnblogs.com/KIDofot/p/9067594.html

你可能感兴趣的:(操作系统,php)