Merge pull request #4797 from wschaeferB/5046-RecentActivityNPE-PreStoryCleanup

5046 recent activity npe pre story cleanup
This commit is contained in:
Richard Cordovano 2019-05-14 15:12:43 -04:00 committed by GitHub
commit 721d2bc174
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -22,11 +22,16 @@
*/ */
package org.sleuthkit.autopsy.recentactivity; package org.sleuthkit.autopsy.recentactivity;
import java.io.*; import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringReader;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.*;
import java.util.logging.Level; import java.util.logging.Level;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
@ -40,7 +45,6 @@ import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProcessTerminator; import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProcessTerminator;
import org.sleuthkit.autopsy.ingest.IngestJobContext; import org.sleuthkit.autopsy.ingest.IngestJobContext;
import org.sleuthkit.autopsy.recentactivity.UsbDeviceIdMapper.USBInfo; import org.sleuthkit.autopsy.recentactivity.UsbDeviceIdMapper.USBInfo;
import org.sleuthkit.datamodel.*;
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
import org.w3c.dom.Document; import org.w3c.dom.Document;
@ -50,6 +54,14 @@ import org.w3c.dom.NodeList;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.HashSet;
import static java.util.TimeZone.getTimeZone; import static java.util.TimeZone.getTimeZone;
import org.openide.util.Lookup; import org.openide.util.Lookup;
import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress; import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress;
@ -57,7 +69,13 @@ import org.sleuthkit.autopsy.ingest.IngestModule.IngestModuleException;
import org.sleuthkit.autopsy.ingest.IngestServices; import org.sleuthkit.autopsy.ingest.IngestServices;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent; import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService; import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException; import org.sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException;
import org.sleuthkit.datamodel.Report;
import org.sleuthkit.datamodel.TskCoreException;
/** /**
* Extract windows registry data using regripper. Runs two versions of * Extract windows registry data using regripper. Runs two versions of
@ -72,21 +90,19 @@ import org.sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamExce
}) })
class ExtractRegistry extends Extract { class ExtractRegistry extends Extract {
private final Logger logger = Logger.getLogger(this.getClass().getName());
private String RR_PATH;
private String RR_FULL_PATH;
private Path rrHome; // Path to the Autopsy version of RegRipper
private Path rrFullHome; // Path to the full version of RegRipper
private Content dataSource;
private IngestJobContext context;
final private static UsbDeviceIdMapper USB_MAPPER = new UsbDeviceIdMapper(); final private static UsbDeviceIdMapper USB_MAPPER = new UsbDeviceIdMapper();
final private static String RIP_EXE = "rip.exe"; final private static String RIP_EXE = "rip.exe";
final private static String RIP_PL = "rip.pl"; final private static String RIP_PL = "rip.pl";
final private static int MS_IN_SEC = 1000; final private static int MS_IN_SEC = 1000;
final private static String NEVER_DATE = "Never"; final private static String NEVER_DATE = "Never";
final private static String SECTION_DIVIDER = "-------------------------"; final private static String SECTION_DIVIDER = "-------------------------";
final private static Logger logger = Logger.getLogger(ExtractRegistry.class.getName());
private final List<String> rrCmd = new ArrayList<>(); private final List<String> rrCmd = new ArrayList<>();
private final List<String> rrFullCmd = new ArrayList<>(); private final List<String> rrFullCmd = new ArrayList<>();
private final Path rrHome; // Path to the Autopsy version of RegRipper
private final Path rrFullHome; // Path to the full version of RegRipper
private Content dataSource;
private IngestJobContext context;
ExtractRegistry() throws IngestModuleException { ExtractRegistry() throws IngestModuleException {
moduleName = NbBundle.getMessage(ExtractIE.class, "ExtractRegistry.moduleName.text"); moduleName = NbBundle.getMessage(ExtractIE.class, "ExtractRegistry.moduleName.text");
@ -106,19 +122,19 @@ class ExtractRegistry extends Extract {
executableToRun = RIP_PL; executableToRun = RIP_PL;
} }
rrHome = rrRoot.toPath(); rrHome = rrRoot.toPath();
RR_PATH = rrHome.resolve(executableToRun).toString(); String rrPath = rrHome.resolve(executableToRun).toString();
rrFullHome = rrFullRoot.toPath(); rrFullHome = rrFullRoot.toPath();
RR_FULL_PATH = rrFullHome.resolve(executableToRun).toString();
if (!(new File(RR_PATH).exists())) { if (!(new File(rrPath).exists())) {
throw new IngestModuleException(Bundle.RegRipperNotFound()); throw new IngestModuleException(Bundle.RegRipperNotFound());
} }
if (!(new File(RR_FULL_PATH).exists())) { String rrFullPath = rrFullHome.resolve(executableToRun).toString();
if (!(new File(rrFullPath).exists())) {
throw new IngestModuleException(Bundle.RegRipperFullNotFound()); throw new IngestModuleException(Bundle.RegRipperFullNotFound());
} }
if (PlatformUtil.isWindowsOS()) { if (PlatformUtil.isWindowsOS()) {
rrCmd.add(RR_PATH); rrCmd.add(rrPath);
rrFullCmd.add(RR_FULL_PATH); rrFullCmd.add(rrFullPath);
} else { } else {
String perl; String perl;
File usrBin = new File("/usr/bin/perl"); File usrBin = new File("/usr/bin/perl");
@ -131,9 +147,9 @@ class ExtractRegistry extends Extract {
throw new IngestModuleException("perl not found in your system"); throw new IngestModuleException("perl not found in your system");
} }
rrCmd.add(perl); rrCmd.add(perl);
rrCmd.add(RR_PATH); rrCmd.add(rrPath);
rrFullCmd.add(perl); rrFullCmd.add(perl);
rrFullCmd.add(RR_FULL_PATH); rrFullCmd.add(rrFullPath);
} }
} }
@ -224,23 +240,19 @@ class ExtractRegistry extends Extract {
} }
// parse the autopsy-specific output // parse the autopsy-specific output
if (regOutputFiles.autopsyPlugins.isEmpty() == false) { if (regOutputFiles.autopsyPlugins.isEmpty() == false && parseAutopsyPluginOutput(regOutputFiles.autopsyPlugins, regFile) == false) {
if (parseAutopsyPluginOutput(regOutputFiles.autopsyPlugins, regFile) == false) { this.addErrorMessage(
this.addErrorMessage( NbBundle.getMessage(this.getClass(), "ExtractRegistry.analyzeRegFiles.failedParsingResults",
NbBundle.getMessage(this.getClass(), "ExtractRegistry.analyzeRegFiles.failedParsingResults", this.getName(), regFileName));
this.getName(), regFileName));
}
} }
// create a report for the full output // create a report for the full output
if (!regOutputFiles.fullPlugins.isEmpty()) { if (!regOutputFiles.fullPlugins.isEmpty()) {
//parse the full regripper output from SAM hive files //parse the full regripper output from SAM hive files
if (regFileNameLocal.toLowerCase().contains("sam")) { if (regFileNameLocal.toLowerCase().contains("sam") && parseSamPluginOutput(regOutputFiles.fullPlugins, regFile) == false) {
if (parseSamPluginOutput(regOutputFiles.fullPlugins, regFile) == false) { this.addErrorMessage(
this.addErrorMessage( NbBundle.getMessage(this.getClass(), "ExtractRegistry.analyzeRegFiles.failedParsingResults",
NbBundle.getMessage(this.getClass(), "ExtractRegistry.analyzeRegFiles.failedParsingResults", this.getName(), regFileName));
this.getName(), regFileName));
}
} }
try { try {
Report report = currentCase.addReport(regOutputFiles.fullPlugins, Report report = currentCase.addReport(regOutputFiles.fullPlugins,
@ -259,7 +271,6 @@ class ExtractRegistry extends Extract {
this.addErrorMessage("Error adding regripper output as Autopsy report: " + e.getLocalizedMessage()); //NON-NLS this.addErrorMessage("Error adding regripper output as Autopsy report: " + e.getLocalizedMessage()); //NON-NLS
} }
} }
// delete the hive // delete the hive
regFileNameLocalFile.delete(); regFileNameLocalFile.delete();
} }
@ -273,12 +284,6 @@ class ExtractRegistry extends Extract {
} }
} }
private class RegOutputFiles {
public String autopsyPlugins = "";
public String fullPlugins = "";
}
/** /**
* Execute regripper on the given registry. * Execute regripper on the given registry.
* *
@ -392,11 +397,11 @@ class ExtractRegistry extends Extract {
// that we will submit in a ModuleDataEvent for additional processing. // that we will submit in a ModuleDataEvent for additional processing.
Collection<BlackboardArtifact> wifiBBartifacts = new ArrayList<>(); Collection<BlackboardArtifact> wifiBBartifacts = new ArrayList<>();
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
if (context.dataSourceIngestIsCancelled()) { if (context.dataSourceIngestIsCancelled()) {
return false; return false;
} }
Element tempnode = (Element) children.item(i); Element tempnode = (Element) children.item(i);
String dataType = tempnode.getNodeName(); String dataType = tempnode.getNodeName();
@ -406,12 +411,11 @@ class ExtractRegistry extends Extract {
Element timenode = (Element) timenodes.item(0); Element timenode = (Element) timenodes.item(0);
String etime = timenode.getTextContent(); String etime = timenode.getTextContent();
try { try {
Long epochtime = new SimpleDateFormat("EEE MMM d HH:mm:ss yyyy").parse(etime).getTime(); mtime = new SimpleDateFormat("EEE MMM d HH:mm:ss yyyy").parse(etime).getTime();
mtime = epochtime;
String Tempdate = mtime.toString(); String Tempdate = mtime.toString();
mtime = Long.valueOf(Tempdate) / MS_IN_SEC; mtime = Long.valueOf(Tempdate) / MS_IN_SEC;
} catch (ParseException ex) { } catch (ParseException ex) {
logger.log(Level.WARNING, "Failed to parse epoch time when parsing the registry."); //NON-NLS logger.log(Level.WARNING, "Failed to parse epoch time when parsing the registry.", ex); //NON-NLS
} }
} }
@ -424,7 +428,6 @@ class ExtractRegistry extends Extract {
Element artroot = (Element) artroots.item(0); Element artroot = (Element) artroots.item(0);
NodeList myartlist = artroot.getChildNodes(); NodeList myartlist = artroot.getChildNodes();
String parentModuleName = RecentActivityExtracterModuleFactory.getModuleName(); String parentModuleName = RecentActivityExtracterModuleFactory.getModuleName();
String winver = "";
// If all artifact nodes should really go under one Blackboard artifact, need to process it differently // If all artifact nodes should really go under one Blackboard artifact, need to process it differently
switch (dataType) { switch (dataType) {
@ -508,7 +511,6 @@ class ExtractRegistry extends Extract {
case "Profiler": // NON-NLS case "Profiler": // NON-NLS
String os = ""; String os = "";
String procArch = ""; String procArch = "";
String procId = "";
String tempDir = ""; String tempDir = "";
for (int j = 0; j < myartlist.getLength(); j++) { for (int j = 0; j < myartlist.getLength(); j++) {
Node artchild = myartlist.item(j); Node artchild = myartlist.item(j);
@ -526,7 +528,6 @@ class ExtractRegistry extends Extract {
procArch = value; procArch = value;
break; break;
case "PROCESSOR_IDENTIFIER": //NON-NLS case "PROCESSOR_IDENTIFIER": //NON-NLS
procId = value;
break; break;
case "TEMP": //NON-NLS case "TEMP": //NON-NLS
tempDir = value; tempDir = value;
@ -652,7 +653,7 @@ class ExtractRegistry extends Extract {
try { try {
Long epochtime = new SimpleDateFormat("EEE MMM d HH:mm:ss yyyy").parse(artnode.getAttribute("mtime")).getTime(); //NON-NLS Long epochtime = new SimpleDateFormat("EEE MMM d HH:mm:ss yyyy").parse(artnode.getAttribute("mtime")).getTime(); //NON-NLS
itemMtime = epochtime; itemMtime = epochtime;
itemMtime = itemMtime / MS_IN_SEC; itemMtime /= MS_IN_SEC;
} catch (ParseException e) { } catch (ParseException e) {
logger.log(Level.WARNING, "Failed to parse epoch time for installed program artifact."); //NON-NLS logger.log(Level.WARNING, "Failed to parse epoch time for installed program artifact."); //NON-NLS
} }
@ -738,7 +739,7 @@ class ExtractRegistry extends Extract {
} else { } else {
//add attributes to existing artifact //add attributes to existing artifact
BlackboardAttribute bbattr = bbart.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_USER_NAME)); BlackboardAttribute bbattr = bbart.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_USER_NAME));
if (bbattr == null) { if (bbattr == null) {
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME, bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
parentModuleName, username)); parentModuleName, username));
@ -852,10 +853,9 @@ class ExtractRegistry extends Extract {
String line = bufferedReader.readLine(); String line = bufferedReader.readLine();
Set<UserInfo> userSet = new HashSet<>(); Set<UserInfo> userSet = new HashSet<>();
while (line != null) { while (line != null) {
if (line.contains(SECTION_DIVIDER) && previousLine != null) { if (line.contains(SECTION_DIVIDER) && previousLine != null && previousLine.contains(userInfoSection)) {
if (previousLine.contains(userInfoSection)) { readUsers(bufferedReader, userSet);
readUsers(bufferedReader, userSet);
}
} }
previousLine = line; previousLine = line;
line = bufferedReader.readLine(); line = bufferedReader.readLine();
@ -923,7 +923,7 @@ class ExtractRegistry extends Extract {
} catch (ParseException ex) { } catch (ParseException ex) {
logger.log(Level.SEVERE, "Error parsing the the date from the registry file", ex); //NON-NLS logger.log(Level.SEVERE, "Error parsing the the date from the registry file", ex); //NON-NLS
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error updating TSK_OS_ACCOUNT artifacts to include newly parsed data.", ex); //NON-NLS logger.log(Level.SEVERE, "Error updating TSK_OS_ACCOUNT artifacts to include newly parsed data.", ex); //NON-NLS
} }
return false; return false;
} }
@ -953,8 +953,7 @@ class ExtractRegistry extends Extract {
if (line.contains(userNameLabel)) { if (line.contains(userNameLabel)) {
String userNameAndIdString = line.replace(userNameLabel, ""); String userNameAndIdString = line.replace(userNameLabel, "");
userName = userNameAndIdString.substring(0, userNameAndIdString.lastIndexOf('[')).trim(); userName = userNameAndIdString.substring(0, userNameAndIdString.lastIndexOf('[')).trim();
} } else if (line.contains(sidLabel) && !userName.isEmpty()) {
else if (line.contains(sidLabel) && !userName.isEmpty()){
String sid = line.replace(sidLabel, "").trim(); String sid = line.replace(sidLabel, "").trim();
UserInfo userInfo = new UserInfo(userName, sid); UserInfo userInfo = new UserInfo(userName, sid);
//continue reading this users information until end of file or a blank line between users //continue reading this users information until end of file or a blank line between users
@ -980,12 +979,21 @@ class ExtractRegistry extends Extract {
public void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar) { public void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar) {
this.dataSource = dataSource; this.dataSource = dataSource;
this.context = context; this.context = context;
progressBar.progress(Bundle.Progress_Message_Analyze_Registry()); progressBar.progress(Bundle.Progress_Message_Analyze_Registry());
analyzeRegistryFiles(); analyzeRegistryFiles();
} }
/**
* Private wrapper class for Registry output files
*/
private class RegOutputFiles {
public String autopsyPlugins = "";
public String fullPlugins = "";
}
/** /**
* Class for organizing information associated with a TSK_OS_ACCOUNT before * Class for organizing information associated with a TSK_OS_ACCOUNT before
* the artifact is created. * the artifact is created.
@ -1001,7 +1009,7 @@ class ExtractRegistry extends Extract {
/** /**
* Create a UserInfo object * Create a UserInfo object
* *
* @param name - the os user account name * @param name - the os user account name
* @param userSidString - the SID for the user account * @param userSidString - the SID for the user account
*/ */
private UserInfo(String name, String userSidString) { private UserInfo(String name, String userSidString) {