Register for your free account! | Forgot your password?

Go Back   elitepvpers > MMORPGs > Conquer Online 2 > CO2 Programming
You last visited: Today at 17:31

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

Advertisement



[FAQ] Proxies, packets and bots ooh my!

Discussion on [FAQ] Proxies, packets and bots ooh my! within the CO2 Programming forum part of the Conquer Online 2 category.

Reply
 
Old 10/16/2010, 01:01   #31
 
tkblackbelt's Avatar
 
elite*gold: 0
Join Date: Sep 2010
Posts: 271
Received Thanks: 86
I got a question do you edit the conquer.exe in say ollydbg to change it to connect to my local ip or is there a way to decrypt the server.dat file?

Also would you say I have enough experience in java to atempt to make a proxy. what I've done:

1. Made a Tic Tac toe game with GUI
2. Made a Chat client
3. Made a Cryptor
3. A Poker game
And lots of other small projects
tkblackbelt is offline  
Old 10/16/2010, 02:49   #32
 
elite*gold: 21
Join Date: Jul 2005
Posts: 9,193
Received Thanks: 5,377
Just use null's loader. It changes port ip and website using a textfile.

As for your ability to make a proxy... I'm doubtful when people are using other languages than C# and claiming limited experience with programming...

With C#, while not always ideal, there are TONS of examples and sources to look at... with java all you really have is what.... coproxy source and MAYBE jproxy source if you can get your hands on it?

C# has complete conquer encryption solutions including tannels proxy which got leaked on here a while ago which you can actually log in with if you change just a few packets.

So my answer would be YES.. you can probably set up the basic framework but encryption will be something rather difficult for you to do as you will need to write your own encryption algorithms and a dhkey exchange method for your man in the middle attack.

Hell even with a working sample proxy it took me a while to get a working proxy version of blowfish working :S

Up till blowfish is INCREDIBLY easy (took me like an hour or two?) but once you start getting into editing blowfish keys, setting up dual encryptions based on various factors and stuff it gets... confusing to say the least.

Most of that is just due to my complete lack of encryption knowledge though. Anything I've picked up about it has been in relation to conquer and in my USAGE of it as opposed to writing it from scratch.
pro4never is offline  
Thanks
1 User
Old 10/27/2010, 09:35   #33
 
elite*gold: 0
Join Date: Jun 2006
Posts: 457
Received Thanks: 67
Thank you, and Wow... your reply is super informative pro4never. It took me into reading more and reading and i nearly forgot it is impolite as to not to reply. I realized that the packet structures are indeed clearly listed on conquer wiki.

I just got 2 more questions regarding the password seed. You mentioned it is the very first packet received client gets connected to server. Did you mean once this line of code [Socket s = Server.accept(); ] successfully executed on the server side, the server will send this password seed to the client?

If so, how is the encryption done with this seed. Is it in the coemu source?

Last but not least ... i cant find nulls loader that you've mentioned, can you provide a reference.
shitboi is offline  
Old 10/27/2010, 09:53   #34
 
elite*gold: 21
Join Date: Jul 2005
Posts: 9,193
Received Thanks: 5,377
Quote:
Originally Posted by shitboi View Post
Thank you, and Wow... your reply is super informative pro4never. It took me into reading more and reading and i nearly forgot it is impolite as to not to reply. I realized that the packet structures are indeed clearly listed on conquer wiki.

I just got 2 more questions regarding the password seed. You mentioned it is the very first packet received client gets connected to server. Did you mean once this line of code [Socket s = Server.accept(); ] successfully executed on the server side, the server will send this password seed to the client?

If so, how is the encryption done with this seed. Is it in the coemu source?

Last but not least ... i cant find nulls loader that you've mentioned, can you provide a reference.



Password seed is sent when you connect to TQ's auth server (what you are referencing is accepting the client>proxy connection... when that happens you should be setting up a Proxy>Server connection (Client connection, NOT a listener that blocks off a port)


Here's an example from my super basic test proxy using a version of hybrids interop dll

