配置文件中的数据库连接串加密了,你以为我就挖不出来吗?

运维 数据库运维
前几天在调试物联柜终端上的一个bug时发现 app.config 中的数据库连接串是加密的,因为调试中要切换数据库,我需要将密文放到专门的小工具上解密,改完连接串上的数据库名,还得再加密贴到 app.config 中,烦的要死。

[[337741]]

一:背景

1. 讲故事

前几天在调试物联柜终端上的一个bug时发现 app.config 中的数据库连接串是加密的,因为调试中要切换数据库,我需要将密文放到专门的小工具上解密,改完连接串上的数据库名,还得再加密贴到 app.config 中,烦的要死,内容如下:

改完bug之后,我就想这玩意能防的了谁呢?私以为搞这么麻烦也就防防君子,像我这样的 晓人,加不加密都是等于没加密,照样给你脱库。。。😄😄😄

二:使用 ILSpy 去脱库

1. 从DAL/Repository层去反编译代码

要想得到明文的数据库连接串,可以从代码中反推,比如从 DAL 或者 Repository 中找连接串字段 ConnectionString,我这边的终端程序是用 wpf 写的,采用的是经典的三层架构,所以在 bin 下可以轻松找到,如下图:

 

接下来用 ILSPy 反编译这个 dll。

 

从上图中可以看出,连接串的明文是存放在: OleDbHelper.ConnectionString 中的,然后可以看到,程序中定义了一个 Decrypt 方法专门用来解密连接串,哈哈,有了这个算法,是不是就可以脱库啦???如下代码所示:

  1. class Program 
  2.     { 
  3.         static void Main(string[] args) 
  4.         { 
  5.             var str = "XfES27am6Muw48iB1GlMVqvUbq7/Pp9n4XbZJsDu19YDr/Zdb3m7KT6haD7f9HLj/ZEvIiZbmSU4O5L9g03Y5IUB6KLCZI7s3nDLwTIC+bXLf5quu/r8ZAI+rgNnsNZdwoDfquRLQy5Cf2X8/MFDOcMNaZYMpTYeHsZoEERU/TP9t3n5QllJTihrmDFbiGHLqe1kfN3uB3g1kgs0oobIEfNPr09kQ/pFgzZi/kZCrK10PLZZ0pFj1YU5ReFqBsdBlecV3D2Zl3lx1Ibls24t7w=="
  6.  
  7.             Console.WriteLine(Decrypt(str)); 
  8.         } 
  9.  
  10.         public static string Decrypt(string str) 
  11.         { 
  12.             if (!string.IsNullOrEmpty(str)) 
  13.             { 
  14.                 DESCryptoServiceProvider descsp = new DESCryptoServiceProvider(); 
  15.                 byte[] key = Encoding.Unicode.GetBytes("Oyea"); 
  16.                 byte[] data = Convert.FromBase64String(str); 
  17.                 MemoryStream MStream = new MemoryStream(); 
  18.                 CryptoStream CStream = new CryptoStream(MStream, descsp.CreateDecryptor(keykey), CryptoStreamMode.Write); 
  19.                 CStream.Write(data, 0, data.Length); 
  20.                 CStream.FlushFinalBlock(); 
  21.                 return Encoding.Unicode.GetString(MStream.ToArray()); 
  22.             } 
  23.             return ""
  24.         } 
  25.     } 

 

不过还好,数据库也是在客户那边独立部署的,不存在走外网的情况,不然就玩大了。。。接下来我们来看看如何去防范。

2. 加壳/混淆/加密狗

现在市面上商业版和免费版都提供了给C#代码进行加密和混淆,不过我没用过,我想最多在反编译代码后阅读性上增加了一些障碍,这也不过是时间问题罢了,毕竟SqlConnection,SqlCommand 这些FCL的类你是没法混淆的,我从这些类上反推可以很轻松的就能找到明文的 ConnectionString ,所以这条路我觉得是走不通的。

3. 将解密算法放在 server 端

既然 解密算法 埋在客户端你都能挖出来,那把它放在 server 端不就可以啦?在程序启动的时候,调用一下 webapi 进行解密,这样你总没辙了吧 ???哈哈,大家可以开动脑子想一想,这种方法可行不可行?诚然,解密算法搬走了,再用 ILSpy 去挖已经没有任何意义了,但这里有一个重要突破点,不管是用什么形式解密的,最后的连接串明文都是存放在 OleDbHelper.ConnectionString 这个静态变量中,对吧!接下来的问题就是有没有办法把进程中的这个静态变量给挖出来?你说的对,就是抓程序的 dump文件 用 windbg 去挖。

三:使用 windbg 去脱库

1. 思路

要想挖出 OleDbHelper.ConnectionString,其实也很简单,在 CLR via C# 第四章中关于对象类型和类型对象的解读有这么一张图,很经典。

 

从上图中可以看到,静态字段是在 Manager 类型对象 中,实例字段都是在 Manager 对象 中,对照这张图,我只需要通过 windbg 找到 OleDbHelper 类型对象,也就是所谓的 EEClass。

2. windbg 挖矿实战

使用 !name2ee 找到 Decrypt 方法描述符(MethodDesc)

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

上面的 MethodDesc: 08ed83b0 就是方法描述符的地址。

使用 !dumpmd 导出方法描述符的详细信息,找到 OleDbHelper类型对象 的 EEClass 地址

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

上面的 Class: 08ecab30 就是 OleDbHelper类型对象 在堆上的内存地址。

使用 !dumpclass 导出 Class: 08ecab30 ,从而找到 OleDbHelper类的静态字段

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

从上面导出信息中可以看到 OleDbHelper类中 有两个静态字段: ConnectionString 和 SecurityConnectionString。

使用 !do 打印出两个静态字段

 

看到没有,上图中的两个紫色框框就是明文的 ConnectionString 哈,怎么样?🐂不🐂。

四:总结

 

当认识到上面的两种脱库方式,你应该就能想到,其实你在程序中连接数据库,这本身就是一种错,操作系统都能给你盗版,何况你这区区一个小软件?个人觉得完全杜绝的方式那应该就是:灭掉本地的sqlserver,让所有的数据获取都由远端的 webapi 提供,当然这又是在脱离业务聊技术啦!

本文转载自微信公众号「一线码农聊技术」,可以通过以下二维码关注。转载本文请联系一线码农聊技术公众号。

 

责任编辑:武晓燕 来源: 一线码农聊技术
相关推荐

2022-02-28 07:37:02

Java配置参数

2021-07-26 09:43:24

代码MapStructs项目

2023-09-21 15:20:49

算法开发

2023-02-07 13:51:11

SQLupdate语句

2021-01-06 10:52:02

MySQL数据库安全

2015-06-01 15:11:37

数据库update

2020-05-29 10:18:58

python开发代码

2017-12-13 14:41:45

2022-06-01 11:52:42

网站客户端网络

2022-11-21 10:49:29

Nacos配置加密

2011-03-28 13:25:27

MySQL数据库哈希加密

2011-08-22 16:08:48

2021-06-04 05:19:57

运营商用户投诉

2009-01-20 13:57:02

网络硬盘Google云计算

2009-02-09 12:52:32

文件加密Oracle数据库

2018-12-07 13:16:14

硬件元器件BOM

2021-10-18 09:09:16

数据库

2020-04-09 10:49:19

VMware主机配置

2023-11-07 08:36:34

JavaScriptJS挑战

2021-02-02 11:13:41

BigDecimal支付电商
点赞
收藏

51CTO技术栈公众号