首页
社区
课程
招聘
[原创]基于启发式技术检测复杂病毒Anunnaki
发表于: 2010-4-7 22:18 33934

[原创]基于启发式技术检测复杂病毒Anunnaki

2010-4-7 22:18
33934
收藏
免费 7
支持
分享
最新回复 (43)
雪    币: 296
活跃值: (89)
能力值: ( LV15,RANK:340 )
在线值:
发帖
回帖
粉丝
26
感谢分享!

检测仿真环境那段,感觉它直接调用 gethostbyname 检查LastError是否为10093不稳妥。确实正常情况中没有调用WSAStartup前gethostbyname,会返回10093,不过VM虚拟个系统来跑这个代码,也能得到这个值。或者sandbox关注了网络方面的实现,也有可能过不了。
不过以前真没想过 gethostbyname 还能用来检测仿真环境。以前看到bot中清空DNS缓存然后查询服务器的IP,以为只是为了防止固定IP被封。现在想来对付没有网络的启发扫描环境,可以查询一个自己注册的域名,比较返回的IP是否正确... (当然,没网络的机器也就无法发作了

总之先把文章收下了。写得很详细,回头结合源码对照着看看。


Win32.Anunnaki by Dark Prophet/EOF
http://vx.eof-project.net/viewtopic.php?pid=2065
2010-4-11 19:38
0
雪    币: 95
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
27
好文章,谢谢楼主分享。
2010-4-11 21:50
0
雪    币: 101
活跃值: (88)
能力值: ( LV2,RANK:140 )
在线值:
发帖
回帖
粉丝
28
几个问题,多谢LZ!!

 
0040171C                   |.  64:A1 34000000   mov eax,dword ptr fs:[34] ; 从teb中读取GetLastError数值给eax 
  00401722                   |.  69C0 01000100    imul eax,eax,10001
  00401728                   |.  35 58862413      xor eax,13248658
  0040172D                   |.  3D 35A14934      cmp eax,3449A135          ; 校验返回值
  00401732                   |.  74 24            je short Anunnaki.00401758
  00401734                   |.  6A 00            push 0
  00401736                   |.  68 65737300      push 737365
  0040173B                   |.  68 50726F63      push 636F7250
  00401740                   |.  68 45786974      push 74697845
  00401745                   |.  54               push esp                  ; esp->ExitProcess
  00401746                   |.  E8 50FEFFFF      call Anunnaki.0040159B
  0040174B                   |.  50               push eax
  0040174C                   |.  E8 37FDFFFF      call <Anunnaki.my_getprocaddress>
  00401751                   |.  83C4 0C          add esp,0C
  00401754                   |.  6A 00            push 0
  00401756                   |.  FFD0             call eax                  ;
  00401758                   |>  61               popad
  00401759                   \.  C3               retn


正常都会到0x00401756直接退出线程?错了反倒正常返回?

 push_au  macro  au, fstr
  local  pvar, cnt, es, cn, idx1, idx2, len, ln
  local  hex, dcm, hid

  es = 0
  len = 0
  irpc  c1, <fstr>
    len = len+1
    if es eq 1
      if (("&c1" ge "0") and ("&c1" le "9")) or ("&c1" eq "x") or  ("&c1" eq "X")
        len = len-3


啥语言?看着像脚本。

1 -- 解析代码段,寻找跳向最后一个节的call,记录建立栈帧的地址addr_s
1 -- 执行call后寄存器中出现小于addr_s的数值


这个addr_s啥含义?
2010-4-12 19:21
0
雪    币: 296
活跃值: (89)
能力值: ( LV15,RANK:340 )
在线值:
发帖
回帖
粉丝
29
[QUOTE=nkspark;790004]几个问题,多谢LZ!!

  00401716                   |.  54               push esp               ;esp->"google.com"
  00401717                   |.  FFD7             call edi               ;call - > gethostbyname("google.com")
  00401719                   |.  83C4 10          add esp,10
  0040171C                   |.  64:A1 34000000   mov eax,dword ptr fs:[34] ; 从teb中读取GetLastError数值给eax
  00401722                   |.  69C0 01000100    imul eax,eax,10001
  00401728                   |.  35 58862413      xor eax,13248658
  0040172D                   |.  3D 35A14934      cmp eax,3449A135          ; 校验返回值
  00401732                   |.  74 24            je short Anunnaki.00401758
  00401734                   |.  6A 00            push 0
  00401736                   |.  68 65737300      push 737365
  0040173B                   |.  68 50726F63      push 636F7250
  00401740                   |.  68 45786974      push 74697845
  00401745                   |.  54               push esp                  ; esp->ExitProcess
  00401746                   |.  E8 50FEFFFF      call Anunnaki.0040159B
  0040174B                   |.  50               push eax
  0040174C                   |.  E8 37FDFFFF      call <Anunnaki.my_getprocaddress>
  00401751                   |.  83C4 0C          add esp,0C
  00401754                   |.  6A 00            push 0
  00401756                   |.  FFD0             call eax                  ;
  00401758                   |>  61               popad
  00401759                   \.  C3               retn
[/QUOTE]

不要被GetLastError给迷惑了。这一段是通过没有 WSAStartup 前调用 gethostbyname 会返回10093错误来检测的:
  0040171C                   |.  64:A1 34000000   mov eax,dword ptr fs:[34] ; 从teb中读取GetLastError数值给eax 
  00401722                   |.  69C0 01000100    imul eax,eax,10001
  00401728                   |.  35 58862413      xor eax,13248658
  0040172D                   |.  3D 35A14934      cmp eax,3449A135          ; 校验返回值

10093 这样乘出来正好是 0x3449A135。实际机器中直接gethostbyname会因为没有初始化而返回这个错误值,而虚拟环境中可能因为是个stub而GetLastError为0。
2010-4-12 19:39
0
雪    币: 397
活跃值: (352)
能力值: ( LV9,RANK:410 )
在线值:
发帖
回帖
粉丝
30
ls 的木桩兄弟已经说第一个了,我说后面的吧。

push_au  不是脚本语言,是用masm定义的字符串压栈的宏操作。
里面用了一些不太常用的伪指令fstr等。
他有两个版本,一个asc ,一个unicode 版。
push_sz         macro        fstr  
        push_au        0, <fstr>
endm

push_uz        macro        fstr
        push_au        1, <fstr>
endm       

主要是为了不再堆栈中产生明文的字符串, anti 动态仿真。

addr_s  是从检测的方面记录的值,
比如一个被感染的文件的入口,

00401000    push 0
00401002    call kifilter.00401008
00401007    int3
00401008    call kifilter.00404644  -->被感染,跳向最后一个节

00404644     push ebp             记录此处建立占帧地址addr_s,也就是addr_s == 0x00404644              
00404645     mov ebp,esp   
00404647     push 6F25393D
0040464C     pop edi
0040464D     call kifilter.00404652
00404652     pop eax
00404653     add eax,FFBFB9AE     ---->运算解密的首地址eax== 0x404643,一定小于addr_s
00404659     add eax,kifilter.00404643
0040465F      push 25F0          此处就是产生解密循环计数
00404664     pop edx           
00404665     xor dword ptr ds:[eax],edi
00404667     sub edi,B382A492
0040466D     dec eax
0040466E     dec edx
0040466F      test edx,edx
00404671      jnz short kifilter.00404665

被它感染后的文件都具有该特点,所以我们记录addr_s ,当发现解密首地址值eax小于addr_s时,可作为检测依据进行标记。
2010-4-12 21:42
0
雪    币: 101
活跃值: (88)
能力值: ( LV2,RANK:140 )
在线值:
发帖
回帖
粉丝
31
[QUOTE=木桩;790008]不要被GetLastError给迷惑了。这一段是通过没有 WSAStartup 前调用 gethostbyname 会返回10093错误来检测的:

  0040171C                   |.  64:A1 34000000   mov eax,dword ptr fs:[3...[/QUOTE]

多谢了.

又看了一下, 前面几个je Anunnaki.00401758应该是如果出错,就放弃Anti。
2010-4-13 19:27
0
雪    币: 101
活跃值: (88)
能力值: ( LV2,RANK:140 )
在线值:
发帖
回帖
粉丝
32
收到。理解错了,以为是你用来做启发式检测的。
2010-4-13 19:41
0
雪    币: 109
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
33
有点长.慢慢看吧
2010-4-13 20:19
0
雪    币: 306
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
34
非常不错 LZ很用心
2010-4-14 20:52
0
雪    币: 202
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
35
详细!值得赞!
2010-4-19 11:05
0
雪    币: 611
活跃值: (251)
能力值: ( LV12,RANK:390 )
在线值:
发帖
回帖
粉丝
36
菜鸟提问!!!!
为啥patch ExitProcess()的调用时 在整个代码里搜索 ff 15/ff 25?不是应该搜索0xE8么?

希望大牛讲解一下,我初学,这个地方看了好长时间没看懂。。。。
2010-10-28 23:33
0
雪    币: 611
活跃值: (251)
能力值: ( LV12,RANK:390 )
在线值:
发帖
回帖
粉丝
37
我又问愚蠢问题了。。。ff25是绝对Jmp的机器码 ff15是绝对call的机器码。。。
2010-10-29 00:14
0
雪    币: 300
活跃值: (179)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
38
如果我来免杀你的检测点,就这么干:
1、重定位
8BFF                  mov     edi, edi                        
55                    push    ebp
8BEC                  mov     ebp, esp
/*之间插一大堆指令,该干嘛干嘛*/
8B45 04               mov     eax, dword ptr [ebp+4]
8AC8                  mov     cl, al
66:8BC8               mov     cx, ax
66:33C0               xor     ax, ax
66:83E9 05            sub     cx, xxxxxx  /*忘记计算size了*/
5D                    pop     ebp
C3                    retn
出门之后再将eax和cx或起来就OK。
2 跨节区跳转
这个没有啥子很好的方法,条件允许就多次ret
3、如果你只对 push esp 后堆栈才进行检查的话,那
mov eax,esp
push eax
检查不呢?
4、EPO这个的选择看个人爱好!

=====================
原来LZ是做BD的!
2010-10-29 09:57
0
雪    币: 611
活跃值: (251)
能力值: ( LV12,RANK:390 )
在线值:
发帖
回帖
粉丝
39
额,除了EPO还能怎么调病毒代码?求解。。。。
2010-10-29 20:16
0
雪    币: 160
活跃值: (56)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
40
菜鸟中,继续学习!
2010-10-29 21:14
0
雪    币: 2323
活跃值: (4113)
能力值: ( LV12,RANK:530 )
在线值:
发帖
回帖
粉丝
41
文章很长,说实话,没看完,不过几个结构图讲的很好,清楚明了~~支持一下!
2010-12-17 15:05
0
雪    币: 599
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
42
楼主好人,11楼好人。
2010-12-17 15:22
0
雪    币: 176
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
43
好文!感谢楼主分享
2011-11-27 12:19
0
雪    币: 182
活跃值: (226)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
44
NB,标记一下,有时间读。
2011-11-28 10:47
0
游客
登录 | 注册 方可回帖
返回
//