zzage 发表于 2010-9-23 01:51

金山卫士(影响版本<=1.5.0.1147)ksafebc.sys内核驱动后门利用漏洞

文章标题:金山卫士ksafebc.sys内核驱动后门利用漏洞
文章作者:ZzAge
联系邮箱:zzage@163.com

吾爱破解:http://www.52pojie.net
:http://www.80dfj.org
暗组安全技术论坛:http://forum.darkst.com

影响版本:金山卫士<=1.5.0.1147
文件名:Ksafebc.sys <=1.4.0.1124
MD5:61fe31b0a815197db8508580a0ac8dce
文件签名:Kingsoft Security Co.,Ltd
(金山官方已更新此漏洞)

漏洞原因:Ksafebc.sys这个是BOOT级驱动,在开机启动加载驱动后,此驱动会检测是否存在“KSafeFileBootClean.config”,“KSafeFileBootOccupy.config”,“KSafeFileBootReplace.config”这三个配置文件,如果存在就会读取配置文件里的数据,并实现相关功能!但因为检测和加密配置文件的方式比较简单,也没有其他校验的方法,所以只要伪造一个配置文件,就可以简单的实现其文件操作功能!因为驱动是Boot级别,它启动加载的时机比较早,所以基本上可以利用它达到对任意文件的删除,替换,占坑的目的!

KSafeFileBootClean.config   文件删除功能配置文件
KSafeFileBootOccupy.config文件占坑功能配置文件
KSafeFileBootReplace.config文件替换功能配置文件

例子:KSafeFileBootClean.config

