From 8ac91c2cb8085d5123b43d15c242fbf1f2728e9b Mon Sep 17 00:00:00 2001 From: APriestman Date: Fri, 23 Jan 2015 13:30:27 -0500 Subject: [PATCH] Combine OS attributes found in the registry. --- .../autopsy/recentactivity/ExtractIE.java | 153 +++++----- .../recentactivity/ExtractRegistry.java | 279 +++++++++--------- 2 files changed, 221 insertions(+), 211 deletions(-) diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractIE.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractIE.java index a34e6c31ea..e986b6ad60 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractIE.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractIE.java @@ -59,14 +59,16 @@ import org.sleuthkit.autopsy.ingest.IngestJobContext; import org.sleuthkit.datamodel.*; /** - * Extracts activity from Internet Explorer browser, as well as recent documents in windows. + * Extracts activity from Internet Explorer browser, as well as recent documents + * in windows. */ class ExtractIE extends Extract { + private static final Logger logger = Logger.getLogger(ExtractIE.class.getName()); private IngestServices services = IngestServices.getInstance(); private String moduleTempResultsDir; private String PASCO_LIB_PATH; - private String JAVA_PATH; + private String JAVA_PATH; private static final SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); private Content dataSource; private IngestJobContext context; @@ -90,7 +92,7 @@ class ExtractIE extends Extract { /** * Finds the files storing bookmarks and creates artifacts */ - private void getBookmark() { + private void getBookmark() { org.sleuthkit.autopsy.casemodule.services.FileManager fileManager = currentCase.getServices().getFileManager(); List favoritesFiles; try { @@ -99,7 +101,7 @@ class ExtractIE extends Extract { logger.log(Level.WARNING, "Error fetching 'url' files for Internet Explorer bookmarks.", ex); //NON-NLS this.addErrorMessage( NbBundle.getMessage(this.getClass(), "ExtractIE.getBookmark.errMsg.errGettingBookmarks", - this.getName())); + this.getName())); return; } @@ -107,17 +109,17 @@ class ExtractIE extends Extract { logger.log(Level.INFO, "Didn't find any IE bookmark files."); //NON-NLS return; } - + dataFound = true; for (AbstractFile fav : favoritesFiles) { if (fav.getSize() == 0) { continue; } - + if (context.dataSourceIngestIsCancelled()) { break; } - + String url = getURLFromIEBookmarkFile(fav); String name = fav.getName(); @@ -128,27 +130,27 @@ class ExtractIE extends Extract { Collection bbattributes = new ArrayList(); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(), - NbBundle.getMessage(this.getClass(), - "ExtractIE.parentModuleName.noSpace"), url)); + NbBundle.getMessage(this.getClass(), + "ExtractIE.parentModuleName.noSpace"), url)); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TITLE.getTypeID(), - NbBundle.getMessage(this.getClass(), - "ExtractIE.parentModuleName.noSpace"), name)); + NbBundle.getMessage(this.getClass(), + "ExtractIE.parentModuleName.noSpace"), name)); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID(), - NbBundle.getMessage(this.getClass(), - "ExtractIE.parentModuleName.noSpace"), datetime)); + NbBundle.getMessage(this.getClass(), + "ExtractIE.parentModuleName.noSpace"), datetime)); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(), - NbBundle.getMessage(this.getClass(), - "ExtractIE.parentModuleName.noSpace"), - NbBundle.getMessage(this.getClass(), "ExtractIE.moduleName.text"))); + NbBundle.getMessage(this.getClass(), + "ExtractIE.parentModuleName.noSpace"), + NbBundle.getMessage(this.getClass(), "ExtractIE.moduleName.text"))); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(), - NbBundle.getMessage(this.getClass(), - "ExtractIE.parentModuleName.noSpace"), domain)); + NbBundle.getMessage(this.getClass(), + "ExtractIE.parentModuleName.noSpace"), domain)); this.addArtifact(ARTIFACT_TYPE.TSK_WEB_BOOKMARK, fav, bbattributes); } services.fireModuleDataEvent(new ModuleDataEvent( NbBundle.getMessage(this.getClass(), "ExtractIE.parentModuleName"), BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK)); } - + private String getURLFromIEBookmarkFile(AbstractFile fav) { BufferedReader reader = new BufferedReader(new InputStreamReader(new ReadContentInputStream(fav))); String line, url = ""; @@ -165,12 +167,12 @@ class ExtractIE extends Extract { logger.log(Level.WARNING, "Failed to read from content: " + fav.getName(), ex); //NON-NLS this.addErrorMessage( NbBundle.getMessage(this.getClass(), "ExtractIE.getURLFromIEBmkFile.errMsg", this.getName(), - fav.getName())); + fav.getName())); } catch (IndexOutOfBoundsException ex) { logger.log(Level.WARNING, "Failed while getting URL of IE bookmark. Unexpected format of the bookmark file: " + fav.getName(), ex); //NON-NLS this.addErrorMessage( NbBundle.getMessage(this.getClass(), "ExtractIE.getURLFromIEBmkFile.errMsg2", this.getName(), - fav.getName())); + fav.getName())); } finally { try { reader.close(); @@ -178,14 +180,14 @@ class ExtractIE extends Extract { logger.log(Level.WARNING, "Failed to close reader.", ex); //NON-NLS } } - + return url; } /** - * Finds files that store cookies and adds artifacts for them. + * Finds files that store cookies and adds artifacts for them. */ - private void getCookie() { + private void getCookie() { org.sleuthkit.autopsy.casemodule.services.FileManager fileManager = currentCase.getServices().getFileManager(); List cookiesFiles; try { @@ -201,7 +203,7 @@ class ExtractIE extends Extract { logger.log(Level.INFO, "Didn't find any IE cookies files."); //NON-NLS return; } - + dataFound = true; for (AbstractFile cookiesFile : cookiesFiles) { if (context.dataSourceIngestIsCancelled()) { @@ -218,7 +220,7 @@ class ExtractIE extends Extract { logger.log(Level.SEVERE, "Error reading bytes of Internet Explorer cookie.", ex); //NON-NLS this.addErrorMessage( NbBundle.getMessage(this.getClass(), "ExtractIE.getCookie.errMsg.errReadingIECookie", - this.getName(), cookiesFile.getName())); + this.getName(), cookiesFile.getName())); continue; } String cookieString = new String(t); @@ -233,24 +235,24 @@ class ExtractIE extends Extract { Collection bbattributes = new ArrayList(); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(), - NbBundle.getMessage(this.getClass(), - "ExtractIE.parentModuleName.noSpace"), url)); + NbBundle.getMessage(this.getClass(), + "ExtractIE.parentModuleName.noSpace"), url)); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(), - NbBundle.getMessage(this.getClass(), - "ExtractIE.parentModuleName.noSpace"), datetime)); + NbBundle.getMessage(this.getClass(), + "ExtractIE.parentModuleName.noSpace"), datetime)); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), - NbBundle.getMessage(this.getClass(), - "ExtractIE.parentModuleName.noSpace"), (name != null) ? name : "")); + NbBundle.getMessage(this.getClass(), + "ExtractIE.parentModuleName.noSpace"), (name != null) ? name : "")); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE.getTypeID(), - NbBundle.getMessage(this.getClass(), - "ExtractIE.parentModuleName.noSpace"), value)); + NbBundle.getMessage(this.getClass(), + "ExtractIE.parentModuleName.noSpace"), value)); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(), - NbBundle.getMessage(this.getClass(), - "ExtractIE.parentModuleName.noSpace"), - NbBundle.getMessage(this.getClass(), "ExtractIE.moduleName.text"))); + NbBundle.getMessage(this.getClass(), + "ExtractIE.parentModuleName.noSpace"), + NbBundle.getMessage(this.getClass(), "ExtractIE.moduleName.text"))); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(), - NbBundle.getMessage(this.getClass(), - "ExtractIE.parentModuleName.noSpace"), domain)); + NbBundle.getMessage(this.getClass(), + "ExtractIE.parentModuleName.noSpace"), domain)); this.addArtifact(ARTIFACT_TYPE.TSK_WEB_COOKIE, cookiesFile, bbattributes); } services.fireModuleDataEvent(new ModuleDataEvent( @@ -258,7 +260,7 @@ class ExtractIE extends Extract { } /** - * Locates index.dat files, runs Pasco on them, and creates artifacts. + * Locates index.dat files, runs Pasco on them, and creates artifacts. */ private void getHistory() { logger.log(Level.INFO, "Pasco results path: {0}", moduleTempResultsDir); //NON-NLS @@ -270,8 +272,8 @@ class ExtractIE extends Extract { NbBundle.getMessage(this.getClass(), "ExtractIE.getHistory.errMsg.unableToGetHist", this.getName())); logger.log(Level.SEVERE, "Error finding pasco program "); //NON-NLS return; - } - + } + final String pascoHome = pascoRoot.getAbsolutePath(); logger.log(Level.INFO, "Pasco2 home: {0}", pascoHome); //NON-NLS @@ -280,7 +282,7 @@ class ExtractIE extends Extract { File resultsDir = new File(moduleTempResultsDir); resultsDir.mkdirs(); - + // get index.dat files org.sleuthkit.autopsy.casemodule.services.FileManager fileManager = currentCase.getServices().getFileManager(); List indexFiles; @@ -288,7 +290,7 @@ class ExtractIE extends Extract { indexFiles = fileManager.findFiles(dataSource, "index.dat"); //NON-NLS } catch (TskCoreException ex) { this.addErrorMessage(NbBundle.getMessage(this.getClass(), "ExtractIE.getHistory.errMsg.errGettingHistFiles", - this.getName())); + this.getName())); logger.log(Level.WARNING, "Error fetching 'index.data' files for Internet Explorer history."); //NON-NLS return; } @@ -298,7 +300,7 @@ class ExtractIE extends Extract { logger.log(Level.INFO, msg); return; } - + dataFound = true; String temps; String indexFileName; @@ -321,7 +323,7 @@ class ExtractIE extends Extract { logger.log(Level.SEVERE, "Error while trying to write index.dat file " + datFile.getAbsolutePath(), e); //NON-NLS this.addErrorMessage( NbBundle.getMessage(this.getClass(), "ExtractIE.getHistory.errMsg.errWriteFile", this.getName(), - datFile.getAbsolutePath())); + datFile.getAbsolutePath())); continue; } @@ -336,7 +338,7 @@ class ExtractIE extends Extract { if (bPascProcSuccess) { parsePascoOutput(indexFile, filename); foundHistory = true; - + //Delete index.dat file since it was succcessfully by Pasco datFile.delete(); } else { @@ -345,7 +347,7 @@ class ExtractIE extends Extract { NbBundle.getMessage(this.getClass(), "ExtractIE.getHistory.errMsg.errProcHist", this.getName())); } } - + if (foundHistory) { services.fireModuleDataEvent(new ModuleDataEvent( NbBundle.getMessage(this.getClass(), "ExtractIE.parentModuleName"), BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY)); @@ -353,7 +355,8 @@ class ExtractIE extends Extract { } /** - * Execute pasco on a single file that has been saved to disk. + * Execute pasco on a single file that has been saved to disk. + * * @param indexFilePath Path to local index.dat file to analyze * @param outputFileName Name of file to save output to * @return false on error @@ -386,18 +389,20 @@ class ExtractIE extends Extract { /** * parse Pasco output and create artifacts - * @param origFile Original index.dat file that was analyzed to get this output + * + * @param origFile Original index.dat file that was analyzed to get this + * output * @param pascoOutputFileName name of pasco output file */ private void parsePascoOutput(AbstractFile origFile, String pascoOutputFileName) { - + String fnAbs = moduleTempResultsDir + File.separator + pascoOutputFileName; File file = new File(fnAbs); if (file.exists() == false) { this.addErrorMessage( NbBundle.getMessage(this.getClass(), "ExtractIE.parsePascoOutput.errMsg.notFound", this.getName(), - file.getName())); + file.getName())); logger.log(Level.WARNING, "Pasco Output not found: {0}", file.getPath()); //NON-NLS return; } @@ -414,11 +419,11 @@ class ExtractIE extends Extract { } catch (FileNotFoundException ex) { this.addErrorMessage( NbBundle.getMessage(this.getClass(), "ExtractIE.parsePascoOutput.errMsg.errParsing", this.getName(), - file.getName())); + file.getName())); logger.log(Level.WARNING, "Unable to find the Pasco file at " + file.getPath(), ex); //NON-NLS return; } - + // Keep a list of reported user accounts to avoid repeats Set reportedUserAccounts = new HashSet(); @@ -478,7 +483,7 @@ class ExtractIE extends Extract { } catch (ParseException e) { this.addErrorMessage( NbBundle.getMessage(this.getClass(), "ExtractIE.parsePascoOutput.errMsg.errParsingEntry", - this.getName())); + this.getName())); logger.log(Level.SEVERE, "Error parsing Pasco results.", e); //NON-NLS } } @@ -487,40 +492,40 @@ class ExtractIE extends Extract { BlackboardArtifact bbart = origFile.newArtifact(ARTIFACT_TYPE.TSK_WEB_HISTORY); Collection bbattributes = new ArrayList<>(); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(), - NbBundle.getMessage(this.getClass(), - "ExtractIE.parentModuleName.noSpace"), realurl)); + NbBundle.getMessage(this.getClass(), + "ExtractIE.parentModuleName.noSpace"), realurl)); //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL_DECODED.getTypeID(), "RecentActivity", EscapeUtil.decodeURL(realurl))); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID(), - NbBundle.getMessage(this.getClass(), - "ExtractIE.parentModuleName.noSpace"), ftime)); + NbBundle.getMessage(this.getClass(), + "ExtractIE.parentModuleName.noSpace"), ftime)); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REFERRER.getTypeID(), - NbBundle.getMessage(this.getClass(), - "ExtractIE.parentModuleName.noSpace"), "")); + NbBundle.getMessage(this.getClass(), + "ExtractIE.parentModuleName.noSpace"), "")); // @@@ NOte that other browser modules are adding TITLE in hre for the title bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(), - NbBundle.getMessage(this.getClass(), - "ExtractIE.parentModuleName.noSpace"), - NbBundle.getMessage(this.getClass(), - "ExtractIE.moduleName.text"))); + NbBundle.getMessage(this.getClass(), + "ExtractIE.parentModuleName.noSpace"), + NbBundle.getMessage(this.getClass(), + "ExtractIE.moduleName.text"))); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(), - NbBundle.getMessage(this.getClass(), - "ExtractIE.parentModuleName.noSpace"), domain)); + NbBundle.getMessage(this.getClass(), + "ExtractIE.parentModuleName.noSpace"), domain)); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME.getTypeID(), - NbBundle.getMessage(this.getClass(), - "ExtractIE.parentModuleName.noSpace"), user)); + NbBundle.getMessage(this.getClass(), + "ExtractIE.parentModuleName.noSpace"), user)); bbart.addAttributes(bbattributes); - - if( (!user.isEmpty()) && (!reportedUserAccounts.contains(user))){ + + if ((!user.isEmpty()) && (!reportedUserAccounts.contains(user))) { BlackboardArtifact osAttr = origFile.newArtifact(ARTIFACT_TYPE.TSK_OS_ACCOUNT); osAttr.addAttribute(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME.getTypeID(), - NbBundle.getMessage(this.getClass(), "ExtractIE.parentModuleName.noSpace"), user)); + NbBundle.getMessage(this.getClass(), "ExtractIE.parentModuleName.noSpace"), user)); reportedUserAccounts.add(user); } } catch (TskCoreException ex) { logger.log(Level.SEVERE, "Error writing Internet Explorer web history artifact to the blackboard.", ex); //NON-NLS - } + } } - fileScanner.close(); + fileScanner.close(); } } diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java index 8d70769431..34d57be998 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java @@ -43,6 +43,8 @@ import org.sleuthkit.autopsy.recentactivity.UsbDeviceIdMapper.USBInfo; import org.sleuthkit.datamodel.*; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; +import org.sleuthkit.datamodel.OSUtility; // TEMP +import org.sleuthkit.autopsy.casemodule.Case; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -51,10 +53,10 @@ import org.xml.sax.InputSource; import org.xml.sax.SAXException; /** - * Extract windows registry data using regripper. - * Runs two versions of regripper. One is the generally available set of plug-ins - * and the second is a set that were customized for Autopsy to produce a more structured - * output of XML so that we can parse and turn into blackboard artifacts. + * Extract windows registry data using regripper. Runs two versions of + * regripper. One is the generally available set of plug-ins and the second is a + * set that were customized for Autopsy to produce a more structured output of + * XML so that we can parse and turn into blackboard artifacts. */ class ExtractRegistry extends Extract { @@ -68,7 +70,7 @@ class ExtractRegistry extends Extract { private Content dataSource; private IngestJobContext context; final private static UsbDeviceIdMapper usbMapper = new UsbDeviceIdMapper(); - + ExtractRegistry() { moduleName = NbBundle.getMessage(ExtractIE.class, "ExtractRegistry.moduleName.text"); final File rrRoot = InstalledFileLocator.getDefault().locate("rr", ExtractRegistry.class.getPackage().getName(), false); //NON-NLS @@ -79,7 +81,7 @@ class ExtractRegistry extends Extract { } else { rrFound = true; } - + rrHome = rrRoot.getAbsolutePath(); logger.log(Level.INFO, "RegRipper home: {0}", rrHome); //NON-NLS @@ -88,7 +90,7 @@ class ExtractRegistry extends Extract { } else { RR_PATH = "perl " + rrHome + File.separator + "rip.pl"; //NON-NLS } - + final File rrFullRoot = InstalledFileLocator.getDefault().locate("rr-full", ExtractRegistry.class.getPackage().getName(), false); //NON-NLS if (rrFullRoot == null) { logger.log(Level.SEVERE, "RegRipper Full not found"); //NON-NLS @@ -96,11 +98,10 @@ class ExtractRegistry extends Extract { } else { rrFullFound = true; } - - if(rrFullRoot != null){ + + if (rrFullRoot != null) { rrFullHome = rrFullRoot.getAbsolutePath(); - } - else{ + } else { rrFullHome = ""; } logger.log(Level.INFO, "RegRipper Full home: {0}", rrFullHome); //NON-NLS @@ -111,44 +112,43 @@ class ExtractRegistry extends Extract { RR_FULL_PATH = "perl " + rrFullHome + File.separator + "rip.pl"; //NON-NLS } } - + /** * Search for the registry hives on the system. */ private List findRegistryFiles() { List allRegistryFiles = new ArrayList<>(); org.sleuthkit.autopsy.casemodule.services.FileManager fileManager = currentCase.getServices().getFileManager(); - + // find the user-specific ntuser-dat files try { allRegistryFiles.addAll(fileManager.findFiles(dataSource, "ntuser.dat")); //NON-NLS - } - catch (TskCoreException ex) { + } catch (TskCoreException ex) { logger.log(Level.WARNING, "Error fetching 'ntuser.dat' file."); //NON-NLS } // find the system hives' - String[] regFileNames = new String[] {"system", "software", "security", "sam"}; //NON-NLS + String[] regFileNames = new String[]{"system", "software", "security", "sam"}; //NON-NLS for (String regFileName : regFileNames) { try { allRegistryFiles.addAll(fileManager.findFiles(dataSource, regFileName, "/system32/config")); //NON-NLS - } - catch (TskCoreException ex) { + } catch (TskCoreException ex) { String msg = NbBundle.getMessage(this.getClass(), - "ExtractRegistry.findRegFiles.errMsg.errReadingFile", regFileName); + "ExtractRegistry.findRegFiles.errMsg.errReadingFile", regFileName); logger.log(Level.WARNING, msg); this.addErrorMessage(this.getName() + ": " + msg); } } return allRegistryFiles; } - + /** - * Identifies registry files in the database by mtimeItem, runs regripper on them, and parses the output. + * Identifies registry files in the database by mtimeItem, runs regripper on + * them, and parses the output. */ - private void analyzeRegistryFiles() { + private void analyzeRegistryFiles() { List allRegistryFiles = findRegistryFiles(); - + // open the log file FileWriter logFile = null; try { @@ -156,7 +156,7 @@ class ExtractRegistry extends Extract { } catch (IOException ex) { logger.log(Level.SEVERE, null, ex); } - + int j = 0; for (AbstractFile regFile : allRegistryFiles) { String regFileName = regFile.getName(); @@ -169,52 +169,50 @@ class ExtractRegistry extends Extract { logger.log(Level.SEVERE, "Error writing the temp registry file. {0}", ex); //NON-NLS this.addErrorMessage( NbBundle.getMessage(this.getClass(), "ExtractRegistry.analyzeRegFiles.errMsg.errWritingTemp", - this.getName(), regFileName)); + this.getName(), regFileName)); continue; } - + if (context.dataSourceIngestIsCancelled()) { break; } - + try { if (logFile != null) { - logFile.write(Integer.toString(j-1) + "\t" + regFile.getUniquePath() + "\n"); + logFile.write(Integer.toString(j - 1) + "\t" + regFile.getUniquePath() + "\n"); } - } - catch (TskCoreException | IOException ex) { + } catch (TskCoreException | IOException ex) { logger.log(Level.SEVERE, null, ex); } - + logger.log(Level.INFO, "{0}- Now getting registry information from {1}", new Object[]{moduleName, regFileNameLocal}); //NON-NLS RegOutputFiles regOutputFiles = ripRegistryFile(regFileNameLocal, outputPathBase); if (context.dataSourceIngestIsCancelled()) { break; } - + // parse the autopsy-specific output if (regOutputFiles.autopsyPlugins.isEmpty() == false) { if (parseAutopsyPluginOutput(regOutputFiles.autopsyPlugins, regFile) == false) { this.addErrorMessage( NbBundle.getMessage(this.getClass(), "ExtractRegistry.analyzeRegFiles.failedParsingResults", - this.getName(), regFileName)); + this.getName(), regFileName)); } } // create a report for the full output if (regOutputFiles.fullPlugins.isEmpty() == false) { try { - currentCase.addReport(regOutputFiles.fullPlugins, NbBundle.getMessage(this.getClass(),"ExtractRegistry.parentModuleName.noSpace"), "RegRipper " + regFile.getUniquePath() ); - } - catch (TskCoreException e) { + currentCase.addReport(regOutputFiles.fullPlugins, NbBundle.getMessage(this.getClass(), "ExtractRegistry.parentModuleName.noSpace"), "RegRipper " + regFile.getUniquePath()); + } catch (TskCoreException e) { this.addErrorMessage("Error adding regripper output as Autopsy report: " + e.getLocalizedMessage()); } } - + // delete the hive regFileNameLocalFile.delete(); } - + try { if (logFile != null) { logFile.close(); @@ -223,45 +221,43 @@ class ExtractRegistry extends Extract { logger.log(Level.SEVERE, null, ex); } } - + private class RegOutputFiles { + public String autopsyPlugins = ""; public String fullPlugins = ""; } /** * Execute regripper on the given registry. + * * @param regFilePath Path to local copy of registry - * @param outFilePathBase Path to location to save output file to. Base mtimeItem that will be extended on + * @param outFilePathBase Path to location to save output file to. Base + * mtimeItem that will be extended on */ private RegOutputFiles ripRegistryFile(String regFilePath, String outFilePathBase) { String autopsyType = ""; // Type argument for rr for autopsy-specific modules String fullType; // Type argument for rr for full set of modules RegOutputFiles regOutputFiles = new RegOutputFiles(); - + if (regFilePath.toLowerCase().contains("system")) { //NON-NLS autopsyType = "autopsysystem"; //NON-NLS fullType = "system"; //NON-NLS - } - else if (regFilePath.toLowerCase().contains("software")) { //NON-NLS + } else if (regFilePath.toLowerCase().contains("software")) { //NON-NLS autopsyType = "autopsysoftware"; //NON-NLS fullType = "software"; //NON-NLS - } - else if (regFilePath.toLowerCase().contains("ntuser")) { //NON-NLS + } else if (regFilePath.toLowerCase().contains("ntuser")) { //NON-NLS autopsyType = "autopsyntuser"; //NON-NLS fullType = "ntuser"; //NON-NLS - } - else if (regFilePath.toLowerCase().contains("sam")) { //NON-NLS + } else if (regFilePath.toLowerCase().contains("sam")) { //NON-NLS fullType = "sam"; //NON-NLS - } - else if (regFilePath.toLowerCase().contains("security")) { //NON-NLS + } else if (regFilePath.toLowerCase().contains("security")) { //NON-NLS fullType = "security"; //NON-NLS - } - else { + } else { return regOutputFiles; } - + // run the autopsy-specific set of modules if (!autopsyType.isEmpty() && rrFound) { regOutputFiles.autopsyPlugins = outFilePathBase + "-autopsy.txt"; //NON-NLS @@ -272,17 +268,17 @@ class ExtractRegistry extends Extract { if (context.dataSourceIngestIsCancelled()) { return regOutputFiles; } - + // run the full set of rr modules if (!fullType.isEmpty() && rrFullFound) { regOutputFiles.fullPlugins = outFilePathBase + "-full.txt"; //NON-NLS String errFilePath = outFilePathBase + "-full.err.txt"; //NON-NLS logger.log(Level.INFO, "Writing Full RegRipper results to: {0}", regOutputFiles.fullPlugins); //NON-NLS executeRegRipper(RR_FULL_PATH, rrFullHome, regFilePath, fullType, regOutputFiles.fullPlugins, errFilePath); - } + } return regOutputFiles; } - + private void executeRegRipper(String regRipperPath, String regRipperHomeDir, String hiveFilePath, String hiveFileType, String outputFile, String errFile) { try { logger.log(Level.INFO, "Writing RegRipper results to: {0}", outputFile); //NON-NLS @@ -292,7 +288,7 @@ class ExtractRegistry extends Extract { commandLine.add(hiveFilePath); commandLine.add("-f"); //NON-NLS commandLine.add(hiveFileType); - + ProcessBuilder processBuilder = new ProcessBuilder(commandLine); processBuilder.directory(new File(regRipperHomeDir)); // RegRipper 2.8 has to be run from its own directory processBuilder.redirectOutput(new File(outputFile)); @@ -301,25 +297,26 @@ class ExtractRegistry extends Extract { } catch (IOException ex) { logger.log(Level.SEVERE, "Unable to run RegRipper", ex); //NON-NLS this.addErrorMessage(NbBundle.getMessage(this.getClass(), "ExtractRegistry.execRegRip.errMsg.failedAnalyzeRegFile", this.getName())); - } + } } - + // @@@ VERIFY that we are doing the right thing when we parse multiple NTUSER.DAT /** - * + * * @param regFilePath Path to the output file produced by RegRipper. - * @param regFile File object for registry that we are parsing (to make blackboard artifacts with) - * @return + * @param regFile File object for registry that we are parsing (to make + * blackboard artifacts with) + * @return */ private boolean parseAutopsyPluginOutput(String regFilePath, AbstractFile regFile) { FileInputStream fstream = null; try { SleuthkitCase tempDb = currentCase.getSleuthkitCase(); - + // Read the file in and create a Document and elements File regfile = new File(regFilePath); fstream = new FileInputStream(regfile); - + String regString = new Scanner(fstream, "UTF-8").useDelimiter("\\Z").next(); //NON-NLS String startdoc = ""; //NON-NLS String result = regString.replaceAll("----------------------------------------", ""); @@ -332,14 +329,14 @@ class ExtractRegistry extends Extract { String stringdoc = startdoc + result + enddoc; DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document doc = builder.parse(new InputSource(new StringReader(stringdoc))); - + // cycle through the elements in the doc Element oroot = doc.getDocumentElement(); NodeList children = oroot.getChildNodes(); int len = children.getLength(); for (int i = 0; i < len; i++) { Element tempnode = (Element) children.item(i); - + String dataType = tempnode.getNodeName(); NodeList timenodes = tempnode.getElementsByTagName("mtime"); //NON-NLS @@ -362,22 +359,22 @@ class ExtractRegistry extends Extract { // If there isn't an artifact node, skip this entry continue; } - + Element artroot = (Element) artroots.item(0); NodeList myartlist = artroot.getChildNodes(); String parentModuleName = NbBundle.getMessage(this.getClass(), "ExtractRegistry.parentModuleName.noSpace"); String winver = ""; - + // If all artifact nodes should really go under one Blackboard artifact, need to process it differently - if(dataType.equals("WinVersion")){ - + if (dataType.equals("WinVersion")) { + String version = ""; String systemRoot = ""; String productId = ""; String regOwner = ""; String regOrg = ""; Long installtime = null; - + for (int j = 0; j < myartlist.getLength(); j++) { Node artchild = myartlist.item(j); // If it has attributes, then it is an Element (based off API) @@ -386,27 +383,21 @@ class ExtractRegistry extends Extract { String value = artnode.getTextContent().trim(); String name = artnode.getAttribute("name"); - - if(name.equals("ProductName")){ // NON_NLS + + if (name.equals("ProductName")) { // NON_NLS version = value; - } - else if(name.equals("CSDVersion")){ // NON_NLS + } else if (name.equals("CSDVersion")) { // NON_NLS // This is dependant on the fact that ProductName shows up first in the module output version = version + " " + value; - } - else if(name.equals("SystemRoot")){ + } else if (name.equals("SystemRoot")) { systemRoot = value; - } - else if(name.equals("ProductId")){ + } else if (name.equals("ProductId")) { productId = value; - } - else if(name.equals("RegisteredOwner")){ + } else if (name.equals("RegisteredOwner")) { regOwner = value; - } - else if(name.equals("RegisteredOrganization")){ + } else if (name.equals("RegisteredOrganization")) { regOrg = value; - } - else if(name.equals("InstallDate")){ + } else if (name.equals("InstallDate")) { try { Long epochtime = new SimpleDateFormat("EEE MMM d HH:mm:ss yyyy").parse(value).getTime(); installtime = epochtime; @@ -418,30 +409,37 @@ class ExtractRegistry extends Extract { } } } - + try { Collection bbattributes = new ArrayList<>(); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(), parentModuleName, version)); - if(installtime != null){ + if (installtime != null) { bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(), parentModuleName, installtime)); } bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH.getTypeID(), parentModuleName, systemRoot)); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PRODUCT_ID.getTypeID(), parentModuleName, productId)); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_OWNER.getTypeID(), parentModuleName, regOwner)); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ORGANIZATION.getTypeID(), parentModuleName, regOrg)); - BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO); - bbart.addAttributes(bbattributes); + + // Check if there is already an OS_INFO artifact for this file, and add to that if possible. + ArrayList results = tempDb.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId()); + if (results.isEmpty()) { + BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO); + bbart.addAttributes(bbattributes); + } else { + results.get(0).addAttributes(bbattributes); + } + } catch (TskCoreException ex) { logger.log(Level.SEVERE, "Error adding installed program artifact to blackboard."); //NON-NLS } - } - else if(dataType.equals("Profiler")){ // NON-NLS - + } else if (dataType.equals("Profiler")) { // NON-NLS + String os = ""; String procArch = ""; String procId = ""; String tempDir = ""; - + for (int j = 0; j < myartlist.getLength(); j++) { Node artchild = myartlist.item(j); // If it has attributes, then it is an Element (based off API) @@ -450,39 +448,42 @@ class ExtractRegistry extends Extract { String value = artnode.getTextContent().trim(); String name = artnode.getAttribute("name"); - - if(name.equals("OS")){ // NON-NLS + + if (name.equals("OS")) { // NON-NLS os = value; - } - else if(name.equals("PROCESSOR_ARCHITECTURE")){ // NON-NLS + } else if (name.equals("PROCESSOR_ARCHITECTURE")) { // NON-NLS procArch = value; - } - else if(name.equals("PROCESSOR_IDENTIFIER")){ //NON-NLS + } else if (name.equals("PROCESSOR_IDENTIFIER")) { //NON-NLS procId = value; - } - else if(name.equals("TEMP")){ + } else if (name.equals("TEMP")) { tempDir = value; } } } - + try { Collection bbattributes = new ArrayList<>(); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VERSION.getTypeID(), parentModuleName, os)); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROCESSOR_ARCHITECTURE.getTypeID(), parentModuleName, procArch)); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROCESSOR_NAME.getTypeID(), parentModuleName, procId)); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TEMP_DIR.getTypeID(), parentModuleName, tempDir)); - BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO); - bbart.addAttributes(bbattributes); - } catch (TskCoreException ex) { + + // Check if there is already an OS_INFO artifact for this file and add to that if possible + ArrayList results = tempDb.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId()); + if (results.isEmpty()) { + BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO); + bbart.addAttributes(bbattributes); + } else { + results.get(0).addAttributes(bbattributes); + } + } catch (TskCoreException ex) { logger.log(Level.SEVERE, "Error adding os info artifact to blackboard."); //NON-NLS } - } - else if(dataType.equals("CompName")){ // NON-NLS - + } else if (dataType.equals("CompName")) { // NON-NLS + String compName = ""; String domain = ""; - + for (int j = 0; j < myartlist.getLength(); j++) { Node artchild = myartlist.item(j); // If it has attributes, then it is an Element (based off API) @@ -491,27 +492,32 @@ class ExtractRegistry extends Extract { String value = artnode.getTextContent().trim(); String name = artnode.getAttribute("name"); - - if(name.equals("ComputerName")){ // NON-NLS + + if (name.equals("ComputerName")) { // NON-NLS compName = value; - } - else if(name.equals("Domain")){ // NON-NLS + } else if (name.equals("Domain")) { // NON-NLS domain = value; } } } - + try { Collection bbattributes = new ArrayList<>(); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), parentModuleName, compName)); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(), parentModuleName, domain)); - BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO); - bbart.addAttributes(bbattributes); - } catch (TskCoreException ex) { + + // Check if there is already an OS_INFO artifact for this file and add to that if possible + ArrayList results = tempDb.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId()); + if (results.isEmpty()) { + BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO); + bbart.addAttributes(bbattributes); + } else { + results.get(0).addAttributes(bbattributes); + } + } catch (TskCoreException ex) { logger.log(Level.SEVERE, "Error adding os info artifact to blackboard."); //NON-NLS } - } - else{ + } else { for (int j = 0; j < myartlist.getLength(); j++) { Node artchild = myartlist.item(j); // If it has attributes, then it is an Element (based off API) @@ -531,7 +537,7 @@ class ExtractRegistry extends Extract { // @@@ BC: Why are we ignoring this... break; case "usb": //NON-NLS - try { + try { Long usbMtime = Long.parseLong(artnode.getAttribute("mtime")); //NON-NLS usbMtime = Long.valueOf(usbMtime.toString()); @@ -539,7 +545,7 @@ class ExtractRegistry extends Extract { bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(), parentModuleName, usbMtime)); String dev = artnode.getAttribute("dev"); //NON-NLS String make = ""; - String model = dev; + String model = dev; if (dev.toLowerCase().contains("vid")) { //NON-NLS USBInfo info = usbMapper.parseAndLookup(dev); if (info.getVendor() != null) { @@ -569,7 +575,7 @@ class ExtractRegistry extends Extract { try { bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(), parentModuleName, value)); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(),parentModuleName, itemMtime)); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(), parentModuleName, itemMtime)); BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_INSTALLED_PROG); bbart.addAttributes(bbattributes); } catch (TskCoreException ex) { @@ -593,7 +599,7 @@ class ExtractRegistry extends Extract { logger.log(Level.SEVERE, "Error adding recent object artifact to blackboard."); //NON-NLS } break; - + case "ProcessorArchitecture": //NON-NLS // Architecture is now included under Profiler //try { @@ -608,7 +614,7 @@ class ExtractRegistry extends Extract { // logger.log(Level.SEVERE, "Error adding os info artifact to blackboard."); //NON-NLS //} break; - + case "ProfileList": //NON-NLS try { @@ -618,31 +624,30 @@ class ExtractRegistry extends Extract { BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_ACCOUNT); bbart.addAttribute(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME.getTypeID(), - parentModuleName, username)); + parentModuleName, username)); bbart.addAttribute(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_ID.getTypeID(), - parentModuleName, sid)); + parentModuleName, sid)); bbart.addAttribute(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH.getTypeID(), - parentModuleName, homeDir)); + parentModuleName, homeDir)); } catch (TskCoreException ex) { logger.log(Level.SEVERE, "Error adding account artifact to blackboard."); //NON-NLS } - break; - + break; + case "NtuserNetwork": // NON-NLS - try{ + try { String localPath = artnode.getAttribute("localPath"); String remoteName = value; - - BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_DEVICE_ATTACHED); - bbart.addAttribute(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH.getTypeID(), - parentModuleName, localPath)); - bbart.addAttribute(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), - parentModuleName, remoteName)); - + BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_REMOTE_DRIVE); + bbart.addAttribute(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LOCAL_PATH.getTypeID(), + parentModuleName, localPath)); + bbart.addAttribute(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REMOTE_PATH.getTypeID(), + parentModuleName, remoteName)); + } catch (TskCoreException ex) { logger.log(Level.SEVERE, "Error adding network artifact to blackboard."); //NON-NLS } - break; + break; default: logger.log(Level.WARNING, "Unrecognized node name: {0}", dataType);