smtddr's notes

[Things I find interesting]

Closer to punishing RageQuitters! authp response hash!

Well, the answer was simple as it turns out. I don’t know why I didn’t figure this out before.

GameSpy: \lc\1\challenge\GBUXGJFMQD\id\1\final\

Client: \auth\\gamename\tatvscapwii\response\
688e19f9eb5bdd11c8f150fba0044dd9\port\id\1\final\

GameSpy: \lc\2\sesskey\880746021\proof\id\1\final\

Client: \authp\\authtoken\NDSPo1/FGqZodpn7kGuLMtKPKUkZfzq5nqKv4RygeLPnoB2jY5HOe
/Z6KZseNl8UTSJAG/M5Ck6V+rzjGDHmTlsFAsy6UmYSZVW9TRsQdQf9S6mF7RnCESy
aEKTSCNbgSxH\resp\a5df2b71bbac23fc9f7a931364907656\lid\final\

GameSpy: \pauthr\249190728\lid\final\

Client: \setpd\\pid\249190728\ptype\3\dindex\kv\1\lid\length\217\data\\record\3MRWZ0gy
umuH4kUwtnVck2idXKbvVwTjWXCek+CYtlgQy8zk+wCGKch5zlZjRddLlAEyVwJ5C6qPc
SqOITNsSGx2M35OA3CAktNrshI2DTBMlDE_ElZGH8JVmbUH7gfOJp9hhC+7BEC6z1Tgh
szCo+1FM42HUekj4EKceXCFPtowQXBMfuT5AZ7r90pHfI6Ap1+fky6WBg12nzbf\final\

GameSpy: \setpdr\1\lid\pid\249190728\mod\1319906029\final\

Earlier, I discussed the login process that returned the authtoken string you see in the “authp” command. Now I know where the resp hash comes from.

Along with the token reply, a challenge is also returned from the nas-server. That challenge, plus the sesskey, creates the response hash.

Luigi.A has a C function that performs some “magic” on sesskeys from a much older game. Turns out it’s still the same.

I ported it to python. This is one block of code I don’t mind posting.

def gs_authpresponse(challenge,sesskey):
    subkey = ""
    i = 17
    initkey = hex(sesskey ^ 0x38f371e6)[2:]
    while len(initkey) < 8:
            initkey = "0"+initkey
    for q in range(len(initkey)):
            subkey += struct.pack("B",ord(initkey[q])+i)
            i += 1
    return hashlib.md5(challenge+subkey).hexdigest()

Specifically for the GameSpy traffic above, when the game logged in at https://naswii.nintendowifi.net, it got the above authtoken and a string “challenge=KDPMPT4U”. This challenge is random for each instance of logging in.

The challenge “KDPMPT4U” and sesskey 880746021 given to the python function above, will generate the md5 hash given in the authp-resp.

And that is it. I can login as myself and restore my stats to snapshots of any users I choose, purely from python code.

The login sent to naswii to get the authtoken and challenge has several variables, including the Wii’s serialnumber. However, changing all those variables seems to have no effect(aside from unitcd being changed gives me no authtoken at all) except for these:

userid=1608132906883 gsbrcd=STKJ0lo4c9r

Instinctively, you’d think the “password” here was that STKJ0lo4c9r thing. But it isn’t. It is trivial for me to get that string for any online player I see by using their ProfileID. There appears to be much more security around obtaining that 13 digit ID for an arbitrary user.

Now even stranger still, I can change either of those values arbitrarily(as long as I stay in their charsets) and the pauthr reply from GameSpy wii give me write-access to a different profileid even if the ProfileID didn’t exist before!(I know this because using “getpd”, returns nothing; meaning it hasn’t been used).

This is very important info that significantly affects the nature of what’s going on here. Namely, this means that there are actually no “accounts” per-se. GameSpy must be applying an algorithm to the gsbrcd and userid, to get a profileid. It then must dream-up an arbitrary challenge, blend it all together with the other values the Wii sent during login:

ingamesn=\x00S\x00M\x00T\x00@\x00D\x00D\x00R\x00\x20\x00\x20
sdkver=001000
gamecd=STKE
makercd=08
unitcd=1
macadr=0017ab4477c9
lang=01
devtime=111015082948
csnum=LU103421887
cfc=6236359535615891
region=01

All this combined must create the authtoken. Also, I’ve tampered with the communication to change the userid while the Wii was logging on in order for it to use a different, but valid, pair of challenge & authtoken. The Wii immediate errors without even trying to use it for authp — even though the userid and gsbrcd values are valid. That means, the Wii has the ability to decrypt the authtoken to see if it matches what it expects; not proceeding if it does not. Since I’ve already changed all the other values without causing the login & authp process to fail, it tells me that the Wii is not using any of the values above to verify. It must only be using the userid & gsbrcd values. Those are the ones that if I change them, the Wii quits as soon as it gets the authtoken from naswii.

This also means that the authtoken is worth the trouble of reversing after all, it cannot just be a random sessionID. It must be reversible into something that contains a a profileID and something that involves the challenge.

If I can find out what a userid is for a given profileID(or even better, reverse the authtoken to be able to make one from scratch) I can get pauthr for any profileID I choose. This would give me write-access to any profileID I want.

Then… I’d set all rage-quitters to an extremely reduced score.

Until next time! ^_^