Merge branch 'jlee-r7-cleanup/post-windows-services'
commit
d2e3e5defb
|
@ -12,10 +12,10 @@ module Msf::Payload::Php
|
|||
#
|
||||
# The generated code will initialize
|
||||
#
|
||||
# @options options [String] :disabled_varname PHP variable name in which to
|
||||
# @option options [String] :disabled_varname PHP variable name in which to
|
||||
# store an array of disabled functions.
|
||||
#
|
||||
# @returns [String] A chunk of PHP code
|
||||
# @return [String] A chunk of PHP code
|
||||
#
|
||||
def php_preamble(options = {})
|
||||
dis = options[:disabled_varname] || '$' + Rex::Text.rand_text_alpha(rand(4) + 4)
|
||||
|
@ -42,15 +42,15 @@ module Msf::Payload::Php
|
|||
#
|
||||
# Generate a chunk of PHP code that tries to run a command.
|
||||
#
|
||||
# @options options [String] :cmd_varname PHP variable name containing the
|
||||
# @option options [String] :cmd_varname PHP variable name containing the
|
||||
# command to run
|
||||
# @options options [String] :disabled_varname PHP variable name containing
|
||||
# @option options [String] :disabled_varname PHP variable name containing
|
||||
# an array of disabled functions. See #php_preamble
|
||||
# @options options [String] :output_varname PHP variable name in which to
|
||||
# @option options [String] :output_varname PHP variable name in which to
|
||||
# store the output of the command. Will contain 0 if no exec functions
|
||||
# work.
|
||||
#
|
||||
# @returns [String] A chunk of PHP code that, with a little luck, will run a
|
||||
# @return [String] A chunk of PHP code that, with a little luck, will run a
|
||||
# command.
|
||||
#
|
||||
def php_system_block(options = {})
|
||||
|
|
|
@ -5,34 +5,108 @@ module Msf
|
|||
class Post
|
||||
module Windows
|
||||
|
||||
|
||||
# @deprecated Use {Services} instead
|
||||
module WindowsServices
|
||||
def self.included(base)
|
||||
include Services
|
||||
end
|
||||
|
||||
def setup
|
||||
print_error("The Windows::WindowsServices mixin is deprecated, use Windows::Services instead")
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Post module mixin for dealing with Windows services
|
||||
#
|
||||
module Services
|
||||
|
||||
include ::Msf::Post::Windows::Registry
|
||||
|
||||
#
|
||||
# List all Windows Services present. Returns an Array containing the names
|
||||
# of the services.
|
||||
# Open the service manager with advapi32.dll!OpenSCManagerA on the
|
||||
# given host or the local machine if :host option is nil. If called
|
||||
# with a block, yields the manager and closes it when the block
|
||||
# returns.
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [String] :host (nil) The host on which to open the
|
||||
# service manager. May be a hostname or IP address.
|
||||
# @option opts [Fixnum] :access (0xF003F) Bitwise-or of the
|
||||
# SC_MANAGER_* constants (see
|
||||
# {http://msdn.microsoft.com/en-us/library/windows/desktop/ms685981(v=vs.85).aspx})
|
||||
#
|
||||
# @return [Fixnum] Opaque Windows handle SC_HANDLE as returned by
|
||||
# OpenSCManagerA()
|
||||
# @yield [manager] Gives the block a manager handle as returned by
|
||||
# advapi32.dll!OpenSCManagerA. When the block returns, the handle
|
||||
# will be closed with {#close_sc_manager}.
|
||||
# @raise [RuntimeError] if OpenSCManagerA returns a NULL handle
|
||||
#
|
||||
def open_sc_manager(opts={})
|
||||
host = opts[:host] || nil
|
||||
access = opts[:access] || 0xF003F
|
||||
machine_str = host ? "\\\\#{host}" : nil
|
||||
|
||||
# SC_HANDLE WINAPI OpenSCManager(
|
||||
# _In_opt_ LPCTSTR lpMachineName,
|
||||
# _In_opt_ LPCTSTR lpDatabaseName,
|
||||
# _In_ DWORD dwDesiredAccess
|
||||
# );
|
||||
manag = session.railgun.advapi32.OpenSCManagerA(machine_str,nil,access)
|
||||
if (manag["return"] == 0)
|
||||
raise RuntimeError.new("Unable to open service manager, GetLastError: #{manag["GetLastError"]}")
|
||||
end
|
||||
|
||||
if (block_given?)
|
||||
begin
|
||||
yield manag["return"]
|
||||
ensure
|
||||
close_sc_manager(manag["return"])
|
||||
end
|
||||
else
|
||||
return manag["return"]
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Call advapi32.dll!CloseServiceHandle on the given handle
|
||||
#
|
||||
def close_sc_manager(handle)
|
||||
if handle
|
||||
session.railgun.advapi32.CloseServiceHandle(handle)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# List all Windows Services present
|
||||
#
|
||||
# @return [Array] The names of the services.
|
||||
#
|
||||
# @todo Rewrite to allow operating on a remote host
|
||||
#
|
||||
def service_list
|
||||
serviceskey = "HKLM\\SYSTEM\\CurrentControlSet\\Services"
|
||||
threadnum = 0
|
||||
a =[]
|
||||
services = []
|
||||
registry_enumkeys(serviceskey).each do |s|
|
||||
if threadnum < 10
|
||||
a.push(::Thread.new(s) { |sk|
|
||||
begin
|
||||
srvtype = registry_getvaldata("#{serviceskey}\\#{sk}","Type").to_s
|
||||
if srvtype =~ /32|16/
|
||||
services << sk
|
||||
end
|
||||
rescue
|
||||
end
|
||||
})
|
||||
threadnum += 1
|
||||
else
|
||||
sleep(0.05) and a.delete_if {|x| not x.alive?} while not a.empty?
|
||||
threadnum = 0
|
||||
keys = registry_enumkeys(serviceskey)
|
||||
keys.each do |s|
|
||||
if a.length >= 10
|
||||
a.first.join
|
||||
a.delete_if {|x| not x.alive?}
|
||||
end
|
||||
t = framework.threads.spawn(self.refname+"-ServiceRegistryList",false,s) { |sk|
|
||||
begin
|
||||
srvtype = registry_getvaldata("#{serviceskey}\\#{sk}","Type").to_s
|
||||
if srvtype == "32" or srvtype == "16"
|
||||
services << sk
|
||||
end
|
||||
rescue
|
||||
end
|
||||
}
|
||||
a.push(t)
|
||||
end
|
||||
|
||||
return services
|
||||
|
@ -45,6 +119,13 @@ module WindowsServices
|
|||
# command executed by the service. Service name is case sensitive. Hash
|
||||
# keys are Name, Start, Command and Credentials.
|
||||
#
|
||||
# @param name [String] The target service's name (not to be confused
|
||||
# with Display Name). Case sensitive.
|
||||
#
|
||||
# @return [Hash]
|
||||
#
|
||||
# @todo Rewrite to allow operating on a remote host
|
||||
#
|
||||
def service_info(name)
|
||||
service = {}
|
||||
servicekey = "HKLM\\SYSTEM\\CurrentControlSet\\Services\\#{name.chomp}"
|
||||
|
@ -68,6 +149,8 @@ module WindowsServices
|
|||
# Mode is a string with either auto, manual or disable for the
|
||||
# corresponding setting. The name of the service is case sensitive.
|
||||
#
|
||||
# @todo Rewrite to allow operating on a remote host
|
||||
#
|
||||
def service_change_startup(name,mode)
|
||||
servicekey = "HKLM\\SYSTEM\\CurrentControlSet\\Services\\#{name.chomp}"
|
||||
case mode.downcase
|
||||
|
@ -81,22 +164,30 @@ module WindowsServices
|
|||
end
|
||||
|
||||
#
|
||||
# Create a service that runs it's own process.
|
||||
# Create a service that runs +executable_on_host+ on the session host
|
||||
#
|
||||
# It takes as values the service name as string, the display name as
|
||||
# string, the path of the executable on the host that will execute at
|
||||
# startup as string and the startup type as an integer of 2 for Auto, 3 for
|
||||
# Manual or 4 for Disable, default Auto.
|
||||
# @param name [String] Name of the service to be used as the key
|
||||
# @param display_name [String] Name of the service as displayed by mmc
|
||||
# @param executable_on_host [String] EXE on the remote filesystem to
|
||||
# be used as the service executable
|
||||
# @param startup [Fixnum] Constant used by CreateServiceA for startup
|
||||
# type: 2 for Auto, 3 for Manual, 4 for Disable. Default is Auto
|
||||
# @param server [String,nil] A hostname or IP address. Default is the
|
||||
# remote localhost
|
||||
#
|
||||
# @return [true,false] True if there were no errors, false otherwise
|
||||
#
|
||||
def service_create(name, display_name, executable_on_host, startup=2, server=nil)
|
||||
machine_str = server ? "\\\\#{server}" : nil
|
||||
adv = session.railgun.advapi32
|
||||
manag = adv.OpenSCManagerA(machine_str,nil,0x13)
|
||||
if(manag["return"] != 0)
|
||||
|
||||
# SC_MANAGER_CONNECT 0x01
|
||||
# SC_MANAGER_CREATE_SERVICE 0x02
|
||||
# SC_MANAGER_QUERY_LOCK_STATUS 0x10
|
||||
open_sc_manager(:host=>server, :access=>0x13) do |manager|
|
||||
# SC_HANDLE WINAPI CreateService(
|
||||
# __in SC_HANDLE hSCManager,
|
||||
# __in LPCTSTR lpServiceName,
|
||||
# __in_opt LPCTSTR lpDisplayName,
|
||||
# __in_opt LPCTSTR lpDisplayName,
|
||||
# __in DWORD dwDesiredAccess,
|
||||
# __in DWORD dwServiceType,
|
||||
# __in DWORD dwStartType,
|
||||
|
@ -108,113 +199,112 @@ module WindowsServices
|
|||
# __in_opt LPCTSTR lpServiceStartName,
|
||||
# __in_opt LPCTSTR lpPassword
|
||||
#);
|
||||
# SC_MANAGER_CREATE_SERVICE = 0x0002
|
||||
newservice = adv.CreateServiceA(manag["return"],name,display_name,
|
||||
0x0010,0X00000010,startup,0,executable_on_host,nil,nil,nil,nil,nil)
|
||||
newservice = adv.CreateServiceA(manager, name, display_name,
|
||||
0x0010, 0X00000010, startup, 0, executable_on_host,
|
||||
nil, nil, nil, nil, nil)
|
||||
adv.CloseServiceHandle(newservice["return"])
|
||||
adv.CloseServiceHandle(manag["return"])
|
||||
#SERVICE_START=0x0010 SERVICE_WIN32_OWN_PROCESS= 0X00000010
|
||||
#SERVICE_AUTO_START = 2 SERVICE_ERROR_IGNORE = 0
|
||||
if newservice["GetLastError"] == 0
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
else
|
||||
raise "Could not open Service Control Manager, Access Denied"
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Start a service.
|
||||
#
|
||||
# Returns 0 if service started, 1 if service is already started and 2 if
|
||||
# service is disabled.
|
||||
# @param name [String] Service name (not display name)
|
||||
# @param server [String,nil] A hostname or IP address. Default is the
|
||||
# remote localhost
|
||||
#
|
||||
# @return [Fixnum] 0 if service started successfully, 1 if it failed
|
||||
# because the service is already running, 2 if it is disabled
|
||||
#
|
||||
# @raise [RuntimeError] if OpenServiceA failed
|
||||
#
|
||||
def service_start(name, server=nil)
|
||||
machine_str = server ? "\\\\#{server}" : nil
|
||||
adv = session.railgun.advapi32
|
||||
manag = adv.OpenSCManagerA(machine_str,nil,1)
|
||||
if(manag["return"] == 0)
|
||||
raise "Could not open Service Control Manager, Access Denied"
|
||||
end
|
||||
#open with SERVICE_START (0x0010)
|
||||
servhandleret = adv.OpenServiceA(manag["return"],name,0x10)
|
||||
if(servhandleret["return"] == 0)
|
||||
adv.CloseServiceHandle(manag["return"])
|
||||
raise "Could not Open Service, Access Denied"
|
||||
end
|
||||
retval = adv.StartServiceA(servhandleret["return"],0,nil)
|
||||
adv.CloseServiceHandle(servhandleret["return"])
|
||||
adv.CloseServiceHandle(manag["return"])
|
||||
if retval["GetLastError"] == 0
|
||||
return 0
|
||||
elsif retval["GetLastError"] == 1056
|
||||
return 1
|
||||
elsif retval["GetLastError"] == 1058
|
||||
return 2
|
||||
open_sc_manager(:host=>server, :access=>1) do |manager|
|
||||
# SC_HANDLE WINAPI OpenService(
|
||||
# _In_ SC_HANDLE hSCManager,
|
||||
# _In_ LPCTSTR lpServiceName,
|
||||
# _In_ DWORD dwDesiredAccess
|
||||
# );
|
||||
# open with access SERVICE_START (0x0010)
|
||||
handle = adv.OpenServiceA(manager, name, 0x10)
|
||||
if(handle["return"] == 0)
|
||||
raise RuntimeError.new("Could not open service. OpenServiceA error: #{handle["GetLastError"]}")
|
||||
end
|
||||
retval = adv.StartServiceA(handle["return"],0,nil)
|
||||
adv.CloseServiceHandle(handle["return"])
|
||||
|
||||
# This is terrible. Magic return values should be refactored to
|
||||
# something meaningful.
|
||||
case retval["GetLastError"]
|
||||
when 0; return 0 # everything worked
|
||||
when 1056; return 1 # service already started
|
||||
when 1058; return 2 # service disabled
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Stop a service.
|
||||
#
|
||||
# Returns 0 if service is stopped successfully, 1 if service is already
|
||||
# stopped or disabled and 2 if the service can not be stopped.
|
||||
# @param (see #service_start)
|
||||
# @return [Fixnum] 0 if service stopped successfully, 1 if it failed
|
||||
# because the service is already stopped or disabled, 2 if it
|
||||
# cannot be stopped for some other reason.
|
||||
#
|
||||
# @raise (see #service_start)
|
||||
#
|
||||
def service_stop(name, server=nil)
|
||||
machine_str = server ? "\\\\#{server}" : nil
|
||||
adv = session.railgun.advapi32
|
||||
manag = adv.OpenSCManagerA(machine_str,nil,1)
|
||||
if(manag["return"] == 0)
|
||||
raise "Could not open Service Control Manager, Access Denied"
|
||||
end
|
||||
#open with SERVICE_STOP (0x0020)
|
||||
servhandleret = adv.OpenServiceA(manag["return"],name,0x30)
|
||||
if(servhandleret["return"] == 0)
|
||||
adv.CloseServiceHandle(manag["return"])
|
||||
raise "Could not Open Service, Access Denied"
|
||||
end
|
||||
retval = adv.ControlService(servhandleret["return"],1,56)
|
||||
adv.CloseServiceHandle(servhandleret["return"])
|
||||
adv.CloseServiceHandle(manag["return"])
|
||||
if retval["GetLastError"] == 0
|
||||
return 0
|
||||
elsif retval["GetLastError"] == 1062
|
||||
return 1
|
||||
elsif retval["GetLastError"] == 1052
|
||||
return 2
|
||||
|
||||
# SC_MANAGER_SERVICE_STOP (0x0020)
|
||||
open_sc_manager(:host=>server, :access=>1) do |manager|
|
||||
# open with SERVICE_STOP (0x0020)
|
||||
handle = adv.OpenServiceA(manager, name, 0x20)
|
||||
if(handle["return"] == 0)
|
||||
raise RuntimeError.new("Could not open service. OpenServiceA error: #{handle["GetLastError"]}")
|
||||
end
|
||||
retval = adv.ControlService(handle["return"],1,56)
|
||||
adv.CloseServiceHandle(handle["return"])
|
||||
|
||||
case retval["GetLastError"]
|
||||
when 0; return 0 # worked
|
||||
when 1062; return 1 # already stopped or disabled
|
||||
when 1052; return 2 # cannot be stopped
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Delete a service.
|
||||
#
|
||||
# @param (see #service_start)
|
||||
#
|
||||
def service_delete(name, server=nil)
|
||||
machine_str = server ? "\\\\#{server}" : nil
|
||||
adv = session.railgun.advapi32
|
||||
|
||||
# #define SC_MANAGER_ALL_ACCESS 0xF003F
|
||||
manag = adv.OpenSCManagerA(machine_str,nil,0xF003F)
|
||||
if (manag["return"] == 0)
|
||||
raise "Could not open Service Control Manager, Access Denied"
|
||||
open_sc_manager(:host=>server) do |manager|
|
||||
# Now to grab a handle to the service.
|
||||
# Thank you, Wine project for defining the DELETE constant since it,
|
||||
# and all its friends, are missing from the MSDN docs.
|
||||
# #define DELETE 0x00010000
|
||||
handle = adv.OpenServiceA(manager, name, 0x10000)
|
||||
if (handle["return"] == 0)
|
||||
raise RuntimeError.new("Could not open service. OpenServiceA error: #{handle["GetLastError"]}")
|
||||
end
|
||||
|
||||
# Lastly, delete it
|
||||
adv.DeleteService(handle["return"])
|
||||
|
||||
adv.CloseServiceHandle(handle["return"])
|
||||
|
||||
handle["GetLastError"]
|
||||
end
|
||||
|
||||
# Now to grab a handle to the service.
|
||||
# Thank you, Wine project for defining the DELETE constant since it,
|
||||
# and all its friends, are missing from the MSDN docs.
|
||||
# #define DELETE 0x00010000
|
||||
servhandleret = adv.OpenServiceA(manag["return"],name,0x10000)
|
||||
if (servhandleret["return"] == 0)
|
||||
adv.CloseServiceHandle(manag["return"])
|
||||
raise "Could not Open Service, Access Denied"
|
||||
end
|
||||
|
||||
# Lastly, delete it
|
||||
adv.DeleteService(servhandleret["return"])
|
||||
|
||||
adv.CloseServiceHandle(manag["return"])
|
||||
adv.CloseServiceHandle(servhandleret["return"])
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ module Windows
|
|||
# http://pauldotcom.com/2011/11/safely-dumping-hashes-from-liv.html
|
||||
module ShadowCopy
|
||||
|
||||
include Msf::Post::Windows::WindowsServices
|
||||
include Msf::Post::Windows::Services
|
||||
|
||||
#
|
||||
# Get the device name for the shadow copy, which is used when accessing
|
||||
|
|
|
@ -6,7 +6,7 @@ module Scripts
|
|||
module Meterpreter
|
||||
module Common
|
||||
|
||||
include ::Msf::Post::Windows::WindowsServices
|
||||
include ::Msf::Post::Windows::Services
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -20,7 +20,7 @@ class Metasploit3 < Msf::Exploit::Local
|
|||
Rank = ExcellentRanking
|
||||
|
||||
include Post::Common
|
||||
include Post::Windows::WindowsServices
|
||||
include Post::Windows::Services
|
||||
include Exploit::EXE
|
||||
include Post::File
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ require 'rex'
|
|||
class Metasploit3 < Msf::Exploit::Local
|
||||
Rank = GreatRanking
|
||||
|
||||
include Msf::Post::Windows::WindowsServices
|
||||
include Msf::Post::Windows::Services
|
||||
|
||||
def initialize(info={})
|
||||
super( update_info( info,
|
||||
|
|
|
@ -17,7 +17,7 @@ class Metasploit3 < Msf::Exploit::Local
|
|||
include Msf::Exploit::EXE
|
||||
include Msf::Post::Common
|
||||
include Msf::Post::File
|
||||
include Post::Windows::WindowsServices
|
||||
include Post::Windows::Services
|
||||
|
||||
def initialize(info={})
|
||||
super( update_info( info,
|
||||
|
|
|
@ -15,7 +15,7 @@ require 'rex'
|
|||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::Windows::WindowsServices
|
||||
include Msf::Post::Windows::Services
|
||||
|
||||
def initialize(info={})
|
||||
super( update_info( info,
|
||||
|
|
|
@ -16,7 +16,7 @@ require 'msf/core//post/windows/services'
|
|||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include ::Msf::Post::Windows::WindowsServices
|
||||
include ::Msf::Post::Windows::Services
|
||||
def initialize(info={})
|
||||
super( update_info( info,
|
||||
'Name' => 'Windows Escalate Service Permissions Local Privilege Escalation',
|
||||
|
|
|
@ -14,7 +14,7 @@ require 'msf/core/post/windows/services'
|
|||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Post::Windows::WindowsServices
|
||||
include Post::Windows::Services
|
||||
|
||||
def initialize
|
||||
super(
|
||||
|
|
|
@ -16,7 +16,7 @@ require 'msf/core/post/windows/services'
|
|||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::Windows::WindowsServices
|
||||
include Msf::Post::Windows::Services
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
|
|
|
@ -21,7 +21,7 @@ class Metasploit3 < Msf::Post
|
|||
|
||||
include Msf::Post::Windows::Accounts
|
||||
include Msf::Post::Windows::Registry
|
||||
include Msf::Post::Windows::WindowsServices
|
||||
include Msf::Post::Windows::Services
|
||||
include Msf::Post::Windows::Priv
|
||||
include Msf::Post::Common
|
||||
include Msf::Post::File
|
||||
|
|
|
@ -23,7 +23,7 @@ class Metasploit3 < Msf::Post
|
|||
include Msf::Post::File
|
||||
include Msf::Post::Windows::Priv
|
||||
include Msf::Post::Windows::Registry
|
||||
include Msf::Post::Windows::WindowsServices
|
||||
include Msf::Post::Windows::Services
|
||||
|
||||
def initialize(info={})
|
||||
super( update_info( info,
|
||||
|
|
|
@ -1,114 +1,183 @@
|
|||
#
|
||||
# by kernelsmith (kernelsmith+\x40+kernelsmith+\.com)
|
||||
#
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex'
|
||||
require 'msf/core/post/windows/services'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::Windows::WindowsServices
|
||||
|
||||
def initialize(info={})
|
||||
super( update_info( info,
|
||||
'Name' => 'services_post_testing',
|
||||
'Description' => %q{ This module will test windows services methods within a shell},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [ 'kernelsmith'],
|
||||
'Version' => '$Revision: 11663 $',
|
||||
'Platform' => [ 'windows' ],
|
||||
'SessionTypes' => [ 'shell' ]
|
||||
))
|
||||
register_options(
|
||||
[
|
||||
OptBool.new("VERBOSE" , [true, "Verbose test, shows service status after each test", false]),
|
||||
OptString.new("QSERVICE" , [true, "Service (keyname) to query", "winmgmt"]),
|
||||
OptString.new("NSERVICE" , [true, "New Service (keyname) to create/del", "testes"]),
|
||||
OptString.new("SSERVICE" , [true, "Service (keyname) to start/stop", "W32Time"]),
|
||||
OptString.new("MODE" , [true, "Mode to use for startup/create tests", "demand"]),
|
||||
OptString.new("DNAME" , [true, "Display name used for create test", "Cool display name"]),
|
||||
OptString.new("BINPATH" , [true, "Binary path for create test", "C:\\WINDOWS\\system32\\svchost.exe -k netsvcs"]),
|
||||
], self.class)
|
||||
|
||||
end
|
||||
|
||||
def run
|
||||
|
||||
blab = datastore['VERBOSE']
|
||||
print_status("Running against session #{datastore["SESSION"]}")
|
||||
print_status("Session type is #{session.type}")
|
||||
print_status("Verbosity is set to #{blab.to_s}")
|
||||
print_status("Don't be surprised to see some errors as the script is faster")
|
||||
print_line("than the windows SCM, just make sure the errors are sane. You can")
|
||||
print_line("set VERBOSE to true to see more details")
|
||||
|
||||
print_status()
|
||||
print_status("TESTING service_list")
|
||||
results = service_list
|
||||
print_status("RESULTS: #{results.class} #{results.pretty_inspect}")
|
||||
|
||||
print_status()
|
||||
print_status("TESTING service_list_running")
|
||||
results = service_list_running
|
||||
print_status("RESULTS: #{results.class} #{results.pretty_inspect}")
|
||||
|
||||
print_status()
|
||||
print_status("TESTING service_info on servicename: #{datastore["QSERVICE"]}")
|
||||
results = service_info(datastore['QSERVICE'])
|
||||
print_status("RESULTS: #{results.class} #{results.pretty_inspect}")
|
||||
|
||||
print_status()
|
||||
print_status("TESTING service_query_ex on servicename: #{datastore["QSERVICE"]}")
|
||||
results = service_query_ex(datastore['QSERVICE'])
|
||||
print_status("RESULTS: #{results.class} #{results.pretty_inspect}")
|
||||
|
||||
print_status()
|
||||
print_status("TESTING service_query_config on servicename: #{datastore["QSERVICE"]}")
|
||||
results = service_query_config(datastore['QSERVICE'])
|
||||
print_status("RESULTS: #{results.class} #{results.pretty_inspect}")
|
||||
|
||||
print_status()
|
||||
print_status("TESTING service_change_startup on servicename: #{datastore['QSERVICE']} " +
|
||||
"to #{datastore['MODE']}")
|
||||
results = service_change_startup(datastore['QSERVICE'],datastore['MODE'])
|
||||
print_status("RESULTS: #{results.class} #{results.pretty_inspect}")
|
||||
print_status("Current status of this service " +
|
||||
"#{service_query_ex(datastore['QSERVICE']).pretty_inspect}") if blab
|
||||
|
||||
print_status()
|
||||
print_status("TESTING service_create on servicename: #{datastore['NSERVICE']} using\n" +
|
||||
"display_name: #{datastore['DNAME']}, executable_on_host: " +
|
||||
"#{datastore['BINPATH']}, and startupmode: #{datastore['MODE']}")
|
||||
results = service_create(datastore['NSERVICE'],datastore['DNAME'],datastore['BINPATH'],datastore['MODE'])
|
||||
print_status("RESULTS: #{results.class} #{results.pretty_inspect}")
|
||||
print_status("Current status of this service " +
|
||||
"#{service_query_ex(datastore['QSERVICE']).pretty_inspect}") if blab
|
||||
|
||||
print_status()
|
||||
print_status("TESTING service_start on servicename: #{datastore['SSERVICE']}")
|
||||
results = service_start(datastore['SSERVICE'])
|
||||
print_status("RESULTS: #{results.class} #{results.pretty_inspect}")
|
||||
print_status("Current status of this service " +
|
||||
"#{service_query_ex(datastore['SSERVICE']).pretty_inspect}") if blab
|
||||
print_status("Sleeping to give the service a chance to start")
|
||||
select(nil, nil, nil, 2) # give the service time to start, reduces false negatives
|
||||
|
||||
print_status()
|
||||
print_status("TESTING service_stop on servicename: #{datastore['SSERVICE']}")
|
||||
results = service_stop(datastore['SSERVICE'])
|
||||
print_status("RESULTS: #{results.class} #{results.pretty_inspect}")
|
||||
print_status("Current status of this service " +
|
||||
"#{service_query_ex(datastore['SSERVICE']).pretty_inspect}") if blab
|
||||
|
||||
print_status()
|
||||
print_status("TESTING service_delete on servicename: #{datastore['NSERVICE']}")
|
||||
results = service_delete(datastore['NSERVICE'])
|
||||
print_status("RESULTS: #{results.class} #{results.pretty_inspect}")
|
||||
print_status("Current status of this service " +
|
||||
"#{service_query_ex(datastore['QSERVICE']).pretty_inspect}") if blab
|
||||
print_status()
|
||||
print_status("Testing complete.")
|
||||
end
|
||||
|
||||
end
|
||||
#
|
||||
# by kernelsmith (kernelsmith+\x40+kernelsmith+\.com)
|
||||
#
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex'
|
||||
require 'msf/core/post/windows/services'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::Windows::Services
|
||||
|
||||
include Msf::ModuleTest::PostTest
|
||||
|
||||
def initialize(info={})
|
||||
super( update_info( info,
|
||||
'Name' => 'Test Post::Windows::Services',
|
||||
'Description' => %q{ This module will test windows services methods within a shell},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [ 'kernelsmith', 'egypt' ],
|
||||
'Version' => '$Revision: 11663 $',
|
||||
'Platform' => [ 'windows' ],
|
||||
'SessionTypes' => [ 'meterpreter', 'shell' ]
|
||||
))
|
||||
register_options(
|
||||
[
|
||||
OptString.new("QSERVICE" , [true, "Service (keyname) to query", "winmgmt"]),
|
||||
OptString.new("NSERVICE" , [true, "New Service (keyname) to create/del", "testes"]),
|
||||
OptString.new("SSERVICE" , [true, "Service (keyname) to start/stop", "W32Time"]),
|
||||
OptString.new("DNAME" , [true, "Display name used for create test", "Cool display name"]),
|
||||
OptString.new("BINPATH" , [true, "Binary path for create test", "C:\\WINDOWS\\system32\\svchost.exe -k netsvcs"]),
|
||||
OptEnum.new("MODE", [true, "Mode to use for startup/create tests", "auto",
|
||||
["auto", "manual", "disable"]
|
||||
]),
|
||||
], self.class)
|
||||
|
||||
end
|
||||
|
||||
def test_start
|
||||
it "should start #{datastore["SSERVICE"]}" do
|
||||
ret = true
|
||||
results = service_start(datastore['SSERVICE'])
|
||||
if results != 0
|
||||
# Failed the first time, try to stop it first, then try again
|
||||
service_stop(datastore['SSERVICE'])
|
||||
results = service_start(datastore['SSERVICE'])
|
||||
end
|
||||
ret &&= (results == 0)
|
||||
|
||||
ret
|
||||
end
|
||||
it "should stop #{datastore["SSERVICE"]}" do
|
||||
ret = true
|
||||
results = service_stop(datastore['SSERVICE'])
|
||||
ret &&= (results == 0)
|
||||
|
||||
ret
|
||||
end
|
||||
end
|
||||
|
||||
def test_list
|
||||
it "should list services" do
|
||||
ret = true
|
||||
results = service_list
|
||||
|
||||
ret &&= results.kind_of? Array
|
||||
ret &&= results.length > 0
|
||||
ret &&= results.include? datastore["QSERVICE"]
|
||||
|
||||
ret
|
||||
end
|
||||
end
|
||||
|
||||
def test_info
|
||||
it "should return info on a given service" do
|
||||
ret = true
|
||||
results = service_info(datastore['QSERVICE'])
|
||||
|
||||
ret &&= results.kind_of? Hash
|
||||
if ret
|
||||
ret &&= results.has_key? "Name"
|
||||
ret &&= (results["Name"] == "Windows Management Instrumentation")
|
||||
ret &&= results.has_key? "Startup"
|
||||
ret &&= results.has_key? "Command"
|
||||
ret &&= results.has_key? "Credentials"
|
||||
end
|
||||
|
||||
ret
|
||||
end
|
||||
end
|
||||
|
||||
def test_create
|
||||
it "should create a service" do
|
||||
mode = case datastore["MODE"]
|
||||
when "disable"; 4
|
||||
when "manual"; 3
|
||||
when "auto"; 2
|
||||
else; 2
|
||||
end
|
||||
ret = service_create(datastore['NSERVICE'],datastore['DNAME'],datastore['BINPATH'],mode)
|
||||
|
||||
ret
|
||||
end
|
||||
|
||||
it "should return info on the newly-created service" do
|
||||
ret = true
|
||||
results = service_info(datastore['NSERVICE'])
|
||||
|
||||
ret &&= results.kind_of? Hash
|
||||
ret &&= results.has_key? "Name"
|
||||
ret &&= (results["Name"] == datastore["DNAME"])
|
||||
ret &&= results.has_key? "Startup"
|
||||
ret &&= (results["Startup"].downcase == datastore["MODE"])
|
||||
ret &&= results.has_key? "Command"
|
||||
ret &&= results.has_key? "Credentials"
|
||||
|
||||
ret
|
||||
end
|
||||
|
||||
it "should delete the new service" do
|
||||
ret = service_delete(datastore['NSERVICE'])
|
||||
|
||||
ret
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
=begin
|
||||
def run
|
||||
blab = datastore['VERBOSE']
|
||||
print_status("Running against session #{datastore["SESSION"]}")
|
||||
print_status("Session type is #{session.type}")
|
||||
print_status("Verbosity is set to #{blab.to_s}")
|
||||
print_status("Don't be surprised to see some errors as the script is faster")
|
||||
print_line("than the windows SCM, just make sure the errors are sane. You can")
|
||||
print_line("set VERBOSE to true to see more details")
|
||||
|
||||
print_status()
|
||||
print_status("TESTING service_query_ex on servicename: #{datastore["QSERVICE"]}")
|
||||
results = service_query_ex(datastore['QSERVICE'])
|
||||
print_status("RESULTS: #{results.class} #{results.pretty_inspect}")
|
||||
|
||||
print_status()
|
||||
print_status("TESTING service_query_config on servicename: #{datastore["QSERVICE"]}")
|
||||
results = service_query_config(datastore['QSERVICE'])
|
||||
print_status("RESULTS: #{results.class} #{results.pretty_inspect}")
|
||||
|
||||
print_status()
|
||||
print_status("TESTING service_change_startup on servicename: #{datastore['QSERVICE']} " +
|
||||
"to #{datastore['MODE']}")
|
||||
results = service_change_startup(datastore['QSERVICE'],datastore['MODE'])
|
||||
print_status("RESULTS: #{results.class} #{results.pretty_inspect}")
|
||||
print_status("Current status of this service " +
|
||||
"#{service_query_ex(datastore['QSERVICE']).pretty_inspect}") if blab
|
||||
|
||||
print_status()
|
||||
print_status("TESTING service_start on servicename: #{datastore['SSERVICE']}")
|
||||
results = service_start(datastore['SSERVICE'])
|
||||
print_status("RESULTS: #{results.class} #{results.pretty_inspect}")
|
||||
print_status("Current status of this service " +
|
||||
"#{service_query_ex(datastore['SSERVICE']).pretty_inspect}") if blab
|
||||
print_status("Sleeping to give the service a chance to start")
|
||||
select(nil, nil, nil, 2) # give the service time to start, reduces false negatives
|
||||
|
||||
print_status()
|
||||
print_status("TESTING service_stop on servicename: #{datastore['SSERVICE']}")
|
||||
results = service_stop(datastore['SSERVICE'])
|
||||
print_status("RESULTS: #{results.class} #{results.pretty_inspect}")
|
||||
print_status("Current status of this service " +
|
||||
"#{service_query_ex(datastore['SSERVICE']).pretty_inspect}") if blab
|
||||
|
||||
print_status()
|
||||
print_status("TESTING service_delete on servicename: #{datastore['NSERVICE']}")
|
||||
results = service_delete(datastore['NSERVICE'])
|
||||
print_status("RESULTS: #{results.class} #{results.pretty_inspect}")
|
||||
print_status("Current status of this service " +
|
||||
"#{service_query_ex(datastore['QSERVICE']).pretty_inspect}") if blab
|
||||
print_status()
|
||||
print_status("Testing complete.")
|
||||
end
|
||||
=end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue