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

Copyright © 2012-2016 Basis Technology. Generated on: Tue Oct 25 2016
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.