• Welcome to Valhalla Legends Archive.
 

Finding an ecryption "salt"?

Started by Insolence, May 27, 2007, 04:18 PM

Previous topic - Next topic

Insolence

I'm just getting into Reverse Engineering, and I know a little C#.  I bought and (tried to) read Reversing: Secrets of Reverse Engineering, so if there's anything from that book I should examine more deeply, let me know :)

Anyway, I'm trying to reverse a packet encryption function for an online game, I wrote a C# program that uses SharpPcap to capture and filter packets.

With some help from my friend AntiRush I put a BP on WSARecv and I looked at the first few functions on the stack, and found this:004DBD46  |. 7D 12          JGE SHORT magic1.004DBD5A
004DBD48  |. 50             PUSH EAX
004DBD49  |. 68 44635700    PUSH magic1.00576344                     ;  ASCII "padDecrypt error %d"
004DBD4E  |. E8 F0F0FFFF    CALL magic1.004DAE43


I'm assuming that's where the packet is decrypted.  So, I googled padDecrypt and apparently it has to do with Rijndael encryption.  I went ahead and googled that too, and found that .NET has a RijndaelManaged class already built and setup for me.  Am I going too far to assume that this is the same encryption method used with this program?

Anyway, I wrote up some code to do Rijndael decrypting, but I noticed you need a "salt" along with the packet bytes.  I'm trying to figure out how to get the salt, I'm surprised I've gotten this far.

