Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

Mushy v176 AES Userkey

Newbie Spellweaver
Joined
Jun 15, 2013
Messages
31
Reaction score
0
@Novak redirector works great for localhost, but clearly the cryptoKey is way outdated for v176.



Code:
private static byte[] CryptoKey = { (byte)0xB3, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,(byte)0x96, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00,(byte)0x99, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,(byte)0xD0, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00 };

My question for you all is how do you go about finding the UserKey for a particular version (v176)?

Thanks
 
(O_o(o_O(O_O)o_O)O_o)
Loyal Member
Joined
Apr 9, 2009
Messages
1,088
Reaction score
322
Psure you can just uhh, use Diamondo's getKey tool.
Or just as easy:

1. Open up your version in IDA and locate the CClientSocket funcs, for example ManupulatePacket Will do
IUv6Ejv - Mushy v176 AES Userkey - RaGEZONE Forums


2: With that func (and most others) you can super easily locate the decode related functions:
- CInpPacket::CInPacket (Inpacket buffer)
- CInPacket::DecryptData (AES decrypt)
- CInPacket::InnoHash (IV Shuffle)
- CInPacket::processPacket (Packet Handler)
And with these you ofc wanna go to the DecryptData func since we're looking for the AES key.
i4xMYCh - Mushy v176 AES Userkey - RaGEZONE Forums

