started working on exploit stuff, changed aliases a bit for windows payloads, pimped targets to the max, added wrappers to exploit for payload stuff
git-svn-id: file:///home/svn/incoming/trunk@2729 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
parent
7d2e970774
commit
0e357337a5
|
@ -32,13 +32,75 @@ class ReadableText
|
|||
end
|
||||
end
|
||||
|
||||
def self.dump_exploit_module(mod, indent)
|
||||
#
|
||||
# Dumps information about an exploit module.
|
||||
#
|
||||
def self.dump_exploit_module(mod, indent = '')
|
||||
output = "\n"
|
||||
output += " Name: #{mod.name}\n"
|
||||
output += " Version: #{mod.version}\n"
|
||||
output += " Platform: #{mod.platform_to_s}\n"
|
||||
output += " Privileged: " + (mod.privileged? ? "Yes" : "No") + "\n"
|
||||
output += "\n"
|
||||
|
||||
# Authors
|
||||
output += "Provided by:\n"
|
||||
mod.each_author { |author|
|
||||
output += indent + author.to_s + "\n"
|
||||
}
|
||||
output += "\n"
|
||||
|
||||
# Targets
|
||||
tbl = Rex::Ui::Text::Table.new(
|
||||
'Indent' => indent.length,
|
||||
'Columns' =>
|
||||
[
|
||||
'Id',
|
||||
'Name',
|
||||
])
|
||||
|
||||
output += "Available targets:\n"
|
||||
mod.targets.each_with_index { |target, idx|
|
||||
tbl << [ idx.to_s, target.name || 'All' ]
|
||||
}
|
||||
output += tbl.to_s
|
||||
output += "\n"
|
||||
|
||||
# Options
|
||||
if (mod.options.has_options?)
|
||||
output += "Available options:\n"
|
||||
output += dump_options(mod)
|
||||
output += "\n"
|
||||
end
|
||||
|
||||
# Advanced options
|
||||
if (mod.options.has_advanced_options?)
|
||||
output += "Advanced options:\n"
|
||||
output += dump_advanced_options(mod)
|
||||
output += "\n"
|
||||
end
|
||||
|
||||
# Payload information
|
||||
if (mod.payload.length)
|
||||
output += "Payload information:\n"
|
||||
output += indent + "Space: " + mod.payload_space.to_s + "\n"
|
||||
output += indent + "Avoid: " + mod.payload_badchars.length.to_s + " characters\n"
|
||||
output += "\n"
|
||||
end
|
||||
|
||||
# Description
|
||||
output += "Description:\n"
|
||||
output += word_wrap(mod.description)
|
||||
output += "\n\n"
|
||||
|
||||
return output
|
||||
|
||||
end
|
||||
|
||||
#
|
||||
# Dumps information about a payload module.
|
||||
#
|
||||
def self.dump_payload_module(mod, indent)
|
||||
def self.dump_payload_module(mod, indent = '')
|
||||
# General
|
||||
output = "\n"
|
||||
output += " Name: #{mod.name}\n"
|
||||
|
@ -81,7 +143,7 @@ class ReadableText
|
|||
#
|
||||
# Dumps information about a module, just the basics.
|
||||
#
|
||||
def self.dump_basic_module(mod, indent)
|
||||
def self.dump_basic_module(mod, indent = '')
|
||||
# General
|
||||
output = "\n"
|
||||
output += " Name: #{mod.name}\n"
|
||||
|
@ -113,7 +175,7 @@ class ReadableText
|
|||
|
||||
end
|
||||
|
||||
def self.dump_generic_module(mod, indent)
|
||||
def self.dump_generic_module(mod, indent = '')
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -131,7 +193,9 @@ class ReadableText
|
|||
'Description'
|
||||
])
|
||||
|
||||
mod.options.each_option { |name, opt|
|
||||
mod.options.sorted.each { |entry|
|
||||
name, opt = entry
|
||||
|
||||
next if (opt.advanced?)
|
||||
|
||||
val = mod.datastore[name] || opt.default || ''
|
||||
|
@ -146,7 +210,9 @@ class ReadableText
|
|||
output = ''
|
||||
pad = ' ' * indent
|
||||
|
||||
mod.options.each_option { |name, opt|
|
||||
mod.options.sorted.each { |entry|
|
||||
name, opt = entry
|
||||
|
||||
next if (!opt.advanced?)
|
||||
|
||||
val = mod.datastore[name] || opt.default || ''
|
||||
|
|
|
@ -78,6 +78,8 @@ class Exploit < Msf::Module
|
|||
|
||||
self.targets = Rex::Transformer.transform(info['Targets'], Array,
|
||||
[ Target ], 'Targets')
|
||||
self.default_target = info['DefaultTarget']
|
||||
self.payload = info['Payload'] || {}
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -161,52 +163,126 @@ class Exploit < Msf::Module
|
|||
# Generally, all exploits take an aggressive stance.
|
||||
#
|
||||
def stance
|
||||
Stance::Aggressive
|
||||
module_info['Stance'] || Stance::Aggressive
|
||||
end
|
||||
|
||||
##
|
||||
#
|
||||
# Payload requirement wrappers
|
||||
#
|
||||
##
|
||||
|
||||
#
|
||||
# Return any text that should be prepended to the payload. The payload
|
||||
# module is passed so that the exploit can take a guess at architecture
|
||||
# and platform if it's a multi exploit.
|
||||
#
|
||||
def payload_prepend(payload_module)
|
||||
payload['Prepend'] || ''
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the payload that has been set for this exploit instance
|
||||
# Return any text that should be appended to the payload. The payload
|
||||
# module is passed so that the exploit can take a guess at architecture
|
||||
# and platform if it's a multi exploit.
|
||||
#
|
||||
def payload
|
||||
# TODO
|
||||
def payload_append(payload_module)
|
||||
payload['Append'] || ''
|
||||
end
|
||||
|
||||
#
|
||||
# Return any text that should be prepended to the encoder of the payload.
|
||||
# The payload module is passed so that the exploit can take a guess
|
||||
# at architecture and platform if it's a multi exploit.
|
||||
#
|
||||
def payload_prepend_encoder(payload_module)
|
||||
payload['PrependEncoder'] || ''
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the maximum amount of room the exploit has for a payload.
|
||||
#
|
||||
# TODO: make target based? size differences per platform...
|
||||
#
|
||||
def payload_space
|
||||
payload['Space'].to_i
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the bad characters that cannot be in any payload used by this
|
||||
# exploit.
|
||||
#
|
||||
def payload_badchars
|
||||
payload['BadChars']
|
||||
end
|
||||
|
||||
##
|
||||
#
|
||||
# NOP requirement wrappers
|
||||
#
|
||||
##
|
||||
|
||||
#
|
||||
# Returns the list of registers that the NOP generator should save,
|
||||
# if any. It will use the current target's save registers in precedence
|
||||
# over those defined globally for the exploit module.
|
||||
#
|
||||
# If there are no save registers, nil is returned.
|
||||
#
|
||||
def nop_save_registers
|
||||
if (target and targets[target].save_registers)
|
||||
return targets[target].save_registers
|
||||
else
|
||||
return module_info['SaveRegisters'] || nil
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Attributes
|
||||
#
|
||||
attr_accessor :target, :targets
|
||||
attr_reader :default_target
|
||||
attr_reader :payload
|
||||
|
||||
###
|
||||
#
|
||||
# Local
|
||||
# -----
|
||||
#
|
||||
# The local exploit class is a specialization of the exploit module class that
|
||||
# is geared toward exploits that are performed locally. Locally, in this
|
||||
# case, is defined as an exploit that is realized by means other than network
|
||||
# communication.
|
||||
#
|
||||
###
|
||||
class Local < Exploit
|
||||
def exploit_type
|
||||
Exploit::Type::Local
|
||||
end
|
||||
end
|
||||
###
|
||||
#
|
||||
# Local
|
||||
# -----
|
||||
#
|
||||
# The local exploit class is a specialization of the exploit module class that
|
||||
# is geared toward exploits that are performed locally. Locally, in this
|
||||
# case, is defined as an exploit that is realized by means other than network
|
||||
# communication.
|
||||
#
|
||||
###
|
||||
class Local < Exploit
|
||||
def exploit_type
|
||||
Exploit::Type::Local
|
||||
end
|
||||
end
|
||||
|
||||
###
|
||||
#
|
||||
# Remote
|
||||
# ------
|
||||
#
|
||||
# The remote exploit class is a specialization of the exploit module class
|
||||
# that is geared toward exploits that are performed against targets other than
|
||||
# the local machine. This typically implies exploiting other machines via a
|
||||
# network connection, though it is not limited to this scope.
|
||||
#
|
||||
###
|
||||
class Remote < Exploit
|
||||
###
|
||||
#
|
||||
# Remote
|
||||
# ------
|
||||
#
|
||||
# The remote exploit class is a specialization of the exploit module class
|
||||
# that is geared toward exploits that are performed against targets other than
|
||||
# the local machine. This typically implies exploiting other machines via a
|
||||
# network connection, though it is not limited to this scope.
|
||||
#
|
||||
###
|
||||
class Remote < Exploit
|
||||
|
||||
def exploit_type
|
||||
Exploit::Type::Remote
|
||||
end
|
||||
end
|
||||
def exploit_type
|
||||
Exploit::Type::Remote
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
attr_writer :default_target
|
||||
attr_writer :payload
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -18,8 +18,6 @@ module Exploit::Remote::Tcp
|
|||
[
|
||||
Opt::RHOST,
|
||||
Opt::RPORT,
|
||||
Opt::LHOST(nil, false),
|
||||
Opt::LPORT(nil, false)
|
||||
], Msf::Exploit::Remote::Tcp)
|
||||
end
|
||||
|
||||
|
@ -30,8 +28,8 @@ module Exploit::Remote::Tcp
|
|||
sock = Rex::Socket::Tcp.create(
|
||||
'PeerHost' => datastore['RHOST'],
|
||||
'PeerPort' => datastore['RPORT'].to_i,
|
||||
'LocalHost' => datastore['LHOST'],
|
||||
'LocalPort' => datastore['LPORT'].to_i)
|
||||
'LocalHost' => datastore['LHOST'] || "0.0.0.0",
|
||||
'LocalPort' => datastore['LPORT'] ? datastore['LPORT'].to_i : 0)
|
||||
|
||||
# Set this socket to the global socket as necessary
|
||||
esock = sock if (global)
|
||||
|
|
|
@ -52,6 +52,11 @@ class Module
|
|||
self.datastore = DataStore.new
|
||||
self.datastore.import_options(self.options)
|
||||
|
||||
# If there are default options, import their values into the datastore
|
||||
if (module_info['DefaultOptions'])
|
||||
self.datastore.import_options_from_hash(module_info['DefaultOptions'])
|
||||
end
|
||||
|
||||
self.privileged = module_info['Privileged'] || false
|
||||
end
|
||||
|
||||
|
@ -77,7 +82,7 @@ class Module
|
|||
# name is returned.
|
||||
#
|
||||
def alias
|
||||
return module_info['Alias'] || name
|
||||
return module_info['Alias']
|
||||
end
|
||||
|
||||
#
|
||||
|
|
|
@ -32,10 +32,11 @@ class Msf::Module::Target
|
|||
def initialize(name, opts)
|
||||
opts = {} if (!opts)
|
||||
|
||||
self.name = name
|
||||
self.platforms = Msf::Module::PlatformList.from_a(opts['Platform'])
|
||||
self.ret = opts['Ret']
|
||||
self.opts = opts
|
||||
self.name = name
|
||||
self.platforms = Msf::Module::PlatformList.from_a(opts['Platform'])
|
||||
self.save_registers = opts['SaveRegisters']
|
||||
self.ret = opts['Ret']
|
||||
self.opts = opts
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -46,7 +47,7 @@ class Msf::Module::Target
|
|||
end
|
||||
|
||||
attr_accessor :name, :platforms, :opts
|
||||
attr_accessor :ret
|
||||
attr_accessor :ret, :save_registers
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -206,9 +206,6 @@ protected
|
|||
mod = mod_from_name(path_base)
|
||||
type = path_base.match(/^(.+?)#{File::SEPARATOR}+?/)[1].sub(/s$/, '')
|
||||
|
||||
# Let's rock the house now...
|
||||
dlog("Loading module from #{path_base}...", 'core', LEV_1)
|
||||
|
||||
# Get the module and grab the current number of constants
|
||||
old_constants = mod.constants
|
||||
|
||||
|
|
|
@ -171,6 +171,8 @@ class OptionContainer < Hash
|
|||
# as necessary.
|
||||
#
|
||||
def initialize(opts = {})
|
||||
self.sorted = []
|
||||
|
||||
add_options(opts)
|
||||
end
|
||||
|
||||
|
@ -231,7 +233,6 @@ class OptionContainer < Hash
|
|||
else
|
||||
add_options_hash(opts, owner, advanced)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -265,6 +266,9 @@ class OptionContainer < Hash
|
|||
option.owner = owner
|
||||
|
||||
self.store(option.name, option)
|
||||
|
||||
# Re-calculate the sorted list
|
||||
self.sorted = self.sort
|
||||
end
|
||||
|
||||
# Alias to add advanced options that sets the proper state flag
|
||||
|
@ -298,6 +302,12 @@ class OptionContainer < Hash
|
|||
each_pair(&block)
|
||||
end
|
||||
|
||||
attr_reader :sorted
|
||||
|
||||
protected
|
||||
|
||||
attr_writer :sorted
|
||||
|
||||
end
|
||||
|
||||
#
|
||||
|
|
|
@ -24,8 +24,12 @@ module Msf::Payload::Windows
|
|||
}
|
||||
|
||||
def initialize(info = {})
|
||||
if (info['Alias'])
|
||||
info['Alias'] = 'windows/' + info['Alias']
|
||||
end
|
||||
|
||||
super
|
||||
|
||||
|
||||
register_options(
|
||||
[
|
||||
Msf::OptRaw.new('EXITFUNC', [ true, "Exit technique: #{@@exit_types.keys.join(", ")}", 'seh' ])
|
||||
|
|
|
@ -2,30 +2,39 @@ require 'msf/core'
|
|||
|
||||
module Msf
|
||||
|
||||
class Exploit::Remote::MSRPC_DCOM_MS03_026 < Msf::Exploit::Remote
|
||||
class Exploits::Windows::MSRPC_DCOM_MS03_026 < Msf::Exploit::Remote
|
||||
|
||||
#
|
||||
# This module exploits a vulnerability in a DCERPC service
|
||||
#
|
||||
include Exploit::Remote::DCERPC
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'Microsoft RPC DCOM MSO3-026',
|
||||
'Description' =>
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Microsoft RPC DCOM MSO3-026',
|
||||
'Description' =>
|
||||
"This module exploits a stack overflow in the RPCSS service, this vulnerability" +
|
||||
"was originally found by the Last Stage of Delirium research group and has been" +
|
||||
"widely exploited ever since. This module can exploit the English versions of " +
|
||||
"Windows NT 4.0 SP3-6a, Windows 2000, Windows XP, and Windows 2003 all in one request :)",
|
||||
'Author' => [ 'hdm', 'spoonm' ],
|
||||
'Version' => '$Revision$',
|
||||
'Refs' =>
|
||||
'Author' => [ 'hdm', 'spoonm' ],
|
||||
'Version' => '$Revision$',
|
||||
'Refs' =>
|
||||
[
|
||||
[ 'OSVDB', '2100' ],
|
||||
[ 'MSB', 'MS03-026' ],
|
||||
],
|
||||
'Privileged' => true,
|
||||
'Targets' =>
|
||||
'Privileged' => true,
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'EXITFUNC' => 'seh'
|
||||
},
|
||||
'Payload' =>
|
||||
{
|
||||
'Space' => 880,
|
||||
'BadChars' => "\x00\x0a\x0d\x5c\x5f\x2f\x2e",
|
||||
},
|
||||
'Targets' =>
|
||||
[
|
||||
# Target 0: Universal
|
||||
[
|
||||
|
@ -45,7 +54,7 @@ class Exploit::Remote::MSRPC_DCOM_MS03_026 < Msf::Exploit::Remote
|
|||
},
|
||||
],
|
||||
],
|
||||
'DefaultTarget' => 0)
|
||||
'DefaultTarget' => 0))
|
||||
end
|
||||
|
||||
def exploit
|
||||
|
|
|
@ -23,7 +23,7 @@ module AddUser
|
|||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Windows Execute net user /ADD',
|
||||
'Alias' => 'win32/adduser',
|
||||
'Alias' => 'adduser',
|
||||
'Version' => '$Revision$',
|
||||
'Description' => 'Create a new user and add them to local administration group',
|
||||
'Author' => 'hdm',
|
||||
|
|
|
@ -21,7 +21,7 @@ module Exec
|
|||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Windows Execute Command',
|
||||
'Alias' => 'win32/exec',
|
||||
'Alias' => 'exec',
|
||||
'Version' => '$Revision$',
|
||||
'Description' => 'Execute an arbitrary command',
|
||||
'Author' => 'vlad902',
|
||||
|
@ -64,7 +64,7 @@ module Exec
|
|||
# Returns the command string to use for execution
|
||||
#
|
||||
def command_string
|
||||
return datastore['CMD']
|
||||
return datastore['CMD'] || ''
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -14,7 +14,7 @@ module Shell
|
|||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
'Name' => 'Windows Reverse Shell',
|
||||
'Alias' => 'win32/shell',
|
||||
'Alias' => 'shell',
|
||||
'Version' => '$Revision$',
|
||||
'Description' => 'Connect back to attacker and spawn a command shell',
|
||||
'Author' => 'vlad902',
|
||||
|
|
|
@ -11,8 +11,8 @@ module Shell
|
|||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
'Name' => 'Stage: Shell',
|
||||
'Alias' => 'win32/shell',
|
||||
'Name' => 'Command shell',
|
||||
'Alias' => 'shell',
|
||||
'Version' => '$Revision$',
|
||||
'Description' => 'Spawn a command shell',
|
||||
'Author' => 'hdm',
|
||||
|
|
Loading…
Reference in New Issue