Generating TS3 identities on the GPU

HMNiLK

Member
Apr 28, 2016
1
2
35
Hello,
I've got an idea that it might be possible to generate the security levels on the GPU instead of the CPU to get a much higher Hashrate (similar to Bitcoin Mining). In order to do that, it is required to find out, what is required for TS3 to accept it as a good hash at a certain security level.

According to some research, it is based on the proof-of-work algorithm Hashcash, generating hashes of a string plus an incrementing integer until the resulting hash fits a certain pattern ("good hash", e.g. a specific amount of 0-bits at the beginning or a match with another hash to a specific extend).

What we have is an UID and an "identity string".
The UID is completely static and doesnt change when increasing the security level, while the identity string does.
The UID contains exactly 28 Base64 characters. The identity string however, follows the following scheme: $integer."V".$(204 chars Base64). Also the Base64 encoded part of the identity string has to include the UID, because the identity string is the only information you get when exporting an identity to fully recover it later (including the UID).
What is also interesting is that the $(204 chars Base64) string of the identity string is decoded always the following pattern: $(100 bytes of random data).$(48 bytes Base64). These 48 Base64 chars decode to 51 random bytes. I dont know if these are common hashtypes of something, but I've provided them below.

I've already tried to compare the hashes of the identity string and those of the UID - neither the hashes of the identity string itself on different security levels nor these hashes compared to those of the UID dont seem to follow a clearly visible pattern. So my assumption is that the identity string gets somehow changed statically in the binary, hashed and after that compared to the hash of the UID. But I have no idea on how to approach that.

I currently have no further idea on how to continue searching for the pattern, so how should I start finding the correct pattern required for the hash to be a "good hash" with a certain security level?

As a reference, here are some UIDs, identity strings and their respective hashes (multiple algorithms):

UID:
Code:
8qHgturmuafPtYZL1/r4KKygY5M=
Hash: http://md5hashing.net/hash/sha1/5f8a0892ca4cc881b5b9e390c9cc824a1057e5b1
Security level 9:
Code:
123VvLO7dC2BHJhUPCJDOUS+FyUrdmEBJERdUXJXQQ51Xnw3WH9mdEpRVwodNwttMQdAB1xYZVNTCyEvUn0GV2BUQlFLYwFWHEEHDVR1CRcWJU4GH3BHPG15UWUqQFgaF3p8Bh8CB0pBQUNJRGV6a3YxTU92NFpER2k0UTRYMUJUdlE1YTlrQUNuT000b0djejRkUDVXUA==
Hash: http://md5hashing.net/hash/sha1/e90c54dfc5541a891bca52b5eb8ce13d60c22133
Security level 11:
Code:
2497VvLO7dC2BHJhUPCJDOUS+FyUrdmEBJERdUXJXQQ51Xnw3WH9mdEpRVwodNwttMQdAB1xYZVNTCyEvUn0GV2BUQlFLYwFWHEEHDVR1CRcWJU4GH3BHPG15UWUqQFgaF3p8Bh8CB0pBQUNJRGV6a3YxTU92NFpER2k0UTRYMUJUdlE1YTlrQUNuT000b0djejRkUDVXUA==
Hash: http://md5hashing.net/hash/sha1/f02ad243859dfa425b62168cd6b2da8e203ee25d
Security level 18:
Code:
3668VvLO7dC2BHJhUPCJDOUS+FyUrdmEBJERdUXJXQQ51Xnw3WH9mdEpRVwodNwttMQdAB1xYZVNTCyEvUn0GV2BUQlFLYwFWHEEHDVR1CRcWJU4GH3BHPG15UWUqQFgaF3p8Bh8CB0pBQUNJRGV6a3YxTU92NFpER2k0UTRYMUJUdlE1YTlrQUNuT000b0djejRkUDVXUA==
Hash: http://md5hashing.net/hash/sha1/f907bd591559152b71eef68da64c10389ff6c107
Security level 19:
Code:
264519VvLO7dC2BHJhUPCJDOUS+FyUrdmEBJERdUXJXQQ51Xnw3WH9mdEpRVwodNwttMQdAB1xYZVNTCyEvUn0GV2BUQlFLYwFWHEEHDVR1CRcWJU4GH3BHPG15UWUqQFgaF3p8Bh8CB0pBQUNJRGV6a3YxTU92NFpER2k0UTRYMUJUdlE1YTlrQUNuT000b0djejRkUDVXUA==
Hash: http://md5hashing.net/hash/sha1/eb4657828fa10015ab545818729106f61b14b395
Security level 21:
Code:
535594VvLO7dC2BHJhUPCJDOUS+FyUrdmEBJERdUXJXQQ51Xnw3WH9mdEpRVwodNwttMQdAB1xYZVNTCyEvUn0GV2BUQlFLYwFWHEEHDVR1CRcWJU4GH3BHPG15UWUqQFgaF3p8Bh8CB0pBQUNJRGV6a3YxTU92NFpER2k0UTRYMUJUdlE1YTlrQUNuT000b0djejRkUDVXUA==
Hash: http://md5hashing.net/hash/sha1/17dc4f7e3643915a9f6c29c5a1e1a2d8bf45a7c4
decodeBase64($(204 Base64 chars)):
http://www39.zippyshare.com/v/aLUoiWAt/file.html
decodeBase64($(48 Base64 chars)):
http://www39.zippyshare.com/v/7wTpRjSF/file.html
 