Here's the whole decryption function:
004DC22F   85C0             TEST EAX,EAX
004DC231   7E 06            JLE SHORT magic1.004DC239
004DC233   0183 88000000    ADD DWORD PTR DS:[EBX+88],EAX
004DC239   0105 FC539E01    ADD DWORD PTR DS:[19E53FC],EAX
004DC23F   0143 68          ADD DWORD PTR DS:[EBX+68],EAX
004DC242   8B93 88000000    |MOV EDX,DWORD PTR DS:[EBX+88]
004DC248   3BD7             CMP EDX,EDI
004DC24A   0F8C 03020000    JL magic1.004DC453
004DC250   8B4B 78          MOV ECX,DWORD PTR DS:[EBX+78]
004DC253   0FB641 01        MOVZX EAX,BYTE PTR DS:[ECX+1]
004DC257   0FB631           MOVZX ESI,BYTE PTR DS:[ECX]
004DC25A   C1E0 08          SHL EAX,8
004DC25D   03C6             ADD EAX,ESI
004DC25F   3B83 8C000000    CMP EAX,DWORD PTR DS:[EBX+8C]
004DC265   8945 FC          MOV DWORD PTR SS:[EBP-4],EAX
004DC268   0F8F E1010000    JG magic1.004DC44F
004DC26E   3BC2             CMP EAX,EDX
004DC270   7E 23            JLE SHORT magic1.004DC295
004DC272   2BC2             SUB EAX,EDX
004DC274   50               PUSH EAX
004DC275   03D1             ADD EDX,ECX
004DC277   52               PUSH EDX
004DC278   8BF3             MOV ESI,EBX
004DC27A   E8 161A0000      CALL magic1.004DDC95
004DC27F > 85C0             TEST EAX,EAX
004DC281   7E 06            JLE SHORT magic1.004DC289
004DC283   0183 88000000    ADD DWORD PTR DS:[EBX+88],EAX
004DC289   0105 FC539E01    ADD DWORD PTR DS:[19E53FC],EAX
004DC28F   0143 68          ADD DWORD PTR DS:[EBX+68],EAX
004DC292   8B45 FC          MOV EAX,DWORD PTR SS:[EBP-4]
004DC295   3B83 88000000    CMP EAX,DWORD PTR DS:[EBX+88]
004DC29B   0F85 B2010000    JNZ magic1.004DC453
004DC2A1   8B53 54          MOV EDX,DWORD PTR DS:[EBX+54]
004DC2A4   83A3 88000000 00 AND DWORD PTR DS:[EBX+88],0
004DC2AB   85D2             TEST EDX,EDX
004DC2AD   75 20            JNZ SHORT magic1.004DC2CF
004DC2AF   8B4B 78          MOV ECX,DWORD PTR DS:[EBX+78]
004DC2B2   66:8179 0A FFFF  CMP WORD PTR DS:[ECX+A],0FFFF
004DC2B8   75 0D            JNZ SHORT magic1.004DC2C7
004DC2BA   8B03             MOV EAX,DWORD PTR DS:[EBX]
004DC2BC   51               PUSH ECX
004DC2BD   8BCB             MOV ECX,EBX
004DC2BF   FF50 20          CALL DWORD PTR DS:[EAX+20]
004DC2C2   E9 A3010000      JMP magic1.004DC46A
004DC2C7   85D2             TEST EDX,EDX
004DC2C9   0F84 9B010000    JE magic1.004DC46A
004DC2CF   8BB3 80000000    MOV ESI,DWORD PTR DS:[EBX+80]
004DC2D5   8B4B 78          MOV ECX,DWORD PTR DS:[EBX+78]
004DC2D8   56               PUSH ESI
004DC2D9   83C0 FE          ADD EAX,-2
004DC2DC   03CF             ADD ECX,EDI
004DC2DE   50               PUSH EAX
004DC2DF   E8 90950300      CALL magic1.00515874
004DC2E4   85C0             TEST EAX,EAX
004DC2E6   7D 12            JGE SHORT magic1.004DC2FA
004DC2E8   50               PUSH EAX
004DC2E9   68 34645700      PUSH magic1.00576434                     ; ASCII "padDecrypt error %d"
004DC2EE > E8 F0F0FFFF      CALL magic1.004DB3E3
004DC2F3   59               POP ECX
004DC2F4   59               POP ECX
004DC2F5   E9 55010000      JMP magic1.004DC44F
004DC2FA   F643 2C 80       TEST BYTE PTR DS:[EBX+2C],80
004DC2FE   0F84 D7000000    JE magic1.004DC3DB
004DC304   8B83 80000000    MOV EAX,DWORD PTR DS:[EBX+80]
004DC30A   0FB610           MOVZX EDX,BYTE PTR DS:[EAX]
004DC30D   33C9             XOR ECX,ECX
004DC30F   8A48 01          MOV CL,BYTE PTR DS:[EAX+1]
004DC312   83C0 02          ADD EAX,2
004DC315   84C9             TEST CL,CL
004DC317   79 26            JNS SHORT magic1.004DC33F
004DC319   83E1 7F          AND ECX,7F
004DC31C   C1E1 08          SHL ECX,8
004DC31F   03CA             ADD ECX,EDX
004DC321   8BF1             MOV ESI,ECX
004DC323   56               PUSH ESI
004DC324   50               PUSH EAX
004DC325   8B43 78          MOV EAX,DWORD PTR DS:[EBX+78]
004DC328   83C0 08          ADD EAX,8
004DC32B   50               PUSH EAX
004DC32C   E8 EF2B0600      CALL magic1.0053EF20
004DC331   83C4 0C          ADD ESP,0C
004DC334   83C6 02          ADD ESI,2
004DC337   8975 FC          MOV DWORD PTR SS:[EBP-4],ESI
004DC33A   E9 AD000000      JMP magic1.004DC3EC
004DC33F   8365 FC 00       AND DWORD PTR SS:[EBP-4],0
004DC343   0FB6C9           MOVZX ECX,CL
004DC346   C1E1 08          SHL ECX,8
004DC349   03CA             ADD ECX,EDX
004DC34B   8B93 8C000000    MOV EDX,DWORD PTR DS:[EBX+8C]
004DC351   83EA 08          SUB EDX,8
004DC354   52               PUSH EDX
004DC355   8D55 FC          LEA EDX,DWORD PTR SS:[EBP-4]
004DC358   52               PUSH EDX
004DC359   51               PUSH ECX
004DC35A   894D F8          MOV DWORD PTR SS:[EBP-8],ECX
004DC35D   8B4B 78          MOV ECX,DWORD PTR DS:[EBX+78]
004DC360   83C1 08          ADD ECX,8
004DC363   50               PUSH EAX
004DC364   E8 E4430000      CALL magic1.004E074D
004DC369   83C4 10          ADD ESP,10
004DC36C   EB 5E            JMP SHORT magic1.004DC3CC
004DC36E   8BBB 8C000000    MOV EDI,DWORD PTR DS:[EBX+8C]
004DC374   81C7 00100000    ADD EDI,1000
004DC37A   E8 61D7F2FF      CALL magic1.00409AE0
004DC37F   FFB3 8C000000    PUSH DWORD PTR DS:[EBX+8C]
004DC385   8BF8             MOV EDI,EAX
004DC387   FF73 78          PUSH DWORD PTR DS:[EBX+78]
004DC38A   57               PUSH EDI
004DC38B   E8 902B0600      CALL magic1.0053EF20
004DC390   8B73 78          MOV ESI,DWORD PTR DS:[EBX+78]
004DC393   E8 684CF2FF      CALL magic1.00401000
004DC398   8183 8C000000 00>ADD DWORD PTR DS:[EBX+8C],1000
004DC3A2   897B 78          MOV DWORD PTR DS:[EBX+78],EDI
004DC3A5   8B83 8C000000    MOV EAX,DWORD PTR DS:[EBX+8C]
004DC3AB   83E8 08          SUB EAX,8
004DC3AE   50               PUSH EAX
004DC3AF   8D45 FC          LEA EAX,DWORD PTR SS:[EBP-4]
004DC3B2   50               PUSH EAX
004DC3B3   8B83 80000000    MOV EAX,DWORD PTR DS:[EBX+80]
004DC3B9   FF75 F8          PUSH DWORD PTR SS:[EBP-8]
004DC3BC   8BCF             MOV ECX,EDI
004DC3BE   83C1 08          ADD ECX,8
004DC3C1   40               INC EAX
004DC3C2   40               INC EAX
004DC3C3   50               PUSH EAX
004DC3C4   E8 84430000      CALL magic1.004E074D
004DC3C9   83C4 1C          ADD ESP,1C
004DC3CC   85C0             TEST EAX,EAX
004DC3CE  ^75 9E            JNZ SHORT magic1.004DC36E
004DC3D0   8B45 FC          MOV EAX,DWORD PTR SS:[EBP-4]
004DC3D3   83C0 02          ADD EAX,2
004DC3D6   8945 FC          MOV DWORD PTR SS:[EBP-4],EAX
004DC3D9   EB 11            JMP SHORT magic1.004DC3EC
004DC3DB   50               PUSH EAX
004DC3DC   8B43 78          MOV EAX,DWORD PTR DS:[EBX+78]
004DC3DF   83C0 08          ADD EAX,8
004DC3E2   56               PUSH ESI
004DC3E3   50               PUSH EAX
004DC3E4   E8 372B0600      CALL magic1.0053EF20
004DC3E9   83C4 0C          ADD ESP,0C
004DC3EC   8B73 78          MOV ESI,DWORD PTR DS:[EBX+78]
004DC3EF   8B4D FC          MOV ECX,DWORD PTR SS:[EBP-4]
004DC3F2   8D7E 0A          LEA EDI,DWORD PTR DS:[ESI+A]
004DC3F5   83C1 FC          ADD ECX,-4
004DC3F8   8BD7             MOV EDX,EDI
004DC3FA   E8 1CFCFFFF      CALL magic1.004DC01B
004DC3FF   66:3946 08       CMP WORD PTR DS:[ESI+8],AX
004DC403   74 54            JE SHORT magic1.004DC459
004DC405   FF75 FC          PUSH DWORD PTR SS:[EBP-4]
004DC408   68 0C645700      PUSH magic1.0057640C                     ; ASCII "ERROR: packet checksum failed, pktln=%d"
004DC40D   E8 D1EFFFFF      CALL magic1.004DB3E3
004DC412   0FB707           MOVZX EAX,WORD PTR DS:[EDI]
004DC415   50               PUSH EAX
004DC416   68 FC635700      PUSH magic1.005763FC                     ; ASCII "p->PktType = %d"
004DC41B   E8 C3EFFFFF      CALL magic1.004DB3E3
004DC420   0FB606           MOVZX EAX,BYTE PTR DS:[ESI]
004DC423   50               PUSH EAX
004DC424   68 E8635700      PUSH magic1.005763E8                     ; ASCII "p->SizeBuf[0] = %d"
004DC429   E8 B5EFFFFF      CALL magic1.004DB3E3
004DC42E   0FB646 01        MOVZX EAX,BYTE PTR DS:[ESI+1]
004DC432   50               PUSH EAX
004DC433   68 D4635700      PUSH magic1.005763D4                     ; ASCII "p->SizeBuf[1] = %d"
004DC438   E8 A6EFFFFF      CALL magic1.004DB3E3
004DC43D   0FB646 02        MOVZX EAX,BYTE PTR DS:[ESI+2]
004DC441   50               PUSH EAX
004DC442   68 C0635700      PUSH magic1.005763C0                     ; ASCII "p->RoutingType = %d"
004DC447   E8 97EFFFFF      CALL magic1.004DB3E3
004DC44C   83C4 28          ADD ESP,28
004DC44F   834B 2C 01       OR DWORD PTR DS:[EBX+2C],1
004DC453   33C0             XOR EAX,EAX
004DC455   5F               POP EDI
004DC456   5E               POP ESI
004DC457   C9               LEAVE
004DC458   C3               RETN


