一个老马的写启动分析

来源:互联网 发布:犀牛软件6.0下载 编辑:程序博客网 时间:2024/04/29 01:29

主要工具OllyDBG吾爱破解版

本次案例:大概三个月前免杀且过启动项拦截的小马(感谢XX论坛的共享)  点此下载测试马

主要目标:分析出小马的具体写启动项过程

注意事项:保证安全,在虚拟机中进行分析


Firstly:检测

静态检测:

导出函数:空白——来自LordPE

导出函数:略,详见样本——来自LordPE

区段信息:.rdata .data .rsrc——来自LordPE

版本信息:Microsoft Visual C++ 6.0——来自PEiD

Secondly:分析

静态分析:略

动态分析

首先加载进入OD,入口点部分反汇编为
0040898B > DFDF fistp edi ; 非法使用寄存器
0040898D DFDF fistp edi ; 非法使用寄存器
0040898F DFDF fistp edi ; 非法使用寄存器
00408991 DFDF fistp edi ; 非法使用寄存器
00408993 DFDF fistp edi ; 非法使用寄存器
00408995 DFDF fistp edi ; 非法使用寄存器
00408997 DFDF fistp edi ; 非法使用寄存器
00408999 DFDF fistp edi ; 非法使用寄存器
0040899B /E9 A06A0100 jmp Server.0041F440

