CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/post/windows/gather/enum_artifacts.rb
Views: 11655
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
require 'yaml'
7
8
class MetasploitModule < Msf::Post
9
include Msf::Auxiliary::Report
10
include Msf::Post::File
11
include Msf::Post::Windows::Registry
12
13
def initialize(info = {})
14
super(
15
update_info(
16
info,
17
'Name' => 'Windows Gather File and Registry Artifacts Enumeration',
18
'Description' => %q{
19
This module will check the file system and registry for particular artifacts.
20
21
The list of artifacts is read in YAML format from data/post/enum_artifacts_list.txt
22
or a user specified file. Any matches are written to the loot.
23
},
24
'License' => MSF_LICENSE,
25
'Author' => [ 'averagesecurityguy <stephen[at]averagesecurityguy.info>' ],
26
'Platform' => [ 'win' ],
27
'SessionTypes' => %w[shell powershell meterpreter],
28
'Notes' => {
29
'Stability' => [CRASH_SAFE],
30
'Reliability' => [],
31
'SideEffects' => []
32
}
33
)
34
)
35
36
register_options([
37
OptPath.new(
38
'ARTIFACTS',
39
[
40
true,
41
'Full path to artifacts file.',
42
::File.join(Msf::Config.data_directory, 'post', 'enum_artifacts_list.txt')
43
]
44
)
45
])
46
end
47
48
def run
49
# Load artifacts from yaml file. Artifacts are organized by what they are evidence of.
50
begin
51
yaml = YAML.load_file(datastore['ARTIFACTS'])
52
raise 'File is not valid YAML' unless yaml.instance_of?(Hash)
53
rescue StandardError => e
54
fail_with(Failure::BadConfig, "Could not load artifacts YAML file '#{datastore['ARTIFACTS']}' : #{e.message}")
55
end
56
57
loot_data = ''
58
59
yaml.each_key do |key|
60
print_status("Searching for artifacts of #{key}")
61
artifacts = []
62
63
# Process file entries
64
files = yaml[key]['files']
65
vprint_status("Processing #{files.length} file entries for #{key} ...")
66
67
files.each do |file|
68
fname = file['name']
69
csum = file['csum']
70
71
digest = file_remote_digestmd5(fname)
72
if digest == csum
73
artifacts << fname
74
end
75
end
76
77
# Process registry entries
78
regs = yaml[key]['reg_entries']
79
vprint_status("Processing #{regs.length} registry entries for #{key} ...")
80
81
regs.each do |reg|
82
k = reg['key']
83
v = reg['val']
84
rdata = registry_getvaldata(k, v)
85
if rdata.to_s == reg['data']
86
artifacts << "#{k}\\#{v}"
87
end
88
end
89
90
# Process matches
91
if artifacts.empty?
92
print_status("No artifacts of #{key} found.")
93
next
94
end
95
96
print_status("Artifacts of #{key} found.")
97
loot_data << "Evidence of #{key} found.\n"
98
loot_data << artifacts.map { |a| "\t#{a}\n" }.join
99
end
100
101
return if loot_data.blank?
102
103
vprint_line(loot_data)
104
105
loot_name = 'Enumerated Artifacts'
106
f = store_loot(
107
loot_name.downcase.split.join('.'),
108
'text/plain',
109
session,
110
loot_data,
111
loot_name
112
)
113
print_good("#{loot_name} stored in: #{f}")
114
end
115
end
116
117