documentation fixes, code cleanup

git-svn-id: file:///home/svn/incoming/trunk@2973 4d416f70-5f16-0410-b530-b9f4589650da
unstable
Matt Miller 2005-10-19 03:20:20 +00:00
parent 72506deb57
commit 81c8cf3104
8 changed files with 315 additions and 46 deletions

View File

@ -58,7 +58,7 @@ class DataStore < Hash
end end
# #
# Imports options from a hash # Imports options from a hash and stores them in the datastore.
# #
def import_options_from_hash(option_hash) def import_options_from_hash(option_hash)
option_hash.each_pair { |key, val| option_hash.each_pair { |key, val|
@ -67,7 +67,7 @@ class DataStore < Hash
end end
# #
# Serializes the options in the datastore to a string # Serializes the options in the datastore to a string.
# #
def to_s(delim = ' ') def to_s(delim = ' ')
str = '' str = ''

View File

@ -16,7 +16,8 @@ class EncodedPayload
include Framework::Offspring include Framework::Offspring
# #
# Creates an encoded payload instance # This method creates an encoded payload instance and returns it to the
# caller.
# #
def self.create(pinst, reqs) def self.create(pinst, reqs)
# Create the encoded payload instance # Create the encoded payload instance
@ -225,13 +226,13 @@ class EncodedPayload
protected protected
attr_writer :raw attr_writer :raw # :nodoc:
attr_writer :encoded attr_writer :encoded # :nodoc:
attr_writer :nop_sled_size attr_writer :nop_sled_size # :nodoc:
attr_writer :nop_sled attr_writer :nop_sled # :nodoc:
attr_writer :payload attr_writer :payload # :nodoc:
attr_writer :encoder attr_writer :encoder # :nodoc:
attr_writer :nop attr_writer :nop # :nodoc:
# #
# The payload instance used to generate the payload # The payload instance used to generate the payload

View File

@ -13,32 +13,40 @@ module Msf
### ###
class EncoderState class EncoderState
#
# Initializes a new encoder state, optionally with a key.
#
def initialize(key = nil) def initialize(key = nil)
reset(key) reset(key)
end end
# Reset the encoder state #
# Reset the encoder state by initializing the encoded buffer to an empty
# string.
#
def reset(key = nil) def reset(key = nil)
init_key(key) init_key(key)
self.encoded = '' self.encoded = ''
end end
#
# Set the initial encoding key # Set the initial encoding key
#
def init_key(key) def init_key(key)
self.key = key self.key = key
self.orig_key = key self.orig_key = key
end end
attr_accessor :key attr_accessor :key # :nodoc:
attr_accessor :orig_key attr_accessor :orig_key # :nodoc:
attr_accessor :encoded attr_accessor :encoded # :nodoc:
attr_accessor :context attr_accessor :context # :nodoc:
attr_accessor :badchars attr_accessor :badchars # :nodoc:
attr_accessor :buf attr_accessor :buf # :nodoc:
# Decoder settings # Decoder settings
attr_accessor :decoder_key_offset, :decoder_key_size, :decoder_key_pack attr_accessor :decoder_key_offset, :decoder_key_size, :decoder_key_pack # :nodoc:
end end
@ -56,46 +64,77 @@ class Encoder < Module
super(info) super(info)
end end
##
# #
# Encoder information accessors that can be overriden # Encoder information accessors that can be overriden
# by derived classes # by derived classes
# #
##
#
# Returns MODULE_ENCODER to indicate that this is an encoder module.
#
def self.type def self.type
return MODULE_ENCODER return MODULE_ENCODER
end end
#
# Returns MODULE_ENCODER to indicate that this is an encoder module.
#
def type def type
return MODULE_ENCODER return MODULE_ENCODER
end end
# #
# Returns the decoder stub to use based on the supplied length # Returns the decoder stub to use based on the supplied length.
# #
def decoder_stub(state) def decoder_stub(state)
return module_info['Decoder']['Stub'] return module_info['Decoder']['Stub']
end end
#
# Returns the offset to the key associated with the decoder stub.
#
def decoder_key_offset def decoder_key_offset
return module_info['Decoder']['KeyOffset'] return module_info['Decoder']['KeyOffset']
end end
#
# Returns the size of the key, in bytes.
#
def decoder_key_size def decoder_key_size
return module_info['Decoder']['KeySize'] return module_info['Decoder']['KeySize']
end end
#
# Returns the size of each logical encoding block, in bytes. This
# is typically the same as decoder_key_size.
#
def decoder_block_size def decoder_block_size
return module_info['Decoder']['BlockSize'] return module_info['Decoder']['BlockSize']
end end
#
# Returns the byte-packing character that should be used to encode
# the key.
#
def decoder_key_pack def decoder_key_pack
return module_info['Decoder']['KeyPack'] || 'V' return module_info['Decoder']['KeyPack'] || 'V'
end end
##
# #
# Encoding # Encoding
# #
##
#
# This method generates an encoded version of the supplied buffer in buf
# using the bad characters as guides. On success, an encoded and
# functional version of the supplied buffer will be returned. Otherwise,
# an exception will be thrown if an error is encountered during the
# encoding process.
#
def encode(buf, badchars, state = nil) def encode(buf, badchars, state = nil)
# Initialize an empty set of bad characters # Initialize an empty set of bad characters
badchars = '' if (!badchars) badchars = '' if (!badchars)
@ -139,6 +178,10 @@ class Encoder < Module
return state.encoded return state.encoded
end end
#
# Performs the actual encoding operation after the encoder state has been
# initialized and is ready to go.
#
def do_encode(buf, badchars, state) def do_encode(buf, badchars, state)
# Copy the decoder stub since we may need to modify it # Copy the decoder stub since we may need to modify it
stub = decoder_stub(state).dup stub = decoder_stub(state).dup
@ -175,32 +218,56 @@ class Encoder < Module
return true return true
end end
##
# #
# Buffer management # Buffer management
# #
##
#
# Returns a string that should be prepended to the encoded version of the
# buffer before returning it to callers.
#
def prepend_buf def prepend_buf
return '' return ''
end end
##
# #
# Pre-processing, post-processing, and block encoding stubs # Pre-processing, post-processing, and block encoding stubs
# #
##
#
# Called when encoding is about to start immediately after the encoding
# state has been initialized.
#
def encode_begin(state) def encode_begin(state)
return nil return nil
end end
#
# Called after encoding has completed.
#
def encode_end(state) def encode_end(state)
return nil return nil
end end
#
# Called once for each block being encoded based on the attributes of the
# decoder.
#
def encode_block(state, block) def encode_block(state, block)
return block return block
end end
protected protected
#
# Initializes the encoding state supplied as an argument to the attributes
# that have been defined for this decoder stub, such as key offset, size,
# and pack.
#
def init_state(state) def init_state(state)
# Update the state with default decoder information # Update the state with default decoder information
state.decoder_key_offset = decoder_key_offset state.decoder_key_offset = decoder_key_offset
@ -208,6 +275,12 @@ protected
state.decoder_key_pack = decoder_key_pack state.decoder_key_pack = decoder_key_pack
end end
#
# This method finds a compatible key for the supplied buffer based also on
# the supplied bad characters list. This is meant to make encoders more
# reliable and less prone to bad character failure by doing a fairly
# complete key search before giving up on an encoder.
#
def find_key(buf, badchars) def find_key(buf, badchars)
key_bytes = [ ] key_bytes = [ ]
cur_key = [ ] cur_key = [ ]
@ -256,10 +329,16 @@ protected
return key_bytes_to_integer(key_bytes) return key_bytes_to_integer(key_bytes)
end end
#
# Returns the list of bad keys associated with this encoder.
#
def find_bad_keys def find_bad_keys
return [ {}, {}, {}, {} ] return [ {}, {}, {}, {} ]
end end
#
# Returns the index of any bad characters found in the supplied buffer.
#
def has_badchars?(buf, badchars) def has_badchars?(buf, badchars)
badchars.each_byte { |badchar| badchars.each_byte { |badchar|
idx = buf.index(badchar) idx = buf.index(badchar)

View File

@ -44,52 +44,88 @@ class EventDispatcher
self.subscribers_rwlock = Rex::ReadWriteLock.new self.subscribers_rwlock = Rex::ReadWriteLock.new
end end
##
# #
# Subscriber registration # Subscriber registration
# #
##
#
# This method adds a general subscriber. General subscribers receive
# notifications when all events occur.
#
def add_general_subscriber(subscriber) def add_general_subscriber(subscriber)
add_event_subscriber(general_event_subscribers, subscriber) add_event_subscriber(general_event_subscribers, subscriber)
end end
#
# Removes a general subscriber.
#
def remove_general_subscriber(subscriber) def remove_general_subscriber(subscriber)
remove_event_subscriber(general_event_subscribers, subscriber) remove_event_subscriber(general_event_subscribers, subscriber)
end end
#
# This method adds a recon event subscriber. Recon event subscribers
# receive notifications when events occur that pertain to recon modules.
# The subscriber provided must implement the ReconEvents module methods in
# some form.
#
def add_recon_subscriber(subscriber) def add_recon_subscriber(subscriber)
add_event_subscriber(recon_event_subscribers, subscriber) add_event_subscriber(recon_event_subscribers, subscriber)
end end
#
# Removes a recon event subscriber.
#
def remove_recon_subscriber(subscriber) def remove_recon_subscriber(subscriber)
remove_event_subscriber(recon_event_subscribers, subscriber) remove_event_subscriber(recon_event_subscribers, subscriber)
end end
#
# This method adds an exploit event subscriber. Exploit event subscribers
# receive notifications when events occur that pertain to exploits, such as
# the success or failure of an exploitation attempt. The subscriber
# provided must implement the ExploitEvents module methods in some form.
#
def add_exploit_subscriber(subscriber) def add_exploit_subscriber(subscriber)
add_event_subscriber(exploit_event_subscribers, subscriber) add_event_subscriber(exploit_event_subscribers, subscriber)
end end
#
# Removes an exploit event subscriber.
#
def remove_exploit_subscriber(subscriber) def remove_exploit_subscriber(subscriber)
remove_event_subscriber(exploit_event_subscribers, subscriber) remove_event_subscriber(exploit_event_subscribers, subscriber)
end end
#
# This method adds a session event subscriber. Session event subscribers
# receive notifications when sessions are opened and closed. The
# subscriber provided must implement the SessionEvents module methods in
# some form.
#
def add_session_subscriber(subscriber) def add_session_subscriber(subscriber)
add_event_subscriber(session_event_subscribers, subscriber) add_event_subscriber(session_event_subscribers, subscriber)
end end
#
# Removes a session event subscriber.
#
def remove_session_subscriber(subscriber) def remove_session_subscriber(subscriber)
remove_event_subscriber(session_event_subscribers, subscriber) remove_event_subscriber(session_event_subscribers, subscriber)
end end
#
# Event dispatching entry point
#
## ##
# #
# General events # General events
# #
## ##
#
# Called when a module is loaded into the framework. This, in turn,
# notifies all registered general event subscribers.
#
def on_module_load(name, mod) def on_module_load(name, mod)
subscribers_rwlock.synchronize_read { subscribers_rwlock.synchronize_read {
general_event_subscribers.each { |subscriber| general_event_subscribers.each { |subscriber|
@ -100,6 +136,10 @@ class EventDispatcher
} }
end end
#
# Called when a module is unloaded from the framework. This, in turn,
# notifies all registered general event subscribers.
#
def on_module_created(instance) def on_module_created(instance)
subscribers_rwlock.synchronize_read { subscribers_rwlock.synchronize_read {
general_event_subscribers.each { |subscriber| general_event_subscribers.each { |subscriber|
@ -116,6 +156,10 @@ class EventDispatcher
# #
## ##
#
# Called when recon information is discovered. This, in turn, notifies all
# registered recon event subscribers.
#
def on_recon_discovery(group, info) def on_recon_discovery(group, info)
subscribers_rwlock.synchronize_read { subscribers_rwlock.synchronize_read {
recon_event_subscribers.each { |subscriber| recon_event_subscribers.each { |subscriber|
@ -130,6 +174,10 @@ class EventDispatcher
# #
## ##
#
# Called when an exploit succeeds. This notifies the registered exploit
# event subscribers.
#
def on_exploit_success(exploit) def on_exploit_success(exploit)
subscribers_rwlock.synchronize_read { subscribers_rwlock.synchronize_read {
exploit_event_subscribers.each { |subscriber| exploit_event_subscribers.each { |subscriber|
@ -138,6 +186,10 @@ class EventDispatcher
} }
end end
#
# Called when an exploit fails. This notifies the registered exploit
# event subscribers.
#
def on_exploit_failure(exploit, reason) def on_exploit_failure(exploit, reason)
subscribers_rwlock.synchronize_read { subscribers_rwlock.synchronize_read {
exploit_event_subscribers.each { |subscriber| exploit_event_subscribers.each { |subscriber|
@ -152,6 +204,10 @@ class EventDispatcher
# #
## ##
#
# Called when a new session is opened. This notifies all the registered
# session event subscribers.
#
def on_session_open(session) def on_session_open(session)
subscribers_rwlock.synchronize_read { subscribers_rwlock.synchronize_read {
session_event_subscribers.each { |subscriber| session_event_subscribers.each { |subscriber|
@ -160,6 +216,10 @@ class EventDispatcher
} }
end end
#
# Called when a new session is closed. This notifies all the registered
# session event subscribers.
#
def on_session_close(session) def on_session_close(session)
subscribers_rwlock.synchronize_read { subscribers_rwlock.synchronize_read {
session_event_subscribers.each { |subscriber| session_event_subscribers.each { |subscriber|
@ -170,13 +230,19 @@ class EventDispatcher
protected protected
def add_event_subscriber(array, subscriber) #
# Adds an event subscriber to the supplied subscriber array.
#
def add_event_subscriber(array, subscriber) # :nodoc:
subscribers_rwlock.synchronize_write { subscribers_rwlock.synchronize_write {
array << subscriber array << subscriber
} }
end end
def remove_event_subscriber(array, subscriber) #
# Removes an event subscriber from the supplied subscriber array.
#
def remove_event_subscriber(array, subscriber) # :nodoc:
subscribers_rwlock.synchronize_write { subscribers_rwlock.synchronize_write {
array.delete(subscriber) array.delete(subscriber)
} }

View File

@ -13,13 +13,13 @@ module Msf
module ExploitEvents module ExploitEvents
# #
# Notified when an exploit is successful # This method is called whenever an exploit succeeds.
# #
def on_exploit_success(exploit) def on_exploit_success(exploit)
end end
# #
# Notified when an exploit is unsuccessful # This method is called whenever an exploit fails.
# #
def on_exploit_failure(exploit, reason) def on_exploit_failure(exploit, reason)
end end
@ -54,10 +54,31 @@ class Exploit < Msf::Module
# The various check codes that can be returned from the ``check'' routine. # The various check codes that can be returned from the ``check'' routine.
# #
module CheckCode module CheckCode
#
# The target is safe and is therefore not exploitable.
#
Safe = [ 0, "The target is not exploitable." ] Safe = [ 0, "The target is not exploitable." ]
#
# The target is running the service in requestion but may not be
# exploitable.
#
Detected = [ 1, "The target service is running, but could not be validated." ] Detected = [ 1, "The target service is running, but could not be validated." ]
#
# The target appears to be vulnerable.
#
Appears = [ 2, "The target appears to be vulnerable." ] Appears = [ 2, "The target appears to be vulnerable." ]
#
# The target is vulnerable.
#
Vulnerable = [ 3, "The target is vulnerable." ] Vulnerable = [ 3, "The target is vulnerable." ]
#
# The exploit does not support the check method.
#
Unsupported = [ 4, "This exploit does not support check." ] Unsupported = [ 4, "This exploit does not support check." ]
end end
@ -65,8 +86,20 @@ class Exploit < Msf::Module
# The various basic types of exploits # The various basic types of exploits
# #
module Type module Type
#
# Indicates that the exploit is a remote exploit.
#
Remote = "remote" Remote = "remote"
#
# Indicates that the exploit is a local exploit.
#
Local = "local" Local = "local"
#
# Indicates that the exploit can work anywhere it damn pleases.
#
Omni = "omnipresent" Omni = "omnipresent"
end end
@ -78,7 +111,18 @@ class Exploit < Msf::Module
# be initiated (passive) # be initiated (passive)
# #
module Stance module Stance
#
# Used to indicate that an exploit takes an aggressive stance. This
# means that the exploit proactively triggers a vulnerability.
#
Aggressive = "aggresive" Aggressive = "aggresive"
#
# Used to indicate that an exploit takes a passive stance. This means
# that the exploit waits for interaction from a client or other entity
# before being able to trigger the vulnerability.
#
Passive = "passive" Passive = "passive"
end end
@ -94,6 +138,10 @@ class Exploit < Msf::Module
# #
### ###
class Local < Exploit class Local < Exploit
#
# Returns the fact that this exploit is a local exploit.
#
def exploit_type def exploit_type
Exploit::Type::Local Exploit::Type::Local
end end
@ -111,6 +159,10 @@ class Exploit < Msf::Module
# #
### ###
class Remote < Exploit class Remote < Exploit
#
# Returns the fact that this exploit is a remote exploit.
#
def exploit_type def exploit_type
Exploit::Type::Remote Exploit::Type::Remote
end end
@ -122,7 +174,7 @@ class Exploit < Msf::Module
require 'msf/core/exploit/smb' require 'msf/core/exploit/smb'
# #
# Constructo the clown! Watch as he kills small children with balloons. # Creates an instance of the exploit module. Mad skillz.
# #
def initialize(info = {}) def initialize(info = {})
super(info) super(info)
@ -148,6 +200,8 @@ class Exploit < Msf::Module
# Checks to see if the target is vulnerable, returning unsupported if it's # Checks to see if the target is vulnerable, returning unsupported if it's
# not supported. # not supported.
# #
# This method is designed to be overriden by exploit modules.
#
def check def check
CheckCode::Unsupported CheckCode::Unsupported
end end
@ -158,6 +212,8 @@ class Exploit < Msf::Module
# exploit module. It will also pre-generate the desired payload, though # exploit module. It will also pre-generate the desired payload, though
# exploits can re-generate the payload if necessary. # exploits can re-generate the payload if necessary.
# #
# This method is designed to be overriden by exploit modules.
#
def exploit def exploit
end end
@ -252,16 +308,23 @@ class Exploit < Msf::Module
# #
## ##
#
# Returns true if the exploit module supports the check method.
#
def supports_check? def supports_check?
derived_implementor?(Msf::Exploit, 'check') derived_implementor?(Msf::Exploit, 'check')
end end
#
# Returns true if the exploit module supports the exploit method.
#
def supports_exploit? def supports_exploit?
derived_implementor?(Msf::Exploit, 'exploit') derived_implementor?(Msf::Exploit, 'exploit')
end end
# #
# Returns a hash of the capabilities this exploit module has # Returns a hash of the capabilities this exploit module has support for,
# such as whether or not it supports check and exploit.
# #
def capabilities def capabilities
{ {
@ -280,12 +343,15 @@ class Exploit < Msf::Module
## ##
# #
# The module's type # Returns MODULE_EXPLOIT to indicate that this is an exploit module.
# #
def self.type def self.type
MODULE_EXPLOIT MODULE_EXPLOIT
end end
#
# Returns MODULE_EXPLOIT to indicate that this is an exploit module.
#
def type def type
MODULE_EXPLOIT MODULE_EXPLOIT
end end
@ -581,8 +647,17 @@ class Exploit < Msf::Module
protected protected
#
# Writable copy of the list of targets.
#
attr_writer :targets attr_writer :targets
#
# Writable copy of the default target.
#
attr_writer :default_target attr_writer :default_target
#
# Writable copy of the payload requirement hash.
#
attr_writer :payload_info attr_writer :payload_info
# #
@ -600,6 +675,14 @@ protected
CompatDefaults::Payload.each_pair { |k,v| CompatDefaults::Payload.each_pair { |k,v|
(p[k]) ? p[k] << v : p[k] = v (p[k]) ? p[k] << v : p[k] = v
} }
#
# Set the default save registers if none have been explicitly
# specified.
#
if (module_info['SaveRegisters'] == nil)
module_info['SaveRegisters'] = [ 'esp', 'ebp' ]
end
end end
end end

View File

@ -141,15 +141,15 @@ class ExploitDriver
return session return session
end end
attr_reader :target_idx attr_reader :target_idx # :nodoc:
attr_accessor :exploit attr_accessor :exploit # :nodoc:
attr_accessor :payload attr_accessor :payload # :nodoc:
attr_accessor :use_job attr_accessor :use_job # :nodoc:
attr_accessor :force_wait_for_session attr_accessor :force_wait_for_session # :nodoc:
protected protected
attr_accessor :session attr_accessor :session # :nodoc:
# #
# Job run proc, sets up the exploit and kicks it off. # Job run proc, sets up the exploit and kicks it off.

View File

@ -12,11 +12,16 @@ module Msf
### ###
class Nop < Msf::Module class Nop < Msf::Module
# NOP module, bitch! #
# Returns MODULE_NOP to indicate that this is a NOP module.
#
def self.type def self.type
return MODULE_NOP return MODULE_NOP
end end
#
# Returns MODULE_NOP to indicate that this is a NOP module.
#
def type def type
return MODULE_NOP return MODULE_NOP
end end

View File

@ -24,8 +24,24 @@ class Payload < Msf::Module
# Payload types # Payload types
# #
module Type module Type
#
# Single payload type. These types of payloads are self contained and
# do not go through any staging.
#
Single = (1 << 0) Single = (1 << 0)
#
# The stager half of a staged payload. Its responsibility in life is to
# read in the stage and execute it.
#
Stager = (1 << 1) Stager = (1 << 1)
#
# The stage half of a staged payload. This payload performs whatever
# arbitrary task it's designed to do, possibly making use of the same
# connection that the stager used to read the stage in on, if
# applicable.
#
Stage = (1 << 2) Stage = (1 << 2)
end end
@ -45,12 +61,15 @@ class Payload < Msf::Module
## ##
# #
# This module is a payload. # Returns MODULE_PAYLOAD to indicate that this is a payload module.
# #
def self.type def self.type
return MODULE_PAYLOAD return MODULE_PAYLOAD
end end
#
# Returns MODULE_PAYLOAD to indicate that this is a payload module.
#
def type def type
return MODULE_PAYLOAD return MODULE_PAYLOAD
end end
@ -120,7 +139,8 @@ class Payload < Msf::Module
end end
# #
# The method used to resolve symbols by the payload. # Returns the method used by the payload to resolve symbols for the purpose
# of calling functions, such as ws2ord.
# #
def symbol_lookup def symbol_lookup
module_info['SymbolLookup'] module_info['SymbolLookup']
@ -172,14 +192,16 @@ class Payload < Msf::Module
## ##
# #
# Make sure all our required options are set. # This method ensures that the options associated with this payload all
# have valid values according to each required option in the option
# container.
# #
def validate def validate
self.options.validate(self.datastore) self.options.validate(self.datastore)
end end
# #
# Generates the payload and return the raw buffer # Generates the payload and returns the raw buffer to the caller.
# #
def generate def generate
raw = payload.dup raw = payload.dup
@ -271,8 +293,21 @@ class Payload < Msf::Module
return nops return nops
end end
# Payload prepending and appending for various situations #
attr_accessor :prepend, :append, :prepend_encoder # This attribute holds the string that should be prepended to the buffer
# when it's generated.
#
attr_accessor :prepend
#
# This attribute holds the string that should be appended to the buffer
# when it's generated.
#
attr_accessor :append
#
# This attribute holds the string that should be prepended to the encoded
# version of the payload (in front of the encoder as well).
#
attr_accessor :prepend_encoder
protected protected