F7步过到0040899B,接下来一个JMP跳到了
0041F440 55 push ebp
0041F441 8BEC mov ebp,esp
0041F443 6A FF push -0x1
0041F445 68 68214000 push Server.00402168
0041F44A 68 A0EF4100 push Server.0041EFA0
0041F44F 64:A1 00000000 mov eax,dword ptr fs:[0]
0041F455 50 push eax
很明显从0041F440开始才是真正入口点,0040898B到00408999都不过是干扰指令。按照经验,在调用ExitProcess和GetStartupInfoA之间有一个Call内为程序主代码,往下翻,没有发现调用ExitProcess,有调用GetStartupInfoA,于是从GetStartupInfoA往下翻,代码如下
0041F4F1 FF15 F0104000 call dword ptr ds:[<&KERNEL32.GetStartup>; kernel32.GetStartupInfoA
0041F4F7 E8 F0420000 call Server.004237EC
0041F4FC 8945 9C mov dword ptr ss:[ebp-0x64],eax
0041F4FF F645 D0 01 test byte ptr ss:[ebp-0x30],0x1
0041F503 74 06 je XServer.0041F50B
0041F505 0FB745 D4 movzx eax,word ptr ss:[ebp-0x2C]
0041F509 EB 03 jmp XServer.0041F50E
0041F50B 6A 0A push 0xA
0041F50D 58 pop eax
0041F50E 50 push eax
0041F50F FF75 9C push dword ptr ss:[ebp-0x64]
0041F512 56 push esi
0041F513 56 push esi
0041F514 FF15 98114000 call dword ptr ds:[<&KERNEL32.GetModuleH>; kernel32.GetModuleHandleA
0041F51A 50 push eax
0041F51B E8 D37DFFFF call Server.004172F3
0041F520 8945 A0 mov dword ptr ss:[ebp-0x60],eax
0041F523 50 push eax
0041F524 E8 8D3B0000 call Server.004230B6
0041F529 8B45 EC mov eax,dword ptr ss:[ebp-0x14]
0041F52C 8B08 mov ecx,dword ptr ds:[eax]
0041F52E 8B09 mov ecx,dword ptr ds:[ecx]
0041F530 894D 98 mov dword ptr ss:[ebp-0x68],ecx
0041F533 50 push eax
0041F534 51 push ecx
0041F535 E8 3A410000 call Server.00423674
0041F53A 59 pop ecx
0041F53B 59 pop ecx
0041F53C C3 retn
看到了GetModuleHandleA和retn,可以确定那个Call就在这中间部分,第二个Call是0041F51B E8 D37DFFFF call Server.004172F3F4到这然后F7进入
004172F3 55 push ebp
004172F4 8BEC mov ebp,esp
004172F6 B8 24A00000 mov eax,0xA024
004172FB E8 D0750000 call Server.0041E8D0
00417300 53 push ebx
00417301 56 push esi
00417302 57 push edi
00417303 90 nop
00417304 90 nop
因为编译器一般通常不会编译出NOP这样的指令,可以确定这是程序代码里加入的,好,就是这里了,在004172F3下断方便下次载入,这部分没有什么意义纯属垃圾代码,经过6个NOP来到
00417309 E8 B2070000 call Server.00417AC0
0041730E 8B3D 80114000 mov edi,dword ptr ds:[<&KERNEL32.Sleep>] ; kernel32.Sleep
00417314 68 D0070000 push 0x7D0
00417319 FFD7 call edi
0041731B E8 C9080000 call Server.00417BE9
00417320 E8 3B070000 call Server.00417A60
先跟进第一个Call Server.00417AC0
00417AC0 68 305E4000 push Server.00405E30 ; ASCII "无助的肉鸡们"
00417AC5 6A 00 push 0x0
00417AC7 6A 00 push 0x0
00417AC9 6A 00 push 0x0
00417ACB FF15 24114000 call dword ptr ds:[<&KERNEL32.CreateEven>;kernel32.CreateEventA
00417AD1 FF15 64114000 call dword ptr ds:[<&KERNEL32.GetLastErr>; ntdll.RtlGetLastWin32Error
00417AD7 3D B7000000 cmp eax,0xB7 ;检测是否存在互斥对象
00417ADC 75 13 jnz XServer.00417AF1 ;如果已经存在就跳
00417ADE 68 E8030000 push 0x3E8
00417AE3 FF15 80114000 call dword ptr ds:[<&KERNEL32.Sleep>] ; kernel32.Sleep
00417AE9 6A 00 push 0x0
00417AEB FF15 AC104000 call dword ptr ds:[<&KERNEL32.ExitProces>; kernel32.ExitProcess
00417AF1 C3 retn
00417AC0的那个字符就是生成马的时候填入的,很明显可以看出来这一部分是创建互斥保证不会重复运行,retn回去,下一个Call是动态调用Sleep直接无视,第三个Call(代码较多,重点关注标色部分)
00417BE9 55 push ebp
00417BEA 8BEC mov ebp,esp
00417BEC 81EC 84030000 sub esp,0x384
00417BF2 53 push ebx
00417BF3 56 push esi
00417BF4 57 push edi
00417BF5 6A 4A push 0x4A
00417BF7 33DB xor ebx,ebx
00417BF9 59 pop ecx
00417BFA 33C0 xor eax,eax
00417BFC 8DBD A9FDFFFF lea edi,dword ptr ss:[ebp-0x257]
00417C02 889D A8FDFFFF mov byte ptr ss:[ebp-0x258],bl
00417C08 6A 4A push 0x4A
00417C0A F3:AB rep stos dword ptr es:[edi]
00417C0C 66:AB stos word ptr es:[edi]
00417C0E AA stos byte ptr es:[edi]
00417C0F 59 pop ecx
00417C10 33C0 xor eax,eax
00417C12 8DBD 7DFCFFFF lea edi,dword ptr ss:[ebp-0x383]
00417C18 889D 7CFCFFFF mov byte ptr ss:[ebp-0x384],bl
00417C1E F3:AB rep stos dword ptr es:[edi]
00417C20 66:AB stos word ptr es:[edi]
00417C22 AA stos byte ptr es:[edi]
00417C23 90 nop
00417C24 90 nop
00417C25 90 nop
00417C26 90 nop
00417C27 90 nop
00417C28 90 nop
00417C29 6A 4A push 0x4A
00417C2B 33C0 xor eax,eax
00417C2D 59 pop ecx
00417C2E 8DBD D5FEFFFF lea edi,dword ptr ss:[ebp-0x12B]
00417C34 889D D4FEFFFF mov byte ptr ss:[ebp-0x12C],bl
00417C3A 8B35 44124000 mov esi,dword ptr ds:[<&SHELL32.SHGetSpecialFo>; shell32.SHGetSpecialFolderPathA 获取SHGetSpecialFolderPathA的地址并放入ESI
00417C40 F3:AB rep stos dword ptr es:[edi]
00417C42 66:AB stos word ptr es:[edi]
00417C44 AA stos byte ptr es:[edi]
00417C45 53 push ebx
00417C46 8D85 A8FDFFFF lea eax,dword ptr ss:[ebp-0x258]
00417C4C 6A 18 push 0x18 ;SHGetSpecialFolderPathA函数的第三个参数
00417C4E 50 push eax
00417C4F 53 push ebx
00417C50 FFD6 call esi ;即调用SHGetSpecialFolderPathA
00417C52 90 nop
00417C53 90 nop
00417C54 90 nop
00417C55 90 nop
00417C56 90 nop
00417C57 90 nop
00417C58 8B3D 6CA54000 mov edi,dword ptr ds:[0x40A56C] ; Server.00417D66
00417C5E 8D85 A8FDFFFF lea eax,dword ptr ss:[ebp-0x258]
00417C64 68 38574000 push Server.00405738 ; ASCII "\Server.url"
00417C69 50 push eax
00417C6A 8D85 A8FDFFFF lea eax,dword ptr ss:[ebp-0x258]
00417C70 68 FC534000 push Server.004053FC ; ASCII "%s%s"
00417C75 50 push eax
00417C76 FFD7 call edi ;实际上跟入后是wsprintfA
00417C78 83C4 10 add esp,0x10
00417C7B 8D85 A8FDFFFF lea eax,dword ptr ss:[ebp-0x258]
00417C81 50 push eax
00417C82 FF15 4C124000 call dword ptr ds:[<&SHLWAPI.PathFileExistsA>] ; shlwapi.PathFileExistsA
00417C88 85C0 test eax,eax
00417C8A 75 7F jnz XServer.00417D0B
00417C8C 53 push ebx
00417C8D 8D85 D4FEFFFF lea eax,dword ptr ss:[ebp-0x12C]
00417C93 6A 16 push 0x16
00417C95 50 push eax
00417C96 53 push ebx
00417C97 FFD6 call esi   ;实际上跟入后是SHGetSpecialFolderPathA
00417C99 90 nop
00417C9A 90 nop
00417C9B 90 nop
00417C9C 90 nop
00417C9D 90 nop
00417C9E 90 nop
00417C9F 8D85 D4FEFFFF lea eax,dword ptr ss:[ebp-0x12C]
00417CA5 68 38574000 push Server.00405738 ; ASCII "\Server.url"
00417CAA 50 push eax
00417CAB 8D85 D4FEFFFF lea eax,dword ptr ss:[ebp-0x12C]
00417CB1 68 FC534000 push Server.004053FC ; ASCII "%s%s"
00417CB6 50 push eax
00417CB7 FFD7 call edi  ;实际上跟入后是wsprintfA
00417CB9 83C4 10 add esp,0x10
00417CBC 8D85 7CFCFFFF lea eax,dword ptr ss:[ebp-0x384]
00417CC2 68 2C010000 push 0x12C
00417CC7 50 push eax
00417CC8 53 push ebx
00417CC9 FF15 B8104000 call dword ptr ds:[<&KERNEL32.GetModuleFileNam>; kernel32.GetModuleFileNameA
00417CCF 8D85 A8FDFFFF lea eax,dword ptr ss:[ebp-0x258]
00417CD5 6A 04 push 0x4
00417CD7 50 push eax
00417CD8 8D85 D4FEFFFF lea eax,dword ptr ss:[ebp-0x12C]
00417CDE 50 push eax
00417CDF FF15 28114000 call dword ptr ds:[<&KERNEL32.MoveFileExA>] ; kernel32.MoveFileExA
00417CE5 90 nop
00417CE6 90 nop
00417CE7 90 nop
00417CE8 90 nop
00417CE9 90 nop
00417CEA 90 nop
00417CEB 68 E8030000 push 0x3E8
00417CF0 FF15 80114000 call dword ptr ds:[<&KERNEL32.Sleep>] ; kernel32.Sleep
00417CF6 8D85 D4FEFFFF lea eax,dword ptr ss:[ebp-0x12C]
00417CFC 50 push eax
00417CFD 8D85 7CFCFFFF lea eax,dword ptr ss:[ebp-0x384]
00417D03 50 push eax
00417D04 E8 E9FDFFFF call Server.00417AF2
00417D09 59 pop ecx
00417D0A 59 pop ecx
00417D0B 5F pop edi
00417D0C 5E pop esi
00417D0D 5B pop ebx
00417D0E C9 leave
00417D0F C3 retn
看到那几个调用的函数可以看出这里就是写启动项的地方了,对这一段仔细分析,开始一个SHGetSpecialFolderPathA函数获取用户主目录下的「开始」菜单\程序(即C:\Documents and Settings\Administrator\「开始」菜单\程序)然后然后把目录路径和Server.url连接在一起成为C:\Documents and Settings\Administrator\「开始」菜单\程序\Server.url。再次调用SHGetSpecialFolderPathA获取「开始」菜单\程序\启动 这里正是系统的启动目录,然后把目录路径和Server.url连接在一起成了C:\Documents and Settings\Administrator\「开始」菜单\程序\Server.url 然后调用MoveFileE函数将C:\Documents and Settings\Administrator\「开始」菜单\程序\Server.url移动到C:\Documents and Settings\Administrator\「开始」菜单\程序\Server.url。然后最后一个Call Server.00417AF2为写文件,在Server.url写入[InternetShortcut]URL=file:/// C:\Documents and Settings\Administrator\桌面\Server.exe,接下来就是上线部分由于不是重点直接无视

Thirdly:结论

简述:利用URL可以直接打开本机磁盘文件的漏洞来运行EXE以逃过360的拦截

评价:方法很好可惜长久性不行,而且马的保护太差,连个壳都没有,随便一分析就出来了。


注:此方法在本文章发表前经写手测试已失效


0 0
原创粉丝点击