微软公式编辑器系列漏洞分析(一):CVE-2017-11882
![](http://image.baizhud.com/images/mytent/2022-05-06/165182016616518201lwD6k6.jpeg)
0x00 简介
CVE-2017-11882为Office内存破坏漏洞。攻击者可以利用漏洞以当前登录的用户的身份执行任意命令。所影响的组件是Office 公式编辑器。需要注意的是这里是老版本的公式编辑器,微软在新版本的office中已经默认不使用了。不过,微软仍然保留老版本的公式编辑器,为了兼容。在编辑使用老版本的公式编辑器制作的公式时,才会使用老版本的公式编辑器。
0x01 漏洞分析
打开exploit.rtf
后直接弹出计算器,看到计算器是EQNEDT32.EXE
的子进程。判断漏洞出现在EQNEDT32.EXE
。
我们使用windbg
在kernel32!WinExec
下断点,断下来后看调用栈。
![](http://image.baizhud.com/images/mytent/2022-05-06/1651820166o165U1820V16A6.jpeg)
![](http://image.baizhud.com/images/mytent/2022-05-06/16518201661F65n18D2T0166.jpeg)
可以看到,此时kernel32!WinExec
的参数为cmd.exe /c calc.exe
就是PoC
触发后的WinExec
调用。接着,我们回溯调用栈。看看kernel32!WinExec
是哪个函数调用的。
![](http://image.baizhud.com/images/mytent/2022-05-06/1651820166165183201Ub6P6.jpeg)
继续向上回溯,看上一个函数
![](http://image.baizhud.com/images/mytent/2022-05-06/165182016616P518a2c01g66.jpeg)
继续看0x004115a7
![](http://image.baizhud.com/images/mytent/2022-05-06/16518201661p615Eg1820166.jpeg)
伪代码很简单,下个断点跟一下。在执行完sub_41160F
后计算器已经弹出,说明漏洞出现在sub_41160F
中。随后,我们在sub_41160F
下断点。
![](http://image.baizhud.com/images/mytent/2022-05-06/1651820166c16lEU51820166.jpeg)
函数结束时即到达ret
指令时
![](http://image.baizhud.com/images/mytent/2022-05-06/1651820166M16B5W18201666.jpeg)
发现返回地址已经被修改,变成了00430c12
,我们继续回看Exploit
。
![](http://image.baizhud.com/images/mytent/2022-05-06/1651820166165R3182IX0166.jpeg)
这就是明显的栈溢出。
0x02 Exploit 分析
使用rtfobj.py
将OLE Data
导出来。
![](http://image.baizhud.com/images/mytent/2022-05-06/16518201661653V18rL20166.png)
这里,Equation Native
的结构为Equation Native = Equation Stream Header + MTEF Header + MTEF Data
。
其中Equation Stream Header
的结构为
![](http://image.baizhud.com/images/mytent/2022-05-06/165182016616t51820j5B166.jpeg)
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
![](http://image.baizhud.com/images/mytent/2022-05-06/1651820166165G51820Q0166.png)
![](http://image.baizhud.com/images/mytent/2022-05-06/16518201663165t1820p1J66.jpeg)
![](http://image.baizhud.com/images/mytent/2022-05-06/16518201661v6B51820V1X66.jpeg)
此时ecx = strlen(a1) + 1
,所以微软在这里对字体长度做了限制,不大于0x21
,所以这里不会有问题了。
- BAT人工智能生态时局图:全面战争爆发前夜
- AI博弈论:DeepMind让智能体在非对称博弈中找纳什均衡
- 斯坦福吴恩达团队公布最大医学影像数据集
- Rokid祝明铭:大腿我们不抱,人机交互产品形态未定 | 变局者
- 腾讯AI让二子,柯洁还是输了
- AI创业者的“英雄联盟”,腾讯AI加速器二期项目招募开启
- PyTorch发布一周年:盘点社区和工程大事件,后来者居上态势已显?
- 2018年AI如何发展?普华永道做出了8点预测 | 报告下载
- 不正之风!机器学习论文里都有哪四大投机取巧的写作手法?
- 前端写一个月的原生 Android 是怎样一种体验?
- 给人挖矿还不自知 电脑已变黑客肉鸡
- 反序列化漏洞屡被黑客利用,危害巨大,代码怎样写才安全?
- Mifa 主题微信编辑器
- Mifa GitHub Pages 主题
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 面向对象的7种设计原则(5)-里氏代换原则
- CentOS7下利用Google Authenticator实现SSH登录的二次身份验证
- 满分室间质评之GATK Somatic SNV+Indel+CNV+SV(下)性能优化
- poiAndEasyExcel学习(六)
- C++ 模板沉思录(上)
- Python 为什么会有个奇怪的“...”对象?
- 老板让我从几百个Excel中查找数据,我用Python一分钟搞定!
- 爬取B站20万+条弹幕,我学会了如何成为B站老司机
- Pytorch实现卷积神经网络训练量化(QAT)
- VBA解压缩ZIP文件11——存在问题
- 算法集锦(14)|图像识别| 图像识别算法的罗夏测试
- CenterNet骨干网络之hourglass
- 语音识别中的声学特征提取:梅尔频率倒谱系数MFCC | 老炮儿改名PPLOVELL | 5th
- 基于Apriori的数据关联分析 | 工业数据分析 | 冰水数据智能专题 | 4th
- 基于FP树的频繁项挖掘 | 工业数据分析 | 冰水数据智能 | 5th