Code:
 AuthServer = new ClientSocket.WinsockClient(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                AuthServer.Enable(Program.AuthIp, Program.AuthPort, this.Buffer);
                AuthServer.OnReceive += new ClientSocket.SocketEventCallback<ClientSocket.WinsockClient, byte[]>(AuthServer_OnReceive);
                AuthServer.OnDisconnect += new ClientSocket.SocketEventCallback<ClientSocket.WinsockClient, object>(AuthServer_OnDisconnect);
So basically you want to setup a new connection and then either start a new receiving thread (sync sockets) or event based onreceive/ondisconnect functionality (async sockets)

Async sockets are FAR better because you are not required to specifically create a new thread simply to receive data from each connection, nor is the connection blocked off until it receives something (in certain situations this can result in freezing the entire proxy if you don't handle it properly!)


Password encryption: You can find it on the form by searching liberatepasswordcryptography or something along those lines. It's also contained in project Exodus source (either the original version or the one I upgraded a bit so that nubs could log in using 5309 clients)

Here is an example of using it...

Code:
msvcrt.msvcrt.srand(Client.PassSeed);
                    var rc5Key = new byte[0x10];
                    for (int i = 0; i < 0x10; i++)
                        rc5Key[i] = (byte)msvcrt.msvcrt.rand();                  
                    string Password = Encoding.ASCII.GetString(
                          (new ConquerPasswordCryptpographer(Username).Decrypt(new Encryption.RC5(rc5Key).Decrypt(Pass))));
In this example Pass seed is the stored value from the original password seed (as an int in this example) and Pass is a byte array for the password read from the packet.

You don't need to worry about password encryption at all in proxies unless you want to log users account information (tsk, tsk, naughty, naughty!... not that I don't lol!)

Hope that helps you out some more.
pro4never is offline  
Thanks
1 User
Old 10/28/2010, 00:18   #35
 
elite*gold: 0
Join Date: Jun 2006
Posts: 457
Received Thanks: 67
wow... can't say i have understood all that. But i think i am ready to pull something off now. I'll visit this thread from time to time to stay updated. Thanks again prog4never
shitboi is offline  
Old 10/28/2010, 06:37   #36
 
elite*gold: 0
Join Date: Jun 2006
Posts: 457
Received Thanks: 67
Deciphering the packet

Hey prog4never... i began logging the first packet, but i immediately came into a problem. The first packet - password seed received from auth server should be

[length=2byte][type=2byte][seed=4byte]

This is the first packet logged.

Code:
Proxy Started : Listening for connection on port 9959
Client connected
Redirecting to Auth Server ...
Connection with Auth Server established
starting up and down Streams
40 -11 53 -105 52 108 98 -97 Packet Length :-11
UpStr Packet Length :-257
Connection closed at downStreamService
this is a sample packet in a byte array. theoractically [40 -11] should be the length, [53 -105] should be the type. These 2 are unvarying, therefore I am sure they are the frame of the packet. the last 4 changing bytes must be the signed integer password seed.

I am able to log the first complete packet before i know it's size before hand. I naively thought that i can simply obtain length by doing a
int length (no unsigned short in java) = packet[0]<<8|packet[1];
The output proved that I do not know how to convert the data i have obtained to derive the length and type. This is essential since i'll be needing for any kind of packet handling. Please advice.
shitboi is offline  
Old 10/28/2010, 08:24   #37
 
elite*gold: 21
Join Date: Jul 2005
Posts: 9,193
Received Thanks: 5,377
Quote:
Originally Posted by shitboi View Post
Hey prog4never... i began logging the first packet, but i immediately came into a problem. The first packet - password seed received from auth server should be

[length=2byte][type=2byte][seed=4byte]

This is the first packet logged.

Code:
Proxy Started : Listening for connection on port 9959
Client connected
Redirecting to Auth Server ...
Connection with Auth Server established
starting up and down Streams
40 -11 53 -105 52 108 98 -97 Packet Length :-11
UpStr Packet Length :-257
Connection closed at downStreamService

this is a sample packet in a byte array. theoractically [40 -11] should be the length, [53 -105] should be the type. These 2 are unvarying, therefore I am sure they are the frame of the packet. the last 4 changing bytes must be the signed integer password seed.

I am able to log the first complete packet before i know it's size before hand. I naively thought that i can simply obtain length by doing a
int length (no unsigned short in java) = packet[0]<<8|packet[1];
The output proved that I do not know how to convert the data i have obtained to derive the length and type. This is essential since i'll be needing for any kind of packet handling. Please advice.
Are you running it through the auth decryption? should be required to make sense of it. It must be decrypted for it to make any sense (eg actually display accurate results.)
pro4never is offline  
Thanks
1 User
Old 10/28/2010, 14:41   #38
 
elite*gold: 0
Join Date: Jun 2006
Posts: 457
Received Thanks: 67
I didn't run it through any decryption. I am wondering if i didn't get the concept right. The first 4 bytes are the frame of the packet eh? they are readable without decryption right?

If i am wrong. then i have a problem. I set up the sockets for tcp/ip connection, and i am reading from the tcp stream byte by byte. I need to know how much i should read in order to assemble a complete packet.
shitboi is offline  
Old 10/28/2010, 18:36   #39
 
elite*gold: 21
Join Date: Jul 2005
Posts: 9,193
Received Thanks: 5,377
Nope, you need to run every single packet through encryption/decryption as with the auth encryption there is a counter so if you don't it will lose sync and stop working.

Reading the packet byte by byte?... you should be reading the entire stream... aka the full packet.


Note: Once you get into the game server side the packets will be combined and you will need to split them. You still read the entire stream at once though... store it as a byte array and process/split it as needed.
pro4never is offline  
Thanks
1 User
Old 10/28/2010, 21:23   #40
 
elite*gold: 0
Join Date: Jun 2006
Posts: 457
Received Thanks: 67
Quote:
Originally Posted by pro4never View Post
Nope, you need to run every single packet through encryption/decryption as with the auth encryption there is a counter so if you don't it will lose sync and stop working.

Reading the packet byte by byte?... you should be reading the entire stream... aka the full packet.


Note: Once you get into the game server side the packets will be combined and you will need to split them. You still read the entire stream at once though... store it as a byte array and process/split it as needed.
Right !... i changed my codes and they are now reading the entire packet into a byte[] buffer. The authorization bridging is successful, so i need to move on to the de/en of the auth packets, else i wont be able cheat my client into believing my proxy is the server.

I saw unknownone's de/en . but i am unable to translate it into java. Are there any other resources explaining how it actually works ?

One of the main reasons my translation failed is because java doesn't have unsigned shit ... and i dont have a good understanding of the lower layer of primitive data type in java

[add]:
btw. after i translated it, the pre De/En and post DeEn are different, lol.

Code:
        internal class CryptCounter
        {
            UInt16 m_Counter = 0;

            public byte Key2
            {
                get { return (byte)(m_Counter >> 8); }
            }

            public byte Key1
            {
                get { return (byte)(m_Counter & 0xFF); }
            }

            public void Increment()
            {
                m_Counter++;
            }
        }
Cast aside the bit-wise operations, syntactically I dont quite get the meaning of

Code:
public byte Key1
{
     get { return (byte)(m_Counter & 0xFF); }
}
shitboi is offline  
Old 10/29/2010, 01:23   #41
 
elite*gold: 21
Join Date: Jul 2005
Posts: 9,193
Received Thanks: 5,377



It has to do with bitwise operation based on the current counter. That's why it's essential to encrypt/decrypt every single packet that flows through and to use separate auth cryption for each side of the proxy (client and server)

I've never done much with bitwise operations so I won't be of much help but maybe you know of something similar in java.

The only time I've seen it referenced by anyone was to do with status effects which are stored as a common 'pool' and you need to pull individual values out of it. As far as I understand this is a similar thing where you are combining the bit values of the counter and 0xFF to create Key1
pro4never is offline  
Old 10/29/2010, 04:28   #42
 
elite*gold: 0
Join Date: Jun 2009
Posts: 787
Received Thanks: 314
The (x & 0xFF) is unnecessary. All you're trying to do is get the first byte of a two-byte value. Casting a ushort to a byte will do this anyways.
_tao4229_ is offline  
Old 10/29/2010, 05:40   #43
 
elite*gold: 0
Join Date: Jun 2006
Posts: 457
Received Thanks: 67
First of all, i tried to load the original source into MSVS2008 hoping to get some results.. but it terminated in a weird manner. Never tried C# before, struggled a bit and gave up. Then i went back to the java codes... This is what i have.. somehow it is not working to my desire. I used i&0xff to cast store the unsigned bytes in int.. Can some one point out where i am wrong? I only had Encrypt function in this example.
Code:
public class test{
	public static class CryptCounter {
    private int m_Counter = 0;
    public final int getKey2() {return (byte) (m_Counter >> 8);}
    public final int getKey1() {return (byte) (m_Counter & 0xFF);}
    public final void Increment() {m_Counter++;}
  }
  
  
  private CryptCounter _decryptCounter;
  private CryptCounter _encryptCounter;
  private int[] _cryptKey1;
  private int[] _cryptKey2;
  
	public test(){
		_decryptCounter = new CryptCounter();
    _encryptCounter = new CryptCounter();
    _cryptKey1 = new int[0x100];
    _cryptKey2 = new int[0x100];
    int i_key1 = 0x9D;
    int i_key2 = 0x62;
    for (int i = 0; i < 0x100; i++) {
      _cryptKey1[i] = i_key1;
      _cryptKey2[i] = i_key2;
      i_key1 = ((0x0F+ ((i_key1*0xFA)&0xff) * i_key1 + 0x13)&0xff);
      i_key2 = ((0x79 - ((i_key2 * 0x5C)&0xff) * i_key2 + 0x6D)&0xff);   
    }
  }
  public void Encrypt(int[] buffer){
    for (int i = 0; i < buffer.length; i++){
       buffer[i] ^= ((_cryptKey1[_encryptCounter.getKey1()] ^ _cryptKey2[_encryptCounter.getKey2()])&0xff);
       buffer[i] = ((buffer[i] >> 4 | buffer[i] << 4)&0xff);
       buffer[i] ^= (0xAB&0xff);
       _encryptCounter.Increment();
  	}
  }
  
  public static void main(String[] args){
			test apc = new test();
			int[] a = { 197, 72, 105, 18, 65, 243, 201, 46 };
			apc.Encrypt(a);
			for(int i=0;i<a.length;i++)
				System.out.print(a[i]+" ");
			int x = (a[0]<<8)|a[1];
			System.out.println(x);
	}
}
shitboi is offline  
Old 10/29/2010, 12:17   #44
 
elite*gold: 21
Join Date: Jul 2005
Posts: 9,193
Received Thanks: 5,377
Here's the one from tannels leaked proxy. May be of more use to you seeing as most versions of it only focus on decrypting Client>Server and encrypting Server>client (cause that's all a pserver needs)

