Class: FleeceHives

Inherits:
Object
  • Object
show all
Defined in:
lib/metadata/util/win32/fleece_hives.rb

Class Method Summary collapse

Class Method Details

.addElement(xmlNode, nodeName, regPath, xmlCol, makeCopy = false) ⇒ Object



202
203
204
205
206
207
208
209
210
211
# File 'lib/metadata/util/win32/fleece_hives.rb', line 202

def self.addElement(xmlNode, nodeName, regPath, xmlCol, makeCopy = false)
  eNode = MIQRexml.findElement(nodeName, xmlCol.root)
  eNew =  MIQRexml.findRegElement(regPath, xmlNode)

  if makeCopy
    eNode << MiqXml.createDoc(eNew.to_s).root if eNew
  else
    eNode << eNew if eNew
  end
end

.addIconData(icon_element, peData, iconNode) ⇒ Object



164
165
166
167
168
169
170
# File 'lib/metadata/util/win32/fleece_hives.rb', line 164

def self.addIconData(icon_element, peData, iconNode)
  $log.debug "Adding application image: [#{icon_element}]"
  # Copy this element into another branch of the xml to store icon binary data
  newEle = iconNode.add_element(icon_element.name, icon_element.attributes)
  # Encode binary icon data as an element
  newEle.add_element("binary", {"type" => "icon"}).add_text(MIQEncode.encode(peData.icons[0]))
end

.collect_hive_data(xmlNode, hiveName, regHnd, xmlCol, fs) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/metadata/util/win32/fleece_hives.rb', line 8