EDIT: Also, thanks for reading and/or replying to this thread, I appreciate it :D

EDIT: And here's my Rijndael implementation:
            RijndaelManaged RijndaelCipher = new RijndaelManaged();

            byte[] EncryptedData = packet.Bytes;
            byte[] Salt = new byte[5];//UNKNOWN;

            PasswordDeriveBytes SecretKey = new PasswordDeriveBytes(EncryptedData, Salt);

            // Create a decryptor from the existing SecretKey bytes.
            ICryptoTransform Decryptor = RijndaelCipher.CreateDecryptor(SecretKey.GetBytes(32), SecretKey.GetBytes(16));

            MemoryStream memoryStream = new MemoryStream(EncryptedData);

            // Create a CryptoStream. (always use Read mode for decryption).
            CryptoStream cryptoStream = new CryptoStream(memoryStream, Decryptor, CryptoStreamMode.Read);

            // Since at this point we don't know what the size of decrypted data
            // will be, allocate the buffer long enough to hold EncryptedData;
            // DecryptedData is never longer than EncryptedData.
            byte[] PlainText = new byte[EncryptedData.Length];

            // Start decrypting.
            int DecryptedCount = cryptoStream.Read(PlainText, 0, PlainText.Length-4);

            memoryStream.Close();
            cryptoStream.Close();

            // Convert decrypted data into a string.
            string DecryptedData = Encoding.Unicode.GetString(PlainText, 0, DecryptedCount);