Quote:
public class AuthProtocolCryptographer
{
class CryptCounter
{
UInt16 m_Counter = 0;

public byte Key2
{
get { return (byte)(m_Counter >> 8); }
}

public byte Key1
{
get { return (byte)(m_Counter & 0xFF); }
}

public void Increment()
{
m_Counter++;
}
}

private CryptCounter _decryptCounter;
private CryptCounter _encryptCounter;
private byte[] _cryptKey1;
private byte[] _cryptKey2;

public AuthProtocolCryptographer()
{
_decryptCounter = new CryptCounter();
_encryptCounter = new CryptCounter();
_cryptKey1 = new byte[0x100];
_cryptKey2 = new byte[0x100];
byte i_key1 = 0x9D;
byte i_key2 = 0x62;
for (int i = 0; i < 0x100; i++)
{
_cryptKey1[i] = i_key1;
_cryptKey2[i] = i_key2;
i_key1 = (byte)((0x0F + (byte)(i_key1 * 0xFA)) * i_key1 + 0x13);
i_key2 = (byte)((0x79 - (byte)(i_key2 * 0x5C)) * i_key2 + 0x6D);
}
}

public void Decrypt(byte[] buffer)
{
for (int i = 0; i < buffer.Length; i++)
{
buffer[i] ^= (byte)0xAB;
buffer[i] = (byte)(buffer[i] >> 4 | buffer[i] << 4);
buffer[i] ^= (byte)(_cryptKey1[_decryptCounter.Key1] ^ _cryptKey2[_decryptCounter.Key2]);
_decryptCounter.Increment();
}
}
public void Encrypt(byte[] buffer)
{
for (int i = 0; i < buffer.Length; i++)
{
buffer[i] ^= (byte)0xAB;
buffer[i] = (byte)(buffer[i] >> 4 | buffer[i] << 4);
buffer[i] ^= (byte)(_cryptKey1[_encryptCounter.Key1] ^ _cryptKey2[_encryptCounter.Key2]);
_encryptCounter.Increment();
}
}

public void EncryptBackwards(byte[] buffer)
{
for (int i = 0; i < buffer.Length; i++)
{
buffer[i] ^= (byte)(_cryptKey2[_encryptCounter.Key2] ^ _cryptKey1[_encryptCounter.Key1]);
buffer[i] = (byte)(buffer[i] >> 4 | buffer[i] << 4);
buffer[i] ^= (byte)0xAB;

_encryptCounter.Increment();
}
}
public void DecryptBackwards(byte[] buffer)
{
for (int i = 0; i < buffer.Length; i++)
{
buffer[i] ^= (byte)(_cryptKey2[_decryptCounter.Key2] ^ _cryptKey1[_decryptCounter.Key1]);
buffer[i] = (byte)(buffer[i] >> 4 | buffer[i] << 4);
buffer[i] ^= (byte)0xAB;

_decryptCounter.Increment();
}
}

public void GenerateKeys(UInt32 CryptoKey, UInt32 AccountID)
{
UInt32 tmpkey1 = 0, tmpkey2 = 0;
tmpkey1 = ((CryptoKey + AccountID) ^ (0x4321)) ^ CryptoKey;
tmpkey2 = tmpkey1 * tmpkey1;

for (int i = 0; i < 256; i++)
{
int right = ((3 - (i % 4)) * 8);
int left = ((i % 4)) * 8 + right;
_cryptKey1[i] ^= (byte)(tmpkey1 << right >> left);
_cryptKey2[i] ^= (byte)(tmpkey2 << right >> left);
}
}
}
Usage...


