.NET中新运算符和委托的安全性内部

时间:2015-04-09 09:04:18

标签: .net security .net-internals

前段时间我读到了有关C / C ++的各种安全建议。在那之后我开始思考他们是否适用于.NET我找到了一些答案,但不是全部,所以这里是我的问题。

建议使用HeapAlloc方法而不是VirtualAlloc来分配内存。我知道 VirtualAlloc 有两个潜在的问题。首先,在Windows 8之前,ASLR(地址空间布局随机化)不会随机分配由此函数分配的地址。其次, VirtualAlloc 允许一个人使用固定的基址分配内存,这也是不建议的,因为这使得编写漏洞更容易。有关详细信息,请参阅此article

问题是 new 运算符如何在引擎盖下工作?它是否使用 HeapAlloc VirtualAlloc 或者其他什么东西?

还建议不要直接使用函数指针,而是在需要时使用EncodePointer / DecodePointer 函数对它们进行模糊处理和去模糊处理。这是一个与ASRL类似的概念。这种技术的目标是难以预测指针值并覆盖它,以便它指向一些恶意代码。我们在.NET中有委托,但我认为在幕后.NET必须在某些时候使用函数指针。

问题是.NET内部使用的函数指针的地址是否被混淆了?

2 个答案:

答案 0 :(得分:3)

详细信息相当模糊,我不会花很多时间寻找攻击.NET进程的方法:)我所知道的是:

  • .NET程序集启用了/ DYNAMICBASE选项,与本机程序用于启用ASLR的选项相同。
  • .NET程序集默认启用/ HIGHENTROPYVA选项。 C#编译器公开/ highentropyva编译器选项来控制它。
  • CLR仅使用VirtualAlloc()进行分配。它通过随机化appdomain的加载器堆(jitted代码,静态,类型等)和GC堆段的地址来实现自己的ASLR品牌。每次运行程序都会发生这种情况。线程堆栈也是随机的,可能是因为之前的选项。
  • 异常过滤器的位置是表查找,而不是堆栈上的指针。与/ SAFESEH相同
  • .NET程序中的本机代码(jitter,CLR,CRT)自.NET 4.0起已启用/ GS,检测到堆栈粉碎尝试。

没有EncodePointer()调用,我怀疑他们可以工作。我从来没有听说过对.NET程序的成功攻击,用恶意数据感染托管代码是一个非常高的命令。但谁知道呢。这些年来有相当多的安全更新,所以有人想出了的东西:)

答案 1 :(得分:2)

如果您使用的是不安全的代码或PInvoke(也需要完全信任),所有这些仅适用于您。对于安全的托管代码,此问题不适用,因为CLR的指定方式使您无法破坏内存安全性。因此,通过随机化地址可以防止任何利用。地址不会以安全的托管代码(以任何可用的方式)公开。

托管代码new(与本机new相对))使用托管堆。使用VirtualAlloc从操作系统获取堆内存。我不知道它的位置是否随机化。并非每个new调用都会导致新的OS分配。许多对象适合一个操作系统分配。

delegate确实是一个功能指针。它没有被混淆(大概是出于性能原因)。大多数代表指向代码堆上的jitted代码,可能是使用VirtualAlloc分配的(或者在使用NGEN时通过LoadLibrary加载)。

.NET假定攻击者能够写入任意字节而不会“攻击”您的进程。如果是这种情况,所有安全保证都不在窗口。

因此,我发现你提出的问题并不特别重要。这是一个深度安全的问题,这个问题很好但不是必需的。