Last edited:

Splamy

TeamSpeak Developer
Apr 26, 2016
72
101
71
Your approach is wrong.
1. You dont hash the uid but the public key part of your identity ecdh key
2. The hash technique is sha1($id.$num)
3. The identity level is determined by the 0-bits at the beginning of the hash

Here is a reference implementation for cpu: https://github.com/Splamy/TS3AudioBot/blob/master/TS3Client/Full/Ts3Crypt.cs#L506-L574

I've also tried a bit with gpu calculating, ny numbers so far with a i5-2400 / gtx 970 were
~2.000.000 hashes/s on cpu
~10.000.000 hashes/s on gpu with a very bad own implementation

hashcat can make up to ~3.100.000.000 hashes/s on the gpu so there is definitly space for optimization.
  • For example your id, (extracted with this C# script):
    PHP:
    Encoding.ASCII.GetString(Convert.FromBase64String("vLO7dC2BHJhUPCJDOUS+FyUrdmEBJERdUXJXQQ51Xnw3WH9mdEpRVwodNwttMQdAB1xYZVNTCyEvUn0GV2BUQlFLYwFWHEEHDVR1CRcWJU4GH3BHPG15UWUqQFgaF3p8Bh8CB0pBQUNJRGV6a3YxTU92NFpER2k0UTRYMUJUdlE1YTlrQUNuT000b0djejRkUDVXUA=="))
  • results in:
    PHP:
    "???t-?\u001c?T<\"C9D?\u0017%+va\u0001$D]QrWA\u000eu^|7X\u007fftJQW\n\u001d7\vm1\a@\a\\XeSS\v!/R}\u0006W`TBQKc\u0001V\u001cA\a\rTu\t\u0017\u0016%N\u0006\u001fpG<myQe*@X\u001a\u0017z|\u0006\u001f\u0002\aJAACIDezkv1MOv4ZDGi4Q4X1BTvQ5a9kACnOM4oGcz4dP5WP"
  • This is your private key, the part you are interested in:
    PHP:
    "JAACIDezkv1MOv4ZDGi4Q4X1BTvQ5a9kACnOM4oGcz4dP5WP"
  • Base64 decode it and load it as an biginteger -> bigi
  • Restore the public key from that with ECNamedCurveTable.GetByName("prime256v1").G.Multiply(bigi).Normalize();
  • Export the key in libtomcrypt style and you got your $id from 2)
  • Now you can start bruteforcing higher levels...
 
Top