lots of changes, making the simple wrapper better, lots of improvements
git-svn-id: file:///home/svn/incoming/trunk@2750 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
3aaeeca644
commit
d62566a68f
|
@ -19,9 +19,7 @@
|
|||
require 'msf/core'
|
||||
|
||||
# Simple wrapper
|
||||
require 'msf/base/simple/buffer'
|
||||
require 'msf/base/simple/nop'
|
||||
require 'msf/base/simple/payload'
|
||||
require 'msf/base/simple'
|
||||
|
||||
# Sessions
|
||||
require 'msf/base/session/command_shell'
|
||||
|
|
|
@ -232,6 +232,26 @@ class ReadableText
|
|||
return output
|
||||
end
|
||||
|
||||
#
|
||||
# Dumps the contents of a datastore
|
||||
#
|
||||
def self.dump_datastore(name, ds, indent = 4, col = 60)
|
||||
tbl = Rex::Ui::Text::Table.new(
|
||||
'Indent' => indent,
|
||||
'Header' => name,
|
||||
'Columns' =>
|
||||
[
|
||||
'Name',
|
||||
'Value'
|
||||
])
|
||||
|
||||
ds.each_pair { |n, v|
|
||||
tbl << [ n, v ]
|
||||
}
|
||||
|
||||
return ds.length > 0 ? tbl.to_s : "#{tbl.header_to_s}No entries in data store.\n"
|
||||
end
|
||||
|
||||
#
|
||||
# Jacked from Ernest Ellingson <erne [at] powernav.com>, modified
|
||||
# a bit to add indention
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
# Buffer management
|
||||
require 'msf/base/simple/buffer'
|
||||
require 'msf/base/simple/statistics'
|
||||
|
||||
# Simplified module interfaces
|
||||
require 'msf/base/simple/module'
|
||||
require 'msf/base/simple/encoder'
|
||||
require 'msf/base/simple/exploit'
|
||||
require 'msf/base/simple/nop'
|
||||
require 'msf/base/simple/payload'
|
||||
require 'msf/base/simple/recon'
|
||||
|
||||
# Simplified framework interface
|
||||
require 'msf/base/simple/framework'
|
|
@ -0,0 +1,16 @@
|
|||
module Msf
|
||||
module Simple
|
||||
|
||||
###
|
||||
#
|
||||
# Encoder
|
||||
# -------
|
||||
#
|
||||
# A simplified encoder wrapper.
|
||||
#
|
||||
###
|
||||
class Encoder
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,16 @@
|
|||
module Msf
|
||||
module Simple
|
||||
|
||||
###
|
||||
#
|
||||
# Exploit
|
||||
# -------
|
||||
#
|
||||
# A simplified exploit wrapper.
|
||||
#
|
||||
###
|
||||
class Exploit
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,93 @@
|
|||
require 'msf/base/simple'
|
||||
|
||||
module Msf
|
||||
module Simple
|
||||
|
||||
###
|
||||
#
|
||||
# Framework
|
||||
# ---------
|
||||
#
|
||||
# This class wraps the framework-core supplied Framework class and adds some
|
||||
# helper methods for analyzing statistics as well as other potentially useful
|
||||
# information that is directly necessary to drive the framework-core.
|
||||
#
|
||||
###
|
||||
module Framework
|
||||
|
||||
include GeneralEventSubscriber
|
||||
|
||||
ModuleSimplifiers =
|
||||
{
|
||||
MODULE_ENCODER => Msf::Simple::Encoder,
|
||||
MODULE_EXPLOIT => Msf::Simple::Exploit,
|
||||
MODULE_NOP => Msf::Simple::Nop,
|
||||
MODULE_PAYLOAD => Msf::Simple::Payload,
|
||||
MODULE_RECON => Msf::Simple::Recon,
|
||||
}
|
||||
|
||||
#
|
||||
# Create a simplified instance of the framework
|
||||
#
|
||||
def self.create
|
||||
framework = Msf::Framework.new
|
||||
|
||||
return simplify(framework)
|
||||
end
|
||||
|
||||
#
|
||||
# Extends a framework object that may already exist
|
||||
#
|
||||
def self.simplify(framework)
|
||||
framework.extend(Msf::Simple::Framework)
|
||||
|
||||
# Initialize the simplified framework
|
||||
framework.init_simplified()
|
||||
|
||||
# Set the on_module_created procedure to simplify any module
|
||||
# instance that is created
|
||||
framework.on_module_created_proc = Proc.new { |instance|
|
||||
simplify_module(instance)
|
||||
}
|
||||
|
||||
# Register the framework as its own general event subscriber in this
|
||||
# instance
|
||||
framework.events.add_general_subscriber(framework)
|
||||
|
||||
return framework
|
||||
end
|
||||
|
||||
#
|
||||
# Simplifies a module instance if the type is supported by extending it
|
||||
# with the simplified module interface.
|
||||
#
|
||||
def self.simplify_module(instance)
|
||||
if ((ModuleSimplifiers[instance.type]) and
|
||||
(instance.class.include?(ModuleSimplifiers[instance.type]) == false))
|
||||
instance.extend(ModuleSimplifiers[instance.type])
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
#
|
||||
# Simplified interface
|
||||
#
|
||||
##
|
||||
|
||||
#
|
||||
# Initializes the simplified interface
|
||||
#
|
||||
def init_simplified
|
||||
self.stats = Statistics.new(self)
|
||||
end
|
||||
|
||||
attr_reader :stats
|
||||
|
||||
protected
|
||||
|
||||
attr_writer :stats
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,34 @@
|
|||
require 'msf/base'
|
||||
|
||||
module Msf
|
||||
module Simple
|
||||
|
||||
###
|
||||
#
|
||||
# Module
|
||||
# ------
|
||||
#
|
||||
# Simple module wrapper that provides some common methods for dealing with
|
||||
# modules, such as importing options and other such things.
|
||||
#
|
||||
###
|
||||
module Module
|
||||
|
||||
#
|
||||
# Imports extra options from the supplied hash either as a string or as a
|
||||
# hash.
|
||||
#
|
||||
def _import_extra_options(opts)
|
||||
# If options were supplied, import them into the payload's
|
||||
# datastore
|
||||
if (opts['Option'])
|
||||
self.datastore.import_options_from_hash(opts['Options'])
|
||||
elsif (opts['OptionStr'])
|
||||
self.datastore.import_options_from_s(opts['OptionStr'])
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -11,7 +11,7 @@ module Simple
|
|||
# Simple nop wrapper class for performing generation.
|
||||
#
|
||||
###
|
||||
class Nop
|
||||
module Nop
|
||||
|
||||
#
|
||||
# Generate a nop sled, optionally with a few parameters.
|
||||
|
@ -21,7 +21,7 @@ class Nop
|
|||
#
|
||||
# Format => The format to represent the data as: ruby, perl, c, raw
|
||||
#
|
||||
def self.generate(nop, length, opts)
|
||||
def self.generate_simple(nop, length, opts)
|
||||
# Generate the nop sled using the options supplied
|
||||
buf = nop.generate_sled(length, opts)
|
||||
|
||||
|
@ -29,6 +29,13 @@ class Nop
|
|||
return Buffer.transform(buf, opts['Format'] || 'raw')
|
||||
end
|
||||
|
||||
#
|
||||
# Calls the class method
|
||||
#
|
||||
def generate_simple(length, opts)
|
||||
Msf::Simple::Nop.generate_simple(self, length, opts)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -11,7 +11,9 @@ module Simple
|
|||
# Simple payload wrapper class for performing generation.
|
||||
#
|
||||
###
|
||||
class Payload
|
||||
module Payload
|
||||
|
||||
include Module
|
||||
|
||||
#
|
||||
# Generate a payload with the mad skillz. The payload can be generated in
|
||||
|
@ -20,7 +22,7 @@ class Payload
|
|||
# opts can have:
|
||||
#
|
||||
# Encoder => A encoder module instance.
|
||||
# Badchars => A string of bad characters.
|
||||
# BadChars => A string of bad characters.
|
||||
# Format => The format to represent the data as: ruby, perl, c, raw
|
||||
# Options => A hash of options to set.
|
||||
# OptionStr => A string of options in VAR=VAL form separated by
|
||||
|
@ -34,14 +36,10 @@ class Payload
|
|||
# NoKeyError => No valid encoder key could be found
|
||||
# ArgumentParseError => Options were supplied improperly
|
||||
#
|
||||
def self.generate(payload, opts)
|
||||
# If options were supplied, import them into the payload's
|
||||
# datastore
|
||||
if (opts['Option'])
|
||||
payload.datastore.import_options_from_hash(opts['Options'])
|
||||
elsif (opts['OptionStr'])
|
||||
payload.datastore.import_options_from_s(opts['OptionStr'])
|
||||
end
|
||||
def self.generate_simple(payload, opts)
|
||||
|
||||
# Import any options we may need
|
||||
payload._import_extra_options(opts)
|
||||
|
||||
# Generate the payload
|
||||
e = EncodedPayload.create(payload,
|
||||
|
@ -59,18 +57,26 @@ class Payload
|
|||
|
||||
# Prepend a comment
|
||||
if (fmt != 'raw' and opts['NoComment'] != true)
|
||||
((ds = payload.datastore.to_s) and ds.length > 0) ? ds += "\n" : ds = ''
|
||||
((ou = payload.options.options_used_to_s(payload.datastore)) and ou.length > 0) ? ou += "\n" : ou = ''
|
||||
buf = Buffer.comment(
|
||||
"#{payload.refname} - #{len} bytes\n" +
|
||||
"http://www.metasploit.com\n" +
|
||||
"#{ds}" +
|
||||
((e.encoder) ? "Encoder: #{e.encoder.refname}\n" : '') +
|
||||
((e.nop) ? "NOP generator: #{e.nop.refname}\n" : ''), fmt) + buf
|
||||
((e.nop) ? "NOP gen: #{e.nop.refname}\n" : '') +
|
||||
"#{ou}",
|
||||
fmt) + buf
|
||||
end
|
||||
|
||||
return buf
|
||||
end
|
||||
|
||||
#
|
||||
# Calls the class method
|
||||
#
|
||||
def generate_simple(opts)
|
||||
Msf::Simple::Payload.generate_simple(self, opts)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
module Msf
|
||||
module Simple
|
||||
|
||||
###
|
||||
#
|
||||
# Recon
|
||||
# -------
|
||||
#
|
||||
# A simplified recon wrapper.
|
||||
#
|
||||
###
|
||||
class Recon
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,54 @@
|
|||
module Msf
|
||||
module Simple
|
||||
|
||||
###
|
||||
#
|
||||
# Statistics
|
||||
# ----------
|
||||
#
|
||||
# This class provides an interface to various statistics about the
|
||||
# framework instance.
|
||||
#
|
||||
###
|
||||
class Statistics
|
||||
include Msf::Framework::Offspring
|
||||
|
||||
def initialize(framework)
|
||||
self.framework = framework
|
||||
end
|
||||
|
||||
def num_encoders
|
||||
self.framework.encoders.length
|
||||
end
|
||||
|
||||
def num_exploits
|
||||
self.framework.exploits.length
|
||||
end
|
||||
|
||||
def num_nops
|
||||
self.framework.nops.length
|
||||
end
|
||||
|
||||
def num_payloads
|
||||
self.framework.payloads.length
|
||||
end
|
||||
|
||||
def num_recon
|
||||
self.framework.recon.length
|
||||
end
|
||||
|
||||
def num_payload_stages
|
||||
self.framework.payloads.stages.length
|
||||
end
|
||||
|
||||
def num_payload_stagers
|
||||
self.framework.payloads.stagers.length
|
||||
end
|
||||
|
||||
def num_payload_singles
|
||||
self.framework.payloads.singles.length
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -78,4 +78,36 @@ class DataStore < Hash
|
|||
end
|
||||
end
|
||||
|
||||
###
|
||||
#
|
||||
# ModuleDataStore
|
||||
# ---------------
|
||||
#
|
||||
# DataStore wrapper for modules that will attempt to back values against the
|
||||
# framework's datastore if they aren't found in the module's datastore.
|
||||
#
|
||||
###
|
||||
class ModuleDataStore < DataStore
|
||||
|
||||
def initialize(m)
|
||||
@_module = m
|
||||
end
|
||||
|
||||
#
|
||||
# Fetch the key from the local hash first, or from the framework datastore
|
||||
# if we can't directly find it
|
||||
#
|
||||
def fetch(key)
|
||||
val = super || @_module.framework.datastore[key]
|
||||
end
|
||||
|
||||
#
|
||||
# Same as fetch
|
||||
#
|
||||
def [](key)
|
||||
val = super || @_module.framework.datastore[key]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -44,6 +44,9 @@ class EncodedPayload
|
|||
self.encoder = nil
|
||||
self.nop = nil
|
||||
|
||||
# First, validate
|
||||
pinst.validate()
|
||||
|
||||
# Generate the raw version of the payload first
|
||||
generate_raw()
|
||||
|
||||
|
|
|
@ -2,6 +2,25 @@ require 'msf/core'
|
|||
|
||||
module Msf
|
||||
|
||||
###
|
||||
#
|
||||
# GeneralEventSubscriber
|
||||
# ----------------------
|
||||
#
|
||||
# Called when internal framework events occur.
|
||||
#
|
||||
###
|
||||
module GeneralEventSubscriber
|
||||
#
|
||||
# Called when a module is loaded
|
||||
#
|
||||
attr_accessor :on_module_load_proc
|
||||
#
|
||||
# Called when a new module instance is created
|
||||
#
|
||||
attr_accessor :on_module_created_proc
|
||||
end
|
||||
|
||||
###
|
||||
#
|
||||
# EventDispatcher
|
||||
|
@ -18,6 +37,7 @@ module Msf
|
|||
class EventDispatcher
|
||||
|
||||
def initialize
|
||||
self.general_event_subscribers = []
|
||||
self.exploit_event_subscribers = []
|
||||
self.session_event_subscribers = []
|
||||
self.recon_event_subscribers = []
|
||||
|
@ -27,6 +47,14 @@ class EventDispatcher
|
|||
#
|
||||
# Subscriber registration
|
||||
#
|
||||
|
||||
def add_general_subscriber(subscriber)
|
||||
add_event_subscriber(general_event_subscribers, subscriber)
|
||||
end
|
||||
|
||||
def remove_general_subscriber(subscriber)
|
||||
remove_event_subscriber(general_event_subscribers, subscriber)
|
||||
end
|
||||
|
||||
def add_recon_subscriber(subscriber)
|
||||
add_event_subscriber(recon_event_subscribers, subscriber)
|
||||
|
@ -56,6 +84,38 @@ class EventDispatcher
|
|||
# Event dispatching entry point
|
||||
#
|
||||
|
||||
##
|
||||
#
|
||||
# General events
|
||||
#
|
||||
##
|
||||
|
||||
def on_module_load(name, mod)
|
||||
subscribers_rwlock.synchronize_read {
|
||||
general_event_subscribers.each { |subscriber|
|
||||
next if (!subscriber.on_module_load_proc)
|
||||
|
||||
subscriber.on_module_load_proc.call(name, mod)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def on_module_created(instance)
|
||||
subscribers_rwlock.synchronize_read {
|
||||
general_event_subscribers.each { |subscriber|
|
||||
next if (!subscriber.on_module_created_proc)
|
||||
|
||||
subscriber.on_module_created_proc.call(instance)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
##
|
||||
#
|
||||
# Recon events
|
||||
#
|
||||
##
|
||||
|
||||
def on_recon_discovery(group, info)
|
||||
subscribers_rwlock.synchronize_read {
|
||||
recon_event_subscribers.each { |subscriber|
|
||||
|
@ -64,6 +124,12 @@ class EventDispatcher
|
|||
}
|
||||
end
|
||||
|
||||
##
|
||||
#
|
||||
# Exploit events
|
||||
#
|
||||
##
|
||||
|
||||
def on_exploit_success(exploit)
|
||||
subscribers_rwlock.synchronize_read {
|
||||
exploit_event_subscribers.each { |subscriber|
|
||||
|
@ -80,6 +146,12 @@ class EventDispatcher
|
|||
}
|
||||
end
|
||||
|
||||
##
|
||||
#
|
||||
# Session events
|
||||
#
|
||||
##
|
||||
|
||||
def on_session_open(session)
|
||||
subscribers_rwlock.synchronize_read {
|
||||
session_event_subscribers.each { |subscriber|
|
||||
|
@ -110,6 +182,7 @@ protected
|
|||
}
|
||||
end
|
||||
|
||||
attr_accessor :general_event_subscribers
|
||||
attr_accessor :exploit_event_subscribers
|
||||
attr_accessor :session_event_subscribers
|
||||
attr_accessor :recon_event_subscribers
|
||||
|
|
|
@ -12,6 +12,14 @@ module Msf
|
|||
#
|
||||
###
|
||||
class Framework
|
||||
|
||||
#
|
||||
# Versioning information
|
||||
#
|
||||
Major = 3
|
||||
Minor = 0
|
||||
Version = "#{Major}.#{Minor}"
|
||||
Revision = "$Revision$"
|
||||
|
||||
#
|
||||
# Mixin meant to be included into all classes that can have instances that
|
||||
|
@ -24,10 +32,9 @@ class Framework
|
|||
require 'msf/core/module_manager'
|
||||
|
||||
def initialize()
|
||||
self.events = EventDispatcher.new
|
||||
self.modules = ModuleManager.new
|
||||
|
||||
self.modules.framework = self
|
||||
self.events = EventDispatcher.new
|
||||
self.modules = ModuleManager.new(self)
|
||||
self.datastore = DataStore.new
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -67,11 +74,13 @@ class Framework
|
|||
|
||||
attr_reader :events
|
||||
attr_reader :modules
|
||||
attr_reader :datastore
|
||||
|
||||
protected
|
||||
|
||||
attr_writer :events
|
||||
attr_writer :modules
|
||||
attr_writer :datastore
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ module ReverseTcp
|
|||
|
||||
register_options(
|
||||
[
|
||||
Opt::LHOST("0.0.0.0"),
|
||||
Opt::LHOST,
|
||||
Opt::LPORT(4444)
|
||||
], Msf::Handler::ReverseTcp)
|
||||
|
||||
|
@ -39,7 +39,7 @@ module ReverseTcp
|
|||
#
|
||||
def setup_handler
|
||||
listener_sock = comm.create(
|
||||
'LocalHost' => datastore['LHOST'] || "0.0.0.0",
|
||||
'LocalHost' => datastore['LHOST'],
|
||||
'LocalPort' => datastore['LPORT'].to_i,
|
||||
'Server' => true,
|
||||
'Proto' => 'tcp')
|
||||
|
|
|
@ -59,7 +59,7 @@ class Module
|
|||
self.options.add_advanced_options(info['AdvancedOptions'], self.class)
|
||||
|
||||
# Create and initialize the data store for this module
|
||||
self.datastore = DataStore.new
|
||||
self.datastore = ModuleDataStore.new(self)
|
||||
self.datastore.import_options(self.options)
|
||||
|
||||
# If there are default options, import their values into the datastore
|
||||
|
|
|
@ -25,16 +25,32 @@ class ModuleSet < Hash
|
|||
self.mod_platform_hash = {}
|
||||
self.mod_sorted = nil
|
||||
self.mod_ranked = nil
|
||||
self.mod_extensions = []
|
||||
end
|
||||
|
||||
#
|
||||
# Create an instance of the supplied module by its name
|
||||
#
|
||||
def create(name)
|
||||
klass = self[name]
|
||||
|
||||
return (klass) ? klass.new : nil
|
||||
klass = self[name]
|
||||
instance = nil
|
||||
|
||||
# If the klass is valid for this name, try to create it
|
||||
if (klass)
|
||||
instance = klass.new
|
||||
end
|
||||
|
||||
# Notify any general subscribers of the creation event
|
||||
if (instance)
|
||||
self.framework.events.on_module_created(instance)
|
||||
end
|
||||
|
||||
return instance
|
||||
end
|
||||
|
||||
#
|
||||
# Enumerates each module class in the set
|
||||
#
|
||||
def each_module(opts = {}, &block)
|
||||
mod_sorted = self.sort if (mod_sorted == nil)
|
||||
|
||||
|
@ -130,6 +146,9 @@ protected
|
|||
dup.refname = name
|
||||
|
||||
self[name] = dup
|
||||
|
||||
# Notify the framework that a module was loaded
|
||||
framework.events.on_module_load(name, dup)
|
||||
|
||||
# Invalidate the sorted array
|
||||
invalidate_cache
|
||||
|
@ -146,6 +165,7 @@ protected
|
|||
attr_writer :module_type
|
||||
attr_accessor :mod_arch_hash, :mod_platform_hash
|
||||
attr_accessor :mod_sorted, :mod_ranked
|
||||
attr_accessor :mod_extensions
|
||||
|
||||
end
|
||||
|
||||
|
@ -171,11 +191,12 @@ class ModuleManager < ModuleSet
|
|||
|
||||
include Framework::Offspring
|
||||
|
||||
def initialize()
|
||||
def initialize(framework)
|
||||
self.module_paths = []
|
||||
self.module_history = {}
|
||||
self.module_history_mtime = {}
|
||||
self.module_sets = {}
|
||||
self.framework = framework
|
||||
|
||||
MODULE_TYPES.each { |type|
|
||||
case type
|
||||
|
@ -188,7 +209,7 @@ class ModuleManager < ModuleSet
|
|||
self.module_sets[type] = instance
|
||||
|
||||
# Set the module set's framework reference
|
||||
instance.framework = self.framework
|
||||
instance.framework = framework
|
||||
}
|
||||
|
||||
super
|
||||
|
@ -198,56 +219,85 @@ class ModuleManager < ModuleSet
|
|||
# Accessors by module type
|
||||
#
|
||||
|
||||
#
|
||||
# Returns the set of loaded encoder module classes
|
||||
#
|
||||
def encoders
|
||||
return module_sets[MODULE_ENCODER]
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the set of loaded exploit module classes
|
||||
#
|
||||
def exploits
|
||||
return module_sets[MODULE_EXPLOIT]
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the set of loaded nop module classes
|
||||
#
|
||||
def nops
|
||||
return module_sets[MODULE_NOP]
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the set of loaded payload module classes
|
||||
#
|
||||
def payloads
|
||||
return module_sets[MODULE_PAYLOAD]
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the set of loaded recon module classes
|
||||
#
|
||||
def recon
|
||||
return module_sets[MODULE_RECON]
|
||||
end
|
||||
|
||||
##
|
||||
#
|
||||
# Module path management
|
||||
#
|
||||
##
|
||||
|
||||
#
|
||||
# Adds a path to be searched for new modules
|
||||
#
|
||||
def add_module_path(path)
|
||||
path.sub!(/#{File::SEPARATOR}$/, '')
|
||||
|
||||
# Make sure the path is a valid directory before we try to rock the
|
||||
# house
|
||||
if (File.directory?(path) == false)
|
||||
raise NameError, "The path supplied is not a valid directory.",
|
||||
caller
|
||||
end
|
||||
|
||||
module_paths << path
|
||||
|
||||
load_modules(path)
|
||||
return load_modules(path)
|
||||
end
|
||||
|
||||
#
|
||||
# Removes a path from which to search for modules
|
||||
#
|
||||
def remove_module_path(path)
|
||||
module_paths.delete(path)
|
||||
end
|
||||
|
||||
def register_type_extension(type, ext)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
#
|
||||
# Load all of the modules from the supplied module path (independent of
|
||||
# module type)
|
||||
#
|
||||
def load_modules(path)
|
||||
loaded = {}
|
||||
recalc = {}
|
||||
counts = {}
|
||||
|
||||
Find.find(path) { |file|
|
||||
|
||||
|
@ -319,6 +369,9 @@ protected
|
|||
|
||||
# Append the added module to the hash of file->module
|
||||
loaded[file] = added
|
||||
|
||||
# The number of loaded modules this round
|
||||
counts[type] = (counts[type]) ? (counts[type] + 1) : 1
|
||||
}
|
||||
|
||||
# Cache the loaded file mtimes
|
||||
|
@ -335,17 +388,22 @@ protected
|
|||
module_sets[key].recalculate
|
||||
}
|
||||
|
||||
return loaded.values
|
||||
# Return per-module loaded counts
|
||||
return counts
|
||||
end
|
||||
|
||||
#
|
||||
# Checks to see if the supplied file has changed (if it's even in the
|
||||
# cache)
|
||||
#
|
||||
def has_module_file_changed?(file)
|
||||
return (module_history_mtime[file] != File.new(file).mtime)
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the module object that is associated with the supplied module
|
||||
# name
|
||||
#
|
||||
def mod_from_name(name)
|
||||
obj = Msf
|
||||
|
||||
|
@ -364,8 +422,10 @@ protected
|
|||
return obj
|
||||
end
|
||||
|
||||
#
|
||||
# Called when a module is initially loaded such that it can be
|
||||
# categorized accordingly
|
||||
#
|
||||
def on_module_load(mod, type, name)
|
||||
# Payload modules require custom loading as the individual files
|
||||
# may not directly contain a logical payload that a user would
|
||||
|
|
|
@ -27,7 +27,7 @@ class Nop < Msf::Module
|
|||
# - SaveRegisters (array)
|
||||
# The list of registers that should not be clobbered by the NOP
|
||||
# generator.
|
||||
# - Badchars (string)
|
||||
# - BadChars (string)
|
||||
# The list of characters that should be avoided by the NOP
|
||||
# generator.
|
||||
#
|
||||
|
|
|
@ -227,7 +227,9 @@ class OptionContainer < Hash
|
|||
}
|
||||
end
|
||||
|
||||
#
|
||||
# Adds one or more options
|
||||
#
|
||||
def add_options(opts, owner = nil, advanced = false)
|
||||
return false if (opts == nil)
|
||||
|
||||
|
@ -256,6 +258,9 @@ class OptionContainer < Hash
|
|||
}
|
||||
end
|
||||
|
||||
#
|
||||
# Adds an option
|
||||
#
|
||||
def add_option(option, name = nil, owner = nil, advanced = false)
|
||||
if (option.kind_of?(Array))
|
||||
option = option.shift.new(name, option)
|
||||
|
@ -274,15 +279,19 @@ class OptionContainer < Hash
|
|||
self.sorted = self.sort
|
||||
end
|
||||
|
||||
#
|
||||
# Alias to add advanced options that sets the proper state flag
|
||||
#
|
||||
def add_advanced_options(opts, owner = nil)
|
||||
return false if (opts == nil)
|
||||
|
||||
add_options(opts, owner, true)
|
||||
end
|
||||
|
||||
#
|
||||
# Make sures that each of the options has a value of a compatible
|
||||
# format and that all the required options are set
|
||||
#
|
||||
def validate(datastore)
|
||||
errors = []
|
||||
|
||||
|
@ -300,7 +309,26 @@ class OptionContainer < Hash
|
|||
return true
|
||||
end
|
||||
|
||||
#
|
||||
# Creates string of options that were used from the datastore in VAR=VAL
|
||||
# format separated by commas.
|
||||
#
|
||||
def options_used_to_s(datastore)
|
||||
used = ''
|
||||
|
||||
each_pair { |name, option|
|
||||
next if (datastore[name] == nil)
|
||||
|
||||
used += ", " if (used.length > 0)
|
||||
used += "#{name}=#{datastore[name]}"
|
||||
}
|
||||
|
||||
return used
|
||||
end
|
||||
|
||||
#
|
||||
# Enumerates each option name
|
||||
#
|
||||
def each_option(&block)
|
||||
each_pair(&block)
|
||||
end
|
||||
|
|
|
@ -98,6 +98,13 @@ class Payload < Msf::Module
|
|||
#
|
||||
##
|
||||
|
||||
#
|
||||
# Make sure all our required options are set.
|
||||
#
|
||||
def validate
|
||||
self.options.validate(self.datastore)
|
||||
end
|
||||
|
||||
#
|
||||
# Generates the payload and return the raw buffer
|
||||
#
|
||||
|
|
|
@ -33,12 +33,12 @@ module CommandDispatcher
|
|||
return driver.framework
|
||||
end
|
||||
|
||||
def set_active_module(mod)
|
||||
driver.datastore['_ActiveModule'] = mod
|
||||
def active_module
|
||||
driver.active_module
|
||||
end
|
||||
|
||||
def get_active_module
|
||||
return driver.datastore['_ActiveModule']
|
||||
def active_module=(mod)
|
||||
driver.active_module = mod
|
||||
end
|
||||
|
||||
#
|
||||
|
|
|
@ -14,27 +14,30 @@ class Core
|
|||
|
||||
# Returns the list of commands supported by this command dispatcher
|
||||
def commands
|
||||
return {
|
||||
"?" => "Help menu",
|
||||
"back" => "Move back from the current context",
|
||||
"exit" => "Exit the console",
|
||||
"help" => "Help menu",
|
||||
"info" => "Displays information about one or more module",
|
||||
"quit" => "Exit the console",
|
||||
"search" => "Adds one or more module search paths",
|
||||
"set" => "Sets a variable to a value",
|
||||
"show" => "Displays modules of a given type, or all modules",
|
||||
"unset" => "Unsets one or more variables",
|
||||
"use" => "Selects a module by name",
|
||||
"version" => "Show the console library version number",
|
||||
}
|
||||
{
|
||||
"?" => "Help menu",
|
||||
"back" => "Move back from the current context",
|
||||
"banner" => "Display an awesome metasploit banner",
|
||||
"exit" => "Exit the console",
|
||||
"help" => "Help menu",
|
||||
"info" => "Displays information about one or more module",
|
||||
"quit" => "Exit the console",
|
||||
"search" => "Adds one or more module search paths",
|
||||
"set" => "Sets a variable to a value",
|
||||
"setg" => "Sets a global variable to a value",
|
||||
"show" => "Displays modules of a given type, or all modules",
|
||||
"unset" => "Unsets one or more variables",
|
||||
"unsetg" => "Unsets one or more global variables",
|
||||
"use" => "Selects a module by name",
|
||||
"version" => "Show the console library version number",
|
||||
}
|
||||
end
|
||||
|
||||
#
|
||||
# Pop the current dispatcher stack context, assuming it isn't pointed at
|
||||
# the core stack context.
|
||||
#
|
||||
def cmd_back(args)
|
||||
def cmd_back(*args)
|
||||
if (driver.dispatcher_stack.size > 1)
|
||||
# Destack the current dispatcher
|
||||
driver.destack_dispatcher
|
||||
|
@ -44,10 +47,16 @@ class Core
|
|||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Display one of the fabulous banners
|
||||
#
|
||||
def cmd_banner(*args)
|
||||
end
|
||||
|
||||
#
|
||||
# Instructs the driver to stop executing
|
||||
#
|
||||
def cmd_exit(args)
|
||||
def cmd_exit(*args)
|
||||
driver.stop
|
||||
end
|
||||
|
||||
|
@ -56,7 +65,7 @@ class Core
|
|||
#
|
||||
# Displays the command help banner
|
||||
#
|
||||
def cmd_help(args)
|
||||
def cmd_help(*args)
|
||||
all_commands = {}
|
||||
|
||||
driver.dispatcher_stack.reverse.each { |dispatcher|
|
||||
|
@ -89,10 +98,10 @@ class Core
|
|||
#
|
||||
# Displays information about one or more module
|
||||
#
|
||||
def cmd_info(args)
|
||||
def cmd_info(*args)
|
||||
if (args.length == 0)
|
||||
if (mod = get_active_module())
|
||||
print(Serializer::ReadableText.dump_module(mod))
|
||||
if (active_module)
|
||||
print(Serializer::ReadableText.dump_module(active_module))
|
||||
return true
|
||||
else
|
||||
print(
|
||||
|
@ -118,17 +127,42 @@ class Core
|
|||
#
|
||||
# Adds one or more search paths
|
||||
#
|
||||
def cmd_search(args)
|
||||
def cmd_search(*args)
|
||||
if (args.length == 0)
|
||||
print_error("No search paths were provided.")
|
||||
return false
|
||||
return true
|
||||
end
|
||||
|
||||
args.each { |path|
|
||||
framework.modules.add_module_path(path)
|
||||
totals = {}
|
||||
overall = 0
|
||||
curr_path = nil
|
||||
|
||||
begin
|
||||
# Walk the list of supplied search paths attempting to add each one
|
||||
# along the way
|
||||
args.each { |path|
|
||||
curr_path = path
|
||||
|
||||
if (counts = framework.modules.add_module_path(path))
|
||||
counts.each_pair { |type, count|
|
||||
totals[type] = (totals[type]) ? (totals[type] + count) : count
|
||||
|
||||
overall += count
|
||||
}
|
||||
end
|
||||
}
|
||||
rescue NameError
|
||||
print_error("Failed to add search path #{curr_path}: #{$!}")
|
||||
return true
|
||||
end
|
||||
|
||||
added = "Loaded #{overall} modules:\n"
|
||||
|
||||
totals.each_pair { |type, count|
|
||||
added += " #{count} #{type}#{count != 1 ? 's' : ''}\n"
|
||||
}
|
||||
|
||||
print_line("Added #{args.length} search paths.")
|
||||
print(added)
|
||||
|
||||
recalculate_tab_complete
|
||||
end
|
||||
|
@ -136,31 +170,36 @@ class Core
|
|||
#
|
||||
# Sets a name to a value in a context aware environment
|
||||
#
|
||||
def cmd_set(args)
|
||||
def cmd_set(*args)
|
||||
|
||||
# Figure out if these are global variables
|
||||
global = false
|
||||
|
||||
if (args[0] == '-g')
|
||||
args.shift
|
||||
global = true
|
||||
end
|
||||
|
||||
# Determine which data store we're operating on
|
||||
if (mod = get_active_module())
|
||||
datastore = mod.datastore
|
||||
if (active_module and global == false)
|
||||
datastore = active_module.datastore
|
||||
else
|
||||
datastore = driver.datastore
|
||||
global = true
|
||||
datastore = self.framework.datastore
|
||||
end
|
||||
|
||||
# Dump the contents of the active datastore if no args were supplied
|
||||
if (args.length == 0)
|
||||
tbl = Table.new(
|
||||
Table::Style::Default,
|
||||
'Columns' =>
|
||||
[
|
||||
'Name',
|
||||
'Value'
|
||||
])
|
||||
|
||||
datastore.each_pair { |name, value|
|
||||
tbl << [ name, value ]
|
||||
}
|
||||
|
||||
print(tbl.to_s)
|
||||
if (!global)
|
||||
print("\n" +
|
||||
Msf::Serializer::ReadableText.dump_datastore(
|
||||
"Global", framework.datastore))
|
||||
end
|
||||
|
||||
print("\n" +
|
||||
Msf::Serializer::ReadableText.dump_datastore(
|
||||
(global) ? "Global" : "Module: #{active_module.refname}",
|
||||
datastore) + "\n")
|
||||
return true
|
||||
elsif (args.length < 2)
|
||||
print(
|
||||
|
@ -178,12 +217,21 @@ class Core
|
|||
print_line("#{name} => #{value}")
|
||||
end
|
||||
|
||||
#
|
||||
# Sets the supplied variables in the global datastore
|
||||
#
|
||||
def cmd_setg(*args)
|
||||
args.unshift('-g')
|
||||
|
||||
cmd_set(*args)
|
||||
end
|
||||
|
||||
#
|
||||
# Displays the list of modules based on their type, or all modules if
|
||||
# no type is provided
|
||||
#
|
||||
def cmd_show(args)
|
||||
mod = get_active_module()
|
||||
def cmd_show(*args)
|
||||
mod = self.active_module
|
||||
|
||||
args << "all" if (args.length == 0)
|
||||
|
||||
|
@ -224,12 +272,21 @@ class Core
|
|||
#
|
||||
# Unsets a value if it's been set
|
||||
#
|
||||
def cmd_unset(args)
|
||||
def cmd_unset(*args)
|
||||
|
||||
# Figure out if these are global variables
|
||||
global = false
|
||||
|
||||
if (args[0] == '-g')
|
||||
args.shift
|
||||
global = true
|
||||
end
|
||||
|
||||
# Determine which data store we're operating on
|
||||
if (mod = get_active_module())
|
||||
datastore = mod.datastore
|
||||
if (active_module and global == false)
|
||||
datastore = active_module.datastore
|
||||
else
|
||||
datastore = driver.datastore
|
||||
datastore = framework.datastore
|
||||
end
|
||||
|
||||
# No arguments? No cookie.
|
||||
|
@ -248,8 +305,19 @@ class Core
|
|||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Unsets variables in the global data store
|
||||
#
|
||||
def cmd_unsetg(*args)
|
||||
args.unshift('-g')
|
||||
|
||||
cmd_unset(*args)
|
||||
end
|
||||
|
||||
#
|
||||
# Uses a module
|
||||
def cmd_use(args)
|
||||
#
|
||||
def cmd_use(*args)
|
||||
if (args.length == 0)
|
||||
print(
|
||||
"Usage: use module_name\n\n" +
|
||||
|
@ -266,7 +334,7 @@ class Core
|
|||
return false
|
||||
end
|
||||
rescue NameError => info
|
||||
print_error("The supplied module name is ambiguous.")
|
||||
print_error("The supplied module name is ambiguous: #{$!}.")
|
||||
return false
|
||||
end
|
||||
|
||||
|
@ -288,8 +356,8 @@ class Core
|
|||
end
|
||||
|
||||
# If there's currently an active module, go back
|
||||
if (old_mod = get_active_module())
|
||||
cmd_back([])
|
||||
if (active_module)
|
||||
cmd_back()
|
||||
end
|
||||
|
||||
if (dispatcher != nil)
|
||||
|
@ -297,7 +365,7 @@ class Core
|
|||
end
|
||||
|
||||
# Update the active module
|
||||
set_active_module(mod)
|
||||
self.active_module = mod
|
||||
|
||||
# Update the command prompt
|
||||
driver.update_prompt("#{mod.type}(#{mod_name}) ")
|
||||
|
@ -306,7 +374,7 @@ class Core
|
|||
#
|
||||
# Returns the revision of the console library
|
||||
#
|
||||
def cmd_version(args)
|
||||
def cmd_version(*args)
|
||||
ver = "$Revision$"
|
||||
|
||||
print_line("Version: #{ver.match(/ (.+?) \$/)[1]}")
|
||||
|
|
|
@ -7,9 +7,6 @@ class Encoder
|
|||
|
||||
include Msf::Ui::Console::ModuleCommandDispatcher
|
||||
|
||||
def cmd_encode(args)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end end end end
|
||||
|
|
|
@ -5,8 +5,29 @@ module CommandDispatcher
|
|||
|
||||
class Exploit
|
||||
|
||||
@@exploit_opts = Rex::Parser::Arguments.new(
|
||||
"-e" => [ true, "The payload encoder to use. If none is specified, ENCODER is used." ],
|
||||
"-h" => [ false, "Help banner." ],
|
||||
"-n" => [ true, "The NOP generator to use. If none is specified, NOP is used." ],
|
||||
"-o" => [ true, "A comma separated list of options in VAR=VAL format." ],
|
||||
"-p" => [ true, "The payload to use. If none is specified, PAYLOAD is used." ],
|
||||
"-t" => [ true, "The target index to use." ],
|
||||
"-z" => [ true, "Do not interact with the session after successful exploitation." ])
|
||||
|
||||
include Msf::Ui::Console::ModuleCommandDispatcher
|
||||
|
||||
def commands
|
||||
{
|
||||
"exploit" => "Launch an exploit attempt",
|
||||
}
|
||||
end
|
||||
|
||||
#
|
||||
# Launches an exploitation attempt
|
||||
#
|
||||
def cmd_exploit(*args)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end end end end
|
||||
|
|
|
@ -9,15 +9,15 @@ class Nop
|
|||
|
||||
@@generate_opts = Rex::Parser::Arguments.new(
|
||||
"-b" => [ true, "The list of characters to avoid: '\\x00\\xff'" ],
|
||||
"-t" => [ true, "The output type: ruby, perl, c, or raw." ],
|
||||
"-h" => [ false, "Help banner." ])
|
||||
"-h" => [ false, "Help banner." ],
|
||||
"-t" => [ true, "The output type: ruby, perl, c, or raw." ])
|
||||
|
||||
include Msf::Ui::Console::ModuleCommandDispatcher
|
||||
|
||||
def commands
|
||||
return {
|
||||
"generate" => "Generates a NOP sled",
|
||||
}
|
||||
{
|
||||
"generate" => "Generates a NOP sled",
|
||||
}
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -40,7 +40,7 @@ class Nop
|
|||
when nil
|
||||
length = val.to_i
|
||||
when '-b'
|
||||
badchars = [ val.downcase.gsub(/\\x([a-f0-9][a-f0-9])/, '\1') ].pack("H*")
|
||||
badchars = Rex::Text.hex_to_raw(val)
|
||||
when '-t'
|
||||
type = val
|
||||
when '-h'
|
||||
|
@ -54,10 +54,9 @@ class Nop
|
|||
|
||||
# Generate the sled
|
||||
begin
|
||||
sled = Msf::Simple::Nop.generate(
|
||||
mod,
|
||||
sled = mod.generate_simple(
|
||||
length,
|
||||
'Badchars' => badchars,
|
||||
'BadChars' => badchars,
|
||||
'Format' => type)
|
||||
rescue
|
||||
print_error("Sled generation failed: #{$!}.")
|
||||
|
|
|
@ -8,25 +8,25 @@ module CommandDispatcher
|
|||
class Payload
|
||||
|
||||
@@generate_opts = Rex::Parser::Arguments.new(
|
||||
"-b" => [ true, "The list of characters to avoid '\\x00\\xff'" ],
|
||||
"-t" => [ true, "The output type: ruby, perl, c, or raw." ],
|
||||
"-b" => [ true, "The list of characters to avoid: '\\x00\\xff'" ],
|
||||
"-e" => [ true, "The name of the encoder module to use." ],
|
||||
"-o" => [ true, "A space separated list of options in VAR=VAL format." ],
|
||||
"-h" => [ false, "Help banner." ],
|
||||
"-o" => [ true, "A comma separated list of options in VAR=VAL format." ],
|
||||
"-s" => [ true, "NOP sled length." ],
|
||||
"-h" => [ false, "Help banner." ])
|
||||
"-t" => [ true, "The output type: ruby, perl, c, or raw." ])
|
||||
|
||||
include Msf::Ui::Console::ModuleCommandDispatcher
|
||||
|
||||
def commands
|
||||
return {
|
||||
"generate" => "Generates a payload",
|
||||
}
|
||||
{
|
||||
"generate" => "Generates a payload",
|
||||
}
|
||||
end
|
||||
|
||||
#
|
||||
# Generates a payload
|
||||
#
|
||||
def cmd_generate(args)
|
||||
def cmd_generate(*args)
|
||||
|
||||
# Parse the arguments
|
||||
encoder_name = nil
|
||||
|
@ -58,8 +58,7 @@ class Payload
|
|||
|
||||
# Generate the payload
|
||||
begin
|
||||
buf = Msf::Simple::Payload.generate(
|
||||
mod,
|
||||
buf = mod.generate_simple(
|
||||
'BadChars' => badchars,
|
||||
'Encoder' => encoder_name,
|
||||
'Format' => type,
|
||||
|
|
|
@ -25,7 +25,7 @@ class Driver < Msf::Ui::Driver
|
|||
|
||||
def initialize(prompt = "%umsf", prompt_char = ">%c")
|
||||
# Initialize attributes
|
||||
self.framework = Msf::Framework.new
|
||||
self.framework = Msf::Simple::Framework.create
|
||||
self.dispatcher_stack = []
|
||||
|
||||
# Add the core command dispatcher as the root of the dispatcher
|
||||
|
@ -74,7 +74,7 @@ class Driver < Msf::Ui::Driver
|
|||
begin
|
||||
if (dispatcher.respond_to?('cmd_' + method))
|
||||
eval("
|
||||
dispatcher.#{'cmd_' + method}(arguments)
|
||||
dispatcher.#{'cmd_' + method}(*arguments)
|
||||
found = true")
|
||||
end
|
||||
rescue
|
||||
|
@ -105,6 +105,7 @@ class Driver < Msf::Ui::Driver
|
|||
end
|
||||
|
||||
attr_reader :dispatcher_stack, :framework
|
||||
attr_accessor :active_module
|
||||
|
||||
protected
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ module ModuleCommandDispatcher
|
|||
include Msf::Ui::Console::CommandDispatcher
|
||||
|
||||
def mod
|
||||
return get_active_module
|
||||
return driver.active_module
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -34,10 +34,6 @@ class Table < Rex::Ui::Text::Table
|
|||
end
|
||||
end
|
||||
|
||||
def header_to_s
|
||||
return super + "\n"
|
||||
end
|
||||
|
||||
# Print nothing if there are no rows if the style is default
|
||||
def to_s
|
||||
if (style == Style::Default)
|
||||
|
|
|
@ -13,7 +13,6 @@ module Ui
|
|||
class Driver
|
||||
|
||||
def initialize
|
||||
self.datastore = DataStore.new
|
||||
end
|
||||
|
||||
# Executes the user interface, optionally in an asynchronous fashion
|
||||
|
@ -29,26 +28,8 @@ class Driver
|
|||
def cleanup
|
||||
end
|
||||
|
||||
#
|
||||
# Arbitrary state storage
|
||||
#
|
||||
|
||||
# Store a keyed value
|
||||
def store(key, value)
|
||||
datastore[key] = value
|
||||
end
|
||||
|
||||
# Retrieve a keyed value
|
||||
def fetch(key)
|
||||
return datastore[key]
|
||||
end
|
||||
|
||||
attr_reader :datastore
|
||||
|
||||
protected
|
||||
|
||||
attr_writer :datastore
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -12,14 +12,14 @@ class Rex::Text::UnitTest < Test::Unit::TestCase
|
|||
|
||||
assert_equal("\"\\x01\\x02\\xff\"\n", Rex::Text.to_ruby(str))
|
||||
assert_equal("\"\\x01\\x02\\xff\";\n", Rex::Text.to_perl(str))
|
||||
assert_equal("unsigned char buf[] = \n \"\\x01\\x02\\xff\";\n", Rex::Text.to_c(str))
|
||||
assert_equal("unsigned char buf[] = \n\"\\x01\\x02\\xff\";\n", Rex::Text.to_c(str))
|
||||
|
||||
# 0 -> 20
|
||||
str = "\000\001\002\003\004\005\006\a\010\t\n\v\f\r\016\017\020\021\022\023"
|
||||
|
||||
assert_equal("\"\\x00\\x01\\x02\\x03\" +\n\"\\x04\\x05\\x06\\x07\" +\n\"\\x08\\x09\\x0a\\x0b\" +\n\"\\x0c\\x0d\\x0e\\x0f\" +\n\"\\x10\\x11\\x12\\x13\"\n", Rex::Text.to_ruby(str, 20))
|
||||
assert_equal("\"\\x00\\x01\\x02\\x03\" .\n\"\\x04\\x05\\x06\\x07\" .\n\"\\x08\\x09\\x0a\\x0b\" .\n\"\\x0c\\x0d\\x0e\\x0f\" .\n\"\\x10\\x11\\x12\\x13\";\n", Rex::Text.to_perl(str, 20))
|
||||
assert_equal("unsigned char buf[] = \n \"\\x00\\x01\\x02\\x03\"\n \"\\x04\\x05\\x06\\x07\"\n \"\\x08\\x09\\x0a\\x0b\"\n \"\\x0c\\x0d\\x0e\\x0f\"\n \"\\x10\\x11\\x12\\x13\";\n", Rex::Text.to_c(str, 20, "buf"))
|
||||
assert_equal("unsigned char buf[] = \n\"\\x00\\x01\\x02\\x03\\x04\"\n\"\\x05\\x06\\x07\\x08\\x09\"\n\"\\x0a\\x0b\\x0c\\x0d\\x0e\"\n\"\\x0f\\x10\\x11\\x12\\x13\";\n", Rex::Text.to_c(str, 20, "buf"))
|
||||
end
|
||||
|
||||
def test_wordwrap
|
||||
|
|
|
@ -67,6 +67,21 @@ class Table
|
|||
return str
|
||||
end
|
||||
|
||||
#
|
||||
# :nodoc:
|
||||
#
|
||||
# Returns the header string
|
||||
#
|
||||
def header_to_s
|
||||
if (header)
|
||||
pad = " " * headeri
|
||||
|
||||
return pad + header + "\n" + pad + "=" * header.length + "\n\n"
|
||||
end
|
||||
|
||||
return ''
|
||||
end
|
||||
|
||||
#
|
||||
# Prints the contents of the table
|
||||
#
|
||||
|
@ -129,21 +144,6 @@ protected
|
|||
return ((row.kind_of?(String)) && (row == '__hr__'))
|
||||
end
|
||||
|
||||
#
|
||||
# :nodoc:
|
||||
#
|
||||
# Returns the header string
|
||||
#
|
||||
def header_to_s
|
||||
if (header)
|
||||
pad = " " * headeri
|
||||
|
||||
return pad + header + "\n" + pad + "=" * header.length + "\n"
|
||||
end
|
||||
|
||||
return ''
|
||||
end
|
||||
|
||||
#
|
||||
# :nodoc:
|
||||
#
|
||||
|
|
|
@ -101,7 +101,7 @@ SINGLE_BYTE_SLED =
|
|||
out_sled = ''
|
||||
|
||||
random = opts['Random']
|
||||
badchars = opts['Badchars'] || ''
|
||||
badchars = opts['BadChars'] || ''
|
||||
badregs = opts['SaveRegisters'] || []
|
||||
|
||||
# Did someone specify random NOPs in the environment?
|
||||
|
|
|
@ -46,7 +46,7 @@ nop = Msf::Nops::IA32::SingleByte.new
|
|||
sled = nop.generate_sled(
|
||||
100,
|
||||
'Random' => true)
|
||||
# 'Badchars' => "\x95")
|
||||
# 'BadChars' => "\x95")
|
||||
# 'SaveRegisters' => [ 'eax' ])
|
||||
|
||||
puts sled.unpack("H*")[0]
|
||||
|
|
Loading…
Reference in New Issue