CVE-2010-3654分析及利用

三年前分析的一个漏洞,最近又温习一遍,这个flash中混淆漏洞的鼻祖,10年最经典的漏洞。

漏洞触发原因

该漏洞主要因为avm对返回的类没有进行校验,通过修改swf文件,实现Ref类和Origin类的混淆。

Poc如下,可以看到poc一共由三个类组成:

PoC_Main

Original_Class

Real_Ref_Class

PoC_Main类中首先初始化Real_Ref_Class类,之后调用Original_Class的static_func1方法,该方法会返回一个Original_Class对象,并通过该对象调用方法normal_func1()

Original_Class中包含两个方法,static_func1,返回一个Original_Class对象,normal_func1,不做任何操作

Real_Ref_Class类中包含一个函数func1,该函数返回一个uint类型的变量。

漏洞实际上上将对类Origin_Class的操作混淆成对Real_Ref_Class类的操作,为了达到这个效果,需要修改编译好的swf文件。

将上图中的070102修改成070103,实际上就是修改了avm运行时需要使用到的编号。

运行样本之后,flash崩溃,windbg断下结果如下,可以看到在mov操作的时,eax中的值为41414141,该地址非法,从而导致崩溃,而41414141正是我们可控的数据,崩溃不远处正好有call eax可以导致程序执行,而导致漏洞触发的地址位于寄存器eax中,通过反编译窗口可以发现eax来自于04c1ff9a地址的call eax这个函数。

直接在返回地址下断,重新加载运行,连续断下五次之后,进入对应的call eax,在函数快返回时,调用指令call edi,该函数最终会返回41414141

如下图所示:

实际上此处下断的函数call eax即为Poc_Main中语句var obj:Original_Class = Original_Class.static_func1()对应的jit代码,但此时由于swf的修改导致Original_Class.static_func1()这句代码中的Original_Class变成了Real_Ref_Class。

 

通过修改可以导致Main在实际的调用过程中将Real_Ref_Class误以为Original_Class,由于avm虚拟机的工作机制,导致main中的处理都是基于Original_Class类生成的,故而Original_Class中函数的返回类型决定了Main可以接受什么样的类型,如Original_class中的函数A返回uint,Main就必须接受uint的类型,但是此时如果Real_Ref_Class中的对应A返回为一个String的话,Main就会将这个String当做uint对象处理。

泄露基地址

修改poc将var obj:Original_Class = Original_Class.static_image();修改为

var obj:uint = Original_Class.static_image();

由于main中的接受的类型变成了uint,因此Original_Class对应返回的类型也要修改成uint,因为Original_Classs虽然被替换了,但是其决定了对应的调用返回的类型。

此时在Real_Ref_Class中修改代码,将string换成一个ByteArray对象。

这样的结果就是在Main函数中我们通过漏洞将一个ByteArray的对象当做uint对象来处理,正常情况下这样的做法在编码上是无法通过的,在Main中直接调用uint的方法toString即可获取ByteArray的地址,如下图所示:

此时我们获取了该ByteArray的地址,通过该地址我们可以尝试获取flash player的基地址,从而绕过aslr,下图即为生成的ByteArray在内存中的对象在Bytearray+10+10的位置即为对应的内容,如此处的41414141,为我们ByteArray中的内容。

而01eb4f40处的值00572310即为对应的虚函数,该地址在flash player中的偏移是固定的,获取该值,通过简单的数学运算即可获取对应的基址,此处需要涉及到一个问题,如何读取01eb4f40中的虚函数值。

这就需要用到ascript中的Number类,通过new Number(address)即可进行读取,但是对于Number来说只接受整形对象的参数,此时就需要再次出发该漏洞将我们的uint类型混淆成整形对象(前面获取ByteArray的时候实际是将ByteArray混淆成了uint)

对于actionscript中的所有变量都是一个32位的对象,其中末四位决定了该对象的类型,如下图所示。

如此处我们生成的ByteArray第地址就是01eb4f41,最后一个为001,即一个object类型,而我们的目标是将其混淆为110类型。

如下图所示首先触发漏洞获取ByteArray对象,将该地址与&0xFFFFFFF8做预算,将末尾的类型标志去掉,由于此时为uint,通过toString函数将其装换成String对象,再次出发漏洞,将其混淆成整形对象,之后通过Number读取对应的值。

