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.
parent
6c0f8636ec
commit
c44c0ebf48
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue