Windows漏洞缓解技术

2023/04/11 漏洞 共 5341 字,约 16 分钟

Windows漏洞缓解技术

GS(安全检查)

保护原理

当栈中发生溢出时,Security Cookie将被首先淹没,之后才是EBP和返回地址。

在函数返回之前,系统将执行一个额外的安全验证操作,被称作Security check。

在Security check的过程中,系统将比较栈帧中原先存放的Security Cookie和.data中副本的值,如果两者不吻合,说明栈帧中的Security Cookie已被破坏,即栈中发生了溢出。

当检测到栈中发生溢出时,系统将进入异常处理流程,函数不会被正常返回,ret指令也不会被执行。

变量重排技术

在编译时根据局部变量的类型对变量在栈帧中的位置进行调整,将字符串变量移动到栈帧的高地址,防止字符串溢出时破坏其他的局部变量。将指针参数和字符串参数复制到内存中低地址,防止函数参数被破坏。

绕过GS

利用未被保护的内存突破GS

不会应用GS的情况

(1)函数不包含缓冲区

(2)函数被定义为具有变量参数列表

(3)函数使用无保护的关键字标记

(4)函数在第一个语句中包含内嵌汇编代码

(5)缓冲区不是8字节类型且大小不大于4个字节

新的安全标识:#pragma strict_gs_check

通过添加#pragma strict_gs_check(on) 可以对任意类型的函数添加 Security Cookie,通过设置该标识,可以对不符合 GS 保护条件的函数添加 GS 保护

#pragma strict_gs_check(on) // 为下边的函数强制启用 GS

覆盖虚函数突破 GS

根据GS机制,程序只有在函数返回时,才去检查Security Cookie,而在这之前是没 有任何检查措施。所以我们可以在程序检查 Security Cookie 之前劫持程序流程, 实现对程序的溢出,恰好C++的虚函数满足这个需求。

覆盖虚表指针,指向shellcode。

控制虚表指针,将其指向可以控制的内存空间,就可以在程序调用虚函数时控制程序 的流程。

使用字符串结束符“\0”覆盖虚表指针的最低 位即可让其指向原始参数的最前端。

UAF漏洞利用原理

攻击异常处理突破 GS

1) 分析异常处理函数原型的四个参数,具体如下:

EXCEPTION_DISPOSITION __cdecl _except_handler (

​ struct _EXCEPTION_RECORD * _ExceptionRecord,

​ void *EstablisherFrame, // 这里指向自己覆盖的异常链prve成员的起始地址

​ struct _CONTEXT * _ContextRecord,

​ void * _DispatcherContext

);

2) 可以考虑通过构建一个ret,返回至_EstablisherFrame所指向的地址执行;

3) 通过pop#pop在栈中将“_except_handler返回地址”与“_ExceptionRecord”弹出,使得ret能够将_EstablisherFrame当作返回地址使用;

4) 将_EstablisherFrame所指向位置的数据(也就是自己覆盖的异常链prve成员的起始地址)修改为“jmp xx”的opcode,跳转至shellcode执行;

通过传递一个负 值来将指针向低地址方向移动,将其覆盖为 90909090,通过输入超长字符串来修改 Security Cookie, 此时将 90909090 与 当前 EBP 异或的结果放到栈中 Security Cookie 的位置即可。

同时修改栈和.data中的Cookie挫败GS的Shellcode布局

最开始的位置放上 4 个 0x90 用来修改 0x00403000 的 值,后边跟着弹出“failewest”对话框的机器码,然后用 0x90 填充至 Security Cookie 的位置, 接下来跟着 90909090 与当前 EBP 异或的结果,最后再加上 4 个字节的填充和 Shellcode 的起始 地址(用来覆盖函数返回地址)。

SafeSEH(SEH校验机制)

软件DEP

保护原理

在程序调用异常处理函数前,对要调用的异常处理函数进 行一系列的有效性校验,当发现异常处理函数不可靠时将终止异常处理函数的调用。

RtlDispatchException() 函数 -> 检查异常处理链是否位于当前程序的栈中 -> 检查异常处理函数指针是否指向当前程序的栈中 -> 调用 RtlIsValidHandler() 函数,来对异常处 理函数的有效性进行验证

RtlIsValidHandler() 函数

