From 8c21f845640798da36457618d923e03dc82651e2 Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Thu, 11 Jun 2020 08:46:19 -0400 Subject: [PATCH 1/3] Initial Commit Initial commit --- .../recentactivity/Bundle.properties-MERGED | 7 ++ .../recentactivity/ExtractRegistry.java | 90 ++++++++++++++++++- thirdparty/rr-full/plugins/system | 1 + 3 files changed, 97 insertions(+), 1 deletion(-) diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED index 310602b0f9..8b3d9cf402 100755 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED @@ -5,10 +5,15 @@ ChromeCacheExtract_adding_artifacts_msg=Chrome Cache: Adding %d artifacts for an ChromeCacheExtract_adding_extracted_files_msg=Chrome Cache: Adding %d extracted files for analysis. ChromeCacheExtract_loading_files_msg=Chrome Cache: Loading files from %s. ChromeCacheExtractor.moduleName=ChromeCacheExtractor +# {0} - module name +# {1} - row number +# {2} - table length +# {3} - cache path ChromeCacheExtractor.progressMsg={0}: Extracting cache entry {1} of {2} entries from {3} DataSourceUsage_AndroidMedia=Android Media Card DataSourceUsage_DJU_Drone_DAT=DJI Internal SD Card DataSourceUsage_FlashDrive=Flash Drive +# {0} - OS name DataSourceUsageAnalyzer.customVolume.label=OS Drive ({0}) DataSourceUsageAnalyzer.parentModuleName=Recent Activity Extract.indexError.message=Failed to index artifact for keyword search. @@ -200,8 +205,10 @@ Recently_Used_Artifacts_Mmc=Recently opened according to Windows Management Cons Recently_Used_Artifacts_Office_Trustrecords=Stored in TrustRecords because Office security exception was granted Recently_Used_Artifacts_Officedocs=Recently opened according to Office MRU Recently_Used_Artifacts_Winrar=Recently opened according to WinRAR MRU +Registry_System_Bam=Recently Executed according to Background Activity Moderator (BAM) RegRipperFullNotFound=Full version RegRipper executable not found. RegRipperNotFound=Autopsy RegRipper executable not found. +# {0} - file name SearchEngineURLQueryAnalyzer.init.exception.msg=Unable to find {0}. SearchEngineURLQueryAnalyzer.moduleName.text=Search Engine SearchEngineURLQueryAnalyzer.engineName.none=NONE diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java index 365f71c81a..1117faba64 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java @@ -112,7 +112,8 @@ import org.sleuthkit.datamodel.TskDataException; "Recently_Used_Artifacts_Winrar=Recently opened according to WinRAR MRU", "Recently_Used_Artifacts_Officedocs=Recently opened according to Office MRU", "Recently_Used_Artifacts_Adobe=Recently opened according to Adobe MRU", - "Recently_Used_Artifacts_Mediaplayer=Recently opened according to Media Player MRU" + "Recently_Used_Artifacts_Mediaplayer=Recently opened according to Media Player MRU", + "Registry_System_Bam=Recently Executed according to Background Activity Moderator (BAM)" }) class ExtractRegistry extends Extract { @@ -337,6 +338,12 @@ class ExtractRegistry extends Extract { } catch (IOException | TskCoreException ex) { logger.log(Level.WARNING, String.format("Unable to get shell bags from file %s", regOutputFiles.fullPlugins), ex); } + } else if (regFileNameLocal.toLowerCase().contains("system")) { + try { + createSystemArtifacts(regOutputFiles.fullPlugins, regFile); + } catch (IOException ex) { + logger.log(Level.WARNING, String.format("Unable to get artifacts from file %s", regOutputFiles.fullPlugins), ex); + } } try { Report report = currentCase.addReport(regOutputFiles.fullPlugins, @@ -1227,6 +1234,87 @@ class ExtractRegistry extends Extract { } } + /** + * Create artifacts from the System registry Hive + * + * @param regFileName name of the regripper output file + * + * @param regFile registry file the artifact is associated with + * + * @throws FileNotFound and IOException + */ + private void createSystemArtifacts(String regFileName, AbstractFile regFile) throws FileNotFoundException, IOException { + File regfile = new File(regFileName); + try (BufferedReader reader = new BufferedReader(new FileReader(regfile))) { + String line = reader.readLine(); + while (line != null) { + line = line.trim(); + + if (line.matches("^bam v.*")) { + parseBamKey(regFile, reader, Bundle.Registry_System_Bam()); + } + line = reader.readLine(); + } + } + } + + /** + * Create artifacts from BAM Regripper Plugin records + * + * @param regFile registry file the artifact is associated with + * + * @param reader buffered reader to parse adobemru records + * + * @param comment string that will populate attribute TSK_COMMENT + * + * @throws FileNotFound and IOException + */ + private void parseBamKey(AbstractFile regFile, BufferedReader reader, String comment) throws FileNotFoundException, IOException { + List bbartifacts = new ArrayList<>(); + String line = reader.readLine(); + // Read thru first bam output to get to second bam output which is the same but delimited + while (!line.contains(SECTION_DIVIDER)) { + line = reader.readLine(); + line = line.trim(); + } + line = reader.readLine(); + line = line.trim(); + while (!line.contains(SECTION_DIVIDER)) { + // Split the line into it parts based on delimiter of "|" + // 1570493613|BAM|||\Device\HarddiskVolume3\Program Files\TechSmith\Snagit 2018\Snagit32.exe (S-1-5-21-3042408413-2583535980-1301764466-1001) + String tokens[] = line.split("\\|"); + Long progRunDateTime = Long.valueOf(tokens[0]); + // Split on " (S-" as this signifies a User SID, if S- not used then may have issues becuase of (x86) in path is valid. + // We can add the S- back to the string that we split on since S- is a valid beginning of a User SID + String fileNameSid[] = tokens[4].split("\\s+\\(S-"); + String userSid = "S-" + fileNameSid[1].substring(0, fileNameSid[1].length() - 1); + String fileName = fileNameSid[0]; + if (fileName.startsWith("\\Device\\HarddiskVolume")) { + // Start at point past the 2nd slash + int fileNameStart = fileName.indexOf("\\", 16); + fileName = fileName.substring(fileNameStart, fileName.length()); + + } + Collection attributes = new ArrayList<>(); + attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, getName(), fileName)); + attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME, getName(), userSid)); + attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, getName(), progRunDateTime)); + attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COMMENT, getName(), comment)); + BlackboardArtifact bba = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_PROG_RUN, regFile, attributes); + if (bba != null) { + bbartifacts.add(bba); + bba = createAssociatedArtifact(FilenameUtils.normalize(fileName, true), bba); + if (bba != null) { + bbartifacts.add(bba); + } + } + line = reader.readLine(); + } + if (!bbartifacts.isEmpty()) { + postArtifacts(bbartifacts); + } + } + /** * Create recently used artifacts from adobemru Regripper Plugin records * diff --git a/thirdparty/rr-full/plugins/system b/thirdparty/rr-full/plugins/system index f95897e19d..568b92c648 100644 --- a/thirdparty/rr-full/plugins/system +++ b/thirdparty/rr-full/plugins/system @@ -4,6 +4,7 @@ appcompatcache auditfail backuprestore bam +bam_tln bthport comfoo compname From 25d9db9c0bedea0e24b6af4fa8e8f441d8a17b9a Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Mon, 22 Jun 2020 16:48:16 -0400 Subject: [PATCH 2/3] Update ExtractRegistry.java Added mapping of username from SAM for BAM and others that may want to use it. --- .../recentactivity/ExtractRegistry.java | 76 ++++++++++++++++++- 1 file changed, 74 insertions(+), 2 deletions(-) diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java index 1117faba64..946d64711a 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java @@ -79,6 +79,7 @@ import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.BlackboardArtifact; import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT; +import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_OS_ACCOUNT; import org.sleuthkit.datamodel.BlackboardAttribute; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT; @@ -86,6 +87,8 @@ import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DAT import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_MODIFIED; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_ID; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException; import org.sleuthkit.datamodel.Report; @@ -161,6 +164,7 @@ class ExtractRegistry extends Extract { private final Path rrFullHome; // Path to the full version of RegRipper private Content dataSource; private IngestJobContext context; + private Map userNameMap; private static final String SHELLBAG_ARTIFACT_NAME = "RA_SHELL_BAG"; //NON-NLS private static final String SHELLBAG_ATTRIBUTE_LAST_WRITE = "RA_SHELL_BAG_LAST_WRITE"; //NON-NLS @@ -230,6 +234,17 @@ class ExtractRegistry extends Extract { List allRegistryFiles = new ArrayList<>(); org.sleuthkit.autopsy.casemodule.services.FileManager fileManager = currentCase.getServices().getFileManager(); + // find the sam hives', process this first so we can map the user id's and sids for later use + try { + allRegistryFiles.addAll(fileManager.findFiles(dataSource, "sam", "/system32/config")); //NON-NLS + } catch (TskCoreException ex) { + String msg = NbBundle.getMessage(this.getClass(), + "ExtractRegistry.findRegFiles.errMsg.errReadingFile", "sam"); + logger.log(Level.WARNING, msg, ex); + this.addErrorMessage(this.getName() + ": " + msg); + } + + // find the user-specific ntuser-dat files try { allRegistryFiles.addAll(fileManager.findFiles(dataSource, "ntuser.dat")); //NON-NLS @@ -245,7 +260,7 @@ class ExtractRegistry extends Extract { } // find the system hives' - String[] regFileNames = new String[]{"system", "software", "security", "sam"}; //NON-NLS + String[] regFileNames = new String[]{"system", "software", "security"}; //NON-NLS for (String regFileName : regFileNames) { try { allRegistryFiles.addAll(fileManager.findFiles(dataSource, regFileName, "/system32/config")); //NON-NLS @@ -976,6 +991,16 @@ class ExtractRegistry extends Extract { // index the artifact for keyword search newArtifacts.add(bbart); } + // Get a mapping of user sids to user names and save globally so it can be used for other areas + // of the registry, ie: BAM key + try { + userNameMap = makeUserNameMap(dataSource); + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Unable to create OS Account user name map", ex); + // This is not the end of the world we will just continue without + // user names + userNameMap = new HashMap<>(); + } return true; } catch (FileNotFoundException ex) { logger.log(Level.WARNING, "Error finding the registry file.", ex); //NON-NLS @@ -1288,6 +1313,10 @@ class ExtractRegistry extends Extract { // We can add the S- back to the string that we split on since S- is a valid beginning of a User SID String fileNameSid[] = tokens[4].split("\\s+\\(S-"); String userSid = "S-" + fileNameSid[1].substring(0, fileNameSid[1].length() - 1); + String userName = userNameMap.get(userSid); + if (userName == null) { + userName = userSid; + } String fileName = fileNameSid[0]; if (fileName.startsWith("\\Device\\HarddiskVolume")) { // Start at point past the 2nd slash @@ -1297,7 +1326,7 @@ class ExtractRegistry extends Extract { } Collection attributes = new ArrayList<>(); attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, getName(), fileName)); - attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME, getName(), userSid)); + attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME, getName(), userName)); attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, getName(), progRunDateTime)); attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COMMENT, getName(), comment)); BlackboardArtifact bba = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_PROG_RUN, regFile, attributes); @@ -1717,6 +1746,49 @@ class ExtractRegistry extends Extract { return null; } + /** + * Create a map of userids to usernames from the OS Accounts. + * + * @param dataSource + * + * @return A Map of userIDs and userNames + * + * @throws TskCoreException + */ + private Map makeUserNameMap(Content dataSource) throws TskCoreException { + Map userNameMap = new HashMap<>(); + + List accounts = blackboard.getArtifacts(TSK_OS_ACCOUNT.getTypeID(), dataSource.getId()); + + for (BlackboardArtifact account : accounts) { + BlackboardAttribute nameAttribute = getAttributeForArtifact(account, TSK_USER_NAME); + BlackboardAttribute idAttribute = getAttributeForArtifact(account, TSK_USER_ID); + + String userName = nameAttribute != null ? nameAttribute.getDisplayString() : ""; + String userID = idAttribute != null ? idAttribute.getDisplayString() : ""; + + if (!userID.isEmpty()) { + userNameMap.put(userID, userName); + } + } + + return userNameMap; + } + + /** + * Gets the attribute for the given type from the given artifact. + * + * @param artifact BlackboardArtifact to get the attribute from + * @param type The BlackboardAttribute Type to get + * + * @return BlackboardAttribute for given artifact and type + * + * @throws TskCoreException + */ + private BlackboardAttribute getAttributeForArtifact(BlackboardArtifact artifact, BlackboardAttribute.ATTRIBUTE_TYPE type) throws TskCoreException { + return artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.fromID(type.getTypeID()))); + } + /** * Create the shellbag artifacts from the list of ShellBag objects. * From 611931c30db8165b7e1e1bd270215881901deadd Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Sat, 27 Jun 2020 13:51:11 -0400 Subject: [PATCH 3/3] Update ExtractRegistry.java Change from string to char --- .../org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java index 54e24d994d..fd3584d843 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java @@ -1341,7 +1341,7 @@ class ExtractRegistry extends Extract { String fileName = fileNameSid[0]; if (fileName.startsWith("\\Device\\HarddiskVolume")) { // Start at point past the 2nd slash - int fileNameStart = fileName.indexOf("\\", 16); + int fileNameStart = fileName.indexOf('\\', 16); fileName = fileName.substring(fileNameStart, fileName.length()); }