Real_Ref_Class中定义函数static_strToint,该函数接受一个String类型的参数,并即将其的做|0x000000007操作,目的是转换成以110为结尾的整形对象。

在Origin_Class中定义对应的伪函数,我们知道该类中的函数返回值决定了Real_Ref_Class中的真实类型,由于此处希望按Real_Ref_Class中static_strToint定义的整形返回,因此此处在Origin_Class中不定义返回的类型 ,这样Main就默认接受调用函数返回的类型。

运行之后,泄露出的地址如下。

这样通过读取ByteArray的虚函数地址,即可获取对应的flash player基址,通过读取ByteArray+10的地址,即可获取对应的shellcode的地址(将shellcode部署到ByteArray中)

在Main中,获取bytearray中的shellcode地址。

整个ByteArray的内存详细结构如下。

最后泄露出的flash player基址,shellcode地址如下。

控制eip

漏洞触发时会eax+0x48指向的指针

修改代码,在指向bytearray内容的指针前填充64长度的字符,这样触发时即可获取eip的执行权。

修改main中的代码,假设需要执行的shellcode的指针为eip,

执行之后如下,获取对应的地址call [41424344]。

构建dep

此时通过漏洞获取了flash的基址,获取了可执行权限,获取shellcode的地址,通过获取的基址可以构建rop链来绕过dep,这样每次利用运行时获取对应的基址,之后更新rop链的地址即可绕过aslr的限制,理论上可以直接通过mona生成dep链,但是这个地方有一个需要注意的地方就是,和一般的栈溢出不同,我们的dep链在bytearray中,而bytearray对象在堆上,这就导致rop链中gaaget模块连接起来的重要引出esp不存在了,本质上rop就是利用ret指令会直接将esp中的内容放到eip执行来使整个rop链运行起来,如下图所示:获取eip时esp为001be2fc,而实际可控的bytearray的内容在0247f000中,为此需要调整esp,使其指向rop的地址,为rop链制造可运行的“堆栈”环境。

此时一般最直接的方式其实是xchg指令,直接通过该指令交换esp,和ecx的值(触发时ecx正好指向我们可控的bytearray中shellcode的地址),通过mona进行指令的搜索,发现12条指令,但是并不是所有指令的可以使用这个地方的指令其实是有一个要求的,即交换之后esp需要进行加操作,因为本身xchg指令是有长度的。

经过挑选之后选择的交换gatage为以下,可以看到此处有一个add esp,8的操作,注意此处我们的gatage并不会运行到ret,而是会在add esp,8之后进行一个jmp操作,可能会问,为什么不找直接ret的gatage,没办法,这条是唯一可行的了。

由于此处是jmp,我们需要到00d99460的地方去看看是否有ret,运气不错,虽然jmp了一下,但是00d99460位置只有三句指令,这个地方也需要注意,eax来自esp+14的地址,即我们可控的位置,在00d99460的指令序列中有一个and [eax+24],0EFFFFFFF操作,这里需要保证[eax+24]这出的地址可写可读,写了个脚本跑了下flash的地址空间,发现没有类型的地址

因此此处直接选了一个第地址的50f78,可以看到改地址+24的地方的内存属性可读可写。

这样重新调整过esp的值之后就可以构造rop链了,首先搜取指令用于对virtualprotect函数参数进行布置,搜索的指令如下。

为什么按这样的指令序列进行搜索,直接来看看flash中virtualprotect函数调用,即可发现原因了。

整个rop链如下:

在Real_Ref_Class中定义函数ropfordep,该函数接受flash player的基址和shellcode,之后按上述的结构将rop中的地址更新。

同样编写shellcode函数,该函数保存对应的calc的shellcode,此处注意编码,ByteArray是小端机的排序,所以和内存中的shellcode是相反的,当然你也可以把这个地方的ByteArray在返回的时候转成String,这样的的话就和内存中一致了。

Real_Rel_Class中对应的伪函数。

调试运行,进入rop链中

此时esp设置成功。

堆栈调整之后,esp执行堆上对应的ByteArray中的rop链

参数布置

此时shellcode只有读写权。

调用virtualprotect,将shellcode的地址设置为可执行。

运行之后,shellcode可执行

Calc运行,熟悉的计算器。

转载请注明出处

时间: 2024-11-05 12:31:44

CVE-2010-3654分析及利用的相关文章

开源项目成熟度分析工具-利用github api获取代码库的信息

