作者:枕边月亮
原文来自:CVE-2015-1641 Office类型混淆漏洞及shellcode分析
0x1实验环境:Win7_32位,Office2007
0x2工具:Windbg,OD,火绒剑,UltraEdit,oletools;
0x3漏洞简述:word在解析docx文档的displacedByCustomXML属性时未对customXML对象进行验证,可以传入其他标签对象进行处理,造成类型混淆,通过在word中嵌入构造好的RTF文件,其中经过精心构造的标签以及对应的属性值被displacedByCustomXML解析以及后续函数处理后会造成任意内存写入。
0x4 样本hash值:8bb066160763ba4a0b65ae86d3cfedff8102e2eacbf4e83812ea76ea5ab61a31
0x5:分析记录:
在分析前先做好虚拟机快照,获取RTF样本后使用oletools工具中的rtfobj.pyc脚本分析,这里将文件命名为aa.doc,在cmd命令模式中来到rtfobj.pyc所在的目录,并将aa.doc一块放到该目录,接着执行命令“rtfobj.pyc aa.doc”,得到分析结果如下:一共四个文件,id为0的是“otkloadr.wRAssembly.1”,用来加载 OTKLOADR.DLL 模块,其功能会在之后分析到:
把其他三个OLE对象分别根据他们各自的id用“rtfobj.pyc-s [id] aa.doc”命令依次分离并保存,其中有两个是”.doc”文件,现在样本已经被分离,双击执行也不会有危险,
将其中id为2的"aa.doc_object_0002042c.doc"的后缀改为“.docx”后,打开word就会奔溃,可以预测,漏洞就在这个OLE里面触发的:
在分析这个样本的过程中,由于对RTF文件构造方式不熟悉,使得我在构造样本的时候阻滞了很长时间,东拼西凑就是不能制造crash,后边把问题放到了看雪论坛,前辈们一下就解决了,其实RTF文件的构造不复杂:将原始rtf 样本用文本方式打开,搜索 “objdata” 字符串,可找到与 rtfobj.py 提取后相应 id 的内容,手动抽取对应id的内容另存为一个合法的 rtf 文件即可。前面提到,这个RTF样本一共由四个OLE对象组成,用notepad++打开原始样本,然后搜索“objdata” 字符串,发现一共有四个这样的字符串,也就是那四个OLE,触发漏洞的OLE的id为2,也就是原始样本中的第三个OLE,长这样:
抽取复制OEL的时候一定要把括号成对匹配好,把这个OLE复制出来,即它的开头到下一个OLE的开头的部分,然后新建一个文本文档,并把后缀改为”.rtf”格式,然后在这个文档中先写好“{\rtf}”,然后粘贴OLE进去即可:
然后把这个RTF文件用word打开,就会奔溃;中间失败过几次,后来发现是复制OLE的时候括号复制多了。
接着来定位漏洞触发的位置,先打开Windbg,再打开Winword.exe,用调试器附加Winword.exe后运行存在漏洞的OLE文件,程序在“0x67C39d30“这个地址出现异常,导致奔溃,原因是[ECX]引用了一个不存在的地址;
这个指针[7C38BD50]会指向哪里?,先把这个存在漏洞的OLE解压,在解压目录的资源组织文件“document.xml”中发现如下的代码:上面ECX的值被内嵌成smarttTag标签的element的属性值
martTag标签是一个智能标签,可对名字、地址等自动识别,displacedByCumtomXml属性表示此处要替换为另一个customxml标签,”next”表示后一个,”prev“表示前一个;样本作者在smartTag的element中构造了0x7C38BD50,Word在解析docx文档处理displacedByCustomXML属性时未对customXML对象进行验证,所以能传入smartTag标签对象。
单独加载触发漏洞的OLE时索引到一个不存在的地址,因为这个地址位于” MSVCR71.DLL”中,而这个DLL正是通过第一个OLE对象“otkloadr.wRAssembly.1”引入的。将第一个OLE对象:{\object\objocx{\*\objdata0105000002000000160000006f746b6c6f6164722e5752417373656d626c792e3100000000000000000001000000410105000000000000}},添加到触发漏洞的OLE前面,然后重新加载合并后的RTF运行,通过windbg下条件断点,这里先记录下crash发生的时候“0x7C38BD50“所在的模块地址,待会通过它来下条件断点:
条件断点:
bp wwlib!DllGetClassObject+0x50e6".if(ecx=7c38BD50){}.else{gc}"
0x7C38BD50是smartTag标签的element值,0xFFFFE696(十进制为4294960790)是moveFromRangeStart的值,随后对这两个值进行计算得到一个地址0x7C38BD74。计算过程如下:
随后开始解析第二个smartTag,smartTag标签的element值此时为0x7C38BD68,moveFromRangeStart的值为0x7C376FC3(十进制为2084007875),计算出的地址为0x7C38A428,最后通过memcpy函数将0x7C376FC3覆盖到地址0x7C38A428中,在调试器可以看到,0x7C38A428为虚表指针:
而在7C38A428被覆盖之前,它指向的是kernel32!FlsGetValue:
覆盖之后的0x7c38a428指向的便是攻击者想要执行的代码位置:
接着往下执行会先经过一大片地址为“7C342404”的“ret”,然后进入ROP链,再往后就是shellcode。
将id为1的OLE解压后,在解压目录的“activeX1.bin“中看到用来堆喷的数据块:nop指令上面的是ROP链,heapspary前会使用大量地址为0x7c342404 的ret-sled,
通过XML来加载“activeXL.bin”的堆数据:
在堆喷数据看到ROP链之前有大量的“ret sled”,可以通过这个地址来下断点进入shellcode,方法为:在进入MSVCR71.dll后,通过“uf 7C342304 ”命令来查看它所在的模块地址:MSVCR71!calloc+0xb1,并在该处下断;然后用“bd”命令禁用之前的条件断点,F10执行后就能来到地址0x7C342404。如下图,当程序在“0x7C342404”处断下时,通过“Memory”窗口输入Virtual为“ESP”可以看到堆喷数据,如果不能进入到堆喷数据,有两种解决方案:可以将虚拟机的内存设置为2G;或者找到rop链在堆中的位置,接着在执行“ret”准备跳进堆喷数据的时候将栈顶值修改为ROP链的起始位置;
执行完“0x7C342404”处的“ret”后,便可以接着跟到ROP链,F10单步执行:然后通过NOP进入shellcode。
在Windbg中分析shellcode的时候一直没能顺利跟下去,于是在OD中来分析,断点还是在“0x7C342404”:打开OD和Winword.exe后,用OD附加Winword.exe,接着把完整样本拖进word,这个时就可以下断点,因为shellcode是最后执行,在这之前要先进行堆喷,再触发漏洞,时间上来得及。当程序在“0x7C342404”处断下后,发现很久也跟不到ROP链,这时可以借助之前Windbg的分析结果,发现ROP链的首个位置为“0x7C3651EB”,然后在该位置下断,同时把“0x7C342404”处的断点禁用,接着F9执行,便能来到ROP链的开头。
在ROP链中通过调用VirtualProtect关闭起始地址0x090008b4后的DEP保护:
接着执行地址0x090008b4处的“nop+shellcode”:
首先获取kernel32.dll基址:
接着比较API的hash值来获取所需API函数,这样的好处在于减少了shellcode的大小:
接着用VirtualAlloc分配可执行的内存空间,为执行shellcode做准备:
接着通过调用 GetFileSize遍历进程中打开的文件句柄,获取打开的样本文件的句柄:
CreateFileMapping创建该文件的共享文件数据:
MapViewOfFile来获取共享数据的内存地址:
判断几个标志位是否为“{\rt,0xfefefefe,0xfe,0xffffffff”,是则将shellcode拷贝到VirtualAlloc分配的可执行的内存空间:
但是在之后的分析中,多次调试也没有跟到真实shellcode的位置,于是尝试用Windbg来分析,根据上一阶段的分析可知,第一阶段的shellcoed先判断几个标志字符串是否为“{\rt,0xfefefefe,0xfe,0xffffffff”,是的话就将真实shellcode拷贝到VirtualAlloc分配的可执行的内存空间,如上图所示:顺利的话就会执行“0x090009F9”(偏移0x09F9)地址处的指令。
然后关掉OD,打开Windbg和Winword.exe,用Windbg附加Winword.exe,先在“0x7C342404”,即“ret”链的位置下断,然后将原始样本附加到Winword.exe,执行后来到“ret”,接着在“0x7C3651EB”,即ROP链的开头下断,并用“bd 0”禁用之前的断点,执行后来到ROP链的开头,根据上面的分析,真实shellcode会在偏移“0x09F9”处开始执行,用“bc 0”,“bc 1”先将之前的断点删除,再在“0x090009F9”下断,执行后顺利来到第二阶段的shellcode:
接着将后面的4KB的数据,即第二部分 shellcode,拷贝到函数 VirtualAlloc 申请的具有可执行权限的内存中,然后跳转过去执行
之后会在这部分shellcode的偏移0x2e处解密shellcode,解密的大小为0x3CC字节:
接着根据标志字符串“0xBABABABABA”获得payload的起始位置,然后xor 0xCAFEBABE解码payload,终止标志为0xBBBBBBBB:
接着创建文件,释放payload:
可以根据API参数在UE编辑器看到路径和创建的文件“svchost.exe”:
接着用WinExec函数执行“svchost.exe”:
WinExec函数执行后,在监控软件(火绒剑)中可以看到释放的恶意程序,它的作用主要是进行信息的窃取,:
在恶意payload 执行后会对样本中的部分数据进行异或操作,目的是使其成为看上去正常的word,这部分机器码的开头是“0xBB”,结尾是“0xBCBC”,
重写之后看到的word就是正常打开的空白文档:
原始样本所在的word文档:
有问题大家可以留言哦~也欢迎大家到春秋论坛中来玩耍呢!>>>点击跳转
-
Office高级威胁漏洞在野利用分析
高级威胁漏洞背景 在高级威胁攻击中,黑客远程投递入侵客户端最喜欢的漏洞是office文档漏洞,就在刚刚结束不久的黑帽子大会上,最佳客户端安全漏洞奖颁给了CVE-2017-0199漏洞,这个漏洞是时下o ...
-
堆栈上的舞蹈之释放重引用(UAF) 漏洞原理实验分析
0x01 前言 释放重引用的英文名名称是 Use After Free,也就是著名的 UAF 漏洞的全称.从字面意思可以看出 After Free 就是释放后的内存空间,Use 就是使用的意思,使用释 ...
-
【vulhub】Weblogic CVE-2017-10271漏洞复现&;&;流量分析
Weblogic CVE-2017-10271 漏洞复现&&流量分析 Weblogic CVE-2017-10271 XMLDecoder反序列化 1.Weblogic-XMLDeco ...
-
Java反序列化漏洞Apache CommonsCollections分析
Java反序列化漏洞Apache CommonsCollections分析 cc链,既为Commons-Collections利用链.此篇文章为cc链的第一条链CC1.而CC1目前用的比较多的有两条链 ...
-
Log4j漏洞源码分析
Log4j漏洞源码分析 这几天Log4j的问题消息满天飞,今天我们就一起来看看从源码角度看看这个漏洞是如何产生的. 大家都知道这次问题主要是由于Log4j中提供的jndi的功能. 具体涉及到的入口类是 ...
-
SMB协议利用之ms17-010-永恒之蓝漏洞抓包分析SMB协议
SMB协议利用之ms17-010-永恒之蓝漏洞抓包分析SMB协议 实验环境: Kali msf以及wireshark Win7开启网络共享(SMB协议) 实验步骤: 1.查看本机数据库是否开启,发现数 ...
-
ueditor getshell漏洞重现及分析
0x00 概述 8月21日,网上爆出ueditor .net版本getshell漏洞,由于只校验ContentType而没校验文件后缀导致getshell. 0x01 漏洞重现 Payload: &l ...
-
【转】cve2014-3153 漏洞之详细分析与利用
背景学习: Linux Futex的设计与实现 使用者角度看bionic pthread_mutex和linux futex实现 By kernux TopSec α-lab 一 漏洞概述 这个漏洞是 ...
-
漏洞扫描与分析-Nessus-8.7.2最新版-安装-部署-使用
漏洞扫描与分析-Nessus 2019/10/10 Chenxin 简介 官网 https://zh-cn.tenable.com/ 产品 https://zh-cn.tenable.com/prod ...
随机推荐
-
Sublime Text通过插件编译Sass为CSS及中文编译异常解决
虽然PostCSS才是未来,但是Sass成熟稳定,拥有一大波忠实的使用者,及开源项目,且最近Bootstrap 4 alpha也从Less转到Sass了.所以了解Sass还是非常有必要的. 基于快速开 ...
-
JAVA 实战练习
1.判断变量是否为奇数偶数. package com.JAVA; import java.util.Scanner; public class text { public static void ma ...
-
MyBatis框架Maven资源
<!-- MyBatis框架 --> <dependency> <groupId>org.mybatis</groupId> <artifac ...
-
蓝牙-b
最近智能家居比较火,好多公司开始开发通过蓝牙对智能家居进行连接控制!下面,我就把自己总结的蓝牙方面的知识分享一下!求吐槽!!!!O(∩_∩)O... 1.导入头文件#import <CoreBl ...
-
Cisco VPN Client Error 56解决
Cisco VPN Client Error 56解决 VPN Client报错 650) this.width=650;" style="width:575px;height:1 ...
-
【转】Android Service创建USB HOST通信
之前做了一个关于Android USB通信的Case,通过Android的USB总线给Zigbee供电,和板载的Zigbee(基于Zigbee的自组网)进行通信.要使用Android的USB Host ...
-
js使用正则表达式实现文本框只能输入数字和小数点
第一种情况:且限制小数点前最大3位数,小数点后最大3为三位 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN& ...
-
Maven发布war包到Tomcat
一.修改Tomcat下配置文件tomcat-users.xml,然后启动 <role rolename="manager-gui"/> <role rolenam ...
-
Copy List with Random Pointer leetcode java
题目: A linked list is given such that each node contains an additional random pointer which could poi ...
-
HDU 2222 Keywords Search(AC自动机)题解
题意:给你几个keywords,再给你一段文章,问你keywords出现了几次. 思路:这里就要用到多模匹配算法AC自动机了,AC自动机需要KMP和字典树的知识,匹配时是在字典树上,失配我们就要用到类 ...