Export Address Table Access Filtering (EAF)
“This mitigation filters accesses to the Export Address Table (EAT), allowing or disallowing the read/write access based on the calling code. With EMET in place, most of today’s shellcode will be blocked when it tries to lookup the APIs needed for its payload.”
根据它的介绍,我们可以知道EAF主要是基于这样一个事实: 当前绝大部分的Shellcode在运行时,都需要搜索要用到的API地址,而这一行为通常是通过对相应模块导出表的遍历来实现的。而EAF这个Feature通过对ntdll.dll和kernel32.dll导出表的相应位置(其实就是IMAGE_EXPORT_DIRECTORY.AddressOfFunctions字段) 下硬件断点,来监控shellcode 对导出表的搜索行为. 导出表结构如下:
typedef struct _IMAGE_EXPORT_DIRECTORY {
DWORD Characteristics;
DWORD TimeDateStamp;
WORD MajorVersion;
WORD MinorVersion;
DWORD Name;
DWORD Base;
DWORD NumberOfFunctions;
DWORD NumberOfNames;
DWORD AddressOfFunctions; // Set Hardware Breakpoint here
DWORD AddressOfNames;
DWORD AddressOfNameOrdinals;
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
这次用windbg调试之, 我们看到一个单步异常:
(3ac.154): Single step exception - code 80000004 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
看一下调试寄存器
Dr0= 7c802648, Dr1= 7c90341c, 分别对应了kernel32和ntdll的导出表
不处理异常, 继续跑之, 经过ntdll!RtlCallVectoredExceptionHandlers进入到emet.dll空间,也就是说, emet.dll通过注册了一个向量化异常处理函数, 来处理硬件断点
还原一下该函数:
LONG WINAPI
VectoredHandler3(
struct _EXCEPTION_POINTERS *ExceptionInfo
)
{
HMODULE hModule = NULL;
LONG dwReturnCode = EXCEPTION_CONTINUE_SEARCH;
ClearHardwareBPS(GetCurrentThread());
//
// Is our bp hit?
//
if (ExceptionInfo->ContextRecord->Dr6 & 0x11)
{
if (GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
ExceptionInfo->ContextRecord->Eip,
&hModule))
{
if (hModule)
dwReturnCode = EXCEPTION_CONTINUE_EXECUTION;
else
Die();
}
else
Die();
}
Heapspray Allocations
“With EMET in place some commonly used pages are pre-allocated. Exploits that rely on controlling these pages (and then jumping into them) will fail.”