在现代软件开发中,字符串是存储敏感信息的常见方式,如连接字符串、优惠券代码、许可证密钥等。然而,这些信息往往成为黑客攻击的目标。本文将介绍黑客如何发现并利用这些隐藏在字符串中的秘密。
在深入讨论之前,需要明确几点。本文将展示黑客如何利用JustDecompile、ILDASM和WinDbg等工具。这些工具本身是为了合法目的而设计的,但黑客却可能利用它们进行攻击。因此,了解黑客的攻击手段对于更好地防御这些攻击至关重要。此外,本文不会全面讨论防御机制和方法论。
在.NET环境中,开发者可以使用C#、托管C++、VB.NET等语言编写代码,这些代码会被编译成中间语言(IL)。在运行时,IL代码会被即时编译(JIT)成CPU的原生指令。这种中间语言包含了详细的数据结构信息,使得逆向工程变得相对容易,从而让攻击者能够获取有价值的信息,而无需访问源代码。
要找到程序集中硬编码的秘密,可以使用.NET代码浏览器,如Telerik的JustDecompile或ILSpy等。这些工具允许打开.NET程序集并查看C#、VB.NET或中间语言形式的代码。以一个简单的示例应用程序为例,它包含一个名为Constants的类,用于存储敏感业务信息。
public class Constants
{
public static string ConnectionString = "Data Source=HOMEPC;Initial Catalog=MyDb;User Id=SpiderMan;Password=secret;";
public static string CouponCode50Pct = "AlphaBetaGamma50";
public static string CouponCode75Pct = "AlphaBetaGamma75";
public static string UserName = "SuperUser";
public static string Password = "SuperSecretPassword";
public Constants() { }
}
在JustDecompile中打开编译后的可执行程序集,如图2所示,可以轻松查看这些不应轻易泄露的字符串。
在现实应用中,通过打开程序集来搜索字符串是一项繁琐的工作。黑客通常会使用更高效的工具,如中间语言反汇编器(ILDASM)。与JustDecompile类似,ILDASM可以反汇编.NET程序集,但只能以中间语言的形式查看。
ILDASM有两种模式:图形用户界面和命令行界面。黑客通常更喜欢命令行模式,尤其是进行信息泄露攻击时。如图3所示,使用ILDASM命令行模式搜索.NET程序集中的字符串类型。
ildasm /text /item1:YourAssembly.dll | findstr /C:"ldstr"
这里使用了ILDASM的/text开关,意味着在控制台窗口中显示反汇编的程序集。然后使用findstr命令,其参数为ldstr,这是加载字符串到内存/评估栈的中间语言指令。从命令输出中,可以看到包括连接字符串、用户名、密码等敏感数据的字符串列表。
为了保护知识产权和硬编码的秘密,一种常见的机制是对程序集进行混淆。大多数商业混淆工具不仅使.NET代码难以阅读,还提供加密字符串类型的选项。如图4所示,当对混淆后的程序集运行相同的ILDASM命令时,字符串已被加密。
需要指出的是,程序集混淆和字符串加密并不是完美的解决方案。它确实可以防止一些普通用户,但有决心且具备一定技能的用户仍然可以破解许多防御机制。
到目前为止,所看到的都是对.NET程序集的“静态”攻击。字符串数据类型在运行时也容易泄露秘密。这意味着在运行时,黑客可以附加调试器并检查存储在这些字符串数据类型中的数据。
以WinDbg为例,它是一个原生调试器,也可以用于调试托管应用程序。WinDbg是“Windows调试工具”的一部分,可以在这里下载。
当运行演示应用程序时,会出现登录屏幕。为了便于理解,演示应用程序简化了一些内容。例如,通常在密码字段中,用户输入的字符不会被显示(而是显示*)。另一个简化是在用户点击OK按钮时显示消息框。在现实应用中,点击OK按钮通常会将用户带到新屏幕。这里使用这种方法是为了简化附加WinDbg到运行进程的过程。
如图5所示,是演示的登录屏幕。
点击OK后,会出现一个对话框,显示登录失败。此时,启动WinDbg并附加到运行的进程。如图6所示,选择“附加到进程”菜单选项。
接下来,将得到一个对话框,选择要附加的运行进程。如图7所示。
此时,希望查看.NET托管堆并检查字符串数据类型实例。有多种方法可以做到这一点。将简单地使用!strings命令来实现。如图8所示,运行!strings命令。
!strings命令的输出可能非常长,但在文本框中输入的用户名和密码值应该可以在这里看到,如图9所示。
Microsoft提供了SecureString类,可以帮助防止这类攻击。但需要注意的是,人们已经找到了检查SecureString类以确定存储在SecureString中的字符串实际值的方法。
本文讨论了为什么字符串数据类型对黑客特别感兴趣。展示了黑客如何静态地和在运行时发现存储在字符串数据类型中的敏感信息。希望这些信息对下次在代码中存储秘密时有所帮助。