.text:00011B60               push    ebp
.text:00011B61               mov   ebp, esp
.text:00011B63               push    0FFFFFFFFh
.text:00011B65               push    offset dword_12840
.text:00011B6A               push    offset _except_handler3
.text:00011B6F               mov   eax, large fs:0
.text:00011B75               push    eax
.text:00011B76               mov   large fs:0, esp
.text:00011B7D               add   esp, 0FFFFFFD8h
.text:00011B80               push    ebx
.text:00011B81               push    esi
.text:00011B82               push    edi
.text:00011B83               mov   , esp
.text:00011B86               mov   , 0C0000001h
.text:00011B8D               mov   , 0
.text:00011B94               mov   , 0
.text:00011B9B               mov   , 0
.text:00011BA2               mov   , 0
.text:00011BA6               mov   , 0
.text:00011BAD               mov   , 0
.text:00011BB4               mov   , 0
.text:00011BB8               mov   eax,
//打开配置文件,并返回文件句柄hFile
.text:00011BBB               push    eax             ; SourceString
.text:00011BBC               call    sub_12620
.text:00011BC1               mov   , al
.text:00011BC4               movzx   ecx,
.text:00011BC8               test    ecx, ecx
//判断hFile是否为零
.text:00011BCA               jnz   short loc_11BD8
.text:00011BCC               mov   , 0
.text:00011BD3               jmp   loc_11CA7
.text:00011BD8 ; ---------------------------------------------------------------------------
.text:00011BD8
.text:00011BD8 loc_11BD8:                              ; CODE XREF: sub_11B60+6Aj
.text:00011BD8               lea   edx,
.text:00011BDB               push    edx             ; int
.text:00011BDC               lea   eax,
.text:00011BDF               push    eax             ; int
.text:00011BE0               mov   ecx,
.text:00011BE3               push    ecx             ; SourceString
//读取配置文件的数据,并返回读取到的数据的地址和文件大小
.text:00011BE4               call    sub_12670
.text:00011BE9               mov   , eax
.text:00011BEC               cmp   , 0
.text:00011BF0               jz      short loc_11BF7
.text:00011BF2               jmp   loc_11CA7
.text:00011BF7 ; ---------------------------------------------------------------------------
.text:00011BF7
.text:00011BF7 loc_11BF7:                              ; CODE XREF: sub_11B60+90j
.text:00011BF7               mov   , 1
.text:00011BFB               mov   , 0
.text:00011C02               mov   edx,
.text:00011C05               push    edx
.text:00011C06               mov   eax,
.text:00011C09               push    eax
//异或解密读取到的配置文件的数据
.text:00011C0A               call    sub_12630
.text:00011C0F               mov   ecx,
.text:00011C12               mov   , ecx
.text:00011C15               mov   edx,
.text:00011C18               mov   eax,
.text:00011C1B               imul    eax, 24Ah
.text:00011C21               add   eax, 8
//比较文件大小是否等于读取到的数据长度大小
//if(FileLength==(*DWORD*)(BufferAddr+4)*0x24A+8)
.text:00011C24               cmp   eax,
.text:00011C27               jz      short loc_11C39
.text:00011C29               mov   , 0C0000001h
.text:00011C30               mov   , 0FFFFFFFFh
.text:00011C37               jmp   short loc_11CA7
.text:00011C39 ; ---------------------------------------------------------------------------
.text:00011C39
.text:00011C39 loc_11C39:                              ; CODE XREF: sub_11B60+C7j
.text:00011C39               mov   , 0
.text:00011C40               jmp   short loc_11C4B
.text:00011C42 ; ---------------------------------------------------------------------------
.text:00011C42
.text:00011C42 loc_11C42:                              ; CODE XREF: sub_11B60+115j
.text:00011C42               mov   ecx,
.text:00011C45               add   ecx, 1
.text:00011C48               mov   , ecx
.text:00011C4B
.text:00011C4B loc_11C4B:                              ; CODE XREF: sub_11B60+E0j
.//读取配置文件里需要删除文件的个数=*(DWORD*)(BufferAddr+4)
.text:00011C4B               mov   edx,
.text:00011C4E               mov   eax,
.text:00011C51               cmp   eax,
.text:00011C54               jnb   short loc_11C77
.text:00011C56               mov   ecx,
.text:00011C59               imul    ecx, 24Ah
.text:00011C5F               mov   edx,
.text:00011C62               lea   eax,
.text:00011C66               mov   , eax
.//读取配置文件里需要删除的文件路径=(wchar_t *)(uFileBufferAddr+0x24A*i+8)
.text:00011C69               mov   ecx,
//删除从配置文件读取到的文件
.text:00011C6C               push    ecx             ; wchar_t *
.text:00011C6D               call    sub_11880
.text:00011C72               mov   , eax
.text:00011C75               jmp   short loc_11C42
.text:00011C77 ; ---------------------------------------------------------------------------
.text:00011C77
.text:00011C77 loc_11C77:                              ; CODE XREF: sub_11B60+F4j
.text:00011C77               mov   , 0FFFFFFFFh
.text:00011C7E               jmp   short loc_11CA0
.text:00011C80 ; ---------------------------------------------------------------------------
.text:00011C80
.text:00011C80 loc_11C80:                              ; DATA XREF: .text:00012844o
.text:00011C80               mov   eax, 1
.text:00011C85               retn
.text:00011C86 ; ---------------------------------------------------------------------------
.text:00011C86
.text:00011C86 loc_11C86:                              ; DATA XREF: .text:00012848o
.text:00011C86               mov   esp,
.text:00011C89               mov   , 0C0000001h
.text:00011C90               mov   , 0FFFFFFFFh
.text:00011C97               jmp   short loc_11CA7
.text:00011C99 ; ---------------------------------------------------------------------------
.text:00011C99               mov   , 0FFFFFFFFh
.text:00011CA0
.text:00011CA0 loc_11CA0:                              ; CODE XREF: sub_11B60+11Ej
.text:00011CA0               mov   , 0
.text:00011CA7
.text:00011CA7 loc_11CA7:                              ; CODE XREF: sub_11B60+73j
.text:00011CA7                                       ; sub_11B60+92j ...
.text:00011CA7               movzx   edx,
.text:00011CAB               cmp   edx, 1
.text:00011CAE               jnz   short loc_11CB9
.text:00011CB0               mov   eax,
.text:00011CB3               push    eax             ; P
.text:00011CB4               call    sub_12800
.text:00011CB9
.text:00011CB9 loc_11CB9:                              ; CODE XREF: sub_11B60+14Ej
.text:00011CB9               mov   eax,
.text:00011CBC               mov   ecx,
.text:00011CBF               mov   large fs:0, ecx
.text:00011CC6               pop   edi
.text:00011CC7               pop   esi
.text:00011CC8               pop   ebx
.text:00011CC9               mov   esp, ebp
.text:00011CCB               pop   ebp
.text:00011CCC               retn    4
.text:00011CCC sub_11B60       endp

