Beispiel #1
0
    public static void SendWardenPacket(ref Packets.PacketClass Packet)
    {
        // START Warden Encryption
        var b = new byte[(Packet.Data.Length - 6)];

        Buffer.BlockCopy(Packet.Data, 6, b, 0, b.Length);
        RC4.Crypt(ref b, Maiev.KeyOut);
        Buffer.BlockCopy(b, 0, Packet.Data, 6, b.Length);
        // END

        Worldserver.Send(Packet);
    }
Beispiel #2
0
        public byte[] EncryptText(EncryptTextMessage message)
        {
            byte[] encryptedText = null;
            //Odradi se enkripcija
            if (message.Algorithm == AlgorithmType.RC4)
            {
                RC4 rc = new RC4(message.Key, message.IV);
                encryptedText = rc.Crypt(message.Data);
            }
            else if (message.Algorithm == AlgorithmType.RC4CTR)
            {
                RC4 rc = new RC4(message.Key, message.IV);
                encryptedText = rc.CryptWithCTR(message.Data);
            }
            else if (message.Algorithm == AlgorithmType.A52 || message.Algorithm == AlgorithmType.A52CTR)
            {
                A52 alg = new A52();
                alg.SetKey(message.Key);
                alg.SetF(message.FKeyA52);

                if (message.Algorithm == AlgorithmType.A52)
                {
                    encryptedText = alg.Crypt(message.Data);
                }
                else
                {
                    alg.SetIV(message.IV);
                    encryptedText = alg.CryptWithCTR(message.Data);
                }
            }
            else if (message.Algorithm == AlgorithmType.RSA)
            {
                RSA rsa = new RSA();
                rsa.E = new BigInteger(message.Key);
                rsa.P = new BigInteger(message.P);
                rsa.Q = new BigInteger(message.Q);
                rsa.GenerateRSA();
                //BigInteger result = rsa.Crypt(new BigInteger(message.Data));
                //encryptedText = result.ToByteArray();
                encryptedText = rsa.Crypt(message.Data);
            }
            else if (message.Algorithm == AlgorithmType.TigerHash)
            {
                TigerHash th  = new TigerHash();
                byte[]    msg = message.Data;
                encryptedText = th.ComputeHash(message.Data);
            }
            return(encryptedText);
        }
Beispiel #3
0
        public bool LoadModule(string Name, ref byte[] Data, byte[] Key)
        {
            Key = RC4.Init(Key);
            RC4.Crypt(ref Data, Key);
            var UncompressedLen = BitConverter.ToInt32(Data, 0);

            if (UncompressedLen < 0)
            {
                Console.WriteLine("[WARDEN] Failed to decrypt {0}, incorrect length.", Name);
                return(false);
            }

            var CompressedData = new byte[(Data.Length - 0x108)];

            Array.Copy(Data, 4, CompressedData, 0, CompressedData.Length);
            var dataPos = 4 + CompressedData.Length;
            var Sign    = Conversions.ToString((char)Data[dataPos + 3]) + (char)Data[dataPos + 2] + (char)Data[dataPos + 1] + (char)Data[dataPos];

            if (Sign != "SIGN")
            {
                Console.WriteLine("[WARDEN] Failed to decrypt {0}, sign missing.", Name);
                return(false);
            }

            dataPos += 4;
            var Signature = new byte[256];

            Array.Copy(Data, dataPos, Signature, 0, Signature.Length);

            // Check signature
            if (CheckSignature(Signature, Data, Data.Length - 0x104) == false)
            {
                Console.WriteLine("[WARDEN] Signature fail on Warden Module.");
                return(false);
            }

            var          DecompressedData = new ZipService().DeCompress(CompressedData);
            MemoryStream ms = new(DecompressedData);
            BinaryReader br = new(ms);

            ModuleData = PrepairModule(ref br);
            ms.Close();
            ms.Dispose();
            br = null;
            Console.WriteLine("[WARDEN] Successfully prepaired Warden Module.");
            return(InitModule(ref ModuleData));
        }
