Register for your free account! | Forgot your password?

Go Back   elitepvpers > MMORPGs > Conquer Online 2 > CO2 Private Server
You last visited: Today at 14:44

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



Packet decryption problem

Discussion on Packet decryption problem within the CO2 Private Server forum part of the Conquer Online 2 category.

Reply
 
Old   #1

 
Kiyono's Avatar
 
elite*gold: 20
Join Date: Jun 2006
Posts: 3,296
Received Thanks: 925
Packet decryption problem

So I tried downgrading the Albetros source to 5017 and posted this issue in that thread but since I don't know how many people actually check that thread, I'll post it here as well. The problem is as follows:

The gameserver only handles the first packet properly, in other words packet 1052 is handled ok (correct sizes, type w/e) but then when it receives the next packet, it has these weird huge sizes and wacky IDs such as the charcreation packet becoming ID 34669 instead of 1001.

pro suggested to check the decryption counters and here's my reply:
Quote:
Originally Posted by Kiyono View Post
Well I checked the encryption counters and it all works properly but just in case I overlooked something I decided to swap out the encryption with one from Hybrid's source since I know it works but it still failed, though, at least now every now and then I get the correct packet ID (actually showed 1001) but that was just once in...10+ times of trying and the size was 17k+.

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Albetros.Game.Encryption //Hybrid's source
{
    public class ConquerKeys
    [spoiler]{
        #region public static byte[] Key1 = new byte[256];
        public static byte[] Key1 = 
            {
			    0x9D, 0x90, 0x83, 0x8A, 0xD1, 0x8C, 0xE7, 0xF6, 0x25, 0x28, 0xEB, 0x82, 0x99, 0x64, 0x8F, 0x2E,
			    0x2D, 0x40, 0xD3, 0xFA, 0xE1, 0xBC, 0xB7, 0xE6, 0xB5, 0xD8, 0x3B, 0xF2, 0xA9, 0x94, 0x5F, 0x1E, 
		    	0xBD, 0xF0, 0x23, 0x6A, 0xF1, 0xEC, 0x87, 0xD6, 0x45, 0x88, 0x8B, 0x62, 0xB9, 0xC4, 0x2F, 0x0E, 
		        0x4D, 0xA0, 0x73, 0xDA, 0x01, 0x1C, 0x57, 0xC6, 0xD5, 0x38, 0xDB, 0xD2, 0xC9, 0xF4, 0xFF, 0xFE, 
		    	0xDD, 0x50, 0xC3, 0x4A, 0x11, 0x4C, 0x27, 0xB6, 0x65, 0xE8, 0x2B, 0x42, 0xD9, 0x24, 0xCF, 0xEE, 
		    	0x6D, 0x00, 0x13, 0xBA, 0x21, 0x7C, 0xF7, 0xA6, 0xF5, 0x98, 0x7B, 0xB2, 0xE9, 0x54, 0x9F, 0xDE, 
		    	0xFD, 0xB0, 0x63, 0x2A, 0x31, 0xAC, 0xC7, 0x96, 0x85, 0x48, 0xCB, 0x22, 0xF9, 0x84, 0x6F, 0xCE, 
		        0x8D, 0x60, 0xB3, 0x9A, 0x41, 0xDC, 0x97, 0x86, 0x15, 0xF8, 0x1B, 0x92, 0x09, 0xB4, 0x3F, 0xBE, 
		        0x1D, 0x10, 0x03, 0x0A, 0x51, 0x0C, 0x67, 0x76, 0xA5, 0xA8, 0x6B, 0x02, 0x19, 0xE4, 0x0F, 0xAE, 
		    	0xAD, 0xC0, 0x53, 0x7A, 0x61, 0x3C, 0x37, 0x66, 0x35, 0x58, 0xBB, 0x72, 0x29, 0x14, 0xDF, 0x9E, 
			    0x3D, 0x70, 0xA3, 0xEA, 0x71, 0x6C, 0x07, 0x56, 0xC5, 0x08, 0x0B, 0xE2, 0x39, 0x44, 0xAF, 0x8E, 
			    0xCD, 0x20, 0xF3, 0x5A, 0x81, 0x9C, 0xD7, 0x46, 0x55, 0xB8, 0x5B, 0x52, 0x49, 0x74, 0x7F, 0x7E, 
		        0x5D, 0xD0, 0x43, 0xCA, 0x91, 0xCC, 0xA7, 0x36, 0xE5, 0x68, 0xAB, 0xC2, 0x59, 0xA4, 0x4F, 0x6E, 
			    0xED, 0x80, 0x93, 0x3A, 0xA1, 0xFC, 0x77, 0x26, 0x75, 0x18, 0xFB, 0x32, 0x69, 0xD4, 0x1F, 0x5E, 
			    0x7D, 0x30, 0xE3, 0xAA, 0xB1, 0x2C, 0x47, 0x16, 0x05, 0xC8, 0x4B, 0xA2, 0x79, 0x04, 0xEF, 0x4E, 
			    0x0D, 0xE0, 0x33, 0x1A, 0xC1, 0x5C, 0x17, 0x06, 0x95, 0x78, 0x9B, 0x12, 0x89, 0x34, 0xBF, 0x3E
            };
        #endregion
        #region public static byte[] Key2 = new byte[256];
        public static byte[] Key2 =
            {
				0x62, 0x4F, 0xE8, 0x15, 0xDE, 0xEB, 0x04, 0x91, 0x1A, 0xC7, 0xE0, 0x4D, 0x16, 0xE3, 0x7C, 0x49,
				0xD2, 0x3F, 0xD8, 0x85, 0x4E, 0xDB, 0xF4, 0x01, 0x8A, 0xB7, 0xD0, 0xBD, 0x86, 0xD3, 0x6C, 0xB9,
				0x42, 0x2F, 0xC8, 0xF5, 0xBE, 0xCB, 0xE4, 0x71, 0xFA, 0xA7, 0xC0, 0x2D, 0xF6, 0xC3, 0x5C, 0x29,
				0xB2, 0x1F, 0xB8, 0x65, 0x2E, 0xBB, 0xD4, 0xE1, 0x6A, 0x97, 0xB0, 0x9D, 0x66, 0xB3, 0x4C, 0x99,
				0x22, 0x0F, 0xA8, 0xD5, 0x9E, 0xAB, 0xC4, 0x51, 0xDA, 0x87, 0xA0, 0x0D, 0xD6, 0xA3, 0x3C, 0x09,
				0x92, 0xFF, 0x98, 0x45, 0x0E, 0x9B, 0xB4, 0xC1, 0x4A, 0x77, 0x90, 0x7D, 0x46, 0x93, 0x2C, 0x79,
				0x02, 0xEF, 0x88, 0xB5, 0x7E, 0x8B, 0xA4, 0x31, 0xBA, 0x67, 0x80, 0xED, 0xB6, 0x83, 0x1C, 0xE9,
				0x72, 0xDF, 0x78, 0x25, 0xEE, 0x7B, 0x94, 0xA1, 0x2A, 0x57, 0x70, 0x5D, 0x26, 0x73, 0x0C, 0x59,
				0xE2, 0xCF, 0x68, 0x95, 0x5E, 0x6B, 0x84, 0x11, 0x9A, 0x47, 0x60, 0xCD, 0x96, 0x63, 0xFC, 0xC9,
				0x52, 0xBF, 0x58, 0x05, 0xCE, 0x5B, 0x74, 0x81, 0x0A, 0x37, 0x50, 0x3D, 0x06, 0x53, 0xEC, 0x39,
				0xC2, 0xAF, 0x48, 0x75, 0x3E, 0x4B, 0x64, 0xF1, 0x7A, 0x27, 0x40, 0xAD, 0x76, 0x43, 0xDC, 0xA9,
				0x32, 0x9F, 0x38, 0xE5, 0xAE, 0x3B, 0x54, 0x61, 0xEA, 0x17, 0x30, 0x1D, 0xE6, 0x33, 0xCC, 0x19,
				0xA2, 0x8F, 0x28, 0x55, 0x1E, 0x2B, 0x44, 0xD1, 0x5A, 0x07, 0x20, 0x8D, 0x56, 0x23, 0xBC, 0x89,
				0x12, 0x7F, 0x18, 0xC5, 0x8E, 0x1B, 0x34, 0x41, 0xCA, 0xF7, 0x10, 0xFD, 0xC6, 0x13, 0xAC, 0xF9,
				0x82, 0x6F, 0x08, 0x35, 0xFE, 0x0B, 0x24, 0xB1, 0x3A, 0xE7, 0x00, 0x6D, 0x36, 0x03, 0x9C, 0x69,
				0xF2, 0x5F, 0xF8, 0xA5, 0x6E, 0xFB, 0x14, 0x21, 0xAA, 0xD7, 0xF0, 0xDD, 0xA6, 0xF3, 0x8C, 0xD9
            };
        #endregion
    }[/spoiler]
    public sealed class Cipher : IConquerCipher
    {
        private ushort InCounter;
        private ushort OutCounter;

        public Cipher()
        {
            InCounter = OutCounter = 0;
        }
        public void Encrypt(byte[] In, byte[] Out, int Length)
        {
            lock (this)
            {
                for (int i = 0; i < Length; i++)
                {
                    Out[i] = (byte)(In[i] ^ 0xAB);
                    Out[i] = (byte)((Out[i] << 4) | (Out[i] >> 4));
                    Out[i] = (byte)(ConquerKeys.Key2[OutCounter >> 8] ^ Out[i]);
                    Out[i] = (byte)(ConquerKeys.Key1[OutCounter & 0xFF] ^ Out[i]);
                    OutCounter = (ushort)(OutCounter + 1);
                }
            }
        }

        public void Decrypt(byte[] In, byte[] Out, int Length)
        {
            lock (this)
            {
                for (int i = 0; i < Length; i++)
                {
                    Out[i] = (byte)(In[i] ^ 0xAB);
                    Out[i] = (byte)((Out[i] << 4) | (Out[i] >> 4));
                    Out[i] = (byte)(ConquerKeys.Key2[InCounter >> 8] ^ Out[i]);
                    Out[i] = (byte)(ConquerKeys.Key1[InCounter & 0xFF] ^ Out[i]);
                    InCounter = (ushort)(InCounter + 1);
                }
            }
        }
    }
}
That's how it looks like now and this is where the decryption kicks in:
Code:
public override void OnPacketReceive(IClientWrapper client, byte[] buffer) //Most of it is from Hybrid's source
        {
            try
            {
                Player user = client as Player;
                if (user.Client.Connected && buffer.Length >= 4)
                {
                    var Out = new byte[buffer.Length];
                    lock (user.Cryptographer)
                    {
                        user.Cryptographer.Decrypt(buffer, Out, Out.Length);
#if DUMP
                        Kernel.WritePacket(Out);
#endif
                    }
                    byte[] Recv = Out;
                    int Counter = 0;
                    while (Counter < Recv.Length)
                    {
                        ushort Size = BitConverter.ToUInt16(Recv, Counter);
                        ushort Type = BitConverter.ToUInt16(Recv, Counter + 2);
                            
                        if (Size < Recv.Length)
                        {
                            byte[] InitialPacket = new byte[Size];
                            Buffer.BlockCopy(Recv, Counter, InitialPacket, 0, Size);
                            user.Handler.Handle(InitialPacket, Type);
                        }
                        else if (Size > Recv.Length)
                        {
                            OnError(client, new Exception("Packet ID: " + Type + " with size: " + Size + " is invalid"));
                            break;
                        }
                        else
                        {
                            user.Handler.Handle(Recv, Type);
                        }
                        Counter += Size;
                    }
                }
                else
                {
                    OnError(client, new Exception("An error occured with the client or the buffersize is invalid"));
                }
            }
            catch (Exception P)
            {
                Console.WriteLine(P.ToString());// throw new Exception(P.ToString()); 
            }
        }
