本文为看雪论精华文章
看雪论坛作者ID:SSH山水画
这是一款比较简单的木马,通过分析此样本可以训练分析思路、分析逻辑,并且加强IDA的使用。如有不对的地方,欢迎指出,择优吸收。
File: virus.exe
SHA1: 71b7322291b5a89d227b5cfe82106fce51036da2
SHA256:b48ebc54b9717bbe3a9de3fd5744c8ad1fdd3a26c7b47f6170b98f8abde9a744
LsHashS:1155293a7b9091923b1d1511a8d9c17589bb1b55b4613bd55313ba7b3594b899
MD5:00877507f0b812599868a647330d0630
分析环境:Windows7_Service Pack 1
分析工具:OD IDA 火绒剑 PEID
拖入PEID查一下有没有壳子:
yoda's Protector v1.02 (.dll,.ocx) -> Ashkbiz Danehkar (h) [Overlay] *
不了解,只知道有个加密壳。
右键查看文件属性:
属性为空,至少确定了不是个正规公司开发的程序,直接上火绒剑吧。
过滤FILE_open REG_openkey REG_getval FILE_read 行为(个人习惯,因为这几个行为基本没卵用)。
不得不说,火绒剑真是方便,程序行为十分清晰了。
样本启动了svchost.exe后直接结束了。
而下方的行为显然不是svchost.exe应该有的,目测会有一段注入ShellCode的代码。
到这里,这个程序基本上可以报毒了:静默运行+启动svchost.exe执行敏感代码+无任何文件描述信息。
我们接下来要对这个样本进行稍微详细的分析,看看他具体干了什么。
将样本拖入IDA32,分别查看字符串+导入表:
发现字符串有很多URL还有请求头信息,我们随便选一个:
http://morphed.ru/static.php
去VT查一下:
很好,非常不正常!我们又可以为他扣掉几分(所以到现在还是在做黑白鉴定的工作)。
该步入正题了,上面查看文件属性,文件大小不是很大,字符串和导入表信息也不多,因此我们决定从入口点开始进行分析,在IDA中找到入口点按下F5分析伪源码 (个人比较喜欢F5,但是这是不好的,遇到强度高的样本,F5反而会增加你的工作量)。
可以看到上来就开始开辟内存,拷贝0x00401000处的数据,我们去看看401000存了些啥:
一段函数代码+一堆未知数据,暂时记住这个地方,后面可能会用到。
简单起个名后,继续分析,我们看到memcpy下面的sub_407AC4紧接着就对这块内存进行了操作,跟进去看看函数内部情况:
没有再调用函数,反而进行了很多数据的运算,而一般这种情况不是加密就是解密,结合上面的行为分析结果,加上调用407AC4这个函数后并没有接收这个函数的返回值,推测此处对ShellCode进行了解密一类的操作。
回到入口函数,观察下一行代码:
sub_407B02(pAlloc_, 0x490, LoadLibraryA, GetProcAddress);
参数有很明显的特点:
-
一段ShellCode的首地址
-
一个未知的常量
-
两个经典远线程注入需要用到的函数地址
进入函数内部,为参数命名后,看一下代码:
哦吼,又是没有函数调用,全部在对数据进行操作,两层循环嵌套,循环内调用了GetProcAddress和LoadLibrary,根据传入的参数401000 490我们去看看401490都存了些啥。
定位到401490按D让其以字节显示,观察附近的数据,有了很明显的发现:
下面是一个个函数名字符串,我们按A Alt+A把这些数据以字符串进行展示,观察结果:
根据401490附近的字符串,我们最终可以推测出sub_407B02处的函数用于加载函数,模拟导入表功能,将其命名FixImport。
回到主函数继续分析:return ((int (__stdcall *)(_DWORD))(pAlloc_0 + 0xC0))(sub_407992);
可以看到这行代码用于执行4010C0出的函数,传入参数为407992,一个函数地址。
我们之前记得401000向下是由一段数据+一段函数代码组成。
而这行代码以函数指针的形式调用了4010C0的代码,却不是直接写成函数。
由此我们验证了上文对401000处数据为ShellCode的猜想,接下来我们则需要知道4010C0干了什么。
为Dump中的函数命名
此时,我们dump文件同目录下会生成一个与dump文件同名的idc文件:1.idc
用notepad++将其打开:
static main(void)
{
// set 'loading idc file' mode
set_inf_attr(INF_GENFLAGS, INFFL_LOADIDC|get_inf_attr(INF_GENFLAGS));
GenInfo(); // various settings
Segments(); // segmentation
Enums(); // enumerations
Structures(); // structure types
ApplyStrucTInfos(); // structure type infos
Patches(); // manual patches
SegRegs(); // segment register values
Bytes(); // individual bytes (code,data)
Functions(); // function definitions
// clear 'loading idc file' mode
set_inf_attr(INF_GENFLAGS, ~INFFL_LOADIDC&get_inf_attr(INF_GENFLAGS));
}
我们会看到这样一段代码,把函数内容全部删除,只留下Bytes(); // individual bytes (code,data)
static main(void)
{
Bytes(); // individual bytes (code,data)
}
接下来Ctrl+F搜索Bytes,我们看看这个Bytes函数干了什么:
static Bytes(void) {
Bytes_0();
end_type_updating(UTP_STRUCT);
}
可以看到Bytes调用了Bytes_0,我们再搜索Bytes_0去看看他的内容:
static Bytes_0(void) {
auto x;
#define id x
update_extra_cmt (0X20000, E_PREV + 0, "; File Name : G://1.mem");
update_extra_cmt (0X20000, E_PREV + 1, "; Format : Binary file");
update_extra_cmt (0X20000, E_PREV + 2, "; Base Address: 0000h Range: 0000h - 2000h Loaded length: 2000h");
create_dword (0X20000);
create_dword (0X20004);
create_dword (0X20008);
create_dword (0X2000C);
create_dword (0X20010);
create_dword (0X20014);
create_dword (0X20018);
create_dword (0X2001C);
create_dword (0X20020);
create_dword (0X20024);
create_dword (0X20028);
create_dword (0X2002C);
create_word (0X20036);
create_word (0X2003A);
create_dword (0X2003C);
make_array (0X2003C, 0X9);
create_strlit (0X20060, 0X20068);
set_name (0X20060, "a753");
create_strlit (0X20068, 0X20094);
set_name (0X20068, "aSystem32Wuaucl");
create_strlit (0X20094, 0X200C0);
set_name (0X20094, "aSyswow64Svchos");
create_insn (0X200C0);
create_insn (x=0X200C3);
op_hex (x, 1);
create_insn (0X2014F);
create_insn (0X203C9);
set_cmt (0X2041D, "Trap to Debugger", 0);
create_insn (x=0X2041D);
op_hex (x, 0);
create_insn (0X2041E);
create_insn (0X20424);
create_insn (0X2042A);
create_insn (0X20430);
create_insn (0X20436);
create_insn (0X2043C);
create_insn (0X20442);
create_insn (0X20448);
create_insn (0X2044E);
create_insn (0X20454);
create_insn (0X2045A);
create_insn (0X20460);
create_insn (0X20466);
create_insn (0X2046C);
create_insn (0X20472);
create_insn (0X20478);
create_insn (0X2047E);
create_insn (0X20484);
create_insn (0X2048A);
create_dword (x=0X20490);
op_plain_offset (x, 0, 0);
op_plain_offset (x, 128, 0);
create_dword (0X20494);
make_array (0X20494, 0X2);
create_byte (0X2049D);
make_array (0X2049D, 0X3);
create_dword (x=0X204A0);
op_plain_offset (x, 0, 0);
op_plain_offset (x, 128, 0);
create_dword (x=0X204A4);
op_plain_offset (x, 0, 0);
op_plain_offset (x, 128, 0);
make_array (0X204A8, 0X8);
make_array (0X204B2, 0X2);
create_dword (0X204B4);
make_array (0X204B4, 0X6);
create_dword (x=0X204CC);
op_plain_offset (x, 0, 0);
op_plain_offset (x, 128, 0);
create_dword (x=0X204D0);
op_plain_offset (x, 0, 0);
op_plain_offset (x, 128, 0);
create_byte (0X204D5);
make_array (0X204D5, 0X3);
make_array (0X204DA, 0X2);
make_array (0X204DE, 0X2);
make_array (0X204E2, 0X2);
create_dword (x=0X204E4);
op_plain_offset (x, 0, 0);
op_plain_offset (x, 128, 0);
create_dword (x=0X204E8);
op_plain_offset (x, 0, 0);
op_plain_offset (x, 128, 0);
make_array (0X204EE, 0X2);
make_array (0X204F2, 0X2);
make_array (0X204F6, 0X2);
make_array (0X204FA, 0X6);
create_dword (x=0X20500);
op_plain_offset (x, 0, 0);
op_plain_offset (x, 128, 0);
create_dword (x=0X20504);
op_plain_offset (x, 0, 0);
op_plain_offset (x, 128, 0);
create_byte (0X20509);
make_array (0X20509, 0X3);
create_dword (x=0X2050C);
op_plain_offset (x, 0, 0);
op_plain_offset (x, 128, 0);
make_array (0X20512, 0X2);
create_byte (0X20515);
make_array (0X20515, 0X3);
make_array (0X20519, 0X7);
create_strlit (0X20522, 0X20533);
set_name (0X20522, "aNtdelayexecuti");
create_strlit (0X20536, 0X2053E);
set_name (0X20536, "aZwclose");
create_byte (0X2053F);
create_strlit (0X20541, 0X20550);
set_name (0X20541, "aWcreatesection");
create_strlit (0X20552, 0X20565);
set_name (0X20552, "aZwmapviewofsec");
create_strlit (0X20569, 0X20582);
set_name (0X20569, "aWqueryinformat");
create_word (0X20582);
create_strlit (0X20585, 0X20593);
set_name (0X20585, "aWresumethread");
create_strlit (0X20597, 0X205AB);
set_name (0X20597, "aWunmapviewofse");
create_strlit (0X205AC, 0X205B6);
set_name (0X205AC, "aNtdllDll");
create_strlit (0X205B8, 0X205C4);
set_name (0X205B8, "aClosehandle");
create_strlit (0X205C7, 0X205D2);
set_name (0X205C7, "aReatefilew");
create_strlit (0X205D5, 0X205E3);
set_name (0X205D5, "aReateprocessw");
create_strlit (0X205E7, 0X205F2);
set_name (0X205E7, "aXitprocess");
create_word (0X205F2);
create_strlit (0X205F4, 0X20607);
set_name (0X205F4, "aGetmodulefilen");
create_byte (0X20609);
make_array (0X20609, 0X3);
create_strlit (0X2060C, 0X2061B);
set_name (0X2060C, "aTmodulehandlew");
create_strlit (0X2061E, 0X2062F);
set_name (0X2061E, "aGetthreadconte");
create_strlit (0X20633, 0X20647);
set_name (0X20633, "aEtwindowsdirec");
create_strlit (0X2064B, 0X20662);
set_name (0X2064B, "aEtenvironmentv");
create_strlit (0X20664, 0X20671);
set_name (0X20664, "aVirtualalloc");
create_byte (0X20673);
create_strlit (0X20674, 0X20680);
set_name (0X20674, "aVirtualfree");
create_strlit (0X20682, 0X2068B);
set_name (0X20682, "aLstrcatw");
create_strlit (0X2068C, 0X20699);
set_name (0X2068C, "aKernel32Dll");
make_array (0X20699, 0X3);
create_dword (0X2069C);
make_array (0X2069C, 0X25A);
create_dword (x=0X21004);
op_plain_offset (x, 0, 0);
op_plain_offset (x, 128, 0);
create_word (0X2100A);
create_dword (0X2100C);
make_array (0X2100C, 0X3FD);
}
可以看到一大堆函数代码,不要管,全部删除:
static Bytes_0(void) {
}
00020000 7DD7186E kernel32.VirtualFree
00020004 7DD71856 kernel32.VirtualAlloc
00020008 7DD789F1 kernel32.SetEnvironmentVariableW
0002000C 7DD743E2 kernel32.GetWindowsDirectoryW
00020010 7DD979D4 kernel32.Wow64GetThreadContext
00020014 7DD734B0 kernel32.GetModuleHandleW
00020018 7DD74950 kernel32.GetModuleFileNameW
0002001C 7DD77A10 kernel32.ExitProcess
00020020 7DD7103D kernel32.CreateProcessW
00020024 7DD73F5C kernel32.CreateFileW
00020028 7DD71410 kernel32.CloseHandle
0002002C 7DD9828E kernel32.lstrcatW
00020030 00000000
00020034 7DE90058 ntdll_12.ZwResumeThread
00020038 7DE8FAC8 ntdll_12.ZwQueryInformationProcess
0002003C 7DE8FC40 ntdll_12.ZwMapViewOfSection
00020040 7DE8FF94 ASCII "窑"
00020044 7DE8F9D0 ntdll_12.ZwClose
00020048 7DE8FC70 ntdll_12.ZwUnmapViewOfSection
0002004C 7DE8FD6C ntdll_12.ZwDelayExecution
00020050 00000000
00020054 00000000
00020058 00000000
0002005C 00000000
set_name (0x00020000, "VirtualFree");
set_name (0x00020004, "VirtualAlloc");
set_name (0x00020008, "SetEnvironmentVariableW");
set_name (0x0002000C, "GetWindowsDirectoryW");
set_name (0x00020010, "Wow64GetThreadContext");
set_name (0x00020014, "GetModuleHandleW");
set_name (0x00020018, "GetModuleFileNameW");
set_name (0x0002001C, "ExitProcess");
set_name (0x00020020, "CreateProcessW");
set_name (0x00020024, "CreateFileW");
set_name (0x00020028, "CloseHandle");
set_name (0x0002002C, "lstrcatW");
set_name (0x00020034, "ZwResumeThread");
set_name (0x00020038, "ZwQueryInformationProcess");
set_name (0x0002003C, "ZwMapViewOfSection");
set_name (0x00020044, "ZwClose");
set_name (0x00020048, "ZwUnmapViewOfSection");
set_name (0x0002004C, "ZwDelayExecution");
//记得别忘了后面的;和地址的0x 否则IDA执行脚本时会报错
static Bytes_0(void) {
set_name (0x00020000, "VirtualFree");
set_name (0x00020004, "VirtualAlloc");
set_name (0x00020008, "SetEnvironmentVariableW");
set_name (0x0002000C, "GetWindowsDirectoryW");
set_name (0x00020010, "Wow64GetThreadContext");
set_name (0x00020014, "GetModuleHandleW");
set_name (0x00020018, "GetModuleFileNameW");
set_name (0x0002001C, "ExitProcess");
set_name (0x00020020, "CreateProcessW");
set_name (0x00020024, "CreateFileW");
set_name (0x00020028, "CloseHandle");
set_name (0x0002002C, "lstrcatW");
set_name (0x00020034, "ZwResumeThread");
set_name (0x00020038, "ZwQueryInformationProcess");
set_name (0x0002003C, "ZwMapViewOfSection");
set_name (0x00020044, "ZwClose");
set_name (0x00020048, "ZwUnmapViewOfSection");
set_name (0x0002004C, "ZwDelayExecution");
}
看雪ID:SSH山水画
https://bbs.pediy.com/user-home-867232.htm
*本文由看雪论坛 SSH山水画 原创,转载请注明来自看雪社区。
好消息!!现在看雪《安卓高级研修班》线下班 & 网课(12月班)开始同步招生啦!以前没报上高研班的小伙伴赶快抓紧机会报名,升职加薪唾手可得!!
推荐文章++++
* Frida配合BurpSuite的Brida插件自动解密取证
求分享
求点赞
求在看
本文始发于微信公众号(看雪学院):一款木马释放器的简单分析及IDA的骚操作
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论