more cool shit

git-svn-id: file:///home/svn/incoming/trunk@2711 4d416f70-5f16-0410-b530-b9f4589650da
unstable
Matt Miller 2005-07-10 19:21:40 +00:00
parent eba7bb2a6d
commit 8dc1128b3c
10 changed files with 184 additions and 26 deletions

View File

@ -18,7 +18,7 @@ module Buffer
# #
# Serializes a buffer to a provided format # Serializes a buffer to a provided format
# #
def self.transform(buf, fmt) def self.transform(buf, fmt = "ruby")
case fmt case fmt
when 'raw' when 'raw'
when 'ruby' when 'ruby'
@ -34,6 +34,25 @@ module Buffer
return buf return buf
end end
#
# Creates a comment using the supplied format
#
def self.comment(buf, fmt = "ruby")
case fmt
when 'raw'
when 'ruby'
buf = Rex::Text.to_ruby_comment(buf)
when 'perl'
buf = Rex::Text.to_perl_comment(buf)
when 'c'
buf = Rex::Text.to_c_comment(buf)
else
raise ArgumentError, "Unsupported buffer format: #{fmt}", caller
end
return buf
end
end end
end end

View File

@ -19,11 +19,23 @@ class Payload
# #
# opts can have: # opts can have:
# #
# Encoder => A encoder module instance. # 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 # 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
# whitespace.
# NoComment => Disables prepention of a comment
# #
def self.generate(payload, opts) 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
# Generate the payload # Generate the payload
buf = payload.generate buf = payload.generate
@ -32,8 +44,18 @@ class Payload
buf = opts['Encoder'].encode(buf, opts['Badchars']) buf = opts['Encoder'].encode(buf, opts['Badchars'])
end end
fmt = opts['Format'] || 'raw'
# Serialize the generated payload to some sort of format # Serialize the generated payload to some sort of format
return Buffer.transform(buf, opts['Format'] || 'raw') buf = Buffer.transform(buf, fmt)
# Prepend a comment
if (fmt != 'raw' and opts['NoComment'] != true)
buf = Buffer.comment(
"#{payload.refname}\n#{payload.datastore.to_s}\n", fmt) + buf
end
return buf
end end
end end

View File

@ -10,8 +10,10 @@ module Msf
### ###
class DataStore < Hash class DataStore < Hash
#
# This method is a helper method that imports the default value for # This method is a helper method that imports the default value for
# all of the supplied options # all of the supplied options
#
def import_options(options) def import_options(options)
options.each_option { |name, opt| options.each_option { |name, opt|
if (opt.default) if (opt.default)
@ -19,6 +21,60 @@ class DataStore < Hash
end end
} }
end end
#
# Imports option values from a whitespace separated string in
# VAR=VAL format.
#
def import_options_from_s(option_str)
hash = {}
# Figure out the deliminter, default to space.
delim = /\s/
if (option_str.index(','))
delim = ','
end
# Split on the deliminter
option_str.split(delim).each { |opt|
var, val = opt.split('=')
# Invalid parse? Raise an exception and let those bastards know.
if (var == nil or val == nil)
var = "unknown" if (!var)
raise ArgumentParseError, "Invalid option specified: #{var}", caller
end
# Store the value
hash[var] = val
}
import_options_from_hash(hash)
end
#
# Imports options from a hash
#
def import_options_from_hash(option_hash)
option_hash.each_pair { |key, val|
self.store(key, val)
}
end
#
# Serializes the options in the datastore to a string
#
def to_s(delim = ' ')
str = ''
keys.sort.each { |key|
str += "#{key}=#{self[key]}" + ((str.length) ? delim : '')
}
return str
end
end end
end end

View File

