65.9K
CodeProject 正在变化。 阅读更多。
Home

黑客为什么喜欢字符串数据类型?

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.92/5 (116投票s)

2012年6月17日

CPOL

7分钟阅读

viewsIcon

153975

downloadIcon

1033

为防止存储在字符串数据类型中的敏感数据的威胁做好准备

引言

字符串数据类型经常用于在代码中存储硬编码的秘密。这些秘密可以是应用程序中使用的通用文字,如连接字符串,或特定业务的秘密(如优惠券代码、许可证密钥等)。事实是,绝大多数开发人员/应用程序都将敏感数据存储在字符串数据类型中,这使得黑客对其产生了极大的兴趣。在本文中,我们将演示黑客用来发现存储在字符串中的敏感信息的一些技术。

先澄清几点

在深入讨论之前,我想先绝对清楚地说明几点。首先,在本文中,我将演示黑客如何利用 JustDecompile、ILDASM 和 Windbg 等工具。重要的是要记住,这些工具都不是为了迎合黑客的兴趣而设计的。这些工具是出于合法目的而构建的,并且有充分的理由。这只是坏人利用相同的工具来实现自己的兴趣,而这些兴趣可能对他人造成潜在的危害。因此,了解黑客使用的技术非常重要,以便我们能够更好地准备,以抵御这些技术带来的特定威胁。

最后,本文绝不是关于我将要演示的威胁的防御机制。我将简要提及一些可以用来防御这些威胁的常见方法,但这并不是关于防御机制和方法的全面讨论。

是什么使得这类攻击成为可能?

在 CLR 执行模型下,您可以使用您喜欢的 .NET 语言(如 C#、Managed C++、VB.NET 等)编写代码。这些代码被编译成一种称为 Microsoft 中间语言 (MSIL) 的字节码。因此,您的应用程序或 .NET 程序集实际上包含中间语言形式的代码。当您执行应用程序时,在运行时,这些中间语言代码会被编译成本地 CPU 指令。将中间语言代码编译成本地指令的过程称为即时编译,也称为 JITting。

图 1:CLR 执行模型

这些 .NET 程序集中包含的中间语言非常详细,它保留了有关所有数据结构的信息,如类、字段、属性、方法、参数,甚至方法代码。这种高度冗长的中间语言的存在使得逆向工程 .NET 程序集变得非常简单,从而使攻击者无需访问实际源代码就能获取有价值的信息。

开始吧

为了在程序集中查找硬编码的秘密,您可以像 Telerik 的 JustDecompile 或 ILSpy 等 .NET 代码浏览器一样打开程序集。这些代码浏览器使您能够打开 .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() { }
    }

现在,让我们在 Telerik 的 JustDecompile 中打开已编译的可执行程序集。图 2 显示了此程序集的视图,您可以轻松地查看这些不应轻易泄露给任何人的字符串。

图 2:JustDecompile 中的 .NET 程序集

通常在实际应用程序中,通过在任何 .NET 代码浏览器(如 Telerik JustDecompile)中打开程序集(或一组程序集)来搜索字符串是一项繁琐的工作。今天的黑客很聪明,他们的武器库中有更高效的工具,可以有效地找到易受攻击的代码片段,并相应地规划下一次攻击。其中一个工具是中间语言反汇编器(也称为 ILDASM)。与 JustDecompile 类似,ILDASM 可用于反汇编 .NET 程序集并查看其代码,但使用 ILDASM,您只能以中间语言的形式查看此代码。

ILDASM 可以以两种模式运行,一种是使用其图形用户界面;另一种是使用命令行控制台。黑客通常更喜欢控制台模式的 ILDASM,特别是为了执行信息泄露攻击。图 3 显示了如何在命令行模式下使用 ILDASM 搜索 .NET 程序集代码中存在的字符串类型。

图 3:ILDASM 用于搜索 .NET 程序集中的字符串数据类型

我们使用了带 text 开关的 ILDASM,它基本上意味着将反编译的程序集显示在控制台窗口中。然后,该文本被管道传输到 findstr 命令。findstr 的参数是 ldstrldstr 是一个中间语言指令,用于将字符串加载到内存/求值堆栈中。从该命令的输出中可以看到,它仅列出了我们 .NET 程序集中的字符串,包括连接字符串、用户名、密码等敏感数据。

一种广泛用于保护知识产权和硬编码秘密的常见机制是混淆您的程序集。大多数商业混淆工具不仅使 .NET 代码更难被人阅读,而且还提供加密字符串类型等选项。下面图 4 展示了在混淆的程序集上运行时使用相同的 ILDASM 命令,其中字符串已加密。

图 4:ILDASM 用于在混淆的 .NET 程序集中搜索字符串数据类型

我想指出,程序集混淆和字符串加密绝非完美的解决方案。它确实为普通用户提供了一些保护,但是,有决心、有技能并且有足够时间的用户可以破解许多防御机制。

运行时秘密泄露

到目前为止,我们看到的是针对 .NET 程序集的“静态”攻击。字符串数据类型在运行时也容易发生秘密泄露。这意味着在运行时,黑客可以附加调试器并检查这些字符串数据类型中存储的数据。让我们看看这种类型的攻击是如何执行的。我将在此演示中使用 Windbg。Windbg 是一个本机调试器,它也可以借助扩展 DLL 来调试托管应用程序。Windbg 是“Windows 调试工具”的一部分,可以从 此处 下载。

让我们看看如何在运行时检查字符串秘密。当您启动演示应用程序时,会显示一个登录屏幕。在此演示应用程序中,我简化了一些内容,以便于理解。例如,通常在密码类型的字段中,您看不到用户键入的字符(而是为每个字符显示一个 *)。我进行的另一个简化是在用户单击“确定”按钮时显示一个消息框。在实际应用程序中,通常单击“确定”按钮会将用户带到新屏幕。我使用了此方法来简化附加 windbg 到正在运行的进程的过程。在 Windbg 中也有设置断点的方法。您可以在我的博客 此处 阅读一种设置断点的方法。

下图显示了演示中的登录屏幕。

图 5:登录屏幕

当您单击“确定”时,将出现一个对话框,显示登录失败。此时,启动 windbg 并将其附加到正在运行的进程。为此,您必须在“文件”菜单下选择“附加到进程”选项,如下所示。

图 6:“附加到进程”菜单选项

接下来,将出现以下对话框,供您选择要附加的正在运行的进程。

图 7:“附加到进程”对话框

此时,我们希望查看 .NET 托管堆并检查字符串数据类型实例。有多种方法可以做到。我将简单地使用 !strings 命令来完成。

图 8:运行 !strings 命令

!strings 命令的输出可能非常长,但我们为用户名和密码在文本框中输入的值应该在此处可见,如下所示。

图 9:运行时可见的秘密

Microsoft 提供了 SecureString 类,它可以帮助提供一些针对此类攻击的保护。请记住,人们已经找到了检查 SecureString 类的方法,以确定存储在 SecureString 中的字符串的实际值。

摘要

在本文中,我们讨论了为什么字符串数据类型特别引起黑客的兴趣。我们演示了一些黑客可以静态地以及在运行时使用的一些常见方法来发现存储在字符串数据类型中的敏感信息。希望下次您在代码中存储一些秘密时,会发现这些信息很有用。

历史

  • 首次发布:2012 年 6 月 16 日
  • 第二次发布:2012 年 6 月 17 日 - 更新了图片
© . All rights reserved.