Update:

I'm completely wrong about this.  That is just the packet filtering thing, not decryption, at least I don't think so.  I think this has to be where the decryption is happening:
004DC2C2   E9 A3010000      JMP magic1.004DC46A
004DC2C7   85D2             TEST EDX,EDX
004DC2C9   0F84 9B010000    JE magic1.004DC46A
004DC2CF   8BB3 80000000    MOV ESI,DWORD PTR DS:[EBX+80]
004DC2D5   8B4B 78          MOV ECX,DWORD PTR DS:[EBX+78]
004DC2D8   56               PUSH ESI                                 ; Param 1
004DC2D9   83C0 FE          ADD EAX,-2
004DC2DC   03CF             ADD ECX,EDI
004DC2DE   50               PUSH EAX                                 ; Param 2
004DC2DF   E8 90950300      CALL magic1.00515874                     ; Decryption
004DC2E4   85C0             TEST EAX,EAX
004DC2E6   7D 12            JGE SHORT magic1.004DC2FA
004DC2E8   50               PUSH EAX
004DC2E9   68 34645700      PUSH magic1.00576434                     ; ASCII "padDecrypt error %d"


I assume magic1.00515874 is the padDecrypt function, but I don't understand what it's returning.  I also don't understand what parameters are being passed to it, ESI and EAX?  I couldn't find any padDecrypt functions online that took two parameters, but I'm assuming it's a specialized function inside a class with they key set as a property.  Something like
byte[] padDecrypt(byte[] packet, byte[] outbuffer)
{
     Salt theSalt = this.Salt;
    //....etc.
}


