6 ways to crash the wipeout browser...

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

tmbinc
Posts: 6
Joined: Mon May 30, 2005 6:25 pm

6 ways to crash the wipeout browser...

Post by tmbinc »

Hi,

I noticed the following ways to crash the wipeout browser:

1.) "<div>" * (large number, > ~500). you can use every other tag as well.

The html parser seems to be recursive. At least this slows down the parsing process until it finally crashes.

No big deal, i think, i don't think it can be exploited (but hey, people always told this and a month later, machines get rooted.)

2.) <a href="proc://buttons/http://bla?bla">CRASH ME</a
3.) <a href="proc://exists/http://bla?bla">CRASH ME</a
4.) <a href="proc://sound/http://bla?bla">CRASH ME</a

Looks just like some stupid *strchr(buffer, '<any-nonexisting-char>') =0; (which is damn stupid, yes, but doesn't look too exploitable, too.)

5.) "<" + '(any char)' * 1024

This looks more interesting. The crash boundary is exactly 1024 characters, which makes me feel that the developers of the wipeout browser are indeed damn stupid.

and finally my favourite one:
6.) "<a href="proc://upload/profile:http://?" + 'a' * ~980 + "">CRASH ME</a>"

this one seems to be related with the "%s&upload=profile&value=all&uid=%s" format string. No, they didn't used snprintf. How stupid.

Anyway, i tried something like "http://?" + "\xfc\x23\x91\x88" * (256+16) which should end up at 089123fc, which should be a "jr $ra" (can somebody please check this? i was told that game load to 08900000, and as \x08 seems to cause problems while parsing, i set the MSB. Is this valid for code like for data addresses, too?), and it didn't worked as expected (expected behaviour: "sounds continues, browser hangs", experienced behaviour: "like any other crash - sound hangs, browser hangs"). I don't have a bright idea anymore.

I've spent some disassembling the corresponding functions, but i couldn't find something i'm doing wrong. The buffer in question should be 0x400 bytes, plus 0x20 bytes of variables which are only touched after the sprintf(), and then the return address. So sending 0x420 bytes junk and the the return address should do it. Well, it doesn't.
KiWi
Posts: 13
Joined: Thu Mar 10, 2005 8:21 am

Post by KiWi »

Yo tmbinc !

Nice to see you joining from Gamecube development to PSP development ...

Finding overflows in the Wipeout browser is not the time worth for doing research. I personally think it's easier to find an overflow in the build in media player routines (jpeg viewer, mp3 player, mp4 player etc.)

It would also be more comfortable to turn on the psp and starting code over the build in viewers than booting wipeout from umd and typing hundreds of chars into the url line ...
Regards,

KiWi

Germany's largest Console Community : www.gamefreax-forum.de
placasoft
Posts: 53
Joined: Mon Mar 28, 2005 10:53 am

Post by placasoft »

What does ""proc://exists/" do?
tomt
Posts: 12
Joined: Mon May 23, 2005 8:36 pm

Post by tomt »

sounds very promising for a buffer overflow :)

i have a few questions:

if the wipeout code is encrypted how do you decompile it?

and more generally when doing buffer overflows on console games, i was just thinking.. you must have to unregister all the callbacks the game has to be properly in control of the system right? is that what you meant by the sound continuing?

also surely its better to have a buffer overflow in a game that sony cant easily patch, rather than the firmware which most likely wont work anymore once it is updated, i think this direction is a very good idea.
tmbinc
Posts: 6
Joined: Mon May 30, 2005 6:25 pm

Post by tmbinc »

KiWi: i choosed the first thing which i had some binaries for, and that was wipeout. exploiting something without having binaries sounds nearly impossible for me, at least when doing stack-based overflows where you have to know the return-addr.

Sure an exploit in something else would be better, but at least i don't have any access to the binaries of the loader.


placasoft: Honestly, i don't know. I grepped through the binary, and found it.

tomt: The available rip contains EBOOT.BIN which is encrypted and BOOT.BIN which is unencrypted. I don't know for sure if this executable matches the one on my wipeout disc, but especially the 6.) behaves like i expected that from the code.

About the "sound-or-not":

The sound is played in one thread, the browser works in another thread.
Now, if a thread crashes, the whole game crashes. The exception handler probably halts the whole system (?). If some thread, however, would loop infinite, the other threads should continue. Thus, the sound should continue, while the browser hangs (but not crashes).

