Merge pull request #98 from brandonprry/master
Offline registry reading library for rex (Rex::Registry)unstable
commit
24aaf85a1b
|
@ -0,0 +1,162 @@
|
||||||
|
require_relative "regf"
|
||||||
|
require_relative "nodekey"
|
||||||
|
|
||||||
|
module Rex
|
||||||
|
module Registry
|
||||||
|
|
||||||
|
class Hive
|
||||||
|
attr_accessor :root_key, :hive_regf
|
||||||
|
|
||||||
|
def initialize(hivepath)
|
||||||
|
|
||||||
|
hive_blob = open(hivepath, "rb") { |io| io.read }
|
||||||
|
@hive_regf = RegfBlock.new(hive_blob)
|
||||||
|
|
||||||
|
@root_key = NodeKey.new(hive_blob, 0x1000 + @hive_regf.root_key_offset)
|
||||||
|
end
|
||||||
|
|
||||||
|
def relative_query(path)
|
||||||
|
|
||||||
|
if path == "" || path == "\\"
|
||||||
|
return @root_key
|
||||||
|
end
|
||||||
|
|
||||||
|
current_child = nil
|
||||||
|
paths = path.split("\\")
|
||||||
|
|
||||||
|
@root_key.lf_record.children.each do |child|
|
||||||
|
next if child.name.downcase != paths[1].downcase
|
||||||
|
|
||||||
|
current_child = child
|
||||||
|
|
||||||
|
if paths.length == 2
|
||||||
|
current_child.full_path = path
|
||||||
|
return current_child
|
||||||
|
end
|
||||||
|
|
||||||
|
2.upto(paths.length) do |i|
|
||||||
|
|
||||||
|
if i == paths.length
|
||||||
|
current_child.full_path = path
|
||||||
|
return current_child
|
||||||
|
else
|
||||||
|
if current_child.lf_record
|
||||||
|
current_child.lf_record.children.each do |c|
|
||||||
|
next if c.name.downcase != paths[i].downcase
|
||||||
|
|
||||||
|
current_child = c
|
||||||
|
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
current_child.full_path = path
|
||||||
|
return current_child
|
||||||
|
end
|
||||||
|
|
||||||
|
def value_query(path)
|
||||||
|
if path == "" || path == "\\"
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
paths = path.split("\\")
|
||||||
|
|
||||||
|
@root_key.lf_record.children.each do |root_child|
|
||||||
|
next if root_child.name.downcase != paths[1].downcase
|
||||||
|
|
||||||
|
current_child = root_child
|
||||||
|
|
||||||
|
if paths.length == 2
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
2.upto(paths.length - 1) do |i|
|
||||||
|
next if !current_child.lf_record
|
||||||
|
|
||||||
|
current_child.lf_record.children.each do |c|
|
||||||
|
next if c.name != paths[i]
|
||||||
|
current_child = c
|
||||||
|
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if !current_child.value_list || current_child.value_list.values.length == 0
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
current_child.value_list.values.each do |value|
|
||||||
|
next if value.name.downcase != paths[paths.length - 1].downcase
|
||||||
|
|
||||||
|
value.full_path = path
|
||||||
|
return value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def rip_boot_key
|
||||||
|
|
||||||
|
return if @hive_regf.hive_name !~ /SYSTEM/
|
||||||
|
|
||||||
|
scrambled_key = []
|
||||||
|
default_control_set = ""
|
||||||
|
|
||||||
|
@root_key.lf_record.children.each do |node|
|
||||||
|
next if node.name != "Select"
|
||||||
|
|
||||||
|
node.value_list.values.each do |value|
|
||||||
|
next if value.name != "Default"
|
||||||
|
|
||||||
|
default_control_set = "ControlSet00" + value.value.data.unpack('c').first.to_s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "Default Control Set: " + default_control_set
|
||||||
|
|
||||||
|
@root_key.lf_record.children.each do |node|
|
||||||
|
next if node.name != default_control_set
|
||||||
|
|
||||||
|
node.lf_record.children.each do |cchild|
|
||||||
|
next if cchild.name != "Control"
|
||||||
|
|
||||||
|
puts "Found: " + cchild.name
|
||||||
|
|
||||||
|
cchild.lf_record.children.each do |lsachild|
|
||||||
|
next if lsachild.name != "Lsa"
|
||||||
|
|
||||||
|
puts "Found: " + lsachild.name
|
||||||
|
|
||||||
|
%w[JD Skew1 GBG Data].each do |key|
|
||||||
|
lsachild.lf_record.children.each do |child|
|
||||||
|
next if child.name != key
|
||||||
|
|
||||||
|
puts "Found: " + child.name
|
||||||
|
|
||||||
|
child.class_name_data.each_byte do |byte|
|
||||||
|
scrambled_key << byte if byte != 0x00
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
scrambler = [ 0x8, 0x5, 0x4, 0x2, 0xb, 0x9, 0xd, 0x3, 0x0, 0x6, 0x1, 0xc, 0xe, 0xa, 0xf, 0x7 ]
|
||||||
|
bootkey = scrambled_key
|
||||||
|
|
||||||
|
0.upto(0x10-1) do |i|
|
||||||
|
#p scrambler[i]
|
||||||
|
bootkey[i] = scrambled_key[scrambler[i]]
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "Bootkey: " + bootkey.to_s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,50 @@
|
||||||
|
require_relative "nodekey"
|
||||||
|
|
||||||
|
module Rex
|
||||||
|
module Registry
|
||||||
|
|
||||||
|
class LFBlock
|
||||||
|
|
||||||
|
attr_accessor :number_of_keys, :hash_records, :children
|
||||||
|
|
||||||
|
def initialize(hive_blob, offset)
|
||||||
|
offset = offset + 4
|
||||||
|
lf_header = hive_blob[offset, 2]
|
||||||
|
|
||||||
|
if lf_header !~ /lf/ && lf_header !~ /lh/
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
@number_of_keys = hive_blob[offset + 0x02, 2].unpack('C').first
|
||||||
|
|
||||||
|
@hash_records = []
|
||||||
|
@children = []
|
||||||
|
|
||||||
|
hash_offset = offset + 0x04
|
||||||
|
|
||||||
|
1.upto(@number_of_keys) do |h|
|
||||||
|
|
||||||
|
hash = LFHashRecord.new(hive_blob, hash_offset)
|
||||||
|
|
||||||
|
@hash_records << hash
|
||||||
|
|
||||||
|
hash_offset = hash_offset + 0x08
|
||||||
|
|
||||||
|
@children << NodeKey.new(hive_blob, hash.nodekey_offset + 0x1000)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class LFHashRecord
|
||||||
|
|
||||||
|
attr_accessor :nodekey_offset, :nodekey_name_verification
|
||||||
|
|
||||||
|
def initialize(hive_blob, offset)
|
||||||
|
@nodekey_offset = hive_blob[offset, 4].unpack('l').first
|
||||||
|
@nodekey_name_verification = hive_blob[offset+0x04, 4].to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,52 @@
|
||||||
|
require_relative "lfkey"
|
||||||
|
require_relative "valuelist"
|
||||||
|
|
||||||
|
module Rex
|
||||||
|
module Registry
|
||||||
|
|
||||||
|
class NodeKey
|
||||||
|
|
||||||
|
attr_accessor :timestamp, :parent_offset, :subkeys_count, :lf_record_offset
|
||||||
|
attr_accessor :value_count, :value_list_offset, :security_key_offset
|
||||||
|
attr_accessor :class_name_offset, :name_length, :class_name_length, :full_path
|
||||||
|
attr_accessor :name, :lf_record, :value_list, :class_name_data, :readable_timestamp
|
||||||
|
|
||||||
|
def initialize(hive, offset)
|
||||||
|
|
||||||
|
offset = offset + 0x04
|
||||||
|
|
||||||
|
nk_header = hive[offset, 2]
|
||||||
|
nk_type = hive[offset+0x02, 2]
|
||||||
|
|
||||||
|
if nk_header !~ /nk/
|
||||||
|
puts "nodekey broken"
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
@timestamp = hive[offset+0x04, 8].unpack('q').first
|
||||||
|
@parent_offset = hive[offset+0x10, 4].unpack('l').first
|
||||||
|
@subkeys_count = hive[offset+0x14, 4].unpack('l').first
|
||||||
|
@lf_record_offset = hive[offset+0x1c, 4].unpack('l').first
|
||||||
|
@value_count = hive[offset+0x24, 4].unpack('l').first
|
||||||
|
@value_list_offset = hive[offset+0x28, 4].unpack('l').first
|
||||||
|
@security_key_offset = hive[offset+0x2c, 4].unpack('l').first
|
||||||
|
@class_name_offset = hive[offset+0x30, 4].unpack('l').first
|
||||||
|
@name_length = hive[offset+0x48, 2].unpack('c').first
|
||||||
|
@class_name_length = hive[offset+0x4a, 2].unpack('c').first
|
||||||
|
@name = hive[offset+0x4c, @name_length].to_s
|
||||||
|
|
||||||
|
windows_time = @timestamp
|
||||||
|
unix_time = windows_time/10000000-11644473600
|
||||||
|
ruby_time = Time.at(unix_time)
|
||||||
|
|
||||||
|
@readable_timestamp = ruby_time
|
||||||
|
|
||||||
|
@lf_record = LFBlock.new(hive, @lf_record_offset + 0x1000) if @lf_record_offset != -1
|
||||||
|
@value_list = ValueList.new(hive, @value_list_offset + 0x1000, @value_count) if @value_list_offset != -1
|
||||||
|
@class_name_data = hive[@class_name_offset + 0x1000, @class_name_length]
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,26 @@
|
||||||
|
module Rex
|
||||||
|
module Registry
|
||||||
|
|
||||||
|
class RegfBlock
|
||||||
|
|
||||||
|
attr_accessor :timestamp, :root_key_offset, :hive_name
|
||||||
|
|
||||||
|
def initialize(hive)
|
||||||
|
|
||||||
|
regf_header = hive[0x00, 4]
|
||||||
|
|
||||||
|
if regf_header !~ /regf/
|
||||||
|
puts "Not a registry hive"
|
||||||
|
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
@timestamp = hive[0x0C, 8].unpack('q').first
|
||||||
|
@root_key_offset = 0x20
|
||||||
|
@hive_name = hive[0x30-1, 64].to_s.gsub("\x00", "")
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,66 @@
|
||||||
|
module Rex
|
||||||
|
module Registry
|
||||||
|
|
||||||
|
class ValueKey
|
||||||
|
|
||||||
|
attr_accessor :name_length, :length_of_data, :data_offset, :full_path
|
||||||
|
attr_accessor :value_type, :readable_value_type, :name, :value
|
||||||
|
|
||||||
|
def initialize(hive, offset)
|
||||||
|
offset = offset + 4
|
||||||
|
|
||||||
|
vk_header = hive[offset, 2]
|
||||||
|
|
||||||
|
if vk_header !~ /vk/
|
||||||
|
puts "no vk at offset #{offset}"
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
@name_length = hive[offset+0x02, 2].unpack('c').first
|
||||||
|
@length_of_data = hive[offset+0x04, 4].unpack('l').first
|
||||||
|
@data_offset = hive[offset+ 0x08, 4].unpack('l').first
|
||||||
|
@value_type = hive[offset+0x0C, 4].unpack('c').first
|
||||||
|
|
||||||
|
if @value_type == 1
|
||||||
|
@readable_value_type = "Unicode character string"
|
||||||
|
elsif @value_type == 2
|
||||||
|
@readable_value_type = "Unicode string with %VAR% expanding"
|
||||||
|
elsif @value_type == 3
|
||||||
|
@readable_value_type = "Raw binary value"
|
||||||
|
elsif @value_type == 4
|
||||||
|
@readable_value_type = "Dword"
|
||||||
|
elsif @value_type == 7
|
||||||
|
@readable_value_type = "Multiple unicode strings separated with '\\x00'"
|
||||||
|
end
|
||||||
|
|
||||||
|
flag = hive[offset+0x10, 2].unpack('c').first
|
||||||
|
|
||||||
|
if flag == 0
|
||||||
|
@name = "Default"
|
||||||
|
else
|
||||||
|
@name = hive[offset+0x14, @name_length].to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
@value = ValueKeyData.new(hive, @data_offset, @length_of_data, @value_type, offset)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class ValueKeyData
|
||||||
|
|
||||||
|
attr_accessor :data
|
||||||
|
|
||||||
|
def initialize(hive, offset, length, datatype, parent_offset)
|
||||||
|
offset = offset + 4
|
||||||
|
|
||||||
|
#If the data-size is lower than 5, the data-offset value is used to store
|
||||||
|
#the data itself!
|
||||||
|
if length < 5
|
||||||
|
@data = hive[parent_offset + 0x08, 4]
|
||||||
|
else
|
||||||
|
@data = hive[offset + 0x1000, length]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,25 @@
|
||||||
|
require_relative "valuekey"
|
||||||
|
|
||||||
|
module Rex
|
||||||
|
module Registry
|
||||||
|
|
||||||
|
class ValueList
|
||||||
|
|
||||||
|
attr_accessor :values
|
||||||
|
|
||||||
|
def initialize(hive, offset, number_of_values)
|
||||||
|
offset = offset + 4
|
||||||
|
inner_offset = 0
|
||||||
|
|
||||||
|
@values = []
|
||||||
|
|
||||||
|
1.upto(number_of_values) do |v|
|
||||||
|
valuekey_offset = hive[offset + inner_offset, 4].unpack('l').first
|
||||||
|
@values << ValueKey.new(hive, valuekey_offset + 0x1000)
|
||||||
|
inner_offset = inner_offset + 4
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,455 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
#
|
||||||
|
# $Id$
|
||||||
|
#
|
||||||
|
# This script acts as a small registry reader.
|
||||||
|
# You may easily automate a lot of registry forensics with a proper method.
|
||||||
|
# $Revision$
|
||||||
|
#
|
||||||
|
|
||||||
|
msfbase = File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__
|
||||||
|
$:.unshift(File.join(File.dirname(msfbase), '..', 'lib'))
|
||||||
|
|
||||||
|
require 'rex'
|
||||||
|
require 'msf/ui'
|
||||||
|
require 'rex/registry/hive'
|
||||||
|
|
||||||
|
def print_all(nodekey)
|
||||||
|
print_all_keys(nodekey)
|
||||||
|
print_all_values(nodekey)
|
||||||
|
end
|
||||||
|
|
||||||
|
def print_all_keys(nodekey)
|
||||||
|
table = Rex::Ui::Text::Table.new(
|
||||||
|
'Header' => "Child Keys for #{nodekey.full_path}",
|
||||||
|
'Indent' => ' '.length,
|
||||||
|
'Columns' => [ 'Name', 'Last Edited', 'Subkey Count', 'Value Count' ]
|
||||||
|
)
|
||||||
|
|
||||||
|
if nodekey.lf_record && nodekey.lf_record.children.length > 0
|
||||||
|
nodekey.lf_record.children.each do |key|
|
||||||
|
table << [key.name, key.readable_timestamp, key.subkeys_count, key.value_count]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
puts table.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
def print_all_values(nodekey)
|
||||||
|
|
||||||
|
table = Rex::Ui::Text::Table.new(
|
||||||
|
'Header' => "Values in key #{nodekey.full_path}",
|
||||||
|
'Indent' => ' '.length,
|
||||||
|
'Columns' => ['Name','Value Type', 'Value']
|
||||||
|
)
|
||||||
|
if nodekey.value_list && nodekey.value_list.values.length > 0
|
||||||
|
nodekey.value_list.values.each do |value|
|
||||||
|
table << [value.name, value.readable_value_type, value.value.data]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
puts table.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_system_information
|
||||||
|
if @hive.hive_regf.hive_name =~ /SYSTEM/
|
||||||
|
mounted_devices_info_key = @hive.relative_query("\\MountedDevices")
|
||||||
|
|
||||||
|
current_control_set_key = @hive.value_query('\Select\Default')
|
||||||
|
current_control_set = "ControlSet00" + current_control_set_key.value.data.unpack('c').first.to_s
|
||||||
|
|
||||||
|
computer_name_key = @hive.value_query("\\" + current_control_set + "\\Control\\ComputerName\\ComputerName")
|
||||||
|
computer_name = computer_name_key.value.data.to_s
|
||||||
|
|
||||||
|
event_log_info_key = @hive.relative_query("\\" + current_control_set + "\\Services\\EventLog")
|
||||||
|
|
||||||
|
puts "Computer Name: " + computer_name
|
||||||
|
|
||||||
|
print_all_values(event_log_info_key)
|
||||||
|
puts "-----------------------------------------"
|
||||||
|
|
||||||
|
print_all_values(mounted_devices_info_key)
|
||||||
|
puts "-----------------------------------------"
|
||||||
|
|
||||||
|
elsif @hive.hive_regf.hive_name =~ /SOFTWARE/
|
||||||
|
current_version_info_key = @hive.relative_query("\\Microsoft\\Windows NT\\CurrentVersion")
|
||||||
|
login_info_key = @hive.relative_query("\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon")
|
||||||
|
|
||||||
|
print_all_values(current_version_info_key)
|
||||||
|
puts "-----------------------------------------"
|
||||||
|
|
||||||
|
print_all_values(login_info_key)
|
||||||
|
puts "-----------------------------------------"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_user_information
|
||||||
|
local_groups_info_key = @hive.relative_query("\\SAM\\Domains\\Builtin\\Aliases\\Names")
|
||||||
|
local_users_info_key = @hive.relative_query("\\SAM\\Domains\\Account\\Users\\Names")
|
||||||
|
|
||||||
|
print_all_keys(local_groups_info_key)
|
||||||
|
puts "------------------------------------------------"
|
||||||
|
|
||||||
|
print_all_keys(local_users_info_key)
|
||||||
|
puts "------------------------------------------------"
|
||||||
|
end
|
||||||
|
|
||||||
|
def dump_creds
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_boot_key
|
||||||
|
end
|
||||||
|
|
||||||
|
def list_applications
|
||||||
|
end
|
||||||
|
|
||||||
|
def list_drivers
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_aol_instant_messenger_information
|
||||||
|
|
||||||
|
if @hive.hive_regf.hive_name != /NTUSER[.]dat/i
|
||||||
|
users_list_key = @hive.relative_query('\Software\America Online\AOL Instant Messenger(TM)\CurrentVersion\Users')
|
||||||
|
last_logged_in_user_key = @hive.relative_query("\\Software\\America Online\\AOL Instant Messenger(TM)\\CurrentVersion\\Login - Screen Name")
|
||||||
|
|
||||||
|
print_all_keys(user_list_key)
|
||||||
|
|
||||||
|
user_list_key.lf_record.children.each do |screenname|
|
||||||
|
away_messages_key = @hive.relative_query("\\Software\\America Online\\AOL Instant Messenger(TM)\\CurrentVersion\\Users\\#{screenname.name}\\IAmGoneList")
|
||||||
|
file_xfer_settings_key = @hive.relative_query("\\Software\\America Online\\AOL Instant Messenger(TM)\\CurrentVersion\\Users\\#{screenname.name}\\Xfer")
|
||||||
|
profile_info_key = @hive.relative_query("\\Software\\America Online\\AOL Instant Messenger(TM)\\CurrentVersion\\Users\\#{screenname.name}\\DirEntry")
|
||||||
|
recent_contacts_key = @hive.relative_query("\\Software\\America Online\\AOL Instant Messenger(TM)\\CurrentVersion\\Users\\#{screenname.name}\\Recent IM ScreenNames")
|
||||||
|
|
||||||
|
print_all(away_messages_key)
|
||||||
|
print_all(file_xfer_settings_key)
|
||||||
|
print_all(profile_info_key)
|
||||||
|
print_all(recent_contacts_key)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_msn_messenger_information
|
||||||
|
|
||||||
|
if @hive.hive_regf.hive_name =~ /NTUSER[.]dat/i
|
||||||
|
general_information_key = @hive.relative_query("\\Software\\Microsoft\\MessengerService\\ListCache\\.NETMessengerService\\")
|
||||||
|
file_sharing_information_key = @hive.relative_query("\\Software\\Microsoft\\MSNMessenger\\FileSharing - Autoshare")
|
||||||
|
file_transfers_information_key = @hive.relative_query("\\Software\\Microsoft\\MSNMessenger\\ - FTReceiveFolder")
|
||||||
|
|
||||||
|
print_all(general_information_key)
|
||||||
|
print_all(file_sharing_information_key)
|
||||||
|
print_all(file_transfers_information_key)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_windows_messenger_information
|
||||||
|
if @hive.hive_regf.hive_name =~ /NTUSER[.]dat/i
|
||||||
|
contact_list_information_key = @hive.relative_query("\\Software\\Microsoft\\MessengerService\\ListCache\\.NET Messenger Service")
|
||||||
|
file_transfers_information_key = @hive.realtive_query("\\Software\\Microsoft\\Messenger Service - FtReceiveFolder")
|
||||||
|
last_user_information_key = @hive.relative_query("\\Software\\Microsoft\\MessengerService\\ListCache\\.NET Messenger Service - IdentityName")
|
||||||
|
|
||||||
|
print_all(contact_list_information_key)
|
||||||
|
print_all(file_transers_information_key)
|
||||||
|
print_all(last_user_information_key)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_icq_information
|
||||||
|
if @hive.hive_regf.hive_name != /NTUSER[.]dat/i
|
||||||
|
general_information_key = @hive.relative_query("\\Software\\Mirabalis\\ICQ")
|
||||||
|
|
||||||
|
print_all(general_information_key)
|
||||||
|
elsif @hive.hive_regf.hive_name != /SOFTWARE/
|
||||||
|
owner_number_key = @hive.value_query("\\Software\\Mirabalis\\ICQ\\Owner")
|
||||||
|
|
||||||
|
puts "Owner UIN: #{owner_number_key.value.data.to_s}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_ie_information
|
||||||
|
if @hive.hive_regf.hive_name =~ /NTUSER[.]dat/i
|
||||||
|
stored_logon_information_key = @hive.relative_query("\\Software\\Microsoft\\Protected Storage System Provider\\SID\\Internet Explorer\\Internet Explorer - URL:StringData")
|
||||||
|
stored_search_terms_information_key = @hive.relative_quety("\\Software\\Microsoft\\Protected Storage SystemProvider\\SID\\Internet Explorer\\Internet Explorer - q:SearchIndex")
|
||||||
|
ie_setting_information_key = @hive.relative_query("\\Software\\Microsoft\\Internet Explorer\\Main")
|
||||||
|
history_length_value_key = @hive.value_query("\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\URL History - DaysToKeep")
|
||||||
|
typed_urls_information_key = @hive.relative_query("\\Software\\Microsoft\\Internet Explorer\\Typed URLs")
|
||||||
|
intelliforms_information_key = @hive.relative_query("\\Software\\Microsoft\\Internet Explorer\\Intelliforms")
|
||||||
|
autocomplete_web_addresses_key = @hive.relative_query("\\Software\\Microsoft\\Protected Storage System Provider")
|
||||||
|
default_download_dir = @hive.relative_query("\\Software\\Microsoft\\Internet Explorer")
|
||||||
|
|
||||||
|
print_all(stored_logon_information_key)
|
||||||
|
print_all(stored_search_terms_information_key)
|
||||||
|
print_all(ie_settings_information_key)
|
||||||
|
print_all(type_urls_information_key)
|
||||||
|
print_all(intelliforms_information_key)
|
||||||
|
print_all(autocomplete_web_addresses_key)
|
||||||
|
print_all(default_download_dir)
|
||||||
|
|
||||||
|
puts "Days saved in history: " + history_length_value_key.value.data.to_s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_outlook_information
|
||||||
|
if @hive.hive_regf.hive_name =~ /NTUSER[.]dat/i
|
||||||
|
account_information_key = @hive.relative_query("\\Software\\Microsoft\\Protected Storage System Provider\\SID\\Identification\\INETCOMM Server Passwords")
|
||||||
|
|
||||||
|
print_all(account_information_key)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_yahoo_messenger_information
|
||||||
|
if @hive.hive_regf.hive_name =~ /NTUSER[.]dat/i
|
||||||
|
profiles_key = @hive.relative_query("\\Software\\Yahoo\\Pager\\profiles")
|
||||||
|
|
||||||
|
print_all(profiles_key)
|
||||||
|
|
||||||
|
profiles_key.lf_record.children.each do |child|
|
||||||
|
file_transfers_information_key = @hive.relative_query("\\Software\\Yahoo\\Pager\\profiles\\#{child.name}\\FileTransfer")
|
||||||
|
message_archiving_information_key = @hive.relative_query("\\Software\\Yahoo\\Pager\\profiles\\#{child.name}\\Archive")
|
||||||
|
|
||||||
|
print_all(file_transfer_information_key)
|
||||||
|
print_all(message_archiving_information_key)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_networking_information
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_user_information
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_user_application_information
|
||||||
|
end
|
||||||
|
|
||||||
|
if ARGV.length == 0 || ARGV[0] == "help"
|
||||||
|
no_args = %Q{
|
||||||
|
Usage: reg.rb <command> <opts> <hivepath>
|
||||||
|
|
||||||
|
Available commands:
|
||||||
|
query_key Query for more information about a specific node key
|
||||||
|
query_value Query for the value of a specific value key
|
||||||
|
get_boot_key Extract the boot key from the SYSTEM hive
|
||||||
|
dump_creds Dump the usernames and password hashes of the users from the SAM hive
|
||||||
|
list_applications List all the applications installed via the SOFTWARE hive
|
||||||
|
list_drivers List all the devices and their respective drivers and driver versions from SYSTEM hive
|
||||||
|
get_everything When pointed to a directory with hives, it will run all commands on all available hives
|
||||||
|
get_aol_instant_messenger_information Get credentials and general information on AOL Instant Messenger users from NTUSER.dat
|
||||||
|
get_msn_messenger_information Get credentials and general information on MSN Messenger users from NTUSER.dat
|
||||||
|
get_windows_messenger_information Get credentials and general information on Windows Messenger users from NTUSER.dat
|
||||||
|
get_icq_information Get credentials and general information on ICQ users from NTUSER.dat
|
||||||
|
get_ie_information Get stored credentials, typed history, search terms, and general settings from NTUSER.dat
|
||||||
|
get_outlook_information Gets outlook and outlook express stored credentials and general information from NTUSER.dat
|
||||||
|
get_yahoo_messenger_information Gets credentials and general information on Yahoo! Messenger users from NTUSER.dat
|
||||||
|
get_system_information Gets general system administration from both SOFTWARE and SYSTEM hives
|
||||||
|
get_networking_information Gets networing information from the SAM, SYSTEM, and NTUSER.dat hives
|
||||||
|
get_user_information Gets general user information from the SYSTEM, SECURITY, SAM, and NTUSER.dat hives
|
||||||
|
get_user_application_information Gets user-specific application information from the NTUSER.DAT and SOFTWARE hives
|
||||||
|
}
|
||||||
|
|
||||||
|
puts no_args
|
||||||
|
elsif ARGV[0] == "query_key"
|
||||||
|
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
|
||||||
|
puts "Hive name: #{@hive.hive_regf.hive_name}"
|
||||||
|
|
||||||
|
1.upto(ARGV.length - 2) do |arg|
|
||||||
|
selected = @hive.relative_query(ARGV[arg])
|
||||||
|
|
||||||
|
print_all(selected)
|
||||||
|
end
|
||||||
|
elsif ARGV[0] == "query_value"
|
||||||
|
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
|
||||||
|
puts "Hive name: #{@hive.hive_regf.hive_name}"
|
||||||
|
|
||||||
|
1.upto(ARGV.length - 2) do |i|
|
||||||
|
selected = @hive.value_query(ARGV[i])
|
||||||
|
|
||||||
|
if !selected
|
||||||
|
puts "Value not found."
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "Value Name: #{selected.name}"
|
||||||
|
puts "Value Data: #{selected.value.data.inspect}"
|
||||||
|
end
|
||||||
|
elsif ARGV[0] == "get_boot_key"
|
||||||
|
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
|
||||||
|
|
||||||
|
if @hive.hive_regf.hive_name !~ /SYSTEM/
|
||||||
|
puts "I need a SYSTEM hive to grab the boot key, not a #{@hive.hive_regf.hive_name}."
|
||||||
|
else
|
||||||
|
get_boot_key
|
||||||
|
end
|
||||||
|
|
||||||
|
elsif ARGV[0] == "dump_creds"
|
||||||
|
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
|
||||||
|
|
||||||
|
if @hive.hive_regf.hive_name !~ /SAM/
|
||||||
|
puts "I need a SAM hive, not a #{@hive.hive_regf.hive_name}"
|
||||||
|
else
|
||||||
|
dump_creds
|
||||||
|
end
|
||||||
|
|
||||||
|
elsif ARGV[0] == "list_applications"
|
||||||
|
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
|
||||||
|
|
||||||
|
if @hive.hive_regf.hive_name !~ /SOFTWARE/
|
||||||
|
puts "I need a SOFTWARE hive, not a #{@hive.hive_regf.hive_name}."
|
||||||
|
else
|
||||||
|
list_applications
|
||||||
|
end
|
||||||
|
|
||||||
|
elsif ARGV[0] == "list_drivers"
|
||||||
|
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
|
||||||
|
|
||||||
|
if @hive.hive_regf.hive_name !~ /SYSTEM/
|
||||||
|
puts "I need a SYSTEM hive, not a #{@hive.hive_regf.hive_name}."
|
||||||
|
else
|
||||||
|
list_drivers
|
||||||
|
end
|
||||||
|
|
||||||
|
elsif ARGV[0] == "get_everything"
|
||||||
|
Dir.foreach(ARGV[1]) do |file|
|
||||||
|
next if file =~ /^[.]/
|
||||||
|
|
||||||
|
@hive = Rex::Registry::Hive.new(ARGV[1] + "/" + file)
|
||||||
|
|
||||||
|
if @hive.hive_regf.hive_name =~ /SYSTEM$/
|
||||||
|
|
||||||
|
list_drivers
|
||||||
|
get_boot_key
|
||||||
|
get_system_information
|
||||||
|
get_networking_information
|
||||||
|
get_user_information
|
||||||
|
|
||||||
|
elsif @hive.hive_regf.hive_name =~ /SOFTWARE$/
|
||||||
|
|
||||||
|
list_applications
|
||||||
|
get_icq_information
|
||||||
|
get_system_information
|
||||||
|
get_networking_information
|
||||||
|
get_user_information
|
||||||
|
get_user_application_information
|
||||||
|
|
||||||
|
elsif @hive.hive_regf.hive_name =~ /SAM$/
|
||||||
|
|
||||||
|
get_networking_information
|
||||||
|
get_user_information
|
||||||
|
|
||||||
|
elsif @hive.hive_regf.hive_name =~ /SECURITY$/
|
||||||
|
|
||||||
|
get_user_information
|
||||||
|
|
||||||
|
elsif @hive.hive_regf_hive_name =~ /NTUSER[.]dat$/i
|
||||||
|
|
||||||
|
get_aol_instant_messenger_information
|
||||||
|
get_icq_information
|
||||||
|
get_ie_information
|
||||||
|
get_msn_messenger_information
|
||||||
|
get_outlook_information
|
||||||
|
get_windows_messenger_information
|
||||||
|
get_yahoo_messenger_information
|
||||||
|
get_networking_information
|
||||||
|
get_user_information
|
||||||
|
get_user_application_information
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
elsif ARGV[0] == "get_aol_instant_messenger_information"
|
||||||
|
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
|
||||||
|
|
||||||
|
if @hive.hive_regf.hive_name !~ /NTUSER[.]DAT/i
|
||||||
|
puts "I need the NTUSER.dat hive, not #{@hive.hive_regf.hive_name}."
|
||||||
|
else
|
||||||
|
get_aol_instant_messenger_information
|
||||||
|
end
|
||||||
|
|
||||||
|
elsif ARGV[0] == "get_icq_information"
|
||||||
|
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
|
||||||
|
|
||||||
|
if @hive.hive_regf.hive_name !~ /NTUSER[.]dat/i && @hive.hive_regf.hive_name !~ /SOFTWARE/
|
||||||
|
puts "I need either a SOFTWARE or NTUSER.dat hive, not #{@hive.hive_regf.hive_name}."
|
||||||
|
else
|
||||||
|
get_icq_information
|
||||||
|
end
|
||||||
|
elsif ARGV[0] == "get_ie_information"
|
||||||
|
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
|
||||||
|
|
||||||
|
if @hive.hive_regf.hive_name !~ /NTUSER[.]dat/i
|
||||||
|
puts "I need an NTUSER.dat hive, not #{@hive.hive_regf.hive_name}."
|
||||||
|
else
|
||||||
|
get_ie_information
|
||||||
|
end
|
||||||
|
|
||||||
|
elsif ARGV[0] == "get_msn_messenger_information"
|
||||||
|
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
|
||||||
|
|
||||||
|
if @hive.hive_regf.hive_name !~ /NTUSER[.]dat/i
|
||||||
|
puts "I need an NTUSER.dat hive, not #{@hive.hive_regf.hive_name}."
|
||||||
|
else
|
||||||
|
get_msn_messenger_information
|
||||||
|
end
|
||||||
|
|
||||||
|
elsif ARGV[0] == "get_outlook_information"
|
||||||
|
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
|
||||||
|
|
||||||
|
if @hive.hive_regf.hive_name !~ /NTUSER[.]dat/i
|
||||||
|
puts "I need an NTUSER.dat hive, not #{@hive.hive_regf.hive_name}."
|
||||||
|
else
|
||||||
|
get_outlook_information
|
||||||
|
end
|
||||||
|
|
||||||
|
elsif ARGV[0] == "get_windows_messenger_information"
|
||||||
|
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
|
||||||
|
|
||||||
|
if @hive.hive_regf.hive_name !~ /NTUSER[.]dat/i
|
||||||
|
puts "I need an NTUSER.dat hive, not a #{@hive.hive_regf.hive_name}."
|
||||||
|
else
|
||||||
|
get_windows_messenger_information
|
||||||
|
end
|
||||||
|
|
||||||
|
elsif ARGV[0] == "get_yahoo_messenger_information"
|
||||||
|
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
|
||||||
|
|
||||||
|
if @hive.hive_regf.hive_name !~ /NTUSER[.]dat/i
|
||||||
|
puts "I need an NTUSER.dat hive, not a #{@hive.hive_regf.hive_name}."
|
||||||
|
else
|
||||||
|
get_yahoo_messenger_information
|
||||||
|
end
|
||||||
|
|
||||||
|
elsif ARGV[0] == "get_system_information"
|
||||||
|
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
|
||||||
|
|
||||||
|
if @hive.hive_regf.hive_name !~ /SYSTEM/ && @hive.hive_regf.hive_name !~ /SOFTWARE/
|
||||||
|
puts "I need the SYSTEM or SOFTWARE hive, not #{@hive.hive_regf.hive_name}."
|
||||||
|
else
|
||||||
|
get_system_information
|
||||||
|
end
|
||||||
|
elsif ARGV[0] == "get_networking_information"
|
||||||
|
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
|
||||||
|
|
||||||
|
if @hive.hive_regf.hive_name !~ /SAM/ && @hive.hive_regf.hive_name !~ /SYSTEM/ && @hive.hive_regf.hive_name !~ /NTUSER[.]dat/i
|
||||||
|
puts "I need either a SAM, SYSTEM, or NTUSER.dat hive, not a #{@hive.hive_regf.hive_name}."
|
||||||
|
else
|
||||||
|
get_networking_information
|
||||||
|
end
|
||||||
|
|
||||||
|
elsif ARGV[0] == "get_user_information"
|
||||||
|
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
|
||||||
|
|
||||||
|
if @hive.hive_regf.hive_name !~ /SAM/
|
||||||
|
puts "I need a SAM hive. Not a #{@hive.hive_regf.hive_name}."
|
||||||
|
else
|
||||||
|
get_user_information
|
||||||
|
end
|
||||||
|
elsif ARGV[0] == "get_user_application_information"
|
||||||
|
@hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1])
|
||||||
|
|
||||||
|
if @hive.hive_regf.hive_name !~ /NTUSER[.]dat/i && @hive.hive_regf.hive_name !~ /SOFTWARE/
|
||||||
|
puts "I need either an NTUSER.dat or SOFTWARE hive, not a #{@hive.hive_regf.hive_name}."
|
||||||
|
else
|
||||||
|
get_user_application_information
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue