SPU LS Overflow Exploit

From PS3 Developer wiki
Jump to: navigation, search

From what I can understand, the code that the loaders use to verify the SCE header doesn't check the size before it moves the header into isolated memory.
This means if the right SELF is made, it could replace existing code.
Perhaps:
Make a SELF with a large header, containing arbitrary code at a certain offset
This code would replace a part of a loaders code, meaning we can execute at a higher level.
Finding the right offset to put the code must be the hardest part, as you'd have to figure out where the LS ends and code begins.

[What do you mean with "where the LS ends and code begins"? (as the loader's code is located in the LS)]
Wasn't really aware of that, I guess that means we'd have to dump the LS somehow to find where the code is.

http://pastie.org/1898468


Your shell code would have to overwrite an area of the LS that gets executed. There will be an amount of guesswork as to the offset since we cannot see the code. The code would begin copying areas of the LS into the shared LS, You would need some PPU code to read the shared LS and dump the information. The implementation of this exploit is rather difficult due to the fact we cannot see the code in the first place, and it will not give a clean dump. Admin 16:17, 22 April 2011 (CDT)


So maybe it would be a good idea to first try it with metldr as we can pass our modified loader without having to flash it. Also the SCE header is usually not that big but it needs to be tested to which offset in the LS the data gets copied. If the offset is after the executable code the header will need to be rather big as we are trying to overwrite the code, so the address needs to wrap around to zero IMHO.


Please give your ideas/workings here, I figured using the devwiki would be better than forum threads since they are just full of people wanting a simple solution, lets work together instead.



[edit] How to load METLDR in PlayStation3

After some experiment I succeded to load METLDR in spu isolation. You need geohot's exploit to do this, because you need to turn spu relocation off (MFC_SR1[R]=0) and not let know the HV you are using a SPU (so no calls to lv1_construct_logical_spe or similar). For some strange conf, it doesn't work in HV way.

Here the source code. Enjoy!!!!

Spuisolation.tgz // mirror: Spuisolation.tgz (27.11 KB)

Thks to TitanMKD, Xorloser and Mathieulh.

Here a paste of an userspace metldr loader using xorhack. You need to patch xorhack tools adding read_u32() and write_u32() functions.

 // Turn relocation OFF
  printf("<TURN RELOCATION OFF>\n");
  write_u64(SPU_P1(SPU_CURR)+0x0000, (read_u64(SPU_P1(SPU_CURR)+0x0000) & 0xFFFFFFFFFFFFFFEF�;
  printf("MFC_SR1 = %llx\n", read_u64(SPU_P1(SPU_CURR)+0x0000�;

  // no accesses are to be considered well behaved and cacheable
  write_u64(SPU_P1(SPU_CURR)+0x0900, (u64)0x0);

  // set overwrite mode for signal notification 1/2
  write_u64(SPU_P2(SPU_CURR)+0x4078, (u64)0x0);

  // set signal_notify1 = high metldr real address
  write_u32(SPU_PS(SPU_CURR)+0x1400C, (u32)0x0);

  // set signal_notify2 = low metldr real address
  write_u32(SPU_PS(SPU_CURR)+0x1C00C, (u32)0x11000);


  printf("---> START SPU IN ISOLATION MODE\n");

  // set SPU_PRIVCNTL[LE]=1
  write_u64(SPU_P2(SPU_CURR)+0x4040, (u64)0x4);

  // set SPU_RUNCNTL[Run] = '11'
  write_u32(SPU_PS(SPU_CURR)+0x401C, (u32)0x3);


  for (cx=0; cx<3; cx++)
  {
    // Print SPU_STATUS
    print__spu_status(read_u32(SPU_PS(SPU_CURR)+0x4024�;

    sleep(5);
  }

reference: xorloser blog / geohot blog source: http://www.piemontewireless.net/How_to_load_METLDR_in_ps3

Look at this: http://pastie.org/private/zbypdtxcvtsqypledr47g (decryption of lv2 from graf's payload, it's everything in there, how to load metldr, pass arguments, etc.)