示例#1
0
            public override void HandlePacket(LobbyClient client, ServerPacket packet)
            {
                var reader = packet.Reader;

                string realTag = reader.ReadUnicodeString(50);
                uint   accountPremium = reader.ReadUInt32();
                ulong  timeStamp = reader.ReadUInt64(), accountPermissions = reader.ReadUInt64();

                for (int i = 0; i < 5; i++)
                {
                    reader.ReadInt32();
                }

                ushort voicePortMin = reader.ReadUInt16(), voicePortMax = reader.ReadUInt16();
                uint   voiceAccountId = reader.ReadUInt32();
                string voiceUsername = reader.ReadASCIIString(17), voiceKey = reader.ReadASCIIString(17);

                RsaKeyParameters serverPub = WindowsRSA.ReadPublicKeyBlob(reader);
                string           countryCode = reader.ReadUnicodeString(), voiceURL = reader.ReadASCIIString();

                var generator = new RsaKeyPairGenerator();

                generator.Init(new KeyGenerationParameters(new SecureRandom(), 1024));
                AsymmetricCipherKeyPair clientKeyPair = generator.GenerateKeyPair();
                RsaKeyParameters        clientPub     = (RsaKeyParameters)clientKeyPair.Public;

                client.ClientDecryptEngine = new Pkcs1Encoding(new RsaEngine());
                client.ClientDecryptEngine.Init(false, clientKeyPair.Private);

                byte[] clientPubBlob = WindowsRSA.CreatePublicKeyBlob(clientPub);
                client.ServerEncryptEngine = new Pkcs1Encoding(new RsaEngine());
                client.ServerEncryptEngine.Init(true, serverPub);

                byte[] encryptedClientKey = WindowsRSA.EncryptData(client.ServerEncryptEngine, clientPubBlob);
                client.SetEncryptionKey(client.SrpKey);

                var keyExchange = new GC2LS_KEY_EXCHANGE(encryptedClientKey);

                client.SendPacket(keyExchange);

                client.OnLoginSuccess(client, null);
            }