So as said before, login works flawlessly and you can login several chars at once and it will work but after packet 1052 nothing gets decrypted properly.
Example of what happens when you try to create a char (logging in with an existing char gives the same type of issue)
So any ideas? This is rather odd.
Kiyono is offline  
Old 12/20/2011, 18:28   #2


 
CptSky's Avatar
 
elite*gold: 0
Join Date: Jan 2008
Posts: 1,443
Received Thanks: 1,175
Do you generate the "third" and "fourth" key with the right values?
CptSky is offline  
Old 12/20/2011, 18:49   #3

 
Kiyono's Avatar
 
elite*gold: 20
Join Date: Jun 2006
Posts: 3,296
Received Thanks: 925
Those were never referenced by anything in Hybrid's source so I assumed that those were unneeded, mind clarifying?
Kiyono is offline  
Old 12/20/2011, 19:29   #4


 
CptSky's Avatar
 
elite*gold: 0
Join Date: Jan 2008
Posts: 1,443
Received Thanks: 1,175
Quote:
Originally Posted by Kiyono View Post
Those were never referenced by anything in Hybrid's source so I assumed that those were unneeded, mind clarifying?
I will explain with the implementation I did of the algorithm.


When the MsgServer receive a new connection, it creates a new COSAC object. Also, it generates the IV with the public keys (P, G). These keys are suppose to be known by the server and the client. On a normal client/server, P: 0x13FA0F9D, G: 0x6D5C7962. After, this, the client should send the MsgConnect packet (1052) with the privates keys (A, B) that as been specified by the AccServer. The packet is crypted with the IV, so the server can decrypt it without any problem. With this packet, the MsgServer will check if the client use the right privates keys. If so, it will generate the Key with the private keys (A, B). In CO2, A = Token, B = AccountUID. When the server will generate the Key, it will also reset the encrypt counter as the encrypt routine will still use the IV to crypt the data. The decrypt counter will remain the same and the decrypt routine will use the Key to crypt the data. After generating the Key, the server will answer to the MsgConnect with some packets.

