16

I'm working in a project related with sandboxing technologies.

Currently I'm writing a C program that gets a small assembly .exe binary (.NET) from a remote web server. This binary is stored in memory (never touch disk) and my intention is to run this binary from memory. If my client was made in .NET I would have no problem to run that assembly from memory (in fact, are many differents ways of getting this) but of course that's not possible with C (not completely sure).

My questions is: having that assembly .exe in the address space of my C program, is there any way to run it from there? Is there any way to allow the CLR to run it? At first I thought to invoke powershell to run it from there (using Reflection.Assembly) but that case involve writing the assembly to disk.

In any case, no doubt that the best and efficient way of getting this is by using a .NET client.

LPs
  • 16,045
  • 8
  • 30
  • 61
Tomas Jeff
  • 161
  • 3
  • 5
    It's possible, I have no doubt. Easy? No. I rather suspect this is far outside the scope of a single SO answer. – Nathan Tuggy May 01 '15 at 01:46
  • Well, we know that .net assemblies can only be executed by the .net runtime (or equivalent). So how about using cli to interface with C# from C. Then using already existing C# methods for running an assembly from memory. Would that work the way you want it? – kbzombie May 01 '15 at 01:53
  • 3
    It can be done in PS without writing to disk. Definitely NOT easy. Here is the outline of [how](https://www.defcon.org/images/defcon-21/dc-21-presentations/Bialek/DEFCON-21-Bialek-PowerPwning-Post-Exploiting-by-Overpowering-Powershell.pdf) and a link to [lots of code](https://github.com/clymb3r/powershell) – Jan Chrbolka May 01 '15 at 02:53
  • @kbzombie thanks. I thought to load the .net runtime and then execute the code. But even in that case, when I use ExecuteInDefaultAppDomain I have to provide the path of the Assembly so this have to be on disk. I don't know if exits another alternative to provide the buffer as an input (something like Reflection.Assembly.Load in .NET) – Tomas Jeff May 01 '15 at 10:50
  • @Tomas Jeff I was looking at some decompiled code in justdecompile and apparently Assembly.Load(byte[]) boils down to some external method called RuntimeAssembly.nLoadImage();. [this](https://msdn.microsoft.com/en-us/library/windows/desktop/ms648045%28v=vs.85%29.aspx) is the closest thing i could find related to it. I am pretty sure that i am missing some important details and snags here, but since its possible to get an array of bytes from C over to C# there may be some way to make this work. – kbzombie May 03 '15 at 00:40
  • Not sure if this is what you're after, but at least running machine code loaded in a C program is not too hard on Windows. Use [VirtualProtect()](https://msdn.microsoft.com/en-us/library/windows/desktop/aa366898.aspx) to enable execution permissions for a page in your process' virtual memory. I believe you can request pages for this task with [VirtualAlloc()](https://msdn.microsoft.com/en-us/library/windows/desktop/aa366887.aspx). Then just call the machine code, from the start of a function with the correct conventions within the binary. – Veltas Aug 12 '15 at 23:26
  • You can run a .NET assembly from C (C++ is easier) as described here: http://www.codingvision.net/tips-and-tricks/calling-a-c-method-from-c-c-native-process however, you need an assembly stored as a file to start with. Can you store somekind of a "bootstrap" .net dll that you could load from C? and then this bootstrap .net code can load assembly from memory with .net code like this: http://stackoverflow.com/questions/3158217/load-assembly-from-memory – Simon Mourier Aug 21 '15 at 06:36
  • You can try two approaches here: just start process from memory executable image or try some specific .net loading methods. I guess first approach is easier, there are articles how to run random exe from memory, like this one http://www.joachim-bauch.de/tutorials/loading-a-dll-from-memory/ there are questions about it on SO http://stackoverflow.com/questions/1339443/how-can-i-run-an-executable-from-ram-using-c http://www.codeproject.com/Articles/13897/Load-an-EXE-File-and-Run-It-from-Memory – Andrey Sep 15 '15 at 14:12
  • http://stackoverflow.com/questions/305203/createprocess-from-memory-buffer – Andrey Sep 15 '15 at 14:12
  • possible .net approach is you can have self-hosted CLR and use it to load assembly – Andrey Sep 15 '15 at 14:13
  • to run an executable from memory you have to project it in the memory respecting the alignment of the different sections of it which are mostly DWORD aligned, you have to resolve its VA & RVA, you also have to resolve the import table and load all dependencies. – milevyo Oct 16 '15 at 15:42

3 Answers3

1

If it's a exe. build from .net then it is possible, check http://www.codeproject.com/Articles/13897/Load-an-EXE-File-and-Run-It-from-Memory

If it is an unmanaged binary then I am not aware of a method to do this. If you cannot save it to the HDD, even in a temporary folder you could try some sort of ramdrive. The execution the is easy with the following code:

        //this is using imports from System.Diagnostics and System.IO

        byte[] exeBytes = GetBytesFromStream(stream); // Get the .exe file from a webstream or something
        string tmpFilename = Path.GetFileNameWithoutExtension(Path.GetTempFileName()) + ".exe";
        string tmpFilePath = Path.Combine(Path.GetTempPath, tmpFilename);

        File.WriteAllBytes(tmpFilePath, exeBytes);

        Process.Start(tmpFilePath);
Sotirios
  • 51
  • 3
0

If you have loaded the exe file into memory, and you have the virtual address of that,(in the virtual space of your application), maybe you can use assembly commands like jump, or some method like DLL injections to run the other exe.

alirakiyan
  • 418
  • 4
  • 16
-1

Since the .exe will have IL, instead of actual machine instructions, you can't run it directly. Your best bet is to use the CLR hosting api, and even then I'm not sure you can have it work without touching the disk. Certainly any .NET code that runs as a result of the assembly code executing will end up loading CLR assemblies from disk.

Oliver Mellet
  • 2,389
  • 12
  • 10