Beispiel #4
0
        public Eeprom(string file)
        {
            Data = File.ReadAllBytes(file);

            if (Data.Length != Size)
            {
                throw new InvalidDataException("EEPROM must be 256 bytes.");
            }

            Stream = new MemoryStream(Data);
            Reader = new BinaryReader(Stream);
            Writer = new BinaryWriter(Stream);

            HmacSha1      sha     = new HmacSha1();
            RC4           rc4     = new RC4();
            EepromVersion version = 0;

            // loop through each version attempting to decrypt the security data
            while (version <= EepromVersion.RetailLast)
            {
                byte[] origHash = Data.Subset(0, 20);

                // decrypt according to the specified version
                rc4.Init(sha.Compute(version, origHash));
                byte[] decrypted = Data.Subset(0x14, 0x1C);
                rc4.Crypt(decrypted, 0, decrypted.Length);

                // if decrypted data hash matches the original then it's valid and the specific version is now known
                if (origHash.IsEqual(sha.Compute(version, decrypted)))
                {
                    // update with the decrypted data
                    Stream.Position = 0x14;
                    Writer.Write(decrypted);

                    // set the detected version
                    Version = version;
                    break;
                }

                version++;
            }
        }
Beispiel #5
0
        /// <summary>
        /// Saves the eeprom contents to file.
        /// If the version is unknown the security section will not be overwritten.
        /// </summary>
        /// <param name="file"></param>
        public void Save(string file)
        {
            UpdateChecksums();

            // skip writing security section if version is unknown
            if (Version == EepromVersion.Unknown)
            {
                using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Write, FileShare.None))
                {
                    fs.Position = 0x30;
                    fs.Write(Data, 0x30, Size - 0x30);
                }
            }
            else
            {
                // copy data to a separate buffer
                byte[] eepromCopy = new byte[Size];
                Data.CopyTo(eepromCopy, 0);

                // update security section of copy
                if (Version != EepromVersion.Unknown)
                {
                    HmacSha1 sha = new HmacSha1();
                    RC4      rc4 = new RC4();

                    // hash decrypted confounder/hddkey/region
                    byte[] hash = sha.Compute(Version, eepromCopy.Subset(0x14, 0x1C));
                    hash.CopyTo(eepromCopy, 0);

                    // re-encrypt data
                    rc4.Init(sha.Compute(Version, hash));
                    rc4.Crypt(eepromCopy, 20, 28);
                }

                File.WriteAllBytes(file, eepromCopy);
            }
        }
