微软公式编辑器系列漏洞分析(一):CVE-2017-11882

作者:WeaponX@逢魔安全实验室

0x00 简介

CVE-2017-11882为Office内存破坏漏洞。攻击者可以利用漏洞以当前登录的用户的身份执行任意命令。所影响的组件是Office 公式编辑器。需要注意的是这里是老版本的公式编辑器,微软在新版本的office中已经默认不使用了。不过,微软仍然保留老版本的公式编辑器,为了兼容。在编辑使用老版本的公式编辑器制作的公式时,才会使用老版本的公式编辑器。

0x01 漏洞分析

打开exploit.rtf后直接弹出计算器,看到计算器是EQNEDT32.EXE的子进程。判断漏洞出现在EQNEDT32.EXE

我们使用windbg在kernel32!WinExec下断点,断下来后看调用栈。

可以看到,此时kernel32!WinExec的参数为cmd.exe /c calc.exe就是PoC触发后的WinExec调用。接着,我们回溯调用栈。看看kernel32!WinExec是哪个函数调用的。

继续向上回溯,看上一个函数

继续看0x004115a7

伪代码很简单,下个断点跟一下。在执行完sub_41160F后计算器已经弹出,说明漏洞出现在sub_41160F中。随后,我们在sub_41160F下断点。

函数结束时即到达ret指令时

发现返回地址已经被修改,变成了00430c12,我们继续回看Exploit。

这就是明显的栈溢出。

0x02 Exploit 分析

使用rtfobj.py将OLE Data导出来。

这里,Equation Native的结构为Equation Native = Equation Stream Header + MTEF Header + MTEF Data 。

其中Equation Stream Header的结构为

MTEF Header的结构为

MTEF Data的结构为

到这里,问题就很明显了。原因就是在于在处理字体名称的时候,没有做长度判断。导致使用strcpy拷贝字体名称导致栈溢出。

int __cdecl sub_41160F(char *a1, char *a2, int a3)
{
int result; // eax@12
char v4; // [sp+Ch] [bp-88h]@5
char v5; // [sp+30h] [bp-64h]@4
__int16 v6; // [sp+51h] [bp-43h]@5
char *v7; // [sp+58h] [bp-3Ch]@7
int v8; // [sp+5Ch] [bp-38h]@1
__int16 v9; // [sp+60h] [bp-34h]@1
int v10; // [sp+64h] [bp-30h]@1
__int16 v11; // [sp+68h] [bp-2Ch]@1
char v12; // [sp+6Ch] [bp-28h]@1
int v13; // [sp+90h] [bp-4h]@1
LOWORD(v13) = -1;
LOWORD(v8) = -1;
v9 = strlen(a1);
strcpy(&v12, a1); // overflow here
_strupr(&v12);
...
}

这里,a1是字体名称字符串,可见在strcpy进行字符串拷贝时没有进行长度判断,导致栈溢出。

0x03 Patch Diff

此时ecx = strlen(a1) + 1,所以微软在这里对字体长度做了限制,不大于0x21,所以这里不会有问题了。