Security internals of new operator and delegates in .NET

190 views Asked by At

Some time ago I read about various security recommendations for C/C++. After that I started thinking if they apply to .NET I found some answers but not all so here are my questions.

It is a recommended to use HeapAlloc method instead of VirtualAlloc to allocate memory. There are 2 potential problems with VirtualAlloc that I'm aware of. Firstly, prior to Windows 8, addresses allocated by this function are not randomized by ASLR (Address Space Layout Randomization). Secondly, VirtualAlloc allow one to allocate memory using fixed base address what is also not suggested because makes writing exploits easier. 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?

It is also suggested to not use directly function pointers but to obfuscate and de-obfuscate them when needed by using EncodePointer/DecodePointer functions. It is a concept somehow similar to 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.

The question is if addresses of functions pointers used internally by .NET are being obfuscated?

2

There are 2 answers

5
usr On

All of this only applies to you if you are using unsafe code or PInvoke (which also requires full trust). For safe managed code this issue does not apply because the CLR is specified in such a way that you cannot break memory safety. 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. Heap memory is fetched from the OS by using VirtualAlloc. I don't know whether it's location is randomized. Not every new invocation causes a new OS allocation. Many objects fit into one OS allocation.

delegate is indeed a function pointer under the hood. 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).

.NET assumes that your process is not being "hacked" by an attacker being able to write arbitrary bytes. 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.

0
Hans Passant On

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 assemblies have the /DYNAMICBASE option turned on, same one that native programs use to enable ASLR.
  • .NET assemblies have the /HIGHENTROPYVA option turned on by default. The C# compiler exposes the /highentropyva compiler option to control this.
  • The CLR allocates exclusively with 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. 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
  • The native code in a .NET program (jitter, CLR, CRT) has /GS turned on since .NET 4.0, detects stack smashing attempts.

No EncodePointer() calls, I doubt that they could work. I never heard of a successful attack against a .NET program, it is a pretty tall order to infect managed code with malicious data. But who knows. There have been a fairly large number of security updates over the years so somebody figured out something :)