@ -15,6 +15,14 @@ module Msf
### ###
class Module class Module
class <<self
#
# The module's name that is assigned it it by the framework
# or derived from the path that the module is loaded from.
#
attr_accessor :refname
end
require 'msf/core/module/author' require 'msf/core/module/author'
require 'msf/core/module/platform_list' require 'msf/core/module/platform_list'
require 'msf/core/module/reference' require 'msf/core/module/reference'
@ -44,6 +52,16 @@ class Module
self.privileged = module_info['Privileged'] || false self.privileged = module_info['Privileged'] || false
end end
#
# Return's the module's framework reference name. This is the
# short name that end-users work with. Ex:
#
# win32/shell/reverse_tcp
#
def refname
return self.class.refname
end
# #
# Return the module's name # Return the module's name

View File

@ -64,6 +64,10 @@ protected
# Adds a module with a the supplied name # Adds a module with a the supplied name
def add_module(module_class, name) def add_module(module_class, name)
# Set the module's name so that it can be referenced when
# instances are created.
module_class.refname = name
self[name] = module_class self[name] = module_class
end end

View File

@ -105,11 +105,13 @@ class Payload < Msf::Module
# Now it's our turn... # Now it's our turn...
if ((val = datastore[name])) if ((val = datastore[name]))
if (pack == 'ADDR') if (pack == 'ADDR')
val = Socket.resolv_nbo(host) val = Rex::Socket.resolv_nbo(val)
elsif (pack == 'RAW') elsif (pack == 'RAW')
# Just use the raw value... # Just use the raw value...
else else
val = [ val ].pack(pack) # NOTE:
# Packing assumes integer format at this point, should fix...
val = [ val.to_i ].pack(pack)
end end
# Substitute it # Substitute it

View File

@ -49,6 +49,9 @@ class PayloadSet < ModuleSet
# and module # and module
p = build_payload(handler, mod) p = build_payload(handler, mod)
# Sets the modules derived name
p.refname = name
# Associate this class with the single payload's name # Associate this class with the single payload's name
self[name] = p self[name] = p
@ -95,6 +98,9 @@ class PayloadSet < ModuleSet
# Associate the name as a combination of the stager and stage # Associate the name as a combination of the stager and stage
combined = stage_name + '/' + stager_conn combined = stage_name + '/' + stager_conn
# Sets the modules derived name
p.refname = combined
self[combined] = p self[combined] = p
manager.add_module(p, combined) manager.add_module(p, combined)

View File

@ -8,10 +8,11 @@ module CommandDispatcher
class Payload class Payload
@@generate_opts = Rex::Parser::Arguments.new( @@generate_opts = Rex::Parser::Arguments.new(
"-b" => [ true, "The list of characters to avoid '\\x00\\xff'" ], "-b" => [ true, "The list of characters to avoid '\\x00\\xff'" ],
"-t" => [ true, "The output type: ruby, perl, c, or raw." ], "-t" => [ true, "The output type: ruby, perl, c, or raw." ],
"-e" => [ true, "The name of the encoder module to use." ], "-e" => [ true, "The name of the encoder module to use." ],
"-h" => [ false, "Help banner." ]) "-o" => [ true, "A space separated list of options in VAR=VAL format." ],
"-h" => [ false, "Help banner." ])
include Msf::Ui::Console::ModuleCommandDispatcher include Msf::Ui::Console::ModuleCommandDispatcher
@ -28,6 +29,7 @@ class Payload
# Parse the arguments # Parse the arguments
encoder_name = nil encoder_name = nil
option_str = nil
badchars = nil badchars = nil
encoder = nil encoder = nil
type = "ruby" type = "ruby"
@ -40,8 +42,13 @@ class Payload
type = val type = val
when '-e' when '-e'
encoder_name = val encoder_name = val
when '-o'
option_str = val
when '-h' when '-h'
print(@@generate_opts.usage) print(
"Usage: generate [options]\n\n" +
"Generates a payload.\n" +
@@generate_opts.usage)
return true return true
end end
} }
@ -57,9 +64,10 @@ class Payload
begin begin
buf = Msf::Simple::Payload.generate( buf = Msf::Simple::Payload.generate(
mod, mod,
'Badchars' => badchars, 'Badchars' => badchars,
'Encoder' => encoder, 'Encoder' => encoder,
'Format' => type) 'Format' => type,
'OptionStr' => option_str)
rescue rescue
print_error("Payload generation failed: #{$!}.") print_error("Payload generation failed: #{$!}.")
return false return false