As said, it didn't worked. Maybe because i have to jump to 08xxxxxx and can't set any other bits? Sorry i'm not too familiar with this kseg-stuff. Can anybody enlighten me?

Or the binary is just a little bit different than the one on my disc (japanese vs. US?)

Does anybody know how to place something in the memory at a known location?
placasoft
Posts: 53
Joined: Mon Mar 28, 2005 10:53 am

Post by placasoft »

tmbinc wrote: placasoft: Honestly, i don't know. I grepped through the binary, and found it.
In which binary do you found this?

THX
tomt
Posts: 12
Joined: Mon May 23, 2005 8:36 pm

Post by tomt »

thanks for the info :)

i have the us wipeout, i'll test it if you like (if i get time)
GeKKo
Posts: 9
Joined: Mon May 16, 2005 9:13 am

Post by GeKKo »

The 1. Way doesn't work for me : /.

Hey placa man sieht dich so selten auf pg.de :|
djhuevo
Posts: 47
Joined: Thu Mar 10, 2005 3:50 pm

Post by djhuevo »

tmbinc wrote:and finally my favourite one:
6.) "<a href="proc://upload/profile:http://?" + 'a' * ~980 + "">CRASH ME</a>"

this one seems to be related with the "%s&upload=profile&value=all&uid=%s" format string. No, they didn't used snprintf. How stupid.

Anyway, i tried something like "http://?" + "\xfc\x23\x91\x88" * (256+16) which should end up at 089123fc, which should be a "jr $ra" (can somebody please check this? i was told that game load to 08900000, and as \x08 seems to cause problems while parsing, i set the MSB. Is this valid for code like for data addresses, too?), and it didn't worked as expected (expected behaviour: "sounds continues, browser hangs", experienced behaviour: "like any other crash - sound hangs, browser hangs"). I don't have a bright idea anymore.
tmbinc: the homebrewed ELFs are statics and load to 0x08900000, but how can be you sure at all that the game load to 0x08900000 if the ELF is relocatable?
sobreviviendo en la tierra de los trolldev
placasoft
Posts: 53
Joined: Mon Mar 28, 2005 10:53 am

Post by placasoft »

GeKKo wrote:The 1. Way doesn't work for me : /.

Hey placa man sieht dich so selten auf pg.de :|
lol....komm lieber mal in mein eigenes Forum...pg.de wurde mich zu dumm -.-

In which binary do you found this? @ TMBINC
Erant
Posts: 33
Joined: Fri May 13, 2005 6:19 am

Post by Erant »

placasoft wrote:
GeKKo wrote:The 1. Way doesn't work for me : /.

Hey placa man sieht dich so selten auf pg.de :|
lol....komm lieber mal in mein eigenes Forum...pg.de wurde mich zu dumm -.-

In which binary do you found this? @ TMBINC
I'm guessing he found it in Wipeout Pure's BOOT.BIN.
Live free, prosper, and under my rule.
tmbinc
Posts: 6
Joined: Mon May 30, 2005 6:25 pm

Post by tmbinc »

With help of #pspdev i was able to continously call "sceKernelSleepThread", so sound continued but browser crashed. yay.

The binary is in fact loaded to 08900000. That location seems to be "static", it isn't randomized or so.

Next big task is to place some more interesting code somewhere where we know the memory address of. I haven't succeeded here for now.

Damn, i wish i had a ramdump of the running game...
0xdeadface
Posts: 62
Joined: Tue May 31, 2005 5:11 am

Tres promising

Post by 0xdeadface »

