[Tutorial] Packets - Sniffing and Analysis

On domingo, 12 de septiembre de 2010 0 comentarios

Packets - Sniffing & Analysis


A little bit old tutorial but it covers basic aspect of packet analyzing by WPE and general game Tool. Will be suitable for beginners

1. What do you need?
Well at first you need the following things:
  • WPE (Winsock Packet Editor)
  • Any calculator
  • A Hex-Editor, or notepad

2. First arrangements
Start WPE and go to View -> Options and change the settings for "Winsock 2.0" like this :

Image

Why? Because if the app you will sniff packets on is using Winsock 2.0 WPE will capture them. Since as for default the winsock 2.0 settings are disabled in WPE.

Start the Windows Calculator and change it to "Scientific" so you'll be able to deal with hexadecimal stuff.

3. Sniffing Packets

Let’s sniff some Packets.
Start any app, e.g.Opera. Now start WPE and select the Internet Explorer Process.

Click on the "Target program" button. Image
And select the opera.exe. Now we can start the sniffing clicking this button: Image
Now let’s navigate the Opera to "www.google.com".

Ok now check the Gauge-Window to see if WPE really captured some packets.
So after the page fully loaded my Gauge looked like this:

Image

This doesn't have to be the same for all of you, it can vary.

Now we can stop the sniffing using the red Stop-Button Your WPE should now look like this:

Image

Of course it doesn't have to look exactly like this. So this is where you can view the captured packets. I guess this is enough with sniffing, I guess you could sniff all apps, games or whatever you want now.

4. Analyzing Packets
4.1 The Structure


Well as for my examples I will use a fictive game. Since this should be an universal tutorial and not only for one game. Please consider that I can't write this tutorial for all games/apps and for all packet structures there are on earth, just try to do it yourself.

Well let’s say we have a game called "SomeGameOnline". We start the game and wait for the login screen to appear. Now we start our WPE application and select the "SomeGameOnline.exe” and start sniffing packets.

Let’s try to log in with "myusername" as username and "mypassword" as password. Ok this username does not exist in our game and is not ours but we will use it to test the packets.
Now stop the sniffing process and look at the first packet which was sent from the client to the server.

Our packet should look like this:
(in WPE you will see the packet in HEX-Mode on the left, and the same packet in ASCII-Mode on the right side)

22 00 11 00 6D 79 75 73 65 72 6E 61 6D 65 00 00 00 00 00 00 6D 79 70 61 73 73 77 6F 72 64 00 00 00 00 00 00

(i write it with spaces between every hex value so its easier to read)

So what do we know? We used the username "myusername" and the password "mypassword" and WPE tells us our packets size is 36.
Now let’s check the bytes. When working with bytes you have to know that there’s a reversed byte order for values... means...

Quote:
Little-endian - of a computer, storing the most significant byte of a multibyte number at a higher address than the least significant byte; that is, "little end" first.
Big-endian - of a computer, storing the most significant byte of a multibyte number at a lower address than the least significant byte; that is, "big end" first.

Endianness in networking
Many network protocols may be regarded as big-endian in the sense that the most significant part (at the bit and/or byte-levels) is sent first. The telephone network, historically and presently, send the most significant part first, the area code; doing so allows routing while a telephone number is being composed. The Internet Protocol defines a standard network byte order used for all numeric values in the packet headers and by many higher level protocols and file formats that are designed for use over IP. The Berkeley sockets API defines a set of functions to convert 16- and 32-bit integers to and from network byte order: the htonl (host-to-network-long) and htons (host-to-network-short) functions convert 32-bit and 16-bit values respectively from machine (host) to network order; whereas the ntohl and ntohs functions convert from network to host order.
While the lowest network protocols may deal with sub-byte formatting, all the layers above them usually consider the byte (mostly meant as octet) as their atomic unit.

If you have a decimal value 1 the normal hex value will be 01. If we have a 2 byte delimiter (called WORD or 16bit integer) the value will look like 00 01, if we have a 4 byte delimiter (called DWORD or 32bit integer) it will look like 00 00 00 01.

Quote:
Wiki:
DWORD (double word) – is a unit of data that is twice the size of a word. The x86 platform originally had a word size of 16 bits (2 bytes) and that usage of the term is confusingly retained even though the actual processor word size is now 32 bits or even 64 bits. In that platform, a dword designates a 32-bit (4-byte) unit.

So that’s the normal byte order, if we have the reversed byte order everything is ... yeah ... reversed.... so our value will look like this:

(as 2 bytes) original: 00 01 reversed : 01 00

(as 4 bytes) original: 00 00 00 01 reversed : 01 00 00 00

