Class: Msf::Payload
Overview
This class represents the base class for a logical payload. The framework automatically generates payload combinations at runtime which are all extended from this Payload as a base class.
Defined Under Namespace
Modules: Adapter, Aix, Android, Bsd, Custom, Firefox, Generic, Hardware, JSP, Java, Linux, Mainframe, Multi, Netware, NodeJS, Osx, Php, Pingback, Python, R, Ruby, Single, Solaris, Stager, TransportConfig, Type, Windows Classes: Apk, MachO, UUID
Constant Summary
Constants inherited from Module
Module::REPLICANT_EXTENSION_DS_KEY
Constants included from Module::ModuleInfo
Module::ModuleInfo::UpdateableOptions
Instance Attribute Summary collapse
-
#append ⇒ Object
This attribute holds the string that should be appended to the buffer when it’s generated.
-
#assoc_exploit ⇒ Object
If this payload is associated with an exploit, the assoc_exploit attribute will point to that exploit instance.
-
#available_space ⇒ Object
The amount of space available to the payload, which may be nil, indicating that the smallest possible payload should be used.
-
#prepend ⇒ Object
This attribute holds the string that should be prepended to the buffer when it’s generated.
-
#prepend_encoder ⇒ Object
This attribute holds the string that should be prepended to the encoded version of the payload (in front of the encoder as well).
Attributes inherited from Module
#error, #job_id, #license, #platform, #privileged, #references, #user_data
Attributes included from Framework::Offspring
Attributes included from Module::UUID
Attributes included from Rex::Ui::Subscriber::Input
Attributes included from Rex::Ui::Subscriber::Output
Attributes included from Module::Privileged
Attributes included from Module::Options
Attributes included from Module::ModuleStore
Attributes included from Module::ModuleInfo
Attributes included from Module::FullName
Attributes included from Module::DataStore
Attributes included from Module::Author
Attributes included from Module::Arch
Attributes included from Module::Alert
#alerts, #you_have_been_warned
Class Method Summary collapse
-
.cached_size ⇒ Object
This method returns an optional cached size value.
-
.choose_payload(mod) ⇒ Object
Select a reasonable default payload and minimally configure it.
-
.dynamic_size? ⇒ Boolean
This method returns whether the payload generates variable-sized output.
-
.type ⇒ Object
Returns MODULE_PAYLOAD to indicate that this is a payload module.
Instance Method Summary collapse
-
#apply_prepends(raw) ⇒ Object
A placeholder stub, to be overridden by mixins.
-
#assembly ⇒ Object
Returns the assembly string that describes the payload if one exists.
-
#assembly=(asm) ⇒ Object
Sets the assembly string that describes the payload If this method is used to define the payload, a payload with no offsets will be created.
-
#badchars ⇒ Object
Returns the string of bad characters for this payload, if any.
-
#build(asm, off = {}, opts = {}) ⇒ String
protected
If the payload has assembly that needs to be compiled, do so now.
-
#cached_size ⇒ Object
This method returns an optional cached size value.
-
#compatible_encoders ⇒ Object
Returns the array of compatible encoders for this payload instance.
-
#compatible_nops ⇒ Object
Returns the array of compatible nops for this payload instance.
-
#connection_type ⇒ Object
Returns the module’s connection type, such as reverse, bind, noconn, or whatever else the case may be.
-
#convention ⇒ Object
Returns the staging convention that the payload uses, if any.
-
#dependencies ⇒ Object
Returns the compiler dependencies if the payload has one.
-
#dynamic_size? ⇒ Boolean
This method returns whether the payload generates variable-sized output.
-
#generate(opts = {}) ⇒ Object
Generates the payload and returns the raw buffer to the caller.
-
#generate_complete ⇒ Object
Generates the payload and returns the raw buffer to the caller, handling any post-processing tasks, such as prepended code stubs.
-
#handler_klass ⇒ Object
Return the connection associated with this payload, or none if there isn’t one.
-
#initialize(info = {}) ⇒ Payload
constructor
Creates an instance of a payload module using the supplied information.
-
#internal_generate(opts = {}) ⇒ Object
protected
Generate the payload using our local payload blob and offsets.
-
#merge_name(info, val) ⇒ Object
protected
Merge the name to prefix the existing one and separate them with a comma.
-
#offsets ⇒ Object
Returns the offsets to variables that must be substitute, if any.
-
#on_session(session) ⇒ Object
Once an exploit completes and a session has been created on behalf of the payload, the framework will call the payload’s on_session notification routine to allow it to manipulate the session prior to handing off control to the user.
-
#payload ⇒ Object
Returns the raw payload that has not had variable substitution occur.
-
#payload_type ⇒ Object
Returns the type of payload, either single or staged.
-
#payload_type_s ⇒ Object
Returns the string version of the payload type.
-
#raw_to_db(raw) ⇒ Object
Convert raw bytes to metasm-ready ‘db’ encoding format eg.
-
#replace_var(raw, name, offset, pack) ⇒ Object
Replaces an individual variable in the supplied buffer at an offset using the given pack type.
-
#save_registers ⇒ Object
The list of registers that should be saved by any NOP generators or encoders, if possible.
-
#session ⇒ Object
Returns the session class that is associated with this payload and will be used to create a session as necessary.
-
#size ⇒ Object
Returns the payload’s size.
-
#staged? ⇒ Boolean
This method returns whether or not this payload uses staging.
-
#substitute_vars(raw, offsets) ⇒ Object
Substitutes variables with values from the module’s datastore in the supplied raw buffer for a given set of named offsets.
-
#symbol_lookup ⇒ Object
Returns the method used by the payload to resolve symbols for the purpose of calling functions, such as ws2ord.
-
#type ⇒ Object
Returns MODULE_PAYLOAD to indicate that this is a payload module.
Methods inherited from Module
#adapted_refname, #adapter_refname, #black_listed_auth_filenames, cached?, #debugging?, #default_cred?, #default_options, #fail_with, #file_path, #framework, #has_check?, #orig_cls, #owner, #perform_extensions, #platform?, #platform_to_s, #post_auth?, #register_extensions, #register_parent, #replicant, #required_cred_options, #set_defaults, #stage_refname, #stager_refname, #workspace
Methods included from Module::Reliability
#reliability, #reliability_to_s
Methods included from Module::Stability
Methods included from Module::SideEffects
#side_effects, #side_effects_to_s
Methods included from Module::UUID
Methods included from Module::UI
Methods included from Module::UI::Message
#print_error, #print_good, #print_prefix, #print_status, #print_warning
Methods included from Module::UI::Message::Verbose
#vprint_error, #vprint_good, #vprint_status, #vprint_warning
Methods included from Module::UI::Line
#print_line, #print_line_prefix
Methods included from Module::UI::Line::Verbose
Methods included from Rex::Ui::Subscriber
Methods included from Rex::Ui::Subscriber::Input
Methods included from Rex::Ui::Subscriber::Output
#flush, #print, #print_blank_line, #print_error, #print_good, #print_line, #print_status, #print_warning
Methods included from Module::Type
#auxiliary?, #encoder?, #evasion?, #exploit?, #nop?, #payload?, #post?
Methods included from Module::Ranking
Methods included from Module::Privileged
Methods included from Module::Options
#deregister_option_group, #deregister_options, #register_advanced_options, #register_evasion_options, #register_option_group, #register_options, #validate
Methods included from Module::Network
#comm, #support_ipv6?, #target_host, #target_port
Methods included from Module::ModuleStore
Methods included from Module::ModuleInfo
#alias, #description, #disclosure_date, #info_fixups, #merge_check_key, #merge_info, #merge_info_advanced_options, #merge_info_alias, #merge_info_description, #merge_info_evasion_options, #merge_info_name, #merge_info_options, #merge_info_string, #merge_info_version, #name, #notes, #update_info
Methods included from Module::FullName
#aliases, #fullname, #promptname, #realname, #refname, #shortname
Methods included from Module::DataStore
#import_defaults, #import_target_defaults, #share_datastore
Methods included from Module::Compatibility
#compat, #compatible?, #init_compat
Methods included from Module::Author
Methods included from Module::Auth
Methods included from Module::Arch
#arch?, #arch_to_s, #each_arch
Methods included from Module::Alert
#add_alert, #add_error, #add_info, #add_warning, #alert_user, #errors, #get_alerts, included, #infos, #is_usable?, #warnings, #without_prompt
Constructor Details
#initialize(info = {}) ⇒ Payload
Creates an instance of a payload module using the supplied information.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/msf/core/payload.rb', line 53 def initialize(info = {}) super # # Gets the Dependencies if the payload requires external help # to work # self.module_info['Dependencies'] = self.module_info['Dependencies'] || [] # If this is an adapted or staged payload but there is no stage information, # then this is actually a stager + single combination. Set up the # information hash accordingly. if (self.class.include?(Msf::Payload::Adapter) || self.class.include?(Msf::Payload::Single)) and self.class.include?(Msf::Payload::Stager) if self.module_info['Payload'] self.module_info['Stage']['Payload'] = self.module_info['Payload']['Payload'] || "" self.module_info['Stage']['Assembly'] = self.module_info['Payload']['Assembly'] || "" self.module_info['Stage']['Offsets'] = self.module_info['Payload']['Offsets'] || {} elsif !self.module_info['Stage'] self.module_info['Stage'] = {} self.module_info['Stage']['Payload'] = "" self.module_info['Stage']['Assembly'] = "" self.module_info['Stage']['Offsets'] = {} end @staged = true else @staged = false end # Update the module info hash with the connection type # that is derived from the handler for this payload. This is # used for compatibility filtering purposes. self.module_info['ConnectionType'] = connection_type end |
Instance Attribute Details
#append ⇒ Object
This attribute holds the string that should be appended to the buffer when it’s generated.
586 587 588 |
# File 'lib/msf/core/payload.rb', line 586 def append @append end |
#assoc_exploit ⇒ Object
If this payload is associated with an exploit, the assoc_exploit attribute will point to that exploit instance.
597 598 599 |
# File 'lib/msf/core/payload.rb', line 597 def assoc_exploit @assoc_exploit end |
#available_space ⇒ Object
The amount of space available to the payload, which may be nil, indicating that the smallest possible payload should be used.
603 604 605 |
# File 'lib/msf/core/payload.rb', line 603 def available_space @available_space end |
#prepend ⇒ Object
This attribute holds the string that should be prepended to the buffer when it’s generated.
581 582 583 |
# File 'lib/msf/core/payload.rb', line 581 def prepend @prepend end |
#prepend_encoder ⇒ Object
This attribute holds the string that should be prepended to the encoded version of the payload (in front of the encoder as well).
591 592 593 |
# File 'lib/msf/core/payload.rb', line 591 def prepend_encoder @prepend_encoder end |
Class Method Details
.cached_size ⇒ Object
This method returns an optional cached size value
161 162 163 164 |
# File 'lib/msf/core/payload.rb', line 161 def self.cached_size csize = (const_defined?('CachedSize')) ? const_get('CachedSize') : nil csize == :dynamic ? nil : csize end |
.choose_payload(mod) ⇒ Object
Select a reasonable default payload and minimally configure it
469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 |
# File 'lib/msf/core/payload.rb', line 469 def self.choose_payload(mod) compatible_payloads = mod.compatible_payloads( excluded_platforms: ['Multi'] # We don't want to select a multi payload ).map(&:first) # XXX: Determine LHOST based on global LHOST, RHOST or an arbitrary internet address lhost = mod.datastore['LHOST'] || Rex::Socket.source_address(mod.datastore['RHOST'] || '50.50.50.50') configure_payload = lambda do |payload| if mod.datastore.is_a?(Msf::DataStoreWithFallbacks) payload_defaults = { 'PAYLOAD' => payload } # Set LHOST if this is a reverse payload if payload.index('reverse') payload_defaults['LHOST'] = lhost end mod.datastore.import_defaults_from_hash(payload_defaults, imported_by: 'choose_payload') else mod.datastore['PAYLOAD'] = payload # Set LHOST if this is a reverse payload if payload.index('reverse') mod.datastore['LHOST'] = lhost end end payload end # If there is only one compatible payload, return it immediately if compatible_payloads.length == 1 return configure_payload.call(compatible_payloads.first) end # XXX: This approach is subpar, and payloads should really be ranked! preferred_payloads = [ # These payloads are generally reliable and common enough in practice '/meterpreter/reverse_tcp', '/shell/reverse_tcp', 'cmd/unix/reverse_bash', 'cmd/unix/reverse_netcat', 'cmd/windows/powershell_reverse_tcp', # Fall back on a generic payload to autoselect a specific payload 'generic/shell_reverse_tcp', 'generic/shell_bind_tcp' ] # XXX: This is not efficient in the slightest preferred_payloads.each do |type| payload = compatible_payloads.find { |name| name.end_with?(type) } next unless payload return configure_payload.call(payload) end nil end |
.dynamic_size? ⇒ Boolean
This method returns whether the payload generates variable-sized output
169 170 171 172 |
# File 'lib/msf/core/payload.rb', line 169 def self.dynamic_size? csize = (const_defined?('CachedSize')) ? const_get('CachedSize') : nil csize == :dynamic end |
.type ⇒ Object
Returns MODULE_PAYLOAD to indicate that this is a payload module.
98 99 100 |
# File 'lib/msf/core/payload.rb', line 98 def self.type return Msf::MODULE_PAYLOAD end |
Instance Method Details
#apply_prepends(raw) ⇒ Object
A placeholder stub, to be overridden by mixins
530 531 532 |
# File 'lib/msf/core/payload.rb', line 530 def apply_prepends(raw) raw end |
#assembly ⇒ Object
Returns the assembly string that describes the payload if one exists.
214 215 216 |
# File 'lib/msf/core/payload.rb', line 214 def assembly return module_info['Payload'] ? module_info['Payload']['Assembly'] : nil end |
#assembly=(asm) ⇒ Object
Sets the assembly string that describes the payload If this method is used to define the payload, a payload with no offsets will be created
222 223 224 225 |
# File 'lib/msf/core/payload.rb', line 222 def assembly=(asm) module_info['Payload'] ||= {'Offsets' => {} } module_info['Payload']['Assembly'] = asm end |
#badchars ⇒ Object
Returns the string of bad characters for this payload, if any.
112 113 114 |
# File 'lib/msf/core/payload.rb', line 112 def badchars return self.module_info['BadChars'] end |
#build(asm, off = {}, opts = {}) ⇒ String (protected)
If the payload has assembly that needs to be compiled, do so now.
Blobs will be cached in the framework’s PayloadSet
617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 |
# File 'lib/msf/core/payload.rb', line 617 def build(asm, off={}, opts = {}) if(asm.nil? or asm.empty?) raise ArgumentError, "Assembly must not be empty" end # Use the refname so blobs can be flushed when the module gets # reloaded and use the hash value to ensure that we're actually # getting the right blob for the given assembly. cache_key = refname + asm.hash.to_s cache_entry = framework.payloads.check_blob_cache(cache_key) off.each_pair { |option, val| if (val[1] == 'RAW') asm = asm.gsub(/#{option}/){ datastore[option] } off.delete(option) end } # If there is a valid cache entry, then we don't need to worry about # rebuilding the assembly if cache_entry # Update the local offsets from the cache off.each_key { |option| off[option] = cache_entry[1][option] } # Return the cached payload blob return cache_entry[0].dup end # Assemble the payload from the assembly a = opts[:arch] || self.arch if a.kind_of? Array a = self.arch.first end cpu = case a when ARCH_X86 then Metasm::Ia32.new when ARCH_X64 then Metasm::X86_64.new when ARCH_PPC then Metasm::PowerPC.new when ARCH_ARMLE then Metasm::ARM.new when ARCH_MIPSLE then Metasm::MIPS.new(:little) when ARCH_MIPSBE then Metasm::MIPS.new(:big) else elog("Broken payload #{refname} has arch unsupported with assembly: #{module_info["Arch"].inspect}") elog("Call stack:\n#{caller.join("\n")}") return "" end sc = Metasm::Shellcode.assemble(cpu, asm).encoded # Calculate the actual offsets now that it's been built off.each_pair { |option, val| off[option] = [ sc.offset_of_reloc(option) || val[0], val[1] ] } # Cache the payload blob framework.payloads.add_blob_cache(cache_key, sc.data, off) # Return a duplicated copy of the assembled payload sc.data.dup end |
#cached_size ⇒ Object
This method returns an optional cached size value
177 178 179 |
# File 'lib/msf/core/payload.rb', line 177 def cached_size self.class.cached_size end |
#compatible_encoders ⇒ Object
Returns the array of compatible encoders for this payload instance.
442 443 444 445 446 447 448 449 450 451 |
# File 'lib/msf/core/payload.rb', line 442 def compatible_encoders encoders = [] framework.encoders.each_module_ranked( 'Arch' => self.arch, 'Platform' => self.platform) { |name, mod| encoders << [ name, mod ] } return encoders end |
#compatible_nops ⇒ Object
Returns the array of compatible nops for this payload instance.
456 457 458 459 460 461 462 463 464 465 |
# File 'lib/msf/core/payload.rb', line 456 def compatible_nops nops = [] framework.nops.each_module_ranked( 'Arch' => self.arch) { |name, mod| nops << [ name, mod ] } return nops end |
#connection_type ⇒ Object
Returns the module’s connection type, such as reverse, bind, noconn, or whatever else the case may be.
255 256 257 |
# File 'lib/msf/core/payload.rb', line 255 def connection_type handler_klass.general_handler_type end |
#convention ⇒ Object
Returns the staging convention that the payload uses, if any. This is used to make sure that only compatible stagers and stages are built (where assumptions are made about register/environment initialization state and hand-off).
247 248 249 |
# File 'lib/msf/core/payload.rb', line 247 def convention module_info['Convention'] end |
#dependencies ⇒ Object
Returns the compiler dependencies if the payload has one
237 238 239 |
# File 'lib/msf/core/payload.rb', line 237 def dependencies module_info['Dependencies'] end |
#dynamic_size? ⇒ Boolean
This method returns whether the payload generates variable-sized output
184 185 186 |
# File 'lib/msf/core/payload.rb', line 184 def dynamic_size? self.class.dynamic_size? end |
#generate(opts = {}) ⇒ Object
Generates the payload and returns the raw buffer to the caller.
292 293 294 |
# File 'lib/msf/core/payload.rb', line 292 def generate(opts = {}) internal_generate(opts) end |
#generate_complete ⇒ Object
Generates the payload and returns the raw buffer to the caller, handling any post-processing tasks, such as prepended code stubs.
299 300 301 |
# File 'lib/msf/core/payload.rb', line 299 def generate_complete apply_prepends(generate) end |
#handler_klass ⇒ Object
Return the connection associated with this payload, or none if there isn’t one.
271 272 273 |
# File 'lib/msf/core/payload.rb', line 271 def handler_klass return module_info['Handler'] || Msf::Handler::None end |
#internal_generate(opts = {}) ⇒ Object (protected)
Generate the payload using our local payload blob and offsets
681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 |
# File 'lib/msf/core/payload.rb', line 681 def internal_generate(opts = {}) # Build the payload, either by using the raw payload blob defined in the # module or by actually assembling it if assembly and !assembly.empty? raw = build(assembly, offsets, opts) else raw = payload.dup end # If the payload is generated and there are offsets to substitute, # do that now. if (raw and offsets) substitute_vars(raw, offsets) end return raw end |
#merge_name(info, val) ⇒ Object (protected)
Merge the name to prefix the existing one and separate them with a comma
709 710 711 712 713 714 715 |
# File 'lib/msf/core/payload.rb', line 709 def merge_name(info, val) if (info['Name']) info['Name'] = val + ',' + info['Name'] else info['Name'] = val end end |
#offsets ⇒ Object
Returns the offsets to variables that must be substitute, if any.
230 231 232 |
# File 'lib/msf/core/payload.rb', line 230 def offsets return module_info['Payload'] ? module_info['Payload']['Offsets'] : nil end |
#on_session(session) ⇒ Object
Once an exploit completes and a session has been created on behalf of the payload, the framework will call the payload’s on_session notification routine to allow it to manipulate the session prior to handing off control to the user.
546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 |
# File 'lib/msf/core/payload.rb', line 546 def on_session(session) # If this payload is associated with an exploit, inform the exploit # that a session has been created and potentially shut down any # open sockets. This allows active exploits to continue hammering # on a service until a session is created. if (assoc_exploit) # Signal that a new session is created by calling the exploit's # on_new_session handler. The default behavior is to set an # instance variable, which the exploit will have to check. begin assoc_exploit.on_new_session(session) rescue ::Exception => e dlog("#{assoc_exploit.refname}: on_new_session handler triggered exception: #{e.class} #{e} #{e.backtrace}", 'core', LEV_1) rescue nil end # Set the abort sockets flag only if the exploit is not passive # and the connection type is not 'find' if ( (assoc_exploit.exploit_type == Exploit::Type::Remote) and (assoc_exploit.passive? == false) and (connection_type != 'find') ) assoc_exploit.abort_sockets end end end |
#payload ⇒ Object
Returns the raw payload that has not had variable substitution occur.
207 208 209 |
# File 'lib/msf/core/payload.rb', line 207 def payload return module_info['Payload'] ? module_info['Payload']['Payload'] : nil end |
#payload_type ⇒ Object
Returns the type of payload, either single or staged. Stage is the default because singles and stagers are encouraged to include the Single and Stager mixin which override the payload_type.
129 130 131 |
# File 'lib/msf/core/payload.rb', line 129 def payload_type return Type::Stage end |
#payload_type_s ⇒ Object
Returns the string version of the payload type
136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/msf/core/payload.rb', line 136 def payload_type_s case payload_type when Type::Adapter return "adapter" when Type::Stage return "stage" when Type::Stager return "stager" when Type::Single return "single" else return "unknown" end end |
#raw_to_db(raw) ⇒ Object
Convert raw bytes to metasm-ready ‘db’ encoding format eg. “x90xCC” => “db 0x90,0xCC”
309 310 311 |
# File 'lib/msf/core/payload.rb', line 309 def raw_to_db(raw) raw.unpack("C*").map {|c| "0x%.2x" % c}.join(",") end |
#replace_var(raw, name, offset, pack) ⇒ Object
Replaces an individual variable in the supplied buffer at an offset using the given pack type. This is here to allow derived payloads the opportunity to replace advanced variables.
428 429 430 |
# File 'lib/msf/core/payload.rb', line 428 def replace_var(raw, name, offset, pack) return false end |
#save_registers ⇒ Object
The list of registers that should be saved by any NOP generators or encoders, if possible.
120 121 122 |
# File 'lib/msf/core/payload.rb', line 120 def save_registers return self.module_info['SaveRegisters'] end |
#session ⇒ Object
Returns the session class that is associated with this payload and will be used to create a session as necessary.
279 280 281 |
# File 'lib/msf/core/payload.rb', line 279 def session return module_info['Session'] end |
#size ⇒ Object
Returns the payload’s size. If the payload is staged, the size of the first stage is returned.
192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/msf/core/payload.rb', line 192 def size pl = nil begin pl = generate() rescue Metasploit::Framework::Compiler::Mingw::UncompilablePayloadError rescue NoCompatiblePayloadError rescue PayloadItemSizeError end pl ||= '' pl.length end |
#staged? ⇒ Boolean
This method returns whether or not this payload uses staging.
154 155 156 |
# File 'lib/msf/core/payload.rb', line 154 def staged? (@staged or payload_type == Type::Stager or payload_type == Type::Stage) end |
#substitute_vars(raw, offsets) ⇒ Object
Substitutes variables with values from the module’s datastore in the supplied raw buffer for a given set of named offsets. For instance, RHOST is substituted with the RHOST value from the datastore which will have been populated by the framework.
Supported packing types:
-
ADDR (foo.com, 1.2.3.4)
-
ADDR6 (foo.com, fe80::1234:5678:8910:1234)
-
ADDR16MSB, ADD16LSB, ADDR22MSB, ADD22LSB (foo.com, 1.2.3.4) Advanced packing types for 16/16 and 22/10 bits substitution. The 16 bits types uses two offsets indicating where the 16 bits pair will be substituted, while the 22 bits types uses two offsets indicating the instructions where the 22/10 bits pair will be substituted. Normally these are offsets to “sethi” and “or” instructions on SPARC architecture.
-
HEX (0x12345678, “x41x42x43x44”)
-
RAW (raw bytes)
332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 |
# File 'lib/msf/core/payload.rb', line 332 def substitute_vars(raw, offsets) offsets.each_pair { |name, info| offset, pack = info # Give the derived class a chance to substitute this variable next if (replace_var(raw, name, offset, pack) == true) # Now it's our turn... if ((val = datastore[name])) if (pack == 'ADDR') val = Rex::Socket.resolv_nbo(val) # Someone gave us a funky address (ipv6?) if(val.length == 16) raise RuntimeError, "IPv6 address specified for IPv4 payload." end elsif (pack == 'ADDR6') val = Rex::Socket.resolv_nbo(val) # Convert v4 to the v6ish address if(val.length == 4) nip = "fe80::5efe:" + val.unpack("C*").join(".") val = Rex::Socket.resolv_nbo(nip) end elsif (['ADDR16MSB', 'ADDR16LSB', 'ADDR22MSB', 'ADDR22LSB'].include?(pack)) val = Rex::Socket.resolv_nbo(val) # Someone gave us a funky address (ipv6?) if(val.length == 16) raise RuntimeError, "IPv6 address specified for IPv4 payload." end elsif (pack == 'RAW') # Just use the raw value... else # Check to see if the value is a hex string. If so, convert # it. if val.kind_of?(String) if val =~ /^\\x/n val = [ val.gsub(/\\x/n, '') ].pack("H*").unpack(pack)[0] elsif val =~ /^0x/n val = val.hex end end # NOTE: # Packing assumes integer format at this point, should fix... val = [ val.to_i ].pack(pack) end # Substitute it if (['ADDR16MSB', 'ADDR16LSB'].include?(pack)) if (offset.length != 2) raise RuntimeError, "Missing value for payload offset, there must be two offsets." end if (pack == 'ADDR16LSB') val = val.unpack('N').pack('V') end raw[offset[0], 2] = val[0, 2] raw[offset[1], 2] = val[2, 2] elsif (['ADDR22MSB', 'ADDR22LSB'].include?(pack)) if (offset.length != 2) raise RuntimeError, "Missing value for payload offset, there must be two offsets." end if (pack == 'ADDR22LSB') val = val.unpack('N').pack('V') end hi = (0xfffffc00 & val) >> 10 lo = 0x3ff & val ins = raw[offset[0], 4] raw[offset[0], 4] = ins | hi ins = raw[offset[1], 4] raw[offset[1], 4] = ins | lo else raw[offset, val.length] = val end else wlog("Missing value for payload offset #{name}, skipping.", 'core', LEV_3) end } end |
#symbol_lookup ⇒ Object
Returns the method used by the payload to resolve symbols for the purpose of calling functions, such as ws2ord.
263 264 265 |
# File 'lib/msf/core/payload.rb', line 263 def symbol_lookup module_info['SymbolLookup'] end |
#type ⇒ Object
Returns MODULE_PAYLOAD to indicate that this is a payload module.
105 106 107 |
# File 'lib/msf/core/payload.rb', line 105 def type return Msf::MODULE_PAYLOAD end |