diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED index c8cebe69fc..4d4d3cf10f 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED @@ -17,7 +17,10 @@ ContextViewer.messageFrom=From ContextViewer.messageOn=On ContextViewer.messageTo=To ContextViewer.on=Opened at +ContextViewer.programExecution=Program Execution: ContextViewer.recentDocs=Recent Documents: +ContextViewer.runOn=Program Run On +ContextViewer.runUnknown=\ Program Run at unknown time ContextViewer.title=Context ContextViewer.toolTip=Displays context for selected file. ContextViewer.unknown=Opened at unknown time diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java index 7200f6747f..f7f1f6559e 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java @@ -334,7 +334,8 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte @NbBundle.Messages({ "ContextViewer.attachmentSource=Attached to: ", "ContextViewer.downloadSource=Downloaded from: ", - "ContextViewer.recentDocs=Recent Documents: " + "ContextViewer.recentDocs=Recent Documents: ", + "ContextViewer.programExecution=Program Execution: " }) private void setSourceFields(BlackboardArtifact associatedArtifact) throws TskCoreException { if (BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID() == associatedArtifact.getArtifactTypeID() @@ -357,6 +358,11 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte javax.swing.JPanel usagePanel = new ContextUsagePanel(sourceName, sourceText, associatedArtifact); contextUsagePanels.add(usagePanel); + } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN.getTypeID() == associatedArtifact.getArtifactTypeID()) { + String sourceName = Bundle.ContextViewer_programExecution(); + String sourceText = programExecArtifactToString(associatedArtifact); + javax.swing.JPanel usagePanel = new ContextUsagePanel(sourceName, sourceText, associatedArtifact); + contextUsagePanels.add(usagePanel); } } @@ -416,6 +422,36 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte return sb.toString(); } + /** + * Returns a display string with Program Execution + * artifact. + * + * @param artifact artifact to get doc from. + * + * @return Display string with download URL and date/time. + * + * @throws TskCoreException + */ + @NbBundle.Messages({ + "ContextViewer.runOn=Program Run On", + "ContextViewer.runUnknown= Program Run at unknown time" + }) + private String programExecArtifactToString(BlackboardArtifact artifact) throws TskCoreException { + StringBuilder sb = new StringBuilder(ARTIFACT_STR_MAX_LEN); + Map attributesMap = getAttributesMap(artifact); + + BlackboardAttribute attribute = attributesMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME); + + if (BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN.getTypeID() == artifact.getArtifactTypeID()) { + if (attribute != null && attribute.getValueLong() > 0) { + appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, attributesMap, Bundle.ContextViewer_runOn()); + } else { + sb.append(Bundle.ContextViewer_runUnknown()); + } + } + return sb.toString(); + } + /** * Returns a abbreviated display string for a message artifact. * diff --git a/Core/src/org/sleuthkit/autopsy/events/AutopsyEventPublisher.java b/Core/src/org/sleuthkit/autopsy/events/AutopsyEventPublisher.java index 02a5d2e2ab..f3fb273bcf 100644 --- a/Core/src/org/sleuthkit/autopsy/events/AutopsyEventPublisher.java +++ b/Core/src/org/sleuthkit/autopsy/events/AutopsyEventPublisher.java @@ -42,9 +42,9 @@ public final class AutopsyEventPublisher { private static final Logger logger = Logger.getLogger(AutopsyEventPublisher.class.getName()); private static final int MAX_REMOTE_EVENT_PUBLISH_TRIES = 1; private final LocalEventPublisher localPublisher; // LocalEventPublisher is thread-safe - @GuardedBy("this)") + @GuardedBy("this") private RemoteEventPublisher remotePublisher; - @GuardedBy("this)") + @GuardedBy("this") private String currentChannelName; /** diff --git a/RecentActivity/build.xml b/RecentActivity/build.xml index d298fa519a..4b3d8e3347 100644 --- a/RecentActivity/build.xml +++ b/RecentActivity/build.xml @@ -22,6 +22,9 @@ + + + diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED index 35666d6973..310602b0f9 100755 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED @@ -55,6 +55,13 @@ ExtractSafari_Error_Getting_History=An error occurred while processing Safari hi ExtractSafari_Error_Parsing_Bookmark=An error occured while processing Safari Bookmark files ExtractSafari_Error_Parsing_Cookies=An error occured while processing Safari Cookies files ExtractSafari_Module_Name=Safari +ExtractSru_error_finding_export_srudb_program=Error finding export_srudb program +ExtractSru_module_name=System Resource Usage Extractor +ExtractSru_process_error_executing_export_srudb_program=Error running export_srudb program +ExtractSru_process_errormsg_find_software_hive=Unable to find SOFTWARE HIVE file +ExtractSru_process_errormsg_find_srudb_dat=Unable to find srudb.dat file +ExtractSru_process_errormsg_write_software_hive=Unable to write SOFTWARE HIVE file +ExtractSru_process_errormsg_write_srudb_dat=Unable to write srudb.dat file ExtractZone_Internet=Internet Zone ExtractZone_Local_Intranet=Local Intranet Zone ExtractZone_Local_Machine=Local Machine Zone diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractSru.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractSru.java new file mode 100644 index 0000000000..08782097bf --- /dev/null +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractSru.java @@ -0,0 +1,484 @@ + /* + * + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * + * 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.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.logging.Level; +import java.util.Map; +import org.apache.commons.io.FilenameUtils; +import org.openide.modules.InstalledFileLocator; +import org.openide.util.NbBundle.Messages; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.services.FileManager; +import org.sleuthkit.autopsy.coreutils.ExecUtil; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.coreutils.PlatformUtil; +import org.sleuthkit.autopsy.coreutils.SQLiteDBConnect; +import org.sleuthkit.autopsy.datamodel.ContentUtils; +import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProcessTerminator; +import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress; +import org.sleuthkit.autopsy.ingest.IngestJobContext; +import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.Blackboard; +import org.sleuthkit.datamodel.BlackboardArtifact; +import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT; +import org.sleuthkit.datamodel.BlackboardAttribute; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT; +import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.TskCoreException; + + +/** + * Extract the System Resource Usage database to a temp directory so it can be parsed into a SQLite db + * and then brought into extracted content + */ +final class ExtractSru extends Extract { + + private static final Logger logger = Logger.getLogger(ExtractSru.class.getName()); + + private IngestJobContext context; + + private static final String APPLICATION_USAGE_SOURCE_NAME = "System Resource Usage - Application Usage"; //NON-NLS + private static final String NETWORK_USAGE_SOURCE_NAME = "System Resource Usage - Network Usage"; + +// private static final String ARTIFACT_ATTRIBUTE_NAME = "TSK_ARTIFACT_NAME"; //NON-NLS + + private static final String MODULE_NAME = "extractSRU"; //NON-NLS + + private static final String SRU_TOOL_FOLDER = "markmckinnon"; //NON-NLS + private static final String SRU_TOOL_NAME_WINDOWS_32 = "Export_Srudb_32.exe"; //NON-NLS + private static final String SRU_TOOL_NAME_WINDOWS_64 = "Export_Srudb_64.exe"; //NON-NLS + private static final String SRU_TOOL_NAME_LINUX = "Export_Srudb_Linux.exe"; //NON-NLS + private static final String SRU_TOOL_NAME_MAC = "Export_srudb_macos"; //NON-NLS + private static final String SRU_OUTPUT_FILE_NAME = "Output.txt"; //NON-NLS + private static final String SRU_ERROR_FILE_NAME = "Error.txt"; //NON-NLS + + private static final Map applicationFilesFound = new HashMap<>(); + + @Messages({ + "ExtractSru_module_name=System Resource Usage Extractor" + }) + ExtractSru() { + this.moduleName = Bundle.ExtractSru_module_name(); + } + + @Messages({ + "ExtractSru_error_finding_export_srudb_program=Error finding export_srudb program", + "ExtractSru_process_error_executing_export_srudb_program=Error running export_srudb program" + }) + + @Override + void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar) { + + this.context = context; + + String modOutPath = Case.getCurrentCase().getModuleDirectory() + File.separator + "sru"; + File dir = new File(modOutPath); + if (dir.exists() == false) { + dir.mkdirs(); + } + + String tempDirPath = RAImageIngestModule.getRATempPath(Case.getCurrentCase(), "sru"); //NON-NLS + String softwareHiveFileName = getSoftwareHiveFile(dataSource, tempDirPath); + + if (softwareHiveFileName == null) { + return; + } + + AbstractFile sruAbstractFile = getSruFile(dataSource, tempDirPath); + + String sruFileName = tempDirPath + File.separator + sruAbstractFile.getId() + "_" + sruAbstractFile.getName(); + + if (sruFileName == null) { + this.addErrorMessage(Bundle.ExtractSru_process_errormsg_find_srudb_dat()); + logger.log(Level.SEVERE, "SRUDB.dat file not found"); //NON-NLS + return; //If we cannot find the srudb.dat file we cannot proceed + } + + final String sruDumper = getPathForSruDumper(); + if (sruDumper == null) { + this.addErrorMessage(Bundle.ExtractSru_error_finding_export_srudb_program()); + logger.log(Level.SEVERE, "Error finding export_srudb program"); //NON-NLS + return; //If we cannot find the export_srudb program we cannot proceed + } + + if (context.dataSourceIngestIsCancelled()) { + return; + } + + try { + String modOutFile = modOutPath + File.separator + sruAbstractFile.getId() + "_srudb.db3"; + + extractSruFiles(sruDumper, sruFileName, modOutFile, tempDirPath, softwareHiveFileName); + + findSruExecutedFiles(modOutFile, dataSource); + + createNetUsageArtifacts(modOutFile, sruAbstractFile); + createAppUsageArtifacts(modOutFile, sruAbstractFile); + } catch (IOException ex) { + this.addErrorMessage(Bundle.ExtractSru_process_error_executing_export_srudb_program()); + logger.log(Level.SEVERE, "SRUDB.dat file not found"); //NON-NLS + } + } + + @Messages({ + "ExtractSru_process_errormsg_find_software_hive=Unable to find SOFTWARE HIVE file", + "ExtractSru_process_errormsg_write_software_hive=Unable to write SOFTWARE HIVE file" + }) + + /** + * Extract the SOFTWARE hive file to the temp directory + * + * @param dataSource datasource where software hiive is + * @param tempDirPath temp directory to write file to + * + * @return Software hive file location + */ + String getSoftwareHiveFile(Content dataSource, String tempDirPath) { + FileManager fileManager = Case.getCurrentCase().getServices().getFileManager(); + + List softwareHiveFiles; + + try { + softwareHiveFiles = fileManager.findFiles(dataSource, "SOFTWARE"); //NON-NLS + } catch (TskCoreException ex) { + this.addErrorMessage(Bundle.ExtractSru_process_errormsg_find_software_hive()); + logger.log(Level.WARNING, "Unable to find SOFTWARE HIVE file.", ex); //NON-NLS + return null; // No need to continue + } + + String softwareHiveFileName = null; + + for (AbstractFile softwareFile : softwareHiveFiles) { + + if (softwareFile.getParentPath().endsWith("/config/")) { + softwareHiveFileName = tempDirPath + File.separator + softwareFile.getId() + "_" + softwareFile.getName(); + + try { + ContentUtils.writeToFile(softwareFile, new File(softwareHiveFileName)); + } catch (IOException ex) { + this.addErrorMessage(Bundle.ExtractSru_process_errormsg_find_software_hive()); + logger.log(Level.WARNING, String.format("Unable to write %s to temp directory. File name: %s", softwareFile.getName(), softwareFile), ex); //NON-NLS + return null; + } + } + } + return softwareHiveFileName; + } + + @Messages({ + "ExtractSru_process_errormsg_find_srudb_dat=Unable to find srudb.dat file", + "ExtractSru_process_errormsg_write_srudb_dat=Unable to write srudb.dat file" + }) + /** + * Extract the SOFTWARE hive file to the temp directory + * + * @param dataSource datasource where software hiive is + * @param tempDirPath temp directory to write file to + * + * @return Software hive file location + */ + AbstractFile getSruFile(Content dataSource, String tempDirPath) { + FileManager fileManager = Case.getCurrentCase().getServices().getFileManager(); + + List sruFiles; + + try { + sruFiles = fileManager.findFiles(dataSource, "SRUDB.DAT"); //NON-NLS + } catch (TskCoreException ex) { + this.addErrorMessage(Bundle.ExtractSru_process_errormsg_find_srudb_dat()); + logger.log(Level.WARNING, "Unable to find SRUDB.DAT file.", ex); //NON-NLS + return null; // No need to continue + } + + AbstractFile sruAbstractFile = null; + + for (AbstractFile sruFile : sruFiles) { + + String sruFileName = tempDirPath + File.separator + sruFile.getId() + "_" + sruFile.getName(); + sruAbstractFile = sruFile; + + try { + ContentUtils.writeToFile(sruFile, new File(sruFileName)); + } catch (IOException ex) { + this.addErrorMessage(Bundle.ExtractSru_process_errormsg_write_srudb_dat()); + logger.log(Level.WARNING, String.format("Unable to write %s to temp directory. File name: %s", sruFile.getName(), sruFile), ex); //NON-NLS + return null; + } + + } + return sruAbstractFile; + } + + /** + * Run the export srudb program against the srudb.dat file + * + * @param sruExePath + * @param tempDirPath + * @param tempOutPath + * + * @throws FileNotFoundException + * @throws IOException + */ + void extractSruFiles(String sruExePath, String sruFile, String tempOutFile, String tempOutPath, String softwareHiveFile) throws IOException { + final Path outputFilePath = Paths.get(tempOutPath, SRU_OUTPUT_FILE_NAME); + final Path errFilePath = Paths.get(tempOutPath, SRU_ERROR_FILE_NAME); + + List commandLine = new ArrayList<>(); + commandLine.add(sruExePath); + commandLine.add(sruFile); //NON-NLS + commandLine.add(softwareHiveFile); + commandLine.add(tempOutFile); + + ProcessBuilder processBuilder = new ProcessBuilder(commandLine); + processBuilder.redirectOutput(outputFilePath.toFile()); + processBuilder.redirectError(errFilePath.toFile()); + + ExecUtil.execute(processBuilder, new DataSourceIngestModuleProcessTerminator(context)); + } + + private String getPathForSruDumper() { + Path path = null; + if (PlatformUtil.isWindowsOS()) { + if (PlatformUtil.is64BitOS()) { + path = Paths.get(SRU_TOOL_FOLDER, SRU_TOOL_NAME_WINDOWS_64); + } else { + path = Paths.get(SRU_TOOL_FOLDER, SRU_TOOL_NAME_WINDOWS_32); + } + } else { + if ("Linux".equals(PlatformUtil.getOSName())) { + path = Paths.get(SRU_TOOL_FOLDER, SRU_TOOL_NAME_LINUX); + } else { + path = Paths.get(SRU_TOOL_FOLDER, SRU_TOOL_NAME_MAC); + } + } + File sruToolFile = InstalledFileLocator.getDefault().locate(path.toString(), + ExtractSru.class.getPackage().getName(), false); + if (sruToolFile != null) { + return sruToolFile.getAbsolutePath(); + } + + return null; + } + + private void findSruExecutedFiles(String sruDb, Content dataSource) { + + org.sleuthkit.autopsy.casemodule.services.FileManager fileManager = currentCase.getServices().getFileManager(); + + String sqlStatement = "SELECT DISTINCT SUBSTR(LTRIM(IdBlob, '\\Device\\HarddiskVolume'), INSTR(LTRIM(IdBlob, '\\Device\\HarddiskVolume'), '\\')) " + + " application_name, idBlob source_name FROM SruDbIdMapTable WHERE idType = 0 AND idBlob NOT LIKE '!!%'"; //NON-NLS + + try (SQLiteDBConnect tempdbconnect = new SQLiteDBConnect("org.sqlite.JDBC", "jdbc:sqlite:" + sruDb); //NON-NLS + ResultSet resultSet = tempdbconnect.executeQry(sqlStatement)) { + + while (resultSet.next()) { + + if (context.dataSourceIngestIsCancelled()) { + logger.log(Level.INFO, "Cancelled SRU Artifact Creation."); //NON-NLS + return; + } + + String applicationName = resultSet.getString("application_name"); //NON-NLS + String sourceName = resultSet.getString("source_name"); //NON-NLS + + String normalizePathName = FilenameUtils.normalize(applicationName, true); + String fileName = FilenameUtils.getName(normalizePathName); + String filePath = FilenameUtils.getPath(normalizePathName); + if (fileName.contains(" [")) { + fileName = fileName.substring(0, fileName.indexOf(" [")); + } + List sourceFiles; + try { + sourceFiles = fileManager.findFiles(dataSource, fileName, filePath); //NON-NLS + for (AbstractFile sourceFile : sourceFiles) { + if (sourceFile.getParentPath().endsWith(filePath)) { + applicationFilesFound.put(sourceName.toLowerCase(), sourceFile); + } + } + + } catch (TskCoreException ex) { + logger.log(Level.WARNING, String.format("Error finding actual file %s. file may not exist", normalizePathName)); //NON-NLS + } + } + } catch (SQLException ex) { + logger.log(Level.WARNING, "Error while trying to read into a sqlite db.", ex);//NON-NLS + } + + } + + private void createNetUsageArtifacts(String sruDb, AbstractFile sruAbstractFile) { + List bba = new ArrayList<>(); + + String sqlStatement = "SELECT STRFTIME('%s', timestamp) ExecutionTime, Application_Name, User_Name, " + + " bytesSent, BytesRecvd FROM network_Usage , SruDbIdMapTable " + + " where appId = IdIndex and IdType = 0 order by ExecutionTime;"; //NON-NLS + + try (SQLiteDBConnect tempdbconnect = new SQLiteDBConnect("org.sqlite.JDBC", "jdbc:sqlite:" + sruDb); //NON-NLS + ResultSet resultSet = tempdbconnect.executeQry(sqlStatement)) { + + while (resultSet.next()) { + + if (context.dataSourceIngestIsCancelled()) { + logger.log(Level.INFO, "Cancelled SRU Net Usage Artifact Creation."); //NON-NLS + return; + } + + String applicationName = resultSet.getString("Application_Name"); //NON-NLS + Long executionTime = Long.valueOf(resultSet.getInt("ExecutionTime")); //NON-NLS + Long bytesSent = Long.valueOf(resultSet.getInt("bytesSent")); //NON-NLS + Long bytesRecvd = Long.valueOf(resultSet.getInt("BytesRecvd")); //NON-NLS + String userName = resultSet.getString("User_Name"); //NON-NLS + + Collection bbattributes = Arrays.asList( + new BlackboardAttribute( + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, getName(), + applicationName),//NON-NLS + new BlackboardAttribute( + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME, getName(), + userName), + new BlackboardAttribute( + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, getName(), + executionTime), + new BlackboardAttribute( + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_BYTES_SENT, getName(), bytesSent), + new BlackboardAttribute( + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_BYTES_RECEIVED, getName(), bytesRecvd), + new BlackboardAttribute( + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT, getName(), NETWORK_USAGE_SOURCE_NAME)); + + try { + BlackboardArtifact bbart = sruAbstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN); + bbart.addAttributes(bbattributes); + bba.add(bbart); + BlackboardArtifact associateBbArtifact = createAssociatedArtifact(applicationName.toLowerCase(), bbart); + if (associateBbArtifact != null) { + bba.add(associateBbArtifact); + } + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, "Exception Adding Artifact.", ex);//NON-NLS + } + } + + } catch (SQLException ex) { + logger.log(Level.SEVERE, "Error while trying to read into a sqlite db.", ex);//NON-NLS + } + + try { + blackboard.postArtifacts(bba, MODULE_NAME); + } catch (Blackboard.BlackboardException ex) { + logger.log(Level.SEVERE, "Error Posting Artifact.", ex);//NON-NLS + } + } + + private void createAppUsageArtifacts(String sruDb, AbstractFile sruAbstractFile) { + List bba = new ArrayList<>(); + + String sqlStatement = "SELECT STRFTIME('%s', timestamp) ExecutionTime, Application_Name, User_Name " + + " FROM Application_Resource_Usage, SruDbIdMapTable WHERE " + + " idType = 0 and idIndex = appId order by ExecutionTime;"; //NON-NLS + + try (SQLiteDBConnect tempdbconnect = new SQLiteDBConnect("org.sqlite.JDBC", "jdbc:sqlite:" + sruDb); //NON-NLS + ResultSet resultSet = tempdbconnect.executeQry(sqlStatement)) { + + while (resultSet.next()) { + + if (context.dataSourceIngestIsCancelled()) { + logger.log(Level.INFO, "Cancelled SRU Net Usage Artifact Creation."); //NON-NLS + return; + } + + String applicationName = resultSet.getString("Application_Name"); //NON-NLS + Long executionTime = Long.valueOf(resultSet.getInt("ExecutionTime")); //NON-NLS + String userName = resultSet.getString("User_Name"); + + Collection bbattributes = Arrays.asList( + new BlackboardAttribute( + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, getName(), + applicationName),//NON-NLS + new BlackboardAttribute( + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME, getName(), + userName), + new BlackboardAttribute( + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, getName(), + executionTime), + new BlackboardAttribute( + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT, getName(), APPLICATION_USAGE_SOURCE_NAME)); + + try { + BlackboardArtifact bbart = sruAbstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN); + bbart.addAttributes(bbattributes); + bba.add(bbart); + BlackboardArtifact associateBbArtifact = createAssociatedArtifact(applicationName.toLowerCase(), bbart); + if (associateBbArtifact != null) { + bba.add(associateBbArtifact); + } + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, "Exception Adding Artifact.", ex);//NON-NLS + } + } + + } catch (SQLException ex) { + logger.log(Level.SEVERE, "Error while trying to read into a sqlite db.", ex);//NON-NLS + } + + try { + blackboard.postArtifacts(bba, MODULE_NAME); + } catch (Blackboard.BlackboardException ex) { + logger.log(Level.SEVERE, "Error Posting Artifact.", ex);//NON-NLS + } + } + + /** + * Create associated artifacts using file path name and the artifact it associates with + * + * @param filePathName file and path of object being associated with + * + * @param bba blackboard artifact to associate with + * + * @returnv BlackboardArtifact or a null value + */ + private BlackboardArtifact createAssociatedArtifact(String filePathName, BlackboardArtifact bba) { + if (applicationFilesFound.containsKey(filePathName)) { + AbstractFile sourceFile = applicationFilesFound.get(filePathName); + Collection bbattributes2 = new ArrayList<>(); + bbattributes2.addAll(Arrays.asList( + new BlackboardAttribute(TSK_ASSOCIATED_ARTIFACT, this.getName(), + bba.getArtifactID()))); + + BlackboardArtifact associatedObjectBba = createArtifactWithAttributes(TSK_ASSOCIATED_OBJECT, sourceFile, bbattributes2); + if (associatedObjectBba != null) { + return associatedObjectBba; + } + } + + return null; + } + +} diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAImageIngestModule.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAImageIngestModule.java index 444a6d638d..c5cb62a779 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAImageIngestModule.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAImageIngestModule.java @@ -78,6 +78,7 @@ public final class RAImageIngestModule implements DataSourceIngestModule { Extract safari = new ExtractSafari(); Extract zoneInfo = new ExtractZoneIdentifier(); Extract recycleBin = new ExtractRecycleBin(); + Extract sru = new ExtractSru(); extractors.add(chrome); extractors.add(firefox); @@ -91,7 +92,8 @@ public final class RAImageIngestModule implements DataSourceIngestModule { 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); + browserExtractors.add(chrome); browserExtractors.add(firefox); browserExtractors.add(iexplore); diff --git a/thirdparty/markmckinnon/Export_Srudb_Linux b/thirdparty/markmckinnon/Export_Srudb_Linux new file mode 100644 index 0000000000..0af32da85b Binary files /dev/null and b/thirdparty/markmckinnon/Export_Srudb_Linux differ diff --git a/thirdparty/markmckinnon/Export_srudb_macos b/thirdparty/markmckinnon/Export_srudb_macos new file mode 100644 index 0000000000..eeff65b668 Binary files /dev/null and b/thirdparty/markmckinnon/Export_srudb_macos differ diff --git a/thirdparty/markmckinnon/LICENSE-2.0.txt b/thirdparty/markmckinnon/LICENSE-2.0.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/thirdparty/markmckinnon/LICENSE-2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/thirdparty/markmckinnon/export_srudb_32.exe b/thirdparty/markmckinnon/export_srudb_32.exe new file mode 100644 index 0000000000..e642c1d8df Binary files /dev/null and b/thirdparty/markmckinnon/export_srudb_32.exe differ diff --git a/thirdparty/markmckinnon/export_srudb_64.exe b/thirdparty/markmckinnon/export_srudb_64.exe new file mode 100644 index 0000000000..7b07367739 Binary files /dev/null and b/thirdparty/markmckinnon/export_srudb_64.exe differ diff --git a/unix_setup.sh b/unix_setup.sh index 2a75ab72c7..edd6c36632 100644 --- a/unix_setup.sh +++ b/unix_setup.sh @@ -57,13 +57,13 @@ fi ext_jar_filepath=$PWD/autopsy/modules/ext/sleuthkit-$TSK_VERSION.jar; echo -n "Copying sleuthkit-$TSK_VERSION.jar into the Autopsy directory..." -rm -f $ext_jar_filepath; +rm -f "$ext_jar_filepath"; if [ "$?" -gt 0 ]; then #checking if remove operation failed echo "ERROR: Deleting $ext_jar_filepath failed." echo "Please check your permissions." exit 1 else - cp $sleuthkit_jar_filepath $ext_jar_filepath + cp $sleuthkit_jar_filepath "$ext_jar_filepath" if [ "$?" -ne 0 ]; then # checking copy operation was successful echo "ERROR: Copying $sleuthkit_jar_filepath to $ext_jar_filepath failed." echo "Please check your permissions."