恶意软件如何隐藏DLL以及如何识别它?——可以使用vmmmap、procexp、volatility 3

发布时间 2023-05-03 17:22:13作者: bonelee

 

 

 

好了,为了简单表示上述提到的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,以后遇到了再回头看吧。