Hardline Dreams - A Python Matrix Online Server Project

Full Version: Auth Packets -> stopping randomizing!
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2 3
Hi at all,
we found something out (maybe its a very "stupid" solution at first) regarding this topic.

As we all know and you can see : normal Auth Server Packets (The TCP Packets on Port 11000 after launchpad UDP Session), are varied everytime (it is uninteresting what you send to the client).

We tried many things out, first the "send stupid the packets i got sniffed" solution. This doenst works, cause the client gerates at every session new packets which are encrypted.

So to make a session "real" you need to generate the same packets and
the same session, but how could this be done ?

A simple question with (at first!) stupid solution Smile

First we tried it with giving the srand command a static value (like 0 or something)...but this doesnt worked really...but for some reason at my one client , i thought it works...what i had forgot : i had tried something other before that Wink

As i saw in filemon, the client access many dlls , one of them was crypt32.dll .

So as all of us know , a programm searched first in his root folder for a library and then search all know pathes .

I have placed a empty file called "crypt32.dll" in the matrix online root folder, sniffed a auth session from real server connect and place this packets in my auth and launchpad enviroment.

And then stared client up with the empty crypt32.dll and see what happened....client send the same packets as sniffed from real to the auth server and after that i got connected to my test margin and test world server and entered the world.

Easy to reproduze :
1. create the dummy crypt32.dll file in your mxo directory.
2. start client and sniff a auth session with it.
3. replace the packets in your server sources (if you have).
4. start and have fun Wink

At the moment this seems to be good, but we must thing further : this only works on one client ...cause it seems that the MxO client generates something that changed the packet from PC to PC (i bet for a client hash checksum that is generated depend on the hardware and something more).

At all a small explanation about some auth packets too (what we found out too):

Packet 1 from Client
Example :
09 06 F1 1D 07 00 04 00 00 00
09 06 ->header
F1 1D 07-> not really know only that this is sent everytime

04 -> this is the RSA algorythm that is used..you can change this value by editing the pubkey.dat file...but if you fill out 00 Zero, the real server see that something is wrong and resend you the pubkey.dat in a packet.

Response 1 from Client Example
12 07 00 00 00 00 CF 88 44 4A 04 00 00 00 00 00
00 00 00

12 07 -> header
CF 88 44 4A -> timestamp in hex, but must be readed backwards..means :
4A 44 88 CF = 1246005455 = 26.06.2009 10:37:35
04 -> RSA Algo identifier

If you have an invalid pubkey or no pubkey.dat , you get an another answer with the public.key (to test this you can delete the key and see what real server answers you).

And important is that you cant gereate the timestamp by yourself cause its part of the encryption and as we dont know how the encryption really works and you dont have the secret key, there is no big chance to do something with it.

Packet 2 from client
80 AA 08 04 00 00 00 01 28 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 80 00 and them many encrypted data which varies.

We dont really know what the values means ..80 AA is the header sure, but dont know really the rest cause its encrypted.

If you view your memory with a cheat tool or something you can see that the encrypted part must be username and password and something else.

Response from Server 2
11 09 and 16 bytes with encrypted part.
11 09 is a header.

Client request 2
A packet with a header from 55 0A or 45 0A or 35 0A, depends on if you use launchpad and if you use qlsession or something with no user and password.

Dont really know for what this stand , we only know that the response is the server list.

For World Server list decryption see the topic from morpheus...one thing important there is , that there is a again a backwards readed timestamp , and there are two parts in the packets which are encrypted too.

And if you change only the timestamp you see that the encryption doesnt work cause you can an incompatble message.

So that was it for now Wink


make a crypt32.dll with just stubs, and have each function output printf that its been called...
that way you know which functions are being called
then you can add additional debugging info to them (output the parameters , break on execution, etc)
windows api, not like posix is a pain in the ass to get info about/api info, so we are screwed to some chinese webs or crap msdn info but i like your idea rajko.

The problem is that, at least as i expect, parameters to that callings will only be pointers to memory data, and nothing more (apart from some nulls, like microsoft way to do all). Apart from that, i would happily create one dll xD.


then go ahead

also, i made one like this, but im having trouble getting matrix.exe to actually load it
damn sxs, it keeps loading from system32
great, that saves a lot of work, as having the params on txt/c++ code leads us to knowing size and that things.

And we could always trick the client to look for it on local dir rajko, like watching memory till a c:\windows\system32\crypt32.dll appears and change to whatever, like same but cryp33, so we just overwrite on char on that path making it the same size, no longer, no shorter.

But it shall be done manually as all mods to matrix.exe lead to a corrupted file error when loading margin server (crc check, we suppose).

not so much time at the moment (few mins to go) but will try some things.

BTW we have found a way of turning random generations from client to static generations leading to a server full connection (no file corruption message), meaning that we always generate the same numbers when matrix.exe calls them. So our initial packet (connection ID) is always the same. Maybe it has any effect, but I think that static analysis of patterns > random things analysis.

Lot of work to do yet.


i want to do some tests, please send me whatever makes the packets static
also, about your first post...the first byte in tcp is how many bytes are in the packet...
(sometimes it could be 2 bytes if the packet is bigger)
so its
09 06 F1 1D 07 00 04 00 00 00

09 bytes make up the next packet (you have to do this in TCP because its STREAM, not DGRAM, so you might receive packets stuck one to another etc)

06 F1 1D 07 00 04 00 00 00

0x06 AS_GetPublicKeyRequest



i managed overloaded crypt32.dll to load, all i had to do was disable SafeDLLs in registry and reboot


the only crypt32.dll functions being called (and they arent called during auth) are
Which aren't supposed to be called by applications, their workings are undocumented...
so i guess they are being called by some other higher up dll, like advapi32.dll

and its obvious what its using advapi32.dll for...just generating random numbers...

CryptGenRandom is used both during auth and during margin login
Yes Morpheus told me that with a PM that we have to trace the CryptGenRandom .

I think this is for client hash generating...well i will check this the next days too.

What i could say is that client hash generating depends on some more things, like how you start the client (its a difference if you use -clone or the launcher for it, if you change values in the useropts etc.)..its very interesting.

Our goal must be to generate something, that works computer independent (like a "login bypass" or something).

Morpheus has regarding the cryptgen function some more information, maybe he can later say something here about itWink


only reason CryptGenRandom is called is because CryptoPP's NonblockingRng::GenerateBlock calls it. Matrix exclusively uses CryptoPP for all and any encryption/hash work
Pages: 1 2 3