首页
社区
课程
招聘
[原创]趋势科技 tmactmon.sys DOS漏洞分析(0day)
发表于: 2012-11-8 20:26 6764

[原创]趋势科技 tmactmon.sys DOS漏洞分析(0day)

2012-11-8 20:26
6764

当tmactmon.sys接收到ioctl_code=0x9100444f的IRP时,会调用Dispatch函数进行进行处理,如下所示。
.text:00011116 ; int __stdcall BugDispatch(int, PIRP Irp)
.text:00011116 BugDispatch     proc near               ; DATA XREF: sub_11C4C+16D o
.text:00011116
.text:00011116 inbuffer        = dword ptr -1Ch
.text:00011116 UserBuffer      = dword ptr -18h
.text:00011116 IoStatus        = dword ptr -10h
.text:00011116 outbufferLength = dword ptr -0Ch
.text:00011116 inbufferLength  = dword ptr -8
.text:00011116 var_4           = dword ptr -4
.text:00011116 Irp             = dword ptr  0Ch
.text:00011116
.text:00011116                 mov     edi, edi
.text:00011118                 push    ebp
.text:00011119                 mov     ebp, esp
.text:0001111B                 sub     esp, 1Ch
在该处理函数的最后,会将inLength、outLength、inbuffer、UserBuffer等信息保存,并调用sub_12BE2函数。可以看到传入的参数即为栈中存放inbuffer的地址。
.text:0001115E loc_1115E:                ; CODE XREF: BugDispatch+2A j
.text:0001115E                 mov     edx, [eax+10h]
.text:00011161                 mov     [ebp+inbuffer], edx
.text:00011164                 mov     edx, [esi+3Ch]
.text:00011167                 mov     [ebp+UserBuffer], edx
.text:0001116A                 mov     edx, [eax+8]
.text:0001116D                 mov     [ebp+outbufferLength], edx
.text:00011170                 mov     edx, [eax+4]
.text:00011173                 mov     [ebp+inbufferLength], edx
.text:00011176                 mov     [ebp+IoStatus], ecx
.text:00011179                 mov     eax, [eax+0Ch]
.text:0001117C                 mov     [ebp+var_4], eax
.text:0001117F                 lea     eax, [ebp+inbuffer]
.text:00011182                 push    eax
.text:00011183                 call    sub_12BE2
sub_12BE2函数完成的主要功能是调用sub_12AE8函数对ring3传来的缓冲区进行检查。对sub_12AE8函数进行反编译后的代码如下。可以看到,该函数使用ProbeForRead 和ProbeForWrite对输入和输出缓冲区进行了严格的检查,同时还检查了发送ioctl是否是趋势本身的进程。
signed int __thiscall sub_12AE8(int this, int a2)
{
  if ( &inbuffer && (inLength || !inbuffer) && (outLength || !outBuffer ))
  {
    if ( ExGetPreviousMode() == 1 )
    {
      ProbeForRead(*(const void **)v3, *(_DWORD *)(v3 + 16), 1u);
      ProbeForWrite(*(PVOID *)(v3 + 4), *(_DWORD *)(v3 + 20), 1u);
    }
    //省略无关代码
LABEL_13:
    if ( !v7 )
    {
      v5 = *(_DWORD *)(v3 + 8);
      if ( v5 && *(_BYTE *)(v5 + 24) )
        v2 = *(_DWORD *)(v5 + 8) != (_DWORD)PsGetCurrentProcessId() ? 0xC00000BB : 0;      
     else
        v2 = -1073741637;
    }
    result = v2;
  }
  else
  {
    result = -1073741811;
  }
  return result;
}
当检查通过后,就会调用sub_1291C,sub_1291C将会继续调用sub_19814函数,sub_19814的执行过程如下。注意观察红色部分的汇编代码,由于ebp+arg_4的内容为inbuffer中的dword[1],可以任意指定,不妨指定为0x12210005,所以将会调用sub_19554执行。
.text:00019814 ; int __stdcall sub_19814(int, int, PVOID Object)
.text:00019814 sub_19814       proc near       ; CODE XREF: v6+29 p
.text:00019814 var_20          = dword ptr -20h
.text:00019814 ms_exc          = CPPEH_RECORD ptr -18h
.text:00019814 arg_0           = dword ptr  8
.text:00019814 arg_4           = dword ptr  0Ch
.text:00019814 Object          = dword ptr  10h
.text:00019814
.text:00019814                 push    10h
.text:00019816                 push    offset unk_1E1A8
.text:0001981B                 call    __SEH_prolog4
.text:00019820                 mov     esi, ecx
.text:00019822                 lea     eax, [esi+14h]
.text:00019825                 mov     [ebp+var_20], eax
.text:00019828                 xor     ecx, ecx
.text:0001982A                 inc     ecx
.text:0001982B                 lock xadd [eax], ecx
.text:0001982F                 cmp     [ebp+arg_4], 1221A007h
.text:00019836                 jnz     short loc_19885

