Saturday, December 1, 2012

In-Memory Managed Dll Loading With PowerShell

Download: Out-CompressedDll

The .NET framework has a very handy method which loads a managed executable as a byte array – [System.Reflection.Assembly]::Load(byte[] rawAssembly). From the perspective of a malicious script, this is very convenient because it allows for a dll to be self-contained within the script body. What’s not as convenient is the size required to store the raw dll as a byte array in the script. To alleviate the size dilemma, I’ve written a PowerShell script that reads in a managed dll, compresses it, base64-encodes it, and outputs generated code that you can simply paste into any script that requires the dll.
As an example, I’ll compile the following code and run it through the script:
PS C:\> csc /target:library test.cs
Microsoft (R) Visual C# Compiler version 4.0.30319.17929
for Microsoft (R) .NET Framework 4.5
Copyright (C) Microsoft Corporation. All rights reserved.

PS C:\> Out-CompressedDll .\test.dll | Out-File LoadDll.ps1

I then add the following to the generated script to run the DoStuff method: [Test]::DoStuff()

This results in the following script:
And that's all there is to it!

Note that this technique will only load MSIL-based dlls. It will not load native or  IJW ('it just works' - mixed-mode) dlls.

3 comments:

  1. Awesome technique, thanks for sharing!

    Very stealthy!

    ReplyDelete
  2. I've found (at least when generating MSF psh payloads) that Gzip compression tends to yield more compact output and doesn't require we play byte games with the beginning of the compressed stream between *nix and MSFT deflate implementations. Its supported by the OS in PSH2+ (at least, 1 may as well).

    -rageltman

    ReplyDelete
    Replies
    1. Thanks for the tip! I'll mess around with that and implement the change as soon as possible. :D

      Delete