CVE-2015-7645 analyze and exploit
Hack team之后adobe和google合作对flash进行了大改,一度提高了flash的利用门槛,CVE-2015-7645作为第一个突破这些限制的漏洞利用方式,可以作为vetect利用方式之后的一个模板,应该是今年最后一篇技术文章了哈哈。
漏洞分析
POC由三个as文件superexternalizable,subexternalizable,externalizable组成。
该漏洞由IExternalizable导致,这个类导出两个函数readExternal和writeExternal,poc创建一个子类superexternalizable继承IExternalizable,并声明对应的readExternal和writeExternal函数。

创建subexternalizable类,该类继承superexternalizable,其中的红框中的triteExternal变量的赋值调用是造成漏洞的关键。

此时当subexternalizable或superexternalizable中存在同名的writeExternal的变量时会触发漏洞,编译的时候不要申明成writeExternal,因为默认编译器是不允许这么写的(野外的该漏洞exploit通过将该同名变量申明在namespace中绕过该编译器的检测)。
在externalizable类里,ByteArray对象在对subexternalizable类进行writeObject操作时(该处为一个反序列化操作,此时会去调用subexternalizable中的writeExternal函数),但是由于avm中的问题,对writeExternal函数的引用被混淆为对应变量writeExternal的引用,从而导致代码混淆可执行,该漏洞也是自adobe对flash中vector的length增加校验并配备隔离堆之后,首个突破次限制的漏洞。

编译好之后将其中的74改成77,即triteExternal->writeExternal.

漏洞触发时的地址如下,熟悉flash的同学可以发现此处实际上为一处对象中的虚函数调用。

下断点bp FlashPlayer+0063a67a,重启windbg之后断下,单步即可。

在avm中通过getproperty获取对应object的Property的类型,如下图所示,其中的getBinding根据属性名字返回对应的bindID,该id低三位表示对应的property类型,其余位表示对应的真正值。

下图为不同id值对应的property。

如下图漏洞触发后调试图所示,在进行sar eax,3这条指令时,此时eax为19a,该值即为对应的writeExternal的id,通过计算A=1010->010,此时可以看到为一个BKIND_VAR的类型,而不是我们需要的method类型。

之后去掉后三位,获取对应的取值,为0x33,通过该值获取method array中对应的writeExternal函数的地址。

之后的触发代码相当于执行call [eax+8],如下图此时由于0x33这个错误的id(注意此处的id是可控的,具体方式就是通过修改superexternalizable中变量的个数,每多一个变量增加一)导致计算的eax出错,call [eax+8]相当于call 0,从而报错。

接下来看看正常版本的情况,如下图所示将触发代码去掉后运行到漏洞触发点时,对应的eax为21。

后三位id标识为1,1=0001->001 BKIND_MOTHED类型,此时为正常的mothed类型。

此时对应的edx即为对应对象的vtable(虚函数列表对象,该对象偏移0x8的位置保存的methods数组保存了不同虚函数对象对应的MethodEnv,如eax所示,MethodEnv对象+0x8的位置保存了MethodInfo对象,MethodInfo偏移0x8的位置保存了该虚函数要调用的函数指针,通过该函数指针最终调用的writeExternal,具体如下图所示)。

对应Methods数组。

对应漏洞的源码如下,漏洞的问题主要在ClassInfo中,一开始获取对应wirteExternal的id时没有对该id的类型进行校验,此时攻击者通过特殊的构造可以导致获取的id值为对应的构造变量writeExternal的id。

之后A类对象在writeExternal函数的真实调用时,该id被用作索引,在MethodEnv中获取对应的函数指针,通过构造的writeExternal变量的id通常很大,从而导致vtable对象的越界,访问到相邻的vtable对象B中的方法中,如果此时B类的对象为攻击者可控,就会导致avm调用该B对象的方法,但是涉及到的内存操作却是A对象的内存,此时如果B类的内存空间远大于A类的话,B类函数的调用就有可能造成A内存操作的越界访问。


漏洞利用
整个漏洞利用思路如下:
- vtable维度上使subexternalizable类的vtable和可控MyExt类的vtable相邻
- 对象内存维度上使subexternalizable类的对象和MyBy(继承自ByteArray)对象相邻
- 触发漏洞修改MyBy中的length

Vtable布局
因此需要触发漏洞的A类(此处使用subexternalizable)的vtable对象和可控B类(此处使用MyExt3)的vtable对象在内存中相邻。如下图为对应的类MyExt3,在该类中包含了三个虚函数f1-f3。

下图为subexternalizable类对象和对应的vtable对象。

下图为MyExt3对象的vtable对象,明显处于低地址可以看到此时MyExt3的vtable对象要比subexternalizable对象的vtable小8个字节(/4=2),即少了两个虚函数,flash中的vtable是以对象的大小在内存中分配的,即大小相同的vtable的在内存中的相邻存储的。

superexternalizable类加对应继承类subexternalizable一共2+3=5个虚函数(要把sub中的三个算上),但是MyExt3中只有3个,因此需要在MyExt3中的增加两个虚函数。
补充之后重新编译,两个虚函数已经相邻了

