Permalink
Browse files

Updates to enum_artifacts

  • Loading branch information...
1 parent bddeb99 commit efda420e5fad3079ceae2a455260632c1567c040 @averagesecurityguy averagesecurityguy committed Jan 27, 2012
Showing with 99 additions and 55 deletions.
  1. +32 −10 data/post/enum_artifacts_list.txt
  2. +15 −3 lib/msf/core/post/file.rb
  3. +52 −42 modules/post/windows/gather/enum_artifacts.rb
@@ -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 @@ def file_local_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
end
@@ -61,7 +65,11 @@ def file_local_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
end
@@ -84,7 +92,11 @@ def file_local_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
end
@@ -9,6 +9,7 @@
require 'msf/core'
require 'msf/core/post/file'
require 'msf/core/post/windows/registry'
+require 'yaml'
class Metasploit3 < Msf::Post
@@ -21,7 +22,7 @@ def initialize(info={})
'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 @@ def initialize(info={})
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 @@ def run
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
- end
+ 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
- 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")
+ 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
- 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

0 comments on commit efda420

Please sign in to comment.