For the AccServer, the private keys are sent with the same packet than the IP of the MsgServer.

The MsgLoginReply of the AccServer
Code:
        public struct MsgInfo
        {
            public MsgHeader Header;
            public Int32 AccountUID;
            public Int32 Token;
            public fixed Byte IPAddress[0x10];
            public Int32 Port;
        };
The MsgConnect of the MsgServer
Code:
        public struct MsgInfo
        {
            public MsgHeader Header;
            public Int32 AccountUID;
            public Int32 Token;
            public Int16 Constant; //In the CO2 app...
            public fixed Byte Language[_MAX_LANGUAGE_SIZE];
            public Int32 ResValue;
        };
By the way, the crypto you use is only valid for the AccServer as it does not handle the Key, but only the IV.
CptSky is offline  
Thanks
1 User
Old 12/20/2011, 20:10   #5

 
Kiyono's Avatar
 
elite*gold: 20
Join Date: Jun 2006
Posts: 3,296
Received Thanks: 925
Oh I see, that's what was wrong.
I simply added
Code:
user.Cryptographer.SetKeys((uint)BitConverter.ToUInt32(packet, 8), (uint)BitConverter.ToUInt32(packet, 4));
To the 1052 packet, stuck the SetKeys void in there and it works, no longer weird packet sizes.
Kiyono is offline  
Reply


