• Welcome to Valhalla Legends Archive.
 

"Server Token"

Started by HydraPride, June 21, 2003, 11:56 PM

Previous topic - Next topic

HydraPride

The question:
WHAT IS THE SERVER TOKEN?

It's simple. How do I find it? Nobody seems to want to tell me how to find the server token. Rather, they just talk about other things when I try and get real information out of them. It's not like I haven't tried to find it; believe me, I have. Now I'm looking for answers.

Grok

It seems rather obvious, but I have to ask -- "Are you on a Token Ring Network?"

iago

Go to bnetdocs and search for it.  

What you'll find out is that it's a random-ish dword sent to you from battle.net in the packet s->SID_AUTH_INFO (0x50).
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


HydraPride

#3
Hmm.. thanks iago.. but that's what I've been using in my program and I still get 0x101 from packet 0x51S->C. everything else is correct, it seems. I just dont get it.

HydraPride

Does the client token have to maintain any consistency with anything?

DarkMinion


      case SID_AUTH_INFO: //0x50
         {
            dwNLSRevision = *(unsigned long *)(pszData + 4);
            dwSessionKey = *(unsigned long *)(pszData + 8); //Server key


As you can see it is the second DWORD in 0x50.  If you are using Warcraft II then it would be the second DWORD in packet 0x1d:


      case SID_OLD_SERVER_KEY: //0x1d
         dwSessionKey = *(unsigned long *)(pszData + 8); //Server key
         break;


It is used for things like password and cdkey hashing....for example here are it's uses with the old logon and cdkey packets.


void SendOLSPassword(char *szAccount, char *szPassword, unsigned long dwSessionKey)
{
   unsigned long dwPasswordHash[7];
   dwPasswordHash[0] = GetTickCount();
   dwPasswordHash[1] = dwSessionKey;
   calchashbuf(dwPasswordHash + 2, (char *)szPassword, strlen(szPassword));
   calchashbuf(dwPasswordHash + 2, dwPasswordHash, 7 * sizeof(unsigned long));
   dBuf.add(dwPasswordHash, 7 * sizeof(unsigned long));
   dBuf.add(szAccount);
   SendPacket(SID_OLS_PASSWORD);
}


And...


void SendOldCDKey(char *szCDKey, unsigned long dwSessionKey)
{
   unsigned long dwProductId, dwValue1, dwValue2, dwClientKey;
   dwClientKey = GetTickCount();
   DecodeCDKey(szCDKey, &dwProductId, &dwValue1, &dwValue2);
   dBuf.add((int)0);
   dBuf.add((int)strlen(szCDKey));
   dBuf.add(dwProductId);
   dBuf.add(dwValue1);
   dBuf.add(dwSessionKey);
   dBuf.add(dwClientKey);
   unsigned long dwHash[5], dwHash2[5];
   dwHash[0] = dwClientKey;
   dwHash[1] = dwSessionKey;
   dwHash[2] = dwProductId;
   dwHash[3] = dwValue1;
   dwHash[4] = dwValue2;
   calchashbuf(dwHash2, dwHash, 20);
   dBuf.add(dwHash2, 20);
   dBuf.add("DMBot");
   SendPacket(SID_OLD_CDKEY);
}


Hope this helps...

HydraPride

That does help , but I already had my answer. Now I'm still trying to figure out what the m'f is wrong with this. everything seems right, but I dont know about the hash data that I send. Maybe that's incorrect. Is there a new hashing function I should be aware of? Currently, I'm using something like prolix's.

DarkMinion

Paste the code you're using?

HydraPride

#8
DWORD numKeys   = 0x00000001;
DWORD bSpawn   = 0x00000000;
DWORD dwProgram   = 0x00000001;
DWORD dwKeyLen   = 0x0000000d;
DWORD dwKeyVal1 = b; // b is the "value 1" from decode.
                                      // this value is correct.
DWORD dwBlank   = 0x00000000;
DWORD dwClient   = GetTickCount();

// CALC HASH -- >

DWORD hashbuf[6], hash[5];

// set up hash buffer

hashbuf [ 0 ] = dwClient; // there's a space here because the forum is weird
                                     // doesnt accept some things
hashbuf[1] = dwServerToken;
hashbuf[2] = a;    // program id, the first return val
hashbuf[3] = b;    // val 1
hashbuf[4] = 0;    // 0
hashbuf[5] = c;    // val 2


sha1_hash((char*)hashbuf, 24, (char*)hash);


// END CALC HASH

// Setup for packet 0x51
char newDP[120];
dwBP *bpToken=new dwBP(NULL), *bpVersion=new dwBP(NULL), *bpChecksum=new dwBP(NULL), *bpNumKeys=new dwBP(NULL), *bpSpawn=new dwBP(NULL), *bpKeyLen=new dwBP(NULL), *bpProduct=new dwBP(NULL), *bpKeyVal1=new dwBP(NULL), *bpBlank=new dwBP(NULL), *bpHash[5];
for(int k=0; k<5; k++)
    bpHash[k]=new dwBP(NULL);

bpToken->SetNewBitsValue((DWORD)dwClient);
bpVersion->SetNewBitsValue((DWORD)lpdwVersion);
bpChecksum->SetNewBitsValue((DWORD)lpdwChecksum);
bpNumKeys->SetNewBitsValue((DWORD)numKeys);
bpSpawn->SetNewBitsValue((DWORD)bSpawn);
bpKeyLen->SetNewBitsValue((DWORD)dwKeyLen);
bpProduct->SetNewBitsValue((DWORD)dwProgram);
bpKeyVal1->SetNewBitsValue((DWORD)dwKeyVal1);
bpBlank->SetNewBitsValue((DWORD)dwBlank);




// I do stuff a little bit differently, and it's just an interim code
// snippet that i put together for the packets.
// I do set up packet 0x51 correctly... I've verified that.


Edit: use the code tag when pasting source.

c0ol

i dont totally understand ur packet buffer system, but assuming it works, is sha1_hash a normal sha1 hashing function, or one that works on bnet.  Bnet uses a non standard sha1 hashing function.

Arta

Are you using the correct hashing function? Battle.net doesn't use standard sha-1, they modified it.

Are you using the same Client Token in each packet that contains Client Token (hashed or otherwise)? This value should be the same every time you use it.

What is 'dwBP'? Whatever you're doing looks very strange. I hope you're freeing all that memory at some point.

HydraPride

#11
First, I am freeing the memory so dont worry.
=P
Second, Where can I get documentation on a hashing function that works? I'm using prolix's style hash right now.
Third, the client token does remain the same.

dwBP as I said is just some temporary thing until i get going
I just put it together in about 1 second.

I'd appreciate a link to some sort of proper hashing function. Thanks.

iago

You have to figure out the hashing system that battle.net uses, preferably by reverse engineering.  Hint: Check battle.snp ;-)
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