判断异常处理函数地址是不是在加载模块的内存空间,如果属于加载模块的 内存空间,校验函数将依次进行如下校验:

IMAGE_DLLCHARACTERISTICS_NO_SEH 标识

安全 S.E.H 表

ILonly 标识

位于不可执行页(non-executable page),是否启用DEP

如果异常处理函数的地址没有包含在加载模块的内存空间,校验函数将直接进行 DEP 相 关检测,函数依次进行如下校验:

位于不可执行页(non-executable page),是否启用DEP

允许跳转到加载模块的内存空间外执行

RtlIsValidHandler校验流程

绕过SafeSEH

攻击返回地址绕过 SafeSEH

###

利用虚函数绕过 SafeSEH

###

从堆中绕过 SafeSEH

(1)首先在堆中申请 500 字节的空间,用来存放 shellcode。

(2)函数 test 存在一个典型的溢出,通过向 str 复制超长字符串造成 str 溢出,进而覆盖程 序的 S.E.H 信息。

(3)用 shellcode 在堆中的起始地址覆盖异常处理函数地址,然后通过制造除 0 异常,将程 序转入异常处理,进而跳转到堆中的 shellcode 执行。

跳到堆中绕过SafeSEH的Shellcode布局

利用未启用 SafeSEH 模块绕过 SafeSEH

(1)编译一个不使用 SafeSEH 的动态链接库 SEH_NOSafeSEH_JUMP.DLL, 然后由启用 SafeSEH 的应用程序 SEH_NOSafeSEH.EXE 去加载它。

(2)SEH_NOSafeSEH 中的 test 函数存在一个典型的溢出,通过向 str 复制超长字符串造成 str 溢出,进而覆盖程序的 S.E.H 信息。

(3)使用 SEH_NOSafeSEH_JUMP.DLL 中的“pop pop retn”指令地址覆盖异常处理函数地 址,然后通过制造除 0 异常,将程序转入异常处理。通过劫持异常处理流程,程序转入 SEH_NOSaeSEH_JUMP.DLL 中执行“pop pop retn”指令,在执行 retn 后程序转入 shellcode 执行。

利用加载模块之外的地址绕过 SafeSEH

类型为 Map 的映射文件,SafeSEH 是无视它们的, 当异常处理函数指针指向这些地址范围内时,是不对其进行有效性验证的,所以如果我们可以 在这些文件中找到跳转指令绕过 SafeSEH。

利用Adobe Flash Player ActiveX控件绕过SafeSEH

未启用 SafeSEH 模块

DEP(数据执行保护)

硬件DEP

保护原理

DEP 的基本原理是将数据所在内存页标识为不可执行,当程序溢出成功转入 shellcode 时,

程序会尝试在数据页面上执行指令,此时 CPU 就会抛出异常,而不是去执行恶意指令。

DEP工作原理

AMD 称之为 No-Execute Page-Protection (NX),Intel 称之为 Execute Disable Bit (XD)

绕过DEP

攻击未启用 DEP 的程序

###

利用 Ret2Libc 挑战 DEP

Ret2libc流程

(1)通过跳转到 ZwSetInformationProcess 函数将 DEP 关闭后再转入 shellcode 执行

进程的 DEP 设置标识保存在 KPROCESS 结构中的_KEXECUTE_OPTIONS 上,而这 个标识可以通过 API 函数 ZwQueryInformationProcess 和 ZwSetInformationProcess 进行查询和 修改。

_KEXECUTE_OPTIONS //_KEXECUTE_OPTIONS 结构

Pos0ExecuteDisable :1bit

Pos1ExecuteEnable :1bit

Pos2DisableThunkEmulation :1bit

Pos3Permanent :1bit //未置1会进行兼容性检测

Pos4ExecuteDispatchEnable :1bit

Pos5ImageDispatchEnable :1bit

Pos6Spare :2bit

当前进程 DEP 开启ExecuteDisable 位被置 1,当 进程 DEP 关闭ExecuteEnable 位被置1,DisableThunkEmulation 是为了兼容 ATL 程序设置的, Permanent 被置 1 后表示这些标志都不能再被修改。

关键函数 NtSetInformationProcess(在 Ntdll.dll 中 Nt函数和 Zw函数功能是完全一样的)

