- 第一部分: Introduction to Exploit Development
- 第二部分:Saved Return Pointer Overflows
- 第三部分:Structured Exception Handler (SEH)
- 第四部分:Egg Hunters
- 第五部分:Unicode 0x00410041
- 第六部分:WIN32 shellcode 编写
- 第七部分:返回导向编程(ROP)
- 第八部分:堆喷射第一节【覆写 EIP】
- 第九部分:堆喷射[第二章:UAF]
- 第十部分:内核利用程序之栈溢出
- 第十一部分:内核利用程序之任意位置任意写
- 第十二部分:内核利用程序之空指针引用
- 第十三部分:内核利用程序之未初始化栈变量
- 第十四部分:内核利用程序之整数溢出
- 第十五部分:内核利用程序之 UAF
- 第十六部分:内核利用程序之池溢出
- 第十七部分:内核利用程序之任意位置任意写
- 第十八篇:内核利用程序之 RS2 Bitmap 巫术
- 第十九篇:内核利用程序之 Razer
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
侦查挑战
好,就如前面提到的,我们在本文将进行栈溢出挑战。HackSysTeam 提供给了我们驱动的源代码,我们也可以看看相关的部分!
NTSTATUS TriggerStackOverflow(IN PVOID UserBuffer, IN SIZE_T Size) {
NTSTATUS Status = STATUS_SUCCESS;
ULONG KernelBuffer[BUFFER_SIZE] = {0};
PAGED_CODE();
__try {
// Verify if the buffer resides in user mode
ProbeForRead(UserBuffer, sizeof(KernelBuffer), (ULONG)__alignof(KernelBuffer));
DbgPrint("[+] UserBuffer: 0x%p\n", UserBuffer);
DbgPrint("[+] UserBuffer Size: 0x%X\n", Size);
DbgPrint("[+] KernelBuffer: 0x%p\n", &KernelBuffer);
DbgPrint("[+] KernelBuffer Size: 0x%X\n", sizeof(KernelBuffer));
#ifdef SECURE
// Secure Note: This is secure because the developer is passing a size
// equal to size of KernelBuffer to RtlCopyMemory()/memcpy(). Hence,
// there will be no overflow
RtlCopyMemory((PVOID)KernelBuffer, UserBuffer, sizeof(KernelBuffer));
#else
DbgPrint("[+] Triggering Stack Overflow\n");
// Vulnerability Note: This is a vanilla Stack based Overflow vulnerability
// because the developer is passing the user supplied size directly to
// RtlCopyMemory()/memcpy() without validating if the size is greater or
// equal to the size of KernelBuffer
RtlCopyMemory((PVOID)KernelBuffer, UserBuffer, Size);
#endif
}
__except (EXCEPTION_EXECUTE_HANDLER) {
Status = GetExceptionCode();
DbgPrint("[-] Exception Code: 0x%X\n", Status);
}
return Status;
}
这里展示了含有漏洞的代码,同时也给出了解决的方案。 RtlCopyMemory
使用一个指向 kernel buffer 的指针,一个 input buffer 的指针以及一个指定拷贝字节数的整型数。显然这里有点故事,在有漏洞的版本中,buffer 尺寸是基于 input buffer 的尺寸,而安全版本中尺寸被严格限制到了 kernel buffer 的大小。如果我们调用到该函数,传递一个尺寸大于 kernel buffer 的 input buffer,就会发现一些端倪。
好,让我们看看 IDA 中的 IrpDeviceIoCtlHandler
表,这里驱动程序比较了输入的 IOCTL 码,找到识别它的例程。
有相当数量的 IOCTL!转到图形的左侧可以看到下面的内容:
可以看到如果 IOCTL 码是 0x222003,我们就会转入到 TriggerStackOverflow 函数的调用分支。花些时间来调查一下这一 switch 语句。最基本的,输入 IOCTL 通过比较大小来进行匹配,一路递减直到找到一个合法的码值或干脆命中最后的"Invalid IOCTL…"。
看看 TriggerStackOverflow
函数,我们或多或少可以看到在源码中发现的内容,注意到 kernel buffer 长度为 0x800(2048)。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论