简体   繁体   English

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

[英]Security internals of new operator and delegates in .NET

Some time ago I read about various security recommendations for C/C++. 前段时间我读到了有关C / C ++的各种安全建议。 After that I started thinking if they apply to .NET I found some answers but not all so here are my questions. 之后我开始思考他们是否适用于.NET我找到了一些答案,但并非所有答案都是如此,所以这里是我的问题。

It is a recommended to use HeapAlloc method instead of VirtualAlloc to allocate memory. 建议使用HeapAlloc方法而不是VirtualAlloc来分配内存。 There are 2 potential problems with VirtualAlloc that I'm aware of. 我知道VirtualAlloc有两个潜在的问题。 Firstly, prior to Windows 8, addresses allocated by this function are not randomized by ASLR (Address Space Layout Randomization). 首先,在Windows 8之前,ASLR(地址空间布局随机化)不会随机分配由此函数分配的地址。 Secondly, VirtualAlloc allow one to allocate memory using fixed base address what is also not suggested because makes writing exploits easier. 其次, VirtualAlloc允许使用固定的基址分配内存,这也是不建议的,因为使写入漏洞更容易。 For details see also this article . 有关详细信息,请参阅本文

The question is how new operator works under the hood? 问题是操作员如何在引擎盖下工作? Does it use HeapAlloc , VirtualAlloc or maybe something else? 它是否使用HeapAllocVirtualAlloc或其他东西?

It is also suggested to not use directly function pointers but to obfuscate and de-obfuscate them when needed by using EncodePointer / DecodePointer functions. 还建议不要直接使用函数指针,而是在需要时使用EncodePointer / DecodePointer函数对它们进行模糊处理和去模糊处理 It is a concept somehow similar to ASRL. 这是一个与ASRL类似的概念。 The goal of this technique is to make it difficult to predict a pointer value and override it so that it will point some malicious code. 这种技术的目标是难以预测指针值并覆盖它,以便它指向一些恶意代码。 We have delegates in .NET however I think that under the hood .NET must use function pointers at some point. 我们在.NET中有委托,但我认为在幕后.NET必须在某些时候使用函数指针。

The question is if addresses of functions pointers used internally by .NET are being obfuscated? 问题是.NET内部使用的函数指针的地址是否被混淆了?

Details are fairly obscure, I don't spend a lot of time looking for ways to attack .NET processes :) What I know is in place: 细节相当模糊,我不会花很多时间寻找攻击.NET进程的方法:)我所知道的是:

  • .NET assemblies have the /DYNAMICBASE option turned on, same one that native programs use to enable ASLR. .NET程序集启用了/ DYNAMICBASE选项,与本机程序用于启用ASLR的选项相同。
  • .NET assemblies have the /HIGHENTROPYVA option turned on by default. .NET程序集默认启用/ HIGHENTROPYVA选项。 The C# compiler exposes the /highentropyva compiler option to control this. C#编译器公开/ highentropyva编译器选项来控制它。
  • The CLR allocates exclusively with VirtualAlloc(). CLR仅使用VirtualAlloc()进行分配。 It implements its own brand of ASLR by randomizing the addresses of an appdomain's loader heap (jitted code, statics, types, etc) and the GC heap segments. 它通过随机化appdomain的加载器堆(jitted代码,静态,类型等)和GC堆段的地址来实现自己的ASLR品牌。 This occurs for every single run of the program. 每次运行程序都会发生这种情况。 The thread stacks are randomized too, probably because of the previous options. 线程堆栈也是随机的,可能是因为之前的选项。
  • Exception filters are located with a table lookup, not pointers on the stack. 异常过滤器位于表查找中,而不是堆栈上的指针。 Same as /SAFESEH 与/ SAFESEH相同
  • The native code in a .NET program (jitter, CLR, CRT) has /GS turned on since .NET 4.0, detects stack smashing attempts. .NET程序中的本机代码(jitter,CLR,CRT)自.NET 4.0开启/ GS后,检测到堆栈粉碎尝试。

No EncodePointer() calls, I doubt that they could work. 没有EncodePointer()调用,我怀疑他们可以工作。 I never heard of a successful attack against a .NET program, it is a pretty tall order to infect managed code with malicious data. 我从来没有听说过对.NET程序的成功攻击,用恶意数据感染托管代码是一个非常高的命令。 But who knows. 但谁知道呢。 There have been a fairly large number of security updates over the years so somebody figured out something :) 多年来已经有相当多的安全更新,所以有人想出了一些东西 :)

All of this only applies to you if you are using unsafe code or PInvoke (which also requires full trust). 所有这些仅适用于您使用不安全的代码或PInvoke(也需要完全信任)。 For safe managed code this issue does not apply because the CLR is specified in such a way that you cannot break memory safety. 对于安全的托管代码,此问题不适用,因为CLR的指定方式使您无法破坏内存安全性。 Therefore, there is nothing to exploit that can be prevented by randomizing addresses. 因此,通过随机化地址可以防止任何利用。 Addresses are not exposed in safe managed code (in any usable way). 地址不会以安全的托管代码(以任何可用的方式)公开。

Managed code new (as opposed to native new ) uses the managed heap. 托管代码new (与native new相对)使用托管堆。 Heap memory is fetched from the OS by using VirtualAlloc . 使用VirtualAlloc从操作系统获取堆内存。 I don't know whether it's location is randomized. 我不知道它的位置是否随机化。 Not every new invocation causes a new OS allocation. 并非每个new调用都会导致新的OS分配。 Many objects fit into one OS allocation. 许多对象适合一个OS分配。

delegate is indeed a function pointer under the hood. delegate确实是一个功能指针。 It is not obfuscated (presumably for performance reasons). 它没有被混淆(大概是出于性能原因)。 Most delegates point to jitted code on the code heap which, presumably, is allocated using VirtualAlloc (or loaded via LoadLibrary when NGEN is in use). 大多数代表指向代码堆上的jitted代码,可能是使用VirtualAlloc分配的(或者在NGEN使用时通过LoadLibrary加载)。

.NET assumes that your process is not being "hacked" by an attacker being able to write arbitrary bytes. .NET假定您的进程没有被攻击者能够写入任意字节的“黑客”攻击。 If that is the case all security guarantees are out of the window. 如果是这种情况,则所有安全保证都不在窗口内。

Therefore, I find the issues that you raise not particularly concerning. 因此,我发现你提出的问题并不特别重要。 This is a question of security in depth which is good to have but not required. 这是一个深度安全的问题,这个问题很好但不是必需的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM