Equation漏洞混淆利用分析总结(下)

样本三

如下所示在该样本中,使用了Ole10Native的流,因此没有equative head,默认读取红框中的4位长度。之后的metf head为01.

 

可以看到metf head的长度为01时,直接进入到if判断中(该if中的函数实际是一个异常处理函数,但是当传入的参数为45,145时不影响之后的漏洞利用),之后读取0A一位,因此当metf head的version为01时,实际的metf head的长度只有两位。

 

往后读取01,进入11882流程,导致直接返回,进入case流程。

 

进入case中的0798流程,读取08,进入之后的fun_Matrixdispatch,此时进入fun_Matrixdispatch中的11882/0802流程。

 

 

样本四

如下所示可以看到样本使用的是常用的equationative流,长度为1c的字节,之后紧跟metf头,但是咋看之下却并不能确定其具体的漏洞cve,从metf之后的88字节来看,应该是对应的11882/0802漏洞

 

从vt上报的漏洞类型来看,大多数厂商的识别是0802系列,由于从上文所知,metf之后的构造拥有多种方式,因此我们就来看看这个漏洞是否真是0802.

可以看到fun_ParseMTEFData函数中,metf头检验之后,向后读取一字节,此时获取的为0d,作为参数进入到正常的11882/0802流程,0d>09,因此函数直接跳过再次向下读取。 

一直跳过0D 0A,直到蓝色框中的01字节。

 

01被正常11882/0802返回,直接dispatch到case1中。

进入case1流程中的0798,向下再读取一字节01。 

0798中由01  dispatch进入到case0流程。

 

如上文所示,在样本二中提到进入该函数中实际上是有方法进入到对应的equation流程中,但是在当时的漏洞利用样本中,该函数直接进入到if流程中,当时的分析中提到要进入else中需要相关的特殊构造,即a4等于1,else中实际是一个while循环,依次读取并传入到0798的dispatch中。

可以看到while循环中之后会读取02的tag,在该tag中会以此处理之后的3个字节,样本中一共构造了四对02的tag用于混淆,之后处理35tag,35tag->5,即tag 5,而tag5实际上就是0798的漏洞tag,因此基本可以证明该样本使用的漏洞是0798.

 

如下所示,读取对应的35位tag

导致dispatch到case4中,即对应的0798漏洞流程中。

 

0798函数中,以此向后读取5字节的内容,其中第四,第五字节将导致溢出,即下图中的20,80,之后分别以这两字节内容为长度进行栈上数据的拷贝,一共调用两次,最终两段栈上数据连成一片,从而造成溢出。

第一次拷贝,参数为20,及0012f3fc,0012f3fc为目标栈上的地址。

 

第二次,拷贝,参数一为80,参数二为0012f404。可以看到第二次拷贝的地址在第一次拷贝的高地址出。

 

拷贝前的堆栈。

 

拷贝之后的堆栈,可以看到此时返回地址已经被覆盖,但是这个覆盖的数据是不是很奇怪,50505050这个地址并没有意义,难道这只是测试样本?但是从沙箱的结果来看样本是执行成功的。

 

仔细再看一下漏洞函数可以发现,实际上在溢出之后,函数返回之前,还有相当一部分的操作,即之后的sub_4428F0函数,及之后的还有一次0798的操作,也就是还能向后读取数据,结合对应的样本数据,可以发现确实还能向后拷贝,sub_4428F0函数之后将其结果作为参数,返回给0798漏洞流程,同时也能看到第一次溢出的拷贝的数据v6,是作为第四个参数传入到该函数中的,我们的看看这个函数具体做了啥。

 

首先可以看到a2,a3这两个参数来自于sub_43b349函数,值分别为word_45B246和word_45B244

 

而word_45B246和word_45B244的相关引用函数如下所示,其中Headcheck引起了我们的注意

 

可以看到这两个位置的数据是在metf头检验中进行的设置,即函数sub_43B1D0。

可以看到sub_43B1D0中设置a2,a3的值是依赖于metf头之后的一位的值,且在处理的过程中有ReadByte的操作,这就意味这实际上可以通过该函数来实现往metf头之后插入混淆数据的操作。

 

