How to crack encrypted database connection string

Keywords: Database

1: Background

1. Tell a story

A few days ago, when debugging a bug on the IOT cabinet terminal, I found that the database connection string in app.config is encrypted. To switch the database during debugging, I need to decrypt the ciphertext on a special gadget. After changing the database name on the connection string, I have to encrypt and paste it in app.config. It's annoying. The contents are as follows:

  <appSettings>
    <!-- Database connection string -->
    <add key="OLEDBConnStr" value="XfES27am6Muw48iB1GlMVqvUbq7/Pp9n4XbZJsDu19YDr/Zdb3m7KT6haD7f9HLj/ZEvIiZbmSU4O5L9g03Y5IUB6KLCZI7s3nDLwTIC+bXLf5quu/r8ZAI+rgNnsNZdwoDfquRLQy5Cf2X8/MFDOcMNaZYMpTYeHsZoEERU/TP9t3n5QllJTihrmDFbiGHLqe1kfN3uB3g1kgs0oobIEfNPr09kQ/pFgzZi/kZCrK10PLZZ0pFj1YU5ReFqBsdBlecV3D2Zl3lx1Ibls24t7w==" />
  </appSettings>

After fixing the bug, I thought this thing could be prevented. Who? I think it's a gentleman to prevent such trouble, like me   Xiaoren, whether you add encryption or not is equal to no encryption. I'll take you off the database anyway... 😄😄😄

2: Use ILSpy to take off the library

1. Decompile code from DAL/Repository layer

To get the plaintext database connection string, you can deduce it from the code, such as from   DAL   perhaps   Repository   Connection string field not found in   ConnectionString, the terminal program on my side is written in wpf and adopts the classic three-tier architecture, so   bin   It can be easily found in the following figure:

Next use   ILSPy   Decompile this dll.

As can be seen from the above figure, the plaintext of the connection string is stored in:   OleDbHelper.ConnectionString   Then you can see that one is defined in the program   Decrypt   This method is specially used to decrypt the connection string. Ha ha, with this algorithm, can we get rid of the database??? The following code is shown:

    class Program
    {
        static void Main(string[] args)
        {
            var str = "XfES27am6Muw48iB1GlMVqvUbq7/Pp9n4XbZJsDu19YDr/Zdb3m7KT6haD7f9HLj/ZEvIiZbmSU4O5L9g03Y5IUB6KLCZI7s3nDLwTIC+bXLf5quu/r8ZAI+rgNnsNZdwoDfquRLQy5Cf2X8/MFDOcMNaZYMpTYeHsZoEERU/TP9t3n5QllJTihrmDFbiGHLqe1kfN3uB3g1kgs0oobIEfNPr09kQ/pFgzZi/kZCrK10PLZZ0pFj1YU5ReFqBsdBlecV3D2Zl3lx1Ibls24t7w==";

            Console.WriteLine(Decrypt(str));
        }

        public static string Decrypt(string str)
        {
            if (!string.IsNullOrEmpty(str))
            {
                DESCryptoServiceProvider descsp = new DESCryptoServiceProvider();
                byte[] key = Encoding.Unicode.GetBytes("Oyea");
                byte[] data = Convert.FromBase64String(str);
                MemoryStream MStream = new MemoryStream();
                CryptoStream CStream = new CryptoStream(MStream, descsp.CreateDecryptor(key, key), CryptoStreamMode.Write);
                CStream.Write(data, 0, data.Length);
                CStream.FlushFinalBlock();
                return Encoding.Unicode.GetString(MStream.ToArray());
            }
            return "";
        }
    }

However, fortunately, the database is also deployed independently on the customer's side. There is no external network, otherwise it will play a big game... Next, let's see how to prevent it.

2. Shell / confuse / encrypt dog

Both the commercial version and the free version on the market now provide C# code encryption and confusion, but I haven't used it. I think it's only a matter of time. After all, you can't confuse the FCL classes such as SqlConnection and SqlCommand, I can easily find the plaintext ConnectionString by extrapolating from these classes, so I think this road is impassable.

3. Put the decryption algorithm on the server side

since   Decryption algorithm   You can dig it out on the client, so just put it on the server? When the program starts, call webapi to decrypt, so you have no choice??? Ha ha, you can use your brain to think about whether this method is feasible or not? It is true that the decryption algorithm has been removed and it is meaningless to dig with ILSpy, but there is an important breakthrough here. No matter what form of decryption is used, the final connection string plaintext is stored in   OleDbHelper.ConnectionString   In this static variable, right! The next question is whether there is a way to dig out this static variable in the process? You're right. Grab the dump file of the program and dig it with windbg.

3: Use windbg to remove the database

1. Ideas

To dig out   OleDbHelper.ConnectionString is also very simple. In   CLR via C#   In the fourth chapter, there is such a picture about object types and the interpretation of type objects, which is very classic.

As can be seen from the above figure, the static field is in the   Manager type object   In, instance fields are in   Manager object   In this figure, I just need to find it through windbg   OleDbHelper type object, that is, the so-called   EEClass.

2. windbg mining practice

  • use! name2ee found Decrypt method descriptor (MethodDesc)

0:000>  !name2ee xxx.Utilities.dll xxx.Utilities.Database.OleDbHelper.Decrypt
Module:      08ed7cdc
Assembly:    xxx.Utilities.dll
Token:       060002aa
MethodDesc:  08ed83b0
Name:        xxx.Utilities.Database.OleDbHelper.Decrypt(System.String)
JITTED Code Address: 048b6af0

above   MethodDesc: 08ed83b0   Is the address of the method descriptor.

  • use! dumpmd exports the details of the method descriptor and finds the EEClass address of the OleDbHelper type object

0:000> !dumpmd 08ed83b0
Method Name:  xxx.Utilities.Database.OleDbHelper.Decrypt(System.String)
Class:        08ecab30
MethodTable:  08ed8468
mdToken:      060002aa
Module:       08ed7cdc
IsJitted:     yes
CodeAddr:     048b6af0
Transparency: Critical

above   Class: 08ecab30   Is the memory address of the OleDbHelper type object on the heap.

  • use! dumpclass export   Class: 08ecab30  , To find the static field of the OleDbHelper class

0:000> !dumpclass 08ecab30
Class Name:      xxx.Utilities.Database.OleDbHelper
mdToken:         02000033
File:            D:\code\A18001\Source\Main\TunnelClient\bin\Debug\xxx.Utilities.dll
Parent Class:    795115b0
Module:          08ed7cdc
Method Table:    08ed8468
Vtable Slots:    4
Total Method Slots:  6
Class Attributes:    100081  Abstract,
Transparency:        Critical
NumInstanceFields:   0
NumStaticFields:     2
      MT    Field   Offset                 Type VT     Attr    Value Name
799bfd60  4000152       74        System.String  0   static 04c28270 ConnectionString
799bfd60  4000153       78        System.String  0   static 04c299e8 SecurityConnectionString

From the exported information above, you can see that there are two static fields in the OleDbHelper class:   ConnectionString   and   SecurityConnectionString.

  • use! do prints out two static fields

See, the two purple boxes in the figure above are plaintext ConnectionString, huh? 🐂 no 🐂.

4: Summary

When you realize the above two ways to remove the database, you should be able to think that in fact, it is a mistake for you to connect the database in the program. The operating system can pirate for you, not to mention your little software? I think the way to completely eliminate it should be to destroy the local SQL server and make all data acquisition provided by the remote webapi. Of course, this is divorced from business chat technology! 😄😄😄

Posted by porta325 on Sun, 28 Nov 2021 00:33:27 -0800