Jump to content

Mangos zero srp-6 authentication hashes


Recommended Posts

Hello all. This is my first time posting.


I'm trying to incrementally learn how mongos zero works. I've been working through the AuthSocket.cpp and related files to learn how the connection login works. Unfortunately c++ is not one of the languages I'm very familiar with so in order to learn I've been implementing the logic in Go.


So far I've learned all about SRP-6 and have written a Go library for it. In SRP-6 the implementor is able to chose the hashing algorithms for hashing the salt and password, and the verification of the server and client.


From the mangos zero code it would seem to hash the username and password with:

v = H(s, p)    where    p = sha1(username:password)

The verification of the client and the server also seem to use standard proof hashes:

User -> Host:  M = H(H(N) xor H(g), H(I), s, A, B, K)
Host -> User:  H(A, M, K)


I'm currently not having any luck authenticating with a running WoW client. I've written both the server and client code of the SRP-6 algorithm so I can quickly test hashes.


I've also read through the implementation in VB over at https://github.com/mangosvb/serverZero

Their implementation seems to be slightly different using Array.Reverse() several times on various variables.


I've posted my implementation thus far up on gitlab.




So my plead for help is does anyone who is familiar with the authentication logic know the details and might be able to help me figure out what the issue with my code is. 


Any information would be greatly appreciated. I'd like to contribute to the overall project, but I first need to get a grasp on how the basics work.

Link to comment
Share on other sites

Hello, I felt into the same position as you few months ago. Trying to understand how the SRP6 worked..

I finally succeeded to rewrite both server-side & client-side in Java. I've also decided to massively comment my code to avoid your situation again :)

Server side: https://github.com/Warkdev/JaNGOSAuth/blob/master/src/main/java/eu/jangos/auth/network/srp/SRPServer.java - See Step 1, Step 2 for the required arguments.

Client side: https://github.com/Warkdev/JaNGOSAuth/blob/master/src/test/java/eu/jangos/auth/utils/SRPClient.java

These classes are used in the following classes:

Server: https://github.com/Warkdev/JaNGOSAuth/blob/master/src/main/java/eu/jangos/auth/network/handler/AuthServerHandler.java

Client: https://github.com/Warkdev/JaNGOSAuth/blob/master/src/test/java/eu/jangos/auth/network/handler/AuthServerHandlerTest.java


Anyway, during my researches, I've found out that Blizzard did slightly modify the SRP6 algorithm towards the official one. It's a bad practice but it's how they work.

Link to comment
Share on other sites

Thanks for the help. 


Your code was much easy to follow. I cleaned up my code based on the work you've done. I'm still not having any luck with it, but I think I'm getting closer.


I'm going to take a detour and write a wow client spoofer now to try and debug things from that end.


Also, from the original paper http://srp.stanford.edu/srp6.ps in section 3 they discuss message ordering. Blizzard seems to be using the optimized message ordering in their implementation. So the only really unusual part of the implementation seems to be the zipper style hash used to calculate:

K = H(S)

From my understanding of the hash you fan out S then hash the two intermediate byte vectors and then weave them back together to get a byte vector K of length 40. You can check my implementation here to see if anything looks weird.   128 


Anyway thanks for the help. I'll probably come back to this later and be able to fix whatever the issue is when I have a clear head.

Link to comment
Share on other sites

Well, one thing you should be carefull at is my BigNumber class: https://github.com/Warkdev/JaNGOSAuth/blob/master/src/main/java/eu/jangos/auth/utils/BigNumber.java

The method "asByteArray" is very counter-intuitive. It's returning the corresponding byte array in the reverse order (always).

I think this may be your issue for the zipperHash. The array t is actually S reversed (32 bytes), later N is added in reverse order too (32 bytes), g in reverse order too (1 byte). Finally, everything is put together in BigNumber (setBinary is also reversing the array) and reversed again.

I remember my pain of debugging this protocol. :)

Link to comment
Share on other sites

I admit that I had to use several sources as well... from Mangos to MangosVB and also BunnyEmu.

At the end, I tried to get a more concise implementation with clear comments but it appears it's still not :)


Have fun debugging this ! However, I can promis you that both my client/server side works.

Link to comment
Share on other sites


This topic is now archived and is closed to further replies.

  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Privacy Policy Terms of Use