但是实际上仔细看代码就可以知道,上面a2,a3是取的栈上的地址,也就是说这个值实际上在溢出之后是可控的。

 

再次调试可以看到a2,a3的地址分别为0012f420,0012f41c。

 

溢出之后可以看到此时a2,a3的值被修改。

 

如下所示,该函数的调用栈,需要注意的是2,3,4参数,其中第四个参数为溢出数据的第一段内容,2,3参数的低四字节(溢出时被修改为5800,06eb)需要注意,下文中会有相关解释。

 

进入函数,可以看到首先通过sub_435B4A返回了一段内存v5,之后通过传入的参数对该段内存进行初始化,其中红框中的三处赋值初始化是关键,第一二次赋值分别将二三参数的低四位分别去处并v5偏移40和42处(06rb5800),之后通过函数memory将a4的0x14长度的数据拷贝到v5偏移50处,a4就是之前0798溢出时的第一次拷贝shellcode 

此时反编译一下00281c3c这段内存,可以看到之前第一次拷贝的06eb5800的对应反编译源码为pop eax,jmp 00281c6e

 

而00281c6e正好就是之前v5+50处拷贝的溢出shellcode的第一段,而最终00281c3c这段内存会作为参数返回。

 

00281c3c的作为返回值返回,并作为参数1传入到之后的0798 dispatch函数中。

进入dispatch后,之前溢出shellcode之后的35将再次触发0798的漏洞,函数首先分别获取参数1偏移0x28,和0x2a处的数据,并保存到局部变量中,需要注意是获取的是两字节,赋值后内存中变成了00445800. 

0044实际上只之前sub_4428F0函数的返回地址。

有意思的是在漏洞函数中sub_438349中,该函数会设置对应传入的a2,a3地址的值,此时正好将00445800设置为00440000(该值在之后的利用中被使用).

如下所示之后35之后依次读取的5个字节为35, 33,36,20,44(其中用于控制溢出长度的字节为20,44)。

第一次拷贝,拷贝地址为0012f35c,长度的控制参数为20.

 

第二次拷贝,拷贝地址为0012f376,长度的控制参数为44.

 

拷贝前的堆栈数据。

 

拷贝后的栈数据,此时返回地址已经被修改为00430bfb,需要注意的此时覆盖的只是返回地址的第四位,即高四位并没有被修改,返回地址后四位即为传入的第一个参数00281c3c,同样需要注意的还有00281c3c之后的00440000,现在来整理以下第二次漏洞利用的流程

 

00281c3c作为参数一传入0798漏洞函数,之后分别获取00281c3c偏移40,42处的内容),并赋值给v5,v6,其中v5就是0044000(其来源上文中已经说明),之后将00281c3c,v5,v6分别作为2,3,4参数传入到dispatch函数中。

 

之后进入漏洞函数2,3,4参数又分别作为1,2,3参数来调用case 4处的漏洞函数。

 

此时函数返回,由于之前的漏洞将函数的返回地址已经修改为00430bfb,而该地址对应的反汇编代码为ret,执行ret,将导致程序的执行流程直接进入到00430bfb之后的00281c3c中。

 

00281c3c向下执行,最终导致执行之后00281c3c中已经构造好的shellcode

 

这里可以看到在jmp前,有一条pop eax的操作,此时pop,即将之前栈上00281c3c之后的00440000赋值给eax,该值作为之后shellcode中寻址的高位地址,最终从此处进入到攻击者控制的流程中。

 

由此可以看到该样本中0798和正常0798的区别之处

  1. 首先正常进行一次0798的漏洞利用,在上布置好后续的shellcode
  2. 之后精心在函数sub_4428f0中构造出一段包含跳板shellcode的内存,并将该段内存作为参数再次调用0798函数。
  3. 再次触发漏洞,通过ret的方式将程序的执行流程定向到之前的跳板shellcode中。

 

总结