Similar Threads Similar Threads
CO Packet decryption.
12/07/2008 - CO2 Programming - 11 Replies
Hi, i recently made a Java proxy, I'm wondering if anyone would like to share with me the CO packet encryption/decryption packet structure. I wouldn't mind it for testing purposes, thanks.
packet decryption?
08/21/2007 - World of Warcraft - 1 Replies
soo, ich wuerde gerne bissl mit den wow-packets rumspielen. allerdings hab ich keine ahnung, wie ich die decrypten soll. weiss da wer was? Ping
Packet Decryption
07/10/2006 - Conquer Online 2 - 3 Replies
My Other Thread Died (*sigh* And I Still Can't Decrypt The First Server -> Client Packet) Heres What I Posted About It There: http://www.elitepvpers.com/forum/index.php?...f=53 &t=25033&s= But For Now, Becuase Im Not Tottally Selfish, Heres The Vb6 Solution To Decrypting The First Client -> Server Packet It Currently Has: *Encrypt Packets *Decrypt Packets
Packet decryption problem..
06/02/2006 - Conquer Online 2 - 2 Replies
In Lowfyr's packet decryption guide, first step to get key3/key4 1.) Add key 1 with key 2 205C48F4 + 0044A62E = 20A0EF22 What do I do when key1+key2 is more than 4 bytes? Discard the first byte? Just as an example, I have gotten this from the server.. key1 363504E3 key2 D9007F2D add them together = 10F358410 do I just discard the 1 and end up with 0F358410?
t4c packet decryption
09/29/2005 - General Coding - 0 Replies
Hey I was wondering if anyone could help me with packet decrypting of a game. Its called The 4th Coming. its a 2d game, and speed hacks work on it, so you know the game is kinda crap. I have a server for it and the client, but now I need someone to try and figure out he packets. Here is the Outpu of the Database, I was wondering if someone could use this info so they can either decrypt packets or change the data on another real server. The information is sotred on a Microsoft MDB. here the...



All times are GMT +1. The time now is 14:45.


Powered by vBulletin®
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2025 elitepvpers All Rights Reserved.