无壳
该病毒包含一个exe,一个dll
cmd.exe和command.com表明也许用到了shell进程
IsBadReadPtr用于验证一个进程是否对一块内存具有读取权限,这里看到了MapViewOfFile和UnMapViewOfFile表明程序用到了内存映射文件进行进程间通信。GetFileSize,CreateFileA,CopyFileA表明创建了一个文件。GetCommdandLineA读取了命令行参数控制程序的执行,GetModuleFileNameA读取了可执行文件的路径,可能用来安装病毒。
该病毒在C:\WINDOWS\System32\目录下安装了inet_epar32.dll,zzz69806582可能是个加密字符串,可能是命令的加密,net start cisvc启动了索引服务
下面来看下dll
GetActiveWindow用于获取最上层窗口的句柄,字符串“dddd,MMMM dd,yyyy"有加密特征,接着就是一些月份,我们不知道这些月份用来干嘛的
还有周一到周日
CreateMutexA创建互斥量,可能是为了在同一时刻只允许系统中运行一个病毒的实例CreateThread创建了一个新的线程,GetWindowTextA获取窗口的输入,GetForegroundWindow获取最上层的窗口,GetAsyncKeyState扫描键盘的状态,GetCommandLineA从命令行获取命令控制病毒的行为
这里和exe中看到了同一个字符串zzz69806582,<SHIFT>这个按键
很明显,这是一个击键记录器
看下exe导入了哪些函数
这里,和我们在strings下看到的一样
这里,dll导出了zzz69806582这个函数,原来不是一个字符串
USER32.DLL中只导入了三个函数,我们更加确信这是一个击键记录器
打开procmon
这里我们看到该病毒在C:\WINDOWS\System32目录下创建了inet_epar3.dll这个文件,用LoadPE比较一下
该病毒获取了cisvc的句柄,然后启动了命令行
最后,通过发送net start cisvc来启动索引服务。
用procexp查看进程树
cisvc服务正在运行
将可执行文件载入IDA
病毒将async.dll复制到C:\WINDOWS\System32\系统目录中,接着创建字符串C:\WINDOWS\System32\cisvc.exe并作为sub_401070的参数,接着调用系统命令net start cisvc启动索引服务.enter跟进sub_401070
cisvc.exe被映射到内存,MapViewOfFile返回内存映射视图的基址,UnmapViewOfFile调用之后对该文件的所有修改都会被写入硬盘,我们看看病毒向该程序写入了什么
lpBaseAddress表示cisvc.exe映射到内存的基址,该基址的var_28偏移处是将要被写入的位置,写入4E*4=312个字节,写入的内容是byte_409030处的内容,双击进入
这里是一段shellcode,按C将其转换为代码
(看不懂IDA shellcode分析的看我之前的文章<<病毒分析之shellcode的分析方法>>)
这就是将要注入到cisvc.exe的代码,一直到409168
这里,开头直接跳到了loc_409134处
调用的第一个函数是sub_4090dd
查看引用
该函数直接调用了两个函数,sub_4090bc和sub_40905f
4090dd的开头是pop ebx,这里ebx保存的是字符串"C:\WINDOWS\System32\inet_epar32.dll"以及导出函数名"zzz69806582"的地址。接着调用了sub_4090bc
首先清零eax,接着访问PEB结构(mov eax,fs:[eax+30]),fs指向当前活动线程的TEB结构,,其中偏移30处是指向PEB结构的指针,PEB结构偏移0ch处是指向PEB_LDR_DATA结构的指针,PEB_LDR_DATA结构的0x1c偏移处存放着一些指向动态链接库信息的链表地址,第一个是ntdll.dll
PEB_LDR_DATA结构如下
typedef struct _PEB_LDR_DATA
{
ULONG Length; // +0x00
BOOLEAN Initialized; // +0x04
PVOID SsHandle; // +0x08
LIST_ENTRY InLoadOrderModuleList; // +0x0c
LIST_ENTRY InMemoryOrderModuleList; // +0x14
LIST_ENTRY InInitializationOrderModuleList;// +0x1c
} PEB_LDR_DATA,PPEB_LDR_DATA; // +0x24
LIST_ENTRY结构定义如下
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY Flink;
struct _LIST_ENTRY Blink;
} LIST_ENTRY, PLIST_ENTRY, RESTRICTED_POINTER PRLIST_ENTRY;
这个双链表指向进程装载的模块,结构中的每个指针指向一个LDR_DATA_TABLE_ENTRY结构
typedef struct _LDR_DATA_TABLE_ENTRY
{
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
WORD LoadCount;
WORD TlsIndex;
union
{
LIST_ENTRY HashLinks;
struct
{
PVOID SectionPointer;
ULONG CheckSum;
};
};
union
{
ULONG TimeDateStamp;
PVOID LoadedImports;
};
_ACTIVATION_CONTEXT EntryPointActivationContext;
PVOID PatchInformation;
LIST_ENTRY ForwarderLinks;
LIST_ENTRY ServiceTagLinks;
LIST_ENTRY StaticLinks;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
mov esi,[eax+1ch]
lodsd将LDR_TABLE_ENTRY.InInitializationOrderLinks.Flink的值给eax
mov eax,[eax+8] eax获得LDR_DATA_TABLE_ENTRY.DllBase的值
这段代码的作用是在内存中找到kernel32.dll
这里,kernel32.dll的基址指针和753a4fc这个常量做为sub_40905f的参数被压栈,并且调用了两次sub_40905f
这里对参数进行重命名
在sub_40905f中调用了sub_40903e,enter
这里是一个解码循环
我们开始分析sub_40905f这个函数
409060到40906d开始解析kernel32.dll这个PE文件,并获取了指向PE特征域的指针
40906d到409079加上了正确的偏移,获得了指向IMAGE_EXPORT_DIRECTORY的指针,edx:=IMAGE_EXPORT_DIRECTORY的地址
409073处开始解析IMAGE_EXPORT_DIRECTORY结构体,加载NumberOfNames值及AddressOfNames指针
AddressOfName中的每个字符串指针都被传递到sub_40903e这个函数中,然后将这个计算结果与409092处传递给这个函数的参数进行比较
一旦AddressOfNames的正确索引被找到,它将作为位置40909d处的AddressOfNameOrdinals数组的索引,来获得对应的序号的数值,这个值被当作4090a6处的AddressOfFunctions数组的索引使用,这是病毒想要的值,它在4090b4处被写到了栈上,这里我们已经知道sub_40905f函数的作用:根据哈希值获取导出符号名,第一个kernell32.dll的导出函数地址被存放在[ebp-4]中,第二个函数被存放在[ebp-0ch]中,接着调用了第一个函数,第二个函数,如图所示
在shellcode的末尾出现了inet_epar32.dll路径和导出函数名,说明这个shellcode加载了这个DLL并调用了它的导出函数
我们知道cisvc.exe被注入了shellcode但是用IDA我们看不出来该病毒导出了kernell32.dll的哪两个函数(其实第一个我们可以猜到是LoadLibrary),我们恢复虚拟机到快照查看一下cisvc.exe感染前后的变化
shellcode修改了cisvc.exe的入口点,载入OD
在调用kernel32.dll第一个导出函数的地方下端断(忘了的看上面IDA的分析)
F9运行,在第一个函数处断了下来,如图
我们猜对了,这里调用的第一个函数是LoadLibraryExA
往下5行,是第二个函数的调用,GetProcAddress
这里我们看到LoadLibraryExA的第三个参数在eax中,我们在数据窗口中右键选择
go expresion
这里我们看eax存储的是字符串C:\WINDOWS\System32\inet_epar32.dll.zzz69806582
LoadLobraryExA将inet_epar32.dll载入内存.
在1001b1b处,该病毒将zzz69806582作为参数调用GetProcAddress,获取导出函数的地址最后一次函数调用是什么
在1001b21处下断及call dword ptr ss:[ebp-0x8]处下断,我们来看看该处是什么调用
如图,这里调用的是inet_epa.zzz69806582
最后1001b27处执行jmp cisvc.100129b跳转到cisvc原始的入口点.
接下来分析键盘记录器
来到StartAddress
该病毒调用CreateMutexA创建了一个名为MZ的互斥量,这个互斥量避免了同一时刻PC上有多个病毒实例在运行,如果该互斥量已经存在则OpenMutexA会终止这个线程(开头),创建互斥量之后在100014d4处调用CreateFileA创建了kernel64x.dll的文件,获取该文件的句柄后调用SetFilePointer将文件指针指向末尾
之后调用了sub_10001380这个函数,双击进入
sub_10001380调用了四个函数,分别是:
sub_10001030,sprintf,WriteFile,Sleep
双击进入sub_10001030
sub_10001030调用了四个函数,分别是
sub_10001000,mbsnbcmp,GetAsyncKeyState,sprintf
先看sub_10001000
GetForegroundWindow识别当前聚焦的窗口(即正在输入的窗口),它告诉击键记录器当前哪个应用程序正在执行输入,然后获取窗口的标题
这里先判断<shift>键有没有按下,10h对应<shift>键,接着判断大写锁定键有没有按下,对应14h
接下来的部分是一个大的循环结构用来遍历所有的按键
最后将所有的击键记录到kernel64x.dll这个文件中
该病毒启动索引服务cisvc.exe然后以直接注入的方式注入shellcode来加载一个DLL该DLL的用于实现击键记录.
(看不懂IDA shellcode分析的看我之前的文章<<病毒分析之shellcode的分析方法>>)
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2020-11-13 10:56
被Golden_Boy编辑
,原因: 图片上传失败