CVE:CVE-2005-2827
CNNVD:CNNVD-200512-225
Microsoft Windows是美国微软（Microsoft）公司发布的一系列操作系统。
Microsoft Windows处理异步过程调用(APC)队列列表的方式存在漏洞，本地攻击者可以利用此漏洞提供任意函数指针，劫持执行流，最终完全控制系统。线程在退出的时候，PspExitThread会从ETHREAD.ApcState.ApcListHead[0]和ApcListHead[1]分离线程的APC队列，这样每个队列都会是一个循环的、双向链接的列表，其第一个和最后一个节点不指回到表头(LIST_ENTRY结构)。但是，由于没有修改表头的指针，因此其目的可能仅仅是允许PspExitThread中的APC释放循环，以便无需回到表头并错误的尝试释放ETHREAD结构中内存便可走过每个列表并释放其节点。攻击者可以利用这一过程释放数据，最终导致ExFreePoolWithTag操作用户内存。
外部进程所排列的APC会计算该进程的pool限额，因此包含有APC结构pool块的限额块会引用队列进程。如果正在退出线程的列表中包含有当前终止外部进程所排列的APC，且该APC节点代表进程的Process对象的最后引用，则释放该节点会导致在ExFreePoolWithTag中破坏Process对象，所造成的后果包括执行PspProcessDelete。这会使用KeStackAttachProcess切换到结束进程的地址空间，调用PspExitProcess。然后使用KeUnstackDetachProcess反转切换。
"attach"和"detach"函数都调用KiMoveApcState，其目的是临时分离其APC的线程，这样就不会分发到非预期的地址空间中，然后在线程的原始地址空间恢复后重新链接APC列表。在附加过程中，复制了ETHREAD.ApcState结构，并调整了列表的第一个和最后一个节点的指针以便引用拷贝。在分离的时候，尽管假设第一个和最后一个节点的指针仍是断开的(因为APC释放循环仍在进行)，但调整了这些节点指针以重新将列表链接到原始的ETHREAD.ApcState。最终结果是释放循环仍会继续，尝试释放部分ETHREAD结构。由于所访问的ETHREAD部分中包含有可预测的且大部分为清零的值，因此最终会导致对攻击者提供指针的kernel操作。
以下过程说明了函数调用顺序和漏洞产生过程中所涉及到的参数：
. PspExitThread
. . KeFlushQueueApc
. . (detaches APC queues from ETHREAD.ApcState.ApcListHead)
. . (APC free loop begins)
. . ExFreePool(1st_APC -- queued by exited_process)
. . . ExFreePoolWithTag(1st_APC)
. . . . ObfDereferenceObject(exited_process)
. . . . . ObpRemoveObjectRoutine
. . . . . . PspProcessDelete
. . . . . . . KeStackAttachProcess(exited_process)
. . . . . . . . KiAttachProcess
. . . . . . . . . KiMoveApcState(ETHREAD.ApcState --> duplicate)
. . . . . . . . . KiSwapProcess
. . . . . . . PspExitProcess(0)
. . . . . . . KeUnstackDetachProcess
. . . . . . . . KiMoveApcState(duplicate --> ETHREAD.ApcState)
. . . . . . . . KiSwapProcess
. . ExFreePool(2nd_APC)
. . ExFreePool(ETHREAD + 30h)
. . (APC free loop ends)
solution:Upgrade microsoft windows_2000 to a higher version than *,*:sp1,*:sp2,*:sp3,*:sp4,and avoid the version *:sp1,*:sp2,*:sp3,*:sp4; Upgrade microsoft windows_nt to a higher version than 4.0,and avoid the version 4.0