漏洞概述
- 软件网址:http://safe.2345.cc/
- 版本:v3.7 X64
2345安全软件的驱动2345BdPcSafe.sys在ioctl(0x0022204C)接口处理中,对输入数据校验不严格,精心构造的数据可导致在处理过程中内存拷贝时溢出,然后bsod拒绝服务,甚至可内核提权。
漏洞分析
在IRP_MJ_DEVICE_CONTROL处理函数中,对0x22204C接口进行处理时,有一段拷贝字符串的操作如下所示:

1 | struct _ioctl_buf |
a2是一个_ioctl_buf结构(由应用层输入构造而成),len2是输入的另一个字符串的长度,通过a2->len(2字节)和len2(2字节)计算得到len1,关键在于len1是也一个WORD变量,只有2字节,所以当a2->len+len2的大小超过WORD溢出之后,会被截断成WORD,截断后的值赋给len1,此时就可能导致len1的值反而小于a2->len。比如:
1 | 0xa3d0 + 0xb4f0 = 0x158C0 =>截断=> 0x58C0 |
接着根据len1分配内存p,memmove拷贝a2->ptr内容到p中,长度按a2->len,问题就来了,a2-len大于len1时,就会导致拷贝溢出,bsod(写溢出,可控制内容,可以做更多的利用了,这里我不擅长了)。
好了,漏洞成因这里就分析完了。
下面看一下poc:
1 | int poc() |
其中buff.buf1和buff.buf2的长度0xa3d0 + 0xb4f0 = 0x158c0(截断)就是a2->len(0x58c0),buff.buf2的长度b4f0就是len2。
我们在调试中看一下计算结果,可以清晰看到len1=0xdb2 < 0x58c0(a2->len)。
1 | 0: kd> p |
结语
这个漏洞主要是对输入参数结构体的长度字段校验不够严谨,导致变量溢出截断出现意外的大小结果导致了漏洞的产生。
该系列后续会继续分析其他原因引起的漏洞,如有兴趣,敬请期待!