Merge pull request #7136 from sleuthkit/release-4.19.0

Merge release 4.19.0 branch into develop branch
This commit is contained in:
Richard Cordovano 2021-07-14 16:55:30 -04:00 committed by GitHub
commit b51c6c9866
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 284 additions and 205 deletions

View File

@ -5,7 +5,10 @@ CentralRepoCommentDialog.title.addEditCentralRepoComment=Add/Edit Central Reposi
OpenIDE-Module-Name=Central Repository OpenIDE-Module-Name=Central Repository
OpenIDE-Module-Display-Category=Ingest Module OpenIDE-Module-Display-Category=Ingest Module
OpenIDE-Module-Short-Description=Central Repository Ingest Module OpenIDE-Module-Short-Description=Central Repository Ingest Module
OpenIDE-Module-Long-Description=Central Repository ingest module and central database. \n\nThe Central Repository ingest module stores attributes of artifacts matching selected correlation types into a central database.\nStored attributes are used in future cases to correlate and analyzes files and artifacts during ingest. OpenIDE-Module-Long-Description=\
Central Repository ingest module and central database. \n\n\
The Central Repository ingest module stores attributes of artifacts matching selected correlation types into a central database.\n\
Stored attributes are used in future cases to correlate and analyzes files and artifacts during ingest.
CentralRepoCommentDialog.commentLabel.text=Comment: CentralRepoCommentDialog.commentLabel.text=Comment:
CentralRepoCommentDialog.okButton.text=&OK CentralRepoCommentDialog.okButton.text=&OK
CentralRepoCommentDialog.cancelButton.text=C&ancel CentralRepoCommentDialog.cancelButton.text=C&ancel

View File

@ -280,6 +280,7 @@ public final class OtherOccurrences {
UniquePathKey uniquePathKey = new UniquePathKey(newNode); UniquePathKey uniquePathKey = new UniquePathKey(newNode);
nodeDataMap.put(uniquePathKey, newNode); nodeDataMap.put(uniquePathKey, newNode);
} }
}
if (file != null && corAttr.getCorrelationType().getDisplayName().equals("Files")) { if (file != null && corAttr.getCorrelationType().getDisplayName().equals("Files")) {
List<AbstractFile> caseDbFiles = getCaseDbMatches(corAttr, openCase, file); List<AbstractFile> caseDbFiles = getCaseDbMatches(corAttr, openCase, file);
@ -287,7 +288,6 @@ public final class OtherOccurrences {
addOrUpdateNodeData(openCase, nodeDataMap, caseDbFile); addOrUpdateNodeData(openCase, nodeDataMap, caseDbFile);
} }
} }
}
return nodeDataMap; return nodeDataMap;
} catch (CentralRepoException ex) { } catch (CentralRepoException ex) {
logger.log(Level.SEVERE, "Error getting artifact instances from database.", ex); // NON-NLS logger.log(Level.SEVERE, "Error getting artifact instances from database.", ex); // NON-NLS

View File

@ -223,7 +223,7 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
String caseDisplayName = Bundle.OtherOccurrencesPanel_caseDetailsDialog_noCaseNameError(); String caseDisplayName = Bundle.OtherOccurrencesPanel_caseDetailsDialog_noCaseNameError();
String details = Bundle.OtherOccurrencesPanel_caseDetailsDialog_noDetails(); String details = Bundle.OtherOccurrencesPanel_caseDetailsDialog_noDetails();
try { try {
if (-1 != selectedRowViewIdx) { if (-1 != selectedRowViewIdx && filesTableModel.getRowCount() > 0) {
CentralRepository dbManager = CentralRepository.getInstance(); CentralRepository dbManager = CentralRepository.getInstance();
int selectedRowModelIdx = filesTable.convertRowIndexToModel(selectedRowViewIdx); int selectedRowModelIdx = filesTable.convertRowIndexToModel(selectedRowViewIdx);
List<NodeData> rowList = filesTableModel.getListOfNodesForFile(selectedRowModelIdx); List<NodeData> rowList = filesTableModel.getListOfNodesForFile(selectedRowModelIdx);
@ -254,8 +254,8 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
private void saveToCSV() throws NoCurrentCaseException { private void saveToCSV() throws NoCurrentCaseException {
if (casesTableModel.getRowCount() > 0) { if (casesTableModel.getRowCount() > 0) {
if(CSVFileChooser == null) { if (CSVFileChooser == null) {
try{ try {
CSVFileChooser = futureFileChooser.get(); CSVFileChooser = futureFileChooser.get();
} catch (InterruptedException | ExecutionException ex) { } catch (InterruptedException | ExecutionException ex) {
// If something happened with the thread try and // If something happened with the thread try and
@ -331,6 +331,7 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
casesTableModel.clearTable(); casesTableModel.clearTable();
OtherOccurrenceOneTypeWorker.OneTypeData data = get(); OtherOccurrenceOneTypeWorker.OneTypeData data = get();
correlationAttributes.addAll(data.getCorrelationAttributesToAdd());
for (CorrelationCase corCase : data.getCaseNames().values()) { for (CorrelationCase corCase : data.getCaseNames().values()) {
casesTableModel.addCorrelationCase(new CorrelationCaseWrapper(corCase)); casesTableModel.addCorrelationCase(new CorrelationCaseWrapper(corCase));
} }
@ -339,13 +340,14 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
casesTableModel.addCorrelationCase(NO_ARTIFACTS_CASE); casesTableModel.addCorrelationCase(NO_ARTIFACTS_CASE);
} else if (caseCount == 0) { } else if (caseCount == 0) {
casesTableModel.addCorrelationCase(NO_RESULTS_CASE); casesTableModel.addCorrelationCase(NO_RESULTS_CASE);
} } else {
String earliestDate = data.getEarliestCaseDate(); String earliestDate = data.getEarliestCaseDate();
earliestCaseDate.setText(earliestDate.isEmpty() ? Bundle.OtherOccurrencesPanel_earliestCaseNotAvailable() : earliestDate); earliestCaseDate.setText(earliestDate.isEmpty() ? Bundle.OtherOccurrencesPanel_earliestCaseNotAvailable() : earliestDate);
foundInLabel.setText(String.format(Bundle.OtherOccurrencesPanel_foundIn_text(), data.getTotalCount(), caseCount, data.getDataSourceCount())); foundInLabel.setText(String.format(Bundle.OtherOccurrencesPanel_foundIn_text(), data.getTotalCount(), caseCount, data.getDataSourceCount()));
if (caseCount > 0) { if (caseCount > 0) {
casesTable.setRowSelectionInterval(0, 0); casesTable.setRowSelectionInterval(0, 0);
} }
}
} catch (InterruptedException | ExecutionException ex) { } catch (InterruptedException | ExecutionException ex) {
logger.log(Level.SEVERE, "Failed to update OtherOccurrence panel", ex); logger.log(Level.SEVERE, "Failed to update OtherOccurrence panel", ex);
@ -389,7 +391,7 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
casesTableModel.addCorrelationCase(NO_ARTIFACTS_CASE); casesTableModel.addCorrelationCase(NO_ARTIFACTS_CASE);
} else if (caseCount == 0) { } else if (caseCount == 0) {
casesTableModel.addCorrelationCase(NO_RESULTS_CASE); casesTableModel.addCorrelationCase(NO_RESULTS_CASE);
} } else {
String earliestDate = data.getEarliestCaseDate(); String earliestDate = data.getEarliestCaseDate();
earliestCaseDate.setText(earliestDate.isEmpty() ? Bundle.OtherOccurrencesPanel_earliestCaseNotAvailable() : earliestDate); earliestCaseDate.setText(earliestDate.isEmpty() ? Bundle.OtherOccurrencesPanel_earliestCaseNotAvailable() : earliestDate);
foundInLabel.setText(String.format(Bundle.OtherOccurrencesPanel_foundIn_text(), data.getInstanceDataCount(), caseCount, data.getDataSourceCount())); foundInLabel.setText(String.format(Bundle.OtherOccurrencesPanel_foundIn_text(), data.getInstanceDataCount(), caseCount, data.getDataSourceCount()));
@ -397,6 +399,7 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
casesTable.setRowSelectionInterval(0, 0); casesTable.setRowSelectionInterval(0, 0);
} }
} }
}
/** /**
* Updates displayed information to be correct for the current case * Updates displayed information to be correct for the current case
@ -440,7 +443,7 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
currentCaseName = null; currentCaseName = null;
logger.log(Level.WARNING, "Unable to get current case for other occurrences content viewer", ex); logger.log(Level.WARNING, "Unable to get current case for other occurrences content viewer", ex);
} }
if (casesTableModel.getRowCount() > 0) {
for (NodeData nodeData : correlatedNodeDataMap.values()) { for (NodeData nodeData : correlatedNodeDataMap.values()) {
for (int selectedRow : selectedCaseIndexes) { for (int selectedRow : selectedCaseIndexes) {
try { try {
@ -457,7 +460,8 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
} }
} }
} }
if (dataSourcesTable.getRowCount() > 0) { }
if (dataSourcesTableModel.getRowCount() > 0) {
dataSourcesTable.setRowSelectionInterval(0, 0); dataSourcesTable.setRowSelectionInterval(0, 0);
} }
@ -496,12 +500,14 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
try { try {
Map<UniquePathKey, NodeData> correlatedNodeDataMap = get(); Map<UniquePathKey, NodeData> correlatedNodeDataMap = get();
if (dataSourcesTableModel.getRowCount() > 0) {
for (NodeData nodeData : correlatedNodeDataMap.values()) { for (NodeData nodeData : correlatedNodeDataMap.values()) {
for (int selectedDataSourceRow : selectedDataSources) { for (int selectedDataSourceRow : selectedDataSources) {
int rowModelIndex = dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow);
try { try {
if (nodeData.isCentralRepoNode()) { if (nodeData.isCentralRepoNode()) {
if (dataSourcesTableModel.getCaseUUIDForRow(dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow)).equals(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID()) if (dataSourcesTableModel.getCaseUUIDForRow(rowModelIndex).equals(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID())
&& dataSourcesTableModel.getDeviceIdForRow(dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow)).equals(nodeData.getDeviceID())) { && dataSourcesTableModel.getDeviceIdForRow(rowModelIndex).equals(nodeData.getDeviceID())) {
filesTableModel.addNodeData(nodeData); filesTableModel.addNodeData(nodeData);
} }
} else { } else {
@ -514,7 +520,9 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
} }
} }
} }
if (filesTable.getRowCount() > 0) { }
if (filesTableModel.getRowCount() > 0) {
filesTable.setRowSelectionInterval(0, 0); filesTable.setRowSelectionInterval(0, 0);
} }
} catch (InterruptedException | ExecutionException ex) { } catch (InterruptedException | ExecutionException ex) {
@ -535,27 +543,29 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
private void updateOnFileSelection() { private void updateOnFileSelection() {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
try { try {
if (filesTable.getSelectedRowCount() == 1) { if (filesTableModel.getRowCount() > 0 && filesTable.getSelectedRowCount() == 1) {
//if there is one file selected update the deatils to show the data for that file //if there is one file selected update the deatils to show the data for that file
occurrencePanel = new OccurrencePanel(filesTableModel.getListOfNodesForFile(filesTable.convertRowIndexToModel(filesTable.getSelectedRow()))); occurrencePanel = new OccurrencePanel(filesTableModel.getListOfNodesForFile(filesTable.convertRowIndexToModel(filesTable.getSelectedRow())));
} else if (dataSourcesTable.getSelectedRowCount() == 1) { } else if (dataSourcesTableModel.getRowCount() > 0 && dataSourcesTable.getSelectedRowCount() == 1) {
//if no files were selected and only one data source is selected update the information to reflect the data source //if no files were selected and only one data source is selected update the information to reflect the data source
String caseName = dataSourcesTableModel.getCaseNameForRow(dataSourcesTable.convertRowIndexToModel(dataSourcesTable.getSelectedRow())); String caseName = dataSourcesTableModel.getCaseNameForRow(dataSourcesTable.convertRowIndexToModel(dataSourcesTable.getSelectedRow()));
String dsName = dataSourcesTableModel.getValueAt(dataSourcesTable.convertRowIndexToModel(dataSourcesTable.getSelectedRow()), 0).toString(); String dsName = dataSourcesTableModel.getValueAt(dataSourcesTable.convertRowIndexToModel(dataSourcesTable.getSelectedRow()), 0).toString();
String caseCreatedDate = ""; String caseCreatedDate = "";
if (casesTableModel.getRowCount() > 0) {
for (int row : casesTable.getSelectedRows()) { for (int row : casesTable.getSelectedRows()) {
if (casesTableModel.getValueAt(casesTable.convertRowIndexToModel(row), 0).toString().equals(caseName)) { if (casesTableModel.getValueAt(casesTable.convertRowIndexToModel(row), 0).toString().equals(caseName)) {
caseCreatedDate = getCaseCreatedDate(row); caseCreatedDate = getCaseCreatedDate(row);
break; break;
} }
} }
}
occurrencePanel = new OccurrencePanel(caseName, caseCreatedDate, dsName); occurrencePanel = new OccurrencePanel(caseName, caseCreatedDate, dsName);
} else if (casesTable.getSelectedRowCount() == 1) { } else if (casesTable.getSelectedRowCount() == 1) {
//if no files were selected and a number of data source other than 1 are selected //if no files were selected and a number of data source other than 1 are selected
//update the information to reflect the case //update the information to reflect the case
String createdDate; String createdDate;
String caseName = ""; String caseName = "";
if (casesTable.getRowCount() > 0) { if (casesTableModel.getRowCount() > 0) {
caseName = casesTableModel.getValueAt(casesTable.convertRowIndexToModel(casesTable.getSelectedRow()), 0).toString(); caseName = casesTableModel.getValueAt(casesTable.convertRowIndexToModel(casesTable.getSelectedRow()), 0).toString();
} }
if (caseName.isEmpty()) { if (caseName.isEmpty()) {
@ -586,7 +596,7 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
*/ */
private String getCaseCreatedDate(int caseTableRowIdx) { private String getCaseCreatedDate(int caseTableRowIdx) {
try { try {
if (CentralRepository.isEnabled()) { if (CentralRepository.isEnabled() && casesTableModel.getRowCount() > 0) {
CorrelationCase partialCase; CorrelationCase partialCase;
partialCase = casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(caseTableRowIdx)); partialCase = casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(caseTableRowIdx));
if (partialCase == null) { if (partialCase == null) {
@ -633,7 +643,7 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
for (CorrelationAttributeInstance corAttr : coAtInstances) { for (CorrelationAttributeInstance corAttr : coAtInstances) {
correlatedNodeDataMap.putAll(OtherOccurrences.getCorrelatedInstances(abstractFile, deviceIdStr, dataSourceNameStr, corAttr)); correlatedNodeDataMap.putAll(OtherOccurrences.getCorrelatedInstances(abstractFile, deviceIdStr, dataSourceNameStr, corAttr));
if(isCancelled()) { if (isCancelled()) {
return new HashMap<>(); return new HashMap<>();
} }
} }

View File

@ -36,6 +36,8 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.DataSource;
import org.sleuthkit.datamodel.HashUtility; import org.sleuthkit.datamodel.HashUtility;
import org.sleuthkit.datamodel.InvalidAccountIDException; import org.sleuthkit.datamodel.InvalidAccountIDException;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
@ -192,7 +194,11 @@ public class CorrelationAttributeUtil {
} else if (artifactTypeID == ARTIFACT_TYPE.TSK_INSTALLED_PROG.getTypeID()) { } else if (artifactTypeID == ARTIFACT_TYPE.TSK_INSTALLED_PROG.getTypeID()) {
BlackboardAttribute setNameAttr = sourceArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH)); BlackboardAttribute setNameAttr = sourceArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH));
String pathAttrString = null;
if (setNameAttr != null) { if (setNameAttr != null) {
pathAttrString = setNameAttr.getValueString();
}
if (pathAttrString != null && !pathAttrString.isEmpty()) {
makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH, CorrelationAttributeInstance.INSTALLED_PROGS_TYPE_ID); makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH, CorrelationAttributeInstance.INSTALLED_PROGS_TYPE_ID);
} else { } else {
makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, CorrelationAttributeInstance.INSTALLED_PROGS_TYPE_ID); makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, CorrelationAttributeInstance.INSTALLED_PROGS_TYPE_ID);
@ -389,9 +395,17 @@ public class CorrelationAttributeUtil {
private static CorrelationAttributeInstance makeCorrAttr(BlackboardArtifact artifact, CorrelationAttributeInstance.Type correlationType, String value) { private static CorrelationAttributeInstance makeCorrAttr(BlackboardArtifact artifact, CorrelationAttributeInstance.Type correlationType, String value) {
try { try {
Case currentCase = Case.getCurrentCaseThrows(); Case currentCase = Case.getCurrentCaseThrows();
AbstractFile bbSourceFile = currentCase.getSleuthkitCase().getAbstractFileById(artifact.getObjectID()); Content sourceContent = currentCase.getSleuthkitCase().getContentById(artifact.getObjectID());
if (null == bbSourceFile) { if (null == sourceContent) {
logger.log(Level.SEVERE, "Error creating artifact instance. Abstract File was null."); // NON-NLS logger.log(Level.SEVERE, "Error creating artifact instance of type {0}. Failed to load content with ID: {1} associated with artifact with ID: {2}",
new Object[]{correlationType.getDisplayName(), artifact.getObjectID(), artifact.getId()}); // NON-NLS
return null;
}
Content ds = sourceContent.getDataSource();
if (ds == null) {
logger.log(Level.SEVERE, "Error creating artifact instance of type {0}. Failed to load data source for content with ID: {1}",
new Object[]{correlationType.getDisplayName(), artifact.getObjectID()}); // NON-NLS
return null; return null;
} }
@ -401,17 +415,24 @@ public class CorrelationAttributeUtil {
correlationType, correlationType,
value, value,
correlationCase, correlationCase,
CorrelationDataSource.fromTSKDataSource(correlationCase, bbSourceFile.getDataSource()), CorrelationDataSource.fromTSKDataSource(correlationCase, ds),
"", "",
"", "",
TskData.FileKnown.UNKNOWN, TskData.FileKnown.UNKNOWN,
bbSourceFile.getId()); sourceContent.getId());
} else { } else {
if (! (sourceContent instanceof AbstractFile)) {
logger.log(Level.SEVERE, "Error creating artifact instance of type {0}. Source content of artifact with ID: {1} is not an AbstractFile",
new Object[]{correlationType.getDisplayName(), artifact.getId()});
return null;
}
AbstractFile bbSourceFile = (AbstractFile) sourceContent;
return new CorrelationAttributeInstance( return new CorrelationAttributeInstance(
correlationType, correlationType,
value, value,
correlationCase, correlationCase,
CorrelationDataSource.fromTSKDataSource(correlationCase, bbSourceFile.getDataSource()), CorrelationDataSource.fromTSKDataSource(correlationCase, ds),
bbSourceFile.getParentPath() + bbSourceFile.getName(), bbSourceFile.getParentPath() + bbSourceFile.getName(),
"", "",
TskData.FileKnown.UNKNOWN, TskData.FileKnown.UNKNOWN,

View File

@ -1,7 +1,7 @@
/* /*
* Central Repository * Central Repository
* *
* Copyright 2017-2020 Basis Technology Corp. * Copyright 2017-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -30,9 +30,7 @@ import java.util.Set;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.stream.Collectors;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages; import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
@ -64,9 +62,9 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException;
import org.sleuthkit.datamodel.Tag; import org.sleuthkit.datamodel.Tag;
import org.sleuthkit.autopsy.events.AutopsyEvent; import org.sleuthkit.autopsy.events.AutopsyEvent;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.datamodel.Blackboard; import org.sleuthkit.datamodel.Blackboard;
import org.sleuthkit.datamodel.BlackboardAttribute; 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; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT;
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME;
import org.sleuthkit.datamodel.OsAccount; import org.sleuthkit.datamodel.OsAccount;
@ -678,7 +676,9 @@ public final class CaseEventListener implements PropertyChangeListener {
@Override @Override
public void run() { public void run() {
if (!CentralRepository.isEnabled()) { //Nothing to do here if the central repo is not enabled or if ingest is running but is set to not save data/make artifacts
if (!CentralRepository.isEnabled()
|| (IngestManager.getInstance().isIngestRunning() && !(IngestEventsListener.isFlagSeenDevices() || IngestEventsListener.shouldCreateCrProperties()))) {
return; return;
} }
@ -706,13 +706,16 @@ public final class CaseEventListener implements PropertyChangeListener {
TskData.FileKnown.KNOWN, TskData.FileKnown.KNOWN,
osAccount.getId()); osAccount.getId());
// Save to the database if requested
if(IngestEventsListener.shouldCreateCrProperties()) {
dbManager.addArtifactInstance(correlationAttributeInstance); dbManager.addArtifactInstance(correlationAttributeInstance);
}
// Look up and create artifacts for previously seen accounts if requested
if (IngestEventsListener.isFlagSeenDevices()) {
List<CorrelationAttributeInstance> previousOccurences = dbManager.getArtifactInstancesByTypeValue(CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.OSACCOUNT_TYPE_ID), correlationAttributeInstance.getCorrelationValue()); List<CorrelationAttributeInstance> previousOccurences = dbManager.getArtifactInstancesByTypeValue(CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.OSACCOUNT_TYPE_ID), correlationAttributeInstance.getCorrelationValue());
List<String> caseDisplayNames;
for (CorrelationAttributeInstance instance : previousOccurences) { for (CorrelationAttributeInstance instance : previousOccurences) {
if (!instance.getCorrelationCase().getCaseUUID().equals(correlationAttributeInstance.getCorrelationCase().getCaseUUID())) { if (!instance.getCorrelationCase().getCaseUUID().equals(correlationAttributeInstance.getCorrelationCase().getCaseUUID())) {
caseDisplayNames = dbManager.getListCasesHavingArtifactInstances(correlationAttributeInstance.getCorrelationType(), correlationAttributeInstance.getCorrelationValue());
SleuthkitCase tskCase = osAccount.getSleuthkitCase(); SleuthkitCase tskCase = osAccount.getSleuthkitCase();
Blackboard blackboard = tskCase.getBlackboard(); Blackboard blackboard = tskCase.getBlackboard();
@ -735,6 +738,7 @@ public final class CaseEventListener implements PropertyChangeListener {
} }
} }
} }
}
} catch (CentralRepoException ex) { } catch (CentralRepoException ex) {
LOGGER.log(Level.SEVERE, String.format("Cannot get central repository for OsAccount: %s.", accountAddr.get()), ex); //NON-NLS LOGGER.log(Level.SEVERE, String.format("Cannot get central repository for OsAccount: %s.", accountAddr.get()), ex); //NON-NLS

View File

@ -1,4 +1,4 @@
IngestSettingsPanel.ingestSettingsLabel.text=Ingest Settings IngestSettingsPanel.ingestSettingsLabel.text=Ingest Settings
IngestSettingsPanel.flagTaggedNotableItemsCheckbox.text=Flag items previously tagged as notable IngestSettingsPanel.flagTaggedNotableItemsCheckbox.text=Flag items previously tagged as notable
IngestSettingsPanel.flagPreviouslySeenDevicesCheckbox.text=Flag devices previously seen in other cases IngestSettingsPanel.flagPreviouslySeenDevicesCheckbox.text=Flag devices and users previously seen in other cases
IngestSettingsPanel.createCorrelationPropertiesCheckbox.text=Save items to the Central Repository IngestSettingsPanel.createCorrelationPropertiesCheckbox.text=Save items to the Central Repository

View File

@ -11,5 +11,5 @@ CentralRepoIngestModuleFactory.ingestmodule.desc=Saves properties to the central
CentralRepoIngestModuleFactory.ingestmodule.name=Central Repository CentralRepoIngestModuleFactory.ingestmodule.name=Central Repository
IngestSettingsPanel.ingestSettingsLabel.text=Ingest Settings IngestSettingsPanel.ingestSettingsLabel.text=Ingest Settings
IngestSettingsPanel.flagTaggedNotableItemsCheckbox.text=Flag items previously tagged as notable IngestSettingsPanel.flagTaggedNotableItemsCheckbox.text=Flag items previously tagged as notable
IngestSettingsPanel.flagPreviouslySeenDevicesCheckbox.text=Flag devices previously seen in other cases IngestSettingsPanel.flagPreviouslySeenDevicesCheckbox.text=Flag devices and users previously seen in other cases
IngestSettingsPanel.createCorrelationPropertiesCheckbox.text=Save items to the Central Repository IngestSettingsPanel.createCorrelationPropertiesCheckbox.text=Save items to the Central Repository

View File

@ -29,7 +29,7 @@
</Group> </Group>
</Group> </Group>
</Group> </Group>
<EmptySpace pref="47" max="32767" attributes="0"/> <EmptySpace max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>

View File

@ -88,7 +88,7 @@ final class IngestSettingsPanel extends IngestModuleIngestJobSettingsPanel {
.addComponent(flagTaggedNotableItemsCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(flagTaggedNotableItemsCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(flagPreviouslySeenDevicesCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(flagPreviouslySeenDevicesCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(createCorrelationPropertiesCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) .addComponent(createCorrelationPropertiesCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
.addContainerGap(47, Short.MAX_VALUE)) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
); );
layout.setVerticalGroup( layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

View File

@ -39,7 +39,8 @@ GlobalSettingsPanel.askForCentralRepoDbChoice.sqliteChoice.text=Use SQLite
GlobalSettingsPanel.onMultiUserChange.disabledMu.description=The Central Repository will be reconfigured to use a local SQLite database. GlobalSettingsPanel.onMultiUserChange.disabledMu.description=The Central Repository will be reconfigured to use a local SQLite database.
GlobalSettingsPanel.onMultiUserChange.disabledMu.description2=Press Configure PostgreSQL to change to a PostgreSQL database. GlobalSettingsPanel.onMultiUserChange.disabledMu.description2=Press Configure PostgreSQL to change to a PostgreSQL database.
GlobalSettingsPanel.onMultiUserChange.disabledMu.title=Central Repository Change Necessary GlobalSettingsPanel.onMultiUserChange.disabledMu.title=Central Repository Change Necessary
GlobalSettingsPanel.onMultiUserChange.enable.description=Do you want to update the Central Repository to use this PostgreSQL server? # {0} - server name
GlobalSettingsPanel.onMultiUserChange.enable.description=Do you want to update the Central Repository to use the PostgreSQL server on {0}?
GlobalSettingsPanel.onMultiUserChange.enable.description2=Any data in an existing SQLite Central Repository will not be transferred to the new database. GlobalSettingsPanel.onMultiUserChange.enable.description2=Any data in an existing SQLite Central Repository will not be transferred to the new database.
GlobalSettingsPanel.onMultiUserChange.enable.title=Central Repository GlobalSettingsPanel.onMultiUserChange.enable.title=Central Repository
GlobalSettingsPanel.testCurrentConfiguration.dbDoesNotExist.message=Database does not exist. GlobalSettingsPanel.testCurrentConfiguration.dbDoesNotExist.message=Database does not exist.

View File

@ -47,6 +47,7 @@ import java.util.logging.Level;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import org.openide.util.ImageUtilities; import org.openide.util.ImageUtilities;
import org.sleuthkit.autopsy.centralrepository.datamodel.DatabaseTestResult; import org.sleuthkit.autopsy.centralrepository.datamodel.DatabaseTestResult;
import org.sleuthkit.autopsy.centralrepository.datamodel.PostgresSettingsLoader;
@ -152,7 +153,8 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
*/ */
@NbBundle.Messages({ @NbBundle.Messages({
"GlobalSettingsPanel.onMultiUserChange.enable.title=Central Repository", "GlobalSettingsPanel.onMultiUserChange.enable.title=Central Repository",
"GlobalSettingsPanel.onMultiUserChange.enable.description=Do you want to update the Central Repository to use this PostgreSQL server?", "# {0} - server name",
"GlobalSettingsPanel.onMultiUserChange.enable.description=Do you want to update the Central Repository to use the PostgreSQL server on {0}?",
"GlobalSettingsPanel.onMultiUserChange.enable.description2=Any data in an existing SQLite Central Repository will not be transferred to the new database." "GlobalSettingsPanel.onMultiUserChange.enable.description2=Any data in an existing SQLite Central Repository will not be transferred to the new database."
}) })
public static void onMultiUserChange(Component parent, boolean muPreviouslySelected, boolean muCurrentlySelected) { public static void onMultiUserChange(Component parent, boolean muPreviouslySelected, boolean muCurrentlySelected) {
@ -161,10 +163,12 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
if (!muPreviouslySelected && muCurrentlySelected) { if (!muPreviouslySelected && muCurrentlySelected) {
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(() -> {
PostgresCentralRepoSettings multiUserSettings
= new PostgresCentralRepoSettings(PostgresSettingsLoader.MULTIUSER_SETTINGS_LOADER);
if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(parent, if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(parent,
"<html><body>" "<html><body>"
+ "<div style='width: 400px;'>" + "<div style='width: 400px;'>"
+ "<p>" + Bundle.GlobalSettingsPanel_onMultiUserChange_enable_description() + "</p>" + "<p>" + Bundle.GlobalSettingsPanel_onMultiUserChange_enable_description(multiUserSettings.getHost()) + "</p>"
+ "<p style='margin-top: 10px'>" + Bundle.GlobalSettingsPanel_onMultiUserChange_enable_description2() + "</p>" + "<p style='margin-top: 10px'>" + Bundle.GlobalSettingsPanel_onMultiUserChange_enable_description2() + "</p>"
+ "</div>" + "</div>"
+ "</body></html>", + "</body></html>",

View File

@ -128,9 +128,11 @@ public final class InterCasePanel extends javax.swing.JPanel {
} }
}); });
for (CorrelationAttributeInstance.Type type : types) { for (CorrelationAttributeInstance.Type type : types) {
if (! type.getDbTableName().contains("os_account") && ! type.getDbTableName().contains("installed_program")) {
correlationTypeFilters.put(type.getDisplayName(), type); correlationTypeFilters.put(type.getDisplayName(), type);
this.correlationTypeComboBox.addItem(type.getDisplayName()); this.correlationTypeComboBox.addItem(type.getDisplayName());
} }
}
} catch (CentralRepoException ex) { } catch (CentralRepoException ex) {
logger.log(Level.WARNING, "Error getting correlation types", ex); logger.log(Level.WARNING, "Error getting correlation types", ex);
} }

View File

@ -80,8 +80,7 @@ class DataSourceGroupingNode extends DisplayableItemNode {
new DataArtifacts(dsObjId), new DataArtifacts(dsObjId),
new AnalysisResults(dsObjId), new AnalysisResults(dsObjId),
new OsAccounts(Case.getCurrentCaseThrows().getSleuthkitCase(), dsObjId), new OsAccounts(Case.getCurrentCaseThrows().getSleuthkitCase(), dsObjId),
new Tags(dsObjId), new Tags(dsObjId)
new Reports()
)); ));
} catch (NoCurrentCaseException ex) { } catch (NoCurrentCaseException ex) {

View File

@ -291,11 +291,18 @@ public class DataResultFilterNode extends FilterNode {
NbBundle.getMessage(this.getClass(), "DataResultFilterNode.action.viewFileInDir.text"), ban)); NbBundle.getMessage(this.getClass(), "DataResultFilterNode.action.viewFileInDir.text"), ban));
} }
} else if (artifactTypeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID()) { } else if (artifactTypeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID()) {
try {
if (ba.getAttribute(BlackboardAttribute.Type.TSK_ASSOCIATED_ARTIFACT) != null) {
//action to go to the source artifact //action to go to the source artifact
actionsList.add(new ViewSourceArtifactAction(DataResultFilterNode_viewSourceArtifact_text(), ba)); actionsList.add(new ViewSourceArtifactAction(DataResultFilterNode_viewSourceArtifact_text(), ba));
// action to go to the source file of the artifact // action to go to the source file of the artifact
actionsList.add(new ViewContextAction( actionsList.add(new ViewContextAction(
NbBundle.getMessage(this.getClass(), "DataResultFilterNode.action.viewSrcFileInDir.text"), ban)); NbBundle.getMessage(this.getClass(), "DataResultFilterNode.action.viewSrcFileInDir.text"), ban));
}
} catch (TskCoreException ex) {
LOGGER.log(Level.WARNING, "Error looking up attributes for artifact with ID=" + ba.getId());
}
} else { } else {
// if the artifact links to another file, add an action to go to // if the artifact links to another file, add an action to go to
// that file // that file

View File

@ -96,6 +96,17 @@ final class DomainDetailsPanel extends JPanel {
runDomainWorker((DomainArtifactsTabPanel) selectedComponent, true); runDomainWorker((DomainArtifactsTabPanel) selectedComponent, true);
} else if (!StringUtils.isBlank(domain) && selectedComponent instanceof MiniTimelinePanel) { } else if (!StringUtils.isBlank(domain) && selectedComponent instanceof MiniTimelinePanel) {
runMiniTimelineWorker((MiniTimelinePanel) selectedComponent, true); runMiniTimelineWorker((MiniTimelinePanel) selectedComponent, true);
} else if (selectedComponent instanceof OtherOccurrencesPanel) {
if (CentralRepository.isEnabled()) {
try {
((OtherOccurrencesPanel) selectedComponent).populateTableForOneType(CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.DOMAIN_TYPE_ID), domain);
} catch (CentralRepoException ex) {
logger.log(Level.INFO, "Central repository exception while trying to get instances by type and value for domain: " + domain, ex);
((OtherOccurrencesPanel) selectedComponent).reset();
}
} else {
((OtherOccurrencesPanel) selectedComponent).reset();
}
} }
} }
} }

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2015-2020 Basis Technology Corp. * Copyright 2015-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -19,7 +19,6 @@
package org.sleuthkit.autopsy.experimental.autoingest; package org.sleuthkit.autopsy.experimental.autoingest;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader; import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
@ -28,18 +27,16 @@ import java.nio.file.attribute.BasicFileAttributes;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.UUID; import java.util.UUID;
import java.util.logging.Level;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath; import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory; import javax.xml.xpath.XPathFactory;
import org.openide.util.lookup.ServiceProvider; import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.xml.sax.SAXException;
@Immutable @Immutable
@ServiceProvider(service = ManifestFileParser.class) @ServiceProvider(service = ManifestFileParser.class)
@ -50,6 +47,7 @@ public final class AutopsyManifestFileParser implements ManifestFileParser {
private static final String CASE_NAME_XPATH = "/AutopsyManifest/CaseName/text()"; private static final String CASE_NAME_XPATH = "/AutopsyManifest/CaseName/text()";
private static final String DEVICE_ID_XPATH = "/AutopsyManifest/DeviceId/text()"; private static final String DEVICE_ID_XPATH = "/AutopsyManifest/DeviceId/text()";
private static final String DATA_SOURCE_NAME_XPATH = "/AutopsyManifest/DataSource/text()"; private static final String DATA_SOURCE_NAME_XPATH = "/AutopsyManifest/DataSource/text()";
private static final Logger logger = Logger.getLogger(AutopsyManifestFileParser.class.getName());
@Override @Override
public boolean fileIsManifest(Path filePath) { public boolean fileIsManifest(Path filePath) {
@ -78,6 +76,7 @@ public final class AutopsyManifestFileParser implements ManifestFileParser {
} catch (Exception ex) { } catch (Exception ex) {
// If the above call to createManifestDOM threw an exception // If the above call to createManifestDOM threw an exception
// try to fix the given XML file. // try to fix the given XML file.
logger.log(Level.WARNING, String.format("Failed to create DOM for manifest at %s, attempting repair", filePath), ex);
tempPath = ManifestFileParser.makeTidyManifestFile(filePath); tempPath = ManifestFileParser.makeTidyManifestFile(filePath);
doc = ManifestFileParser.createManifestDOM(tempPath); doc = ManifestFileParser.createManifestDOM(tempPath);
} }

View File

@ -52,7 +52,7 @@ KeywordSearchResultFactory.createNodeForKey.noResultsFound.text=No results found
KeywordSearchResultFactory.query.exception.msg=Could not perform the query KeywordSearchResultFactory.query.exception.msg=Could not perform the query
OpenIDE-Module-Display-Category=Ingest Module OpenIDE-Module-Display-Category=Ingest Module
OpenIDE-Module-Long-Description=Keyword Search ingest module.\n\nThe module indexes files found in the disk image at ingest time.\nIt then periodically runs the search on the indexed files using one or more keyword lists (containing pure words and/or regular expressions) and posts results.\n\n\The module also contains additional tools integrated in the main GUI, such as keyword list configuration, keyword search bar in the top-right corner, extracted text viewer and search results viewer showing highlighted keywords found. OpenIDE-Module-Long-Description=Keyword Search ingest module.\n\nThe module indexes files found in the disk image at ingest time.\nIt then periodically runs the search on the indexed files using one or more keyword lists (containing pure words and/or regular expressions) and posts results.\n\nThe module also contains additional tools integrated in the main GUI, such as keyword list configuration, keyword search bar in the top-right corner, extracted text viewer and search results viewer showing highlighted keywords found.
OpenIDE-Module-Name=KeywordSearch OpenIDE-Module-Name=KeywordSearch
OptionsCategory_Name_KeywordSearchOptions=Keyword Search OptionsCategory_Name_KeywordSearchOptions=Keyword Search
OptionsCategory_Keywords_KeywordSearchOptions=Keyword Search OptionsCategory_Keywords_KeywordSearchOptions=Keyword Search
@ -403,7 +403,7 @@ ExtractedContentPanel.pageOfLabel.text=of
ExtractedContentPanel.pageCurLabel.text=- ExtractedContentPanel.pageCurLabel.text=-
ExtractedContentPanel.pagesLabel.text=Page: ExtractedContentPanel.pagesLabel.text=Page:
KeywordSearchJobSettingsPanel.ocrCheckBox.text=Enable Optical Character Recognition (OCR) KeywordSearchJobSettingsPanel.ocrCheckBox.text=Enable Optical Character Recognition (OCR)
KeywordSearchJobSettingsPanel.limitedOcrCheckbox.text=<html>Only process images which are over 100KB in size or extracted from a document (Beta)</html> KeywordSearchJobSettingsPanel.limitedOcrCheckbox.text=<html>Only process PDFs, MS Office docs and images which are over 100KB in size or extracted from another file (Beta)</html>
KeywordSearchJobSettingsPanel.ocrOnlyCheckbox.text=Only index text extracted using OCR KeywordSearchJobSettingsPanel.ocrOnlyCheckbox.text=Only index text extracted using OCR
TextZoomPanel.zoomInButton.text= TextZoomPanel.zoomInButton.text=
TextZoomPanel.zoomOutButton.text= TextZoomPanel.zoomOutButton.text=

View File

@ -147,7 +147,6 @@ public final class KeywordSearchJobSettings implements IngestModuleIngestJobSett
} }
/** /**
* @inheritDoc
*/ */
@Override @Override
public long getVersionNumber() { public long getVersionNumber() {

View File

@ -82,7 +82,7 @@ Results will be opened in a separate Results Viewer for every search executed. I
\section ad_hoc_kw_lists Keyword Lists \section ad_hoc_kw_lists Keyword Lists
In addition to being selected during ingest, keyword lists can also be run through the Keyword Lists button. For information on setting up these keyword lists, see the \ref keywordListsTab section of the ingest module documentation. In addition to being selected during ingest, keyword lists can also be run through the Keyword Lists button. For information on setting up these keyword lists, see the \ref keyword_keywordListsTab section of the ingest module documentation.
Lists created using the Keyword Search Configuration Dialog can be manually searched by the user by pressing on the 'Keyword Lists' button and selecting the check boxes corresponding to the lists to be searched. The search can be restricted to only certain data sources by selecting the checkbox near the bottom and then highlighting the data sources to search within. Multiple data sources can be selected used shift+left click or control+left click. Once everything has been configured, press "Search" to begin the search. The "Save search results" checkbox determines whether the search results will be saved to the case database. Lists created using the Keyword Search Configuration Dialog can be manually searched by the user by pressing on the 'Keyword Lists' button and selecting the check boxes corresponding to the lists to be searched. The search can be restricted to only certain data sources by selecting the checkbox near the bottom and then highlighting the data sources to search within. Multiple data sources can be selected used shift+left click or control+left click. Once everything has been configured, press "Search" to begin the search. The "Save search results" checkbox determines whether the search results will be saved to the case database.

View File

@ -111,7 +111,11 @@ Descriptions of the property types:
- <b>ICCID Number</b> - <b>ICCID Number</b>
- ICCID properties are currently only created by custom Autopsy modules. - ICCID properties are currently only created by custom Autopsy modules.
- <b>Credit Card</b> - <b>Credit Card</b>
- Credid Card properties are created by the \ref keyword_search_page. - Credit Card properties are created by the \ref keyword_search_page.
- <b>OS Account</b>
- OS account properties are created by the disk image data source processor and the \ref recent_activity_page.
- <b>Installed Programs</b>
- Installed program properties are created primarily by the \ref recent_activity_page.
- <b> App-specific Accounts (Facebook, Twitter, etc)</b> - <b> App-specific Accounts (Facebook, Twitter, etc)</b>
- These properties primarily come from the \ref android_analyzer_page. - These properties primarily come from the \ref android_analyzer_page.
@ -148,7 +152,7 @@ There are three settings for the Central Repository ingest module:
<ul> <ul>
<li><b>Save items to the Central Repository</b> - This should only be unselected in the rare case that you don't want to add any properties from the current data source to the central repository, but still want to flag past occurrences. <li><b>Save items to the Central Repository</b> - This should only be unselected in the rare case that you don't want to add any properties from the current data source to the central repository, but still want to flag past occurrences.
<li><b>Flag items previously tagged as notable</b> - Enabling this causes Interesting Item/File artifacts to be created when properties matching those previously flagged are found. See the next section \ref cr_tagging for details. <li><b>Flag items previously tagged as notable</b> - Enabling this causes Interesting Item/File artifacts to be created when properties matching those previously flagged are found. See the next section \ref cr_tagging for details.
<li><b>Flag previously seen devices</b> - When this is enabled, an Interesting Item artifact will be created if any device-related property (USB, MAC Address, IMSI, IMEI, ICCID) is found that is already in the central repository, regardless of whether they have been flagged. <li><b>Flag previously seen devices and users</b> - When this is enabled, an Interesting Item artifact will be created if any device-related property (USB, MAC Address, IMSI, IMEI, ICCID) or an OS account is found that is already in the central repository, regardless of whether they have been flagged.
</li> </li>
\subsection cr_tagging Tagging Files and Artifacts \subsection cr_tagging Tagging Files and Artifacts

View File

@ -75,9 +75,9 @@ Registry hive files can be viewed in a format similar to a registry editor.
\image html content_viewer_registry.png \image html content_viewer_registry.png
\section cv_metadata File Metadata \section cv_metadata File Metadata / Source File Metadata
The File Metadata tab displays basic information about the file, such as type, size, and hash. It also displays the output of the Sleuth Kit istat tool. The File Metadata tab displays basic information about the file selected or the file associated with the result, such as type, size, and hash. It also displays the output of the Sleuth Kit istat tool.
\image html content_viewer_metadata.png \image html content_viewer_metadata.png
@ -87,14 +87,20 @@ The OS Accounts tab displays information on the OS account associated with a giv
\image html content_viewer_os_account.png \image html content_viewer_os_account.png
\section cv_results Results \section cv_results Data Artifacts
The Results tab is active when selecting items with associated results such as keyword hits, call logs, and messages. The exact fields displayed depend on the type of result. The two images below show the Results tab for a call log and a web bookmark. The Data Artifacts tab shows the artifacts associated with the item selected in the result viewer such as web bookmarks, call logs, and messages. The exact fields displayed depend on the type of data artifact. The two images below show the Data Artifacts tab for a call log and a web bookmark.
\image html content_viewer_results_call.png \image html content_viewer_results_call.png
<br> <br>
\image html content_viewer_results_bookmark.png \image html content_viewer_results_bookmark.png
\section cv_analysis_results Analysis Results
The Analysis Results tab shows all analysis results associated with the item selected in the result viewer. If you select an analysis result, it will auto-scroll to that result in the list. Analysis results come from data such as hash set hits, interesting items, and keyword hits. The image below shows web category analysis results.
\image html content_viewer_analysis_result_webcat.png
\section cv_context Context \section cv_context Context
The Context tab shows information on where a file came from and allows you to navigate to the original result. For example, it can show the the URL for downloaded files and the email message a file was attached to. In the image below you can see the context for an image that was sent as an email attachment. The Context tab shows information on where a file came from and allows you to navigate to the original result. For example, it can show the the URL for downloaded files and the email message a file was attached to. In the image below you can see the context for an image that was sent as an email attachment.

View File

@ -21,18 +21,18 @@ or select the "Tools", "File Search by Attributes".
There are several categories that you can use to filter and show the directories and files within the images in the current opened case. There are several categories that you can use to filter and show the directories and files within the images in the current opened case.
The categories are: The categories are:
\li Name: \li Name:
Search for all files and directory whose name contains the pattern given. Search for all files and directories whose name contains the pattern given. Search is on the file/directory name only and does not look at the parent path.
Note: it doesn't support regular expression and keyword matching. Note: it doesn't support regular expression and keyword matching.
\li Size: \li Size:
Search for all files and directory whose size matches the pattern given. The pattern can be "equal to", "greater than", and "less than". The unit for the size can be "Byte(s)", "KB", "MB", "GB", and "TB". Search for all files and directories whose size matches the pattern given. The pattern can be "equal to", "greater than", and "less than". The unit for the size can be "Byte(s)", "KB", "MB", "GB", and "TB".
\li MIME Type: \li MIME Type:
Search for all files with the selected MIME type. Multiple types can be used by holding SHIFT or CTRL while selecting. Search for all files with the selected MIME type. Multiple types can be used by holding SHIFT or CTRL while selecting.
\li MD5: \li MD5:
Search for all files with the given MD5 hash. Search for all files with the given MD5 hash.
\li Date: \li Date:
Search for all files and directory whose "date property" is within the date range given. The "date properties" are "Modified Date", "Accessed Date", "Changed Date", and "Created Date". You must also specify the timezone for the date given. Search for all files and directories whose "date property" is within the date range given. The "date properties" are "Modified Date", "Accessed Date", "Changed Date", and "Created Date". You must also specify the timezone for the date given.
\li Known Status: \li Known Status:
Search for all files and directory whose known status is recognized as either Unknown, Known, or Known Bad. For more on Known Status, see the \ref hash_db_page. Search for all files whose known status is recognized as either Unknown, Known, or Known Bad. For more on Known Status, see the \ref hash_db_page.
To use any of these filters, check the box next to the category and click "Search" button to start the search process. The result will show up in the "Result Viewer". To use any of these filters, check the box next to the category and click "Search" button to start the search process. The result will show up in the "Result Viewer".
\li Data Source: \li Data Source:
Search only within the specified data source instead of the entire case. Note that multiple data sources can be selected by holding SHIFT or CTRL while selecting. Search only within the specified data source instead of the entire case. Note that multiple data sources can be selected by holding SHIFT or CTRL while selecting.

View File

@ -19,7 +19,7 @@ Hosts are displayed in the \ref tree_viewer_page. Depending on the \ref view_opt
\subsection host_os_accounts OS Accounts \subsection host_os_accounts OS Accounts
OS accounts can be viewed in the OS Accounts node under Results. Each OS account is associated with a host, and the host information is displayed in the OS Account tab of the content viewer. OS accounts can be viewed in the OS Accounts node of the tree viewer. Each OS account is associated with a host, and the host information is displayed in the OS Account tab of the content viewer.
\image html host_os_accounts.png \image html host_os_accounts.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 59 KiB

View File

@ -18,11 +18,11 @@ Refer to \ref ad_hoc_keyword_search_page for more details on specifying regular
\section keyword_search_configuration_dialog Keyword Search Configuration Dialog \section keyword_search_configuration_dialog Keyword Search Configuration Dialog
The keyword search configuration dialog has three tabs, each with its own purpose: The keyword search configuration dialog has three tabs, each with its own purpose:
\li The \ref keywordListsTab is used to add, remove, and modify keyword search lists. \li The \ref keyword_keywordListsTab is used to add, remove, and modify keyword search lists.
\li The \ref stringExtractionTab is used to enable language scripts and extraction type. \li The \ref keyword_stringExtractionTab is used to enable language scripts and extraction type.
\li The \ref generalSettingsTab is used to configure the ingest timings and display information. \li The \ref keyword_generalSettingsTab is used to configure the ingest timings and display information.
## Lists tab {#keywordListsTab} \subsection keyword_keywordListsTab Lists tab
The Lists tab is used to create/import and add content to keyword lists. To create a list, select the 'New List' button and choose a name for the new Keyword List. Once the list has been created, keywords can be added to it (see \ref ad_hoc_kw_types_section for more information on keyword types). Lists can be added to the keyword search ingest process; searches will happen at regular intervals as content is added to the index. The Lists tab is used to create/import and add content to keyword lists. To create a list, select the 'New List' button and choose a name for the new Keyword List. Once the list has been created, keywords can be added to it (see \ref ad_hoc_kw_types_section for more information on keyword types). Lists can be added to the keyword search ingest process; searches will happen at regular intervals as content is added to the index.
@ -40,7 +40,7 @@ Under the Keyword list is the option to send ingest inbox messages for each hit.
\image html keyword-search-inbox.PNG \image html keyword-search-inbox.PNG
## String Extraction tab {#stringExtractionTab} \subsection keyword_stringExtractionTab String Extraction tab
The string extraction setting defines how strings are extracted from files from which text cannot be extracted normally because their file formats are not supported. This is the case with arbitrary binary files (such as the page file) and chunks of unallocated space that represent deleted files. The string extraction setting defines how strings are extracted from files from which text cannot be extracted normally because their file formats are not supported. This is the case with arbitrary binary files (such as the page file) and chunks of unallocated space that represent deleted files.
When we extract strings from binary files we need to interpret sequences of bytes as text differently, depending on the possible text encoding and script/language used. In many cases we don't know in advance what the specific encoding/language the text is encoded in. However, it helps if the investigator is looking for a specific language, because by selecting less languages the indexing performance will be improved and the number of false positives will be reduced. When we extract strings from binary files we need to interpret sequences of bytes as text differently, depending on the possible text encoding and script/language used. In many cases we don't know in advance what the specific encoding/language the text is encoded in. However, it helps if the investigator is looking for a specific language, because by selecting less languages the indexing performance will be improved and the number of false positives will be reduced.
@ -50,20 +50,36 @@ The default setting is to search for English strings only, encoded as either UTF
The user can also use the String Viewer first and try different script/language settings, and see which settings give satisfactory results for the type of text relevant to the investigation. Then the same setting that works for the investigation can be applied to the keyword search ingest. The user can also use the String Viewer first and try different script/language settings, and see which settings give satisfactory results for the type of text relevant to the investigation. Then the same setting that works for the investigation can be applied to the keyword search ingest.
## General Settings tab {#generalSettingsTab} \subsection keyword_generalSettingsTab General Settings tab
\image html keyword-search-configuration-dialog-general.PNG \image html keyword-search-configuration-dialog-general.PNG
### NIST NSRL Support \subsubsection keyword_nsrl NIST NSRL Support
The hash lookup ingest service can be configured to use the NIST NSRL hash set of known files. The keyword search advanced configuration dialog "General" tab contains an option to skip keyword indexing and search on files that have previously marked as "known" and uninteresting files. Selecting this option can greatly reduce size of the index and improve ingest performance. In most cases, user does not need to keyword search for "known" files. The hash lookup ingest service can be configured to use the NIST NSRL hash set of known files. The keyword search advanced configuration dialog "General" tab contains an option to skip keyword indexing and search on files that have previously marked as "known" and uninteresting files. Selecting this option can greatly reduce size of the index and improve ingest performance. In most cases, user does not need to keyword search for "known" files.
### Result update frequency during ingest \subsubsection keyword_update_freq Result update frequency during ingest
To control how frequently searches are executed during ingest, the user can adjust the timing setting available in the keyword search advanced configuration dialog "General" tab. Setting the number of minutes lower will result in more frequent index updates and searches being executed and the user will be able to see results more in real-time. However, more frequent updates can affect the overall performance, especially on lower-end systems, and can potentially lengthen the overall time needed for the ingest to complete. To control how frequently searches are executed during ingest, the user can adjust the timing setting available in the keyword search advanced configuration dialog "General" tab. Setting the number of minutes lower will result in more frequent index updates and searches being executed and the user will be able to see results more in real-time. However, more frequent updates can affect the overall performance, especially on lower-end systems, and can potentially lengthen the overall time needed for the ingest to complete.
One can also choose to have no periodic searches. This will speed up the ingest. Users choosing this option can run their keyword searches once the entire keyword search index is complete. One can also choose to have no periodic searches. This will speed up the ingest. Users choosing this option can run their keyword searches once the entire keyword search index is complete.
### Optical Character Recognition \section keyword_usage Using the Module
There is also a setting to enable Optical Character Recognition (OCR). If enabled, text may be extracted from supported image types. Enabling this feature will make the keyword search module take longer to run, and the results are not perfect. The secondary checkbox can make OCR run faster by only processing large images and images extracted from documents.
Search queries can be executed manually by the user at any time, as long as there are some files already indexed and ready to be searched. Searching before indexing is complete will naturally only search indexes that are already compiled.
See \ref ingest_page "Ingest" for more information on ingest in general.
Once there are files in the index, \ref ad_hoc_keyword_search_page will be available for use to manually search at any time.
\subsection keyword_ingest_settings Ingest Settings
The Ingest Settings for the Keyword Search module allow the user to enable or disable the specific built-in search expressions, Phone Numbers, IP Addresses, Email Addresses, and URLs. Using the Advanced button (covered below), one can add custom keyword groups.
\image html keyword-search-ingest-settings.PNG
\subsubsection keyword_ocr Optical Character Recognition
\anchor keyword_search_ocr_config
There is also a setting to enable Optical Character Recognition (OCR). If enabled, text may be extracted from supported image types. Enabling this feature will make the keyword search module take longer to run, and the results are not perfect.
The following shows a sample image containing text: The following shows a sample image containing text:
@ -73,7 +89,12 @@ The "Indexed Text" tab shows the results when running the keyword search module
\image html keyword-search-ocr-indexed-text.png \image html keyword-search-ocr-indexed-text.png
\anchor keyword_search_ocr_config The two options to related to OCR are the following:
<ul>
<li>Only index text extracted from an image. This will prevent keyword search from indexing text found in text files, docs, etc.
<li>Only run on large images and documents and extracted files. With this selected, OCR will only be performed on images over 100KB and PDFs/Office docs. It will also run on images of any size that were extracted from another file.
</ul>
By default, OCR is only configured for English text. Its configuration depends on the presence of language files (called "traineddata" files) By default, OCR is only configured for English text. Its configuration depends on the presence of language files (called "traineddata" files)
that exist in a location that Autopsy can understand. To add support for more languages, you will need to download additional "traineddata" that exist in a location that Autopsy can understand. To add support for more languages, you will need to download additional "traineddata"
and move them to the right location. The following steps breakdown this process for you: and move them to the right location. The following steps breakdown this process for you:
@ -88,28 +109,8 @@ and move them to the right location. The following steps breakdown this process
The language files will now be supported when OCR is enabled in the Keyword Search Settings. The language files will now be supported when OCR is enabled in the Keyword Search Settings.
<!----------------------------------------->
<br> \section keyword_results Seeing Results
Using the Module
======
Search queries can be executed manually by the user at any time, as long as there are some files already indexed and ready to be searched. Searching before indexing is complete will naturally only search indexes that are already compiled.
See \ref ingest_page "Ingest" for more information on ingest in general.
Once there are files in the index, \ref ad_hoc_keyword_search_page will be available for use to manually search at any time.
<!----------------------------------->
Ingest Settings
------
The Ingest Settings for the Keyword Search module allow the user to enable or disable the specific built-in search expressions, Phone Numbers, IP Addresses, Email Addresses, and URLs. Using the Advanced button (covered below), one can add custom keyword groups.
\image html keyword-search-ingest-settings.PNG
Seeing Results
------
The Keyword Search module will save the search results regardless whether the search is performed by the ingest process, or manually by the user. The saved results are available in the Directory Tree in the left hand side panel. The Keyword Search module will save the search results regardless whether the search is performed by the ingest process, or manually by the user. The saved results are available in the Directory Tree in the left hand side panel.

View File

@ -25,8 +25,8 @@ These columns display the following information:
<ul> <ul>
<li> (S)core column - indicates whether the item is interesting or notable. <li> (S)core column - indicates whether the item is interesting or notable.
<ul> <ul>
<li>Displays a red icon if the file is a match for a notable hashset or has been tagged with a notable tag. <li>Displays a red icon if at least one child analysis result is notable or the file is tagged with a notable tag.
<li>Displays a yellow icon if the file has an interesting item match or has been tagged with a non-notable tag. <li>Displays a yellow icon if at least one child analysis result is likely notable or the file has a tag.
</ul> </ul>
<li> (C)omment column - indicates whether the item has a comment in the Central Repository or has a comment associated with a tag. <li> (C)omment column - indicates whether the item has a comment in the Central Repository or has a comment associated with a tag.
<li> (O)ther occurrences column - indicates how many data sources in the Central Repository contain this item. The count will include the selected item. <li> (O)ther occurrences column - indicates how many data sources in the Central Repository contain this item. The count will include the selected item.

View File

@ -3,10 +3,12 @@
[TOC] [TOC]
The tree on the left-hand side of the main window is where you can browse the files in the data sources in the case and find saved results from automated analyis (ingest). The tree has five main areas: The tree on the left-hand side of the main window is where you can browse the files in the data sources in the case and find saved results from automated analyis (ingest). The tree has seven main areas:
- <b>Persons / Hosts / Data Sources:</b> This shows the directory tree hierarchy of the data sources. You can navigate to a specific file or directory here. Each data source added to the case is represented as a distinct sub tree. If you add a data source multiple times, it shows up multiple times. - <b>Persons / Hosts / Data Sources:</b> This shows the directory tree hierarchy of the data sources. You can navigate to a specific file or directory here. Each data source added to the case is represented as a distinct sub tree. If you add a data source multiple times, it shows up multiple times.
- <b>Views:</b> Specific types of files from the data sources are shown here, aggregated by type or other properties. Files here can come from more than one data source. - <b>File Views:</b> Specific types of files from the data sources are shown here, aggregated by type or other properties. Files here can come from more than one data source.
- <b>Results:</b> This is where you can see the results from both the automated analysis (ingest) running in the background and your search results. - <b>Data Artifacts:</b> This isone of the main places where results from running \ref ingest_page appear.
- <b>Analysis Results:</b> This is the other main place where results from running \ref ingest_page appear.
- <b>OS Accounts:</b> This is where you can see the results from both the automated analysis (ingest) running in the background and your search results.
- <b>Tags:</b> This is where files and results that have been \ref tagging_page "tagged" are shown. - <b>Tags:</b> This is where files and results that have been \ref tagging_page "tagged" are shown.
- <b>Reports:</b> Reports that you have generated, or that ingest modules have created, show up here. - <b>Reports:</b> Reports that you have generated, or that ingest modules have created, show up here.
@ -43,22 +45,28 @@ Unallocated space is the chunks of a file system that are currently not being us
An example of the single file extraction option is shown below. An example of the single file extraction option is shown below.
\image html extracting-unallocated-space.PNG \image html extracting-unallocated-space.PNG
\section ui_tree_views Views \section ui_tree_views File Views
Views filter all the files in the case by some property of the file. Views filter all the files in the case by some property of the file.
- <b>File Types</b> Sorts files by file extension or by MIME type, and shows them in the appropriate group. For example, files with .mp3 and .wav extensions end up in the "Audio" group. - <b>File Types</b> Sorts files by file extension or by MIME type, and shows them in the appropriate group. For example, files with .mp3 and .wav extensions end up in the "Audio" group.
- <b>Deleted Files</b> Displays files that have been deleted, but the names have been recovered. - <b>Deleted Files</b> Displays files that have been deleted, but the names have been recovered.
- <b>File Size</b> Sorts files based on size. - <b>File Size</b> Sorts files based on size.
\section ui_tree_results Data Artifacts
\section ui_tree_results Results This section shows the data artifacts created by running ingest. In general, data artifacts contain concrete information extracted from the data source. For example, call logs and messages from communication logs or web bookmarks extracted from a browser database.
- <b>Extracted Content:</b> Many ingest modules will place results here; EXIF metadata, GPS locations, or Web history for example.
- <b>Keyword Hits:</b> Keyword search hits show up here. \section ui_tree_analysis_results Analysis Results
- <b>Hashset Hits:</b> Hashset hits show up here.
- <b>E-Mail Messages:</b> Email messages show up here. This section shows the analysis results created by running ingest. In general, analysis results contain information that the user has indicated they are interested in. For example, if the user sets up a list of \ref hash_db_page "notable hashes", any hash set hits will appear here.
- <b>Interesting Items:</b> Things deemed interesting show up here.
- <b>Accounts:</b> Credit card accounts show up here. \section ui_tree_os_accounts OS Accounts
- <b>Tags:</b> Any item you tag shows up here so you can find it again easily.
This section shows the OS accounts found in the case. See \ref host_os_accounts for an example.
\section ui_tree_tags Tags
Any item you tag shows up here so you can find it again easily. See \ref tagging_page for more information.
\section ui_tree_reports Reports \section ui_tree_reports Reports