Beispiel #6
0
    public static void On_SMSG_WARDEN_DATA(ref Packets.PacketClass Packet)
    {
        // START Warden Decryption
        var b = new byte[(Packet.Data.Length - 4)];

        Buffer.BlockCopy(Packet.Data, 4, b, 0, b.Length);
        RC4.Crypt(ref b, Maiev.KeyIn);
        Buffer.BlockCopy(b, 0, Packet.Data, 4, b.Length);
        // END

        var WardenData = new byte[(Packet.Data.Length - 4)];

        Buffer.BlockCopy(Packet.Data, 4, WardenData, 0, WardenData.Length);
        MaievOpcode Opcode = (MaievOpcode)Packet.GetInt8();

        Console.ForegroundColor = ConsoleColor.Cyan;
        Console.WriteLine("SMSG_WARDEN_DATA [{0}]", Opcode);
        Console.ForegroundColor = ConsoleColor.White;
        switch (Opcode)
        {
        case MaievOpcode.MAIEV_MODULE_INFORMATION:
        {
            var Name = Packet.GetByteArray(16);
            var Key  = Packet.GetByteArray(16);
            var Size = Packet.GetUInt32();
            Maiev.ModuleName = BitConverter.ToString(Name).Replace("-", "");
            Maiev.ModuleKey  = Key;
            ModuleLength     = (int)Size;
            Maiev.ModuleData = Array.Empty <byte>();
            if (File.Exists(@"modules\" + Maiev.ModuleName + ".mod") == false)
            {
                Console.WriteLine("[{0}][WARDEN] Module is missing.", Strings.Format(DateAndTime.TimeOfDay, "HH:mm:ss"));
                Packets.PacketClass response = new(OPCODES.CMSG_WARDEN_DATA);
                response.AddInt8((byte)MaievResponse.MAIEV_RESPONSE_FAILED_OR_MISSING);
                SendWardenPacket(ref response);
                response.Dispose();
            }
            else
            {
                Console.WriteLine("[{0}][WARDEN] Module is initiated.", Strings.Format(DateAndTime.TimeOfDay, "HH:mm:ss"));
                Maiev.ModuleData = File.ReadAllBytes(@"modules\" + Maiev.ModuleName + ".mod");
                if (Maiev.LoadModule(Maiev.ModuleName, ref Maiev.ModuleData, Maiev.ModuleKey))
                {
                    Console.WriteLine("[{0}][WARDEN] Successfully loaded the module.", Strings.Format(DateAndTime.TimeOfDay, "HH:mm:ss"));
                    Packets.PacketClass response = new(OPCODES.CMSG_WARDEN_DATA);
                    response.AddInt8((byte)MaievResponse.MAIEV_RESPONSE_SUCCESS);
                    SendWardenPacket(ref response);
                    response.Dispose();
                }
                else
                {
                    Packets.PacketClass response = new(OPCODES.CMSG_WARDEN_DATA);
                    response.AddInt8((byte)MaievResponse.MAIEV_RESPONSE_FAILED_OR_MISSING);
                    SendWardenPacket(ref response);
                    response.Dispose();
                }
            }

            break;
        }

        case MaievOpcode.MAIEV_MODULE_TRANSFER:
        {
            var Size = Packet.GetUInt16();
            var Data = Packet.GetByteArray(Size);
            Maiev.ModuleData = Realmserver.Concat(Maiev.ModuleData, Data);
            ModuleLength    -= Size;
            if (ModuleLength <= 0)
            {
                Console.WriteLine("[{0}][WARDEN] Module is fully transfered.", Strings.Format(DateAndTime.TimeOfDay, "HH:mm:ss"));
                if (Directory.Exists("modules") == false)
                {
                    Directory.CreateDirectory("modules");
                }

                File.WriteAllBytes(@"modules\" + Maiev.ModuleName + ".mod", Maiev.ModuleData);
                if (Maiev.LoadModule(Maiev.ModuleName, ref Maiev.ModuleData, Maiev.ModuleKey))
                {
                    Console.WriteLine("[{0}][WARDEN] Successfully loaded the module.", Strings.Format(DateAndTime.TimeOfDay, "HH:mm:ss"));
                    Packets.PacketClass response = new(OPCODES.CMSG_WARDEN_DATA);
                    response.AddInt8((byte)MaievResponse.MAIEV_RESPONSE_SUCCESS);
                    SendWardenPacket(ref response);
                    response.Dispose();
                }
            }
            else
            {
                Console.WriteLine("[{0}][WARDEN] Module transfer. Bytes left: {1}", Strings.Format(DateAndTime.TimeOfDay, "HH:mm:ss"), ModuleLength);
            }

            break;
        }

        case MaievOpcode.MAIEV_MODULE_RUN:
        {
            Console.WriteLine("[{0}][WARDEN] Requesting a scan.", Strings.Format(DateAndTime.TimeOfDay, "HH:mm:ss"));

            // TODO: Encrypt?
            Maiev.ReadKeys2();
            RC4.Crypt(ref WardenData, Maiev.ModKeyIn);
            var HandledBytes = Maiev.HandlePacket(WardenData);
            if (HandledBytes <= 0)
            {
                return;
            }

            var thePacket = Maiev.ReadPacket();
            if (thePacket.Length == 0)
            {
                return;
            }

            RC4.Crypt(ref WardenData, Maiev.ModKeyOut);

            // TODO: Decrypt?

            Packets.DumpPacket(thePacket);
            Packets.PacketClass response = new(OPCODES.CMSG_WARDEN_DATA);
            response.AddByteArray(thePacket);
            SendWardenPacket(ref response);
            response.Dispose();
            break;
        }

        case MaievOpcode.MAIEV_MODULE_UNK:
        {
            // TODO: Encrypt?
            Maiev.ReadKeys2();
            RC4.Crypt(ref WardenData, Maiev.ModKeyIn);
            var HandledBytes = Maiev.HandlePacket(WardenData);
            if (HandledBytes <= 0)
            {
                return;
            }

            var thePacket = Maiev.ReadPacket();
            if (thePacket.Length == 0)
            {
                return;
            }

            RC4.Crypt(ref WardenData, Maiev.ModKeyOut);
            // TODO: Decrypt?

            Packets.DumpPacket(thePacket);
            Packets.PacketClass response = new(OPCODES.CMSG_WARDEN_DATA);
            response.AddByteArray(thePacket);
            SendWardenPacket(ref response);
            response.Dispose();
            break;
        }

        case MaievOpcode.MAIEV_MODULE_SEED:
        {
            Maiev.GenerateNewRC4Keys(Realmserver.SS_Hash);
            var HandledBytes = Maiev.HandlePacket(WardenData);
            if (HandledBytes <= 0)
            {
                return;
            }

            var thePacket = Maiev.ReadPacket();
            Maiev.ModKeyIn  = new byte[258];
            Maiev.ModKeyOut = new byte[258];
            Packets.PacketClass response = new(OPCODES.CMSG_WARDEN_DATA);
            response.AddByteArray(thePacket);
            SendWardenPacket(ref response);
            response.Dispose();
            Maiev.ReadKeys();
            break;
        }

        default:
        {
            Console.WriteLine("[{0}][WARDEN] Unhandled Opcode [{1}] 0x{2:X}", Strings.Format(DateAndTime.TimeOfDay, "HH:mm:ss"), Opcode, Conversions.ToInteger(Opcode));
            break;
        }
        }
    }
Beispiel #7
0
        public void On_CMSG_WARDEN_DATA(ref Packets.PacketClass packet, ref WS_Network.ClientClass client)
        {
            byte[] b = new byte[checked (packet.Data.Length - 6 - 1 + 1)];
            Buffer.BlockCopy(packet.Data, 6, b, 0, b.Length);
            RC4.Crypt(ref b, client.Character.WardenData.KeyOut);
            Buffer.BlockCopy(b, 0, packet.Data, 6, b.Length);
            packet.GetInt16();
            MaievResponse Response = (MaievResponse)packet.GetInt8();

            WorldServiceLocator._WorldServer.Log.WriteLine(LogType.DEBUG, "[{0}:{1}] CMSG_WARDEN_DATA [{2}]", client.IP, client.Port, Response);
            if (!client.Character.WardenData.Ready)
            {
                return;
            }
            switch (Response)
            {
            case MaievResponse.MAIEV_RESPONSE_FAILED_OR_MISSING:
                MaievSendTransfer(ref client.Character);
                break;

            case MaievResponse.MAIEV_RESPONSE_SUCCESS:
                MaievSendSeed(ref client.Character);
                break;

            case MaievResponse.MAIEV_RESPONSE_RESULT:
                MaievResult(ref client.Character, ref packet);
                break;

            case MaievResponse.MAIEV_RESPONSE_HASH:
            {
                byte[] hash = new byte[20];
                Buffer.BlockCopy(packet.Data, packet.Offset, hash, 0, 20);
                WorldServiceLocator._WS_Warden.Maiev.GenerateNewRC4Keys(client.Character.WardenData.K);
                byte[] PacketData = new byte[17]
                {
                    5,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0
                };
                Buffer.BlockCopy(client.Character.WardenData.Seed, 0, PacketData, 1, 16);
                int HandledBytes = WorldServiceLocator._WS_Warden.Maiev.HandlePacket(PacketData);
                if (HandledBytes <= 0)
                {
                    WorldServiceLocator._WorldServer.Log.WriteLine(LogType.CRITICAL, "[WARDEN] Failed to handle 0x05 packet.");
                    break;
                }
                byte[] thePacket = WorldServiceLocator._WS_Warden.Maiev.ReadPacket();
                byte[] ourHash   = new byte[20];
                Array.Copy(thePacket, 1, ourHash, 0, ourHash.Length);
                WorldServiceLocator._WS_Warden.Maiev.ReadXorByte(ref client.Character);
                WorldServiceLocator._WS_Warden.Maiev.ReadKeys(ref client.Character);
                WorldServiceLocator._WorldServer.Log.WriteLine(LogType.DEBUG, "[WARDEN] XorByte: {0}", client.Character.WardenData.xorByte);
                bool HashCorrect = true;
                int  i           = 0;
                do
                {
                    if (hash[i] != ourHash[i])
                    {
                        HashCorrect = false;
                        break;
                    }
                    i = checked (i + 1);
                }while (i <= 19);
                if (!HashCorrect)
                {
                    WorldServiceLocator._WorldServer.Log.WriteLine(LogType.CRITICAL, "[WARDEN] Hashes in packet 0x05 didn't match. Cheater?");
                }
                break;
            }

            case (MaievResponse)3:
                break;

            default:
                break;
            }
        }
Beispiel #8
0
        /////end RSA ---------------------------------------------------------


        /////RC4 ---------------------------------------------------------
        public byte[] RC4Crypt(byte[] input)
        {
            return(rc4.Crypt(input));
        }