Files
metasploit-gs/modules/post/windows/gather/enum_services.rb
T

127 lines
4.2 KiB
Ruby
Raw Normal View History

2011-07-30 15:11:52 +00:00
##
2017-07-24 06:26:21 -07:00
# This module requires Metasploit: https://metasploit.com/download
2013-10-15 13:50:46 -05:00
# Current source: https://github.com/rapid7/metasploit-framework
2011-07-30 15:11:52 +00:00
##
2016-03-08 14:02:44 +01:00
class MetasploitModule < Msf::Post
2013-08-30 16:28:54 -05:00
include Msf::Post::Windows::Services
2011-07-30 15:11:52 +00:00
2013-08-30 16:28:54 -05:00
def initialize(info={})
super(update_info(info,
'Name' => "Windows Gather Service Info Enumeration",
'Description' => %q{
2014-02-18 18:24:23 -06:00
This module will query the system for services and display name and
configuration info for each returned service. It allows you to
optionally search the credentials, path, or start type for a string
and only return the results that match. These query operations are
cumulative and if no query strings are specified, it just returns all
services. NOTE: If the script hangs, windows firewall is most likely
on and you did not migrate to a safe process (explorer.exe for
example).
2013-08-30 16:28:54 -05:00
},
'License' => MSF_LICENSE,
'Platform' => ['win'],
'SessionTypes' => ['meterpreter'],
'Author' => ['Keith Faber', 'Kx499']
))
register_options(
[
OptString.new('CRED', [ false, 'String to search credentials for' ]),
OptString.new('PATH', [ false, 'String to search path for' ]),
2014-07-04 20:37:09 +01:00
OptEnum.new('TYPE', [true, 'Service startup Option', 'All', ['All', 'Auto', 'Manual', 'Disabled' ]])
])
2013-08-30 16:28:54 -05:00
end
2011-07-30 15:11:52 +00:00
2013-08-30 16:28:54 -05:00
def run
2011-07-30 15:11:52 +00:00
2013-08-30 16:28:54 -05:00
# set vars
credentialCount = {}
2013-08-30 16:28:54 -05:00
qcred = datastore["CRED"] || nil
qpath = datastore["PATH"] || nil
2014-07-04 20:37:09 +01:00
2013-08-30 16:28:54 -05:00
if datastore["TYPE"] == "All"
qtype = nil
else
2014-07-04 20:37:09 +01:00
qtype = datastore["TYPE"].downcase
2013-08-30 16:28:54 -05:00
end
2014-02-18 18:24:23 -06:00
2013-08-30 16:28:54 -05:00
if qcred
2014-02-18 18:24:23 -06:00
qcred = qcred.downcase
print_status("Credential Filter: #{qcred}")
2013-08-30 16:28:54 -05:00
end
2014-02-18 18:24:23 -06:00
2013-08-30 16:28:54 -05:00
if qpath
2014-02-18 18:24:23 -06:00
qpath = qpath.downcase
print_status("Executable Path Filter: #{qpath}")
2013-08-30 16:28:54 -05:00
end
2014-02-18 18:24:23 -06:00
2013-08-30 16:28:54 -05:00
if qtype
print_status("Start Type Filter: #{qtype}")
2013-08-30 16:28:54 -05:00
end
2016-08-10 13:30:09 -05:00
results_table = Rex::Text::Table.new(
'Header' => 'Services',
'Indent' => 1,
'SortIndex' => 0,
'Columns' => ['Name', 'Credentials', 'Command', 'Startup']
)
2014-07-04 20:46:50 +01:00
print_status("Listing Service Info for matching services, please wait...")
service_list.each do |srv|
2013-08-30 16:28:54 -05:00
srv_conf = {}
2014-02-18 18:24:23 -06:00
# make sure we got a service name
if srv[:name]
2013-08-30 16:28:54 -05:00
begin
srv_conf = service_info(srv[:name])
2013-12-18 11:15:52 +00:00
if srv_conf[:startname]
2014-02-18 18:24:23 -06:00
# filter service based on filters passed, the are cumulative
if qcred && !srv_conf[:startname].downcase.include?(qcred)
2013-12-18 11:15:52 +00:00
next
end
2014-02-18 18:24:23 -06:00
if qpath && !srv_conf[:path].downcase.include?(qpath)
2013-12-18 11:15:52 +00:00
next
end
# There may not be a 'Startup', need to check nil
2014-02-18 18:24:23 -06:00
if qtype && !(START_TYPE[srv_conf[:starttype]] || '').downcase.include?(qtype)
2013-12-18 11:15:52 +00:00
next
end
2014-07-04 20:37:09 +01:00
# count the occurance of specific credentials services are running as
2014-07-04 20:46:50 +01:00
serviceCred = srv_conf[:startname].upcase
2014-07-04 20:37:09 +01:00
unless serviceCred.empty?
if credentialCount.has_key?(serviceCred)
credentialCount[serviceCred] += 1
else
credentialCount[serviceCred] = 1
# let the user know a new service account has been detected for possible lateral
# movement opportunities
2014-07-04 20:46:50 +01:00
print_good("New service credential detected: #{srv[:name]} is running as '#{srv_conf[:startname]}'")
2014-07-04 20:37:09 +01:00
end
end
2013-12-18 11:15:52 +00:00
results_table << [srv[:name],
srv_conf[:startname],
START_TYPE[srv_conf[:starttype]],
srv_conf[:path]]
2013-08-30 16:28:54 -05:00
end
2013-12-15 18:43:55 +00:00
rescue RuntimeError => e
2014-02-18 18:24:23 -06:00
print_error("An error occurred enumerating service: #{srv[:name]}: #{e}")
2013-08-30 16:28:54 -05:00
end
else
2014-07-04 20:46:50 +01:00
print_error("Problem enumerating service - no service name found")
2013-08-30 16:28:54 -05:00
end
end
print_line results_table.to_s
2014-07-04 20:37:09 +01:00
# store loot on completion of collection
p = store_loot("windows.services", "text/plain", session, results_table.to_s, "windows_services.txt", "Windows Services")
print_good("Loot file stored in: #{p.to_s}")
2013-08-30 16:28:54 -05:00
end
2011-07-30 15:11:52 +00:00
end