1: Background
1. Tell a story
I found a bug in the terminal of IOT cabinet a few days ago app.config The database connection string in is encrypted, because I want to switch the database during debugging, I need to put the ciphertext on a special tool to decrypt. After changing the database name on the connection string, I have to encrypt and paste it to the app.config The contents are as follows:
After fixing the bug, I thought that this thing can prevent who? I think that if I make such trouble, I will guard against the gentleman, like meexplain
Add or not encrypt is equal to no encryption, still give you out of the library…
2: Using ilspy to remove Library
1. Decompile the code from the DAL / repository layer
To get a clear text database connection string, you can infer it from the code, such as from theDAL
perhapsRepository
Find connection string field inConnectionString
The terminal program here is written in WPF, using the classic three-tier architecture, so in thebin
It can be easily found in the following figure:
Next, useILSPy
Decompile the 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 aDecrypt
Method is specially used to decrypt the connection string. Ha ha, with this algorithm, can we get rid of the database??? As shown in the following code:
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 "";
}
}
But fortunately, the database is also independently deployed on the customer side, there is no need to go outside the network, otherwise it will play big… Now let’s look at how to guard against it.
2. Shell / obfuscation / dongle
Now the commercial version and the free version on the market provide C ා code encryption and confusion, but I have not used it. I think it is only a matter of time to add some obstacles to the readability after decompiling the code. After all, you can’t confuse such FCL classes as SqlConnection and SqlCommand. I can easily find plaintext from these classes Connection string, so I don’t think this road is going to work.
3. Put the decryption algorithm on the server side
sinceDecryption algorithm
Buried in the client you can dig out, then put it on the server side can not it? When the program starts, call webapi to decrypt, so you always have no way??? Ha ha, you can use your mind to think about it. Is this feasible? It is true that the decryption algorithm has moved away, and it is no longer meaningful to use ilspy to dig. However, there is an important breakthrough here. No matter what form of decryption is used, the final plaintext of the connection string is stored in theOleDbHelper.ConnectionString
In this static variable, right! The next question is, is there any way to dig out the static variable in the process? You are right, that is to grab the dump file of the program and use WinDbg to dig it.
3: Using WinDbg to remove Library
1. Ideas
If you want to dig outOleDbHelper.ConnectionString
In fact, it is very simpleCLR via C#
In Chapter 4, there is such a picture about the object type and the interpretation of type object, which is very classic.
As you can see from the figure above, the static field is in theManager type object
The instance fields are all in theManager object
I just need to find it through WinDbgOledbhelper type object
That is to sayEEClass
。
2. WinDbg mining practice
- Use! Name2ee to find the 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
aboveMethodDesc: 08ed83b0
Is the address of the method descriptor.
- Use! Dumpmd to export the details of the method descriptor to find 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
aboveClass: 08ecab30
This is the memory address of the oledbhelper type object on the heap.
- Export using! Dumpclass
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 above export information, you can see that there are two static fields in the oledbhelper class:ConnectionString
andSecurityConnectionString
。
- Use! Do to print out two static fields
See, the two purple boxes in the above figure are plaintext connectionstring ha, how about that? no
4: Summary
When you realize the above two ways of taking off the database, you should be able to think of it. In fact, connecting to the database in the program is a mistake in itself. The operating system can give you piracy, not to mention a small piece of software? In my opinion, the way to completely eliminate this problem should be: kill the local SQL server and make all data acquisition provided by the remote webapi. Of course, this is divorced from the business chat technology!