示例#2
0
            public override void HandlePacket(LobbyClient client, ServerPacket packet)
            {
                var reader = packet.Reader;

                // Read data from packet
                uint hwVValue          = reader.ReadUInt32();
                int  encryptedDataSize = reader.ReadInt32();

                byte[] encryptedData = reader.ReadBytes(encryptedDataSize);

                // Decrypt data
                byte[] decryptedData = WindowsRSA.DecryptData(client._clientDecryptEngine, encryptedData);

                // Create reader for decrypted data
                var dataReader = new APBBinaryReader(new MemoryStream(decryptedData));

                string queryLanguage = dataReader.ReadASCIIString(4);

                if (queryLanguage != "WQL")
                {
                    Log.Warn($"Unexpected query language for WMI request ({queryLanguage})");
                    client.Disconnect();
                    return;
                }

                int numSections = dataReader.ReadInt32();
                int numFields   = dataReader.ReadInt32();

                XmlWriterSettings settings = new XmlWriterSettings();

                settings.OmitXmlDeclaration = true;

                // Create array to store hashes of sections
                var hashes = new List <byte[]>(numSections);

                // Create XML writer to write response for WMI queries
                StringBuilder hwBuilder = new StringBuilder();
                XmlWriter     hwWriter  = XmlWriter.Create(hwBuilder, settings);

                hwWriter.WriteStartElement("HW");
                hwWriter.WriteAttributeString("v", hwVValue.ToString());

                // Read each section, which contains data on a WQL query for the HW part of the response
                for (int i = 0; i < numSections; i++)
                {
                    byte   sectionNumber     = dataReader.ReadByte();
                    byte   sectionNameLength = dataReader.ReadByte();
                    string sectionName       = dataReader.ReadASCIIString(sectionNameLength + 1);
                    byte   skipHash          = dataReader.ReadByte();
                    byte   selectLength      = dataReader.ReadByte();
                    string selectClause      = dataReader.ReadASCIIString(selectLength + 1);
                    byte   fromLength        = dataReader.ReadByte();
                    string fromClause        = dataReader.ReadASCIIString(fromLength + 1);

                    Log.Info($"WMI Query: Section={sectionName}, SkipHash={skipHash}, Query=SELECT {selectClause} {fromClause}");

                    byte[] hash = client._hardwareStore.BuildWmiSectionAndHash(hwWriter, sectionName, selectClause, fromClause, (skipHash == 1));
                    if (hash != null)
                    {
                        hashes.Add(hash);
                    }
                }

                hwWriter.WriteEndElement();
                hwWriter.Flush();

                // Create the middle section, which is the first 4 bytes of each hash concatenated together
                byte[] hashBlock = new byte[4 * hashes.Count];
                for (int i = 0; i < hashes.Count; i++)
                {
                    Buffer.BlockCopy(hashes[i], 0, hashBlock, i * 4, 4);
                }

                // Now we need to prepare the BFP section, which in APB is done with similar code to that at https://github.com/cavaliercoder/sysinv/
                StringBuilder bfpBuilder = new StringBuilder();
                XmlWriter     bfpWriter  = XmlWriter.Create(bfpBuilder, settings);

                client._hardwareStore.BuildBfpSection(bfpWriter);
                bfpWriter.Flush();

                // Generate the hash for the BFP section
                byte[] bfpHash = client._hardwareStore.BuildBfpHash();

                // Generate the Windows information section
                byte[] windowsInfo = client._hardwareStore.BuildWindowsInfo();

                // Encrypt the BFP, HW, and hash sections with our public key
                byte[] hwUnicodeData  = Encoding.Unicode.GetBytes(hwBuilder.ToString());
                byte[] bfpUnicodeData = Encoding.Unicode.GetBytes(bfpBuilder.ToString());

                byte[] encryptedHWData    = WindowsRSA.EncryptData(client._serverEncryptEngine, hwUnicodeData);
                byte[] encryptedBFPData   = WindowsRSA.EncryptData(client._serverEncryptEngine, bfpUnicodeData);
                byte[] encryptedHashBlock = WindowsRSA.EncryptData(client._serverEncryptEngine, hashBlock);

                // Construct and send the response!
                var hardwareInfo = new GC2LS_HARDWARE_INFO(windowsInfo, 0, 0, client._hardwareStore.BfpVersion, bfpHash, encryptedHashBlock, encryptedBFPData, encryptedHWData);

                client.SendPacket(hardwareInfo);
            }
            public override void HandlePacket(LobbyClient client, ServerPacket packet)
            {
                var reader = packet.Reader;

                string realTag            = reader.ReadUnicodeString(50);
                uint   accountPremium     = reader.ReadUInt32();
                ulong  timeStamp          = reader.ReadUInt64();
                ulong  accountPermissions = reader.ReadUInt64();

                Log.Debug($"m_szRealTag = {realTag}");
                Log.Debug($"m_nAccountPremium = {accountPremium}");
                Log.Debug($"m_nTimestamp = {timeStamp}");
                Log.Debug($"m_nAccountPermissions = {accountPermissions}");

                for (int i = 0; i < 5; i++)
                {
                    Log.Debug($"m_nConfigFileVersion[{i}] = {reader.ReadInt32()}");
                }

                ushort voicePortMin   = reader.ReadUInt16();
                ushort voicePortMax   = reader.ReadUInt16();
                uint   voiceAccountId = reader.ReadUInt32();
                string voiceUsername  = reader.ReadASCIIString(17);
                string voiceKey       = reader.ReadASCIIString(17);

                Log.Debug($"m_nVoicePortMin = {voicePortMin}");
                Log.Debug($"m_nVoicePortMax = {voicePortMax}");
                Log.Debug($"m_nVoiceAccountID = {voiceAccountId}");
                Log.Debug($"m_szVoiceUsername = {voiceUsername}");
                Log.Debug($"m_szUnknownVoiceKey = {voiceKey}");

                // Read the server's public key
                RsaKeyParameters serverPub = WindowsRSA.ReadPublicKeyBlob(reader);

                // Read the rest of the packet data
                string countryCode = reader.ReadUnicodeString();
                string voiceURL    = reader.ReadASCIIString();

                Log.Debug($"m_nCountryCode = {countryCode}");
                Log.Debug($"m_szVoiceURL = {voiceURL}");

                // Create a new random RSA 1024 bit keypair for the client
                var generator = new RsaKeyPairGenerator();

                generator.Init(new KeyGenerationParameters(new SecureRandom(), 1024));
                AsymmetricCipherKeyPair clientKeyPair = generator.GenerateKeyPair();
                RsaKeyParameters        clientPub     = (RsaKeyParameters)clientKeyPair.Public;

                // Create the decryption engine for later
                client._clientDecryptEngine = new Pkcs1Encoding(new RsaEngine());
                client._clientDecryptEngine.Init(false, clientKeyPair.Private);

                // Put the client public key into the Microsoft Crypto API format
                byte[] clientPubBlob = WindowsRSA.CreatePublicKeyBlob(clientPub);

                // Create encryption engine with the server's public key
                client._serverEncryptEngine = new Pkcs1Encoding(new RsaEngine());
                client._serverEncryptEngine.Init(true, serverPub);

                // Encrypt the client key blob to send to the server
                byte[] encryptedClientKey = WindowsRSA.EncryptData(client._serverEncryptEngine, clientPubBlob);

                // Use the SRP key we calculated before
                client.SetEncryptionKey(client._srpKey);

                var keyExchange = new GC2LS_KEY_EXCHANGE(encryptedClientKey);

                client.SendPacket(keyExchange);

                client.OnLoginSuccess(client, null);
            }