So now let’s check our login-packet again.

22 00 11 00 6D 79 75 73 65 72 6E 61 6D 65 00 00 00 00 00 00 6D 79 70 61 73 73 77 6F 72 64 00 00 00 00 00 00

As we know most values are either displayed as 2 or 4 bytes we can start checking our login-packet.
The first 2 bytes look like a value.

22 00 , reversed: 00 22

Start your calculator and change the view from Dec (standard) to Hex.
Now enter your hex value 0022 (of course without the spaces). Now change the view to Dec again and you see our value is 34. Let’s check the packet-size again ... WPE is saying our packet is 36 bytes long. Do you see the parallels? Our packet-size minus our 2 bytes at the beginning = 34. So the first 2 bytes are indicating the packet length that will follow.
(It has not to be this way ... the length can be on the 4. position or somewhere else...)

In my example the 2 bytes which are indicating the length aren't included in the length, that's because some games which use encrypted packets are doing it also this way, cause they do encrypt all the bytes excepting the packet length (in most cases the first 1, 2 or 4 bytes).
But you shouldn't care about encryption now, since our packet seems to be sent in plain text. You know that cause when you look at the ASCII-Mode you see our username and password we used before.

Ok. What we know is the first 2 bytes indicate the packet length. But what about the rest? Well since I'm doing this for a long time know in most cases the next few bytes are a command or the "packet-header" (its not a real "header" but i just call it this way). How to test this?
Just sniff another login-packet in our game and change the username and password you enter to something else (no matter what). The value should not change.

Now we know 11 00 is our command (or "header"). You don't have to deal with this 2 bytes in dec, it’s just a hexadecimal header used for the packet protocol the developers created for the game. Like 11 00 is the login 12 00 is the getserverlist-packet and so on, you got what I mean?

We already discovered so much now let’s continue. We look at the ASCII-Mode and it seems to be that the next value is our username "myusername" but what’s that? There are so many 00s following our username in the HEX-Mode.
Most games have a limit for the username and password the user can enter. In most cases its either 12, 16, 24, 28 or 32 characters of length. So for an easier packet protocol they set the length of the buffers or variables for the username and password static ....
Like if our buffer has a length of 5 and we write "lol" into it the buffer will look like this:

6C 6F 6C 00 00

So now we know how the login-packets structure looks like:

2B = 2 Bytes
4B = 4 Bytes
XB = X Bytes

22 00 11 00 6D 79 75 73 65 72 6E 61 6D 65 00 00 00 00 00 00 6D 79 70 61 73 73 77 6F 72 64 00 00 00 00 00 00

<LENGTH>.2B <HEADER>.2B .16B .16B

So that’s the basic guide to analyze a packet. Well the thing is you will have to deal with a lot of values... Like you login and the server responds with some 4 byte values... just write them onto a piece of paper and check the next packets which are sent. So you can discover their function. Like the server responds with a 4 byte sessionID which the client next sends to the character server to authenticate himself, and so on.

4.2 Extended Structure Analysis

In the following example I will show (or simulate) a login-procedure with serverresponses and finally the "worldlist selection". Well since most mmorpgs use more than one servers or "worlds" I will try to show you here, how most of the stuff is done basically.

Well we start right under the login-procedur we analyzed in the chapter above. Now let’s assume we sent our login packet. So now we're waiting for the server to respond. What do we know?
If our login is false, the server has to tell that the client so that the client can give us an error message, else it will give us an ok and let us through.

Now let’s again assume we sent our login packet and received a packet from the server. Wow what’s with the client? It says wrong password, did we type something wrong?
Let’s check the packet (which could look like this) :

04 00 12 00 02 00

<LENGTH>.2B <HEADER>.2B .2B

So that’s the packet the server sends us, telling the client the password is wrong. I already colored the stuff we learned in the above tutorials. But what’s the last 2 bytes for? Well that’s probably a flag, telling the client whether the login was successful or not. Just do some checks and log in with some fictive username which does not exist in the game and the packet could look like this:

04 00 12 00 01 00

Now the client tells you "This Accountname is not available, please register first."

So now we surely know, the last 2 bytes is the login-flag. You can again reverse it and transform it from hex to dec using your calculator. Basically you don't have to do it since you already see what values it'll be, but if you're still not that good in hexadecimal use the calculator.

So that’s the flags we know for now:

original: 01 00 reversed : 00 01 dec : 1
original: 02 00 reversed : 00 02 dec : 2

So that’s basically a server variable transformed into a WORD (2 bytes). So when we have a successful login the flag maybe 00 00 and would tell the client "hey the login was successful, go on". But since we still don't know what the flag would look like when we had a successful login, we go on and test it.
Log in with your username and password and the server responds something like that:

