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

时间:2022-05-06
本文章向大家介绍微软公式编辑器系列漏洞分析(一):CVE-2017-11882,主要内容包括0x00 简介、0x01 漏洞分析、0x02 Exploit 分析、0x03 Patch Diff、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。

0x00 简介

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

0x01 漏洞分析

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

我们使用windbgkernel32!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.pyOLE Data导出来。

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

其中Equation Stream Header的结构为

MTEF Header的结构为

Description

Size (byte)

Value

Comment

MTEF Version

1

0x3

MTEFv3

Generating Platform

1

0x3

Windows

Generating Product

1

0x1

Equation Editor

Product Version

1

0x3

Product Subversion

1

0xa

MTEF Data的结构为

Description

Size (byte)

Value

Comment

Tag

1

0x8

0x8 denotes Font record

Typeface Number

1

0x5a

Style

1

0x5a

Font Name

Variable, NULL terminated

“cmd.exe /c calc.exe AAAAAAAAAAAAAAAAAAAAAAAA” + 0x00430c12

到这里,问题就很明显了。原因就是在于在处理字体名称的时候,没有做长度判断。导致使用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,所以这里不会有问题了。