1.github api github api是http形式的api,功能还是比较丰富的,博主因为项目的原因主要用到的是提取project信息这项功能,返回的数据是JSON格式. api页:https://developer.github.com/v3/ Options: (H) means HTTP/HTTPS only, (F) means FTP only --anyauth Pick "any" authentication method (H) -a, --append Ap

丘成桐大学生数学竞赛2010年分析与方程个人赛试题参考解答

1 (1)Let {xk}nk=1?(0,π) , and define x=1n∑k=1nxi. Show that ∏k=1nsinxkxk≤(sinxx)n. Proof. Direct computations show (lnsinxx)′′=(lnsinx?lnx)′′=?1sin2x+1x2<0, for all x∈(0,π) . Thus lnsinxx is a concave function in (0,π) . Jensen's inequality then yiel

NSA Fuzzbunch分析与利用案例

Shadow Brokers泄露出一份震惊世界的机密文档,其中包含了多个 Windows 远程漏洞利用工具.本文主要介绍了其中一款工具Fuzzbunch的分析与利用案例 1 整体目录介绍 解压EQGRP_Lost_in_Translation-master.zip文件(下载地址:https://github.com/x0rz/EQGRP_Lost_in_Translation).总共包含三个目录: 1. windows目录针对Windows操作系统的利用工具和相关攻击代码: 2. swift目录

IE UAF 漏洞(CVE-2012-4969)漏洞分析与利用

简介 首先这是一个IE的UAF的漏洞,由于IE 6至9版本中的mshtml.dll中的CMshtmlEd::Exec函数中存在释放后使用漏洞,可导致任意代码执行. 本文包含了分析与利用,包含了对象的申请,对象在何时释放,什么时候被占位等,在漏洞利用方面,metasploit生成的exp的heap Spray有点难看,就自己根据自己的经验写了exp 实验环境 Windows 7 Sp1 32位 IE 8 windbg IDA mona 漏洞分析 获得exp(poc) 搜了一下metasploit那

【转】cve2014-3153 漏洞之详细分析与利用

By kernux TopSec α-lab 一 漏洞概述 这个漏洞是今年5月份爆出来的,漏洞影响范围非常广.受影响的Linux系统可能被直接DOS,精心设计可以获取根权限.该漏洞主要产生于内核的 Futex系统调用.Futex是快速用户空间mutex的意思,它是glibc中的互斥量实现的基础.内核空间其实只是提供了很简单的futex接 口,futex函数定义在/liunx/futex.c中,漏洞利用了 futex_requeue,futex_lock_pi,futex_wait_requeue

Vivotek 摄像头远程栈溢出漏洞分析及利用

Vivotek 摄像头远程栈溢出漏洞分析及利用 近日,Vivotek 旗下多款摄像头被曝出远程未授权栈溢出漏洞,攻击者发送特定数据可导致摄像头进程崩溃. 漏洞作者@bashis 放出了可造成摄像头 Crash 的 PoC :https://www.seebug.org/vuldb/ssvid-96866 该漏洞在 Vivotek 的摄像头中广泛存在,按照官方的安全公告,会影响以下版本 CC8160 CC8370-HV CC8371-HV CD8371-HNTV CD8371-HNVF2 FD81

PCMan FTP Server缓冲区溢出漏洞分析与利用

简要介绍 这个软件是台湾国立阳明大学医学系的一个学生在大四的时候写的,这个漏洞是有CVE的(CVE-2013-4730),软件应该还挺普及的,这是一个缓冲区溢出漏洞 具体exp可以点这里 实验用poc(其实这里直接对USER命令溢出都是可以的,即不用知道账号密码即可远程代码执行,USER命令的buf距离返回地址是2000) import socket as s from sys import argv # if(len(argv) != 4): print "USAGE: %s host <

CVE-2015-7645分析及利用

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

DVWA系统之21 存储型XSS分析与利用

存储型跨站可以将XSS语句直接写入到数据库中,因而相比反射型跨站的利用价值要更大. 在DVWA中选择XSS stored,这里提供了一个类型留言本的页面. 我们首先查看low级别的代码,这里提供了$message和$name两个变量,分别用于接收用户在Message和Name框中所提交的数据.对这两个变量都通过mysql_real_escape_string()函数进行了过滤,但是这只能阻止SQL注入漏洞. 可以看出,在low级别下,Name和Message这两个文本框都存在跨站漏洞,但是由于D