如下所示即可看到11882/0802/0798这三个漏洞的混淆点了,对于这三个漏洞,除了绿色1c,*8(11882,0802),*1/*4-*5(0798)不能变,其他位置都是可变的,其中紫色指有要求的变(第一处不能大于0x20000,第二处只能为01(当为01时,metf头由五位变成1位,即之前的后四位去掉),02,03,102,103),当metf为五位时,之后的一位,即第六位实际上是可以导致之后有附加数据的,及下图中的蓝色部分,因此metf头之后和tag头之间也是可以插入混淆数据的。除此之外eqnolefilehdr,mtef head其余位置应该都是可以随便搞的。

之后mtef byte stread中可以插入任意多的tag,只要保证最终进入08,05tag即可,因此在紫色01和绿色08之间也是可以加入混淆数据的(通过0798中的处理或标准流程中11882处理(>9,01,04会进入0798),0798中还依赖dispatch来处理,case0/case1/case5流程中是可以再次进入到0798,如上文的第2,4个样本。

 

 转载请注明出处

转载于:https://www.cnblogs.com/goabout2/p/10201155.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/450233.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

5 个常用的软件质量指标

在软件开发中,软件质量是衡量软件是否符合需求、标准的重要体现。除了 代码质量外,影响软件整体质量的因素还有很多。因此,要确保软件的整体质量,就需要在各个环节严格控制。本文列出了衡量软件质量的5个最常用的指标。1. SLOC&a…

介绍一个对陌生程序快速进行性能瓶颈分析的技巧

前言 工作多年,一直做的是curd系统。前几年做的系统应用场景,大多对数据库依赖比较重。例如报表统计,数据迁移,批量对账等。所以这些系统出现性能瓶颈一般出在数据库操作上面。 如果程序因为数据库操作出现性能瓶颈是比较好办的&a…

掌握穷变富的12条原则 迅速从普通人变成有钱人

“穷忙”和“富闲”是对立面,“穷”对“忙”,“富”对“闲”,很多“穷忙女”是在拿青春当赌注,希望自己今天的“美丽”明天就能在市场上有个不错的“回报”;而多数“富闲女”则是在拿智慧当筹码,既不可替代…

windows下安装和设置gradle

一、安装前检查 检查jdk是否已经安装 二、下载gradle 1. https://gradle.org/releases/ 2.设置gradle环境变量 3. 环境变量中增加名为GRADLE_HOME的变量名,值为Gralde的解压路径,例如D:\Gradle 在path的后追加%GRADLE_HOME%\bin; 4. 验证 5.修改默认缓存目录 修改Gradle默认缓存…

赚大钱一定要选择

赚大钱一定要选择 八大赚钱定律让你赚翻天 许多人看起来已经步入小康了,但他们还说不上是真正的富人,从科学理财的观念看,凭高收入和攒钱来实现富裕的思路完全是错误的,依靠攒钱,不仅多数人无法获得最终的财务自由&…

深解微服务架构:从过去,到未来

http://www.uml.org.cn/zjjs/im... 微服务的诞生 微服务架构(MicroserviceArchitect)是一种架构模式,它提倡将单块架构的应用划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行在其独立…

解决IntelliJ Idea中文乱码问题、修改IDEA编码

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 有两种办法可以修改 IntelliJ IDEA 的文件编码(IDE 版本为 14.1.4) File->Settings->Editor->File En…

前端框架开始学习Vue(一)

MVVM开发思想图(图片可能会被缩小&#xff0c;请右键另存查看&#xff0c;图片来源于网络)定义基本Vue代码结构1 v-text,v-cloak,v-html命令默认 v-text没有闪烁问题&#xff0c;但是会覆盖元素中原本的内容&#xff0c;插值表达式只会替换自己的占位符,<!DOCTYPE html> …

P1616 疯狂的采药(洛谷,动态规划递推,完全背包)

先上题目链接:P1616 疯狂的采药 然后放AC代码: #include<bits/stdc.h> #define ll long long using namespace std; ll f[100010]; ll timee[10010]; ll w[10010]; int main() {ll t,m;cin>>t>>m;//t总时间,m总草药//time时间,w价值for(ll i1;i<m;i){scan…

MySQL通过source命令执行sql文件

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 IT人员经常会和MySQL打交道&#xff0c;备份和恢复应该是最常用的操作了&#xff0c;那么通过直接执行sql文件无疑是最快捷的方式&#x…

MySQL索引底层实现原理

索引的本质 MySQL官方对索引的定义为&#xff1a;索引&#xff08;Index&#xff09;是帮助MySQL高效获取数据的数据结构。提取句子主干&#xff0c;就可以得到索引的本质&#xff1a;索引是数据结构。 我们知道&#xff0c;数据库查询是数据库的最主要功能之一。我们都希望查询…

解决 A component required a bean of ‘XXX.RoleService‘ that could not be found.

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 springboot工程启动报错&#xff0c;无法启动成功。 dubbo订阅服务失败&#xff0c;提示如下&#xff1a; 出错原因&#xff1a;唉&…

配合OAuth2进行单设备登录拦截

2019独角兽企业重金招聘Python工程师标准>>> 要进行单设备登录&#xff0c;在其他地点登录后&#xff0c;本地的其他操作会被拦截返回登录界面。 原理就在于要在登录时在redis中存储Session,进行操作时要进行Session的比对。 具体实现&#xff0c;假设我们的OAuth 2…

C++知识点(六)数组、指针与字符串导学

1.数组 地址连续存放初始化&#xff1a;列出全部初始值后&#xff0c;第1维下标个数可以省略不做初始化&#xff0c;局部变量中为垃圾数据&#xff0c;static变量为0只对一部分进行初始化&#xff0c;其余数值初始化为02.动态内存分配&#xff1a; new delete 3.动态创建数组 n…

钱线观察:货币基金T+0驾到 活期存款将死?

导语&#xff1a;即使没有任何投资风险&#xff0c;通胀也在侵蚀居民的财富&#xff0c;现金是不安全的。最近出现的一项业务&#xff0c;货币基金"T0"赎回&#xff0c;意味着货币基金可以像活期存款一样即时取现&#xff0c;而其收益率普遍高于活期存款。因此有人认…

CentOS 7.0 上安装和配置 VNC 服务器

作为一个系统管理员&#xff0c;大多数时间是通过网络管理服务器的。在管理服务器的过程中很少会用到图形界面&#xff0c;多数情况下我们只是用 SSH 来完成我们的管理任务。在这篇文章里&#xff0c;我们将配置 VNC 来提供一个连接我们 CentOS 7 服务器的方法。VNC 允许我们开…

Mongo DB 简单搭建和部署

1.先下载源代码包 官网下载地址&#xff1a;http://www.mongodb.org/downloads 2.解包tar xf mongodb-linux-x86_64-rhel62-3.2.7.tgz 3.把包移动到 /usr/local/mongodb mv mongodb-linux-x86_64-rhel62-3.2.7/ /usr/local/mongodb 指定同一时间最多可开启的文件数&#xff08…

NSOperation的进阶使用和简单探讨

本文将会从多个方面探讨NSOperation类和NSOperationQueue类的相关内容 一、简介 NSOperation类是iOS2.0推出的&#xff0c;通过NSThread实现的,但是效率一般。 从OS X10.6和iOS4推出GCD时&#xff0c;又重写了NSOperation和NSOperationQueue&#xff0c;NSOperation和NSOperati…

廖雪峰Java1-2程序基础-7布尔运算符

布尔运算符 关系运算符&#xff1a;>&#xff0c; >&#xff0c; <&#xff0c; <&#xff0c; &#xff0c;!与运算 &&或运算 |非运算 &#xff01;int n 5;boolean t n > 0;//trueboolean f n < 0;//falseboolean isFive n 5;//trueboolean i…

第二十一届国际C语言混乱代码大赛结果公布

摘要&#xff1a;国际C语言混乱代码大赛&#xff08;IOCCC, The International Obfuscated C Code Contest&#xff09;是一项著名的国际编程赛事&#xff0c;从1984年开始到2006年&#xff0c;每年举办一次。2006年后中止了多年&#xff0c;2011年又开始恢复。比赛的目的是写出…