HydraPride

#13

void sha1_hash(void* lpSource, int nLength, void* lpResult)
{
 BYTE bBuffer[1024];
 int i;
 DWORD a, b, c, d, e, g, * lpdwBuffer;

 ZeroMemory(bBuffer, 1024);
 CopyMemory(bBuffer, lpSource, nLength);
 lpdwBuffer = (LPDWORD) bBuffer;

 for (i=0; i<64; i++)
     lpdwBuffer[i+16] = ROL(1, (lpdwBuffer[i] ^ lpdwBuffer[i+8] ^
                           lpdwBuffer[i+2] ^ lpdwBuffer[i+13]) % 32);
 a = 0x67452301lu;
 b = 0xefcdab89lu;
 c = 0x98badcfelu;
 d = 0x10325476lu;
 e = 0xc3d2e1f0lu;
 for (i = 0; i < (20 * 1); i++)
 {
     g = lpdwBuffer[i] + ROL(a,5) + e + ((b & c) | (~b & d)) + 0x5a827999lu;
     e = d;
     d = c;
     c = ROL(b,30);
     b = a;
     a = g;
 }
 for (; i < (20 * 2); i++)
 {
     g = (d ^ c ^ b) + e + ROL(g,5) + lpdwBuffer[i] + 0x6ed9eba1lu;
     e = d;
     d = c;
     c = ROL(b,30);
     b = a;
     a = g;
 }
 for (; i < (20 * 3); i++)
 {
     g = lpdwBuffer[i] + ROL(g,5) + e + ((c & b) | (d & c) | (d & b)) -
         0x70e44324lu;
     e = d;
     d = c;
     c = ROL(b,30);
     b = a;
     a = g;
 }
 for (; i < (20 * 4); i++)
 {
     g = (d ^ c ^ b) + e + ROL(g,5) + lpdwBuffer[i] - 0x359d3e2alu;
     e = d;
     d = c;
     c = ROL(b,30);
     b = a;
     a = g;
 }

 lpdwBuffer = (LPDWORD) lpResult;
 lpdwBuffer[0] = 0x67452301lu + g;
 lpdwBuffer[1] = 0xefcdab89lu + b;
 lpdwBuffer[2] = 0x98badcfelu + c;
 lpdwBuffer[3] = 0x10325476lu + d;
 lpdwBuffer[4] = 0xc3d2e1f0lu + e;
 return;
}



Above is the hashing function I use.
I had a different one, but I switched it with something I found on this board, and it still returns the same failure.

This makes me sad. I cannot open the file battle.snp, for it is too large for my windows to load. Wordpad, or whatever text program I use, locks up when I load the file. Lol






This is crap!!!

can anyone help me more specifically? pretty please =]

Zakath

It wouldn't do you a ton of good to open it in a text editor. You really need to open it in a disassembler :P
Quote from: iago on February 02, 2005, 03:07 PM
Yes, you can't have everybody...contributing to the main source repository.  That would be stupid and create chaos.

Opensource projects...would be dumb.