From d33675d8704e69f73866cbcb7d70daee9b886eeb Mon Sep 17 00:00:00 2001 From: Matt Miller Date: Sat, 16 Jun 2007 05:04:03 +0000 Subject: [PATCH] framework now properly handles using singles without handlers as both stages and singles, fixes #115 git-svn-id: file:///home/svn/framework3/trunk@4994 4d416f70-5f16-0410-b530-b9f4589650da --- lib/msf/base/simple/payload.rb | 21 ++++--- lib/msf/core/module.rb | 7 +++ lib/msf/core/module_manager.rb | 8 +++ lib/msf/core/payload.rb | 61 ++++++++++++++++--- lib/msf/core/payload/single.rb | 24 ++++++++ modules/payloads/singles/bsd/x86/exec.rb | 4 +- modules/payloads/singles/linux/x86/adduser.rb | 2 +- modules/payloads/singles/linux/x86/exec.rb | 2 +- .../payloads/singles/windows/download_exec.rb | 6 +- modules/payloads/singles/windows/exec.rb | 2 +- 10 files changed, 111 insertions(+), 26 deletions(-) diff --git a/lib/msf/base/simple/payload.rb b/lib/msf/base/simple/payload.rb index a63fa5d50b..a28bdaf3ae 100644 --- a/lib/msf/base/simple/payload.rb +++ b/lib/msf/base/simple/payload.rb @@ -64,15 +64,20 @@ module Payload ((e.nop) ? "NOP gen: #{e.nop.refname}\n" : '') + "#{ou}", fmt) + buf - + # If it's multistage, include the second stage too - if (payload.staged? and payload.stage_payload) - buf += - "\n" + - Buffer.comment( - "#{payload.refname} - #{payload.stage_payload.length} bytes (stage 2)\n" + - "http://www.metasploit.com\n", - fmt) + Buffer.transform(payload.stage_payload, fmt) + if payload.staged? + stage = payload.generate_stage + + # If a stage was generated, then display it + if stage and stage.length > 0 + buf += + "\n" + + Buffer.comment( + "#{payload.refname} - #{stage.length} bytes (stage 2)\n" + + "http://www.metasploit.com\n", + fmt) + Buffer.transform(stage, fmt) + end end end diff --git a/lib/msf/core/module.rb b/lib/msf/core/module.rb index dbab5216ec..caf67ae824 100644 --- a/lib/msf/core/module.rb +++ b/lib/msf/core/module.rb @@ -338,6 +338,13 @@ class Module return (platform.all?) ? [ "All" ] : platform.names end + # + # Checks to see if this module is compatible with the supplied platform + # + def platform?(what) + (platform & what).empty? == false + end + # # Returns whether or not the module requires or grants high privileges. # diff --git a/lib/msf/core/module_manager.rb b/lib/msf/core/module_manager.rb index c2372848a6..f3c75e3019 100644 --- a/lib/msf/core/module_manager.rb +++ b/lib/msf/core/module_manager.rb @@ -148,6 +148,14 @@ class ModuleSet < Hash def recalculate end + # + # Forces all modules in this set to be loaded. + # + def force_load_set + each_module { |name, mod| + } + end + attr_reader :module_type # diff --git a/lib/msf/core/payload.rb b/lib/msf/core/payload.rb index d979b45c8b..39d6d4cc8d 100644 --- a/lib/msf/core/payload.rb +++ b/lib/msf/core/payload.rb @@ -54,6 +54,24 @@ class Payload < Msf::Module def initialize(info = {}) super + # If this is a 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::Single) and + self.class.include?(Msf::Payload::Stager) + self.module_info['Stage'] = {} + + if self.module_info['Payload'] + self.module_info['Stage']['Payload'] = self.module_info['Payload']['Payload'] || "" + self.module_info['Stage']['Offsets'] = self.module_info['Payload']['Offsets'] || {} + else + self.module_info['Stage']['Payload'] = "" + self.module_info['Stage']['Offsets'] = {} + end + + @staged = true + 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. @@ -104,11 +122,27 @@ class Payload < Msf::Module return Type::Stage end + # + # Returns the string version of the payload type + # + def payload_type_s + case payload_type + when Type::Stage + return "stage" + when Type::Stager + return "stager" + when Type::Single + return "single" + else + return "unknown" + end + end + # # This method returns whether or not this payload uses staging. # def staged? - (payload_type == Type::Stager or payload_type == Type::Stage) + (@staged or payload_type == Type::Stager or payload_type == Type::Stage) end # @@ -208,15 +242,7 @@ class Payload < Msf::Module # Generates the payload and returns the raw buffer to the caller. # def generate - raw = payload.dup - - # 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 + internal_generate end # @@ -377,6 +403,21 @@ class Payload < Msf::Module protected + # + # Generate the payload using our local payload blob and offsets + # + def internal_generate + raw = payload.dup + + # 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 + ## # # Custom merge operations for payloads diff --git a/lib/msf/core/payload/single.rb b/lib/msf/core/payload/single.rb index c972516a58..8a1b18952a 100644 --- a/lib/msf/core/payload/single.rb +++ b/lib/msf/core/payload/single.rb @@ -17,4 +17,28 @@ module Msf::Payload::Single return Msf::Payload::Type::Single end + # + # Conditional generation depending on whether or not this single payload is + # used in conjunction with a stager. When a stager is used, generate will + # return the stager. When a stager is not used, generate will return the + # single payload + # + def generate + # If we're staged, then we call the super to generate the STAGER + if staged? + super + # Otherwise, we'll be generating the stage, let's do that now + else + # If they defined a custom method that will return the payload, then + # call it + if self.class.method_defined?(:generate_stage) + generate_stage + # Otherwise, just use the default method to generate the single + # payload + else + internal_generate + end + end + end + end diff --git a/modules/payloads/singles/bsd/x86/exec.rb b/modules/payloads/singles/bsd/x86/exec.rb index 8ce11486dc..8fe493ce62 100644 --- a/modules/payloads/singles/bsd/x86/exec.rb +++ b/modules/payloads/singles/bsd/x86/exec.rb @@ -1,5 +1,5 @@ ## -# $Id:$ +# $Id$ ## ## @@ -50,7 +50,7 @@ module Exec # # Dynamically builds the adduser payload based on the user's options. # - def generate + def generate_stage cmd = datastore['CMD'] || '' payload = "\x6a\x3b\x58\x99\x52\x66\x68\x2d\x63\x89\xe7\x52" + diff --git a/modules/payloads/singles/linux/x86/adduser.rb b/modules/payloads/singles/linux/x86/adduser.rb index 28c227997c..6ceb65ac84 100644 --- a/modules/payloads/singles/linux/x86/adduser.rb +++ b/modules/payloads/singles/linux/x86/adduser.rb @@ -54,7 +54,7 @@ module AddUser # # Dynamically builds the adduser payload based on the user's options. # - def generate + def generate_stage user = datastore['USER'] || 'metasploit' pass = datastore['PASS'] || 'metasploit' shell = datastore['SHELL'] || '/bin/sh' diff --git a/modules/payloads/singles/linux/x86/exec.rb b/modules/payloads/singles/linux/x86/exec.rb index b75cf0fa10..eb63e4e94e 100644 --- a/modules/payloads/singles/linux/x86/exec.rb +++ b/modules/payloads/singles/linux/x86/exec.rb @@ -51,7 +51,7 @@ module Exec # # Dynamically builds the adduser payload based on the user's options. # - def generate + def generate_stage cmd = datastore['CMD'] || '' payload = "\x6a\x0b\x58\x99\x52\x66\x68\x2d\x63\x89\xe7\x68" + diff --git a/modules/payloads/singles/windows/download_exec.rb b/modules/payloads/singles/windows/download_exec.rb index ff8aa2ee3e..0d352e621c 100644 --- a/modules/payloads/singles/windows/download_exec.rb +++ b/modules/payloads/singles/windows/download_exec.rb @@ -1,5 +1,5 @@ ## -# $Id:$ +# $Id$ ## ## @@ -80,8 +80,8 @@ module DownloadExec # # Constructs the payload # - def generate - return super + (datastore['URL'] || '') + "\x80" + def generate_stage + return module_info['Payload']['Payload'] + (datastore['URL'] || '') + "\x80" end end diff --git a/modules/payloads/singles/windows/exec.rb b/modules/payloads/singles/windows/exec.rb index 434f3f5a5e..3019dad0dc 100644 --- a/modules/payloads/singles/windows/exec.rb +++ b/modules/payloads/singles/windows/exec.rb @@ -1,5 +1,5 @@ ## -# $Id:$ +# $Id$ ## ##