Autopsy  4.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
ExtractRegistry.java
Go to the documentation of this file.
1  /*
2  *
3  * Autopsy Forensic Browser
4  *
5  * Copyright 2012-2014 Basis Technology Corp.
6  *
7  * Copyright 2012 42six Solutions.
8  * Contact: aebadirad <at> 42six <dot> com
9  * Project Contact/Architect: carrier <at> sleuthkit <dot> org
10  *
11  * Licensed under the Apache License, Version 2.0 (the "License");
12  * you may not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  *
15  * http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  */
23 package org.sleuthkit.autopsy.recentactivity;
24 
25 import java.io.*;
26 import java.io.File;
27 import java.text.ParseException;
28 import java.text.SimpleDateFormat;
29 import java.util.*;
30 import java.util.logging.Level;
31 import javax.xml.parsers.DocumentBuilder;
32 import javax.xml.parsers.DocumentBuilderFactory;
33 import javax.xml.parsers.ParserConfigurationException;
34 import org.openide.modules.InstalledFileLocator;
35 import org.openide.util.NbBundle;
43 import org.sleuthkit.datamodel.*;
44 import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
45 import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
46 import org.w3c.dom.Document;
47 import org.w3c.dom.Element;
48 import org.w3c.dom.Node;
49 import org.w3c.dom.NodeList;
50 import org.xml.sax.InputSource;
51 import org.xml.sax.SAXException;
52 
59 class ExtractRegistry extends Extract {
60 
61  private Logger logger = Logger.getLogger(this.getClass().getName());
62  private String RR_PATH;
63  private String RR_FULL_PATH;
64  private String rrHome; // The current version of RegRipper need to be run from its own directory
65  private String rrFullHome;
66  private boolean rrFound = false; // true if we found the Autopsy-specific version of regripper
67  private boolean rrFullFound = false; // true if we found the full version of regripper
68  private Content dataSource;
69  private IngestJobContext context;
70  final private static UsbDeviceIdMapper usbMapper = new UsbDeviceIdMapper();
71 
72  ExtractRegistry() {
73  moduleName = NbBundle.getMessage(ExtractIE.class, "ExtractRegistry.moduleName.text");
74  final File rrRoot = InstalledFileLocator.getDefault().locate("rr", ExtractRegistry.class.getPackage().getName(), false); //NON-NLS
75  if (rrRoot == null) {
76  logger.log(Level.SEVERE, "RegRipper not found"); //NON-NLS
77  rrFound = false;
78  return;
79  } else {
80  rrFound = true;
81  }
82 
83  rrHome = rrRoot.getAbsolutePath();
84  logger.log(Level.INFO, "RegRipper home: {0}", rrHome); //NON-NLS
85 
86  if (PlatformUtil.isWindowsOS()) {
87  RR_PATH = rrHome + File.separator + "rip.exe"; //NON-NLS
88  } else {
89  RR_PATH = "perl " + rrHome + File.separator + "rip.pl"; //NON-NLS
90  }
91 
92  final File rrFullRoot = InstalledFileLocator.getDefault().locate("rr-full", ExtractRegistry.class.getPackage().getName(), false); //NON-NLS
93  if (rrFullRoot == null) {
94  logger.log(Level.SEVERE, "RegRipper Full not found"); //NON-NLS
95  rrFullFound = false;
96  } else {
97  rrFullFound = true;
98  }
99 
100  if (rrFullRoot != null) {
101  rrFullHome = rrFullRoot.getAbsolutePath();
102  } else {
103  rrFullHome = "";
104  }
105  logger.log(Level.INFO, "RegRipper Full home: {0}", rrFullHome); //NON-NLS
106 
107  if (PlatformUtil.isWindowsOS()) {
108  RR_FULL_PATH = rrFullHome + File.separator + "rip.exe"; //NON-NLS
109  } else {
110  RR_FULL_PATH = "perl " + rrFullHome + File.separator + "rip.pl"; //NON-NLS
111  }
112  }
113 
117  private List<AbstractFile> findRegistryFiles() {
118  List<AbstractFile> allRegistryFiles = new ArrayList<>();
119  org.sleuthkit.autopsy.casemodule.services.FileManager fileManager = currentCase.getServices().getFileManager();
120 
121  // find the user-specific ntuser-dat files
122  try {
123  allRegistryFiles.addAll(fileManager.findFiles(dataSource, "ntuser.dat")); //NON-NLS
124  } catch (TskCoreException ex) {
125  logger.log(Level.WARNING, "Error fetching 'ntuser.dat' file."); //NON-NLS
126  }
127 
128  // find the system hives'
129  String[] regFileNames = new String[]{"system", "software", "security", "sam"}; //NON-NLS
130  for (String regFileName : regFileNames) {
131  try {
132  allRegistryFiles.addAll(fileManager.findFiles(dataSource, regFileName, "/system32/config")); //NON-NLS
133  } catch (TskCoreException ex) {
134  String msg = NbBundle.getMessage(this.getClass(),
135  "ExtractRegistry.findRegFiles.errMsg.errReadingFile", regFileName);
136  logger.log(Level.WARNING, msg);
137  this.addErrorMessage(this.getName() + ": " + msg);
138  }
139  }
140  return allRegistryFiles;
141  }
142 
147  private void analyzeRegistryFiles() {
148  List<AbstractFile> allRegistryFiles = findRegistryFiles();
149 
150  // open the log file
151  FileWriter logFile = null;
152  try {
153  logFile = new FileWriter(RAImageIngestModule.getRAOutputPath(currentCase, "reg") + File.separator + "regripper-info.txt"); //NON-NLS
154  } catch (IOException ex) {
155  logger.log(Level.SEVERE, null, ex);
156  }
157 
158  int j = 0;
159  for (AbstractFile regFile : allRegistryFiles) {
160  String regFileName = regFile.getName();
161  String regFileNameLocal = RAImageIngestModule.getRATempPath(currentCase, "reg") + File.separator + regFileName;
162  String outputPathBase = RAImageIngestModule.getRAOutputPath(currentCase, "reg") + File.separator + regFileName + "-regripper-" + Integer.toString(j++); //NON-NLS
163  File regFileNameLocalFile = new File(regFileNameLocal);
164  try {
165  ContentUtils.writeToFile(regFile, regFileNameLocalFile);
166  } catch (IOException ex) {
167  logger.log(Level.SEVERE, "Error writing the temp registry file. {0}", ex); //NON-NLS
168  this.addErrorMessage(
169  NbBundle.getMessage(this.getClass(), "ExtractRegistry.analyzeRegFiles.errMsg.errWritingTemp",
170  this.getName(), regFileName));
171  continue;
172  }
173 
174  if (context.dataSourceIngestIsCancelled()) {
175  break;
176  }
177 
178  try {
179  if (logFile != null) {
180  logFile.write(Integer.toString(j - 1) + "\t" + regFile.getUniquePath() + "\n");
181  }
182  } catch (TskCoreException | IOException ex) {
183  logger.log(Level.SEVERE, null, ex);
184  }
185 
186  logger.log(Level.INFO, "{0}- Now getting registry information from {1}", new Object[]{moduleName, regFileNameLocal}); //NON-NLS
187  RegOutputFiles regOutputFiles = ripRegistryFile(regFileNameLocal, outputPathBase);
188  if (context.dataSourceIngestIsCancelled()) {
189  break;
190  }
191 
192  // parse the autopsy-specific output
193  if (regOutputFiles.autopsyPlugins.isEmpty() == false) {
194  if (parseAutopsyPluginOutput(regOutputFiles.autopsyPlugins, regFile) == false) {
195  this.addErrorMessage(
196  NbBundle.getMessage(this.getClass(), "ExtractRegistry.analyzeRegFiles.failedParsingResults",
197  this.getName(), regFileName));
198  }
199  }
200 
201  // create a report for the full output
202  if (regOutputFiles.fullPlugins.isEmpty() == false) {
203  try {
204  currentCase.addReport(regOutputFiles.fullPlugins, NbBundle.getMessage(this.getClass(), "ExtractRegistry.parentModuleName.noSpace"), "RegRipper " + regFile.getUniquePath()); //NON-NLS
205  } catch (TskCoreException e) {
206  this.addErrorMessage("Error adding regripper output as Autopsy report: " + e.getLocalizedMessage()); //NON-NLS
207  }
208  }
209 
210  // delete the hive
211  regFileNameLocalFile.delete();
212  }
213 
214  try {
215  if (logFile != null) {
216  logFile.close();
217  }
218  } catch (IOException ex) {
219  logger.log(Level.SEVERE, null, ex);
220  }
221  }
222 
223  private class RegOutputFiles {
224 
225  public String autopsyPlugins = "";
226  public String fullPlugins = "";
227  }
228 
236  private RegOutputFiles ripRegistryFile(String regFilePath, String outFilePathBase) {
237  String autopsyType = ""; // Type argument for rr for autopsy-specific modules
238  String fullType; // Type argument for rr for full set of modules
239 
240  RegOutputFiles regOutputFiles = new RegOutputFiles();
241 
242  if (regFilePath.toLowerCase().contains("system")) { //NON-NLS
243  autopsyType = "autopsysystem"; //NON-NLS
244  fullType = "system"; //NON-NLS
245  } else if (regFilePath.toLowerCase().contains("software")) { //NON-NLS
246  autopsyType = "autopsysoftware"; //NON-NLS
247  fullType = "software"; //NON-NLS
248  } else if (regFilePath.toLowerCase().contains("ntuser")) { //NON-NLS
249  autopsyType = "autopsyntuser"; //NON-NLS
250  fullType = "ntuser"; //NON-NLS
251  } else if (regFilePath.toLowerCase().contains("sam")) { //NON-NLS
252  fullType = "sam"; //NON-NLS
253  } else if (regFilePath.toLowerCase().contains("security")) { //NON-NLS
254  fullType = "security"; //NON-NLS
255  } else {
256  return regOutputFiles;
257  }
258 
259  // run the autopsy-specific set of modules
260  if (!autopsyType.isEmpty() && rrFound) {
261  regOutputFiles.autopsyPlugins = outFilePathBase + "-autopsy.txt"; //NON-NLS
262  String errFilePath = outFilePathBase + "-autopsy.err.txt"; //NON-NLS
263  logger.log(Level.INFO, "Writing RegRipper results to: {0}", regOutputFiles.autopsyPlugins); //NON-NLS
264  executeRegRipper(RR_PATH, rrHome, regFilePath, autopsyType, regOutputFiles.autopsyPlugins, errFilePath);
265  }
266  if (context.dataSourceIngestIsCancelled()) {
267  return regOutputFiles;
268  }
269 
270  // run the full set of rr modules
271  if (!fullType.isEmpty() && rrFullFound) {
272  regOutputFiles.fullPlugins = outFilePathBase + "-full.txt"; //NON-NLS
273  String errFilePath = outFilePathBase + "-full.err.txt"; //NON-NLS
274  logger.log(Level.INFO, "Writing Full RegRipper results to: {0}", regOutputFiles.fullPlugins); //NON-NLS
275  executeRegRipper(RR_FULL_PATH, rrFullHome, regFilePath, fullType, regOutputFiles.fullPlugins, errFilePath);
276  }
277  return regOutputFiles;
278  }
279 
280  private void executeRegRipper(String regRipperPath, String regRipperHomeDir, String hiveFilePath, String hiveFileType, String outputFile, String errFile) {
281  try {
282  logger.log(Level.INFO, "Writing RegRipper results to: {0}", outputFile); //NON-NLS
283  List<String> commandLine = new ArrayList<>();
284  commandLine.add(regRipperPath);
285  commandLine.add("-r"); //NON-NLS
286  commandLine.add(hiveFilePath);
287  commandLine.add("-f"); //NON-NLS
288  commandLine.add(hiveFileType);
289 
290  ProcessBuilder processBuilder = new ProcessBuilder(commandLine);
291  processBuilder.directory(new File(regRipperHomeDir)); // RegRipper 2.8 has to be run from its own directory
292  processBuilder.redirectOutput(new File(outputFile));
293  processBuilder.redirectError(new File(errFile));
294  ExecUtil.execute(processBuilder, new DataSourceIngestModuleProcessTerminator(context));
295  } catch (IOException ex) {
296  logger.log(Level.SEVERE, "Unable to run RegRipper", ex); //NON-NLS
297  this.addErrorMessage(NbBundle.getMessage(this.getClass(), "ExtractRegistry.execRegRip.errMsg.failedAnalyzeRegFile", this.getName()));
298  }
299  }
300 
301  // @@@ VERIFY that we are doing the right thing when we parse multiple NTUSER.DAT
310  private boolean parseAutopsyPluginOutput(String regFilePath, AbstractFile regFile) {
311  FileInputStream fstream = null;
312  try {
313  SleuthkitCase tempDb = currentCase.getSleuthkitCase();
314 
315  // Read the file in and create a Document and elements
316  File regfile = new File(regFilePath);
317  fstream = new FileInputStream(regfile);
318 
319  String regString = new Scanner(fstream, "UTF-8").useDelimiter("\\Z").next(); //NON-NLS
320  String startdoc = "<?xml version=\"1.0\"?><document>"; //NON-NLS
321  String result = regString.replaceAll("----------------------------------------", "");
322  result = result.replaceAll("\\n", ""); //NON-NLS
323  result = result.replaceAll("\\r", ""); //NON-NLS
324  result = result.replaceAll("'", "&apos;"); //NON-NLS
325  result = result.replaceAll("&", "&amp;"); //NON-NLS
326  result = result.replace('\0', ' '); // NON-NLS
327  String enddoc = "</document>"; //NON-NLS
328  String stringdoc = startdoc + result + enddoc;
329  DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
330  Document doc = builder.parse(new InputSource(new StringReader(stringdoc)));
331 
332  // cycle through the elements in the doc
333  Element oroot = doc.getDocumentElement();
334  NodeList children = oroot.getChildNodes();
335  int len = children.getLength();
336  for (int i = 0; i < len; i++) {
337  Element tempnode = (Element) children.item(i);
338 
339  String dataType = tempnode.getNodeName();
340 
341  NodeList timenodes = tempnode.getElementsByTagName("mtime"); //NON-NLS
342  Long mtime = null;
343  if (timenodes.getLength() > 0) {
344  Element timenode = (Element) timenodes.item(0);
345  String etime = timenode.getTextContent();
346  try {
347  Long epochtime = new SimpleDateFormat("EEE MMM d HH:mm:ss yyyy").parse(etime).getTime();
348  mtime = epochtime;
349  String Tempdate = mtime.toString();
350  mtime = Long.valueOf(Tempdate) / 1000;
351  } catch (ParseException ex) {
352  logger.log(Level.WARNING, "Failed to parse epoch time when parsing the registry."); //NON-NLS
353  }
354  }
355 
356  NodeList artroots = tempnode.getElementsByTagName("artifacts"); //NON-NLS
357  if (artroots.getLength() == 0) {
358  // If there isn't an artifact node, skip this entry
359  continue;
360  }
361 
362  Element artroot = (Element) artroots.item(0);
363  NodeList myartlist = artroot.getChildNodes();
364  String parentModuleName = NbBundle.getMessage(this.getClass(), "ExtractRegistry.parentModuleName.noSpace");
365  String winver = "";
366 
367  // If all artifact nodes should really go under one Blackboard artifact, need to process it differently
368  if (dataType.equals("WinVersion")) { //NON-NLS
369 
370  String version = "";
371  String systemRoot = "";
372  String productId = "";
373  String regOwner = "";
374  String regOrg = "";
375  Long installtime = null;
376 
377  for (int j = 0; j < myartlist.getLength(); j++) {
378  Node artchild = myartlist.item(j);
379  // If it has attributes, then it is an Element (based off API)
380  if (artchild.hasAttributes()) {
381  Element artnode = (Element) artchild;
382 
383  String value = artnode.getTextContent().trim();
384  String name = artnode.getAttribute("name"); //NON-NLS
385 
386  if (name.equals("ProductName")) { // NON-NLS
387  version = value;
388  } else if (name.equals("CSDVersion")) { // NON-NLS
389  // This is dependant on the fact that ProductName shows up first in the module output
390  version = version + " " + value;
391  } else if (name.equals("SystemRoot")) { //NON-NLS
392  systemRoot = value;
393  } else if (name.equals("ProductId")) { //NON-NLS
394  productId = value;
395  } else if (name.equals("RegisteredOwner")) { //NON-NLS
396  regOwner = value;
397  } else if (name.equals("RegisteredOrganization")) { //NON-NLS
398  regOrg = value;
399  } else if (name.equals("InstallDate")) { //NON-NLS
400  try {
401  Long epochtime = new SimpleDateFormat("EEE MMM d HH:mm:ss yyyy").parse(value).getTime();
402  installtime = epochtime;
403  String Tempdate = installtime.toString();
404  installtime = Long.valueOf(Tempdate) / 1000;
405  } catch (ParseException e) {
406  logger.log(Level.SEVERE, "RegRipper::Conversion on DateTime -> ", e); //NON-NLS
407  }
408  }
409  }
410  }
411 
412  try {
413  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
414  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, version));
415  if (installtime != null) {
416  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, installtime));
417  }
418  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH, parentModuleName, systemRoot));
419  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PRODUCT_ID, parentModuleName, productId));
420  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_OWNER, parentModuleName, regOwner));
421  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ORGANIZATION, parentModuleName, regOrg));
422 
423  // Check if there is already an OS_INFO artifact for this file, and add to that if possible.
424  ArrayList<BlackboardArtifact> results = tempDb.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId());
425  if (results.isEmpty()) {
426  BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO);
427  bbart.addAttributes(bbattributes);
428 
429  // index the artifact for keyword search
430  this.indexArtifact(bbart);
431  } else {
432  results.get(0).addAttributes(bbattributes);
433  }
434 
435  } catch (TskCoreException ex) {
436  logger.log(Level.SEVERE, "Error adding installed program artifact to blackboard."); //NON-NLS
437  }
438  } else if (dataType.equals("Profiler")) { // NON-NLS
439 
440  String os = "";
441  String procArch = "";
442  String procId = "";
443  String tempDir = "";
444 
445  for (int j = 0; j < myartlist.getLength(); j++) {
446  Node artchild = myartlist.item(j);
447  // If it has attributes, then it is an Element (based off API)
448  if (artchild.hasAttributes()) {
449  Element artnode = (Element) artchild;
450 
451  String value = artnode.getTextContent().trim();
452  String name = artnode.getAttribute("name"); //NON-NLS
453 
454  if (name.equals("OS")) { // NON-NLS
455  os = value;
456  } else if (name.equals("PROCESSOR_ARCHITECTURE")) { // NON-NLS
457  procArch = value;
458  } else if (name.equals("PROCESSOR_IDENTIFIER")) { //NON-NLS
459  procId = value;
460  } else if (name.equals("TEMP")) { //NON-NLS
461  tempDir = value;
462  }
463  }
464  }
465 
466  try {
467  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
468  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VERSION, parentModuleName, os));
469  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROCESSOR_ARCHITECTURE, parentModuleName, procArch));
470  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TEMP_DIR, parentModuleName, tempDir));
471 
472  // Check if there is already an OS_INFO artifact for this file and add to that if possible
473  ArrayList<BlackboardArtifact> results = tempDb.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId());
474  if (results.isEmpty()) {
475  BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO);
476  bbart.addAttributes(bbattributes);
477 
478  // index the artifact for keyword search
479  this.indexArtifact(bbart);
480  } else {
481  results.get(0).addAttributes(bbattributes);
482  }
483  } catch (TskCoreException ex) {
484  logger.log(Level.SEVERE, "Error adding os info artifact to blackboard."); //NON-NLS
485  }
486  } else if (dataType.equals("CompName")) { // NON-NLS
487 
488  String compName = "";
489  String domain = "";
490 
491  for (int j = 0; j < myartlist.getLength(); j++) {
492  Node artchild = myartlist.item(j);
493  // If it has attributes, then it is an Element (based off API)
494  if (artchild.hasAttributes()) {
495  Element artnode = (Element) artchild;
496 
497  String value = artnode.getTextContent().trim();
498  String name = artnode.getAttribute("name"); //NON-NLS
499 
500  if (name.equals("ComputerName")) { // NON-NLS
501  compName = value;
502  } else if (name.equals("Domain")) { // NON-NLS
503  domain = value;
504  }
505  }
506  }
507 
508  try {
509  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
510  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, parentModuleName, compName));
511  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN, parentModuleName, domain));
512 
513  // Check if there is already an OS_INFO artifact for this file and add to that if possible
514  ArrayList<BlackboardArtifact> results = tempDb.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId());
515  if (results.isEmpty()) {
516  BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO);
517  bbart.addAttributes(bbattributes);
518 
519  // index the artifact for keyword search
520  this.indexArtifact(bbart);
521  } else {
522  results.get(0).addAttributes(bbattributes);
523  }
524  } catch (TskCoreException ex) {
525  logger.log(Level.SEVERE, "Error adding os info artifact to blackboard."); //NON-NLS
526  }
527  } else {
528  for (int j = 0; j < myartlist.getLength(); j++) {
529  Node artchild = myartlist.item(j);
530  // If it has attributes, then it is an Element (based off API)
531  if (artchild.hasAttributes()) {
532  Element artnode = (Element) artchild;
533 
534  String value = artnode.getTextContent().trim();
535  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
536 
537  switch (dataType) {
538  case "recentdocs": //NON-NLS
539  // BlackboardArtifact bbart = tempDb.getContentById(orgId).newArtifact(ARTIFACT_TYPE.TSK_RECENT_OBJECT);
540  // bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID(), "RecentActivity", dataType, mtime));
541  // bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity", dataType, mtimeItem));
542  // bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE.getTypeID(), "RecentActivity", dataType, value));
543  // bbart.addAttributes(bbattributes);
544  // @@@ BC: Why are we ignoring this...
545  break;
546  case "usb": //NON-NLS
547  try {
548  Long usbMtime = Long.parseLong(artnode.getAttribute("mtime")); //NON-NLS
549  usbMtime = Long.valueOf(usbMtime.toString());
550 
551  BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_DEVICE_ATTACHED);
552  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, usbMtime));
553  String dev = artnode.getAttribute("dev"); //NON-NLS
554  String make = "";
555  String model = dev;
556  if (dev.toLowerCase().contains("vid")) { //NON-NLS
557  USBInfo info = usbMapper.parseAndLookup(dev);
558  if (info.getVendor() != null) {
559  make = info.getVendor();
560  }
561  if (info.getProduct() != null) {
562  model = info.getProduct();
563  }
564  }
565  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_MAKE, parentModuleName, make));
566  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL, parentModuleName, model));
567  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_ID, parentModuleName, value));
568  bbart.addAttributes(bbattributes);
569 
570  // index the artifact for keyword search
571  this.indexArtifact(bbart);
572  } catch (TskCoreException ex) {
573  logger.log(Level.SEVERE, "Error adding device attached artifact to blackboard."); //NON-NLS
574  }
575  break;
576  case "uninstall": //NON-NLS
577  Long itemMtime = null;
578  try {
579  Long epochtime = new SimpleDateFormat("EEE MMM d HH:mm:ss yyyy").parse(artnode.getAttribute("mtime")).getTime(); //NON-NLS
580  itemMtime = epochtime;
581  itemMtime = itemMtime / 1000;
582  } catch (ParseException e) {
583  logger.log(Level.WARNING, "Failed to parse epoch time for installed program artifact."); //NON-NLS
584  }
585 
586  try {
587  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, value));
588  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, itemMtime));
589  BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_INSTALLED_PROG);
590  bbart.addAttributes(bbattributes);
591 
592  // index the artifact for keyword search
593  this.indexArtifact(bbart);
594  } catch (TskCoreException ex) {
595  logger.log(Level.SEVERE, "Error adding installed program artifact to blackboard."); //NON-NLS
596  }
597  break;
598  case "office": //NON-NLS
599  String officeName = artnode.getAttribute("name"); //NON-NLS
600 
601  try {
602  BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_RECENT_OBJECT);
603  // @@@ BC: Consider removing this after some more testing. It looks like an Mtime associated with the root key and not the individual item
604  if (mtime != null) {
605  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED, parentModuleName, mtime));
606  }
607  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, parentModuleName, officeName));
608  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE, parentModuleName, value));
609  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, artnode.getNodeName()));
610  bbart.addAttributes(bbattributes);
611 
612  // index the artifact for keyword search
613  this.indexArtifact(bbart);
614  } catch (TskCoreException ex) {
615  logger.log(Level.SEVERE, "Error adding recent object artifact to blackboard."); //NON-NLS
616  }
617  break;
618 
619  case "ProcessorArchitecture": //NON-NLS
620  // Architecture is now included under Profiler
621  //try {
622  // String processorArchitecture = value;
623  // if (processorArchitecture.equals("AMD64"))
624  // processorArchitecture = "x86-64";
625 
626  // BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO);
627  // bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROCESSOR_ARCHITECTURE.getTypeID(), parentModuleName, processorArchitecture));
628  // bbart.addAttributes(bbattributes);
629  //} catch (TskCoreException ex) {
630  // logger.log(Level.SEVERE, "Error adding os info artifact to blackboard."); //NON-NLS
631  //}
632  break;
633 
634  case "ProfileList": //NON-NLS
635  try {
636 
637  String homeDir = value;
638  String sid = artnode.getAttribute("sid"); //NON-NLS
639  String username = artnode.getAttribute("username"); //NON-NLS
640 
641  BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_ACCOUNT);
642  bbart.addAttribute(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
643  parentModuleName, username));
644  bbart.addAttribute(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_ID,
645  parentModuleName, sid));
646  bbart.addAttribute(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH,
647  parentModuleName, homeDir));
648  // index the artifact for keyword search
649  this.indexArtifact(bbart);
650  } catch (TskCoreException ex) {
651  logger.log(Level.SEVERE, "Error adding account artifact to blackboard."); //NON-NLS
652  }
653  break;
654 
655  case "NtuserNetwork": // NON-NLS
656  try {
657  String localPath = artnode.getAttribute("localPath"); //NON-NLS
658  String remoteName = value;
659  BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_REMOTE_DRIVE);
660  bbart.addAttribute(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LOCAL_PATH,
661  parentModuleName, localPath));
662  bbart.addAttribute(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REMOTE_PATH,
663  parentModuleName, remoteName));
664  // index the artifact for keyword search
665  this.indexArtifact(bbart);
666  } catch (TskCoreException ex) {
667  logger.log(Level.SEVERE, "Error adding network artifact to blackboard."); //NON-NLS
668  }
669  break;
670 
671  case "shellfolders": // NON-NLS
672  // The User Shell Folders subkey stores the paths to Windows Explorer folders for the current user of the computer
673  // (https://technet.microsoft.com/en-us/library/Cc962613.aspx).
674  // No useful information. Skip.
675  break;
676 
677  default:
678  logger.log(Level.WARNING, "Unrecognized node name: {0}", dataType); //NON-NLS
679  break;
680  }
681  }
682  }
683  }
684  }
685  return true;
686  } catch (FileNotFoundException ex) {
687  logger.log(Level.SEVERE, "Error finding the registry file."); //NON-NLS
688  } catch (SAXException ex) {
689  logger.log(Level.SEVERE, "Error parsing the registry XML: {0}", ex); //NON-NLS
690  } catch (IOException ex) {
691  logger.log(Level.SEVERE, "Error building the document parser: {0}", ex); //NON-NLS
692  } catch (ParserConfigurationException ex) {
693  logger.log(Level.SEVERE, "Error configuring the registry parser: {0}", ex); //NON-NLS
694  } finally {
695  try {
696  if (fstream != null) {
697  fstream.close();
698  }
699  } catch (IOException ex) {
700  }
701  }
702  return false;
703  }
704 
705  @Override
706  public void process(Content dataSource, IngestJobContext context) {
707  this.dataSource = dataSource;
708  this.context = context;
709  analyzeRegistryFiles();
710  }
711 
712 }

Copyright © 2012-2015 Basis Technology. Generated on: Wed Apr 6 2016
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.