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运行,熟悉的计算器。
转载请注明出处
CVE-2010-3654分析及利用的更多相关文章
- CVE-2014-3153分析和利用
本文是结合参考资料对CVE-2014-3153的分析,当然各位看官可以看最后的资料,他们写的比我好. 在看CVE-2014-3153之前我们用参考资料4中例子来熟悉下这类漏洞是如何产生的: /** * ...
- NSA Fuzzbunch分析与利用案例
Shadow Brokers泄露出一份震惊世界的机密文档,其中包含了多个 Windows 远程漏洞利用工具.本文主要介绍了其中一款工具Fuzzbunch的分析与利用案例 1 整体目录介绍 解压EQGR ...
- FakeID签名漏洞分析及利用(二)
本文转自:http://blog.csdn.net/l173864930/article/details/38409521 继上一次Masterkey漏洞之后,Bluebox在2014年7月30日又公 ...
- word漏洞分析与利用
众所周知,溢出漏洞从应用形式上可分为远程服务溢出漏洞和客户端(本地)溢出漏洞两类.远程服务溢出漏洞大家很熟悉了,红色代码.冲击波.振荡波等蠕虫都利用了此类漏洞,漏洞的调试和利用有相应的一套方法,前面的 ...
- 【转】cve2014-3153 漏洞之详细分析与利用
背景学习: Linux Futex的设计与实现 使用者角度看bionic pthread_mutex和linux futex实现 By kernux TopSec α-lab 一 漏洞概述 这个漏洞是 ...
- Vivotek 摄像头远程栈溢出漏洞分析及利用
Vivotek 摄像头远程栈溢出漏洞分析及利用 近日,Vivotek 旗下多款摄像头被曝出远程未授权栈溢出漏洞,攻击者发送特定数据可导致摄像头进程崩溃. 漏洞作者@bashis 放出了可造成摄像头 C ...
- 【逆向实战】ES文件浏览器未授权访问漏洞(CVE-2019-6447)具体分析及利用
/作者:Kali_MG1937 CSDN博客号:ALDYS4 QQ:3496925334 未经许可,禁止转载/ 漏洞简介 CVE-2019-6447是Android端上的一个知名软件:ES文件浏览器的 ...
- Java练习小题_求一个3*3矩阵对角线元素之和,矩阵的数据用行的形式输入到计算机中 程序分析:利用双重for循环控制输入二维数组,再将a[i][i]累加后输出。
要求说明: 题目:求一个3*3矩阵对角线元素之和,矩阵的数据用行的形式输入到计算机中 程序分析:利用双重for循环控制输入二维数组,再将 a[i][i] 累加后输出. 实现思路: [二维数组]相关知识 ...
- CVE-2016-10190 FFmpeg Http协议 heap buffer overflow漏洞分析及利用
作者:栈长@蚂蚁金服巴斯光年安全实验室 -------- 1. 背景 FFmpeg是一个著名的处理音视频的开源项目,非常多的播放器.转码器以及视频网站都用到了FFmpeg作为内核或者是处理流媒体的工具 ...
随机推荐
- php-fpm启动,重启,终止操作
最近安装了mysqli扩展,重启了nginx后,phpinfo()没有显示出mysqli,后来搞不出原因,直接使用了pdo连接数据库.直到今天安装redis后phpinfo()没有显示redis,内心 ...
- 多个文件下载打包生成zip格式下载
这个多个文件下载生成zip格式必须先引用一个ICSharpCode.SharpZipLib.dll. 代码如下 //将多个文件打包成压缩文件zip格式下载 protected voi ...
- windows7设置开机启动方式
打开计算机(资源管理器)(快捷键win+e),输入 C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup 将需要开机启动的软件的快捷 ...
- [BZOJ3223]Tyvj 1729 文艺平衡树
[BZOJ3223]Tyvj 1729 文艺平衡树 试题描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区 ...
- js基础总结
DOM 节点 document节点 nodeType:9 文本节点 nodeType:3 元素节点 nodeType:1 注释节点 nodeType:8 属性节点 nodeType:2 at ...
- bzoj4691: Let There Be Light
如果原点能被一个光源照到,那么这两个点之间一定没有任何球.我们可以通过三分距离来确定某线段和球是否有交点. 注意到m非常小,于是我们可以枚举原点被哪些光源照到.由于\(O(2^{n}*m)\)会超时, ...
- mysql 查询表结构
use information_schema; select column_name, column_type, data_type, is_nullable, column_comment from ...
- powershell批量设置权限
批量设置权限 $acl=get-acl .\demo Get-ChildItem .\Documents -Recurse -Force|Set-Acl -AclObject $acl
- 数据库如何生成sql语句
以SQL SERVER 2008为例子. 1.启动客户端管理器,连接到要生成脚本的数据库. 2.在左边的”对象资源管理器“中,右键选择该数据库打开菜单.选择”任务“,”生成脚本“菜单,打开对话框. 3 ...
- 使用ajaxfileupload.js实现上传文件功能
<div class="pictureList"> <div class="pictureItem" id="uploadItem& ...