mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-15 09:17:42 +00:00
Merge pull request #7169 from eugene7646/flag_unique_apps_7862
Flag unique apps (7862)
This commit is contained in:
commit
3d008c338e
@ -37,7 +37,7 @@ 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.Content;
|
||||||
import org.sleuthkit.datamodel.DataSource;
|
import org.sleuthkit.datamodel.DataArtifact;
|
||||||
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;
|
||||||
@ -271,8 +271,8 @@ public class CorrelationAttributeUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the associated artifact of a "meta-artifact" such as an interesting
|
* Gets the associated artifact of a "meta-artifact" such as an "interesting
|
||||||
* artifact hit artifact.
|
* artifact hit" or "previously seen" artifact.
|
||||||
*
|
*
|
||||||
* @param artifact An artifact.
|
* @param artifact An artifact.
|
||||||
*
|
*
|
||||||
@ -290,7 +290,14 @@ public class CorrelationAttributeUtil {
|
|||||||
if (assocArtifactAttr != null) {
|
if (assocArtifactAttr != null) {
|
||||||
sourceArtifact = Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboardArtifact(assocArtifactAttr.getValueLong());
|
sourceArtifact = Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboardArtifact(assocArtifactAttr.getValueLong());
|
||||||
}
|
}
|
||||||
} else {
|
} else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_PREVIOUSLY_SEEN.getTypeID() == artifact.getArtifactTypeID()) {
|
||||||
|
Content content = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID());
|
||||||
|
if (content instanceof DataArtifact) {
|
||||||
|
sourceArtifact = (BlackboardArtifact) content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sourceArtifact == null) {
|
||||||
sourceArtifact = artifact;
|
sourceArtifact = artifact;
|
||||||
}
|
}
|
||||||
return sourceArtifact;
|
return sourceArtifact;
|
||||||
|
@ -727,7 +727,7 @@ public final class CaseEventListener implements PropertyChangeListener {
|
|||||||
TSK_COMMENT, MODULE_NAME,
|
TSK_COMMENT, MODULE_NAME,
|
||||||
Bundle.CaseEventsListener_prevCaseComment_text()));
|
Bundle.CaseEventsListener_prevCaseComment_text()));
|
||||||
BlackboardArtifact newAnalysisResult = osAccount.newAnalysisResult(
|
BlackboardArtifact newAnalysisResult = osAccount.newAnalysisResult(
|
||||||
BlackboardArtifact.Type.TSK_INTERESTING_ARTIFACT_HIT, Score.SCORE_LIKELY_NOTABLE,
|
BlackboardArtifact.Type.TSK_PREVIOUSLY_SEEN, Score.SCORE_LIKELY_NOTABLE,
|
||||||
null, Bundle.CaseEventsListener_prevExists_text(), null, attributesForNewArtifact, osAccountInstance.getDataSource().getId()).getAnalysisResult();
|
null, Bundle.CaseEventsListener_prevExists_text(), null, attributesForNewArtifact, osAccountInstance.getDataSource().getId()).getAnalysisResult();
|
||||||
try {
|
try {
|
||||||
// index the artifact for keyword search
|
// index the artifact for keyword search
|
||||||
|
@ -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");
|
||||||
@ -26,6 +26,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -46,14 +47,13 @@ import org.sleuthkit.autopsy.ingest.IngestManager;
|
|||||||
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
|
||||||
import org.sleuthkit.datamodel.Blackboard;
|
import org.sleuthkit.datamodel.Blackboard;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT;
|
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_PREVIOUSLY_SEEN;
|
||||||
|
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_PREVIOUSLY_UNSEEN;
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
import org.sleuthkit.autopsy.coreutils.ThreadUtils;
|
import org.sleuthkit.autopsy.coreutils.ThreadUtils;
|
||||||
import static org.sleuthkit.autopsy.ingest.IngestManager.IngestModuleEvent.DATA_ADDED;
|
import static org.sleuthkit.autopsy.ingest.IngestManager.IngestModuleEvent.DATA_ADDED;
|
||||||
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.autopsy.ingest.events.DataSourceAnalysisEvent;
|
import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisEvent;
|
||||||
@ -199,7 +199,7 @@ public class IngestEventsListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make an Interesting Item artifact based on a new artifact being
|
* Make a "previously seen" artifact based on a new artifact being
|
||||||
* previously seen.
|
* previously seen.
|
||||||
*
|
*
|
||||||
* @param originalArtifact Original artifact that we want to flag
|
* @param originalArtifact Original artifact that we want to flag
|
||||||
@ -215,18 +215,15 @@ public class IngestEventsListener {
|
|||||||
Bundle.IngestEventsListener_prevTaggedSet_text()),
|
Bundle.IngestEventsListener_prevTaggedSet_text()),
|
||||||
new BlackboardAttribute(
|
new BlackboardAttribute(
|
||||||
TSK_COMMENT, MODULE_NAME,
|
TSK_COMMENT, MODULE_NAME,
|
||||||
Bundle.IngestEventsListener_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(","))),
|
Bundle.IngestEventsListener_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(","))));
|
||||||
new BlackboardAttribute(
|
makeAndPostArtifact(BlackboardArtifact.Type.TSK_PREVIOUSLY_SEEN, originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevTaggedSet_text());
|
||||||
TSK_ASSOCIATED_ARTIFACT, MODULE_NAME,
|
|
||||||
originalArtifact.getArtifactID()));
|
|
||||||
makeAndPostInterestingArtifact(originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevTaggedSet_text());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an Interesting Artifact hit for a device which was previously seen
|
* Create a "previously seen" hit for a device which was previously seen
|
||||||
* in the central repository.
|
* in the central repository.
|
||||||
*
|
*
|
||||||
* @param originalArtifact the artifact to create the interesting item for
|
* @param originalArtifact the artifact to create the "previously seen" item for
|
||||||
* @param caseDisplayNames the case names the artifact was previously seen
|
* @param caseDisplayNames the case names the artifact was previously seen
|
||||||
* in
|
* in
|
||||||
*/
|
*/
|
||||||
@ -240,39 +237,46 @@ public class IngestEventsListener {
|
|||||||
Bundle.IngestEventsListener_prevExists_text()),
|
Bundle.IngestEventsListener_prevExists_text()),
|
||||||
new BlackboardAttribute(
|
new BlackboardAttribute(
|
||||||
TSK_COMMENT, MODULE_NAME,
|
TSK_COMMENT, MODULE_NAME,
|
||||||
Bundle.IngestEventsListener_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(","))),
|
Bundle.IngestEventsListener_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(","))));
|
||||||
new BlackboardAttribute(
|
makeAndPostArtifact(BlackboardArtifact.Type.TSK_PREVIOUSLY_SEEN, originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevExists_text());
|
||||||
TSK_ASSOCIATED_ARTIFACT, MODULE_NAME,
|
|
||||||
originalArtifact.getArtifactID()));
|
|
||||||
makeAndPostInterestingArtifact(originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevExists_text());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a "previously unseen" hit for an application which was never seen in
|
||||||
|
* the central repository.
|
||||||
|
*
|
||||||
|
* @param originalArtifact the artifact to create the "previously unseen" item
|
||||||
|
* for
|
||||||
|
*/
|
||||||
|
static private void makeAndPostPreviouslyUnseenArtifact(BlackboardArtifact originalArtifact) {
|
||||||
|
Collection<BlackboardAttribute> attributesForNewArtifact = new ArrayList<>();
|
||||||
|
makeAndPostArtifact(BlackboardArtifact.Type.TSK_PREVIOUSLY_UNSEEN, originalArtifact, attributesForNewArtifact, "");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make an interesting item artifact to flag the passed in artifact.
|
* Make an artifact to flag the passed in artifact.
|
||||||
*
|
*
|
||||||
* @param originalArtifact Artifact in current case we want to flag
|
* @param originalArtifact Artifact in current case we want to flag
|
||||||
* @param attributesForNewArtifact Attributes to assign to the new
|
* @param attributesForNewArtifact Attributes to assign to the new artifact
|
||||||
* Interesting items artifact
|
* @param configuration The configuration to be specified for the new artifact hit
|
||||||
* @param configuration The configuration to be specified for the new interesting artifact hit
|
|
||||||
*/
|
*/
|
||||||
private static void makeAndPostInterestingArtifact(BlackboardArtifact originalArtifact, Collection<BlackboardAttribute> attributesForNewArtifact, String configuration) {
|
private static void makeAndPostArtifact(BlackboardArtifact.Type newArtifactType, BlackboardArtifact originalArtifact, Collection<BlackboardAttribute> attributesForNewArtifact, String configuration) {
|
||||||
try {
|
try {
|
||||||
SleuthkitCase tskCase = originalArtifact.getSleuthkitCase();
|
SleuthkitCase tskCase = originalArtifact.getSleuthkitCase();
|
||||||
AbstractFile abstractFile = tskCase.getAbstractFileById(originalArtifact.getObjectID());
|
|
||||||
Blackboard blackboard = tskCase.getBlackboard();
|
Blackboard blackboard = tskCase.getBlackboard();
|
||||||
// Create artifact if it doesn't already exist.
|
// Create artifact if it doesn't already exist.
|
||||||
if (!blackboard.artifactExists(abstractFile, TSK_INTERESTING_ARTIFACT_HIT, attributesForNewArtifact)) {
|
BlackboardArtifact.ARTIFACT_TYPE type = BlackboardArtifact.ARTIFACT_TYPE.fromID(newArtifactType.getTypeID());
|
||||||
BlackboardArtifact newInterestingArtifact = abstractFile.newAnalysisResult(
|
if (!blackboard.artifactExists(originalArtifact, type, attributesForNewArtifact)) {
|
||||||
BlackboardArtifact.Type.TSK_INTERESTING_ARTIFACT_HIT, Score.SCORE_LIKELY_NOTABLE,
|
BlackboardArtifact newArtifact = originalArtifact.newAnalysisResult(
|
||||||
|
newArtifactType, Score.SCORE_LIKELY_NOTABLE,
|
||||||
null, configuration, null, attributesForNewArtifact)
|
null, configuration, null, attributesForNewArtifact)
|
||||||
.getAnalysisResult();
|
.getAnalysisResult();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// index the artifact for keyword search
|
// index the artifact for keyword search
|
||||||
blackboard.postArtifact(newInterestingArtifact, MODULE_NAME);
|
blackboard.postArtifact(newArtifact, MODULE_NAME);
|
||||||
} catch (Blackboard.BlackboardException ex) {
|
} catch (Blackboard.BlackboardException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Unable to index blackboard artifact " + newInterestingArtifact.getArtifactID(), ex); //NON-NLS
|
LOGGER.log(Level.SEVERE, "Unable to index blackboard artifact " + newArtifact.getArtifactID(), ex); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
@ -299,7 +303,8 @@ public class IngestEventsListener {
|
|||||||
}
|
}
|
||||||
switch (IngestManager.IngestModuleEvent.valueOf(evt.getPropertyName())) {
|
switch (IngestManager.IngestModuleEvent.valueOf(evt.getPropertyName())) {
|
||||||
case DATA_ADDED: {
|
case DATA_ADDED: {
|
||||||
//if ingest isn't running create the interesting items otherwise use the ingest module setting to determine if we create interesting items
|
//if ingest isn't running create the "previously seen" items,
|
||||||
|
// otherwise use the ingest module setting to determine if we create "previously seen" items
|
||||||
boolean flagNotable = !IngestManager.getInstance().isIngestRunning() || isFlagNotableItems();
|
boolean flagNotable = !IngestManager.getInstance().isIngestRunning() || isFlagNotableItems();
|
||||||
boolean flagPrevious = !IngestManager.getInstance().isIngestRunning() || isFlagSeenDevices();
|
boolean flagPrevious = !IngestManager.getInstance().isIngestRunning() || isFlagSeenDevices();
|
||||||
boolean createAttributes = !IngestManager.getInstance().isIngestRunning() || shouldCreateCrProperties();
|
boolean createAttributes = !IngestManager.getInstance().isIngestRunning() || shouldCreateCrProperties();
|
||||||
@ -474,7 +479,7 @@ public class IngestEventsListener {
|
|||||||
// Was it previously marked as bad?
|
// Was it previously marked as bad?
|
||||||
// query db for artifact instances having this TYPE/VALUE and knownStatus = "Bad".
|
// query db for artifact instances having this TYPE/VALUE and knownStatus = "Bad".
|
||||||
// if getKnownStatus() is "Unknown" and this artifact instance was marked bad in a previous case,
|
// if getKnownStatus() is "Unknown" and this artifact instance was marked bad in a previous case,
|
||||||
// create TSK_INTERESTING_ARTIFACT_HIT artifact on BB.
|
// create TSK_PREVIOUSLY_SEEN artifact on BB.
|
||||||
if (flagNotableItemsEnabled) {
|
if (flagNotableItemsEnabled) {
|
||||||
List<String> caseDisplayNames;
|
List<String> caseDisplayNames;
|
||||||
try {
|
try {
|
||||||
@ -487,6 +492,8 @@ public class IngestEventsListener {
|
|||||||
LOGGER.log(Level.INFO, String.format("Unable to flag notable item: %s.", eamArtifact.toString()), ex);
|
LOGGER.log(Level.INFO, String.format("Unable to flag notable item: %s.", eamArtifact.toString()), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// flag previously seen devices
|
||||||
if (flagPreviousItemsEnabled
|
if (flagPreviousItemsEnabled
|
||||||
&& (eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.USBID_TYPE_ID
|
&& (eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.USBID_TYPE_ID
|
||||||
|| eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.ICCID_TYPE_ID
|
|| eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.ICCID_TYPE_ID
|
||||||
@ -505,7 +512,28 @@ public class IngestEventsListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (CorrelationAttributeNormalizationException ex) {
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
LOGGER.log(Level.INFO, String.format("Unable to flag notable item: %s.", eamArtifact.toString()), ex);
|
LOGGER.log(Level.INFO, String.format("Unable to flag previously seen device: %s.", eamArtifact.toString()), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// flag previously unseen apps
|
||||||
|
if (flagPreviousItemsEnabled
|
||||||
|
&& eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.INSTALLED_PROGS_TYPE_ID) {
|
||||||
|
try {
|
||||||
|
List<CorrelationAttributeInstance> previousOccurences = dbManager.getArtifactInstancesByTypeValue(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue());
|
||||||
|
// make sure the previous instances do not contain current case
|
||||||
|
for (Iterator<CorrelationAttributeInstance> iterator = previousOccurences.iterator(); iterator.hasNext();) {
|
||||||
|
CorrelationAttributeInstance instance = iterator.next();
|
||||||
|
if (instance.getCorrelationCase().getCaseUUID().equals(eamArtifact.getCorrelationCase().getCaseUUID())) {
|
||||||
|
// this is the current case - remove the instace from the previousOccurences list
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (previousOccurences.isEmpty()) {
|
||||||
|
makeAndPostPreviouslyUnseenArtifact(bbArtifact);
|
||||||
|
}
|
||||||
|
} catch (CorrelationAttributeNormalizationException ex) {
|
||||||
|
LOGGER.log(Level.INFO, String.format("Unable to flag previously unseen application: %s.", eamArtifact.toString()), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (createCorrelationAttributes) {
|
if (createCorrelationAttributes) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Central Repository
|
* Central Repository
|
||||||
*
|
*
|
||||||
* Copyright 2011-2018 Basis Technology Corp.
|
* Copyright 2011-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");
|
||||||
@ -48,7 +48,7 @@ import org.sleuthkit.autopsy.ingest.IngestServices;
|
|||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
import org.sleuthkit.datamodel.Blackboard;
|
import org.sleuthkit.datamodel.Blackboard;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT;
|
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_PREVIOUSLY_SEEN;
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
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;
|
||||||
@ -327,7 +327,7 @@ final class CentralRepoIngestModule implements FileIngestModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Post a new interesting artifact for the file marked bad.
|
* Post a new "previously seen" artifact for the file marked bad.
|
||||||
*
|
*
|
||||||
* @param abstractFile The file from which to create an artifact.
|
* @param abstractFile The file from which to create an artifact.
|
||||||
* @param caseDisplayNames Case names to be added to a TSK_COMMON attribute.
|
* @param caseDisplayNames Case names to be added to a TSK_COMMON attribute.
|
||||||
@ -343,9 +343,9 @@ final class CentralRepoIngestModule implements FileIngestModule {
|
|||||||
try {
|
try {
|
||||||
|
|
||||||
// Create artifact if it doesn't already exist.
|
// Create artifact if it doesn't already exist.
|
||||||
if (!blackboard.artifactExists(abstractFile, TSK_INTERESTING_FILE_HIT, attributes)) {
|
if (!blackboard.artifactExists(abstractFile, TSK_PREVIOUSLY_SEEN, attributes)) {
|
||||||
BlackboardArtifact tifArtifact = abstractFile.newAnalysisResult(
|
BlackboardArtifact tifArtifact = abstractFile.newAnalysisResult(
|
||||||
BlackboardArtifact.Type.TSK_INTERESTING_FILE_HIT, Score.SCORE_LIKELY_NOTABLE,
|
BlackboardArtifact.Type.TSK_PREVIOUSLY_SEEN, Score.SCORE_LIKELY_NOTABLE,
|
||||||
null, Bundle.CentralRepoIngestModule_prevTaggedSet_text(), null, attributes)
|
null, Bundle.CentralRepoIngestModule_prevTaggedSet_text(), null, attributes)
|
||||||
.getAnalysisResult();
|
.getAnalysisResult();
|
||||||
try {
|
try {
|
||||||
|
@ -230,26 +230,23 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
|
|||||||
this.artifact = artifact;
|
this.artifact = artifact;
|
||||||
this.artifactType = getType(artifact);
|
this.artifactType = getType(artifact);
|
||||||
|
|
||||||
for (Content lookupContent : this.getLookup().lookupAll(Content.class)) {
|
srcContent = getSourceContentFromLookup(artifact);
|
||||||
if ((lookupContent != null) && (!(lookupContent instanceof BlackboardArtifact))) {
|
if (srcContent == null) {
|
||||||
srcContent = lookupContent;
|
throw new IllegalArgumentException(MessageFormat.format("Artifact missing source content (artifact objID={0})", artifact));
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
/*
|
/*
|
||||||
* Calling this getter causes the unique path of the source
|
* Calling this getter causes the unique path of the source content
|
||||||
* content to be cached in the Content object. This is
|
* to be cached in the Content object. This is advantageous as long
|
||||||
* advantageous as long as this node is constructed in a
|
* as this node is constructed in a background thread instead of a
|
||||||
* background thread instead of a UI thread.
|
* UI thread.
|
||||||
*/
|
*/
|
||||||
srcContent.getUniquePath();
|
srcContent.getUniquePath();
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
logger.log(Level.WARNING, MessageFormat.format("Error getting the unique path of the source content (artifact objID={0})", artifact.getId()), ex);
|
logger.log(Level.WARNING, MessageFormat.format("Error getting the unique path of the source content (artifact objID={0})", artifact.getId()), ex);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (srcContent == null) {
|
|
||||||
throw new IllegalArgumentException(MessageFormat.format("Artifact missing source content (artifact objID={0})", artifact));
|
|
||||||
}
|
|
||||||
setName(Long.toString(artifact.getArtifactID()));
|
setName(Long.toString(artifact.getArtifactID()));
|
||||||
String displayName = srcContent.getName();
|
String displayName = srcContent.getName();
|
||||||
setDisplayName(displayName);
|
setDisplayName(displayName);
|
||||||
@ -381,6 +378,32 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the source content in the Lookup created by createLookup() method.
|
||||||
|
*
|
||||||
|
* @param artifact Artifact who's source Content we are trying to find.
|
||||||
|
*
|
||||||
|
* @return Source Content of the input artifact, if one exists. Null
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
private Content getSourceContentFromLookup(BlackboardArtifact artifact) {
|
||||||
|
for (Content lookupContent : this.getLookup().lookupAll(Content.class)) {
|
||||||
|
/*
|
||||||
|
* NOTE: createLookup() saves the artifact and its source content
|
||||||
|
* (if one exists). However, createLookup() has to be static because
|
||||||
|
* it is being called by super(), therefore it can't store the
|
||||||
|
* source content in this.srcContent class variable. That's why we
|
||||||
|
* have to have the logic below, which reads the Lookup contents,
|
||||||
|
* and decides that the source content is the entry in Lookup that
|
||||||
|
* is NOT the input artifact.
|
||||||
|
*/
|
||||||
|
if ((lookupContent != null) && (lookupContent.getId() != artifact.getId())) {
|
||||||
|
return lookupContent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private helper method to allow content specified in a path id attribute
|
* Private helper method to allow content specified in a path id attribute
|
||||||
* to be retrieved.
|
* to be retrieved.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2020 Basis Technology Corp.
|
* Copyright 2020-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");
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2019 Basis Technology Corp.
|
* Copyright 2019-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");
|
||||||
@ -25,10 +25,11 @@ import java.util.Collections;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
import org.sleuthkit.autopsy.centralrepository.ingestmodule.CentralRepoIngestModuleFactory;
|
import org.sleuthkit.autopsy.centralrepository.ingestmodule.CentralRepoIngestModuleFactory;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException;
|
import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DefaultArtifactUpdateGovernor;
|
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DefaultArtifactUpdateGovernor;
|
||||||
@ -36,6 +37,7 @@ 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.DataSource;
|
||||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
@ -47,10 +49,10 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
* ingest process, this code could break. This code expects that the central
|
* ingest process, this code could break. This code expects that the central
|
||||||
* repository ingest module:
|
* repository ingest module:
|
||||||
*
|
*
|
||||||
* a) Creates a TSK_INTERESTING_FILE_HIT artifact for a file whose hash is in
|
* a) Creates a TSK_PREVIOUSLY_SEEN artifact for a file whose hash is in
|
||||||
* the central repository as a notable file.
|
* the central repository as a notable file.
|
||||||
*
|
*
|
||||||
* b) Creates a TSK_INTERESTING_ARTIFACT_HIT artifact for a matching id in the
|
* b) Creates a TSK_PREVIOUSLY_SEEN artifact for a matching id in the
|
||||||
* central repository.
|
* central repository.
|
||||||
*
|
*
|
||||||
* c) The created artifact will have a TSK_COMMENT attribute attached where one
|
* c) The created artifact will have a TSK_COMMENT attribute attached where one
|
||||||
@ -99,13 +101,11 @@ public class PastCasesSummary implements DefaultArtifactUpdateGovernor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static final Set<Integer> ARTIFACT_UPDATE_TYPE_IDS = new HashSet<>(Arrays.asList(
|
private static final Set<Integer> ARTIFACT_UPDATE_TYPE_IDS = new HashSet<>(Arrays.asList(
|
||||||
ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(),
|
ARTIFACT_TYPE.TSK_PREVIOUSLY_SEEN.getTypeID()
|
||||||
ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID()
|
|
||||||
));
|
));
|
||||||
|
|
||||||
private static final String CENTRAL_REPO_INGEST_NAME = CentralRepoIngestModuleFactory.getModuleName().toUpperCase().trim();
|
private static final String CENTRAL_REPO_INGEST_NAME = CentralRepoIngestModuleFactory.getModuleName().toUpperCase().trim();
|
||||||
private static final BlackboardAttribute.Type TYPE_COMMENT = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_COMMENT);
|
private static final BlackboardAttribute.Type TYPE_COMMENT = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_COMMENT);
|
||||||
private static final BlackboardAttribute.Type TYPE_ASSOCIATED_ARTIFACT = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT);
|
|
||||||
|
|
||||||
private static final Set<Integer> CR_DEVICE_TYPE_IDS = new HashSet<>(Arrays.asList(
|
private static final Set<Integer> CR_DEVICE_TYPE_IDS = new HashSet<>(Arrays.asList(
|
||||||
ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID(),
|
ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID(),
|
||||||
@ -242,30 +242,23 @@ public class PastCasesSummary implements DefaultArtifactUpdateGovernor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an artifact with a TYPE_ASSOCIATED_ARTIFACT attribute, retrieves
|
* Given a TSK_PREVIOUSLY_SEEN artifact, retrieves it's parent artifact.
|
||||||
* the related artifact.
|
|
||||||
*
|
*
|
||||||
* @param artifact The artifact with the TYPE_ASSOCIATED_ARTIFACT attribute.
|
* @param artifact The input TSK_PREVIOUSLY_SEEN artifact.
|
||||||
*
|
*
|
||||||
* @return The artifact if found or null if not.
|
* @return The artifact if found or null if not.
|
||||||
*
|
*
|
||||||
* @throws SleuthkitCaseProviderException
|
* @throws TskCoreException
|
||||||
|
* @throws NoCurrentCaseException
|
||||||
*/
|
*/
|
||||||
private BlackboardArtifact getParentArtifact(BlackboardArtifact artifact) throws SleuthkitCaseProviderException {
|
private BlackboardArtifact getParentArtifact(BlackboardArtifact artifact) throws TskCoreException, NoCurrentCaseException {
|
||||||
Long parentId = DataSourceInfoUtilities.getLongOrNull(artifact, TYPE_ASSOCIATED_ARTIFACT);
|
|
||||||
if (parentId == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
SleuthkitCase skCase = caseProvider.get();
|
BlackboardArtifact sourceArtifact = null;
|
||||||
try {
|
Content content = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID());
|
||||||
return skCase.getArtifactByArtifactId(parentId);
|
if (content instanceof BlackboardArtifact) {
|
||||||
} catch (TskCoreException ex) {
|
sourceArtifact = (BlackboardArtifact) content;
|
||||||
logger.log(Level.WARNING,
|
|
||||||
String.format("There was an error fetching the parent artifact of a TSK_INTERESTING_ARTIFACT_HIT (parent id: %d)", parentId),
|
|
||||||
ex);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
return sourceArtifact;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -275,9 +268,10 @@ public class PastCasesSummary implements DefaultArtifactUpdateGovernor {
|
|||||||
*
|
*
|
||||||
* @return True if there is a device associated artifact.
|
* @return True if there is a device associated artifact.
|
||||||
*
|
*
|
||||||
* @throws SleuthkitCaseProviderException
|
* @throws TskCoreException
|
||||||
|
* @throws NoCurrentCaseException
|
||||||
*/
|
*/
|
||||||
private boolean hasDeviceAssociatedArtifact(BlackboardArtifact artifact) throws SleuthkitCaseProviderException {
|
private boolean hasDeviceAssociatedArtifact(BlackboardArtifact artifact) throws TskCoreException, NoCurrentCaseException {
|
||||||
BlackboardArtifact parent = getParentArtifact(artifact);
|
BlackboardArtifact parent = getParentArtifact(artifact);
|
||||||
if (parent == null) {
|
if (parent == null) {
|
||||||
return false;
|
return false;
|
||||||
@ -295,9 +289,10 @@ public class PastCasesSummary implements DefaultArtifactUpdateGovernor {
|
|||||||
*
|
*
|
||||||
* @throws SleuthkitCaseProviderException
|
* @throws SleuthkitCaseProviderException
|
||||||
* @throws TskCoreException
|
* @throws TskCoreException
|
||||||
|
* @throws NoCurrentCaseException
|
||||||
*/
|
*/
|
||||||
public PastCasesResult getPastCasesData(DataSource dataSource)
|
public PastCasesResult getPastCasesData(DataSource dataSource)
|
||||||
throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException {
|
throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException, NoCurrentCaseException {
|
||||||
|
|
||||||
if (dataSource == null) {
|
if (dataSource == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -308,7 +303,7 @@ public class PastCasesSummary implements DefaultArtifactUpdateGovernor {
|
|||||||
List<String> deviceArtifactCases = new ArrayList<>();
|
List<String> deviceArtifactCases = new ArrayList<>();
|
||||||
List<String> nonDeviceArtifactCases = new ArrayList<>();
|
List<String> nonDeviceArtifactCases = new ArrayList<>();
|
||||||
|
|
||||||
for (BlackboardArtifact artifact : skCase.getBlackboard().getArtifacts(ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID(), dataSource.getId())) {
|
for (BlackboardArtifact artifact : skCase.getBlackboard().getArtifacts(ARTIFACT_TYPE.TSK_PREVIOUSLY_SEEN.getTypeID(), dataSource.getId())) {
|
||||||
List<String> cases = getCasesFromArtifact(artifact);
|
List<String> cases = getCasesFromArtifact(artifact);
|
||||||
if (cases == null || cases.isEmpty()) {
|
if (cases == null || cases.isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
@ -321,12 +316,9 @@ public class PastCasesSummary implements DefaultArtifactUpdateGovernor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<String> filesCases = skCase.getBlackboard().getArtifacts(ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(), dataSource.getId()).stream()
|
|
||||||
.flatMap((art) -> getCasesFromArtifact(art).stream());
|
|
||||||
|
|
||||||
return new PastCasesResult(
|
return new PastCasesResult(
|
||||||
getCaseCounts(deviceArtifactCases.stream()),
|
getCaseCounts(deviceArtifactCases.stream()),
|
||||||
getCaseCounts(Stream.concat(filesCases, nonDeviceArtifactCases.stream()))
|
getCaseCounts(nonDeviceArtifactCases.stream())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user