Updates to enum_artifacts
parent
bddeb9912b
commit
efda420e5f
|
@ -1,14 +1,36 @@
|
|||
# This file contains a list of artifacts used by the enum_artifacts post module
|
||||
# Artifacts should be listed one per line and use the following formats:
|
||||
# File entries
|
||||
# file|path/to/file|md5sum
|
||||
# YAML:1.0
|
||||
# Configuration file for enum_artifacts.rb module
|
||||
# This file contains a YAML formated list of artifacts used by the
|
||||
# enum_artifacts post module. Artifacts should be listed using the following
|
||||
# format:
|
||||
#
|
||||
# Registry entries
|
||||
# reg|hive|key|value
|
||||
# ---
|
||||
# malware_name:
|
||||
# files:
|
||||
# - name: path\to\file
|
||||
# csum: 00112233445566778899aabbccddeeff
|
||||
# - name: path\to\another\file
|
||||
# csum: 112233445566778899aabbccddeeff00
|
||||
#
|
||||
# reg_entries:
|
||||
# - key: registry_key
|
||||
# val: registry_value
|
||||
# data: data
|
||||
#
|
||||
# Happy hunting
|
||||
---
|
||||
test_evidence:
|
||||
files:
|
||||
- name: c:\ntdetect.comx
|
||||
csum: b2de3452de03674c6cec68b8c8ce7c78
|
||||
- name: c:\boot.ini
|
||||
csum: fa579938b0733b87066546afe951082c
|
||||
|
||||
reg_entries:
|
||||
- key: HKEY_LOCAL_MACHINE\SYSTEM\Selectx
|
||||
val: Current
|
||||
data: 1
|
||||
- key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ACPI
|
||||
val: DisplayName
|
||||
data: Microsoft ACPI Driver
|
||||
|
||||
file|c:\ntdetect.com|b2de3452de03674c6cec68b8c8ce7c78
|
||||
file|c:\boot.ini|fa579938b0733b87066546afe951082c
|
||||
reg|HKEY_LOCAL_MACHINE\SYSTEM\Select|Current|1
|
||||
reg|HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ACPI|DisplayName|Microsoft ACPI Driver
|
||||
|
|
|
@ -38,7 +38,11 @@ module File
|
|||
#
|
||||
|
||||
def file_remote_digestmd5(file2md5)
|
||||
chksum = Digest::MD5.hexdigest(read_file(file2md5))
|
||||
data = read_file(file2md5)
|
||||
chksum = nil
|
||||
if data
|
||||
chksum = Digest::MD5.hexdigest(data)
|
||||
end
|
||||
return chksum
|
||||
end
|
||||
|
||||
|
@ -61,7 +65,11 @@ module File
|
|||
#
|
||||
|
||||
def file_remote_digestsha1(file2sha1)
|
||||
chksum = Digest::SHA1.hexdigest(read_file(file2sha1))
|
||||
data = read_file(file2sha1)
|
||||
chksum = nil
|
||||
if data
|
||||
chksum = Digest::SHA1.hexdigest(data)
|
||||
end
|
||||
return chksum
|
||||
end
|
||||
|
||||
|
@ -84,7 +92,11 @@ module File
|
|||
#
|
||||
|
||||
def file_remote_digestsha2(file2sha2)
|
||||
chksum = Digest::SHA256.hexdigest(read_file(file2sha2))
|
||||
data = read_file(file2sha2)
|
||||
chksum = nil
|
||||
if data
|
||||
chksum = Digest::SHA256.hexdigest(data)
|
||||
end
|
||||
return chksum
|
||||
end
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ require 'rex'
|
|||
require 'msf/core'
|
||||
require 'msf/core/post/file'
|
||||
require 'msf/core/post/windows/registry'
|
||||
require 'yaml'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
|
@ -21,7 +22,7 @@ class Metasploit3 < Msf::Post
|
|||
'Name' => 'Windows 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 from data/post/artifacts or a user specified file. Any
|
||||
list of artifacts is read 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>' ],
|
||||
|
@ -36,14 +37,15 @@ class Metasploit3 < Msf::Post
|
|||
true,
|
||||
'Full path to artifacts file.',
|
||||
::File.join(Msf::Config.data_directory, 'post', 'enum_artifacts_list.txt')
|
||||
])
|
||||
]),
|
||||
OptString.new( 'VERBOSE', [false, "Show verbose output", false] )
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def run
|
||||
# Store any found artifacts so they can be written to loot
|
||||
files_found = []
|
||||
reg_found = []
|
||||
evidence = {}
|
||||
if datastore['VERBOSE'] == 'true' then verbose = true end
|
||||
|
||||
# Check artifacts file path
|
||||
filename = datastore['ARTIFACTS']
|
||||
|
@ -52,55 +54,63 @@ class Metasploit3 < Msf::Post
|
|||
return
|
||||
end
|
||||
|
||||
# Start enumerating
|
||||
print_status("Processing artifacts file...")
|
||||
file = ::File.open(filename, "rb")
|
||||
file.each_line do |line|
|
||||
line.strip!
|
||||
next if line.length < 1
|
||||
next if line[0,1] == "#"
|
||||
# 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 = []
|
||||
|
||||
# Check registry
|
||||
if line =~ /^reg/
|
||||
type, reg_key, val, data = line.split("|")
|
||||
reg_data = registry_getvaldata(reg_key, val)
|
||||
if reg_data.to_s == data
|
||||
reg_found << "#{reg_key}\\#{val}"
|
||||
end
|
||||
# Process file entries
|
||||
if verbose
|
||||
print_status("Processing #{files.length.to_s} file entries for #{key}.")
|
||||
end
|
||||
|
||||
# Check file
|
||||
if line =~ /^file/
|
||||
type, file, hash = line.split("|")
|
||||
digest = file_remote_digestmd5(file)
|
||||
if digest == hash
|
||||
files_found << file
|
||||
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
|
||||
if verbose
|
||||
print_status("Processing #{regs.length.to_s} registry entries for #{key}.")
|
||||
end
|
||||
|
||||
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_error("Artifacts of #{key} found.")
|
||||
evidence[key] = found
|
||||
end
|
||||
end
|
||||
|
||||
# Reporting. In case the user wants to separte artifact types (file vs registry),
|
||||
# we've already done it at this point.
|
||||
if files_found.empty?
|
||||
print_status("No file artifacts found")
|
||||
else
|
||||
save(files_found, "Enumerated File Artifacts")
|
||||
end
|
||||
|
||||
if reg_found.empty?
|
||||
print_status("No registry artifacts found")
|
||||
else
|
||||
save(reg_found, "Enumerated Registry Artifacts")
|
||||
end
|
||||
save(evidence, "Enumerated Artifacts")
|
||||
end
|
||||
|
||||
def save(data, name)
|
||||
f = store_loot('enumerated.artifacts', 'text/plain', session, data.join("\n"), name)
|
||||
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)
|
||||
print_status("#{name} stored in: #{f}")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
=begin
|
||||
To-do: Use CSV or yaml format to store enum_artifacts_list.txt
|
||||
=end
|
||||
|
|
Loading…
Reference in New Issue