作者:selph
前言
窥探Ring0漏洞世界:缓冲区溢出之突破GS保护
实验环境:
•虚拟机:Windows 7 x86
•物理机:Windows 10 x64
•软件:IDA,Windbg,VS2022
漏洞分析
本次实验内容是BufferOverflowStackGS(环境提供的栈溢出一共有两个,一个是普通的,一个是GS保护的)
首先用IDA打开HEVD.sys,搜索BufferOverflowStack,可以看到两个函数:BufferOverflowGSStackIoctlHandler和TriggerBufferOverflowStackGS,跟上一篇一样,前者是分发程序,后者是漏洞程序
从IDA的F5里可以看出,这是一个经典的栈溢出漏洞:使用用户输入的长度进行memcpy调用,和上一例完全一样
int __stdcall TriggerBufferOverflowStackGS(void *UserBuffer, unsigned int Size)
{
unsigned __int8 KernelBuffer[512]; // [esp+14h] [ebp-21Ch] BYREF
CPPEH_RECORD ms_exc; // [esp+218h] [ebp-18h]
memset(KernelBuffer, 0, sizeof(KernelBuffer));
ms_exc.registration.TryLevel = 0;
ProbeForRead(UserBuffer, 0x200u, 1u);
_DbgPrintEx(0x4Du, 3u, “[+] UserBuffer: 0x%p\n”, UserBuffer);
_DbgPrintEx(0x4Du, 3u, “[+] UserBuffer Size: 0x%zX\n”, Size);
_DbgPrintEx(0x4Du, 3u, “[+] KernelBuffer: 0x%p\n”, KernelBuffer);
_DbgPrintEx(0x4Du, 3u, “[+] KernelBuffer Size: 0x%zX\n”, 0x200u);
_DbgPrintEx(0x4Du, 3u, “[+] Triggering Buffer Overflow in Stack (GS)\n”);
memcpy(KernelBuffer, UserBuffer, Size);
return 0;
}
交叉引用查看调用处:依然跟上次一样
int __stdcall BufferOverflowStackGSIoctlHandler(_IRP *Irp, _IO_STACK_LOCATION *IrpSp)
{
int v2; // ecx
_NAMED_PIPE_CREATE_PARAMETERS *Parameters; // edx
v2 = -1073741823;
Parameters = IrpSp->Parameters.CreatePipe.Parameters;
if ( Parameters )
return TriggerBufferOverflowStackGS(Parameters, IrpSp->Parameters.Create.Options);
return v2;
}
接着往上走,找到控制码,这里调用处前面的标号是$LN6
查看前面的跳转表:
可以看到,这里是按顺序排的,这里eax只要等于1即可跳转过来
根据上例可知,eax=0,需要的输入是0x00222003,查看eax是怎么来的:
是通过这个索引获取的,所以这里eax得是比上次多4,所以这次使用的控制码是: