diff --git a/lib/rex/registry/hive.rb b/lib/rex/registry/hive.rb index c8420bac85..101443b362 100644 --- a/lib/rex/registry/hive.rb +++ b/lib/rex/registry/hive.rb @@ -5,14 +5,35 @@ module Rex module Registry class Hive - attr_accessor :root_key, :hive_regf + attr_accessor :root_key, :hive_regf, :hive_name def initialize(hivepath) - - hive_blob = open(hivepath, "rb") { |io| io.read } + + 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) + + keys = [] + + root_key.lf_record.children.each do |key| + keys << key.name + end + + if keys.include? "LastKnownGoodRecovery" + @hive_name = "SYSTEM" + elsif keys.include? "Microsoft" + @hive_name = "SOFTWARE" + elsif keys.include? "Environment" + @hive_name = "NTUSER.DAT" + elsif keys.include? "SAM" + @hive_name = "SAM" + elsif keys.include? "Policy" + @hive_name = "SECURITY" + else + @hive_name = "UNKNOWN" + end + end def relative_query(path) @@ -25,17 +46,17 @@ class Hive paths = path.split("\\") return if !@root_key.lf_record - - @root_key.lf_record.children.each do |child| + + @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 - + end + 2.upto(paths.length) do |i| if i == paths.length @@ -45,14 +66,13 @@ class Hive if current_child.lf_record && current_child.lf_record.children 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 @@ -60,17 +80,17 @@ class Hive current_child.full_path = path return current_child - end + end - def value_query(path) - if path == "" || path == "\\" + def value_query(path) + if path == "" || path == "\\" return nil end - + paths = path.split("\\") - + return if !@root_key.lf_record - + @root_key.lf_record.children.each do |root_child| next if root_child.name.downcase != paths[1].downcase @@ -81,15 +101,15 @@ class Hive 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 + 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 @@ -97,13 +117,12 @@ class Hive 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 - end end diff --git a/lib/rex/registry/regf.rb b/lib/rex/registry/regf.rb index b135f5ec42..bfb719d95a 100644 --- a/lib/rex/registry/regf.rb +++ b/lib/rex/registry/regf.rb @@ -2,22 +2,20 @@ module Rex module Registry class RegfBlock - - attr_accessor :timestamp, :root_key_offset, :hive_name + + attr_accessor :timestamp, :root_key_offset 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 diff --git a/tools/reg.rb b/tools/reg.rb index 71d4c67bff..dc6815ed61 100755 --- a/tools/reg.rb +++ b/tools/reg.rb @@ -63,7 +63,7 @@ table = Rex::Ui::Text::Table.new( end def get_system_information - if @hive.hive_regf.hive_name =~ /SYSTEM/ + if @hive.hive_name =~ /SYSTEM/ mounted_devices_info_key = @hive.relative_query("\\MountedDevices") current_control_set_key = @hive.value_query('\Select\Default') @@ -82,7 +82,7 @@ def get_system_information print_all_values(mounted_devices_info_key) if mounted_devices_info_key puts "-----------------------------------------" if mounted_devices_info_key - elsif @hive.hive_regf.hive_name =~ /SOFTWARE/ + elsif @hive.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") @@ -161,7 +161,7 @@ end def get_aol_instant_messenger_information - if @hive.hive_regf.hive_name != /NTUSER\.dat/i + if @hive.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") @@ -184,7 +184,7 @@ end def get_msn_messenger_information - if @hive.hive_regf.hive_name =~ /NTUSER\.dat/i + if @hive.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") @@ -196,7 +196,7 @@ def get_msn_messenger_information end def get_windows_messenger_information - if @hive.hive_regf.hive_name =~ /NTUSER\.dat/i + if @hive.hive_name =~ /NTUSER\.dat/i contact_list_information_key = @hive.relative_query("\\Software\\Microsoft\\MessengerService\\ListCache\\.NET Messenger Service") file_transfers_information_key = @hive.relative_query("\\Software\\Microsoft\\Messenger Service - FtReceiveFolder") last_user_information_key = @hive.relative_query("\\Software\\Microsoft\\MessengerService\\ListCache\\.NET Messenger Service - IdentityName") @@ -208,18 +208,18 @@ def get_windows_messenger_information end def get_icq_information - if @hive.hive_regf.hive_name =~ /NTUSER\.dat/i + if @hive.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/ + elsif @hive.hive_name =~ /SOFTWARE/ owner_number_key = @hive.relative_query("\\Software\\Mirabalis\\ICQ\\Owner") print_all(owner_number_key) end end def get_ie_information - if @hive.hive_regf.hive_name =~ /NTUSER\.dat/i + if @hive.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") @@ -242,7 +242,7 @@ def get_ie_information end def get_outlook_information - if @hive.hive_regf.hive_name =~ /NTUSER\.dat/i + if @hive.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) @@ -250,7 +250,7 @@ def get_outlook_information end def get_yahoo_messenger_information - if @hive.hive_regf.hive_name =~ /NTUSER\.dat/i + if @hive.hive_name =~ /NTUSER\.dat/i profiles_key = @hive.relative_query("\\Software\\Yahoo\\Pager\\profiles") print_all(profiles_key) @@ -306,7 +306,7 @@ case ARGV[0] when "query_key" @hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1]) - puts "Hive name: #{@hive.hive_regf.hive_name}" + puts "Hive name: #{@hive.hive_name}" 1.upto(ARGV.length - 2) do |arg| selected = @hive.relative_query(ARGV[arg]) @@ -315,7 +315,7 @@ when "query_key" when "query_value" @hive = Rex::Registry::Hive.new(ARGV[ARGV.length - 1]) - puts "Hive name: #{@hive.hive_regf.hive_name}" + puts "Hive name: #{@hive.hive_name}" 1.upto(ARGV.length - 2) do |i| selected = @hive.value_query(ARGV[i]) @@ -332,8 +332,8 @@ when "query_value" when "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}." + if @hive.hive_name !~ /SYSTEM/ + puts "I need a SYSTEM hive to grab the boot key, not a #{@hive.hive_name}." else get_boot_key end @@ -341,8 +341,8 @@ when "get_boot_key" when "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}" + if @hive.hive_name !~ /SAM/ + puts "I need a SAM hive, not a #{@hive.hive_name}" else dump_creds end @@ -350,8 +350,8 @@ when "dump_creds" when "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}." + if @hive.hive_name !~ /SOFTWARE/ + puts "I need a SOFTWARE hive, not a #{@hive.hive_name}." else list_applications end @@ -359,8 +359,8 @@ when "list_applications" when "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}." + if @hive.hive_name !~ /SYSTEM/ + puts "I need a SYSTEM hive, not a #{@hive.hive_name}." else list_drivers end @@ -372,9 +372,9 @@ when "get_everything" @hive = Rex::Registry::Hive.new(ARGV[1] + "/" + file) next if !@hive.hive_regf - next if !@hive.hive_regf.hive_name + next if !@hive.hive_name - case @hive.hive_regf.hive_name + case @hive.hive_name when /SYSTEM/ @@ -431,8 +431,8 @@ end when "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}." + if @hive.hive_name !~ /NTUSER\.DAT/i + puts "I need the NTUSER.dat hive, not #{@hive.hive_name}." else get_aol_instant_messenger_information end @@ -440,8 +440,8 @@ when "get_aol_instant_messenger_information" when "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}." + if @hive.hive_name !~ /NTUSER\.dat/i && @hive.hive_name !~ /SOFTWARE/ + puts "I need either a SOFTWARE or NTUSER.dat hive, not #{@hive.hive_name}." else get_icq_information end @@ -449,8 +449,8 @@ when "get_icq_information" when "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}." + if @hive.hive_name !~ /NTUSER\.dat/i + puts "I need an NTUSER.dat hive, not #{@hive.hive_name}." else get_ie_information end @@ -458,8 +458,8 @@ when "get_ie_information" when "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}." + if @hive.hive_name !~ /NTUSER\.dat/i + puts "I need an NTUSER.dat hive, not #{@hive.hive_name}." else get_msn_messenger_information end @@ -467,8 +467,8 @@ when "get_msn_messenger_information" when "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}." + if @hive.hive_name !~ /NTUSER\.dat/i + puts "I need an NTUSER.dat hive, not #{@hive.hive_name}." else get_outlook_information end @@ -476,8 +476,8 @@ when "get_outlook_information" when "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}." + if @hive.hive_name !~ /NTUSER\.dat/i + puts "I need an NTUSER.dat hive, not a #{@hive.hive_name}." else get_windows_messenger_information end @@ -485,8 +485,8 @@ when "get_windows_messenger_information" when "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}." + if @hive.hive_name !~ /NTUSER\.dat/i + puts "I need an NTUSER.dat hive, not a #{@hive.hive_name}." else get_yahoo_messenger_information end @@ -494,8 +494,8 @@ when "get_yahoo_messenger_information" when "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}." + if @hive.hive_name !~ /SYSTEM/ && @hive.hive_name !~ /SOFTWARE/ + puts "I need the SYSTEM or SOFTWARE hive, not #{@hive.hive_name}." else get_system_information end @@ -503,8 +503,8 @@ when "get_system_information" when "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}." + if @hive.hive_name !~ /SAM/ && @hive.hive_name !~ /SYSTEM/ && @hive.hive_name !~ /NTUSER\.dat/i + puts "I need either a SAM, SYSTEM, or NTUSER.dat hive, not a #{@hive.hive_name}." else get_networking_information end @@ -512,8 +512,8 @@ when "get_networking_information" when "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}." + if @hive.hive_name !~ /SAM/ + puts "I need a SAM hive. Not a #{@hive.hive_name}." else get_user_information end @@ -521,12 +521,12 @@ when "get_user_information" when "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}." + if @hive.hive_name !~ /NTUSER\.dat/i && @hive.hive_name !~ /SOFTWARE/ + puts "I need either an NTUSER.dat or SOFTWARE hive, not a #{@hive.hive_name}." else get_user_application_information end else puts "Sorry invalid command, try with \"help\"" -end \ No newline at end of file +end