If you managed to call the KernelSleepThread, how did you achieve that?
If you'd like to share please do :) but if not - Wouldn't it simply be possible to place your own code in the data you pass (except you'll have a pain to code it in such a way that it only uses allowed bytes)? That's at a known address (program counter - xx) which you can stuff in ra and jump to?

0xdf
Shine
Posts: 728
Joined: Fri Dec 03, 2004 12:10 pm
Location: Germany

Re: Tres promising

Post by Shine »

0xdeadface wrote:If you managed to call the KernelSleepThread, how did you achieve that?
perhaps by overwriting the return address, which is stored on stack.

@tmbinc: which disassembler did you use and how did you find the functions which parses the URL?
tmbinc
Posts: 6
Joined: Mon May 30, 2005 6:25 pm

Post by tmbinc »

0xdeadface:

I overwrote the return address with the address of the sceKernelSleepThread function (or better, the wrapper).

Yes, i could pass my own code, but the problem is finding it in memory. I don't know where the stack is located nor any other place where i can upload code to. The only thing i know is that the binary itself is loaded to 08900000.

Basically only .data or .bss are fixed in memory, and i wasn't able to find anything useful which i could do to have specific data loaded there.

Making some "shellcode" which only contains allowed bytes is probably difficult but not impossible. so far i wrote some "put-something-to-vram" which doesn't have any nullbytes - but still, i don't know where i have to jump to.

@shine:

IDA Pro, as always. I'm a lucky employee who could convince his company that this piece of software is "absolutely required for my work". And well, it is. :)

Finding the stuff is easy. Just search for some sprintf()-like format strings, and look how they are used.

Or search for stack frames in the range of ~1kb or so (just search for the "addiu $sp, -0x400...0x500" or whatever - some binary wildcarding does it fine). That gives you a lot of interesting functions.
0xdeadface
Posts: 62
Joined: Tue May 31, 2005 5:11 am

Post by 0xdeadface »

"deleted....forgot to think*

0xdf
chaos
Posts: 135
Joined: Sun Apr 10, 2005 5:05 pm

Post by chaos »

is the location random? or would it be the same place every time?

if it was fixed, and you could put enough nops in front of it, it would be possible to generate a batch of say 1000 possible locations..

i'm sure we could find enough volunteers to try them fairly quickly..
Chaosmachine Studios: High Quality Homebrew.
LiquidIce
Posts: 55
Joined: Mon Apr 04, 2005 1:15 am
Contact:

Post by LiquidIce »

Yes, you have one volunteer here with his PSP booted into the Wipeout browser, ready to test. Let me know what I need to do, and it shall be done.

Sounds like you guys might be on to something here.
Shine
Posts: 728
Joined: Fri Dec 03, 2004 12:10 pm
Location: Germany

Post by Shine »

tmbinc wrote:With help of #pspdev i was able to continously call "sceKernelSleepThread", so sound continued but browser crashed. yay.
Are you sure that the kernel function was called? Freezing the browser is a known issue, see this topic. How does your URL look like? Perhaps with some JavaScript we can write some bytes, which cannot be parsed.
0xdeadface
Posts: 62
Joined: Tue May 31, 2005 5:11 am

Stack

Post by 0xdeadface »

tmbinc,
While I assume you already have done this, have you checked where with your own (meaning any homebrew) app the stack lies?
It'd be kinda safe to assume that the stack at that moment of crashing can't be *that* far away from that address. Surely it'll be a tad deeper, but most likely in the order of bytes, not Kb's.

If you have determined how long the string is you can pass (both before the jump address and after it you should be able to inject different fragments of code to and some cleverly guessed jump addresses to figure out where your stack lies exactly at that moment in time?

This is, by the way, assuming that the crash happens in usermode code. I don't know whether kernel code uses it's own stackspace.

Unfortunately I have no WipeOut....might want to get that :)

0xdf
(edited to make one thing a bit more readable'
Shine
Posts: 728
Joined: Fri Dec 03, 2004 12:10 pm
Location: Germany

Post by Shine »

tmbinc wrote: Does anybody know how to place something in the memory at a known location?
Perhaps loading an image could work. If the graphics mode has no unused bytes, like 3 bytes for true color per pixel instead of 4 bytes, then you can load a true color PNG image in the browser. But I don't know, if it is possible to execute code in VRAM.

Ok, now some code which may help to write arbitrary bytes on the stack:

Code: Select all

<center>"<a href="proc&#58;//upload/profile&#58;http&#58;//?x">CRASH ME</a>" 
<script> 
/* use this for dumping
var properties = ""; 
for &#40;var property in document.links&#91;0&#93;&#41; 
  properties = properties + property + "=" + document.links&#91;0&#93;&#91;property&#93; + "<br>"; 
document.write&#40;properties&#41;; 
*/
// 0x9ACE131E,sceKernelSleepThread 
call=unescape&#40;"%u131e%u9ace"&#41;; 
big="";
for &#40;i = 0; i < 272; i++&#41; big = big + call; 
document.links&#91;0&#93;.href="proc&#58;//upload/profile&#58;http&#58;//?" + big;
</script> 
But it doesn't work on my PSP. It crashs on clicking the link and doesn't call sceKernelSleepThread.
tmbinc
Posts: 6
Joined: Mon May 30, 2005 6:25 pm

Post by tmbinc »

You need to put the address of sceKernelSleepThread, not the ID. the address would be 0x08a39360. otherwise it would work, though i didn't tried with javascript. i had to use 0x48a39360 because 0x08 wouldn't be parsed, but maybe you have more luck with javascript!

i used Wipeout-USA (is there another version?)

0xdeadface: the problem is that each thread allocates a new stack, most threads have stack sized of ~64k. this gives a rather large space to search :/
0xdeadface
Posts: 62
Joined: Tue May 31, 2005 5:11 am

Post by 0xdeadface »

tmbinc,

Have you already determined the correct position in the string where the return address should be placed?

I wonder how many bytes you can get stuffed behind it...it would, in case of a bruteforce search, at least limit the search space

I know it´d be a ridiculous venture but......if all else fails.....

0xdf
tmbinc
Posts: 6
Joined: Mon May 30, 2005 6:25 pm

Post by tmbinc »

Shine: i'm sorry, i wasn't able to get this to work with javascript. try a static file.

anyway, i think call= "\x60\x93\xa3\x48"; should do it (or does it produce unicode crap?), but it doesn't. or should unescape() work around something?
Galfpart
Posts: 9
Joined: Wed Jun 01, 2005 8:32 pm

Post by Galfpart »

tmbinc, nice work so far.

tmbinc:
have you tried looking for a byte sequence in the wipeout
binary which will form an opcode to copy the current stack pointer
into the Program counter/ Instruction Pointer ?

something like

MOV PC, SP (ARM equivalent)

or

PUSH ESP (IA32 equivalent)
RET

From there you can continue your experiments ;-)

This might work, depending on the layout of the stack.


i'd love to try it out myself but i don't have a psp ;-)
any sponsors around ? ;-)

