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

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