恶意软件如何隐藏DLL以及如何识别它?——可以使用vmmmap、procexp、volatility 3
好了,为了简单表示上述提到的PEB和DLL加载的关系,给一一张图如下:
TEB(Thread Environment Block,线程环境块)系统在此TEB中保存频繁使用的线程相关的数据。
PEB(Process Environment Block,进程环境块)存放进程信息,每个进程都有自己的PEB信息。
上图可以看到dll清单类似os进程枚举,都有blink和flink双链表指针结构,指向进程所有的dll加载。
我用vol3实验下,看看加载的dll:
PS D:\Application\volatility3-stable> python .\vol.py -f D:\book\malwarecookbook-master\malwarecookbook-master\15\6\prolaco.vmem\prolaco.vmem windows.dlllist --pid 632 Volatility 3 Framework 2.4.1 Progress: 100.00 PDB scanning finished PID Process Base Size Name Path LoadTime File output 632 winlogon.exe 0x1000000 0x80000 winlogon.exe \??\C:\WINDOWS\system32\winlogon.exe N/A Disabled 632 winlogon.exe 0x7c900000 0xb0000 - - N/A Disabled 632 winlogon.exe 0x7c800000 0xf4000 kernel32.dll C:\WINDOWS\system32\kernel32.dll N/A Disabled 632 winlogon.exe 0x77dd0000 0x9b000 ADVAPI32.dll C:\WINDOWS\system32\ADVAPI32.dll N/A Disabled 632 winlogon.exe 0x77e70000 0x91000 RPCRT4.dll C:\WINDOWS\system32\RPCRT4.dll N/A Disabled 632 winlogon.exe 0x776c0000 0x11000 AUTHZ.dll C:\WINDOWS\system32\AUTHZ.dll N/A Disabled 632 winlogon.exe 0x77c10000 0x58000 msvcrt.dll C:\WINDOWS\system32\msvcrt.dll N/A Disabled 632 winlogon.exe 0x77a80000 0x94000 CRYPT32.dll C:\WINDOWS\system32\CRYPT32.dll N/A Disabled 632 winlogon.exe 0x77d40000 0x90000 USER32.dll C:\WINDOWS\system32\USER32.dll N/A Disabled 632 winlogon.exe 0x77f10000 0x46000 GDI32.dll C:\WINDOWS\system32\GDI32.dll N/A Disabled 632 winlogon.exe 0x77b20000 0x12000 MSASN1.dll C:\WINDOWS\system32\MSASN1.dll N/A Disabled 632 winlogon.exe 0x75940000 0x8000 NDdeApi.dll C:\WINDOWS\system32\NDdeApi.dll N/A Disabled 632 winlogon.exe 0x75930000 0xa000 PROFMAP.dll C:\WINDOWS\system32\PROFMAP.dll N/A Disabled 632 winlogon.exe 0x5b860000 0x54000 NETAPI32.dll C:\WINDOWS\system32\NETAPI32.dll N/A Disabled 632 winlogon.exe 0x769c0000 0xb3000 USERENV.dll C:\WINDOWS\system32\USERENV.dll N/A Disabled 632 winlogon.exe 0x76bf0000 0xb000 PSAPI.DLL C:\WINDOWS\system32\PSAPI.DLL N/A Disabled 632 winlogon.exe 0x76bc0000 0xf000 REGAPI.dll C:\WINDOWS\system32\REGAPI.dll N/A Disabled 632 winlogon.exe 0x77fe0000 0x11000 Secur32.dll C:\WINDOWS\system32\Secur32.dll N/A Disabled 632 winlogon.exe 0x77920000 0xf3000 SETUPAPI.dll C:\WINDOWS\system32\SETUPAPI.dll N/A Disabled 632 winlogon.exe 0x77c00000 0x8000 VERSION.dll C:\WINDOWS\system32\VERSION.dll N/A Disabled 632 winlogon.exe 0x76360000 0x10000 WINSTA.dll C:\WINDOWS\system32\WINSTA.dll N/A Disabled 632 winlogon.exe 0x76c30000 0x2e000 WINTRUST.dll C:\WINDOWS\system32\WINTRUST.dll N/A Disabled 632 winlogon.exe 0x76c90000 0x28000 IMAGEHLP.dll C:\WINDOWS\system32\IMAGEHLP.dll N/A Disabled
可疑的dll加载,文章说到的特质:
上面的话,是重点哈!就是说为了找到隐藏的DLL,其做法和前面隐藏进程名是一样的思路,都是进行内存扫描,然后再和PEB里加载的DLL进行比较。
我们看下unlinker的代码实现:
#include <Windows.h> #include <stdio.h> typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING, *PUNICODE_STRING; typedef struct _PEB_LDR_DATA { ULONG Length; UCHAR Initialized; PVOID SsHandle; LIST_ENTRY InLoadOrderModuleList; LIST_ENTRY InMemoryOrderModuleList; LIST_ENTRY InInitializationOrderModuleList; PVOID EntryInProgress; } PEB_LDR_DATA, *PPEB_LDR_DATA; typedef struct _LDR_MODULE { LIST_ENTRY InLoadOrderModuleList; LIST_ENTRY InMemoryOrderModuleList; LIST_ENTRY InInitializationOrderModuleList; PVOID DllBase; PVOID EntryPoint; ULONG SizeOfImage; UNICODE_STRING FullDllName; UNICODE_STRING BaseDllName; ULONG Flags; USHORT LoadCount; USHORT TlsIndex; LIST_ENTRY HashLinks; PVOID SectionPrimer; ULONG CheckSum; ULONG TimeDateStamp; PVOID LoadedImports; PVOID EntryPointActivationContext; PVOID PatchInformation; } LDR_MODULE, *PLDR_MODULE; //http://www.openrce.org/blog/view/844/How_to_hide_dll #define CUT_LIST(item) \ item.Blink->Flink = item.Flink; \ item.Flink->Blink = item.Blink int UnlinkDll(HANDLE hModToHide) { PPEB_LDR_DATA LdrData = NULL; PLDR_MODULE Module = NULL; __asm { mov eax, fs:30h //Find the PEB mov ebx, [eax+0Ch] //PEB.Ldr mov [LdrData], ebx }; for ( Module = (PLDR_MODULE)LdrData->InLoadOrderModuleList.Flink; Module->DllBase != 0; Module = (PLDR_MODULE)Module->InLoadOrderModuleList.Flink ) { if ((HMODULE)Module->DllBase == hModToHide) { CUT_LIST(Module->InLoadOrderModuleList); CUT_LIST(Module->InInitializationOrderModuleList); CUT_LIST(Module->InMemoryOrderModuleList); ZeroMemory(Module, sizeof(LDR_MODULE)); break; } } return 0; } int main (int argc, char **argv) { printf("unlink DLL demo!\n"); UnlinkDll(GetModuleHandleW(L"kernel32.dll")); // block until a key is pressed (for analysis time) getchar(); return 0; }
是不是就是个进程隐藏的思路是一样的呢!!!的确如此!!!都是在链表里找到自己,然后解除链接!!!
#define CUT_LIST(item) \
item.Blink->Flink = item.Flink; \
item.Flink->Blink = item.Blink
好了,我们看看现象,以及如何发现隐藏的DLL:
在我的机器上,我使用vmmap看到的,注意vmmap这个工具也是sysinternals开发的,感觉用起来还是很不错的!
不过书中前面说的可能有些问题,最新的procexp是可以看到加载的DLL的:
最后,我们随便用一个进程id实验下vol3的ldr modules命令用法:
PS D:\Application\volatility3-stable> python .\vol.py -f D:\book\malwarecookbook-master\malwarecookbook-master\15\6\prolaco.vmem\prolaco.vmem windows.ldrmodules --pid 632 Volatility 3 Framework 2.4.1 Progress: 100.00 PDB scanning finished Pid Process Base InLoad InInit InMem MappedPath 632 winlogon.exe 0x1000000 True False True \WINDOWS\system32\winlogon.exe 632 winlogon.exe 0x5b860000 True True True \WINDOWS\system32\netapi32.dll 632 winlogon.exe 0x7c800000 True True True \WINDOWS\system32\kernel32.dll 632 winlogon.exe 0x77dd0000 True True True \WINDOWS\system32\advapi32.dll 632 winlogon.exe 0x77e70000 True True True \WINDOWS\system32\rpcrt4.dll
因为要在虚拟机里抓取UNlinker的vmem,比较繁琐,在此就不再实验了。
最后,更高阶的对抗,还会是内核级别的rootkit,以后遇到了再回头看吧。