Again.. Pretty straightforward. Now in versions 185+ or something you will have 2 decrypts (as shown in the image, i didn't give the new one a name yet) but in v176 just open CAESCipher::Decrypt (after naming/locating it ofc).

3: Open the first func mentioned in the sub
XfBPuca - Mushy v176 AES Userkey - RaGEZONE Forums

And see this:
Qof82Nq - Mushy v176 AES Userkey - RaGEZONE Forums

Which is the userkey.
PHP:
UserKeyTemp[0] = 41;
UserKeyTemp[1] = 179;
UserKeyTemp[2] = 136;
UserKeyTemp[3] = 32;
UserKeyTemp[4] = 246;
UserKeyTemp[5] = 191;
UserKeyTemp[6] = 2;
UserKeyTemp[7] = 72;
UserKeyTemp[8] = 24;
UserKeyTemp[9] = 91;
UserKeyTemp[10] = 118;
UserKeyTemp[11] = 16;
UserKeyTemp[12] = 94;
UserKeyTemp[13] = 218;
UserKeyTemp[14] = 15;
UserKeyTemp[15] = 135;
UserKeyTemp[16] = 202;
UserKeyTemp[17] = 94;
UserKeyTemp[18] = 205;
UserKeyTemp[19] = 159;
UserKeyTemp[20] = 90;
UserKeyTemp[21] = 12;
UserKeyTemp[22] = 245;
UserKeyTemp[23] = 41;
UserKeyTemp[24] = 64;
UserKeyTemp[25] = 213;
UserKeyTemp[26] = 156;
UserKeyTemp[27] = 126;
UserKeyTemp[28] = 97;
UserKeyTemp[29] = 47;
UserKeyTemp[30] = 48;
UserKeyTemp[31] = 40;
Since you have the key as an array of integers, you can go ahead and turn it into any format key as desired.



oh btw, that one is for v188. The key in mapleshark format would be:
PHP:
29B38820F6BF0248185B76105EDA0F87CA5ECD9F5A0CF52940D59C7E612F3028
and in odin format:
PHP:
new byte[]{
            (byte)0x29,(byte)0x00,(byte)0x00,
            (byte)0x00,(byte)0xF6,(byte)0x00,
            (byte)0x00,(byte)0x00,(byte)0x18,
            (byte)0x00,(byte)0x00,(byte)0x00,
            (byte)0x5E,(byte)0x00,(byte)0x00,
            (byte)0x00,(byte)0xCA,(byte)0x00,
            (byte)0x00,(byte)0x00,(byte)0x5A,
            (byte)0x00,(byte)0x00,(byte)0x00,
            (byte)0x40,(byte)0x00,(byte)0x00,
            (byte)0x00,(byte)0x61,(byte)0x00,
            (byte)0x00,(byte)0x00
        }

but since you are doing v176, here's that one:
PHP:
new byte[]  { (byte) 0xB3, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, (byte) 0x96, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, (byte) 0x99, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, (byte) 0xD0, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00 }
 

Attachments

You must be registered for see attachments list
Upvote 0
Newbie Spellweaver
Joined
Oct 10, 2016
Messages
8
Reaction score
0
Can you read my private message?



Psure you can just uhh, use Diamondo's getKey tool.
Or just as easy:

1. Open up your version in IDA and locate the CClientSocket funcs, for example ManupulatePacket Will do
IUv6Ejv - Mushy v176 AES Userkey - RaGEZONE Forums


2: With that func (and most others) you can super easily locate the decode related functions:
- CInpPacket::CInPacket (Inpacket buffer)
- CInPacket::DecryptData (AES decrypt)
- CInPacket::InnoHash (IV Shuffle)
- CInPacket::processPacket (Packet Handler)
And with these you ofc wanna go to the DecryptData func since we're looking for the AES key.
i4xMYCh - Mushy v176 AES Userkey - RaGEZONE Forums

Again.. Pretty straightforward. Now in versions 185+ or something you will have 2 decrypts (as shown in the image, i didn't give the new one a name yet) but in v176 just open CAESCipher::Decrypt (after naming/locating it ofc).

3: Open the first func mentioned in the sub
XfBPuca - Mushy v176 AES Userkey - RaGEZONE Forums

And see this:
Qof82Nq - Mushy v176 AES Userkey - RaGEZONE Forums

Which is the userkey.
PHP:
UserKeyTemp[0] = 41;
UserKeyTemp[1] = 179;
UserKeyTemp[2] = 136;
UserKeyTemp[3] = 32;
UserKeyTemp[4] = 246;
UserKeyTemp[5] = 191;
UserKeyTemp[6] = 2;
UserKeyTemp[7] = 72;
UserKeyTemp[8] = 24;
UserKeyTemp[9] = 91;
UserKeyTemp[10] = 118;
UserKeyTemp[11] = 16;
UserKeyTemp[12] = 94;
UserKeyTemp[13] = 218;
UserKeyTemp[14] = 15;
UserKeyTemp[15] = 135;
UserKeyTemp[16] = 202;
UserKeyTemp[17] = 94;
UserKeyTemp[18] = 205;
UserKeyTemp[19] = 159;
UserKeyTemp[20] = 90;
UserKeyTemp[21] = 12;
UserKeyTemp[22] = 245;
UserKeyTemp[23] = 41;
UserKeyTemp[24] = 64;
UserKeyTemp[25] = 213;
UserKeyTemp[26] = 156;
UserKeyTemp[27] = 126;
UserKeyTemp[28] = 97;
UserKeyTemp[29] = 47;
UserKeyTemp[30] = 48;
UserKeyTemp[31] = 40;
Since you have the key as an array of integers, you can go ahead and turn it into any format key as desired.



oh btw, that one is for v188. The key in mapleshark format would be:
PHP:
29B38820F6BF0248185B76105EDA0F87CA5ECD9F5A0CF52940D59C7E612F3028
and in odin format:
PHP:
new byte[]{
            (byte)0x29,(byte)0x00,(byte)0x00,
            (byte)0x00,(byte)0xF6,(byte)0x00,
            (byte)0x00,(byte)0x00,(byte)0x18,
            (byte)0x00,(byte)0x00,(byte)0x00,
            (byte)0x5E,(byte)0x00,(byte)0x00,
            (byte)0x00,(byte)0xCA,(byte)0x00,
            (byte)0x00,(byte)0x00,(byte)0x5A,
            (byte)0x00,(byte)0x00,(byte)0x00,
            (byte)0x40,(byte)0x00,(byte)0x00,
            (byte)0x00,(byte)0x61,(byte)0x00,
            (byte)0x00,(byte)0x00
        }

but since you are doing v176, here's that one:
PHP:
new byte[]  { (byte) 0xB3, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, (byte) 0x96, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, (byte) 0x99, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, (byte) 0xD0, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00 }

Can you read my private message?
 

Attachments

You must be registered for see attachments list
Upvote 0
Newbie Spellweaver
Joined
Jun 15, 2013
Messages
31
Reaction score
0
Thanks for the reply Novak!

So there is an additional crypto method that is unimplemented, do you have any more details on that? I can help with this.

Also for my knowledge, why does the redirector need to even touch encryption? Why can't the redirector simply accept the already encrypted packets from the client and just directly send them to my server?

Isn't this what happens when you connect to local host?

(EDIT) Oh, your pm said v18x requires new crypto method, so v176 should be good to go with your redirector, wonder why I am getting garbage opcodes to the server still then. As far as i can tell, client is delivering already encrypted packets to your redirector and redirector is encrypting yet again. Basically double encrypting, something smells funny here.
 
Upvote 0
(O_o(o_O(O_O)o_O)O_o)
Loyal Member
Joined
Apr 9, 2009
Messages
1,088
Reaction score
322
Also for my knowledge, why does the redirector need to even touch encryption? Why can't the redirector simply accept the already encrypted packets from the client and just directly send them to my server?

My redirectors actually have an option that enables this. The issue with it though is that you have to force the redirector to listen on all possible ports, as it can't read the ports from the packets. Meaning that unless you hardcode the IP's/Ports data goes to, you can't have different ports/ips on channels. Also my (old) redirectors that i released didn't kill old connections when new connections became active, so the server never knew you logged out or disconnected. Alltogether not as elegant a method as handling the data :p

So there is an additional crypto method that is unimplemented, do you have any more details on that? I can help with this.

The newer versions have two changes in cryptography that occurs after receiving a packet that's about 32k+ bytes in length.
1: The data coming from the server uses a new encryption algorithm
2: the data going from the client to the server has a new opcode encryption.

nr. 1 i've solved a while back and posted about on this forum. It's very simple to implement.
nr. 2 however i didn't (fully) figure out yet :( I'm close but i'm a bit of a noob so haven't completely tackled it yet.
 
Upvote 0
Newbie Spellweaver
Joined
Jun 15, 2013
Messages
31
Reaction score
0
So, basically the only reason you'd decrypt at the redirector is to get the port to redirect the packet to. Makes sense.

Code:
public static bool linkAllPorts = false; //AKA workOnAnyVersionButHaveBugsAndNotWorkOnOdinAtAll

I infer that is the option you're talking about?
What bugs does this have and why wouldn't it work on Odin?
 
Upvote 0
(O_o(o_O(O_O)o_O)O_o)
Loyal Member
Joined
Apr 9, 2009
Messages
1,088
Reaction score
322
So, basically the only reason you'd decrypt at the redirector is to get the port to redirect the packet to. Makes sense.

Code:
public static bool linkAllPorts = false; //AKA workOnAnyVersionButHaveBugsAndNotWorkOnOdinAtAll

I infer that is the option you're talking about?
What bugs does this have and why wouldn't it work on Odin?

Bugs is only the connections staying alive.

As far as "doesn't work on odin" goes, it's because odin has channel ip's/ports that are custom, and no nexon's ip. You'd have to change the channel's IP to nexon's on the server side. The redirector catches data going to nexon and redirects it somewhere else, if the client had received an IP to connect to that isn't nexon's, the client's outgoing data wouldn't be redirected. It's really just all bout that one packet that defines the channels' ip/port. If you set that thing to have nexon's IP, this method of redirection would work just fine.



Actually my bad, it's more like,

If you host channel 1 on IP a, and channel 2 on IP b, the redirector has to somehow know which IP it has to redirect data to. By reading the packet that defines the new connection's IP/port, the redirector can kill old connections, and connect to the new port/ip instead.

If you don't read this packet, the redirector can't really know which data is going where, especially if both ip's use the same port for the channels.
This means that source's that support channels on differen't IP's, could give you issues considering it's a pain to account for that in your redirector without just reading the packet that tells you what to do.
 
Upvote 0
Newbie Spellweaver
Joined
Jun 15, 2013
Messages
31
Reaction score
0
Bugs is only the connections staying alive.

As far as "doesn't work on odin" goes, it's because odin has channel ip's/ports that are custom, and no nexon's ip. You'd have to change the channel's IP to nexon's on the server side. The redirector catches data going to nexon and redirects it somewhere else, if the client had received an IP to connect to that isn't nexon's, the client's outgoing data wouldn't be redirected. It's really just all bout that one packet that defines the channels' ip/port. If you set that thing to have nexon's IP, this method of redirection would work just fine.



Actually my bad, it's more like,

If you host channel 1 on IP a, and channel 2 on IP b, the redirector has to somehow know which IP it has to redirect data to. By reading the packet that defines the new connection's IP/port, the redirector can kill old connections, and connect to the new port/ip instead.

If you don't read this packet, the redirector can't really know which data is going where, especially if both ip's use the same port for the channels.
This means that source's that support channels on differen't IP's, could give you issues considering it's a pain to account for that in your redirector without just reading the packet that tells you what to do.
That makes sense thanks.

regarding the unimplemented opcode encryption, presumably it is already correctly implemented on my v176 source otherwise I couldn't login and play my server on local host. I could just look at server encryption and implement that in redirect or correct?
 
Upvote 0
(O_o(o_O(O_O)o_O)O_o)
Loyal Member
Joined
Apr 9, 2009
Messages
1,088
Reaction score
322
regarding the unimplemented opcode encryption, presumably it is already correctly implemented on my v176 source otherwise I couldn't login and play my server on local host. I could just look at server encryption and implement that in redirect or correct?

This opcode encryption was added in v185+ or so lol. 176 doesn't have it. I did 176 myself too. I'm working on v188 now.
 
Upvote 0
Newbie Spellweaver
Joined
Oct 10, 2016
Messages
8
Reaction score
0
This opcode encryption was added in v185+ or so lol. 176 doesn't have it. I did 176 myself too. I'm working on v188 now.

thanks to ur fast reply novak!

however, can u read one more my lately private message?

sorry about request again but i need ur help ;_;
 
Upvote 0
Initiate Mage
Joined
Sep 25, 2016
Messages
2
Reaction score
0
This opcode encryption was added in v185+ or so lol. 176 doesn't have it. I did 176 myself too. I'm working on v188 now.
Did you ever finish anything on v188 that you're willing to share or hint about? In particular the client send op encryption.
 
Upvote 0
Back
Top