Module: Msf::Payload::Stager
- Includes:
- TransportConfig
- Included in:
- Osx::ReverseTcp_x64
- Defined in:
- lib/msf/core/payload/stager.rb
Overview
Base mixin interface for use by stagers.
Constant Summary
Constants included from Rex::Payloads::Meterpreter::UriChecksum
Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_CONN, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_CONN_MAX_LEN, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_INITJ, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_INITN, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_INITP, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_INITW, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_INIT_CONN, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_MIN_LEN, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_MODES, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_UUID_MIN_LEN
Instance Attribute Summary collapse
-
#stage_arch ⇒ Object
Returns the value of attribute stage_arch.
-
#stage_platform ⇒ Object
Returns the value of attribute stage_platform.
-
#stage_prefix ⇒ Object
A value that should be prefixed to a stage, such as a tag.
Instance Method Summary collapse
-
#assembly ⇒ String?
Return the stager payload’s assembly text, if any.
-
#encode_stage(stg) ⇒ String
Encodes the stage prior to transmission.
-
#encode_stage? ⇒ Boolean
Whether to use an Encoder on the second stage.
-
#encode_stage_preserved_registers ⇒ Object
Takes an educated guess at the list of registers an encoded stage would need to preserve based on the Convention.
- #format_uuid(uuid_raw) ⇒ Object
-
#generate_stage(opts = {}) ⇒ String
Generates the stage payload and substitutes all offsets.
-
#handle_connection(conn, opts = {}) ⇒ Object
Transmit the associated stage.
-
#handle_connection_stage(conn, opts = {}) ⇒ Object
Allow the stage to process whatever it is it needs to process.
-
#handle_intermediate_stage(conn, payload) ⇒ Object
Gives derived classes an opportunity to alter the stage and/or encapsulate its transmission.
- #initialize(info = {}) ⇒ Object
-
#offsets ⇒ Hash
(also: #stager_offsets)
Return the stager payload’s offsets.
-
#payload ⇒ String?
(also: #stager_payload)
Return the stager payload’s raw payload.
-
#payload_type ⇒ Object
Sets the payload type to a stager.
- #sends_hex_uuid? ⇒ Boolean
-
#stage_assembly ⇒ String
Returns the assembly text of the stage payload.
-
#stage_offsets ⇒ Hash
Returns variable offsets within the stage payload.
-
#stage_over_connection? ⇒ Boolean
Whether or not any stages associated with this stager should be sent over the connection that is established.
-
#stage_payload(opts = {}) ⇒ String?
Returns the raw stage payload.
-
#transport_config(opts = {}) ⇒ Object
Perform attempt at detecting the appropriate transport config.
Methods included from TransportConfig
#transport_config_bind_named_pipe, #transport_config_bind_tcp, #transport_config_reverse_http, #transport_config_reverse_https, #transport_config_reverse_ipv6_tcp, #transport_config_reverse_named_pipe, #transport_config_reverse_tcp, #transport_config_reverse_udp, #transport_uri_components
Methods included from UUID::Options
#generate_payload_uuid, #generate_uri_uuid_mode, #record_payload_uuid, #record_payload_uuid_url
Methods included from Rex::Payloads::Meterpreter::UriChecksum
#generate_uri_checksum, #generate_uri_uuid, #process_uri_resource, #uri_checksum_lookup
Instance Attribute Details
#stage_arch ⇒ Object
Returns the value of attribute stage_arch.
11 12 13 |
# File 'lib/msf/core/payload/stager.rb', line 11 def stage_arch @stage_arch end |
#stage_platform ⇒ Object
Returns the value of attribute stage_platform.
12 13 14 |
# File 'lib/msf/core/payload/stager.rb', line 12 def stage_platform @stage_platform end |
#stage_prefix ⇒ Object
A value that should be prefixed to a stage, such as a tag.
326 327 328 |
# File 'lib/msf/core/payload/stager.rb', line 326 def stage_prefix @stage_prefix end |
Instance Method Details
#assembly ⇒ String?
Return the stager payload’s assembly text, if any.
72 73 74 |
# File 'lib/msf/core/payload/stager.rb', line 72 def assembly return module_info['Stager']['Assembly'] end |
#encode_stage(stg) ⇒ String
Encodes the stage prior to transmission
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 |
# File 'lib/msf/core/payload/stager.rb', line 269 def encode_stage(stg) return stg unless encode_stage? stage_enc_mod = nil # Handle StageEncoder if specified by the user if datastore['StageEncoder'].to_s.length > 0 stage_enc_mod = datastore["StageEncoder"] end # Allow the user to specify additional registers to preserve saved_registers = datastore['StageEncoderSaveRegisters'].to_s + " " + encode_stage_preserved_registers saved_registers.strip! estg = nil begin # Generate an encoded version of the stage. We tell the encoding system # to save certain registers to ensure that it does not get clobbered. encp = Msf::EncodedPayload.create( self, 'Raw' => stg, 'Encoder' => stage_enc_mod, 'EncoderOptions' => { 'SaveRegisters' => saved_registers }, 'ForceSaveRegisters' => true, 'ForceEncode' => true, 'Arch' => self.stage_arch, 'Platform' => self.stage_platform) if encp.encoder if stage_enc_mod print_status("Encoded stage with #{stage_enc_mod}") else print_status("Encoded stage with #{encp.encoder.refname}") end estg = encp.encoded end rescue if datastore['StageEncodingFallback'] && estg.nil? print_warning("StageEncoder failed, falling back to no encoding") estg = stg else raise RuntimeError, "Stage encoding failed and StageEncodingFallback is disabled" end end estg end |
#encode_stage? ⇒ Boolean
Whether to use an Encoder on the second stage
136 137 138 |
# File 'lib/msf/core/payload/stager.rb', line 136 def encode_stage? !!(datastore['EnableStageEncoding']) end |
#encode_stage_preserved_registers ⇒ Object
Takes an educated guess at the list of registers an encoded stage would need to preserve based on the Convention
261 262 263 264 265 |
# File 'lib/msf/core/payload/stager.rb', line 261 def encode_stage_preserved_registers module_info['Convention'].to_s.scan(/\bsock([a-z]{3,}+)\b/). map {|reg| reg.first }. join(" ") end |
#format_uuid(uuid_raw) ⇒ Object
164 165 166 167 168 169 170 |
# File 'lib/msf/core/payload/stager.rb', line 164 def format_uuid(uuid_raw) if sends_hex_uuid? return uuid_raw end return Msf::Payload::UUID.new({raw: uuid_raw}) end |
#generate_stage(opts = {}) ⇒ String
Generates the stage payload and substitutes all offsets.
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/msf/core/payload/stager.rb', line 144 def generate_stage(opts={}) # XXX: This is nearly identical to Payload#internal_generate # Compile the stage as necessary if stage_assembly and !stage_assembly.empty? raw = build(stage_assembly, stage_offsets) else raw = stage_payload(opts) end # Substitute variables in the stage substitute_vars(raw, stage_offsets) if (stage_offsets) return raw end |
#handle_connection(conn, opts = {}) ⇒ Object
Transmit the associated stage.
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
# File 'lib/msf/core/payload/stager.rb', line 177 def handle_connection(conn, opts={}) # If the stage should be sent over the client connection that is # established (which is the default), then go ahead and transmit it. if (stage_over_connection?) if respond_to? :include_send_uuid if include_send_uuid uuid_raw = conn.get_once(16, 1) if uuid_raw opts[:uuid] = format_uuid(uuid_raw) end end end # Generate and encode the stage if stage encoding is enabled begin p = generate_stage(opts) p = encode_stage(p) rescue ::RuntimeError, ::StandardError => e warning_msg = "Failed to stage" warning_msg << " (#{conn.peerhost})" if conn.respond_to? :peerhost warning_msg << ": #{e}" print_warning warning_msg if conn.respond_to? :close && !conn.closed? conn.close end return end # Give derived classes an opportunity to an intermediate state before # the stage is sent. This gives derived classes an opportunity to # augment the stage and the process through which it is read on the # remote machine. # # If we don't use an intermediate stage, then we need to prepend the # stage prefix, such as a tag if handle_intermediate_stage(conn, p) == false p = (self.stage_prefix || '') + p end sending_msg = "Sending #{encode_stage? ? "encoded ":""}stage" sending_msg << " (#{p.length} bytes)" # The connection should always have a peerhost (even if it's a # tunnel), but if it doesn't, erroring out here means losing the # session, so make sure it does, just to be safe. if conn.respond_to? :peerhost sending_msg << " to #{conn.peerhost}" end print_status(sending_msg) # Send the stage conn.put(p) end # Give the stages a chance to handle the connection handle_connection_stage(conn, opts) end |
#handle_connection_stage(conn, opts = {}) ⇒ Object
Allow the stage to process whatever it is it needs to process.
Override to deal with sending the final stage in cases where #generate_stage is not the whole picture, such as when uploading an executable. The default is to simply attempt to create a session on the given conn
socket with Handler#create_session.
245 246 247 |
# File 'lib/msf/core/payload/stager.rb', line 245 def handle_connection_stage(conn, opts={}) create_session(conn, opts) end |
#handle_intermediate_stage(conn, payload) ⇒ Object
Gives derived classes an opportunity to alter the stage and/or encapsulate its transmission.
253 254 255 |
# File 'lib/msf/core/payload/stager.rb', line 253 def handle_intermediate_stage(conn, payload) false end |
#initialize(info = {}) ⇒ Object
14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/msf/core/payload/stager.rb', line 14 def initialize(info={}) super self.stage_arch = self.arch self.stage_platform = self.platform ( [ Msf::OptBool.new("EnableStageEncoding", [ false, "Encode the second stage payload", false ]), Msf::OptString.new("StageEncoder", [ false, "Encoder to use if EnableStageEncoding is set", nil ]), Msf::OptString.new("StageEncoderSaveRegisters", [ false, "Additional registers to preserve in the staged payload if EnableStageEncoding is set", "" ]), Msf::OptBool.new("StageEncodingFallback", [ false, "Fallback to no encoding if the selected StageEncoder is not compatible", true ]) ], Msf::Payload::Stager) end |
#offsets ⇒ Hash Also known as: stager_offsets
Return the stager payload’s offsets.
These will be used for substitutions during stager generation.
82 83 84 |
# File 'lib/msf/core/payload/stager.rb', line 82 def offsets return module_info['Stager']['Offsets'] end |
#payload ⇒ String? Also known as: stager_payload
Return the stager payload’s raw payload.
Can be nil if the stager is not pre-assembled.
64 65 66 |
# File 'lib/msf/core/payload/stager.rb', line 64 def payload return module_info['Stager']['Payload'] end |
#payload_type ⇒ Object
Sets the payload type to a stager.
54 55 56 |
# File 'lib/msf/core/payload/stager.rb', line 54 def payload_type return Msf::Payload::Type::Stager end |
#sends_hex_uuid? ⇒ Boolean
160 161 162 |
# File 'lib/msf/core/payload/stager.rb', line 160 def sends_hex_uuid? false end |
#stage_assembly ⇒ String
Returns the assembly text of the stage payload.
103 104 105 106 107 108 |
# File 'lib/msf/core/payload/stager.rb', line 103 def stage_assembly if module_info['Stage'] return module_info['Stage']['Assembly'] end nil end |
#stage_offsets ⇒ Hash
Returns variable offsets within the stage payload.
These will be used for substitutions during generation of the final stage.
117 118 119 120 121 122 |
# File 'lib/msf/core/payload/stager.rb', line 117 def stage_offsets if module_info['Stage'] return module_info['Stage']['Offsets'] end nil end |
#stage_over_connection? ⇒ Boolean
Whether or not any stages associated with this stager should be sent over the connection that is established.
128 129 130 |
# File 'lib/msf/core/payload/stager.rb', line 128 def stage_over_connection? true end |
#stage_payload(opts = {}) ⇒ String?
Returns the raw stage payload.
Can be nil if the final stage is not pre-assembled.
92 93 94 95 96 97 |
# File 'lib/msf/core/payload/stager.rb', line 92 def stage_payload(opts = {}) if module_info['Stage'] return module_info['Stage']['Payload'] end nil end |
#transport_config(opts = {}) ⇒ Object
Perform attempt at detecting the appropriate transport config. Call the determined config with passed options. Override this in stages/stagers to use specific transports
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/msf/core/payload/stager.rb', line 34 def transport_config(opts={}) if self.refname =~ /reverse_/ direction = 'reverse' else direction = 'bind' end if self.refname =~ /_tcp/ proto = 'tcp' elsif self.refname =~ /_https/ proto = 'https' else proto = 'http' end send("transport_config_#{direction}_#{proto}", opts) end |