Refactor ModuleTest and add a few more tests

This makes running tests from a post module as easy as creating methods
that start with +test_+ and running +it()+ blocks inside them.
James Lee 2012-03-02 17:55:11 -07:00
parent 6c0f8636ec
commit c44c0ebf48
2 changed files with 112 additions and 21 deletions

View File

@ -1,16 +1,33 @@
module Msf
module Msf::ModuleTest module ModuleTest
attr_accessor :error attr_accessor :tests
attr_accessor :failures
def initialize(info={})
@tests = 0
@failures = 0
super
end
def run_all_tests
tests = self.methods.select { |m| m.to_s =~ /^test_/ }
tests.each { |test_method|
self.send(test_method)
}
end
def it(msg="", &block) def it(msg="", &block)
@tests += 1
begin begin
result = block.call result = block.call
unless result unless result
print_error("FAILED: #{msg}") print_error("FAILED: #{msg}")
print_error("FAILED: #{error}") if error print_error("FAILED: #{error}") if error
@error = nil @failures += 1
return return
end end
rescue ::Exception => e rescue ::Exception => e
@ -23,5 +40,19 @@ module Msf::ModuleTest
end end
end end
module ModuleTest::PostTest
include ModuleTest
def run
print_status("Running against session #{datastore["SESSION"]}")
print_status("Session type is #{session.type}")
print_status("Session platform is #{session.platform}")
@tests = 0; @failures = 0
run_all_tests
vprint_status("Testing complete.")
print_status("Passed: #{@tests - @failures}; Failed: #{@failures}")
end
end
end

View File

@ -6,11 +6,9 @@ $:.push "test/lib" unless $:.include? "test/lib"
#require 'module_test' #require 'module_test'
load 'test/lib/module_test.rb' load 'test/lib/module_test.rb'
load 'lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb'
class Metasploit3 < Msf::Post class Metasploit3 < Msf::Post
include Msf::ModuleTest include Msf::ModuleTest::PostTest
def initialize(info={}) def initialize(info={})
super( update_info( info, super( update_info( info,
@ -18,25 +16,16 @@ class Metasploit3 < Msf::Post
'Description' => %q{ This module will test meterpreter API methods }, 'Description' => %q{ This module will test meterpreter API methods },
'License' => MSF_LICENSE, 'License' => MSF_LICENSE,
'Author' => [ 'egypt'], 'Author' => [ 'egypt'],
'Version' => '$Revision: 11663 $', 'Version' => '$Revision$',
'Platform' => [ 'windows', 'linux' ], 'Platform' => [ 'windows', 'linux', 'java' ],
'SessionTypes' => [ 'meterpreter' ] 'SessionTypes' => [ 'meterpreter' ]
)) ))
end end
def run
print_status("Running against session #{datastore["SESSION"]}")
print_status("Session type is #{session.type}")
test_sys_config
test_net_config
test_fs
print_status("Testing complete.")
end
def test_sys_config def test_sys_config
vprint_status("Starting system config tests")
it "should return a user id" do it "should return a user id" do
uid = session.sys.config.getuid uid = session.sys.config.getuid
true true
@ -49,14 +38,49 @@ class Metasploit3 < Msf::Post
end end
def test_net_config def test_net_config
vprint_status("Starting networking tests")
it "should return network interfaces" do it "should return network interfaces" do
ifaces = session.net.config.get_interfaces ifaces = session.net.config.get_interfaces
res = !!(ifaces and ifaces.length > 0)
ifaces and ifaces.length > 0 res
end end
it "should have an interface that matches session_host" do
ifaces = session.net.config.get_interfaces
res = !!(ifaces and ifaces.length > 0)
p session.session_host
res &&= !! ifaces.find { |iface|
iface.ip == session.session_host || iface.ip6 == session.session_host
}
res
end
it "should return network routes" do
routes = session.net.config.get_routes
routes[0] and routes[0].length > 0
end
end end
def test_fs def test_fs
vprint_status("Starting filesystem tests")
it "should return the proper directory separator" do
sysinfo = session.sys.config.sysinfo
if sysinfo["OS"] =~ /windows/i
sep = session.fs.file.separator
res = (sep == "\\")
else
sep = session.fs.file.separator
res = (sep == "/")
end
res
end
it "should return the current working directory" do it "should return the current working directory" do
wd = session.fs.dir.pwd wd = session.fs.dir.pwd
@ -119,7 +143,6 @@ class Metasploit3 < Msf::Post
fd = session.fs.file.new("meterpreter-test", "rb") fd = session.fs.file.new("meterpreter-test", "rb")
contents = fd.read contents = fd.read
vprint_status("Wrote #{contents}") vprint_status("Wrote #{contents}")
p fd
res &&= (contents == "test") res &&= (contents == "test")
fd.close fd.close
@ -129,8 +152,45 @@ class Metasploit3 < Msf::Post
res res
end end
it "should upload a file" do
res = true
remote = "HACKING.remote.txt"
local = "HACKING"
vprint_status("uploading")
session.fs.file.upload_file(remote, local)
vprint_status("done")
res &&= session.fs.dir.entries.include?(remote)
vprint_status("remote file exists? #{res.inspect}")
if res
session.fs.file.download(remote, remote)
res &&= ::File.file? remote
::File.unlink remote
end end
res
end
end
def test_sniffer
begin
session.core.use "sniffer"
rescue
# Not all meterpreters have a sniffer extension, don't count it
# against them.
return
end
it "should list interfaces" do
session.sniffer.interfaces.kind_of? Array
end
# XXX: how do we test this more thoroughly in a generic way?
end
protected
def create_directory(name) def create_directory(name)
res = true res = true