Merge pull request #77 from rapid7/lab_temp2

squashed lab upload commit
unstable
Jonathan Cran 2011-12-22 13:00:26 -08:00
commit 5cec44bc43
11 changed files with 187 additions and 100 deletions

View File

@ -134,11 +134,11 @@ class FogDriver < VmDriver
end
end
def copy_from(from, to)
def copy_from_guest(from, to)
raise "unimplemented"
end
def copy_to(from, to)
def copy_to_guest(from, to)
raise "unimplemented"
end

View File

@ -102,7 +102,7 @@ class RemoteEsxDriver < VmDriver
raise "Not Implemented"
end
def copy_from(from, to)
def copy_from_guest(from, to)
if @os == "linux"
scp_from(from, to)
else
@ -110,7 +110,7 @@ class RemoteEsxDriver < VmDriver
end
end
def copy_to(from, to)
def copy_to_guest(from, to)
if @os == "linux"
scp_to(from, to)
else

View File

@ -116,7 +116,7 @@ class RemoteWorkstationDriver < VmDriver
end
end
def copy_from(from, to)
def copy_from_guest(from, to)
from = filter_input(from)
to = filter_input(to)
@ -133,7 +133,7 @@ class RemoteWorkstationDriver < VmDriver
end
end
def copy_to(from, to)
def copy_to_guest(from, to)
from = filter_input(from)
to = filter_input(to)
@ -165,9 +165,8 @@ class RemoteWorkstationDriver < VmDriver
directory = filter_input(directory)
if @tools
emote_system_command("ssh #{@user}@#{@host} vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " +
remote_system_command("ssh #{@user}@#{@host} vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " +
"createDirectoryInGuest \'#{@location}\' \'#{directory}\' nogui")
system_command(vmrunstr)
else
raise "Not Implemented - Install VmWare Tools"
end
@ -178,17 +177,21 @@ class RemoteWorkstationDriver < VmDriver
end
def running?
## Get running VMs
running = `ssh #{@user}@#{@host} \"vmrun list nogui\"`
running_array = running.split("\n")
running_array.shift
running_array.each do |vmx|
if vmx.to_s == @location.to_s
return true
# Get running VMs
running = remote_system_command("vmrun list nogui")
if running
running_array = running.split("\n")
running_array.shift
running_array.each do |vmx|
if vmx.to_s == @location.to_s
return true
end
end
end
false
end

View File

@ -98,14 +98,14 @@ module Drivers
system_command(command)
end
def copy_from(from, to)
def copy_from_guest(from, to)
from = filter_input(from)
to = filter_input(to)
raise "Not supported by Virtual Box"
end
def copy_to(from, to)
def copy_to_guest(from, to)
from = filter_input(from)
to = filter_input(to)

View File

@ -24,6 +24,7 @@ class VmDriver
@location = filter_command(config["location"])
@credentials = config["credentials"] || []
@tools = filter_input(config["tools"])
@os = filter_input(config["os"])
@hostname = filter_input(config["hostname"]) || filter_input(config["vmid"].to_s)
@ -86,11 +87,11 @@ class VmDriver
raise "Command not Implemented"
end
def copy_from(from, to)
def copy_from_guest(from, to)
raise "Command not Implemented"
end
def copy_to(from, to)
def copy_to_guest(from, to)
raise "Command not Implemented"
end
@ -142,7 +143,7 @@ private
def filter_input(string)
return "" unless string # nil becomes empty string
return unless string.class == String # Allow other types unmodified
return string unless string.class == String # Allow other types unmodified
unless /^[\d\w\s\[\]\{\}\/\\\.\-\"\(\):!]*$/.match string
raise "WARNING! Invalid character in: #{string}"
@ -166,8 +167,7 @@ private
# the ability to still run clean (controlled entirely by us)
# command lines.
def system_command(command)
#puts "DEBUG: system command #{command}"
system(command)
`#{command}`
end

View File

@ -107,7 +107,6 @@ class WorkstationDriver < VmDriver
# Ghettohack!
string = File.open(output_file,"r").read
`rm #{output_file}`
else
raise "zomgwtfbbqnotools"
end
@ -115,7 +114,7 @@ class WorkstationDriver < VmDriver
return string
end
def copy_from(from, to)
def copy_from_guest(from, to)
from = filter_input(from)
to = filter_input(to)
if @tools
@ -127,7 +126,8 @@ class WorkstationDriver < VmDriver
system_command(vmrunstr)
end
def copy_to(from, to)
def copy_to_guest(from, to)
from = filter_input(from)
to = filter_input(to)
if @tools

View File

@ -91,13 +91,13 @@ class WorkstationVixrDriver < VmDriver
end
end
def copy_from(from, to)
def copy_from_guest(from, to)
from = filter_input(from)
to = filter_input(to)
cp_from_host(from,to)
end
def copy_to(from, to)
def copy_to_guest(from, to)
from = filter_input(from)
to = filter_input(to)
vm.cp_to_guest(from,to)

View File

@ -1,19 +1,15 @@
$:.unshift(File.join(File.dirname(__FILE__), '..', '..'))
module Lab
module Modifier
module Meterpreter
end
end
end
# This allows us to override the default way of running commands
# Currently useful for the esx controller
module Lab
class Vm
module Modifier
module Meterpreter
attr_accessor :framework
attr_accessor :session
@ -165,3 +161,5 @@ class Vm
end
end
end

View File

@ -18,7 +18,9 @@ class Vm
attr_accessor :host
attr_accessor :os
attr_accessor :arch
attr_accessor :tags
attr_accessor :type
## Initialize takes a vm configuration hash of the form
## - vmid (unique identifier)
## driver (vm technology)
@ -75,8 +77,6 @@ class Vm
#Only fog systems need this
@fog_config = config['fog_config']
#puts "Passing driver config: #{config}"
# Process the correct driver
if @driver_type == "workstation"
@driver = Lab::Drivers::WorkstationDriver.new(config)
@ -101,8 +101,6 @@ class Vm
# Load in a list of modifiers. These provide additional methods
# Currently it is up to the user to verify that
# modifiers are properly used with the correct VM image.
#
# If not, the results are likely to be disasterous.
@modifiers = config['modifiers']
if @modifiers
@ -112,6 +110,14 @@ class Vm
# modifier likely didn't exist
end
end
# Consume all tags
@tags = config['tags']
end
def tagged?(tag_name)
return false unless @tags
return true if @tags.include?(tag_name)
end
def running?
@ -163,12 +169,12 @@ class Vm
@driver.start
end
def copy_to(from,to)
@driver.copy_to(from,to)
def copy_to_guest(from,to)
@driver.copy_to_guest(from,to)
end
def copy_from(from,to)
@driver.copy_from(from,to)
def copy_from_guest(from,to)
@driver.copy_from_guest(from,to)
end
def run_command(command)
@ -196,7 +202,7 @@ class Vm
end
def to_s
return "#{@vmid}"
return "#{@hostname}"
end
def to_yaml

View File

@ -50,19 +50,25 @@ module Controllers
def [](x)
# Support indexing by both names and number
if x.class == String
find_by_vmid(x)
find_by_hostname(x)
else
return @vms[x]
end
end
def find_by_vmid(vmid)
def find_by_hostname(vmid)
@vms.each do |vm|
if (vm.hostname.to_s.downcase == vmid.to_s.downcase)
return vm
end
end
return nil
return nil
end
def find_by_tag(tag_name)
tagged_vms = []
@vms.each { |vm| tagged_vms << vm if vm.tagged?(tag_name) }
return tagged_vms
end
def add_vm(vmid, location=nil, os=nil, tools=nil, credentials=nil, user=nil, host=nil)
@ -75,7 +81,7 @@ module Controllers
end
def remove_by_vmid(vmid)
@vms.delete(self.find_by_vmid(vmid))
@vms.delete(self.find_by_hostname(vmid))
end
def from_file(file)
@ -108,6 +114,14 @@ module Controllers
false
end
def includes_hostname?(hostname)
@vms.each do |vm|
return true if (vm.hostname == hostname)
end
false
end
def build_from_dir(driver_type, dir, clear=false)
if clear
@ -229,7 +243,7 @@ module Controllers
def running?(vmid)
if includes_vmid?(vmid)
return self.find_by_vmid(vmid).running?
return self.find_by_hostname(vmid).running?
end
return false
end

View File

@ -28,6 +28,9 @@ class Plugin::Lab < Msf::Plugin
{
"lab_help" => "lab_help <lab command> - Show that command's description.",
"lab_show" => "lab_show - show all vms in the lab.",
"lab_search" => "lab_search - search local vms in the lab.",
"lab_search_tags" => "lab_search_tag - search local vms in the lab.",
#"lab_search_remote" => "lab_search_remote - search remote vms in the lab.",
"lab_show_running" => "lab_show_running - show running vms.",
"lab_load" => "lab_load [file] - load a lab definition from disk.",
"lab_save" => "lab_save [filename] - persist a lab definition in a file.",
@ -41,6 +44,7 @@ class Plugin::Lab < Msf::Plugin
"lab_stop" => "lab_stop [vmid+|all] stop the specified vm.",
"lab_revert" => "lab_revert [vmid+|all] [snapshot] revert the specified vm.",
"lab_snapshot" => "lab_snapshot [vmid+|all] [snapshot] snapshot all targets for this exploit.",
"lab_upload" => "lab_upload [vmid] [local_path] [remote_path] upload a file.",
"lab_run_command" => "lab_run_command [vmid+|all] [command] run a command on all targets.",
"lab_browse_to" => "lab_browse_to [vmid+|all] [uri] use the default browser to browse to a uri."
}
@ -103,16 +107,15 @@ class Plugin::Lab < Msf::Plugin
##
## Commands for dealing with a currently-loaded lab
##
def cmd_lab_show(*args)
if args.empty?
hlp_print_lab
else
args.each do |vmid|
if @controller.includes_vmid? vmid
print_line @controller[vmid].to_yaml
args.each do |name|
if @controller.includes_hostname? name
print_line @controller[name].to_yaml
else
print_error "Unknown vm '#{vmid}'"
print_error "Unknown vm '#{name}'"
end
end
end
@ -122,27 +125,57 @@ class Plugin::Lab < Msf::Plugin
hlp_print_lab_running
end
def cmd_lab_search(*args)
if args.empty?
hlp_print_lab
else
args.each do |arg|
print_line "Searching for vms with hostname matching #{arg}"
@controller.each do |vm|
print_line "checking to see #{vm.hostname} matches #{arg}"
print_line "#{vm.hostname} matched #{arg}" if vm.hostname =~ Regexp.new(arg)
end
end
end
end
def cmd_lab_search_tags(*args)
if args.empty?
hlp_print_lab
else
args.each do |arg|
print_line "Searching for vms with tags matching #{arg}"
@controller.each do |vm|
print_line "checking to see #{vm.hostname} is tagged #{arg}"
print_line "#{vm.hostname} tagged #{arg}" if vm.tagged?(arg)
end
end
end
end
def cmd_lab_start(*args)
return lab_usage if args.empty?
if args[0] == "all"
@controller.each do |vm|
print_line "Starting lab vm #{vm.vmid}."
print_line "Starting lab vm #{vm.hostname}."
if !vm.running?
vm.start
else
print_line "Lab vm #{vm.vmid} already running."
print_line "Lab vm #{vm.hostname} already running."
end
end
else
args.each do |arg|
if @controller.includes_vmid? arg
vm = @controller.find_by_vmid(arg)
if @controller.includes_hostname? arg
vm = @controller.find_by_hostname(arg)
if !vm.running?
print_line "Starting lab vm #{vm.vmid}."
print_line "Starting lab vm #{vm.hostname}."
vm.start
else
print_line "Lab vm #{vm.vmid} already running."
print_line "Lab vm #{vm.hostname} already running."
end
end
end
@ -154,22 +187,22 @@ class Plugin::Lab < Msf::Plugin
if args[0] == "all"
@controller.each do |vm|
print_line "Stopping lab vm #{vm.vmid}."
print_line "Stopping lab vm #{vm.hostname}."
if vm.running?
vm.stop
else
print_line "Lab vm #{vm.vmid} not running."
print_line "Lab vm #{vm.hostname} not running."
end
end
else
args.each do |arg|
if @controller.includes_vmid? arg
vm = @controller.find_by_vmid(arg)
if @controller.includes_hostname? arg
vm = @controller.find_by_hostname(arg)
if vm.running?
print_line "Stopping lab vm #{vm.vmid}."
print_line "Stopping lab vm #{vm.hostname}."
vm.stop
else
print_line "Lab vm #{vm.vmid} not running."
print_line "Lab vm #{vm.hostname} not running."
end
end
end
@ -183,10 +216,10 @@ class Plugin::Lab < Msf::Plugin
@controller.each{ |vm| vm.suspend }
else
args.each do |arg|
if @controller.includes_vmid? arg
if @controller.find_by_vmid(arg).running?
if @controller.includes_hostname? arg
if @controller.find_by_hostname(arg).running?
print_line "Suspending lab vm #{arg}."
@controller.find_by_vmid(arg).suspend
@controller.find_by_hostname(arg).suspend
end
end
end
@ -201,10 +234,10 @@ class Plugin::Lab < Msf::Plugin
@controller.each{ |vm| vm.reset }
else
args.each do |arg|
if @controller.includes_vmid? arg
if @controller.find_by_vmid(arg).running?
if @controller.includes_hostname? arg
if @controller.find_by_hostname(arg).running?
print_line "Resetting lab vm #{arg}."
@controller.find_by_vmid(arg).reset
@controller.find_by_hostname(arg).reset
end
end
end
@ -220,10 +253,10 @@ class Plugin::Lab < Msf::Plugin
print_line "Snapshotting all lab vms to snapshot: #{snapshot}."
@controller.each{ |vm| vm.create_snapshot(snapshot) }
else
args[0..-2].each do |vmid_arg|
next unless @controller.includes_vmid? vmid_arg
print_line "Snapshotting #{vmid_arg} to snapshot: #{snapshot}."
@controller[vmid_arg].create_snapshot(snapshot)
args[0..-2].each do |name_arg|
next unless @controller.includes_hostname? name_arg
print_line "Snapshotting #{name_arg} to snapshot: #{snapshot}."
@controller[name_arg].create_snapshot(snapshot)
end
end
end
@ -237,10 +270,10 @@ class Plugin::Lab < Msf::Plugin
print_line "Reverting all lab vms to snapshot: #{snapshot}."
@controller.each{ |vm| vm.revert_snapshot(snapshot) }
else
args[0..-2].each do |vmid_arg|
next unless @controller.includes_vmid? vmid_arg
print_line "Reverting #{vmid_arg} to snapshot: #{snapshot}."
@controller[vmid_arg].revert_snapshot(snapshot)
args[0..-2].each do |name_arg|
next unless @controller.includes_hostname? name_arg
print_line "Reverting #{name_arg} to snapshot: #{snapshot}."
@controller[name_arg].revert_snapshot(snapshot)
end
end
end
@ -253,16 +286,48 @@ class Plugin::Lab < Msf::Plugin
print_line "Running command #{command} on all vms."
@controller.each do |vm|
if vm.running?
print_line "#{vm.vmid} running command: #{command}."
print_line "#{vm.hostname} running command: #{command}."
vm.run_command(command)
end
end
else
args[0..-2].each do |name_arg|
next unless @controller.includes_hostname? name_arg
if @controller[name_arg].running?
print_line "#{name_arg} running command: #{command}."
@controller[name_arg].run_command(command)
end
end
end
end
#
# Command: lab_upload [vmids] [from] [to]
#
# Description: Uploads a file to the guest(s)
#
# Quirks: Pass "all" as a vmid to have it operate on all vms.
#
def cmd_lab_upload(*args)
return lab_usage if args.empty?
return lab_usage if args.count < 3
local_path = args[args.count-2]
vm_path = args[args.count-1]
if args[0] == "all"
@controller.each do |vm|
if vm.running?
print_line "Copying from #{local_path} to #{vm_path} on #{vm.hostname}"
vm.copy_to_guest(local_path, vm_path)
end
end
else
args[0..-2].each do |vmid_arg|
next unless @controller.includes_vmid? vmid_arg
if @controller[vmid_arg].running?
print_line "#{vmid_arg} running command: #{command}."
@controller[vmid_arg].run_command(command)
print_line "Copying from #{local_path} to #{vm_path} on #{vmid_arg}"
@controller[vmid_arg].copy_to_guest(local_path, vm_path)
end
end
end
@ -275,16 +340,16 @@ class Plugin::Lab < Msf::Plugin
print_line "Opening: #{uri} on all vms."
@controller.each do |vm|
if vm.running?
print_line "#{vm.vmid} opening to uri: #{uri}."
print_line "#{vm.hostname} opening to uri: #{uri}."
vm.open_uri(uri)
end
end
else
args[0..-2].each do |vmid_arg|
next unless @controller.includes_vmid? vmid_arg
if @controller[vmid_arg].running?
print_line "#{vmid_arg} opening to uri: #{uri}."
@controller[vmid_arg].open_uri(uri)
args[0..-2].each do |name_arg|
next unless @controller.includes_hostname? name_arg
if @controller[name_arg].running?
print_line "#{name_arg} opening to uri: #{uri}."
@controller[name_arg].open_uri(uri)
end
end
end
@ -347,14 +412,13 @@ class Plugin::Lab < Msf::Plugin
tbl = Rex::Ui::Text::Table.new(
'Header' => 'Available Lab VMs',
'Indent' => indent.length,
'Columns' => [ 'Vmid', 'Name', 'Location', "Power?" ]
'Columns' => [ 'Hostname', 'Driver', 'Type' ]
)
@controller.each do |vm|
tbl << [ vm.vmid,
vm.name,
vm.location,
vm.running?]
tbl << [ vm.hostname,
vm.driver.class,
vm.type]
end
print_line tbl.to_s
@ -366,14 +430,14 @@ class Plugin::Lab < Msf::Plugin
tbl = Rex::Ui::Text::Table.new(
'Header' => 'Running Lab VMs',
'Indent' => indent.length,
'Columns' => [ 'Vmid', 'Name', 'Location', 'Power?' ]
'Columns' => [ 'Hostname', 'Driver', 'Type', 'Power?' ]
)
@controller.each do |vm|
if vm.running?
tbl << [ vm.vmid,
vm.name,
vm.location,
tbl << [ vm.hostname,
vm.driver.class,
vm.type,
vm.running?]
end
end
@ -390,6 +454,8 @@ class Plugin::Lab < Msf::Plugin
# inheriting from Msf::Plugin to ensure that the framework attribute on
# their instance gets set.
#
attr_accessor :controller
def initialize(framework, opts)
super
@ -430,4 +496,4 @@ class Plugin::Lab < Msf::Plugin
end
end ## End Class
end ## End Module
end ## End Module