08 00 12 00 00 00 C6 6F 5D A1

<LENGTH>.2B <HEADER>.2B .2B .4B

So what do we know? The first two bytes indicate the length. Next is the header, then the flag (which seems to be 0 in dec) and some DWORD (4 bytes) value.

Ok what could this new value be? We still don't know... Let’s reverse it and transform it into dec using our calc.

original: C6 6F 5D A1
reversed : A1 5D 6F C6
dec : 2707255238

We don't know it yet ... let’s go on with our packet analysis... Just write down the original 4 bytes and look for it in the next packets. So we could be able to analyze the function of this 4 bytes.

Get ingame and redo, or continue the sniffing. Ok now we have the worldserver-selection screen in our game. Let’s check the new packets we captured. The client seems to send something to the server after our above packet (12 00). Well that could be a request to get the worldserverlist.

The packet looks like this: 02 00 13 00

Seems to be nothing great in here, just the length and the flag. That’s the way the serverlist is requested by the client. Next we see a packet we received from the server. As you probably can see in the ASCII-View in WPE there are some strings in plain text, prolly the servernames. Let's see what we got:

39 00 14 00 03 54 68 65 20 4A 75 6E 67 6C 65 00 00 D9 D0 2C 12 D0 07 54 68 65 20 42 65 61 63 68 00 00 00 D9 D0 2C 13 D0 07 54 68 65 20 4C 61 6E 64 00 00 00 00 D9 D0 2C 14 D0 07

WPE shows our total size 59. And the first two bytes tell us 57.
So you remember the total size - 2 (the first two bytes) = the length of our data.

We see the length, and the header, but what is next? Check the ASCII-View in WPE again. There are three names in plaintext... The Jungle, The Beach and The Land. That’s our servernames. So we have 3 servers. Now it seems that the 5 byte of the packet ( 03 ) tells us how many servers we got in the list. We have 3 here so the hex for 3 is 03. So after this servercount we already have our servername "The Jungle", but what’s that? There are those 00s again. Well that means the same we had before with our username and password, you remember? It seems that the maximum length of a servername is 12 (use the ASCII-View and the HEX-View parallel in WPE to count it) that’s why the unused place is filled with 00. So what do we know, what information does such a server list has to store? Well it has to tell the client the name of the server, the IP and the port where the client should next connect right?

Well most IPs are sent as 4 single bytes, some servers also send them as plain text. Let’s assume our server sends it using a DWORD. What would this look like... well let's do an example.
We have the IP address 212.178.67.42. Now you split it into 4 independent values:
212 178 67 42 (so just "remove" the dots).
Now every single value will be converted into hex using our calculator.

212 = D4
178 = B2
67 = 43
42 = 2A

So our DWORD (4 bytes) is D4 B2 43 2A.
(do not reverse this!, since its 4 single values and not ONE big value)

Now Let’s check our packet again... whets after the servername. Well in such cases you just have to play around with the values. Pick every byte and convert it ... either byte for byte (to see if its an IP address) or 2 bytes at once (reversed!) or 4 bytes at once (reversed!). So after we played around a bit we found out that the next 4 bytes after the servername indicate the IP address.
Let’s check it.

D9 D0 2C 12 -> Convert it to dec -> 217.208.44.18

That seems to be an IP-address, if you're not sure, just ping it or something else. Well... we already got the servername, the IP... but what’s with the port? Check the next bytes of our packet, there are still 2 bytes left until the next servername begins. Well the maximum value a port can have is 65535, that’s basically the maximum value a 16bit-integer (also called short or word) can be. Type 65535 (dec) into your calculator and convert it to hex. What do we have here? FF FF - Two bytes…? Well it seems we found our port value. The 2 bytes after the IP -address seems to be our port. Let’s convert it (remember: that’s a normal value again, so we have to reverse it)

original: D0 07
reversed: 07 D0
dec: 2000

The port of the first worldserver seems to be 2000. So I guess you could do the rest of the packet on your own... Now let's collect all data we found and build a structure

39 00 14 00 03 54 68 65 20 4A 75 6E 67 6C 65 00 00 D9 D0 2C 12 D0 07 54 68 65 20 42 65 61 63 68 00 00 00 D9 D0 2C 13 D0 07 54 68 65 20 4C 61 6E 64 00 00 00 00 D9 D0 2C 14 D0 07

.2B
.2B .1B
{ for every servercount : .12B .4B .2B }

So the serverinformation we can gather from this packet is:

Servername -- IP -- Port