示例#4
0
            public override void HandlePacket(LobbyClient client, ServerPacket packet)
            {
                var reader = packet.Reader;

                uint hwVValue          = reader.ReadUInt32();
                int  encryptedDataSize = reader.ReadInt32();

                byte[] encryptedData = reader.ReadBytes(encryptedDataSize);
                byte[] decryptedData = WindowsRSA.DecryptData(client.ClientDecryptEngine, encryptedData);
                var    dataReader    = new APBBinaryReader(new MemoryStream(decryptedData));

                string queryLanguage = dataReader.ReadASCIIString(4);

                if (queryLanguage != "WQL")
                {
                    client.Disconnect();
                    return;
                }

                int numSections = dataReader.ReadInt32(), numFields = dataReader.ReadInt32();

                XmlWriterSettings settings = new XmlWriterSettings();

                settings.OmitXmlDeclaration = true;

                var hashes = new List <byte[]>(numSections);

                StringBuilder hwBuilder = new StringBuilder();
                XmlWriter     hwWriter  = XmlWriter.Create(hwBuilder, settings);

                hwWriter.WriteStartElement("HW");
                hwWriter.WriteAttributeString("v", hwVValue.ToString());

                for (int i = 0; i < numSections; i++)
                {
                    byte   sectionNumber = dataReader.ReadByte(), sectionNameLength = dataReader.ReadByte();
                    string sectionName = dataReader.ReadASCIIString(sectionNameLength + 1);
                    byte   skipHash = dataReader.ReadByte(), selectLength = dataReader.ReadByte();
                    string selectClause = dataReader.ReadASCIIString(selectLength + 1);
                    byte   fromLength   = dataReader.ReadByte();
                    string fromClause   = dataReader.ReadASCIIString(fromLength + 1);
                    byte[] hash         = client.HardwareStore.BuildWmiSectionAndHash(hwWriter, sectionName, selectClause, fromClause, (skipHash == 1));
                    if (hash != null)
                    {
                        hashes.Add(hash);
                    }
                }

                hwWriter.WriteEndElement();
                hwWriter.Flush();

                byte[] hashBlock = new byte[4 * hashes.Count];
                for (int i = 0; i < hashes.Count; i++)
                {
                    Buffer.BlockCopy(hashes[i], 0, hashBlock, i * 4, 4);
                }

                StringBuilder bfpBuilder = new StringBuilder();
                XmlWriter     bfpWriter  = XmlWriter.Create(bfpBuilder, settings);

                client.HardwareStore.BuildBfpSection(bfpWriter);
                bfpWriter.Flush();

                byte[] bfpHash            = client.HardwareStore.BuildBfpHash();
                byte[] windowsInfo        = client.HardwareStore.BuildWindowsInfo();
                byte[] hwUnicodeData      = Encoding.Unicode.GetBytes(hwBuilder.ToString());
                byte[] bfpUnicodeData     = Encoding.Unicode.GetBytes(bfpBuilder.ToString());
                byte[] encryptedHWData    = WindowsRSA.EncryptData(client.ServerEncryptEngine, hwUnicodeData);
                byte[] encryptedBFPData   = WindowsRSA.EncryptData(client.ServerEncryptEngine, bfpUnicodeData);
                byte[] encryptedHashBlock = WindowsRSA.EncryptData(client.ServerEncryptEngine, hashBlock);
                var    hardwareInfo       = new GC2LS_HARDWARE_INFO(windowsInfo, 0, 0, client.HardwareStore.BfpVersion, bfpHash, encryptedHashBlock, encryptedBFPData, encryptedHWData);

                client.SendPacket(hardwareInfo);
            }