cheers
tomt
Posts: 12
Joined: Mon May 23, 2005 8:36 pm

Post by tomt »

i was thinking about this the other day but i didnt post it because i thought it was too dumb

but if you have a vague idea where the stack is you could just put it the return address, and then a huge list of no ops (like several K), followed by your code.

that way as long as the return address is within the list of no ops, it should just run all the way down them to your code, so you dont have to hit the first instruction spot on.

if you cant encode the no op instuction (does mips even have one?) you could always just put a huge list of adds that wont have any effect other than adding lots to a register
pixel
Posts: 791
Joined: Fri Jan 30, 2004 11:43 pm

Post by pixel »

Galfpart wrote: MOV PC, SP (ARM equivalent)

or

PUSH ESP (IA32 equivalent)
RET
That'd be

Code: Select all

jr $sp
for mips...
if you cant encode the no op instuction (does mips even have one?) you could always just put a huge list of adds that wont have any effect other than adding lots to a register
And that's the dword 0.
pixel: A mischievous magical spirit associated with screen displays. The computer industry has frequently borrowed from mythology. Witness the sprites in computer graphics, the demons in artificial intelligence and the trolls in the marketing department.
Galfpart
Posts: 9
Joined: Wed Jun 01, 2005 8:32 pm

Post by Galfpart »

pixel, what'd be the opcode sequence of that instruction ?

thanks in advance
pixel
Posts: 791
Joined: Fri Jan 30, 2004 11:43 pm

Post by pixel »

http://wiki.nobis-crew.org/PlayStation/r3000

There's all the ressources you need to encode the instruction yourself, and even more of them. jr $sp would be 0x03a00008
pixel: A mischievous magical spirit associated with screen displays. The computer industry has frequently borrowed from mythology. Witness the sprites in computer graphics, the demons in artificial intelligence and the trolls in the marketing department.
Galfpart
Posts: 9
Joined: Wed Jun 01, 2005 8:32 pm

Post by Galfpart »

Thanks!

the bad news:

Searching down CASE-INSENSITIVELY for binary string 08 00 a0 03...
Search failed.
Command "AskBinaryText" failed

Gotta have a deeper look...

edit:

as MIPS processors have a lot of registers, there may be more
than just one register pointing to the stack. maybe someone is lucky
and can find any register pointing into his "shellcode". what does
the psp do when it crashes?
i want a coredump ;-)
Last edited by Galfpart on Wed Jun 01, 2005 11:38 pm, edited 1 time in total.
Post Reply