根据以上的分析得出以下配置文件的数据结构:

typedef struct _CLEANDATA
{
DWORD unknow;
DWORD dwNum;
char FilePath;
}CLEANDATA;

解密配置文件函数:
void XorFun(ULONG pBuffer,ULONG FileLength)
{
ULONG i;

if (pBuffer>0)
{
for (i=0;i<FileLength;++i)
{
   *(BYTE*)(pBuffer+i)=*(BYTE*)(pBuffer+i)^0x48;
   
}
}
}上面的读取配置文件数据并根据需要删除文件功能函数源码:
BOOLEAN DoFileClean(BOOLEAN bClean,wchar_t* FilePath)
{
BOOLEAN bDO;
BOOLEAN bRead;
ULONG uFileLength;
ULONG uDataLength,i;
wchar_t *FileName;
ULONG uFileBufferAddr;
if (bClean)
{
bDO=MyOpenFile(FilePath);
bRead=FALSE;
uFileBufferAddr=0;
uFileLength=0;
if (bDO)
{
   bDO=MyReadFile(FilePath,(ULONG)&uFileBufferAddr,(ULONG)&uFileLength);
   if (bDO)
   {
    bRead=TRUE;
    XorFun(uFileBufferAddr,uFileLength);
    uDataLength=*(DWORD*)(uFileBufferAddr+4)*0x24A+8;
   
    if (uDataLength==uFileLength)
    {
   for (i=0;i<*(DWORD*)(uFileBufferAddr+4);++i)
   {
      FileName=(wchar_t *)(uFileBufferAddr+0x24A*i+8);
      MyDeleteFile(bDO,FileName);
   }
   
    } else
    {
   bDO=FALSE;
    }
   }
   
}

if (bRead)
{
   ExFreePoolWithTag(pBuffer,0);
}
}

return bDO;
}

漏洞利用方法:创建一个字节大小为586*文件个数+8的文件,1-4个字节未使用,可以任意字节,5-8字节为文件个数,9-594字节为第一个文件路径,该文件命名KSafeFileBootClean.config,并放在%windir%\system32\目录下,然后创建一个Boot方式加载ksafebc.sys的驱动服务!重启后,利用完成,占坑和替换利用方法与此类似...

tysan 发表于 2010-9-23 01:54

很邪恶的漏洞,话说·

Hmily 发表于 2010-9-23 02:09

官方收到漏洞分析报告了,在新版应该已经修正此漏洞了.

Skyfly 发表于 2010-9-23 03:18

这个我完全看不懂 好有技术含量的。

caroline 发表于 2010-9-23 07:47

非常邪恶、

hapy 发表于 2010-9-23 08:28

哇塞。。。这样也可以啊,代码收藏了,好好研究一下

czjh2008 发表于 2010-9-23 08:30

幸亏我没用金山卫士!

usa-911 发表于 2010-9-23 09:24

这是真正的网络安全!感谢z大分析!

c203770116 发表于 2010-9-23 09:37

金山产品漏洞确实是多~~~~~~~

浅、唱 发表于 2010-9-23 10:18

哈.
很邪恶,不过我喜欢。
实验去囖,:lol
页: [1] 2 3 4 5
查看完整版本: 金山卫士(影响版本<=1.5.0.1147)ksafebc.sys内核驱动后门利用漏洞