金山卫士(影响版本<=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的驱动服务!重启后,利用完成,占坑和替换利用方法与此类似...
很邪恶的漏洞,话说· 官方收到漏洞分析报告了,在新版应该已经修正此漏洞了. 这个我完全看不懂 好有技术含量的。 非常邪恶、 哇塞。。。这样也可以啊,代码收藏了,好好研究一下 幸亏我没用金山卫士! 这是真正的网络安全!感谢z大分析! 金山产品漏洞确实是多~~~~~~~ 哈.
很邪恶,不过我喜欢。
实验去囖,:lol