灯火互联
管理员
管理员
  • 注册日期2011-07-27
  • 发帖数41778
  • QQ
  • 火币41290枚
  • 粉丝1086
  • 关注100
  • 终身成就奖
  • 最爱沙发
  • 忠实会员
  • 灌水天才奖
  • 贴图大师奖
  • 原创先锋奖
  • 特殊贡献奖
  • 宣传大使奖
  • 优秀斑竹奖
  • 社区明星
阅读:3355回复:0

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

楼主#
更多 发布于:2012-11-20 16:27
当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+2Aj
.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+22j
.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+7Ap
.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~
~~~~~~~~~~~~~~~~~~~~~~免责声明~~~~~~~~~~~~~~~~~~~~~
本文所涉及内容仅用于软件安全技术研究、学习,严禁用于不良动机。
任何个人、团体、组织不得将其用于非法目的,否则后果自负。
本人不承担由这些代码造成的用户计算机崩溃,数据丢失等责任及连带责任。

喜欢0 评分0
游客

返回顶部