Merge remote-tracking branch 'upstream/release-4.19.0' into 7805_noFileCorrAttrs
@ -5,7 +5,10 @@ CentralRepoCommentDialog.title.addEditCentralRepoComment=Add/Edit Central Reposi
|
||||
OpenIDE-Module-Name=Central Repository
|
||||
OpenIDE-Module-Display-Category=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.okButton.text=&OK
|
||||
CentralRepoCommentDialog.cancelButton.text=C&ancel
|
||||
|
@ -85,7 +85,7 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
private AbstractFile file = null;
|
||||
|
||||
private SwingWorker<?, ?> worker;
|
||||
|
||||
|
||||
// Initializing the JFileChooser in a thread to prevent a block on the EDT
|
||||
// see https://stackoverflow.com/questions/49792375/jfilechooser-is-very-slow-when-using-windows-look-and-feel
|
||||
private final FutureTask<JFileChooser> futureFileChooser = new FutureTask<>(JFileChooser::new);
|
||||
@ -101,7 +101,7 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
this.correlationAttributes = new ArrayList<>();
|
||||
initComponents();
|
||||
customizeComponents();
|
||||
|
||||
|
||||
ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||
executor.execute(futureFileChooser);
|
||||
}
|
||||
@ -223,7 +223,7 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
String caseDisplayName = Bundle.OtherOccurrencesPanel_caseDetailsDialog_noCaseNameError();
|
||||
String details = Bundle.OtherOccurrencesPanel_caseDetailsDialog_noDetails();
|
||||
try {
|
||||
if (-1 != selectedRowViewIdx) {
|
||||
if (-1 != selectedRowViewIdx && filesTableModel.getRowCount() > 0) {
|
||||
CentralRepository dbManager = CentralRepository.getInstance();
|
||||
int selectedRowModelIdx = filesTable.convertRowIndexToModel(selectedRowViewIdx);
|
||||
List<NodeData> rowList = filesTableModel.getListOfNodesForFile(selectedRowModelIdx);
|
||||
@ -253,9 +253,9 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
|
||||
private void saveToCSV() throws NoCurrentCaseException {
|
||||
if (casesTableModel.getRowCount() > 0) {
|
||||
|
||||
if(CSVFileChooser == null) {
|
||||
try{
|
||||
|
||||
if (CSVFileChooser == null) {
|
||||
try {
|
||||
CSVFileChooser = futureFileChooser.get();
|
||||
} catch (InterruptedException | ExecutionException ex) {
|
||||
// If something happened with the thread try and
|
||||
@ -264,7 +264,7 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
CSVFileChooser = new JFileChooser();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Calendar now = Calendar.getInstance();
|
||||
String fileName = String.format("%1$tY%1$tm%1$te%1$tI%1$tM%1$tS_other_data_sources.csv", now);
|
||||
CSVFileChooser.setCurrentDirectory(new File(Case.getCurrentCaseThrows().getExportDirectory()));
|
||||
@ -339,12 +339,13 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
casesTableModel.addCorrelationCase(NO_ARTIFACTS_CASE);
|
||||
} else if (caseCount == 0) {
|
||||
casesTableModel.addCorrelationCase(NO_RESULTS_CASE);
|
||||
}
|
||||
String earliestDate = data.getEarliestCaseDate();
|
||||
earliestCaseDate.setText(earliestDate.isEmpty() ? Bundle.OtherOccurrencesPanel_earliestCaseNotAvailable() : earliestDate);
|
||||
foundInLabel.setText(String.format(Bundle.OtherOccurrencesPanel_foundIn_text(), data.getTotalCount(), caseCount, data.getDataSourceCount()));
|
||||
if (caseCount > 0) {
|
||||
casesTable.setRowSelectionInterval(0, 0);
|
||||
} else {
|
||||
String earliestDate = data.getEarliestCaseDate();
|
||||
earliestCaseDate.setText(earliestDate.isEmpty() ? Bundle.OtherOccurrencesPanel_earliestCaseNotAvailable() : earliestDate);
|
||||
foundInLabel.setText(String.format(Bundle.OtherOccurrencesPanel_foundIn_text(), data.getTotalCount(), caseCount, data.getDataSourceCount()));
|
||||
if (caseCount > 0) {
|
||||
casesTable.setRowSelectionInterval(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (InterruptedException | ExecutionException ex) {
|
||||
@ -389,12 +390,13 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
casesTableModel.addCorrelationCase(NO_ARTIFACTS_CASE);
|
||||
} else if (caseCount == 0) {
|
||||
casesTableModel.addCorrelationCase(NO_RESULTS_CASE);
|
||||
}
|
||||
String earliestDate = data.getEarliestCaseDate();
|
||||
earliestCaseDate.setText(earliestDate.isEmpty() ? Bundle.OtherOccurrencesPanel_earliestCaseNotAvailable() : earliestDate);
|
||||
foundInLabel.setText(String.format(Bundle.OtherOccurrencesPanel_foundIn_text(), data.getInstanceDataCount(), caseCount, data.getDataSourceCount()));
|
||||
if (caseCount > 0) {
|
||||
casesTable.setRowSelectionInterval(0, 0);
|
||||
} else {
|
||||
String earliestDate = data.getEarliestCaseDate();
|
||||
earliestCaseDate.setText(earliestDate.isEmpty() ? Bundle.OtherOccurrencesPanel_earliestCaseNotAvailable() : earliestDate);
|
||||
foundInLabel.setText(String.format(Bundle.OtherOccurrencesPanel_foundIn_text(), data.getInstanceDataCount(), caseCount, data.getDataSourceCount()));
|
||||
if (caseCount > 0) {
|
||||
casesTable.setRowSelectionInterval(0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -420,7 +422,7 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
|
||||
worker = new SelectionWorker(correlationAttributes, file, deviceId, dataSourceName) {
|
||||
@ -440,31 +442,32 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
currentCaseName = null;
|
||||
logger.log(Level.WARNING, "Unable to get current case for other occurrences content viewer", ex);
|
||||
}
|
||||
|
||||
for (NodeData nodeData : correlatedNodeDataMap.values()) {
|
||||
for (int selectedRow : selectedCaseIndexes) {
|
||||
try {
|
||||
if (nodeData.isCentralRepoNode()) {
|
||||
if (casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedRow)) != null
|
||||
&& casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedRow)).getCaseUUID().equals(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID())) {
|
||||
if (casesTableModel.getRowCount() > 0) {
|
||||
for (NodeData nodeData : correlatedNodeDataMap.values()) {
|
||||
for (int selectedRow : selectedCaseIndexes) {
|
||||
try {
|
||||
if (nodeData.isCentralRepoNode()) {
|
||||
if (casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedRow)) != null
|
||||
&& casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedRow)).getCaseUUID().equals(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID())) {
|
||||
dataSourcesTableModel.addNodeData(nodeData);
|
||||
}
|
||||
} else if (currentCaseName != null && (casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedRow)).getCaseUUID().equals(currentCaseName))) {
|
||||
dataSourcesTableModel.addNodeData(nodeData);
|
||||
}
|
||||
} else if (currentCaseName != null && (casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedRow)).getCaseUUID().equals(currentCaseName))) {
|
||||
dataSourcesTableModel.addNodeData(nodeData);
|
||||
} catch (CentralRepoException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get correlation attribute instance from OtherOccurrenceNodeInstanceData for case " + nodeData.getCaseName(), ex);
|
||||
}
|
||||
} catch (CentralRepoException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get correlation attribute instance from OtherOccurrenceNodeInstanceData for case " + nodeData.getCaseName(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dataSourcesTable.getRowCount() > 0) {
|
||||
if (dataSourcesTableModel.getRowCount() > 0) {
|
||||
dataSourcesTable.setRowSelectionInterval(0, 0);
|
||||
}
|
||||
|
||||
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
|
||||
} catch (InterruptedException | ExecutionException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to update OtherOccurrencesPanel on data source selection", ex);
|
||||
logger.log(Level.SEVERE, "Failed to update OtherOccurrencesPanel on data source selection", ex);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -496,25 +499,29 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
|
||||
try {
|
||||
Map<UniquePathKey, NodeData> correlatedNodeDataMap = get();
|
||||
for (NodeData nodeData : correlatedNodeDataMap.values()) {
|
||||
for (int selectedDataSourceRow : selectedDataSources) {
|
||||
try {
|
||||
if (nodeData.isCentralRepoNode()) {
|
||||
if (dataSourcesTableModel.getCaseUUIDForRow(dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow)).equals(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID())
|
||||
&& dataSourcesTableModel.getDeviceIdForRow(dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow)).equals(nodeData.getDeviceID())) {
|
||||
filesTableModel.addNodeData(nodeData);
|
||||
}
|
||||
} else {
|
||||
if (dataSourcesTableModel.getDeviceIdForRow(dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow)).equals(nodeData.getDeviceID())) {
|
||||
filesTableModel.addNodeData(nodeData);
|
||||
if (dataSourcesTableModel.getRowCount() > 0) {
|
||||
for (NodeData nodeData : correlatedNodeDataMap.values()) {
|
||||
for (int selectedDataSourceRow : selectedDataSources) {
|
||||
int rowModelIndex = dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow);
|
||||
try {
|
||||
if (nodeData.isCentralRepoNode()) {
|
||||
if (dataSourcesTableModel.getCaseUUIDForRow(rowModelIndex).equals(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID())
|
||||
&& dataSourcesTableModel.getDeviceIdForRow(rowModelIndex).equals(nodeData.getDeviceID())) {
|
||||
filesTableModel.addNodeData(nodeData);
|
||||
}
|
||||
} else {
|
||||
if (dataSourcesTableModel.getDeviceIdForRow(dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow)).equals(nodeData.getDeviceID())) {
|
||||
filesTableModel.addNodeData(nodeData);
|
||||
}
|
||||
}
|
||||
} catch (CentralRepoException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get correlation attribute instance from OtherOccurrenceNodeInstanceData for case " + nodeData.getCaseName(), ex);
|
||||
}
|
||||
} catch (CentralRepoException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get correlation attribute instance from OtherOccurrenceNodeInstanceData for case " + nodeData.getCaseName(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (filesTable.getRowCount() > 0) {
|
||||
|
||||
if (filesTableModel.getRowCount() > 0) {
|
||||
filesTable.setRowSelectionInterval(0, 0);
|
||||
}
|
||||
} catch (InterruptedException | ExecutionException ex) {
|
||||
@ -535,18 +542,20 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
private void updateOnFileSelection() {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
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
|
||||
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
|
||||
String caseName = dataSourcesTableModel.getCaseNameForRow(dataSourcesTable.convertRowIndexToModel(dataSourcesTable.getSelectedRow()));
|
||||
String dsName = dataSourcesTableModel.getValueAt(dataSourcesTable.convertRowIndexToModel(dataSourcesTable.getSelectedRow()), 0).toString();
|
||||
String caseCreatedDate = "";
|
||||
for (int row : casesTable.getSelectedRows()) {
|
||||
if (casesTableModel.getValueAt(casesTable.convertRowIndexToModel(row), 0).toString().equals(caseName)) {
|
||||
caseCreatedDate = getCaseCreatedDate(row);
|
||||
break;
|
||||
if (casesTableModel.getRowCount() > 0) {
|
||||
for (int row : casesTable.getSelectedRows()) {
|
||||
if (casesTableModel.getValueAt(casesTable.convertRowIndexToModel(row), 0).toString().equals(caseName)) {
|
||||
caseCreatedDate = getCaseCreatedDate(row);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
occurrencePanel = new OccurrencePanel(caseName, caseCreatedDate, dsName);
|
||||
@ -555,7 +564,7 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
//update the information to reflect the case
|
||||
String createdDate;
|
||||
String caseName = "";
|
||||
if (casesTable.getRowCount() > 0) {
|
||||
if (casesTableModel.getRowCount() > 0) {
|
||||
caseName = casesTableModel.getValueAt(casesTable.convertRowIndexToModel(casesTable.getSelectedRow()), 0).toString();
|
||||
}
|
||||
if (caseName.isEmpty()) {
|
||||
@ -586,7 +595,7 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
*/
|
||||
private String getCaseCreatedDate(int caseTableRowIdx) {
|
||||
try {
|
||||
if (CentralRepository.isEnabled()) {
|
||||
if (CentralRepository.isEnabled() && casesTableModel.getRowCount() > 0) {
|
||||
CorrelationCase partialCase;
|
||||
partialCase = casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(caseTableRowIdx));
|
||||
if (partialCase == null) {
|
||||
@ -614,11 +623,11 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
|
||||
/**
|
||||
* Construct a new SelectionWorker.
|
||||
*
|
||||
*
|
||||
* @param coAtInstances
|
||||
* @param abstractFile
|
||||
* @param deviceIdStr
|
||||
* @param dataSourceNameStr
|
||||
* @param dataSourceNameStr
|
||||
*/
|
||||
SelectionWorker(Collection<CorrelationAttributeInstance> coAtInstances, AbstractFile abstractFile, String deviceIdStr, String dataSourceNameStr) {
|
||||
this.coAtInstances = coAtInstances;
|
||||
@ -632,12 +641,12 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
Map<UniquePathKey, NodeData> correlatedNodeDataMap = new HashMap<>();
|
||||
for (CorrelationAttributeInstance corAttr : coAtInstances) {
|
||||
correlatedNodeDataMap.putAll(OtherOccurrences.getCorrelatedInstances(abstractFile, deviceIdStr, dataSourceNameStr, corAttr));
|
||||
|
||||
if(isCancelled()) {
|
||||
|
||||
if (isCancelled()) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return correlatedNodeDataMap;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Central Repository
|
||||
*
|
||||
* Copyright 2017-2020 Basis Technology Corp.
|
||||
* Copyright 2017-2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* 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.Executors;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.openide.util.Exceptions;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
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.datamodel.Tag;
|
||||
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.datamodel.Blackboard;
|
||||
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_SET_NAME;
|
||||
import org.sleuthkit.datamodel.OsAccount;
|
||||
@ -678,7 +676,8 @@ public final class CaseEventListener implements PropertyChangeListener {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!CentralRepository.isEnabled()) {
|
||||
//Nothing to do here if the central repo is not enabled or the ingest is running and the setting to flag previously seen devices and users is not set to true
|
||||
if (!CentralRepository.isEnabled() || (IngestManager.getInstance().isIngestRunning() && !IngestEventsListener.isFlagSeenDevices())) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -709,10 +708,8 @@ public final class CaseEventListener implements PropertyChangeListener {
|
||||
dbManager.addArtifactInstance(correlationAttributeInstance);
|
||||
|
||||
List<CorrelationAttributeInstance> previousOccurences = dbManager.getArtifactInstancesByTypeValue(CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.OSACCOUNT_TYPE_ID), correlationAttributeInstance.getCorrelationValue());
|
||||
List<String> caseDisplayNames;
|
||||
for (CorrelationAttributeInstance instance : previousOccurences) {
|
||||
if (!instance.getCorrelationCase().getCaseUUID().equals(correlationAttributeInstance.getCorrelationCase().getCaseUUID())) {
|
||||
caseDisplayNames = dbManager.getListCasesHavingArtifactInstances(correlationAttributeInstance.getCorrelationType(), correlationAttributeInstance.getCorrelationValue());
|
||||
SleuthkitCase tskCase = osAccount.getSleuthkitCase();
|
||||
Blackboard blackboard = tskCase.getBlackboard();
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
IngestSettingsPanel.ingestSettingsLabel.text=Ingest Settings
|
||||
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
|
||||
|
@ -11,5 +11,5 @@ CentralRepoIngestModuleFactory.ingestmodule.desc=Saves properties to the central
|
||||
CentralRepoIngestModuleFactory.ingestmodule.name=Central Repository
|
||||
IngestSettingsPanel.ingestSettingsLabel.text=Ingest Settings
|
||||
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
|
||||
|
@ -29,7 +29,7 @@
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace pref="47" max="32767" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
|
@ -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(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))))
|
||||
.addContainerGap(47, Short.MAX_VALUE))
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
|
@ -291,11 +291,18 @@ public class DataResultFilterNode extends FilterNode {
|
||||
NbBundle.getMessage(this.getClass(), "DataResultFilterNode.action.viewFileInDir.text"), ban));
|
||||
}
|
||||
} else if (artifactTypeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID()) {
|
||||
//action to go to the source artifact
|
||||
actionsList.add(new ViewSourceArtifactAction(DataResultFilterNode_viewSourceArtifact_text(), ba));
|
||||
// action to go to the source file of the artifact
|
||||
actionsList.add(new ViewContextAction(
|
||||
NbBundle.getMessage(this.getClass(), "DataResultFilterNode.action.viewSrcFileInDir.text"), ban));
|
||||
try {
|
||||
if (ba.getAttribute(BlackboardAttribute.Type.TSK_ASSOCIATED_ARTIFACT) != null) {
|
||||
//action to go to the source artifact
|
||||
actionsList.add(new ViewSourceArtifactAction(DataResultFilterNode_viewSourceArtifact_text(), ba));
|
||||
|
||||
// action to go to the source file of the artifact
|
||||
actionsList.add(new ViewContextAction(
|
||||
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 {
|
||||
// if the artifact links to another file, add an action to go to
|
||||
// that file
|
||||
|
@ -147,7 +147,6 @@ public final class KeywordSearchJobSettings implements IngestModuleIngestJobSett
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public long getVersionNumber() {
|
||||
|
@ -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
|
||||
|
||||
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.
|
||||
|
||||
|
@ -111,7 +111,11 @@ Descriptions of the property types:
|
||||
- <b>ICCID Number</b>
|
||||
- ICCID properties are currently only created by custom Autopsy modules.
|
||||
- <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>
|
||||
- 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>
|
||||
<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 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>
|
||||
|
||||
\subsection cr_tagging Tagging Files and Artifacts
|
||||
|
@ -75,9 +75,9 @@ Registry hive files can be viewed in a format similar to a registry editor.
|
||||
|
||||
\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
|
||||
|
||||
@ -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
|
||||
|
||||
\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
|
||||
<br>
|
||||
\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
|
||||
|
||||
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.
|
||||
|
@ -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
|
||||
|
||||
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
|
||||
|
||||
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 59 KiB |
@ -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
|
||||
|
||||
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 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_keywordListsTab is used to add, remove, and modify keyword search lists.
|
||||
\li The \ref keyword_stringExtractionTab is used to enable language scripts and extraction type.
|
||||
\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.
|
||||
|
||||
@ -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
|
||||
|
||||
## 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.
|
||||
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.
|
||||
|
||||
|
||||
## General Settings tab {#generalSettingsTab}
|
||||
\subsection keyword_generalSettingsTab General Settings tab
|
||||
|
||||
\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.
|
||||
|
||||
### 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.
|
||||
|
||||
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
|
||||
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.
|
||||
\section keyword_usage 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.
|
||||
|
||||
\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:
|
||||
|
||||
@ -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
|
||||
|
||||
\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)
|
||||
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:
|
||||
@ -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.
|
||||
|
||||
<!----------------------------------------->
|
||||
|
||||
<br>
|
||||
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
|
||||
------
|
||||
\section keyword_results 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.
|
||||
|
||||
|
@ -25,8 +25,8 @@ These columns display the following information:
|
||||
<ul>
|
||||
<li> (S)core column - indicates whether the item is interesting or notable.
|
||||
<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 yellow icon if the file has an interesting item match or has been tagged with a non-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 at least one child analysis result is likely notable or the file has a tag.
|
||||
</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> (O)ther occurrences column - indicates how many data sources in the Central Repository contain this item. The count will include the selected item.
|
||||
|
@ -3,10 +3,12 @@
|
||||
[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>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>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>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>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.
|
||||
\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.
|
||||
- <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>File Size</b> Sorts files based on size.
|
||||
|
||||
\section ui_tree_results Data Artifacts
|
||||
|
||||
\section ui_tree_results Results
|
||||
- <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.
|
||||
- <b>Hashset Hits:</b> Hashset hits show up here.
|
||||
- <b>E-Mail Messages:</b> Email messages show up here.
|
||||
- <b>Interesting Items:</b> Things deemed interesting show up here.
|
||||
- <b>Accounts:</b> Credit card accounts show up here.
|
||||
- <b>Tags:</b> Any item you tag shows up here so you can find it again easily.
|
||||
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.
|
||||
|
||||
\section ui_tree_analysis_results Analysis Results
|
||||
|
||||
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.
|
||||
|
||||
\section ui_tree_os_accounts OS Accounts
|
||||
|
||||
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
|
||||
|
||||
|