metasploit-framework/modules/post/windows/gather/enum_artifacts.rb

111 lines
3.0 KiB
Ruby
Raw Normal View History

2012-01-06 22:43:50 +00:00
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
2012-01-06 22:43:50 +00:00
##
require 'rex'
require 'msf/core'
require 'msf/core/post/file'
2012-01-06 22:43:50 +00:00
require 'msf/core/post/windows/registry'
2012-01-27 00:35:39 +00:00
require 'yaml'
2012-01-06 22:43:50 +00:00
class Metasploit3 < Msf::Post
include Msf::Auxiliary::Report
include Msf::Post::File
2012-01-06 22:43:50 +00:00
include Msf::Post::Windows::Registry
2012-01-18 21:01:00 +00:00
2012-01-06 22:43:50 +00:00
def initialize(info={})
super( update_info( info,
'Name' => 'Windows Gather File and Registry Artifacts Enumeration',
2012-01-12 23:26:35 +00:00
'Description' => %q{
2012-01-18 21:01:00 +00:00
This module will check the file system and registry for particular artifacts. The
2012-01-27 00:35:39 +00:00
list of artifacts is read from data/post/enum_artifacts_list.txt or a user specified file. Any
2012-01-12 23:26:35 +00:00
matches are written to the loot. },
2012-01-06 22:43:50 +00:00
'License' => MSF_LICENSE,
'Author' => [ 'averagesecurityguy <stephen[at]averagesecurityguy.info>' ],
'Platform' => [ 'windows' ],
'SessionTypes' => [ 'meterpreter' ]
))
2012-01-12 23:26:35 +00:00
2012-01-06 22:43:50 +00:00
register_options(
[
2012-01-12 23:26:35 +00:00
OptPath.new( 'ARTIFACTS',
[
true,
'Full path to artifacts file.',
::File.join(Msf::Config.data_directory, 'post', 'enum_artifacts_list.txt')
])
2012-01-06 22:43:50 +00:00
], self.class)
end
def run
# Store any found artifacts so they can be written to loot
2012-01-27 00:35:39 +00:00
evidence = {}
2012-01-06 22:43:50 +00:00
2012-01-12 23:26:35 +00:00
# Check artifacts file path
filename = datastore['ARTIFACTS']
if not ::File.exists?(filename)
print_error("Artifacts file does not exist!")
return
2012-01-06 22:43:50 +00:00
end
2012-01-12 23:26:35 +00:00
2012-01-27 00:35:39 +00:00
# Load artifacts from yaml file. Artifacts are organized by what they
# are evidence of.
yaml = YAML::load_file(filename)
yaml.each_key do |key|
print_status("Searching for artifacts of #{key}")
files = yaml[key]['files']
regs = yaml[key]['reg_entries']
found = []
2012-01-12 23:26:35 +00:00
2012-01-27 00:35:39 +00:00
# Process file entries
vprint_status("Processing #{files.length.to_s} file entries for #{key}.")
2012-01-12 23:26:35 +00:00
2012-01-27 00:35:39 +00:00
files.each do |file|
digest = file_remote_digestmd5(file['name'])
# if the file doesn't exist then digest will be nil
next if digest == nil
if digest == file['csum'] then found << file['name'] end
end
# Process registry entries
vprint_status("Processing #{regs.length.to_s} registry entries for #{key}.")
2012-01-06 22:43:50 +00:00
2012-01-27 00:35:39 +00:00
regs.each do |reg|
rdata = registry_getvaldata(reg['key'], reg['val'])
if rdata.to_s == reg['data']
found << reg['key'] + '\\' + reg['val']
end
end
# Did we find anything? If so store it in the evidence hash to be
# saved in the loot.
if found.empty?
print_status("No artifacts of #{key} found.")
else
print_status("Artifacts of #{key} found.")
2012-01-27 00:35:39 +00:00
evidence[key] = found
end
2012-01-06 22:43:50 +00:00
end
2012-01-27 00:35:39 +00:00
save(evidence, "Enumerated Artifacts")
2012-01-06 22:43:50 +00:00
end
2012-01-12 23:26:35 +00:00
def save(data, name)
2012-01-27 00:35:39 +00:00
str = ""
data.each_pair do |key, val|
str << "Evidence of #{key} found.\n"
val.each do |v|
str << "\t" + v + "\n"
end
end
f = store_loot('enumerated.artifacts', 'text/plain', session, str, name)
2012-01-12 23:26:35 +00:00
print_status("#{name} stored in: #{f}")
end
2012-01-06 22:43:50 +00:00
end