Created
July 27, 2017 07:24
-
-
Save davehardy20/087d0a0b5617be38d9b3a99ab2b87d9b to your computer and use it in GitHub Desktop.
A simple PoC shellcode runner that works in PowerShell Core on Nano Server and demonstrates how to call Win32 APIs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
Author: Matthew Graeber (@mattifestation) | |
License: BSD 3-Clause | |
#> | |
function Invoke-VirtualAlloc { | |
Param ( | |
[IntPtr] $lpAddress, | |
[UInt32] $dwSize, | |
[UInt32] $flAllocationType, | |
[UInt32] $flProtect | |
) | |
$AsmBuilder = [System.Reflection.Assembly].Assembly.GetTypes() | ? {$_.Name -eq 'AssemblyBuilder' } | |
$AssemblyBuilder = $AsmBuilder::DefineDynamicAssembly('TestAssembly', 'Run') | |
$ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('TestModule', $False) | |
$TypeBuilder = $ModuleBuilder.DefineType('Kernel32', [Reflection.TypeAttributes]::Public) | |
$MethodBuilder = $TypeBuilder.DefineMethod('VirtualAlloc', | |
[Reflection.MethodAttributes] 'Public, Static, PinvokeImpl', | |
[Reflection.CallingConventions] 'Standard', | |
[IntPtr], | |
[Type[]] @([IntPtr], [UInt32], [UInt32], [UInt32])) | |
$DllImportConstructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor([Type[]] @([String])) | |
$Field_EntryPoint = [Runtime.InteropServices.DllImportAttribute].GetField('EntryPoint') | |
$Field_CharSet = [Runtime.InteropServices.DllImportAttribute].GetField('CharSet') | |
$Field_ExactSpelling = [Runtime.InteropServices.DllImportAttribute].GetField('ExactSpelling') | |
$Field_SetLastError = [Runtime.InteropServices.DllImportAttribute].GetField('SetLastError') | |
$Field_PreserveSig = [Runtime.InteropServices.DllImportAttribute].GetField('PreserveSig') | |
$Field_CallingConvention = [Runtime.InteropServices.DllImportAttribute].GetField('CallingConvention') | |
$Field_BestFitMapping = [Runtime.InteropServices.DllImportAttribute].GetField('BestFitMapping') | |
$Field_ThrowOnUnmappableChar = [Runtime.InteropServices.DllImportAttribute].GetField('ThrowOnUnmappableChar') | |
$FieldInfoArray = @($Field_EntryPoint, | |
$Field_ExactSpelling, | |
$Field_SetLastError, | |
$Field_PreserveSig, | |
$Field_CallingConvention, | |
$Field_BestFitMapping, | |
$Field_ThrowOnUnmappableChar) | |
$FieldArguments = @('VirtualAlloc', | |
$False, | |
$True, | |
$True, | |
[Runtime.InteropServices.CallingConvention]::Winapi, | |
$False, | |
$False) | |
$CustomAttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($DllImportConstructor, | |
'api-ms-win-core-memory-l1-1-0.dll', | |
[Reflection.FieldInfo[]] $FieldInfoArray, | |
[Object[]] $FieldArguments) | |
$MethodBuilder.SetCustomAttribute($CustomAttribBuilder) | |
$PreserveSigConstructor = [Runtime.InteropServices.PreserveSigAttribute].GetConstructor(@()) | |
$CustomAttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($PreserveSigConstructor, @()) | |
$MethodBuilder.SetCustomAttribute($CustomAttribBuilder) | |
$MethodBuilder.SetImplementationFlags([Reflection.MethodImplAttributes]::PreserveSig) | |
$Kernel32 = $TypeBuilder.CreateType() | |
$MethodInfo = New-Object Reflection.Emit.DynamicMethod('VirtualAlloc', [IntPtr], @([IntPtr], [UInt32], [UInt32], [UInt32])) | |
$Generator = $MethodInfo.GetILGenerator() | |
$Generator.Emit([System.Reflection.Emit.OpCodes]::Ldarg_0) | |
$Generator.Emit([System.Reflection.Emit.OpCodes]::Ldarg_1) | |
$Generator.Emit([System.Reflection.Emit.OpCodes]::Ldarg_2) | |
$Generator.Emit([System.Reflection.Emit.OpCodes]::Ldarg_3) | |
$Generator.Emit([System.Reflection.Emit.OpCodes]::Call, $Kernel32.GetMethod('VirtualAlloc')) | |
$Generator.Emit([System.Reflection.Emit.OpCodes]::Ret) | |
$Delegate = [Func``5[IntPtr, UInt32, UInt32, UInt32, IntPtr]] | |
$ProxyMethod = $MethodInfo.CreateDelegate($Delegate) | |
$ProxyMethod.Invoke($lpAddress, $dwSize, $flAllocationType, $flProtect) | |
} | |
function Invoke-CreateThread { | |
Param ( | |
[IntPtr] $lpThreadAttributes, | |
[UInt32] $dwStackSize, | |
[IntPtr] $lpStartAddress, | |
[IntPtr] $lpParameter, | |
[UInt32] $dwCreationFlags, | |
[IntPtr] $lpThreadId | |
) | |
$AsmBuilder = [System.Reflection.Assembly].Assembly.GetTypes() | ? {$_.Name -eq 'AssemblyBuilder' } | |
$AssemblyBuilder = $AsmBuilder::DefineDynamicAssembly('TestAssembly_2', 'Run') | |
$ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('TestModule', $False) | |
$TypeBuilder = $ModuleBuilder.DefineType('Kernel32', [Reflection.TypeAttributes]::Public) | |
$MethodBuilder = $TypeBuilder.DefineMethod('CreateThread', | |
[Reflection.MethodAttributes] 'Public, Static, PinvokeImpl', | |
[Reflection.CallingConventions] 'Standard', | |
[IntPtr], | |
[Type[]] @([IntPtr], [UInt32], [IntPtr], [IntPtr], [UInt32], [IntPtr])) | |
$DllImportConstructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor([Type[]] @([String])) | |
$Field_EntryPoint = [Runtime.InteropServices.DllImportAttribute].GetField('EntryPoint') | |
$Field_CharSet = [Runtime.InteropServices.DllImportAttribute].GetField('CharSet') | |
$Field_ExactSpelling = [Runtime.InteropServices.DllImportAttribute].GetField('ExactSpelling') | |
$Field_SetLastError = [Runtime.InteropServices.DllImportAttribute].GetField('SetLastError') | |
$Field_PreserveSig = [Runtime.InteropServices.DllImportAttribute].GetField('PreserveSig') | |
$Field_CallingConvention = [Runtime.InteropServices.DllImportAttribute].GetField('CallingConvention') | |
$Field_BestFitMapping = [Runtime.InteropServices.DllImportAttribute].GetField('BestFitMapping') | |
$Field_ThrowOnUnmappableChar = [Runtime.InteropServices.DllImportAttribute].GetField('ThrowOnUnmappableChar') | |
$FieldInfoArray = @($Field_EntryPoint, | |
$Field_ExactSpelling, | |
$Field_SetLastError, | |
$Field_PreserveSig, | |
$Field_CallingConvention, | |
$Field_BestFitMapping, | |
$Field_ThrowOnUnmappableChar) | |
$FieldArguments = @('CreateThread', | |
$False, | |
$True, | |
$True, | |
[Runtime.InteropServices.CallingConvention]::Winapi, | |
$False, | |
$False) | |
$CustomAttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($DllImportConstructor, | |
'api-ms-win-core-processthreads-l1-1-0.dll', | |
[Reflection.FieldInfo[]] $FieldInfoArray, | |
[Object[]] $FieldArguments) | |
$MethodBuilder.SetCustomAttribute($CustomAttribBuilder) | |
$PreserveSigConstructor = [Runtime.InteropServices.PreserveSigAttribute].GetConstructor(@()) | |
$CustomAttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($PreserveSigConstructor, @()) | |
$MethodBuilder.SetCustomAttribute($CustomAttribBuilder) | |
$MethodBuilder.SetImplementationFlags([Reflection.MethodImplAttributes]::PreserveSig) | |
$Kernel32 = $TypeBuilder.CreateType() | |
$MethodInfo = New-Object Reflection.Emit.DynamicMethod('CreateThread', [IntPtr], @([IntPtr], [UInt32], [IntPtr], [IntPtr], [UInt32], [IntPtr])) | |
$Generator = $MethodInfo.GetILGenerator() | |
$Generator.Emit([System.Reflection.Emit.OpCodes]::Ldarg_0) | |
$Generator.Emit([System.Reflection.Emit.OpCodes]::Ldarg_1) | |
$Generator.Emit([System.Reflection.Emit.OpCodes]::Ldarg_2) | |
$Generator.Emit([System.Reflection.Emit.OpCodes]::Ldarg_3) | |
$Generator.Emit([System.Reflection.Emit.OpCodes]::Ldarg_S, ([Byte] 4)) | |
$Generator.Emit([System.Reflection.Emit.OpCodes]::Ldarg_S, ([Byte] 5)) | |
$Generator.Emit([System.Reflection.Emit.OpCodes]::Call, $Kernel32.GetMethod('CreateThread')) | |
$Generator.Emit([System.Reflection.Emit.OpCodes]::Ret) | |
$Delegate = [Func``7[IntPtr, UInt32, IntPtr, IntPtr, UInt32, IntPtr, IntPtr]] | |
$ProxyMethod = $MethodInfo.CreateDelegate($Delegate) | |
$ProxyMethod.Invoke($lpThreadAttributes, | |
$dwStackSize, | |
$lpStartAddress, | |
$lpParameter, | |
$dwCreationFlags, | |
$lpThreadId) | |
} | |
$X64SampleInstructions = [Byte[]] @( | |
0xB9, 0x03, 0x00, 0x00, 0x00, # mov ecx, 3 | |
0x83, 0xC1, 0x03, # add ecx, 3 | |
0x31, 0xC0, # xor eax, eax | |
0xC3) # ret | |
<# | |
# Sample instructions that will crash your PowerShell Core remoting session | |
$X64SampleInstructions = [Byte[]] @( | |
0x48, 0x31, 0xC0, # xor rax, rax | |
0x50, # push rax | |
0xC3) # ret | |
#> | |
$ShellcodeAddr = Invoke-VirtualAlloc -lpAddress ([IntPtr]::Zero) -dwSize $X64SampleInstructions.Length -flAllocationType 0x3000 -flProtect 0x40 | |
[System.Runtime.InteropServices.Marshal]::Copy($X64SampleInstructions, 0, $ShellcodeAddr, $X64SampleInstructions.Length) | |
Invoke-CreateThread -lpThreadAttributes ([IntPtr]::Zero) -dwStackSize 0 -lpStartAddress $ShellcodeAddr -lpParameter ([IntPtr]::Zero) -dwCreationFlags 0 -lpThreadId ([IntPtr]::Zero) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment