CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/scripts/meterpreter/event_manager.rb
Views: 1904
1
##
2
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
3
# If you'd like to improve this script, please try to port it as a post
4
# module instead. Thank you.
5
##
6
7
8
9
# Author: Carlos Perez at carlos_perez[at]darkoperator.com
10
#-------------------------------------------------------------------------------
11
################## Variable Declarations ##################
12
@client = client
13
eventlog_name = nil
14
print_logs = false
15
list_logs = false
16
clear_logs = false
17
local_log = false
18
local_log_path = nil
19
supress_print = false
20
filter = '\d*'
21
filter_string = "*"
22
meter_type = client.platform
23
opts = Rex::Parser::Arguments.new(
24
"-h" => [ false, "Help menu" ],
25
"-i" => [ false, "Show information about Event Logs on the System and their configuration"],
26
"-l" => [ true, "List a given Event Log."],
27
"-c" => [ true, "Clear a given Event Log (or ALL if no argument specified)"],
28
"-f" => [ true, "Event ID to filter events on"],
29
"-s" => [ true, "Save logs to local CSV file, optionally specify alternate folder in which to save logs"],
30
"-p" => [ false, "Suppress printing filtered logs to screen"]
31
)
32
33
34
################## Function Declarations ##################
35
36
# Usage Message Function
37
#-------------------------------------------------------------------------------
38
def usage(opts)
39
print_line "Meterpreter Script for Windows Event Log Query and Clear."
40
print_line(opts.usage)
41
raise Rex::Script::Completed
42
end
43
44
# Wrong Meterpreter Version Message Function
45
#-------------------------------------------------------------------------------
46
def wrong_meter_version(meter = meter_type)
47
print_error("#{meter} version of Meterpreter is not supported with this script!")
48
raise Rex::Script::Completed
49
end
50
51
# Function for Enumerating EventLogs
52
#-------------------------------------------------------------------------------
53
def get_log_details
54
logs_detail = Array.new
55
56
eventlog_list.each do |log_name|
57
58
# Create a hash to store the log info in (and throw default info in)
59
log_detail = Hash.new
60
log_detail[:name] = log_name
61
log_detail[:retention] = "Disabled"
62
log_detail[:size] = 0
63
log_detail[:number_of_records] = 0
64
65
key = "HKLM\\SYSTEM\\CurrentControlSet\\Services\\"
66
if @client.sys.config.sysinfo['OS'] =~ /Windows 2003|.Net|XP|2000/
67
key = "#{key}Eventlog"
68
else
69
key = "#{key}eventlog"
70
end
71
72
begin
73
unless (registry_getvaldata("#{key}\\#{log_name}","Retention") == 0) then log_detail[:retention] = "Disabled" end
74
log_detail[:size] = registry_getvaldata("#{key}\\#{log_name}","MaxSize")
75
76
# Open the event log
77
eventlog = @client.sys.eventlog.open(log_name)
78
log_detail[:num_of_records] = eventlog.length
79
rescue
80
log_detail[:num_of_records] = "Access Denied"
81
end
82
83
84
logs_detail << log_detail
85
end
86
87
return logs_detail
88
end
89
90
91
# Function for Printing Event Log Details
92
#-------------------------------------------------------------------------------
93
def print_log_details
94
print_status("Retrieving Event Log Configuration")
95
tbl = Rex::Text::Table.new(
96
'Header' => "Event Logs on System",
97
'Indent' => 1,
98
'Columns' => [
99
"Name",
100
"Retention",
101
"Maximum Size",
102
"Records"
103
])
104
105
eventlog_details = get_log_details
106
107
eventlog_details.each do |log_detail|
108
tbl << [log_detail[:name],log_detail[:retention],"#{log_detail[:size]}K",log_detail[:num_of_records]]
109
end
110
111
print_line("\n" + tbl.to_s + "\n")
112
end
113
114
115
# Function for doings queries of EventLogs
116
#-------------------------------------------------------------------------------
117
def list_logs(eventlog_name,filter,filter_string,logs,local_log,sup_print)
118
begin
119
event_data = ""
120
csv_data = "EventID,Date,Data\n"
121
log = @client.sys.eventlog.open(eventlog_name)
122
log.each_backwards do |e|
123
if e.eventid.to_s =~ /#{filter}/
124
if not sup_print
125
print_status("EventID: #{e.eventid}")
126
print_status("Date: #{e.generated}")
127
print_status("Data:")
128
e.strings.each do |l|
129
l.split("\r\n").each do |ml|
130
print_status("\t#{ml.chomp}")
131
event_data << " #{ml.chomp}"
132
end
133
end
134
print_status
135
end
136
csv_data << "#{e.eventid},#{e.generated},\"#{event_data}\"\n"
137
event_data = ""
138
end
139
end
140
rescue
141
print_error("Failed to Open Event Log #{eventlog_name}")
142
raise Rex::Script::Completed
143
end
144
145
if local_log
146
log_file = File.join(logs, "#{eventlog_name}.csv")
147
print_good("CSV File saved to #{log_file}")
148
file_local_write(log_file,csv_data)
149
end
150
end
151
152
# Function for clearing EventLogs
153
#-------------------------------------------------------------------------------
154
def clear_logs(log_name=nil)
155
log_names = []
156
if log_name.nil?
157
log_names = eventlog_list
158
else
159
log_names << log_name
160
end
161
162
log_names.each do |name|
163
begin
164
print_status("Clearing #{name}")
165
event_log = @client.sys.eventlog.open(name)
166
event_log.clear
167
print_status("Event Log #{name} Cleared!")
168
rescue
169
print_error("Failed to Clear #{name}, Access Denied")
170
end
171
end
172
173
return log_names
174
end
175
176
################## Main ##################
177
opts.parse(args) { |opt, idx, val|
178
case opt
179
when "-h"
180
usage(opts)
181
when "-i"
182
print_logs = true
183
print_log_details
184
raise Rex::Script::Completed
185
when "-c"
186
clear_logs = true
187
eventlog_name = val
188
when "-l"
189
list_logs = true
190
eventlog_name = val
191
when "-f"
192
filter = val
193
when "-s"
194
local_log = true
195
if File.directory?(val)
196
local_log_path = val
197
else
198
print_error("Log folder #{val} does not exist!")
199
raise Rex::Script::Completed
200
end
201
when "-p"
202
supress_print = true
203
end
204
}
205
206
# Check for Version of Meterpreter
207
wrong_meter_version(meter_type) if meter_type != 'windows'
208
209
# Print usage & exit if the user didn't specify an action
210
# to default to just running for all logs)
211
if !list_logs and !clear_logs and !print_logs
212
usage(opts)
213
end
214
215
# Log Folder Creation
216
#-----------------------------------------------------------------------
217
#Get Hostname
218
host = @client.sys.config.sysinfo["Computer"]
219
220
# Create Filename info to be appended to downloaded files
221
filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")
222
223
# Create a directory for any local logging if the user desires
224
if local_log
225
if local_log_path
226
logs = ::File.join(local_log_path, Rex::FileUtils.clean_path(host + filenameinfo) )
227
else
228
logs = ::File.join(Msf::Config.log_directory, "scripts", 'event_manager', Rex::FileUtils.clean_path(host + filenameinfo) )
229
end
230
231
::FileUtils.mkdir_p(logs)
232
end
233
234
# List the logs if the user desires
235
if list_logs and eventlog_name
236
list_logs(eventlog_name,filter,filter_string,logs,local_log,supress_print)
237
else
238
print_error("You must specify and eventlog to query!")
239
end
240
241
242
# Finally, clear the specified logs if the user desires
243
if clear_logs
244
if eventlog_name
245
clear_logs(eventlog_name)
246
else
247
eventlog_list.each do |eventlog_name|
248
print_status eventlog_name + ": "
249
clear_logs(eventlog_name)
250
end
251
end
252
end
253
254