.text:00019885 loc_19885:                  ; CODE XREF: sub_19814+22 j
.text:00019885                 mov     ebx, [ebp+Object]
.text:00019888                 push    ebx             ; Object
.text:00019889                 push    [ebp+arg_4]     ; int
.text:0001988C                 mov     ecx, esi
.text:0001988E                 call    sub_19554
sub_19554的执行过程如下所示,标红几处为重要的跳转。由于ecx=0x12210005,最终会执行到.text:00019591。ebp+Object的内容为inbuffer中的dword[3],可以被任意指定,不妨指定为0xffff0000,最终在push  dword ptr [esi]执行出错,内存0xffff0000不可读。
.text:00019554 ; int __stdcall sub_19554(int, PVOID Object)
.text:00019554 sub_19554    proc near      ; CODE XREF: sub_19814+7A p
.text:00019554 arg_0           = dword ptr  8
.text:00019554 Object          = dword ptr  0Ch
.text:00019554
.text:00019554                 mov     edi, edi
.text:00019556                 push    ebp
.text:00019557                 mov     ebp, esp
.text:00019559                 mov     ecx, [ebp+arg_0]  ;ecx=0x12210005
.text:0001955C                 push    ebx
.text:0001955D                 push    esi
.text:0001955E                 push    edi
.text:0001955F                 mov     eax, 12210006h
.text:00019564                 cmp     ecx, eax
.text:00019566                 mov     edi, 0E0000001h
.text:0001956B                 mov     ebx, edi
.text:0001956D                ja      loc_19670
.text:00019573                 jz      loc_19645
.
text:00019579                 sub     ecx, 12210001h
.text:0001957F                 jz      loc_1961B
.text:00019585                 dec     ecx
.text:00019586                jz      short loc_195E0
.text:00019588                 sub     ecx, 3
.text:0001958B                jnz     loc_196AC
.text:00019591                 mov     esi, [ebp+Object]
.text:00019594                 test    esi, esi
.text:00019596                 jz      loc_196B1
.text:0001959C                 and     [ebp+Object], ecx
.text:0001959F                 lea     eax, [ebp+Object]
.text:000195A2                 push    eax
.text:000195A3                 push    dword ptr [esi]
.text:000195A5                 call    sub_194E6
从整个漏洞的分析过程可以看到,触发该漏洞需要注入到趋势自身的ring3进程,并向tmactmon.sys发送恶意构造的IRP请求,其中ioctl_code=0x9100444f, inLength=0x10, outLength=0x10, inbuffer为0,0,0,0,5,0,0x21,0x12,0,0,0,0,0,0,0xff,0xff。以上就是整个分析过程。
Happy Hacking~
~~~~~~~~~~~~~~~~~~~~~~免责声明~~~~~~~~~~~~~~~~~~~~~
本文所涉及内容仅用于软件安全技术研究、学习,严禁用于不良动机。
任何个人、团体、组织不得将其用于非法目的,否则后果自负。
本人不承担由这些代码造成的用户计算机崩溃,数据丢失等责任及连带责任。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 6
支持
分享
最新回复 (13)
雪    币: 106
活跃值: (40)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
有检查调用者吗?如果有检查调用者,能突破吗?
2012-11-8 20:53
0
雪    币: 253
活跃值: (46)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
3
帖子中已经说了,是检查了调用者的。能不能突破没有看过,仅供学习
2012-11-8 21:00
0
雪    币: 219
活跃值: (783)
能力值: (RANK:290 )
在线值:
发帖
回帖
粉丝
4
mark mark
2012-11-8 21:08
0
雪    币: 822
活跃值: (380)
能力值: ( LV12,RANK:310 )
在线值:
发帖
回帖
粉丝
5
2012-11-8 21:32
0
雪    币: 433
活跃值: (1870)
能力值: ( LV17,RANK:1820 )
在线值:
发帖
回帖
粉丝
6
通过复制句柄也许可以绕过
2012-11-8 21:40
0
雪    币: 692
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
感觉对调用者的检查很难突破吧。。  期待有大牛提供方法来学习一下
2012-11-8 21:58
0
雪    币: 239
活跃值: (133)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
8
复制句柄应该都处理过了吧
2012-11-8 22:19
0
雪    币: 239
活跃值: (133)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
9
不如多研究下Selfprotection
2012-11-8 22:45
0
雪    币: 106
活跃值: (40)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
嗯.目前的一些调用者检查没法突破,不过也有些比较弱的存在.
2012-11-9 10:26
0
雪    币: 544
活跃值: (264)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
11
调用者检查都是悲剧。
2012-11-11 00:04
0
雪    币: 310
活跃值: (159)
能力值: ( LV12,RANK:200 )
在线值:
发帖
回帖
粉丝
12
利用句柄复制进行文件占坑实现阻止?
2012-11-12 10:29
0
雪    币: 58
活跃值: (25)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
13
果断留名占位,期待学习精彩后文.
2012-11-13 10:18
0
雪    币: 75
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
请问你那有什么好的英文书籍推荐吗?
中文的书几乎都看过了,谢谢
2013-5-28 11:07
0
游客
登录 | 注册 方可回帖
返回
//