def self.collect_hive_data(xmlNode, hiveName, regHnd, xmlCol, fs)
  # SAM hive
  if hiveName.downcase == "sam"
    scanFor = [
      ["SAM", "HKEY_LOCAL_MACHINE\\SAM\\SAM"],
    ]
  # SYSTEM hive
  elsif hiveName.downcase == "system"
    # Preprocess some keys by making copies of them so they are not lost during processServices
    scanFor = [
      # The following are used for system category
      ["system/network", "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"],
    ]
    scanFor.each { |i| addElement(xmlNode.root, i[0], i[1], xmlCol, true) }

    processServices(xmlNode, hiveName, regHnd, xmlCol)

    scanFor = [
      ["system/os", "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ComputerName"],
      ["system/os", "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"],
      ["system/os", "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\ProductOptions"],
    ]
  # SOFTWARE hive
  elsif hiveName.downcase == "software"
    scanFor = [
      # The following are used for the system category
      ["system/network", "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards"],

      # The following are used for the software category
      ["software", "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix"],
      #                 ["software", "HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\Installer\\Products"],
      ["software", "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData"],
      ["software", "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"],
      ["software", "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths"],
      #                 ["software", "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"],
      #                 ["software", "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce"],
      #                 ["software", "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnceEx"],
    ]

    # The following are for the system/os category, but I can't remove it for
    #   software because it screws up the product keys, due to the way product
    #   keys are precollected from this key
    eNode = MIQRexml.findElement("system/os", xmlCol.root)
    eNode = eNode.add_element("key", "keyname" => "CurrentVersion", "fqname" => "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion")
    currentOS_ele = regHnd.open(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion")
    currentOS_ele.each_element_with_attribute('name') { |e| eNode << e } unless currentOS_ele.nil?
  end

  scanFor.each { |i| addElement(xmlNode.root, i[0], i[1], xmlCol) } unless scanFor.nil?

  case hiveName.downcase
  when "software"
    begin
      postProcessApps(xmlCol, fs)
    rescue Exception => err
      $log.warn "Exception during Post-process Applications: [#{err}]"
    end
    begin
      collectProductKeys(xmlNode.root, xmlCol, regHnd)
    rescue => err
      $log.warn "Exception during Collect Product Keys: [#{err}]"
    end
  end
end

.collectProductKeys(_xml, xmlCol, regHnd) ⇒ Object



95
96
97
98
99
100
101
102
103
# File 'lib/metadata/util/win32/fleece_hives.rb', line 95

def self.collectProductKeys(_xml, xmlCol, regHnd)
  prodKeys = MIQRexml.findElement("software/productkeys", xmlCol.root)
  regHnd.digitalProductKeys.each do |e|
    if e.parent && e.parent.attributes['fqname'] && e.parent.attributes['fqname'].downcase != 'software\\microsoft\\windows nt\\currentversion'
      pk = productKeys(e)
      prodKeys << pk if pk
    end
  end
end

.postProcessApps(xmlCol, fs) ⇒ Object



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/metadata/util/win32/fleece_hives.rb', line 128

def self.postProcessApps(xmlCol, fs)
  appPath = MIQRexml.findRegElement("software/App Paths", xmlCol.root)
  return if appPath.nil?
  # The icon sections below will need to be uncommented when we are ready to start
  # implementing application image uploading.
  # iconNode = MIQRexml.findElement("Applications/images", xmlCol.root)
  appPath.each_element do|e|
    e.each_element_with_attribute('name', '(Default)', max = 1) do|e1|
      begin
        fileName = e1.text
        fileName.tr!("\\", "/")
        fileName = fileName[1..-2] if fileName[0, 1] == "\"" && fileName[-1, 1] == "\""

        #          $log.warn "Processing App - [#{fileName}]"
        fh = fs.fileOpen(fileName)
        vi = File.getVersionInfo(fh)
        # Access application icons
        # peData = PEheader.new(fh)
        fh.close
        #          $log.warn "Processing App - [#{fileName}] - VI length:[#{vi.length}]"
        if vi.length > 0
          e2 = e.add_element('versioninfo')
          vi.each_pair { |k, v| e2.add_element("value", "name" => k).add_text(v.to_s) }
        end

      #     if peData.icons.length > 0
      #     ie = e1.add_element("image",{"file"=>fileName, "count"=>peData.icons.length.to_s, "md5"=>Digest::MD5.hexdigest(peData.icons[0])})
      #     addIconData(ie, peData, iconNode)
      #     end
      rescue Exception => e
        #          $log.warn "postProcessApps - [#{fileName}] - error [#{e.to_s}]"
      end
    end
  end
end

.processServices(xmlNode, _hiveName, _regHnd, xmlCol) ⇒ Object



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/metadata/util/win32/fleece_hives.rb', line 172

def self.processServices(xmlNode, _hiveName, _regHnd, xmlCol)
  eServices = MIQRexml.findElement("services", xmlCol.root)

  eSvcList = MIQRexml.findRegElement("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services", xmlNode.root)
  if eSvcList
    eSvcList.each_element do |e|
      next if e.name != "key"

      # Remove child elements's that have children.  This data is not being processed on the server
      # and adds a lot of extract size to the xml and time for tagging.
      e.each_element { |e1| e1.remove! if e1.name == 'key' }

      # Create one element referring to the type by name
      serviceType = MIQRexml.getChildAttrib(e, "Type", 1).to_i
      e2 = e.add_element("value", "name" => "TypeName", "type" => "REG_SZ")
      e2.text = if (serviceType & 0x00000001) > 0
                  "kernel"
                elsif (serviceType & 0x00000002) > 0
                  "filesystem"
                elsif ((serviceType & 0x00000010) > 0) || ((serviceType & 0x00000020) > 0)
                  "win32_service"
                else
                  "misc"
                end

      eServices << e
    end
  end
end

.productKeys(xmlNode) ⇒ Object



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/metadata/util/win32/fleece_hives.rb', line 105

def self.productKeys(xmlNode)
  p = xmlNode.parent

  newEle = xmlNode.get_path
  t = nil
  newEle.each_recursive { |e1| t = e1 }

  p.each_element do|e|
    if e.attributes['name'] && e.attributes['name'].downcase.include?("product")
      x = e.shallow_copy
      x.text = e.text
      t << x
    end
  end
  ret = nil
  begin
    ret = newEle.find_first("//*/key[@keyname=\"Microsoft\"]")
    ret = ret.elements[1] if ret
  rescue => e
  end
  ret
end

.scanRegistry(_c, fs, hives = ["sam", nil, "security", nil, "default", nil, "system", nil, "software", nil]) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/metadata/util/win32/fleece_hives.rb', line 73

def self.scanRegistry(_c, fs, hives = ["sam", nil, "security", nil, "default", nil, "system", nil, "software", nil])
  xmlCol = MiqXml.createDoc("<miq/>")

  hives.each_slice(2) do |hive, filter|
    regHnd = RemoteRegistry.new(fs)

    $log.debug "Loading registry hive [#{hive}]..."
    xml = regHnd.loadHive(hive, filter)
    $log.debug "Loading registry hive complete."

    # File.open("C:/temp/reg_extract_full_#{c}.xml","w"){|f| xml.write(f,0)}

    # Scrap details from this hive
    $log.debug "Fleecing registry data."
    FleeceHives.collect_hive_data(xml, hive, regHnd, xmlCol, fs)
    $log.debug "Fleecing complete."
  end

  # File.open("C:/temp/reg_extract_#{c}.xml","w"){|f| xmlCol.write(f,0)}
  xmlCol
end