Kerberos Ticket - zeroKilo/GROBackendWV GitHub Wiki

Kerberos Ticket

A Kerberos ticket is used to authenticate a client to a secure server, the content is structured as following:

        public byte[] sessionKey;
        public uint serverPID;
        public byte[] ticketBuffer;

The session key is a 16-byte random key that is used for decrypting and encrypting other buffers. the server PID should match the connection string PID that was used before. the ticketBuffer contains unknown data, but 36 bytes of random data is ok too, because the client never has to process this.

After the content is created, it is encrypted with a key that's derived from the user PID. It uses the same RC4 encryption as used in the DATA QPackets. After that a 16 byte HMAC hash of the encrypted buffer is appended

Example Code for Generating

        public byte[] toBuffer()
        {
            MemoryStream m = new MemoryStream();
            m.Write(sessionKey, 0, 16);
            Helper.WriteU32(m, serverPID);
            Helper.WriteU32(m, (uint)ticket.Length);
            m.Write(ticket, 0, ticket.Length);
            byte[] buff = m.ToArray();
            byte[] key = Helper.DeriveKey(userPID);
            buff = Helper.Encrypt(key, buff);
            byte[] hmac = Helper.MakeHMAC(key, buff);
            m = new MemoryStream();
            m.Write(buff, 0, buff.Length);
            m.Write(hmac, 0, hmac.Length);
            return m.ToArray();
        }

        public static byte[] DeriveKey(uint pid, string input = "UbiDummyPwd")
        {
            uint count = 65000 + (pid % 1024);
            MD5 md5 = MD5.Create();
            byte[] buff = Encoding.ASCII.GetBytes(input);
            for (uint i = 0; i < count; i++)
                buff = md5.ComputeHash(buff);
            return buff;
        }

        public static byte[] MakeHMAC(byte[] key, byte[] data)
        {
            HMACMD5 hmac = new HMACMD5(key);
            return hmac.ComputeHash(data);
        }