修改后的代码,MyExt4-7分别继承MyExt3,并补充了增加的两个虚函数。

对应的MyExt4类,5-7类似。

此时再编译运行之后
Subexternalizable的vtable如下为044b6b20。

MyExt3对应的四个子类的对象分别如下,在044b6b60,044b6b80,044b6bc0,044b6be0四个地址

对应的sub myext myext三个vtable对象的内存情况如下,此时在漏洞触发代码调用即会索引044b6b20这个函数指针,如果id过大,就会访问到相邻044b6b80(即MyExt*对应的vtable中),由于id可控,即可控制调用任意的044b6b80中的函数,如下图所示origin函数指针为0455e20,混淆盗用的函数指针为0455fd00,即MyExt3中的f2函数,此时MyExt3类的大小结构就决定了之后如何覆盖相邻的对象。

堆fengshui
现在subexternalizable的vtable对象已经和MyExt3的vtable对象内存相邻了,接下来是让subexternalizable对象的内存和bytearray相邻(主要是vector在19.0.0.193之后就被增加了对应的安全机制),此处是通过将subexternalizable的vtable对象混淆成大空间MyExt3的vtable对象来实现对subexternalizable对象之后的bytearray对象的length修改,从而获取一个全内存读写的bytearray,下图中通过堆fengshui实现将bytearray对象稳定的分配到subexternalizable对象之后。

MyBy1为继承ByteArray之后的类,其中增加的变量主要用于后期的利用和定位。

此时的真实内存如下,可以看到相邻的subexternalizable和MyBy对象。

修改长度
此时vtable维度上subexternalizable的vtable和MyExt3的vtable内存相邻,对象维度上subexternalizable和MyBy内存相邻,混淆发生后,subexternalizable的vtable会被混淆为对应的MyExt3的vtable,即函数调用为MyExt3的vtable,而该函数的this指针却没变,因此此时该函数操作的内存空间是subexternalizable的内存,如果此时MyExt3内中的变量很多,对应函数操作的内存就能大到超过subexternalizable对象的内存空间,从而起到修改MyBy长度的作用。
如下图所示MyExt3中定义大量的uint变量,之后在混淆触发函数f2中对这些变量的操作实际上就已经超出了subexternalizable的内存范围,如下图中f2首先通过MyBy中的标记123,11223344判断位置,之后获取对应MyBy中的buf指针,并将其长度修改为0xFFFFFFF6.

如下图所示即为MyBy的判断指标及对应的bufaddr(通过该地址可以确认这个超长bytearray的位置)。

测试此时的ByteArray的length。

此时获取一个巨大的array。

此时对应的内存如下

此时该处为被修改的MyBy对象,由于在MyExt3中记录了偏移0x44的内容对应的地址,即0448c500的地址A(bufAddre),有了该地址通过减去偏移就可以算出该MyBy的地址04483ca0,及其中对应的a4(下图中0448f641),a5,a6的地址。

打印出的地址

通过该超长的ByteArray,可以访问内存任意地址,注意将infiniteBy设置成小端显示,由ByteArray的问题导致,设置position时需要减去287454020,这个地方导致MyBy的a0值需要被设置成了0。

通过调试确定虚函数及a4变量的地址分别在bufAddr地址-68,和+40的位置。
在externalizable中将trige设置为全局变量

通过设置a0,将position设置为0,这样的话读取的时候就不需要做-11223344的操作了,在GerAddr函数中将infiniteBy中的a4域作为对象容器,以后对于任意的对象只要将其赋值到infiniteBy.a4中,即可对该对象的地址进行读取,GetAddrV0用于读取对应的vector对象中的buf对象(shellcode会保存在该对象中)

此时拥有了全内存读写及对应的对象地址获取的能力之后,即可以对内存中的virtualprotect函数进行搜索,之后的代码可以借鉴HackTeam泄露出来的flash利用代码来实现。
首先按MZ搜索出对应pe文件。

搜索出对应的kernel32.dll

最后找到对应virtualprotect函数

如下图所示获取的virtualprotect函数地址。

CallVP调用virtualprotect将shellcode设置为可执行。
使用的Shellcode会保存在vector中。

获取vector中的content中的指针,即上图中对应的shellcode地址,其实就是获取vector对象偏移1c处的content指针(调试版本和正常版本有所区别),content指针偏移+8的位置即为对应的内容。

运行之后结果如下,此时的shellcode是不可执行的。

首先定义一个PayLoad函数,通过修改该函数的vtable函数实现virtualprotect函数的调用(即将其vtable函数替换为virtualprotect函数即可),如下图所示首先获取该函数对象的地址,之后分别保存对象指针,及vtable指针。

将vtable替换成virtualprotect函数,并设置对应参数(将对应的Payload vector中shellcode的地址,长度传入,可执行标志),调用virtualprotect,最后通过Set将修改的vtable修改回来。