The Jungle -- 217.208.44.18 -- 2000
The Beach -- 217.208.44.19 -- 2000
The Land -- 217.208.44.20 -- 2000

Ok now, let’s get back to the game, choose a server and sniff the packets. Now after you've chosen the server, the client connects to this (see IP and ports we found out above) and we get the character list. But let’s see what really happens after the client successfully connected to the worldserver.

The client seems to send a packet to the worldserver: 06 00 15 00 C6 6F 5D A1

This is our value from above that we got from the server after we successfully logged in, remember? And now the server sends it again to the worldserver? Well yeah, that’s kind of an authentication-method most mmorpgs use. Look... you log in using "John" as username and "12345" (irrelevant in my example) as password. Now the server checks whether this information is right or not. In our example ... if the information IS correct, the server generates a DWORD ( 4 bytes ) or 32bit Integer value stores it and sends it back to the client. That’s called sessionid (most websites which have a login-interface also use this kind of authentication, but of course if can vary). Now after the client has chosen a worldserver he would like he connects to it and sends his sessionid. Well since the login server and the worldserver are "seperated from each other" (or basically two different applications) the world server does need this value to check whether someone really logged in before and got this sessionid. Since the loginserver stored our sessionid (in a database or whereever) the worldserver just checks whether the sessionid is available. Normally the sessionid is deleted when the client disconnects from the game, the server or whatever.

Now that’s the part where I stop. I won't update the encryption chapter since it’s basically the same for everything. If you know how to decrypt one packet, you basically know how to decrypt every packet of one game.

4.3 The Encryption

Well I won't be writing to much in here, since you can't tell just from looking at the packets what kind of encryption it is. Well of course you can, but not in all cases. I will just write some hints down.

Like let’s assume we capture a login-packet of a mmorpg. You shouldn't be able to read your username or password in ASCII-Mode now anymore.

At first do some checks, like the one with the first 2 bytes being the length and so on. Well next you can redo the sniff at the login process and see if the bytes do change ( of course use the same username and password as before ). Using that method you can say whether the encryption is static or not. Next do the checks like the one sniffing more login packets where you use fictive usernames and password which vary in length and see if some values change.

Well now you could do some basic analysis. Like let’s assume we have a login packet which looks like this (we used the username and password as before "myusername" and "mypassword"):

22 00 66 77 1A 0E 02 04 12 05 19 16 1A 12 77 77 77 77 77 77 1A 0E 07 16 04 04 00 18 05 13 77 77 77 77 77 77

Now we see the first two bytes and do the lengths check. Ok its works, it seems to be the packet length. Now do the check with the other username and passwords... You will notice that the first four bytes do not change. That means starting from the 5 byte there is our username and password data.

I hope you know how to use a HexEditor for the next steps. Let’s write down the packet beginning at the 5 byte. It looks like that to me, using HexWorkshop: Image
So we see there are some bytes being 77... Seems to be strange. Let’s write down our username and password under the exact positions of both values (the 77 does seem to be placeholders, since their the same everywhere right?)
My Hex-Editor looks like this: Image
Wow what’s that? Our username and password does exactly fit into the encrypted packet data.
Well that could be a XOR-Encryption


Quote:
Wiki:
The logical operation exclusive disjunction, also called exclusive or (symbolized XOR, EOR, EXOR, or ⊕), is a type of logical disjunction on two operands that results in a value of true if exactly one of the operands has a value of true.[1] A simple way to state this is "one or the other but not both."

How to test it? Start your calculator and be sure "Hex" is checked. Now type in the first byte of the value which could be your username. In our case its 1A. So we type 1A into the calculator. Now we look at the line under the encrypted data, and see that 6D in hex stands for a "m" in ASCII. Now when you already typed 1A into your calculator hit the XOR-Button... then type in our hex value for "m" (6D) and hit enter. Our result is 77. Strange isn't it? Now Let’s do the check. Take the next byte of our encrypted data. In our case its 0E. Type 0E into the calculator, press the XOR-Button, type 77 and hit enter. You should get 79 now which is the hex value for "y". Well it seems we have a static XOR-Encryption using the key 77 here. So you'll be able to decrypt all the packet data of our game using the XOR method and the key 77.
An implementation into a programming language could look like this

Syntax « c » : [ Download ] [ Hide ] [ Expand ]
// we are starting from byte 2 since the first 2 bytes are our
// packet length which is not encrypted,
for (int i = 2; i < packetLength; i++)
   {
      packet[i] = packet[i] ^ 0x77;
   }

Well that’s the end of my tutorial. I hope it's not to complicate and I didn't mix up to much things. I hope you enjoyed it.

0 comentarios:

Publicar un comentario