diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED index 77d6eb550f..052850870e 100755 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED @@ -5,15 +5,10 @@ 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 DomainCategoryRunner_moduleName_text=DomainCategoryRunner @@ -27,7 +22,6 @@ ExtractEdge_process_errMsg_errGettingWebCacheFiles=Error trying to retrieving Ed ExtractEdge_process_errMsg_spartanFail=Failure processing Microsoft Edge spartan.edb file ExtractEdge_process_errMsg_unableFindESEViewer=Unable to find ESEDatabaseViewer ExtractEdge_process_errMsg_webcacheFail=Failure processing Microsoft Edge WebCacheV01.dat file -# {0} - sub module name ExtractIE_executePasco_errMsg_errorRunningPasco={0}: Error analyzing Internet Explorer web history ExtractOs.androidOs.label=Android ExtractOs.androidVolume.label=OS Drive (Android) @@ -60,7 +54,6 @@ ExtractOs.windowsVolume.label=OS Drive (Windows) ExtractOs.yellowDogLinuxOs.label=Linux (Yellow Dog) ExtractOs.yellowDogLinuxVolume.label=OS Drive (Linux Yellow Dog) ExtractOS_progressMessage=Checking for OS -# {0} - sub module name ExtractPrefetch_errMsg_prefetchParsingFailed={0}: Error analyzing prefetch files ExtractPrefetch_module_name=Windows Prefetch Extractor ExtractRecycleBin_module_name=Recycle Bin @@ -156,19 +149,13 @@ Firefox.getDlV24.errMsg.errAnalyzeFile={0}: Error while trying to analyze file:{ Firefox.getDlV24.errMsg.errParsingArtifacts={0}: Error parsing {1} Firefox web download artifacts. Progress_Message_Analyze_Registry=Analyzing Registry Files Progress_Message_Analyze_Usage=Data Sources Usage Analysis -# {0} - browserName Progress_Message_Chrome_AutoFill=Chrome Auto Fill Browser {0} -# {0} - browserName Progress_Message_Chrome_Bookmarks=Chrome Bookmarks Browser {0} Progress_Message_Chrome_Cache=Chrome Cache -# {0} - browserName Progress_Message_Chrome_Cookies=Chrome Cookies Browser {0} -# {0} - browserName Progress_Message_Chrome_Downloads=Chrome Downloads Browser {0} Progress_Message_Chrome_FormHistory=Chrome Form History -# {0} - browserName Progress_Message_Chrome_History=Chrome History Browser {0} -# {0} - browserName Progress_Message_Chrome_Logins=Chrome Logins Browser {0} Progress_Message_Edge_Bookmarks=Microsoft Edge Bookmarks Progress_Message_Edge_Cookies=Microsoft Edge Cookies @@ -223,7 +210,6 @@ 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/Extract.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Extract.java index 872465e460..4118501e80 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Extract.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Extract.java @@ -34,6 +34,7 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.logging.Level; import org.openide.util.NbBundle.Messages; @@ -66,6 +67,7 @@ abstract class Extract { private final ArrayList errorMessages = new ArrayList<>(); String moduleName = ""; boolean dataFound = false; + private RAOsAccountCache osAccountCache = null; Extract() { } @@ -89,6 +91,11 @@ abstract class Extract { void configExtractor() throws IngestModuleException { } + void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar, RAOsAccountCache osAccountCache) { + this.osAccountCache = osAccountCache; + process(dataSource, context, progressBar); + } + abstract void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar); void complete() { @@ -137,7 +144,7 @@ abstract class Extract { DataArtifact createDataArtifactWithAttributes(BlackboardArtifact.ARTIFACT_TYPE type, AbstractFile file, Collection attributes) { try { - Optional optional = file.getOsAccount(); + Optional optional = getOsAccount(file); DataArtifact bbart = file.newDataArtifact(new BlackboardArtifact.Type(type), attributes, optional.isPresent() ? optional.get() : null); return bbart; } catch (TskException ex) { @@ -498,4 +505,12 @@ abstract class Extract { return tempFile; } + + Optional getOsAccount(AbstractFile file) throws TskCoreException { + if(osAccountCache == null) { + return file.getOsAccount(); + } + + return osAccountCache.getOsAccount(file); + } } diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java index 4a735e890d..df5bf9306a 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java @@ -2226,7 +2226,9 @@ class ExtractRegistry extends Extract { if (homeDir != null && !homeDir.isEmpty()) { List attributes = new ArrayList<>(); - attributes.add(createOsAccountAttribute(TSK_HOME_DIR, homeDir, osAccount, host, file)); + String dir = homeDir.replaceFirst("^(%\\w*%)", ""); + dir = dir.replace("\\", "/"); + attributes.add(createOsAccountAttribute(TSK_HOME_DIR, dir, osAccount, host, file)); osAccount.addAttributes(attributes); } diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAImageIngestModule.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAImageIngestModule.java index 54474ab677..3ce8d88b39 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAImageIngestModule.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAImageIngestModule.java @@ -26,6 +26,7 @@ import java.io.File; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.logging.Level; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; @@ -39,6 +40,9 @@ import org.sleuthkit.autopsy.ingest.IngestMessage.MessageType; import org.sleuthkit.datamodel.Content; import org.sleuthkit.autopsy.ingest.IngestModule.ProcessResult; import org.sleuthkit.autopsy.ingest.IngestJobContext; +import org.sleuthkit.datamodel.DataSource; +import org.sleuthkit.datamodel.OsAccount; +import org.sleuthkit.datamodel.SleuthkitCase; /** * Recent activity image ingest module @@ -51,6 +55,8 @@ public final class RAImageIngestModule implements DataSourceIngestModule { private final IngestServices services = IngestServices.getInstance(); private IngestJobContext context; private final StringBuilder subCompleted = new StringBuilder(); + protected SleuthkitCase tskCase; + private RAOsAccountCache accountCache = new RAOsAccountCache(); RAImageIngestModule() { } @@ -58,6 +64,8 @@ public final class RAImageIngestModule implements DataSourceIngestModule { @Override public void startUp(IngestJobContext context) throws IngestModuleException { this.context = context; + + tskCase = Case.getCurrentCase().getSleuthkitCase(); Extract iexplore; Extract edge; @@ -83,17 +91,21 @@ public final class RAImageIngestModule implements DataSourceIngestModule { Extract webAccountType = new ExtractWebAccountType(); Extract messageDomainType = new DomainCategoryRunner(); + extractors.add(recentDocuments); + extractors.add(registry); // this should run after quicker modules like the browser modules and needs to run before the DataSourceUsageAnalyzer + extractors.add(osExtract); // this needs to run before the DataSourceUsageAnalyzer + extractors.add(dataSourceAnalyzer); //this needs to run after ExtractRegistry and ExtractOs extractors.add(chrome); extractors.add(firefox); extractors.add(iexplore); extractors.add(edge); extractors.add(safari); - extractors.add(recentDocuments); +// extractors.add(recentDocuments); extractors.add(SEUQA); // this needs to run after the web browser modules extractors.add(webAccountType); // this needs to run after the web browser modules - extractors.add(registry); // this should run after quicker modules like the browser modules and needs to run before the DataSourceUsageAnalyzer - extractors.add(osExtract); // this needs to run before the DataSourceUsageAnalyzer - extractors.add(dataSourceAnalyzer); //this needs to run after ExtractRegistry and ExtractOs +// extractors.add(registry); // this should run after quicker modules like the browser modules and needs to run before the DataSourceUsageAnalyzer +// extractors.add(osExtract); // this needs to run before the DataSourceUsageAnalyzer +// extractors.add(dataSourceAnalyzer); //this needs to run after ExtractRegistry and ExtractOs extractors.add(zoneInfo); // this needs to run after the web browser modules extractors.add(recycleBin); // this needs to run after ExtractRegistry and ExtractOS extractors.add(sru); @@ -132,7 +144,10 @@ public final class RAImageIngestModule implements DataSourceIngestModule { progressBar.progress(extracter.getName(), i); try { - extracter.process(dataSource, context, progressBar); + extracter.process(dataSource, context, progressBar, accountCache); + if(extracter instanceof ExtractRegistry) { + accountCache.initialize(tskCase, ((DataSource)dataSource).getHost()); + } } catch (Exception ex) { logger.log(Level.SEVERE, "Exception occurred in " + extracter.getName(), ex); //NON-NLS subCompleted.append(NbBundle.getMessage(this.getClass(), "RAImageIngestModule.process.errModFailed", @@ -220,7 +235,7 @@ public final class RAImageIngestModule implements DataSourceIngestModule { * * @return Path to directory */ - protected static String getRATempPath(Case a_case, String mod) { + static String getRATempPath(Case a_case, String mod) { String tmpDir = a_case.getTempDirectory() + File.separator + "RecentActivity" + File.separator + mod; //NON-NLS File dir = new File(tmpDir); if (dir.exists() == false) { @@ -239,7 +254,7 @@ public final class RAImageIngestModule implements DataSourceIngestModule { * * @return Path to directory */ - protected static String getRAOutputPath(Case a_case, String mod) { + static String getRAOutputPath(Case a_case, String mod) { String tmpDir = a_case.getModuleDirectory() + File.separator + "RecentActivity" + File.separator + mod; //NON-NLS File dir = new File(tmpDir); if (dir.exists() == false) { diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAOsAccountCache.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAOsAccountCache.java new file mode 100755 index 0000000000..32f91ddf76 --- /dev/null +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAOsAccountCache.java @@ -0,0 +1,108 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2021 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.recentactivity; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.BlackboardAttribute; +import org.sleuthkit.datamodel.Host; +import org.sleuthkit.datamodel.OsAccount; +import org.sleuthkit.datamodel.OsAccountAttribute; +import org.sleuthkit.datamodel.SleuthkitCase; +import org.sleuthkit.datamodel.TskCoreException; + +/** + * Cache of OsAccounts for a given host to be used by the various + * Recent Activity Extractors. + * + */ +final class RAOsAccountCache { + private final Map accountCache = new HashMap<>(); + + /** + * initialize the account map for the given host. This should be done after + * the ExtractRegistry is run. + * + * @param tskCase + * @param host + * + * @throws TskCoreException + */ + void initialize(SleuthkitCase tskCase, Host host) throws TskCoreException { + buildAccountMap(tskCase, host); + } + + /** + * Returns the appropriate OsAccount for the given file. + * + * If the file is not associated with an OsAccount, try to find one + * based on the location of the file. + * + * If the file is associated with the system account of S-1-5-32-544 use + * the file path to determine which user account to associate the file with. + * + * + * @param file + * @return + * @throws TskCoreException + */ + Optional getOsAccount(AbstractFile file) throws TskCoreException { + Optional optional = file.getOsAccount(); + + if(!optional.isPresent()) { + return getAccountForPath(file.getParentPath()); + } + + OsAccount osAccount = optional.get(); + if(osAccount.getName().equals("S-1-5-32-544")) { + return getAccountForPath(file.getParentPath()); + } + + return optional; + } + + private Optional getAccountForPath(String path) { + return null; + } + + /** + * Build a map of user home directories to OsAccounts for the given host. + * + * @throws TskCoreException + */ + private void buildAccountMap(SleuthkitCase tskCase, Host host) throws TskCoreException { + BlackboardAttribute.Type homeDir = new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_HOME_DIR); + List accounts = tskCase.getOsAccountManager().getAccounts(host); + + for(OsAccount account: accounts) { + List attributeList = account.getOsAccountAttributes(); + + for(OsAccountAttribute attribute: attributeList) { + if(attribute.getHostId().isPresent() + && attribute.getHostId().get().equals(host.getId()) + && attribute.getAttributeType().equals(homeDir)) { + accountCache.put(attribute.getValueString(), account); + } + } + } + } +}