运行之后可以发现此时shellcode获取了对应的执行权。

此时shellcode已经绕过dep,再次通过PayLoad将其vt函数修改为对应的shellcode地址

运行之后,熟悉的计算器。

转载请注明出处
CVE-2015-7645 analyze and exploit的更多相关文章
- 如何确定Ubuntu下是否对某个CVE打了补丁
前些日子在月赛中,拿到了一台Ubuntu14.04的服务器,但并不是root权限,需要提权.我Google了一下,找到了CVE-2015-1318,CVE-2015-1328,CVE-2015 ...
- CVE-2015-1328 Ubuntu 12.04, 14.04, 14.10, 15.04 overlayfs Local Root
catalog . 引言 . Description . Effected Scope . Exploit Analysis . Principle Of Vulnerability . Patch ...
- CVE-2015-1328(本地提权漏洞)
/* # Exploit Title: ofs.c - overlayfs local root in ubuntu # Date: 2015-06-15 # Exploit Author: rebe ...
- linux提权辅助工具(一):linux-exploit-suggester.sh
来自:https://raw.githubusercontent.com/mzet-/linux-exploit-suggester/master/linux-exploit-suggester.sh ...
- billu_b0x靶场刷题
https://www.vulnhub.com/ 里面有很多安全环境,只要下载相关镜像,在虚拟机上面搭建运行就可以练习对应靶场了. 第一步.信息收集 nmap扫描内网开放80端口的存活主机 nmap ...
- How to exploit the x32 recvmmsg() kernel vulnerability CVE 2014-0038
http://blog.includesecurity.com/2014/03/exploit-CVE-2014-0038-x32-recvmmsg-kernel-vulnerablity.html ...
- CVE-2014-0050: Exploit with Boundaries, Loops without Boundaries、Apache Commons FileUpload and Apache Tomcat DoS
catalog . Description . Analysis . POC . Solution 1. Description MultipartStream.java in Apache Comm ...
- 几个 Ceph 性能优化的新方法和思路(2015 SH Ceph Day 参后感)
一周前,由 Intel 与 Redhat 在10月18日联合举办了 Shanghai Ceph Day.在这次会议上,多位专家做了十几场非常精彩的演讲.本文就这些演讲中提到的 Ceph性能优化方面的知 ...
- MyBB \inc\class_core.php <= 1.8.2 unset_globals() Function Bypass and Remote Code Execution(Reverse Shell Exploit) Vulnerability
catalogue . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 MyBB's unset_globals() function ca ...
随机推荐
- 学习CodeIgniter框架之旅(一)自定义模板目录
在常用的框架本身都已经做好了分层和目录结构,但这在很多时候不满足项目的需求甚至在某些情况下变得不合理,因此很多时候需要自定义目录结构,在此就看看如果在CodeIgniter框架中自定义模板目录: 在C ...
- 关于编写性能高效的javascript事件的技术
如何能做出高效的web前端程序是我每次做前端开发都会不自觉去考虑的问题.几年前雅虎里牛逼的前端工程师们出了一本关于提升web前端性能的书籍,轰动了整个web开发技术界,让神秘的web前端优化问题成为了 ...
- Genymotion安装及遇到的问题
https://www.genymotion.com/ 首先注册,不注册看不到下载按钮. 注册登陆后下载安装包(一定要记住用户名和密码,因为安装后登陆要用) 一路下一步. 选择虚拟设备 genymot ...
- RESTful 接口调试分享利器 restc
这个工具来自于https://elemefe.github.io/restc/ 这里对Abp进行了一次封装 1.在项目中添加nuget包 Abp.Web.Api.Restc 2.在项目Abp模块的D ...
- for和foreace的区别
foreach语句是java5的新特征之一,在遍历数组.集合方面,foreach为开发人员提供了极大的方便. foreach语句是for语句的特殊简化版本,但是foreach语句并不能完全取代for语 ...
- php无限极分类以及递归(thinkphp)
php无限极分类: 无限极分类重点在于表的设计: 1在model中: class CatModel extends Model{ protected $cat = array(); public fu ...
- ES5新语法forEach和map及封装原理
### forEach 在es5中提供了forEach方法进行遍历,其实就是模仿了jQuery中each方法,不过将 i 于v进行了调换,下面两种方法进行对比一下 var arr = [ 11, 22 ...
- 为select 设置样式
问题: 在为表单添加下拉菜单时,有时候对菜单的样式没有特别的要求,就是需要修改下select元素的宽度和高度,但众所周知select元素的样式很难修改: select在各个浏览器,字体大小为14px时 ...
- 微信公众帐号开发-消息创建时间long型与标准时间的互相转换
/** * */ package com.hd.admin.wxmeet.utils; /** * @author jymcpp * */ import java.text.DateFor ...
- (转)实现DataList的分页 新增列
前几天在做网上商城,要展示商品信息(有图片,有文字),DataView虽然可以分页,但它的缺点是不能自定义显示格式.而DataList解决了它的缺点,但DataList本身却不能分页.很是头痛,于是在 ...