Edit:
004DC2CF   8BB3 80000000    MOV ESI,DWORD PTR DS:[EBX+80]
004DC2D5   8B4B 78          MOV ECX,DWORD PTR DS:[EBX+78]
004DC2D8   56               PUSH ESI                                 ; Param 1
004DC2D9   83C0 FE          ADD EAX,-2
004DC2DC   03CF             ADD ECX,EDI
004DC2DE   50               PUSH EAX                                 ; Param 2
Based on that book, EBX seems to be a class, something like this
struct Something
{
    UNKNOWN    Member1; // [EBX+78]
    UNKNOWN    Member2; // [EBX+80]
}


I'll look through and try to find out where they get EBX from.

Edit#2:
Found two other members, I suppose:
struct Something
{
    UNKNOWN    Member1; // [EBX+68]
    UNKNOWN    Member2; // [EBX+78]
    UNKNOWN    Member3; // [EBX+80]
    UNKNOWN    Member4; // [EBX+88]
}


Edit #3:
I'm going to assume it's the packet class, because of these guys:
004DC3FF   66:3946 08       CMP WORD PTR DS:[ESI+8],AX
004DC403   74 54            JE SHORT magic1.004DC459
004DC405   FF75 FC          PUSH DWORD PTR SS:[EBP-4]
004DC408   68 0C645700      PUSH magic1.0057640C                     ; ASCII "ERROR: packet checksum failed, pktln=%d"
004DC40D   E8 D1EFFFFF      CALL magic1.004DB3E3
004DC412   0FB707           MOVZX EAX,WORD PTR DS:[EDI]
004DC415   50               PUSH EAX
004DC416   68 FC635700      PUSH magic1.005763FC                     ; ASCII "p->PktType = %d"
004DC41B   E8 C3EFFFFF      CALL magic1.004DB3E3
004DC420   0FB606           MOVZX EAX,BYTE PTR DS:[ESI]
004DC423   50               PUSH EAX
004DC424   68 E8635700      PUSH magic1.005763E8                     ; ASCII "p->SizeBuf[0] = %d"
004DC429   E8 B5EFFFFF      CALL magic1.004DB3E3
004DC42E   0FB646 01        MOVZX EAX,BYTE PTR DS:[ESI+1]
004DC432   50               PUSH EAX
004DC433   68 D4635700      PUSH magic1.005763D4                     ; ASCII "p->SizeBuf[1] = %d"
004DC438   E8 A6EFFFFF      CALL magic1.004DB3E3
004DC43D   0FB646 02        MOVZX EAX,BYTE PTR DS:[ESI+2]
004DC441   50               PUSH EAX
004DC442   68 C0635700      PUSH magic1.005763C0                     ; ASCII "p->RoutingType = %d"


I also noticed in my first post the disassembled method is cut off early, I left out the code after the switch/case statements, I think.  Fixed that.

I added more members I found, and infered their values from above:
struct Packet
{
    UNKNOWN    Member1; // [EBX+54]
    UNKNOWN    Member2; // [EBX+68]
    WORD       SizeBuf; // [EBX+78]
    WORD       RoutingType; // [EBX+80]
    BYTE[?]    PktType; // [EBX+82]
    UNKNOWN    Member5; // [EBX+88]
    UNKNOWN    Member6; // [EBX+2C]
    UNKNOWN    Member7; // [EBX+8C]
}


Edit #3:
004DC4AA   . B9 8C635700    MOV ECX,magic1.0057638C                  ;  ASCII "0xd4a0ba0250b6fd2ec626e7efd637df76c716e22d0944b88b"
I was researching that constant ASCII hex value, and apparently it's a prime public key (I think).  So, from that I need to make a private key to decrypt the AES (Rijindael(sp)) stuff.

warz

What game is this, if you don't mind me asking?

Insolence

Oh, of course I don't mind--Magic The Gathering: Online :)