Skip to content

Commit f1b7a9f

Browse files
committed
Land rapid7#3488 - loot storage into the enum_services post module
2 parents 79c433e + bb54fec commit f1b7a9f

File tree

1 file changed

+47
-16
lines changed

1 file changed

+47
-16
lines changed

modules/post/windows/gather/enum_services.rb

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ def initialize(info={})
1616
'Name' => "Windows Gather Service Info Enumeration",
1717
'Description' => %q{
1818
This module will query the system for services and display name and configuration
19-
info for each returned service. It allows you to optionally search the credentials, path, or start
20-
type for a string and only return the results that match. These query operations
19+
info for each returned service. It allows you to optionally search the credentials, path,
20+
or start type for a string and only return the results that match. These query operations
2121
are cumulative and if no query strings are specified, it just returns all services.
2222
NOTE: If the script hangs, windows firewall is most likely on and you did not
2323
migrate to a safe process (explorer.exe for example).
@@ -36,9 +36,12 @@ def initialize(info={})
3636
end
3737

3838

39+
3940
def run
4041

4142
# set vars
43+
lootString = ""
44+
credentialCount = {}
4245
qcred = datastore["CRED"] || nil
4346
qpath = datastore["PATH"] || nil
4447
if datastore["TYPE"] == "All"
@@ -47,24 +50,29 @@ def run
4750
qtype = datastore["TYPE"]
4851
end
4952
if qcred
50-
print_status("Credential Filter: " + qcred)
53+
print_status("Credential Filter: #{qcred}")
5154
end
5255
if qpath
53-
print_status("Executable Path Filter: " + qpath)
56+
print_status("Executable Path Filter: #{qpath}")
5457
end
5558
if qtype
56-
print_status("Start Type Filter: " + qtype)
59+
print_status("Start Type Filter: #{qtype}")
60+
end
61+
62+
if datastore['VERBOSE']
63+
print_status("Listing Service Info for matching services:")
64+
else
65+
print_status("Detailed output is only printed when VERBOSE is set to True. Running this module can take some time.\n")
5766
end
5867

59-
print_status("Listing Service Info for matching services:")
6068
service_list.each do |sname|
6169
srv_conf = {}
6270
isgood = true
63-
#make sure we got a service name
71+
# make sure we got a service name
6472
if sname
6573
begin
6674
srv_conf = service_info(sname)
67-
#filter service based on filters passed, the are cumulative
75+
# filter service based on filters passed, the are cumulative
6876
if qcred and ! srv_conf['Credentials'].downcase.include? qcred.downcase
6977
isgood = false
7078
end
@@ -75,22 +83,45 @@ def run
7583
if qtype and ! (srv_conf['Startup'] || '').downcase.include? qtype.downcase
7684
isgood = false
7785
end
86+
# count the occurance of specific credentials services are running as
87+
serviceCred = srv_conf['Credentials'].upcase
88+
unless serviceCred.empty?
89+
if credentialCount.has_key?(serviceCred)
90+
credentialCount[serviceCred] += 1
91+
else
92+
credentialCount[serviceCred] = 1
93+
# let the user know a new service account has been detected for possible lateral
94+
# movement opportunities
95+
print_good("New service credential detected: #{sname} is running as '#{srv_conf['Credentials']}'")
96+
end
97+
end
7898

79-
#if we are still good return the info
99+
# if we are still good return the info
80100
if isgood
81-
vprint_status("\tName: #{sname}")
82-
vprint_good("\t\tStartup: #{srv_conf['Startup']}")
83-
vprint_good("\t\tCommand: #{srv_conf['Command']}")
84-
vprint_good("\t\tCredentials: #{srv_conf['Credentials']}")
101+
msgString = "\tName: #{sname}"
102+
msgString << "\n\t\tStartup: #{srv_conf['Startup']}"
103+
#remove invalid char at the end
104+
commandString = srv_conf['Command']
105+
commandString.gsub!(/[\x00-\x08\x0b\x0c\x0e-\x19\x7f-\xff]+/n,"")
106+
msgString << "\n\t\t#{commandString}"
107+
msgString << "\n\t\tCredentials: #{srv_conf['Credentials']}\n"
108+
vprint_good(msgString)
109+
lootString << msgString
85110
end
86-
rescue
111+
rescue ::Exception => e
112+
# July 3rd 2014 wchen-r7: Not very sure what exceptions this method is trying to rescue,
113+
# probably the typical shut-everything-up coding habit. We'll have to fix this later,
114+
# but for now let's at least print the error for debugging purposes
87115
print_error("An error occured enumerating service: #{sname}")
116+
print_error(e.to_s)
88117
end
89118
else
90-
print_error("Problem enumerating services")
119+
print_error("Problem enumerating services (no service name found)")
91120
end
92-
93121
end
122+
# store loot on completion of collection
123+
p = store_loot("windows.services", "text/plain", session, lootString, "windows_services.txt", "Windows Services")
124+
print_good("Loot file stored in: #{p.to_s}")
94125
end
95126

96127
end

0 commit comments

Comments
 (0)