View File

@ -49,13 +49,13 @@ class Driver < Msf::Ui::Driver
dispatcher_stack.each { |dispatcher| dispatcher_stack.each { |dispatcher|
begin begin
eval(" if (dispatcher.respond_to?('cmd_' + method))
if (dispatcher.respond_to?('cmd_' + method)) eval("
dispatcher.#{'cmd_' + method}(arguments) dispatcher.#{'cmd_' + method}(arguments)
found = true found = true")
end") end
rescue rescue
output.print_error("Error while running command #{method}: #{$!}.") output.print_error("Error while running command #{method}: #{$!}\n#{$@}\n.")
end end
# If the dispatcher stack changed as a result of this command, # If the dispatcher stack changed as a result of this command,

View File

@ -11,27 +11,50 @@ module Rex
### ###
module Text module Text
DefaultWrap = 60
# #
# Converts a raw string into a ruby buffer # Converts a raw string into a ruby buffer
# #
def self.to_ruby(str, wrap = 60) def self.to_ruby(str, wrap = DefaultWrap)
return hexify(str, wrap, '"', '" +', '', '"') return hexify(str, wrap, '"', '" +', '', '"')
end end
#
# Creates a ruby-style comment
#
def self.to_ruby_comment(str, wrap = DefaultWrap)
return wordwrap(str, 0, wrap, '', '# ')
end
# #
# Converts a raw string into a C buffer # Converts a raw string into a C buffer
# #
def self.to_c(str, wrap = 60, name = "buf") def self.to_c(str, wrap = DefaultWrap, name = "buf")
return hexify(str, wrap, ' "', '"', "unsigned char #{name}[] = \n", '";') return hexify(str, wrap, '"', '"', "unsigned char #{name}[] = \n", '";')
end
#
# Creates a c-style comment
#
def self.to_c_comment(str, wrap = DefaultWrap)
return "/*\n" + wordwrap(str, 0, wrap, '', ' * ') + " */\n"
end end
# #
# Converts a raw string into a perl buffer # Converts a raw string into a perl buffer
# #
def self.to_perl(str, wrap = 60) def self.to_perl(str, wrap = DefaultWrap)
return hexify(str, wrap, '"', '" .', '', '";') return hexify(str, wrap, '"', '" .', '', '";')
end end
#
# Creates a perl-style comment
#
def self.to_perl_comment(str, wrap = DefaultWrap)
return wordwrap(str, 0, wrap, '', '# ')
end
# #
# Returns the raw string # Returns the raw string
# #
@ -49,7 +72,7 @@ module Text
# #
# Wraps text at a given column using a supplied indention # Wraps text at a given column using a supplied indention
# #
def self.wordwrap(str, indent = 0, col = 60, append = '', prepend = '') def self.wordwrap(str, indent = 0, col = DefaultWrap, append = '', prepend = '')
return str.gsub(/.{1,#{col - indent}}(?:\s|\Z)/){ return str.gsub(/.{1,#{col - indent}}(?:\s|\Z)/){
( (" " * indent) + prepend + $& + append + 5.chr).gsub(/\n\005/,"\n").gsub(/\005/,"\n")} ( (" " * indent) + prepend + $& + append + 5.chr).gsub(/\n\005/,"\n").gsub(/\005/,"\n")}
end end
@ -57,7 +80,7 @@ module Text
# #
# Converts a string to a hex version with wrapping support # Converts a string to a hex version with wrapping support
# #
def self.hexify(str, col = 60, line_start = '', line_end = '', buf_start = '', buf_end = '') def self.hexify(str, col = DefaultWrap, line_start = '', line_end = '', buf_start = '', buf_end = '')
output = buf_start output = buf_start
cur = 0 cur = 0
count = 0 count = 0