2012-01-11 00:45:24 +00:00
|
|
|
require_relative "regf"
|
|
|
|
require_relative "nodekey"
|
|
|
|
|
|
|
|
module Rex
|
|
|
|
module Registry
|
|
|
|
|
|
|
|
class Hive
|
2012-02-03 23:01:35 +00:00
|
|
|
attr_accessor :root_key, :hive_regf, :hive_name
|
2012-01-11 00:45:24 +00:00
|
|
|
|
|
|
|
def initialize(hivepath)
|
2012-02-03 23:01:35 +00:00
|
|
|
|
|
|
|
hive_blob = open(hivepath, "rb") { |io| io.read }
|
|
|
|
|
2012-01-11 00:45:24 +00:00
|
|
|
@hive_regf = RegfBlock.new(hive_blob)
|
2012-04-03 02:42:51 +00:00
|
|
|
return nil if !@hive_regf.root_key_offset
|
2012-02-03 23:01:35 +00:00
|
|
|
|
2012-04-03 02:42:51 +00:00
|
|
|
@root_key = NodeKey.new(hive_blob, 0x1000 + @hive_regf.root_key_offset)
|
|
|
|
return nil if !@root_key.lf_record
|
2012-02-03 23:01:35 +00:00
|
|
|
|
2012-04-03 02:33:01 +00:00
|
|
|
keys = []
|
2012-02-03 23:01:35 +00:00
|
|
|
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
|
|
|
|
|
2012-01-11 00:45:24 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def relative_query(path)
|
|
|
|
|
|
|
|
if path == "" || path == "\\"
|
|
|
|
return @root_key
|
|
|
|
end
|
|
|
|
|
|
|
|
current_child = nil
|
|
|
|
paths = path.split("\\")
|
|
|
|
|
2012-01-16 23:54:33 +00:00
|
|
|
return if !@root_key.lf_record
|
2012-02-03 23:01:35 +00:00
|
|
|
|
|
|
|
@root_key.lf_record.children.each do |child|
|
2012-01-11 00:45:24 +00:00
|
|
|
next if child.name.downcase != paths[1].downcase
|
|
|
|
|
|
|
|
current_child = child
|
2012-02-03 23:01:35 +00:00
|
|
|
|
2012-01-11 00:45:24 +00:00
|
|
|
if paths.length == 2
|
|
|
|
current_child.full_path = path
|
|
|
|
return current_child
|
2012-02-03 23:01:35 +00:00
|
|
|
end
|
|
|
|
|
2012-01-11 00:45:24 +00:00
|
|
|
2.upto(paths.length) do |i|
|
|
|
|
|
|
|
|
if i == paths.length
|
|
|
|
current_child.full_path = path
|
|
|
|
return current_child
|
|
|
|
else
|
2012-01-16 23:54:33 +00:00
|
|
|
if current_child.lf_record && current_child.lf_record.children
|
2012-01-11 00:45:24 +00:00
|
|
|
current_child.lf_record.children.each do |c|
|
|
|
|
next if c.name.downcase != paths[i].downcase
|
2012-02-03 23:01:35 +00:00
|
|
|
|
2012-01-11 00:45:24 +00:00
|
|
|
current_child = c
|
2012-02-03 23:01:35 +00:00
|
|
|
|
2012-01-11 00:45:24 +00:00
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-01-16 23:54:33 +00:00
|
|
|
return if !current_child
|
|
|
|
|
2012-01-11 00:45:24 +00:00
|
|
|
current_child.full_path = path
|
|
|
|
return current_child
|
2012-02-03 23:01:35 +00:00
|
|
|
end
|
2012-01-11 00:45:24 +00:00
|
|
|
|
2012-02-03 23:01:35 +00:00
|
|
|
def value_query(path)
|
|
|
|
if path == "" || path == "\\"
|
2012-01-11 00:45:24 +00:00
|
|
|
return nil
|
|
|
|
end
|
2012-02-03 23:01:35 +00:00
|
|
|
|
2012-01-11 00:45:24 +00:00
|
|
|
paths = path.split("\\")
|
2012-02-03 23:01:35 +00:00
|
|
|
|
2012-01-16 23:54:33 +00:00
|
|
|
return if !@root_key.lf_record
|
2012-02-03 23:01:35 +00:00
|
|
|
|
2012-01-11 00:45:24 +00:00
|
|
|
@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|
|
2012-02-03 23:01:35 +00:00
|
|
|
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
|
2012-01-11 00:45:24 +00:00
|
|
|
|
|
|
|
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
|
2012-02-03 23:01:35 +00:00
|
|
|
|
2012-01-11 00:45:24 +00:00
|
|
|
value.full_path = path
|
|
|
|
return value
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|