zoukankan      html  css  js  c++  java
  • 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内存操作的越界访问。

      

    漏洞利用

    整个漏洞利用思路如下:

    1. vtable维度上使subexternalizable类的vtable和可控MyExt类的vtable相邻
    2. 对象内存维度上使subexternalizable类的对象和MyBy(继承自ByteArray)对象相邻
    3. 触发漏洞修改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地址

     

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

     

     转载请注明出处

  • 相关阅读:
    重新想象 Windows 8 Store Apps (15) 控件 UI: 字体继承, Style, ControlTemplate, SystemResource, VisualState, VisualStateManager
    重新想象 Windows 8 Store Apps (12) 控件之 GridView 特性: 拖动项, 项尺寸可变, 分组显示
    返璞归真 asp.net mvc (10) asp.net mvc 4.0 新特性之 Web API
    与众不同 windows phone (29) Communication(通信)之与 OData 服务通信
    与众不同 windows phone (33) Communication(通信)之源特定组播 SSM(Source Specific Multicast)
    与众不同 windows phone (27) Feature(特性)之搜索的可扩展性, 程序的生命周期和页面的生命周期, 页面导航, 系统状态栏
    与众不同 windows phone (30) Communication(通信)之基于 Socket TCP 开发一个多人聊天室
    返璞归真 asp.net mvc (12) asp.net mvc 4.0 新特性之移动特性
    重新想象 Windows 8 Store Apps (2) 控件之按钮控件: Button, HyperlinkButton, RepeatButton, ToggleButton, RadioButton, CheckBox, ToggleSwitch
    重新想象 Windows 8 Store Apps (10) 控件之 ScrollViewer 特性: Chaining, Rail, Inertia, Snap, Zoom
  • 原文地址:https://www.cnblogs.com/goabout2/p/6209468.html
Copyright © 2011-2022 走看看