撞洞 GeekPWN 2020 | 某办公处理软件公式编辑器栈溢出漏洞解析

 

01 漏洞说明

在挖掘公式编辑器漏洞的过程中,找到了一些空指针解引用、内存越界访问、栈溢出等类型的漏洞。经过分析确认,找到的栈溢出漏洞同GeekPwn 2020参赛人员所提交的栈溢出代码执行漏洞为同一个。

今天主要针对该栈溢出漏洞进行分析、说明。

影响版本:某办公处理软件 2019版 11.1.0.10132

漏洞类型:栈溢出

 

02 详情

crash dump分析

利用windbg分析产生的crash dump文件,打开后通过命令!analyze -v显示如下:

   FOLLOWUP_IP: 
   EqnEdit+362bc
   004362bc 8945f0          mov     dword ptr [ebp-10h],eax

   NTGLOBALFLAG:  22800000

   APPLICATION_VERIFIER_FLAGS:  0

   APP:  eqnedit.exe

   ANALYSIS_VERSION: 6.3.9600.17237 (debuggers(dbg).140716-0327) x86fre

   LAST_CONTROL_TRANSFER:  from 00431085 to 004362bc

   FAULTING_THREAD:  00000760

   PRIMARY_PROBLEM_CLASS:  INVALID_POINTER_WRITE

   BUGCHECK_STR:  APPLICATION_FAULT_INVALID_POINTER_WRITE

触发崩溃地址的指令是mov dword ptr [ebp-10h],eax,查看对应地址的伪代码如下所示:

很明显,经过虚函数调用后,result的指针地址被改变,导致在写入的时候触发异常。在汇编层面,result等同于ebp指针,因此在经过上层函数调用后,ebp指针被修改。这里很可能是存在栈溢出,因为在一个函数最终返回时,基本上都会调用类似以下序列的汇编指令:

mov esp,ebp
pop ebp
retn

因此如果产生了栈溢出但是没有覆盖返回地址仅仅覆盖了部分ebp指针指向的内容时,就可能会产生如上的异常效果。

那么接下来就是分析通过v9[8]到底调用了哪个函数。

调试分析

找到对应触发崩溃的文件,利用windbg调试EqnEdit.exe程序,在004362B6下断点,输出eax的值,结果如下:

查看对应的函数如下:

经过分析后,ida反编译内容如下:

而关键的进行越界写的操作就在函数sub_43ECFA中,ida伪代码如下:

可以看出整个函数逻辑如下,在函数sub_43EBDF中,读取MTEF数据的单个字节作为index,在sub_43ECFA中,通过计算后,将index转换为循环次数,不断地从缓冲区中读取数据,并写入到栈上。如果index值过大将导致缓冲区溢出,覆盖返回地址,最终可能导致任意代码执行。

那么关键函数sub_43EBDF又是如何被调用的,查看崩溃时的调用栈如下:

0018f330 004362bc eqnedit+0x362bc
0018f34c 00431085 eqnedit+0x31085
0018f374 004362b9 eqnedit+0x362b9
0018f3a0 0043727a eqnedit+0x3727a
0018f3d8 004362b9 eqnedit+0x362b9
0018f404 00431085 eqnedit+0x31085
0018f42c 004362b9 eqnedit+0x362b9
0018f458 0043727a eqnedit+0x3727a
0018f490 004362b9 eqnedit+0x362b9
0018f4bc 00431085 eqnedit+0x31085
0018f4e4 004362b9 eqnedit+0x362b9
0018f510 00433c91 eqnedit+0x33c91
0018f534 00433700 eqnedit+0x33700
0018f58c 0042c7a1 eqnedit+0x2c7a1
0018f5b0 00407a6b eqnedit+0x7a6b

在函数sub_43622d中,对读取的数据进行判断后进行调用对应的处理函数,如下:

而在case 4情况下才会调用sub_43EBDF,此时读取的tag值为5,查看MathType 6.9 SDK,如下:

看来是在解析MATRIX record的过程中产生栈溢出漏洞。

经过分析后,发现该漏洞完全可以利用,由于公式编辑器没有开启重定位,也就不需要绕过ASLR,通过一定的ROP技术绕过DEP即可,而且程序里导入了WinExec函数,利用起来会更加便利,效果见视频。

 

03 漏洞修复

目前,在最新版的WPS 2021版中,已将该漏洞修复,限定了循环拷贝的次数小于等于8,伪代码如下:

 

04 视频演示

https://www.bilibili.com/video/BV1Fy4y1B7EM

(完)