Updates to enum_artifacts

unstable
Stephen Haywood 2012-01-26 19:35:39 -05:00
parent bddeb9912b
commit efda420e5f
3 changed files with 99 additions and 55 deletions

View File

@ -1,14 +1,36 @@
# This file contains a list of artifacts used by the enum_artifacts post module # YAML:1.0
# Artifacts should be listed one per line and use the following formats: # Configuration file for enum_artifacts.rb module
# File entries # This file contains a YAML formated list of artifacts used by the
# file|path/to/file|md5sum # 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 # 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

View File

@ -38,7 +38,11 @@ module File
# #
def file_remote_digestmd5(file2md5) 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 return chksum
end end
@ -61,7 +65,11 @@ module File
# #
def file_remote_digestsha1(file2sha1) 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 return chksum
end end
@ -84,7 +92,11 @@ module File
# #
def file_remote_digestsha2(file2sha2) 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 return chksum
end end

View File

@ -9,6 +9,7 @@ require 'rex'
require 'msf/core' require 'msf/core'
require 'msf/core/post/file' require 'msf/core/post/file'
require 'msf/core/post/windows/registry' require 'msf/core/post/windows/registry'
require 'yaml'
class Metasploit3 < Msf::Post class Metasploit3 < Msf::Post
@ -21,7 +22,7 @@ class Metasploit3 < Msf::Post
'Name' => 'Windows File and Registry Artifacts Enumeration', 'Name' => 'Windows File and Registry Artifacts Enumeration',
'Description' => %q{ 'Description' => %q{
This module will check the file system and registry for particular artifacts. The 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. }, matches are written to the loot. },
'License' => MSF_LICENSE, 'License' => MSF_LICENSE,
'Author' => [ 'averagesecurityguy <stephen[at]averagesecurityguy.info>' ], 'Author' => [ 'averagesecurityguy <stephen[at]averagesecurityguy.info>' ],
@ -36,14 +37,15 @@ class Metasploit3 < Msf::Post
true, true,
'Full path to artifacts file.', 'Full path to artifacts file.',
::File.join(Msf::Config.data_directory, 'post', 'enum_artifacts_list.txt') ::File.join(Msf::Config.data_directory, 'post', 'enum_artifacts_list.txt')
]) ]),
OptString.new( 'VERBOSE', [false, "Show verbose output", false] )
], self.class) ], self.class)
end end
def run def run
# Store any found artifacts so they can be written to loot # Store any found artifacts so they can be written to loot
files_found = [] evidence = {}
reg_found = [] if datastore['VERBOSE'] == 'true' then verbose = true end
# Check artifacts file path # Check artifacts file path
filename = datastore['ARTIFACTS'] filename = datastore['ARTIFACTS']
@ -52,55 +54,63 @@ class Metasploit3 < Msf::Post
return return
end end
# Start enumerating # Load artifacts from yaml file. Artifacts are organized by what they
print_status("Processing artifacts file...") # are evidence of.
file = ::File.open(filename, "rb") yaml = YAML::load_file(filename)
file.each_line do |line| yaml.each_key do |key|
line.strip! print_status("Searching for artifacts of #{key}")
next if line.length < 1 files = yaml[key]['files']
next if line[0,1] == "#" regs = yaml[key]['reg_entries']
found = []
# Check registry # Process file entries
if line =~ /^reg/ if verbose
type, reg_key, val, data = line.split("|") print_status("Processing #{files.length.to_s} file entries for #{key}.")
reg_data = registry_getvaldata(reg_key, val)
if reg_data.to_s == data
reg_found << "#{reg_key}\\#{val}"
end
end end
# Check file files.each do |file|
if line =~ /^file/ digest = file_remote_digestmd5(file['name'])
type, file, hash = line.split("|") # if the file doesn't exist then digest will be nil
digest = file_remote_digestmd5(file) next if digest == nil
if digest == hash if digest == file['csum'] then found << file['name'] end
files_found << file 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
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 end
# Reporting. In case the user wants to separte artifact types (file vs registry), save(evidence, "Enumerated Artifacts")
# 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
end end
def save(data, name) 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}") print_status("#{name} stored in: #{f}")
end end
end end
=begin
To-do: Use CSV or yaml format to store enum_artifacts_list.txt
=end