CVE-2017-11882 poc分析

思路:由样本poc出发,寻找漏洞触发点

0x00 工具&实验环境

0x01 分析行为

第一步:观察poc行为

​ 打开11882.rtf (样本文件)后,弹出一个计算器,如下图所示:

​ ok,既然弹出了计算器,那么我就用windbg附加到Word程序用bp命令下那几个函数的断点嘛(CreateProcess系列、WinExec、ShellExecute系列),然后再把11882.rtf脱进被附加调试器的Word程序。

​ 但是结果出乎我意料,计算器都弹出来了,windbg却还是BUSY状态(没有触发断点)。我的第一反应就是,难道windbg出bug了?于是我再三检查,查阅可以弹出计算器的函数,试了几次,都没有断下来。于是,我请教了一位搞逆向很厉害的树老哥。老哥直接给了我方法,解开了我的疑惑。

第二步:找出计算器被弹出的地方

树老哥 是这样做的:

首先他打开pchunter查看计算器进程的进程信息,结果如下图:

​ 发现有什么不对劲的地方了吗?calc的父进程居然不是WINWORD.EXE!(calc.exe的父进程id不等于WINWORD.EXE的进程ID),那就说明计算器不是由WINWORD.EXE进程打开的。那么根据calc的父进程ID查找,得出calc是由进程ID为2440的cmd.exe创建的。而cmd.exe的父进程ID是2476,但是当前进程列表中并没有进程ID是2476的进程信息。说明那个进程ID为2476的进程是个一秒男,放出了cmd.exe就没了。

​ 那么怎么去找到是哪个进程创建了cmd.exe呢?这个时候就可以上进程监控神器:Process Monitor了。Process Monitor 是windows下高级实时监听工具,用于监视文件系统、注册表、进程和线程的活动。

下面是具体操作步骤:

  • 首先打开process monitor开始监控,双击打开11882.rtf样本文件,待弹出计算器程序后,停止process monitor的监控(不关监控的话,会记录很多其他信息,不利于分析)。

  • 打开pchuntor查看cmd.exe的父进程id,得到cmd.exe的父进程id为428

  • 再在Process Monitor中的记录大量记录信息进行PID过滤,得到是EQNEDT32.EXE这个程序创建的cmd.exe。它的路径也可以在下图中得到:

  • 点中任意一个条目,ctrl+p可以得到EQNEDT32.EXE的父进程ID

  • ok,同理使用Process Monitor的过滤功能,得到原来是svchsot.exe创建的EQNEDIT32.EXE。

  • 在看看winword.exe中的进程相关信息,发现WINWORD.EXE是通过调用系统服务启动的公式编辑器EQNEDT32.EXE(可以选中下图中选中那项,再Ctrl+P查看这一条记录的栈信息)

    根据大佬解释,这是一种叫做decom的调用方法(后台调用com组件)。

    好了,既然已经找到了弹出计算器的进程是EQNEDT32.EXE,那么我们就打开这个程序,然后用windbg附加它,bp 那几个函数,再打开11882.rtf样本文件,看看能不能断下来。嘿嘿断下来了,可以看到执行的命令参数为:cmd.exe /c calc.exe &一堆乱码

    好,下面进行栈回溯,看看是哪儿出了问题。

0x02 调试定位漏洞触发点

  • 查看栈回溯信息如下:

    0:000> kb 4
    ChildEBP RetAddr Args to Child
    0018f1d0 00430c18 0018f354 00000000 0018f1f0 kernel32!WinExec
    WARNING: Stack unwind information not available. Following frames may be wrong.
    0018f214 004218e4 0018f354 0018f5e4 0018f7e4 eqnedt32!MFEnumFunc+0x241b
    0018f304 004214e2 0018f354 72ed005a 00000001 eqnedt32!FMDFontListEnum+0x650
    0018f330 0043b466 0018f354 72ed005a 0018f5e4 eqnedt32!FMDFontListEnum+0x24e

    可以定位到返回位置为0x00430c18,IDA 查看该位置处的代码如下:

    .text:00430C0C                 push    1               ; uCmdShow
    .text:00430C0E mov eax, [ebp+lpCmdLine]
    .text:00430C11 push eax ; lpCmdLine
    .text:00430C12 call ds:WinExec ; 调用的它
    .text:00430C18 cmp eax, 20h
    .text:00430C1B jnb loc_430C43
  • 那么是从哪儿执行到call ds:WinExec的呢?只有看栈的信息(或者使用ctrl+f8或ctrl+f7的方法,不建议使用)。很明显栈被破坏了,只看得到最近的一个返回地址是0x004218e4,IDA查看该位置处的代码如下:

    .text:004218DE                 push    eax             ; lpString1
    .text:004218DF call sub_4115A7 ;调用的它
    .text:004218E4 add esp, 4
    .text:004218E7 test eax, eax
    .text:004218E9 jz loc_421919
  • 好,使用OD来附加(因为windbg不好保存断点记录,也不好及时的看堆栈的信息,所以现在换OD上)。先打开EQNEDT32.EXE,用OD附加后在0x4218DF处下断。打开11882.rtf样本poc文件,发现断到了0x4218DF处。

    然后单步步入,看看执行到call ds:WinExec的调用顺序是啥子样子的。有耐心的分析出来是这样的:

    sub_4115A7--->sub_41160F--->ret--->call ds:WinExec

    Tip:我在进入了sub_41160F后(已经使用了bp WinExec函数下断),使用Ctrl+F8,让其自动单步步过找下一个call的时候,发现其实就没有下一个call了。

    意思是:当自动单步步过停止的时候,按esc键先是回到call ds:WinExec处,再按一下esc键,就回到了sub_41160F函数的最后0x00411874 处了,而该处是一条ret指令。

    所以我在这条ret指令处下了断点,重新调试,发现断到这个ret指令的时候,栈顶的值为0x00430c12,也就是call ds:WinExec指令的地址。

    所以判断应该是栈溢出,覆盖了函数的返回地址。

  • 那么是哪儿把sub_41160F的返回地址给覆盖成了0x430c12了呢?先不管,先看看进入sub_41160F函数的时候栈的情况:可以发现刚进入的时候,返回地址是没有出问题的

  • 继续单步调,发现到了这儿,返回地址就马上从正确的0x004115d8变为了,0x00430c12。

