简单尝试利用维控LeviStudioU的一栈缓冲区溢出漏洞

时间:2022-06-22 19:29:24

  这是别人给我发的,让我分析一下,看能否写出exp。只怪自己水平不够,最后没能写出exp,以下为自己的分析思路

  环境为win10 pro x64 英文版(10.0.16299) 默认安全配置

一、漏洞分析

  此漏洞是由于LeviStudioU在处理.G_Picture.xml文件的szFilename时没有对其长度进行检查,导致调用后续的函数MSVCR90!wcscpy时发生缓冲区溢出,从而引发SEH异常。

  首先打开LeviStudioU,附加windbg,到达漏洞现场

简单尝试利用维控LeviStudioU的一栈缓冲区溢出漏洞

  此时引用了无效指针,再次执行到达可控位置

简单尝试利用维控LeviStudioU的一栈缓冲区溢出漏洞

  通过KB回溯堆栈调用,从0x0019d3a8位置的ntdll!KiUserExceptionDispatcher+0x26可判断调用了SEH程序

简单尝试利用维控LeviStudioU的一栈缓冲区溢出漏洞

  通过分析0x0019d860位置的Hmi_BmpLib_Dll!GetXmlBmpInfoByPos+0x24c,可判断上层函数为Hmi_BmpLib_Dll!GetXmlBmpInfoByPos;重新启动程序,用windbg中断Hmi_BmpLib_Dll!GetXmlBmpInfoByPos位置

简单尝试利用维控LeviStudioU的一栈缓冲区溢出漏洞

  

  单步运行到0x03042258位置,出现G_Picture.xml的文件路径。

简单尝试利用维控LeviStudioU的一栈缓冲区溢出漏洞

  

  其中eax为漏洞文件G_Picture.xml的路径。

简单尝试利用维控LeviStudioU的一栈缓冲区溢出漏洞

  

  一直单步运行,直到0x0304239e位置,此时程序准备清空缓冲区。

简单尝试利用维控LeviStudioU的一栈缓冲区溢出漏洞

  

  执行完0x30423ac后,此时会调用memset函数将缓冲区置为0,缓冲区的首地址为ecx=0x0019d426,空间大小为0x206h,存储内容为0。

简单尝试利用维控LeviStudioU的一栈缓冲区溢出漏洞

  继续执行到0x030423b4处,可以看到szFilename变量。

简单尝试利用维控LeviStudioU的一栈缓冲区溢出漏洞

  

  从0x030423b4至0x030423de处,这个过程会从G_Picture.xml文件中取得szFilename的值,并且值转换为unicode字符,即\x61\x61\x61………变为\x0061\x0061\x0061………。

简单尝试利用维控LeviStudioU的一栈缓冲区溢出漏洞

  

  接下来会调用MSVCR90!wcscpy函数。进入此函数,查看esp的值,其中0x19d424为目的地址,0x058fb988为源地址。

  简单尝试利用维控LeviStudioU的一栈缓冲区溢出漏洞

  

  此时重点关注缓冲区地址处0x0019d426的内容值为0

  简单尝试利用维控LeviStudioU的一栈缓冲区溢出漏洞

  

  继续执行到0x683b7130处,如下图所示会将源参数src的第一个值\x0061拷贝到缓冲区0x0019d426处。

简单尝试利用维控LeviStudioU的一栈缓冲区溢出漏洞

  

  查看缓冲区位置0x0019d426的值开始变为\0x00000061

简单尝试利用维控LeviStudioU的一栈缓冲区溢出漏洞

  以此类推,会将源地址内容逐个拷贝到缓冲区0x0019d426处

简单尝试利用维控LeviStudioU的一栈缓冲区溢出漏洞

简单尝试利用维控LeviStudioU的一栈缓冲区溢出漏洞

  

  执行到漏洞触发位置,因为是seh异常,用!exchain查看异常,可知next SEH的地址为0x0019d854,seh的位置为0x0019d858。

简单尝试利用维控LeviStudioU的一栈缓冲区溢出漏洞

  此时改变szFilename的值,将得出:

  SEH在第539字节后被覆盖,

  Next SHE在537个字节后被覆盖(因为字符要被转换为unicode格式)

简单尝试利用维控LeviStudioU的一栈缓冲区溢出漏洞

二、漏洞利用

  根据以上漏洞分析可大致画出如下的栈分布图

简单尝试利用维控LeviStudioU的一栈缓冲区溢出漏洞

  思路1:将seh覆盖为pop pop ret(而且要找到类似0x00nn00mm的地址),然后将next seh改为jmp xx,最后在seh后添加shellcode,但最后因没有发现/safeseh OFF的模块而放弃。

简单尝试利用维控LeviStudioU的一栈缓冲区溢出漏洞

  思路2:利用加载模块之外的地址,找到pop pop ret、call/jmp dword ptr[ebp + xx]或call/jmp dword ptr[esp + xx]的地址,而且格式要为0x00nn00mm,经过查找,未发现符合0x00nn00mm的地址。

简单尝试利用维控LeviStudioU的一栈缓冲区溢出漏洞