public AuthProtocolCryptographer ClientAuth = new AuthProtocolCryptographer();

Client.ClientAuth.Decrypt(Data);

That's all you have to do to modify the byte array in this case.

To re-encrypt it in this case you would be using

Client.ClientAuth.EncryptBackwards(Data);


So this means that in this situation and system of encryption you would use..

Client>Proxy = Decrypt

Proxy>Server = EncryptBackwards

Server>Proxy = DecryptBackwards

Proxy>Client = Encrypt
pro4never is offline  
Thanks
1 User
Old 10/29/2010, 18:43   #45
 
elite*gold: 0
Join Date: Jun 2006
Posts: 457
Received Thanks: 67
I managed to get that piece of code to work. It surprises me though... How is it that that piece of code works while my translated one doesn't. This kills ...

ADD:
forget about above. I have managed to get through the authorization and managed to log into the game. Now i need to edit the server IP and port described in the Auth Response packet to redirect my client to my proxy.

However i am not sure how should i read this Auth Response packet. The traditional way is to read the package in reverse order. But it doesn't quite work for me.
shitboi is offline  
Reply


Similar Threads Similar Threads
I need IPs and proxies
02/25/2010 - Conquer Online 2 - 16 Replies
Hello :) I hope to get help here. I am living in a hostel now because I moved from my hometown to study. And I have to use hostel's internet, where proxy is needed. Some websites and all the mmorpg games are banned here, but if you ask the administrator - he unblocks the game. But I have to give him IP addresses and proxies of CO. I tried to find it myself, found few, but I think, not every, because I can't still turn on the client (I'm not even talking about logging in). Can anyone...
Co proxies
01/12/2006 - Conquer Online 2 - 2 Replies
I have read many of topic about these hacks but... :ops: I didn't understand what they can really do exept jump anywhere, up/repair stuff from anywhere... Could some some list me best things every one could make ? :bandit: For example, what this one doing ? http://www.elitepvpers.com/forum/index.php?...& f=85&t=4579&s= i won't try them 1 by 1... :? edit : oops could u move it to main ? :rolleyes:



All times are GMT +2. The time now is 17:31.


Powered by vBulletin®
Copyright ©2000 - 2024, 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 ©2024 elitepvpers All Rights Reserved.