0x03 分析漏洞成因

​ 下面来分析一下这个sub_41160F函数:

int __cdecl sub_41160F(char *a1, char *a2, int a3)
{
int result; // eax
char v4; // [esp+Ch] [ebp-88h]
char v5; // [esp+30h] [ebp-64h]
__int16 v6; // [esp+51h] [ebp-43h]
char *v7; // [esp+58h] [ebp-3Ch]
int v8; // [esp+5Ch] [ebp-38h]
__int16 v9; // [esp+60h] [ebp-34h]
int v10; // [esp+64h] [ebp-30h]
__int16 v11; // [esp+68h] [ebp-2Ch]
char v12; // [esp+6Ch] [ebp-28h]
int v13; // [esp+90h] [ebp-4h] LOWORD(v13) = -1;
LOWORD(v8) = -1;
v9 = strlen(a1);
strcpy(&v12, a1); //这儿造成的 :覆盖返回地址
_strupr(&v12);
/*
.....省略一部分
*/
return result;
}

堆栈图:

strcpy(&v12,a1) 太明显不过的栈溢出了,对栈上进行字符串拷贝未做长度检测,如果a1所指向的字符串的长度大于或等于48个字节,就可以完全覆盖掉返回地址。调试的时候发现a1所指向的内存为下图所示:

的确如此,((DWORD*)a1)[11] = 0x00430c12 就是call ds:WinExec的地址。

当然,读取a1的过程我也分析了下:分析思路是 根据栈回溯,结合OD,IDA调试查找。是在sub_43b418中调用sub_4164fa读取的a1,读取终止条件是一直读到\0结束。

_BYTE *__cdecl sub_4164FA(_BYTE *a1)
{
char *v1; // ST0C_4
_BYTE *result; // eax do
{
v1 = a1++;
*v1 = sub_416352();//从一块固定内存块中读取
}
while ( *v1 );//读到\0结束
result = a1;
*a1 = 0;
return result;
}

所以关键就是 看怎么才能构造个样本,让我们执行到这个地方,公式编辑器是将样本的哪个地方加载到了那个固定内存块中,如果可以找到,那么就可以构造样本了。

经过回溯栈,找关键call 的方式,我发现 好像并不是公式编辑器解析的文本文档。

全是ole32的rpc*调用。等于说,我分析不动了。那就先暂时分析到这儿,等我功力上去了,再来搞。

0x04 总结

​ 微软和Intel处理器的成功很大一部分原因是因为他们的产品始终都尽最大努力向下兼容。但是这样也造成了极大的安全隐患。比如这个公式编辑器,超级超级老了,不支持ASLR,DEP等漏洞缓解措施。但是为了保持向下兼容,尽管都office 2016了,微软还是将它保留了下来。

​ 所以,很多人都会选择去挖那些微软为了兼容性而保留下来的软件的漏洞。我估计不止office软件,像服务器上的软件比如:SQL Server系列的软件 肯定也有很多。

​ 怎么去挖呢???来个高人指点指点我吧。

