在 【Day 10】穿过 IE 的巴巴 - Hook IE 窃取明文密码讲了 Hook 的红队利用,从 IE 窃取明文密码。可能有些人已经开始感到焦虑了,难道我们没有方法抵挡攻击吗,所以这篇就介绍蓝队的防守方法。
从之前的 【Day 09】Hook 的奇妙冒险 - Ring3 Hook 可以知道,Hook 其实就是改掉原本的 Function,控制程序的进行,改成执行我们自己定义的 Function。基於这一点,我们能怎麽侦测 Hook 呢?
这篇文章会拿之前讲的 Hook IE 的偷取明文连线资讯的 POC 当作目标,实作侦测 Hook 的程序。
Hook 的本质就是 Patch,它必须改掉原本的程序来达到控制程序的目的。根据这点,我们很容易就能想到一个侦测的方法,就是比对档案与记忆体的内容。
因为程序在载入 Image 时,并不是直接执行档案,而是把档案内容复制到记忆体中执行。也就是说,举 Hook IE 中的 wininet.dll 的 SendHttpRequestW 为例,我实际上改的是记忆体中的 SendHttpRequestW,而 wininet.dll 档案本身并没有被改动到。
因此只要比对没有被改动到的档案,与不确定有没有被改动的记忆体,在大部分的情况下,如果两者相同,就代表没有被 Hook。
虽然原理简单,却有不少魔鬼小细节,因此这个主题会分两篇讲解。这篇处理记忆体,下一篇处理档案。
目前已知目标 Process 是 iexplorer.exe,目标 Module 是 WININET.DLL。首先可以看一下 EnumProcessModules 这个函数。其中 lphModule 放着所有 Module 的阵列,我们的目标 wininet.dll 就在这里面。
BOOL EnumProcessModules(
HANDLE hProcess,
HMODULE *lphModule,
DWORD cb,
LPDWORD lpcbNeeded
);
那要怎麽知道目前的这个 Module 是不是我们的目标呢?可以使用 GetModuleFileNameExW 这个函数。其中 lpFilename 就是 Module 的档案路径,只要比对它有没有包含 wininet.dll 字串就可以知道它是不是我们的目标。
DWORD GetModuleFileNameExW(
HANDLE hProcess,
HMODULE hModule,
LPWSTR lpFilename,
DWORD nSize
);
取得 wininet.dll 这个 Module 的 Handle 後,可以使用 GetModuleInformation 取得有关这个 Module 的资讯。其中 Module 的 Base Address 就在 lpmodinfo 里面。lpmodinfo 是一个 MODULEINFO 结构。
BOOL GetModuleInformation(
HANDLE hProcess,
HMODULE hModule,
LPMODULEINFO lpmodinfo,
DWORD cb
);
程序的专案可以参考我的 GitHub zeze-zeze/2021iThome
#include <windows.h>
#include <string>
#include <psapi.h>
int main(int argc, char* argv[]) {
// 1. 开启目标 Process (iexplorer.exe 的 pid)
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, 1912);
if (!hProcess) {
printf("OpenProcess failed: error %d\n", GetLastError());
return 1;
}
// 2. 用 EnumProcessModules 取得所有的 Module Handle
HMODULE hMods[1024], hModule = NULL;
DWORD cbNeeded;
if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) {
for (int i = 0; i < (int)(cbNeeded / sizeof(HMODULE)); i++) {
TCHAR szModPathName[MAX_PATH] = { 0 };
// 3. 用 GetModuleFileNameEx 取得目前的 Module Name
if (GetModuleFileNameEx(hProcess, hMods[i], szModPathName, sizeof(szModPathName) / sizeof(TCHAR))) {
printf("%ls\n", szModPathName);
// 4. 判断是不是目标 (WININET),是的话就记录下来
std::wstring sMod = szModPathName;
if (sMod.find(L"WININET") != std::string::npos) {
hModule = hMods[i];
}
}
else {
printf("GetModuleFileNameEx failed: error %d\n", GetLastError());
return NULL;
}
}
}
else {
printf("EnumProcessModulesEx failed: error %d\n", GetLastError());
return 1;
}
if (hModule == NULL) {
printf("Cannot find target module\n");
return 1;
}
printf("\n\nWININET.dll handle: %p\n", hModule);
// 5. 用 GetModuleInformation 取得 Module 资讯
MODULEINFO lpmodinfo;
if (!GetModuleInformation(hProcess, hModule, &lpmodinfo, sizeof(MODULEINFO))) {
printf("GetModuleInformation failed: error %d\n", GetLastError());
return 1;
}
return 0;
}
记得把 POC 的 pid 改成自己环境测试的 iexplore.exe 的 pid,然後要编成 x86 的执行档,因为目标 Process 是 32-bit。程序会列举所有 Image,虽然使用的函数不同,但这也算是完成 Sysinternals 中的 Listdlls.exe 的最基本功能。
# FindModule.exe
C:\Program Files (x86)\Internet Explorer\IEXPLORE.EXE
C:\WINDOWS\SYSTEM32\ntdll.dll
C:\WINDOWS\System32\KERNEL32.DLL
C:\WINDOWS\System32\KERNELBASE.dll
C:\WINDOWS\SYSTEM32\apphelp.dll
C:\WINDOWS\System32\USER32.dll
C:\WINDOWS\System32\win32u.dll
C:\WINDOWS\System32\GDI32.dll
C:\WINDOWS\System32\gdi32full.dll
C:\WINDOWS\System32\msvcp_win.dll
C:\WINDOWS\System32\ucrtbase.dll
C:\WINDOWS\System32\msvcrt.dll
C:\WINDOWS\System32\ADVAPI32.dll
C:\WINDOWS\System32\sechost.dll
C:\WINDOWS\System32\RPCRT4.dll
C:\WINDOWS\System32\combase.dll
C:\WINDOWS\SYSTEM32\iertutil.dll
C:\WINDOWS\System32\shcore.dll
C:\WINDOWS\System32\IMM32.DLL
C:\WINDOWS\System32\bcryptPrimitives.dll
C:\WINDOWS\SYSTEM32\msIso.dll
C:\WINDOWS\SYSTEM32\kernel.appcore.dll
C:\WINDOWS\SYSTEM32\IEFRAME.dll
C:\WINDOWS\System32\SHLWAPI.dll
C:\WINDOWS\System32\ole32.dll
C:\WINDOWS\System32\OLEAUT32.dll
C:\WINDOWS\System32\SHELL32.dll
C:\WINDOWS\SYSTEM32\USERENV.dll
C:\WINDOWS\SYSTEM32\VERSION.dll
C:\WINDOWS\SYSTEM32\NETAPI32.dll
C:\WINDOWS\SYSTEM32\WINHTTP.dll
C:\WINDOWS\SYSTEM32\WKSCLI.DLL
C:\WINDOWS\SYSTEM32\NETUTILS.DLL
C:\WINDOWS\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.19041.1110_none_a8625c1886757984\comctl32.dll
C:\Program Files (x86)\Internet Explorer\IEShims.dll
C:\WINDOWS\System32\comdlg32.dll
C:\WINDOWS\system32\uxtheme.dll
C:\WINDOWS\SYSTEM32\MSHTML.dll
C:\WINDOWS\SYSTEM32\SspiCli.dll
C:\WINDOWS\SYSTEM32\powrprof.dll
C:\WINDOWS\SYSTEM32\UMPDC.dll
C:\WINDOWS\SYSTEM32\CRYPTBASE.DLL
C:\WINDOWS\SYSTEM32\urlmon.dll
C:\WINDOWS\SYSTEM32\srvcli.dll
C:\WINDOWS\System32\clbcatq.dll
C:\WINDOWS\system32\windows.storage.dll
C:\WINDOWS\system32\Wldp.dll
C:\WINDOWS\SYSTEM32\WININET.dll
C:\WINDOWS\system32\profapi.dll
C:\WINDOWS\System32\WS2_32.dll
C:\WINDOWS\SYSTEM32\ondemandconnroutehelper.dll
C:\WINDOWS\system32\mswsock.dll
C:\WINDOWS\SYSTEM32\IPHLPAPI.DLL
C:\WINDOWS\SYSTEM32\WINNSI.DLL
C:\WINDOWS\System32\NSI.dll
C:\Windows\System32\ieproxy.dll
C:\WINDOWS\System32\MSCTF.dll
C:\WINDOWS\SYSTEM32\IEUI.dll
C:\WINDOWS\SYSTEM32\d2d1.dll
C:\WINDOWS\SYSTEM32\DWrite.dll
C:\WINDOWS\SYSTEM32\dxgi.dll
C:\WINDOWS\SYSTEM32\ieapfltr.dll
C:\WINDOWS\SYSTEM32\CRYPTSP.dll
C:\WINDOWS\System32\bcrypt.dll
C:\WINDOWS\SYSTEM32\d3d11.dll
C:\WINDOWS\System32\DriverStore\FileRepository\iigd_dch.inf_amd64_7afabf937b5bd7bd\igd10iumd32.dll
C:\WINDOWS\System32\CRYPT32.dll
C:\WINDOWS\SYSTEM32\ncrypt.dll
C:\WINDOWS\SYSTEM32\NTASN1.dll
C:\WINDOWS\System32\DriverStore\FileRepository\iigd_dch.inf_amd64_7afabf937b5bd7bd\igdgmm32.dll
C:\WINDOWS\System32\DriverStore\FileRepository\iigd_dch.inf_amd64_7afabf937b5bd7bd\igc32.dll
C:\WINDOWS\SYSTEM32\dxcore.dll
C:\WINDOWS\System32\cfgmgr32.dll
C:\WINDOWS\system32\dataexchange.dll
C:\WINDOWS\system32\dcomp.dll
C:\WINDOWS\system32\twinapi.appcore.dll
C:\WINDOWS\SYSTEM32\TextShaping.dll
C:\WINDOWS\SYSTEM32\srpapi.dll
C:\WINDOWS\SYSTEM32\ninput.dll
C:\WINDOWS\system32\mlang.dll
C:\Windows\System32\jscript9.dll
C:\WINDOWS\SYSTEM32\dwmapi.dll
C:\WINDOWS\SYSTEM32\sxs.dll
C:\WINDOWS\System32\IDStore.dll
C:\WINDOWS\System32\SAMLIB.dll
C:\WINDOWS\System32\PROPSYS.dll
C:\WINDOWS\SYSTEM32\tbs.dll
C:\WINDOWS\System32\imagehlp.dll
C:\WINDOWS\system32\msimtf.dll
C:\WINDOWS\system32\directmanipulation.dll
C:\Windows\System32\vaultcli.dll
C:\WINDOWS\SYSTEM32\wintypes.dll
C:\WINDOWS\SYSTEM32\Secur32.dll
C:\WINDOWS\SYSTEM32\textinputframework.dll
C:\WINDOWS\System32\CoreMessaging.dll
C:\WINDOWS\System32\CoreUIComponents.dll
C:\WINDOWS\SYSTEM32\ntmarta.dll
C:\Windows\System32\OneCoreCommonProxyStub.dll
WININET.dll handle: 71280000
<<: 前端工程师也能开发全端网页:挑战 30 天用 React 加上 Firebase 打造社群网站|Day26 根据主题筛选文章列表
>>: 【程序】开始任务起手式 转生成恶役菜鸟工程师避免 Bad End 的 30 件事 - 13
接着我们要进入到 slate 的下一个重点章节: Immutability 。 虽然这已经算是一个...
接下来,会就六角学院 UI 设计入门 课程中,针对团队合作时会碰到的情境稍作讨论。 设计稿再好看也没...
图片截自三立新闻 与笔者年纪相当的朋友,肯定还记得小时候有个非常红的电示节目叫「龙兄虎弟」吧。当时...
写到最後三天了,想要聊聊和 Android 不完全相关的东西。感谢JetBrains 的开发,和 K...
do while 与 while 的分别 do while 先执行回圈内的循环,再进行检查,判断为 ...