PowerShell reflection offensive use-case

This snippet showcases some techniques to run code with PowerShell reflection.

# load a hello world program in memory and execute it
Add-Type -TypeDefinition @'
using System;

public class MyClass {
    public static void Main(string[] args) {
        Console.WriteLine("Hello, world!");
    }
}
'@ -OutputAssembly HelloWorld.exe

# use System.Reflection.Assembly.Load to load the assembly in memory
$AssemblyBytes = [IO.File]::ReadAllBytes("$PWD\HelloWorld.exe")
$HelloWorldAssembly = [System.Reflection.Assembly]::Load($AssemblyBytes)
# rnvoking the public method using standard .NET syntax:
[MyClass]::Main(@())
# using reflection to invoke the Main method:
$HelloWorldAssembly.EntryPoint.Invoke($null, [Object[]] @(@(,([String[]] @()))))

# dynamically create and execute a .NET assembly in memory using reflection and IL (Intermediate Language) generation
# define the current application domain
$Domain = [AppDomain]::CurrentDomain
# create a new assembly name
$DynAssembly = New-Object System.Reflection.AssemblyName('HelloWorld')
# define a dynamic assembly
$AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, [Reflection.Emit.AssemblyBuilderAccess]::Run)
# define a module builder within the assmebly
$ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('HelloWorld.exe')
# define a public type
$TypeBuilder = $ModuleBuilder.DefineType('MyClass', [Reflection.TypeAttributes]::Public)
# define a static method
$MethodBuilder = $TypeBuilder.DefineMethod('Main', [Reflection.MethodAttributes] 'Public, Static', [Void], @([String[]]))
# get an IL generator for the method
$Generator = $MethodBuilder.GetILGenerator()
get the `WriteLine` method of the `Console` class
$WriteLineMethod = [Console].GetMethod('WriteLine', [Type[]] @([String]))
# emit IL code to load string and call `WriteLine`:
$Generator.Emit([Reflection.Emit.OpCodes]::Ldstr, 'Hello, world!')
$Generator.Emit([Reflection.Emit.OpCodes]::Call, $WriteLineMethod)
$Generator.Emit([Reflection.Emit.OpCodes]::Ret)
# set the entrypoint of the assmbly
$AssemblyBuilder.SetEntryPoint($MethodBuilder)
# create a type
$TypeBuilder.CreateType()
# invoke the main method
[MyClass]::Main(@())

Last updated