cve-2017-11882 poc分析的更多相关文章

  1. CVE: 2014-6271、CVE: 2014-7169 PATCH方案分析

    目录 . RedHat官方给的PATCH第一套方案 . RedHat官方给的PATCH临时方案 . RedHat官方给的PATCH第二套方案 1. RedHat官方给的PATCH第一套方案 0x1: ...

  2. phpstudy后门POC分析和EXP开发

    POC 2019年9月20日,网上传出 phpStudy 软件存在后门,随后作者立即发布声明进行澄清,其真实情况是该软件官网于2016年被非法入侵,程序包自带PHP的php_xmlrpc.dll模块被 ...

  3. CVE-2022-30190 Follina Office RCE分析【附自定义word钓鱼模板POC】

    昨天看了下'Follina' MS-MSDT n-day Microsoft Office RCE 这个漏洞,修改了下chvancooten的脚本,实现可以自定义word模板,便于实战中钓鱼使用,自己 ...

  4. CVE: 2014-6271、CVE: 2014-7169 Bash Specially-crafted Environment Variables Code Injection Vulnerability Analysis

    目录 . 漏洞的起因 . 漏洞原理分析 . 漏洞的影响范围 . 漏洞的利用场景 . 漏洞的POC.测试方法 . 漏洞的修复Patch情况 . 如何避免此类漏洞继续出现 1. 漏洞的起因 为了理解这个漏 ...

  5. Java反序列化漏洞分析

    相关学习资料 http://www.freebuf.com/vuls/90840.html https://security.tencent.com/index.php/blog/msg/97 htt ...

  6. S2-045漏洞初步分析

    0x01 前言 前几天刚分析完s2-032这个漏洞,今天又爆发了一个s2-045的漏洞,又是直接的命令执行,影响了struts2绝大多数的版本. 官方给的漏洞公告在这里   https://cwiki ...

  7. CVE-2012-0158基于exp分析

    CVE-2012-0158这个洞我之前分析过,漏洞战争这本书里也写过,但是都是用poc分析的,我这次找了一个弹计算器的exp来分析,感觉用poc和用exp还是不一样的,从exp分析要比从poc分析更复 ...

  8. 数据挖掘-MovieLens数据集_电影推荐_亲和性分析_Aprioro算法

    #!/usr/bin/env python2 # -*- coding: utf-8 -*- """ Created on Tue Feb  7 14:38:33 201 ...

  9. Mysql LOAD DATA读取客户端任意文件漏洞复现(原理分析)

    环境搭建 怎么设置Mysql支持外联? use mysql; grant all privileges on *.* to root@'%' identified by '密码'; //授权语句 fl ...

随机推荐

  1. 【原创】使用golang访问windows telnet服务器

    本篇博客记录本次使用golang语言tcp方式进行telnet服务器访问 环境: 1.win7系统telnet服务器,使用地址:192.168.8.189 2.python使用telnetlib库对t ...

  2. Java——this关键字

    前言 this关键字属于Java中比较复杂的关键字之一,若是学习过C++或者其他的一些面向对象语言也会遇到this这个关键字并且都会看到this的含义就是表示当前对象.什么叫做表示当前对象?this在 ...

  3. linux内核源码目录结构分析

    原文地址 /arch.arch是architecture的缩写.arch目录下是好多个不同架构的CPU的子目录,譬如arm这种cpu的所有文件都在arch/arm目录下,X86的CPU的所有文件都在a ...

  4. js如何获取url参数

    匹配URL参数的正则是: var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", ...

  5. [转]Virtualbox主机和虚拟机之间文件夹共享及双向拷贝(Windows<->Windows, Windows<->Linux)

    本文转自:https://www.jb51.net/article/97271.htm 最近学习Virtualbox的一些知识,记录下,Virtualbox下如何实现主机和虚拟机之间文件夹共享及双向拷 ...

  6. .NET MVC项目设置包含Areas中的页面为默认启动页

    利用vs创建一个MVC项目后,一般的默认启动页是根目录下-->Controllers-->HomeController-->Index这个方法对应的页面. 我先说下创建Areas的流 ...

  7. 最全的.NET Core跨平台微服务学习资源没有之一

    一.Asp.net Core基础 微软英文官网:https://docs.microsoft.com/en-us/aspnet/core/?view=aspnetcore-2.1 .NET Core: ...

  8. [算法总结] 13 道题搞定 BAT 面试——字符串

    1. KMP 算法 谈到字符串问题,不得不提的就是 KMP 算法,它是用来解决字符串查找的问题,可以在一个字符串(S)中查找一个子串(W)出现的位置.KMP 算法把字符匹配的时间复杂度缩小到 O(m+ ...

  9. 腾讯云下的CentOS7 安装最新版Python3.7.0

    第一步下载Python3.7.0 刚开始我是在windows上下载之后 传到FTP服务器上的 后来发现使用以下命令可以更快捷地下载到服务器 *  wget https://www.python.org ...

  10. 反向ajax实现原理

    留言板显示留言一直刷新,那么实现原理是怎么样的? 一般发送留言就是通过正常的ajax向服务器发送数据,而实时显示留言就需要用到轮询了. 什么是轮询:就是使用定时器,每隔固定的时间从客户端向服务器发起请 ...