Good day! I hope I already won the achievement “learned the author by title” on Habré -) However, today we will speak about a fresh, not yet closed vulnerability in .Net, which was targeted by one person (who will send him an invite to me?) Who wrote me to mail:
Have you tried using IL code to bring objects to string type and transfer to other domains?
At first, I did not understand it, but then I was born a sample of the code that forwards any object of the type located in the SharedDomain to the sandbox and allows its methods to be used WITHOUT marshalling.
')
Hole, on the one hand, it is quite difficult to call, because the ground for this must prepare the host. And not the most usual way, it should be noted. But on the other hand ... Yes it is
bugThe first thing we need is the now common methods of EntityPtr.ToPointer () and * .ToInstance () of
DotNetEx . Their combination causes the object to be incompatible. Those. to the type that he is not:
string str = EntityPtr.ToInstance<string>(EntityPtr.ToPointer(new List<int>()));
Naturally, if you call any method on such a “string”, nothing happens: Exception will crash (except for virtual methods from object - their positions in the Wirth table of the methods will coincide with those defined in our type and the call will occur correctly)
However, since the string is already a serialized object, then when marshalling, it is passed by reference, without copying. This means that we can throw it into a method whose code is executed in the sandbox and there inside it can be casting back to type.
I'll start right away with delicious:
private void methodInsideAppDomain(string str) { object tmp = str; var act = (Action)tmp; act(); } public static void Go(string startingIntPtr) {
Will display a
greeting on the screen.
So what will work:- Dragging objects of any type with casting inside the sandbox into the type from Shared Domain.
- If you call the virtual methods of the base class, which is located in the Shared Domain and which you have redefined to your own, your
- If you pass as an Action, the compiled Expression will also be called. But at the same time, it will also be called up in the sandbox, since there will not be a switch of the domain that goes during marshalling.
What can not:- To bring to your type in the sandbox, because in the sandbox the type and everything connected with it is loaded a second time and you will not get the same type: physically, type descriptors in different domains will be at different addresses, which means InvalidCastException.
- As an action, give the usual delegates to your code. Delegates either check the domain or the call inside the domain goes by near jmp, while the domains have different code selectors ... In general, the call drops. Expression needs to be done.
- Even if you don't need to type the type (we give the List <CustomType>, we get list.First (). DoSomething ()), nothing works anyway. It is necessary to work through the base type.
What affects:- As a matter of fact, since this has to adjust the host, and in the sandbox it does not, the value of the vulnerability falls
- Do not cause external code to switch to the hosting AppDomain. A delegate thrown inside will be called under the same rights. Although it is possible to make the RunAsHost (() => ...) method through a chain, but more on that later =)
- It can be pretty safe, without marshalling, to organize a quick call to host methods from the sandbox. Sometimes it is critical. For example, for forwarding quotes
