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

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

116 lines
3.1 KiB
Ruby
Raw Normal View History

2012-01-06 17:43:50 -05: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
2012-01-06 17:43:50 -05:00
##
2012-01-26 19:35:39 -05:00
require 'yaml'
2012-01-06 17:43:50 -05:00
2016-03-08 14:02:44 +01:00
class MetasploitModule < Msf::Post
2012-01-06 17:43:50 -05:00
include Msf::Auxiliary::Report
2012-01-12 12:49:50 -05:00
include Msf::Post::File
2012-01-06 17:43:50 -05:00
include Msf::Post::Windows::Registry
2013-08-30 16:28:54 -05:00
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Windows Gather File and Registry Artifacts Enumeration',
'Description' => %q{
This module will check the file system and registry for particular artifacts.
The list of artifacts is read in YAML format from data/post/enum_artifacts_list.txt
or a user specified file. Any matches are written to the loot.
},
'License' => MSF_LICENSE,
'Author' => [ 'averagesecurityguy <stephen[at]averagesecurityguy.info>' ],
'Platform' => [ 'win' ],
'SessionTypes' => %w[shell powershell meterpreter],
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [],
'SideEffects' => []
}
)
)
register_options([
OptPath.new(
'ARTIFACTS',
[
true,
'Full path to artifacts file.',
::File.join(Msf::Config.data_directory, 'post', 'enum_artifacts_list.txt')
]
)
])
2012-01-06 17:43:50 -05:00
end
2013-08-30 16:28:54 -05:00
2012-01-06 17:43:50 -05:00
def run
# Load artifacts from yaml file. Artifacts are organized by what they are evidence of.
begin
yaml = YAML.load_file(datastore['ARTIFACTS'])
raise 'File is not valid YAML' unless yaml.instance_of?(Hash)
rescue StandardError => e
fail_with(Failure::BadConfig, "Could not load artifacts YAML file '#{datastore['ARTIFACTS']}' : #{e.message}")
end
loot_data = ''
2013-08-30 16:28:54 -05:00
2012-01-26 19:35:39 -05:00
yaml.each_key do |key|
print_status("Searching for artifacts of #{key}")
artifacts = []
2013-08-30 16:28:54 -05:00
2012-01-26 19:35:39 -05:00
# Process file entries
files = yaml[key]['files']
vprint_status("Processing #{files.length} file entries for #{key} ...")
2013-08-30 16:28:54 -05:00
2012-01-26 19:35:39 -05:00
files.each do |file|
fname = file['name']
csum = file['csum']
digest = file_remote_digestmd5(fname)
if digest == csum
artifacts << fname
end
2012-01-26 19:35:39 -05:00
end
2013-08-30 16:28:54 -05:00
2012-01-26 19:35:39 -05:00
# Process registry entries
regs = yaml[key]['reg_entries']
vprint_status("Processing #{regs.length} registry entries for #{key} ...")
2013-08-30 16:28:54 -05:00
2012-01-26 19:35:39 -05:00
regs.each do |reg|
k = reg['key']
v = reg['val']
rdata = registry_getvaldata(k, v)
2012-01-26 19:35:39 -05:00
if rdata.to_s == reg['data']
artifacts << "#{k}\\#{v}"
2012-01-26 19:35:39 -05:00
end
end
2013-08-30 16:28:54 -05:00
# Process matches
if artifacts.empty?
2012-01-26 19:35:39 -05:00
print_status("No artifacts of #{key} found.")
next
2012-01-26 19:35:39 -05:00
end
print_status("Artifacts of #{key} found.")
loot_data << "Evidence of #{key} found.\n"
loot_data << artifacts.map { |a| "\t#{a}\n" }.join
2012-01-06 17:43:50 -05:00
end
2013-08-30 16:28:54 -05:00
return if loot_data.blank?
2013-08-30 16:28:54 -05:00
vprint_line(loot_data)
2013-08-30 16:28:54 -05:00
loot_name = 'Enumerated Artifacts'
f = store_loot(
loot_name.downcase.split.join('.'),
'text/plain',
session,
loot_data,
loot_name
)
print_good("#{loot_name} stored in: #{f}")
2012-01-12 17:26:35 -06:00
end
2012-01-06 17:43:50 -05:00
end