简单的DOWNLOADER 分析
木马:Downloader-BIX样本见附件
关键点:
1:使用Loadlibrary 和 GetProcessAddress来获取API,运行DOWN回来的东东时是
直接以CALL的形式运行
2:加入大量的垃圾指令看的眼酸
3:通过解密附加数据来获得 URL
4:以写堆栈的形式 而不是PUSH 的形式 压入函数参数
==================================================================
简要分析(以IDA 和OD为主):
004026B1 >/$55 push ebp
004026B2|.89E5 mov ebp, esp
004026B4|.83EC 28 sub esp, 28
004026B7|.81EC 3C080000 sub esp, 83C
004026BD|.89E3 mov ebx, esp
004026BF|.8925 AD264000 mov dword ptr , esp
004026C5|.A1 44504000 mov eax, dword ptr [<&KERNEL32.LoadLi>
004026CA|.8983 0D040000 mov dword ptr , eax
004026D0|.A1 48504000 mov eax, dword ptr [<&KERNEL32.GetPro>
004026D5|.8983 A3050000 mov dword ptr , eax
004026DB|.E8 54050000 call 00402C34 ;修复IAT
{
seg000:00402C34 push ebp
seg000:00402C35 mov ebp, esp
seg000:00402C37 sub esp, 50h
seg000:00402C3A mov ebx, stack_base
seg000:00402C40 mov byte ptr , 2Eh ;这里通过单字节的传送得到字符串
seg000:00402C47 or dh, 9Ah ;基本上使用DH DL CH之类的指令都是属于垃圾指令无视好了
seg000:00402C4A mov byte ptr , 6Ch
seg000:00402C51 xor dl, 82h
seg000:00402C54 mov ch, 59h
seg000:00402C56 mov byte ptr , 72h
seg000:00402C5D mov byte ptr , 6Eh
seg000:00402C64 mov byte ptr , 32h
seg000:00402C6B mov byte ptr , 65h
seg000:00402C72 or ch, 0C1h
seg000:00402C75 mov byte ptr , 0
seg000:00402C7C mov byte ptr , 65h
seg000:00402C83 mov dh, 53h
seg000:00402C85 mov byte ptr , 64h
seg000:00402C8C xor cl, 24h
seg000:00402C8F add ch, 5
seg000:00402C92 mov byte ptr , 6Ch
seg000:00402C99 mov byte ptr , 33h
seg000:00402CA0 mov byte ptr , 6Bh
seg000:00402CA7 and ch, 34h
seg000:00402CAA mov byte ptr , 6Ch
seg000:00402CB1 mov dl, 0CAh
seg000:00402CB3 sub esp, 4
seg000:00402CB6 lea edi,
seg000:00402CBC mov , edi ; 字符串Kernel32.dll
seg000:00402CBF call dword ptr ;LoadLibrary
整个子函数都是用来 获得API地址的,以下不详述
......................................
}
004026E0|.8983 71070000 mov dword ptr , eax
004026E6|.C783 29080000>mov dword ptr , 100000
004026F0|.C783 21040000>mov dword ptr , 300000
004026FA|.83EC 10 sub esp, 10
004026FD|.C70424 000000>mov dword ptr , 6000000
=====================================================================
00402741|.8B83 6E010000 mov eax, dword ptr
00402747|.8983 7E010000 mov dword ptr , eax
0040274D|.83EC 04 sub esp, 4
00402750|.80F4 46 xor ah, 46 ; |
00402753|.8D83 09030000 lea eax, dword ptr ; |
00402759|.890424 mov dword ptr , eax ; |
0040275C|.80E6 1B and dh, 1B ; |
0040275F|.E8 7EF7FFFF call 00401EE2 ; \3727D1~1.00401EE2关键CALL获得下载URL
{
代码有点长 只列关键的
=================================================================
00401FC5|> /80EC D6 /sub ah, 0D6
00401FC8|. |8BB3 4A040000 |mov esi, dword ptr
00401FCE|. |803E 00 |cmp byte ptr , 0
00401FD1|. |75 02 |jnz short 00401FD5
00401FD3|. |EB 3C |jmp short 00402011
00401FD5|> |8BB3 4A040000 |mov esi, dword ptr
00401FDB|. |803E 22 |cmp byte ptr , 22
00401FDE|. |75 08 |jnz short 00401FE8
00401FE0|. |80E2 0F |and dl, 0F
00401FE3|. |80E2 3D |and dl, 3D
00401FE6|. |EB 29 |jmp short 00402011
00401FE8|> |8BB3 10070000 |mov esi, dword ptr
00401FEE|. |8BBB 4A040000 |mov edi, dword ptr
00401FF4|. |8A07 |mov al, byte ptr
00401FF6|. |8806 |mov byte ptr , al
00401FF8|. |80F5 8E |xor ch, 8E
00401FFB|. |8383 10070000>|add dword ptr , 1
00402002|. |8383 4A040000>|add dword ptr , 1
00402009|. |80C9 FF |or cl, 0FF
0040200C|. |80F5 04 |xor ch, 4
0040200F|.^\EB B4 \jmp short 00401FC5
这里是把COMMANDLINE得到的参数 去掉 "和"算是除了GetModuleFileName外 另一个得到自身文件名的方法
================================================================================
004020CB|.80F2 60 xor dl, 60
004020CE|.80EC BE sub ah, 0BE
004020D1|.C74424 14 000>mov dword ptr , 0
004020D9|.80E2 57 and dl, 57
004020DC|.80C2 78 add dl, 78
004020DF|.C74424 18 000>mov dword ptr , 0 ;通过写堆栈来实现参数的PUSH
下面会多次遇到,不详述
004020E7|.80ED 08 sub ch, 8
004020EA|.80ED E7 sub ch, 0E7
004020ED|.FF93 7D070000 call dword ptr ;kernel32.CreateFileA
===============================================================================================
00402290|> /8B83 76010000 /mov eax, dword ptr
00402296|. |3983 4A040000 |cmp dword ptr , eax
0040229C|. |75 0B |jnz short 004022A9
0040229E|. |80ED 1E |sub ch, 1E
004022A1|. |80C6 59 |add dh, 59
004022A4|. |E9 8F000000 |jmp 00402338
004022A9|> |8BB3 4A040000 |mov esi, dword ptr
004022AF|. |813E 41414141 |cmp dword ptr , 41414141 ;通过AAAA标识来遍历文件寻找加密后的URL 为下面解密做准备
004022B5|. |74 02 |je short 004022B9
004022B7|. |EB 5F |jmp short 00402318
004022B9|> |8B83 4A040000 |mov eax, dword ptr
004022BF|. |8983 7E060000 |mov dword ptr , eax
004022C5|. |80E1 2E |and cl, 2E
004022C8|. |8383 7E060000>|add dword ptr , 4
004022CF|. |8B83 7E060000 |mov eax, dword ptr
004022D5|. |8983 10070000 |mov dword ptr , eax
004022DB|. |80F1 AB |xor cl, 0AB
============================================================================================
00402404|.80C1 AE add cl, 0AE ; |
00402407|.8B83 25040000 mov eax, dword ptr ; |
0040240D|.894424 04 mov dword ptr , eax ; |
00402411|.B5 0A mov ch, 0A ; |
00402413|.80EE A4 sub dh, 0A4 ; |
00402416|.E8 24060000 call 00402A3F ; \3727D1~1.00402A3F关键CALL 解密开始 算法很简单 有兴趣的自己研究
============================================================================================
}
00402764|.8983 82060000 mov dword ptr , eax
0040276A|.83BB 82060000>cmp dword ptr , 0
00402771|.74 05 je short 00402778
00402773|.E9 72010000 jmp 004028EA
00402778|>C683 51010000>mov byte ptr , 31
0040277F|.80E1 19 and cl, 19
==============================================================================
004028EA|> \83EC 08 sub esp, 8
004028ED|.80C2 DD add dl, 0DD ; |
004028F0|.8D83 09030000 lea eax, dword ptr ; |
004028F6|.890424 mov dword ptr , eax ; |
004028F9|.B1 C9 mov cl, 0C9 ; |
004028FB|.80E5 F5 and ch, 0F5 ; |
004028FE|.8DBB 4E040000 lea edi, dword ptr ; |
00402904|.897C24 04 mov dword ptr , edi ; |
00402908|.80C1 F8 add cl, 0F8 ; |
0040290B|.80C9 D4 or cl, 0D4 ; |
0040290E|.E8 EDE6FFFF call 00401000 ; \3727D1~1.00401000 下载服务器上的文件
调用了相关API 需要注意的就是 垃圾指令太多,第一次连接上服务器服务器会以字符串形式返回下载的文件大小,由于URL已经失效
所以返回了页面的大小 "169" 换算成16进制就是0A9h
===============================================================================================================
seg000:00402A00 add cl, 0A3h
seg000:00402A03 mov eax,
seg000:00402A06 mov , eax
seg000:00402A0A mov eax,
seg000:00402A0D mov , eax
seg000:00402A11 or cl, 9Fh
seg000:00402A14 sub cl, 8Eh
seg000:00402A17 call sub_4024AF ;这个CALL就是运行DOWN回来文件的关键CALL
{
..................................
seg000:00402676 xor ch, 0Eh
seg000:00402679 and ch, 0Ah
seg000:0040267C mov eax,
seg000:0040267F mov , eax
seg000:00402683 or dh, 0D9h
seg000:00402686 mov dh, 56h
seg000:00402688 mov eax,
seg000:0040268B mov , eax
seg000:0040268F mov eax,
seg000:00402692 mov , eax
seg000:00402696 add cl, 0D2h
seg000:00402699 call dword ptr ;ebx+456h 所存放的就是down回来的PE文件的入口点 直接就运行了文件 本来还
以为会通过CreateProcess之类的运行这次长见识了
seg000:0040269F add esp, 10h
seg000:004026A2 popa
seg000:004026A3 mov , eax
}
篇幅有限 这里只是简要分析,详细的分析过程太长了就不贴了 由于木马下载的服务器已经失效了直接在本机运行调试就可以了至少我没分析出其他有害的地方
当然最保险的还是在虚拟机里调试万一 服务器在某个时间开通。。。。。。。。。
[ 本帖最后由 xhn1002 于 2008-8-13 17:03 编辑 ] 辛苦辛苦,谢谢指导 强
看看学习一下/:good 努力学习中。。。。。。 这真是学习的好教材,事实举例清楚明了! 认真学习了! 现在还是云里雾里的,希望顺着高手的脚步前进
页:
[1]