ZwSetInformationProcess(

IN HANDLE ProcessHandle, //进程句柄,设置为 −1 的时候表示为当前进程

IN PROCESS_INFORMATION_CLASS ProcessInformationClass, //信息类

IN PVOID ProcessInformation, //用来设置_KEXECUTE_OPTIONS

IN ULONG ProcessInformationLength ); //第三个参数的长度

设置为 ->

ULONG ExecuteFlags = MEM_EXECUTE_OPTION_ENABLE;

ZwSetInformationProcess(

NtCurrentProcess(), // (HANDLE)-1

ProcessExecuteFlags, // 0x22

&ExecuteFlags, // ptr to 0x2

sizeof(ExecuteFlags)); // 0x4

如果一个进程的 Permanent 位没有设置,当它加载 DLL 时,系统就会对这个 DLL 进行 DEP 兼容性检查,当存在兼容性问题时进程的 DEP 就会被关闭。

为此微软设立了LdrpCheckNXCompatibility函数,当符合以下条件之一时进程的DEP会被关闭:

(1)当 DLL 受 SafeDisc 版权保护系统保护时;

(2)当 DLL 包含有.aspcak、.pcle、.sforce 等字节时;

(3)Windows V ista 下面当 DLL 包含在注册表“HKEY_LOCAL_MACHINE\SOFTWARE \Microsoft\ Windows NT\CurrentVersion\Image File Execution Options\DllNXOptions”键下边标识 出不需要启动 DEP 的模块时。

关闭DEP流程

(2)通过跳转到 VirtualProtect 函数来将 shellcode 所在内存页设置为可执行状态,然后再转入 shellcode 执行。

VirtualProtect 函数

BOOL VirtualProtect(

LPVOID lpAddress, // 要改变属性的内存起始地址

DWORD dwSize, // 要改变属性的内存区域大小

DWORD flNewProtect, // 内存新的属性类型,设置为 PAGE_EXECUTE_READWRITE(0x40)时该内存页为可读可写可执行

PDWORD lpflOldProtect // 内存原始属性类型保存地址

);

更改为 ->

BOOL VirtualProtect(

shellcode 所在内存空间起始地址,

shellcode 大小,

0x40,

某个可写地址

);

修改内存属性成功时函数返回非 0,修改失败时返回 0。

(3)通过跳转到 VIrtualAlloc 函数开辟一段具有执行权限的内存空间,然后将 shellcode 复 制到这段内存中执行。

利用可执行内存挑战 DEP

###

利用.NET 挑战 DEP

###

利用 Java applet 挑战 DEP

ASLR(地址空间布局随机化)

保护原理

通过加载程序的时候不再使用固定的基址加载,从而干扰 shellcode 定位。

绕过ASLR

攻击未启用 ASLR 的模块

Flash Player ActiveX 并未支持 SafeSEH,ASLR 等新特性

利用部分覆盖进行定位内存地址

映像随机化只是对映像加载基址的前 2 个字节做随机化处理

只覆盖这个地址的最后一个字节,或者最 后两个字节

ASLR 只是随机化了映 像的加载基址,而没有对指令序列进行随机化。

利用 Heap spray 技术定位内存地址

通过申请大量的内存,占领内存中的 0x0C0C0C0C 的位置,并在这些内存中放置 0x90 和 shellcode,最后控制程序转入 0x0C0C0C0C 执行。

利用 Java applet heap spray 技术定位内存地址

为.NET 控件禁用 ASLR

SEHOP(结构化异常处理覆盖保护)

保护原理

SEHOP 的核心任务就是检查这条 S.E.H 链的完整性,在程序转入异常处理前 SEHOP 会检 查 S.E.H 链上最后一个异常处理函数是否为系统固定的终极异常处理函数。如果是,则说明这 条 S.E.H 链没有被破坏,程序可以去执行当前的异常处理函数;如果检测到最后一个异常处理 函数不是终极 BOSS,则说明 S.E.H 链被破坏,可能发生了 S.E.H 覆盖攻击,程序将不会去执 行当前的异常处理函数。

绕过SEHOP

攻击返回地址

###

攻击虚函数

###

利用未启用 SEHOP 的模块

###

伪造 S.E.H 链表

伪造SEH链

文档信息

Search

    Table of Contents