From b355734635a97da7f998ee703bbfc58558e606cd Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Wed, 21 Jul 2021 16:59:26 -0400 Subject: [PATCH 01/64] Modified CR to use TSK_PREVIOUSLY_SEEN --- .../eventlisteners/IngestEventsListener.java | 37 ++++++++++--------- .../ingestmodule/CentralRepoIngestModule.java | 10 ++--- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java index 7aa229949e..a1e5ac440c 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java @@ -1,7 +1,7 @@ /* * Central Repository * - * Copyright 2017-2020 Basis Technology Corp. + * Copyright 2017-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -49,7 +49,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Blackboard; 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 org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.autopsy.coreutils.ThreadUtils; import static org.sleuthkit.autopsy.ingest.IngestManager.IngestModuleEvent.DATA_ADDED; @@ -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. * * @param originalArtifact Original artifact that we want to flag @@ -219,14 +219,14 @@ public class IngestEventsListener { new BlackboardAttribute( TSK_ASSOCIATED_ARTIFACT, MODULE_NAME, originalArtifact.getArtifactID())); - makeAndPostInterestingArtifact(originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevTaggedSet_text()); + makeAndPostPreviouslySeenArtifact(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. * - * @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 * in */ @@ -244,35 +244,35 @@ public class IngestEventsListener { new BlackboardAttribute( TSK_ASSOCIATED_ARTIFACT, MODULE_NAME, originalArtifact.getArtifactID())); - makeAndPostInterestingArtifact(originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevExists_text()); + makeAndPostPreviouslySeenArtifact(originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevExists_text()); } /** - * Make an interesting item artifact to flag the passed in artifact. + * Make a "previously seen" artifact to flag the passed in artifact. * * @param originalArtifact Artifact in current case we want to flag * @param attributesForNewArtifact Attributes to assign to the new - * Interesting items artifact - * @param configuration The configuration to be specified for the new interesting artifact hit + * "previously seen" artifact + * @param configuration The configuration to be specified for the new "previously seen" artifact hit */ - private static void makeAndPostInterestingArtifact(BlackboardArtifact originalArtifact, Collection attributesForNewArtifact, String configuration) { + private static void makeAndPostPreviouslySeenArtifact(BlackboardArtifact originalArtifact, Collection attributesForNewArtifact, String configuration) { try { SleuthkitCase tskCase = originalArtifact.getSleuthkitCase(); AbstractFile abstractFile = tskCase.getAbstractFileById(originalArtifact.getObjectID()); Blackboard blackboard = tskCase.getBlackboard(); // Create artifact if it doesn't already exist. - if (!blackboard.artifactExists(abstractFile, TSK_INTERESTING_ARTIFACT_HIT, attributesForNewArtifact)) { - BlackboardArtifact newInterestingArtifact = abstractFile.newAnalysisResult( - BlackboardArtifact.Type.TSK_INTERESTING_ARTIFACT_HIT, Score.SCORE_LIKELY_NOTABLE, + if (!blackboard.artifactExists(abstractFile, TSK_PREVIOUSLY_SEEN, attributesForNewArtifact)) { + BlackboardArtifact newPreviouslySeenArtifact = abstractFile.newAnalysisResult( + BlackboardArtifact.Type.TSK_PREVIOUSLY_SEEN, Score.SCORE_LIKELY_NOTABLE, null, configuration, null, attributesForNewArtifact) .getAnalysisResult(); try { // index the artifact for keyword search - blackboard.postArtifact(newInterestingArtifact, MODULE_NAME); + blackboard.postArtifact(newPreviouslySeenArtifact, MODULE_NAME); } 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 " + newPreviouslySeenArtifact.getArtifactID(), ex); //NON-NLS } } } catch (TskCoreException ex) { @@ -299,7 +299,8 @@ public class IngestEventsListener { } switch (IngestManager.IngestModuleEvent.valueOf(evt.getPropertyName())) { 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 flagPrevious = !IngestManager.getInstance().isIngestRunning() || isFlagSeenDevices(); boolean createAttributes = !IngestManager.getInstance().isIngestRunning() || shouldCreateCrProperties(); @@ -474,7 +475,7 @@ public class IngestEventsListener { // Was it previously marked as 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, - // create TSK_INTERESTING_ARTIFACT_HIT artifact on BB. + // create TSK_PREVIOUSLY_SEEN artifact on BB. if (flagNotableItemsEnabled) { List caseDisplayNames; try { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java index d40b45be86..fd203915e1 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java @@ -1,7 +1,7 @@ /* * Central Repository * - * Copyright 2011-2018 Basis Technology Corp. + * Copyright 2011-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * 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.Blackboard; 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 static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT; 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 caseDisplayNames Case names to be added to a TSK_COMMON attribute. @@ -343,9 +343,9 @@ final class CentralRepoIngestModule implements FileIngestModule { try { // 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.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) .getAnalysisResult(); try { From d983aafac1cc8b62a0de6405b9372bdf0d934e31 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Thu, 22 Jul 2021 09:52:42 -0400 Subject: [PATCH 02/64] Data source summary --- .../datasourcesummary/datamodel/PastCasesSummary.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/PastCasesSummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/PastCasesSummary.java index ea6c089fca..cca9516180 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/PastCasesSummary.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/PastCasesSummary.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2019 Basis Technology Corp. + * Copyright 2019-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -41,16 +41,16 @@ import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; /** - * Provides information about how a datasource relates to a previous case. NOTE: + * Provides information about how a data source relates to a previous case. NOTE: * This code is fragile and has certain expectations about how the central * repository handles creating artifacts. So, if the central repository changes * ingest process, this code could break. This code expects that the central * 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. * - * 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. * * c) The created artifact will have a TSK_COMMENT attribute attached where one @@ -99,8 +99,7 @@ public class PastCasesSummary implements DefaultArtifactUpdateGovernor { } private static final Set ARTIFACT_UPDATE_TYPE_IDS = new HashSet<>(Arrays.asList( - ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(), - ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID() + ARTIFACT_TYPE.TSK_PREVIOUSLY_SEEN.getTypeID() )); private static final String CENTRAL_REPO_INGEST_NAME = CentralRepoIngestModuleFactory.getModuleName().toUpperCase().trim(); From ad141b6426e991809bc3b5bf92ff162dd49d0b68 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Thu, 22 Jul 2021 16:07:36 -0400 Subject: [PATCH 03/64] datasourcesummary --- .../datasourcesummary/datamodel/AnalysisSummary.java | 7 +++---- .../datasourcesummary/datamodel/PastCasesSummary.java | 11 ++++------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/AnalysisSummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/AnalysisSummary.java index 5fff3eac6c..8b6f472a54 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/AnalysisSummary.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/AnalysisSummary.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2020 Basis Technology Corp. + * Copyright 2020-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -49,8 +49,7 @@ public class AnalysisSummary implements DefaultArtifactUpdateGovernor { private static final Set EXCLUDED_KEYWORD_SEARCH_ITEMS = new HashSet<>(); private static final Set ARTIFACT_UPDATE_TYPE_IDS = new HashSet<>(Arrays.asList( - ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(), - ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID(), + ARTIFACT_TYPE.TSK_PREVIOUSLY_SEEN.getTypeID(), ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID(), ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() )); @@ -122,7 +121,7 @@ public class AnalysisSummary implements DefaultArtifactUpdateGovernor { * @throws TskCoreException */ public List> getInterestingItemCounts(DataSource dataSource) throws SleuthkitCaseProviderException, TskCoreException { - return getCountsData(dataSource, TYPE_SET_NAME, ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT, ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT); + return getCountsData(dataSource, TYPE_SET_NAME, ARTIFACT_TYPE.TSK_PREVIOUSLY_SEEN); } /** diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/PastCasesSummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/PastCasesSummary.java index cca9516180..ad21c68219 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/PastCasesSummary.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/PastCasesSummary.java @@ -306,8 +306,8 @@ public class PastCasesSummary implements DefaultArtifactUpdateGovernor { List deviceArtifactCases = new ArrayList<>(); List 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 cases = getCasesFromArtifact(artifact); if (cases == null || cases.isEmpty()) { continue; @@ -319,13 +319,10 @@ public class PastCasesSummary implements DefaultArtifactUpdateGovernor { nonDeviceArtifactCases.addAll(cases); } } - - Stream filesCases = skCase.getBlackboard().getArtifacts(ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(), dataSource.getId()).stream() - .flatMap((art) -> getCasesFromArtifact(art).stream()); - + return new PastCasesResult( getCaseCounts(deviceArtifactCases.stream()), - getCaseCounts(Stream.concat(filesCases, nonDeviceArtifactCases.stream())) + getCaseCounts(nonDeviceArtifactCases.stream()) ); } } From d8848a5c18696836364230590746c2250817b404 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Mon, 26 Jul 2021 17:43:55 -0400 Subject: [PATCH 04/64] More work --- .../eventlisteners/CaseEventListener.java | 2 +- .../eventlisteners/IngestEventsListener.java | 12 +++--------- .../datasourcesummary/datamodel/AnalysisSummary.java | 2 +- .../datamodel/PastCasesSummary.java | 2 +- 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java index a3ccca4ccf..274317fbac 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java @@ -727,7 +727,7 @@ public final class CaseEventListener implements PropertyChangeListener { TSK_COMMENT, MODULE_NAME, Bundle.CaseEventsListener_prevCaseComment_text())); 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(); try { // index the artifact for keyword search diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java index a1e5ac440c..cee16ddec9 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java @@ -215,10 +215,7 @@ public class IngestEventsListener { Bundle.IngestEventsListener_prevTaggedSet_text()), new BlackboardAttribute( TSK_COMMENT, MODULE_NAME, - Bundle.IngestEventsListener_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(","))), - new BlackboardAttribute( - TSK_ASSOCIATED_ARTIFACT, MODULE_NAME, - originalArtifact.getArtifactID())); + Bundle.IngestEventsListener_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(",")))); makeAndPostPreviouslySeenArtifact(originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevTaggedSet_text()); } @@ -240,10 +237,7 @@ public class IngestEventsListener { Bundle.IngestEventsListener_prevExists_text()), new BlackboardAttribute( TSK_COMMENT, MODULE_NAME, - Bundle.IngestEventsListener_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(","))), - new BlackboardAttribute( - TSK_ASSOCIATED_ARTIFACT, MODULE_NAME, - originalArtifact.getArtifactID())); + Bundle.IngestEventsListener_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(",")))); makeAndPostPreviouslySeenArtifact(originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevExists_text()); } @@ -263,7 +257,7 @@ public class IngestEventsListener { Blackboard blackboard = tskCase.getBlackboard(); // Create artifact if it doesn't already exist. if (!blackboard.artifactExists(abstractFile, TSK_PREVIOUSLY_SEEN, attributesForNewArtifact)) { - BlackboardArtifact newPreviouslySeenArtifact = abstractFile.newAnalysisResult( + BlackboardArtifact newPreviouslySeenArtifact = originalArtifact.newAnalysisResult( BlackboardArtifact.Type.TSK_PREVIOUSLY_SEEN, Score.SCORE_LIKELY_NOTABLE, null, configuration, null, attributesForNewArtifact) .getAnalysisResult(); diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/AnalysisSummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/AnalysisSummary.java index 8b6f472a54..13915de369 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/AnalysisSummary.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/AnalysisSummary.java @@ -121,7 +121,7 @@ public class AnalysisSummary implements DefaultArtifactUpdateGovernor { * @throws TskCoreException */ public List> getInterestingItemCounts(DataSource dataSource) throws SleuthkitCaseProviderException, TskCoreException { - return getCountsData(dataSource, TYPE_SET_NAME, ARTIFACT_TYPE.TSK_PREVIOUSLY_SEEN); + return getCountsData(dataSource, TYPE_SET_NAME, ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT, ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT); } /** diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/PastCasesSummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/PastCasesSummary.java index ad21c68219..d016c0ad19 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/PastCasesSummary.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/PastCasesSummary.java @@ -261,7 +261,7 @@ public class PastCasesSummary implements DefaultArtifactUpdateGovernor { return skCase.getArtifactByArtifactId(parentId); } catch (TskCoreException ex) { logger.log(Level.WARNING, - String.format("There was an error fetching the parent artifact of a TSK_INTERESTING_ARTIFACT_HIT (parent id: %d)", parentId), + String.format("There was an error fetching the parent artifact of a TSK_PREVIOUSLY SEEN (parent id: %d)", parentId), ex); return null; } From 418bb70d8c686de8f5c523c0549738572391a508 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Mon, 26 Jul 2021 17:44:55 -0400 Subject: [PATCH 05/64] More work --- .../datamodel/CorrelationAttributeUtil.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index f9b3c8642d..8d6c27117d 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -32,11 +32,13 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoAccount.Cent import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Account; +import org.sleuthkit.datamodel.AnalysisResult; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.DataArtifact; import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.HashUtility; import org.sleuthkit.datamodel.InvalidAccountIDException; @@ -271,8 +273,8 @@ public class CorrelationAttributeUtil { } /** - * Gets the associated artifact of a "meta-artifact" such as an interesting - * artifact hit artifact. + * Gets the associated artifact of a "meta-artifact" such as an "interesting + * artifact hit" or "previously seen" artifact. * * @param artifact An artifact. * @@ -290,7 +292,15 @@ public class CorrelationAttributeUtil { if (assocArtifactAttr != null) { 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) { + // ELTODO: FOR SOME REASON WE NEVER GET HERE. THAT'S WHY THE "O" COLUMN IS EMPTY FOR "PREVIOUSLY SEEN" ARTIFACTS + sourceArtifact = (BlackboardArtifact) content; + } + } + + if (sourceArtifact == null) { sourceArtifact = artifact; } return sourceArtifact; From 278f4b3ade45dece0e4e2991c3d55275cf572b99 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Mon, 26 Jul 2021 17:49:14 -0400 Subject: [PATCH 06/64] Unused imports --- .../centralrepository/datamodel/CorrelationAttributeUtil.java | 2 -- .../centralrepository/eventlisteners/IngestEventsListener.java | 1 - 2 files changed, 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index 8d6c27117d..5218929aad 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -32,14 +32,12 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoAccount.Cent import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Account; -import org.sleuthkit.datamodel.AnalysisResult; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.DataArtifact; -import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.HashUtility; import org.sleuthkit.datamodel.InvalidAccountIDException; import org.sleuthkit.datamodel.TskCoreException; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java index cee16ddec9..65ba2d2e4e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java @@ -53,7 +53,6 @@ import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_PREVI import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.autopsy.coreutils.ThreadUtils; 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_SET_NAME; import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisEvent; From 4e2fb03891f4aca89ab6c0b0e1371f0eaee7ee5e Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Tue, 27 Jul 2021 14:25:47 -0400 Subject: [PATCH 07/64] Fix for when the source is another artifact and not a file --- .../datamodel/BlackboardArtifactNode.java | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index e3bad44705..5609cefd01 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -120,7 +120,7 @@ public class BlackboardArtifactNode extends AbstractContentNode Date: Tue, 27 Jul 2021 15:28:43 -0400 Subject: [PATCH 08/64] Fix for when the source is another artifact and not a file --- .../eventlisteners/IngestEventsListener.java | 3 +- .../datamodel/BlackboardArtifactNode.java | 38 ++++++++++++++++--- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java index 65ba2d2e4e..fb75198263 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java @@ -252,10 +252,9 @@ public class IngestEventsListener { private static void makeAndPostPreviouslySeenArtifact(BlackboardArtifact originalArtifact, Collection attributesForNewArtifact, String configuration) { try { SleuthkitCase tskCase = originalArtifact.getSleuthkitCase(); - AbstractFile abstractFile = tskCase.getAbstractFileById(originalArtifact.getObjectID()); Blackboard blackboard = tskCase.getBlackboard(); // Create artifact if it doesn't already exist. - if (!blackboard.artifactExists(abstractFile, TSK_PREVIOUSLY_SEEN, attributesForNewArtifact)) { + if (!blackboard.artifactExists(originalArtifact, TSK_PREVIOUSLY_SEEN, attributesForNewArtifact)) { BlackboardArtifact newPreviouslySeenArtifact = originalArtifact.newAnalysisResult( BlackboardArtifact.Type.TSK_PREVIOUSLY_SEEN, Score.SCORE_LIKELY_NOTABLE, null, configuration, null, attributesForNewArtifact) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 5609cefd01..ee2e3940bb 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -120,7 +120,7 @@ public class BlackboardArtifactNode extends AbstractContentNode Date: Tue, 27 Jul 2021 15:32:56 -0400 Subject: [PATCH 09/64] Typo --- .../org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index ee2e3940bb..fef0d1acf3 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -394,7 +394,7 @@ public class BlackboardArtifactNode extends AbstractContentNode Date: Tue, 27 Jul 2021 16:18:47 -0400 Subject: [PATCH 10/64] Removed a comment --- .../centralrepository/datamodel/CorrelationAttributeUtil.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index 5218929aad..61f58628fd 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -293,7 +293,6 @@ public class CorrelationAttributeUtil { } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_PREVIOUSLY_SEEN.getTypeID() == artifact.getArtifactTypeID()) { Content content = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID()); if (content instanceof DataArtifact) { - // ELTODO: FOR SOME REASON WE NEVER GET HERE. THAT'S WHY THE "O" COLUMN IS EMPTY FOR "PREVIOUSLY SEEN" ARTIFACTS sourceArtifact = (BlackboardArtifact) content; } } From b2d6890595f24073b92c92fd5b91f0759b742b14 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Tue, 27 Jul 2021 16:25:05 -0400 Subject: [PATCH 11/64] Reverted some new code to original logic --- .../autopsy/datamodel/BlackboardArtifactNode.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index fef0d1acf3..91b85a1138 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -270,14 +270,11 @@ public class BlackboardArtifactNode extends AbstractContentNode Date: Wed, 28 Jul 2021 13:03:32 -0400 Subject: [PATCH 12/64] Flagging previously unseen apps --- .../eventlisteners/IngestEventsListener.java | 67 ++++++++++++++----- 1 file changed, 51 insertions(+), 16 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java index fb75198263..840b6586bd 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java @@ -26,6 +26,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.EnumSet; +import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; @@ -46,10 +47,10 @@ import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.ModuleDataEvent; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource; -import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Blackboard; import org.sleuthkit.datamodel.BlackboardArtifact; 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.autopsy.coreutils.ThreadUtils; import static org.sleuthkit.autopsy.ingest.IngestManager.IngestModuleEvent.DATA_ADDED; @@ -215,7 +216,7 @@ public class IngestEventsListener { new BlackboardAttribute( TSK_COMMENT, MODULE_NAME, Bundle.IngestEventsListener_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(",")))); - makeAndPostPreviouslySeenArtifact(originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevTaggedSet_text()); + makeAndPostArtifact(BlackboardArtifact.Type.TSK_PREVIOUSLY_SEEN, originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevTaggedSet_text()); } /** @@ -237,34 +238,45 @@ public class IngestEventsListener { new BlackboardAttribute( TSK_COMMENT, MODULE_NAME, Bundle.IngestEventsListener_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(",")))); - makeAndPostPreviouslySeenArtifact(originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevExists_text()); + makeAndPostArtifact(BlackboardArtifact.Type.TSK_PREVIOUSLY_SEEN, originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevExists_text()); } - /** - * Make a "previously seen" artifact to flag the passed in artifact. + * 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 attributesForNewArtifact = new ArrayList<>(); + makeAndPostArtifact(BlackboardArtifact.Type.TSK_PREVIOUSLY_UNSEEN, originalArtifact, attributesForNewArtifact, ""); + } + + /** + * Make an artifact to flag the passed in artifact. * * @param originalArtifact Artifact in current case we want to flag - * @param attributesForNewArtifact Attributes to assign to the new - * "previously seen" artifact - * @param configuration The configuration to be specified for the new "previously seen" artifact hit + * @param attributesForNewArtifact Attributes to assign to the new artifact + * @param configuration The configuration to be specified for the new artifact hit */ - private static void makeAndPostPreviouslySeenArtifact(BlackboardArtifact originalArtifact, Collection attributesForNewArtifact, String configuration) { + private static void makeAndPostArtifact(BlackboardArtifact.Type newArtifactType, BlackboardArtifact originalArtifact, Collection attributesForNewArtifact, String configuration) { try { SleuthkitCase tskCase = originalArtifact.getSleuthkitCase(); Blackboard blackboard = tskCase.getBlackboard(); // Create artifact if it doesn't already exist. - if (!blackboard.artifactExists(originalArtifact, TSK_PREVIOUSLY_SEEN, attributesForNewArtifact)) { - BlackboardArtifact newPreviouslySeenArtifact = originalArtifact.newAnalysisResult( - BlackboardArtifact.Type.TSK_PREVIOUSLY_SEEN, Score.SCORE_LIKELY_NOTABLE, + BlackboardArtifact.ARTIFACT_TYPE type = BlackboardArtifact.ARTIFACT_TYPE.fromID(newArtifactType.getTypeID()); + if (!blackboard.artifactExists(originalArtifact, type, attributesForNewArtifact)) { + BlackboardArtifact newArtifact = originalArtifact.newAnalysisResult( + newArtifactType, Score.SCORE_LIKELY_NOTABLE, null, configuration, null, attributesForNewArtifact) .getAnalysisResult(); try { // index the artifact for keyword search - blackboard.postArtifact(newPreviouslySeenArtifact, MODULE_NAME); + blackboard.postArtifact(newArtifact, MODULE_NAME); } catch (Blackboard.BlackboardException ex) { - LOGGER.log(Level.SEVERE, "Unable to index blackboard artifact " + newPreviouslySeenArtifact.getArtifactID(), ex); //NON-NLS + LOGGER.log(Level.SEVERE, "Unable to index blackboard artifact " + newArtifact.getArtifactID(), ex); //NON-NLS } } } catch (TskCoreException ex) { @@ -480,6 +492,8 @@ public class IngestEventsListener { LOGGER.log(Level.INFO, String.format("Unable to flag notable item: %s.", eamArtifact.toString()), ex); } } + + // flag previously seen devices if (flagPreviousItemsEnabled && (eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.USBID_TYPE_ID || eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.ICCID_TYPE_ID @@ -487,7 +501,7 @@ public class IngestEventsListener { || eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.IMSI_TYPE_ID || eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.MAC_TYPE_ID)) { try { - //only alert to previous instances when they were in another case + // only alert to previous instances when they were in another case List previousOccurences = dbManager.getArtifactInstancesByTypeValue(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); List caseDisplayNames; for (CorrelationAttributeInstance instance : previousOccurences) { @@ -498,9 +512,30 @@ public class IngestEventsListener { } } } 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 previousOccurences = dbManager.getArtifactInstancesByTypeValue(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); + // make sure the previous instances do not contain current case + for (Iterator 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) { eamArtifacts.add(eamArtifact); } From 0caac0d7e3c54516b0baa47fff060957384e9e90 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Wed, 28 Jul 2021 15:29:47 -0400 Subject: [PATCH 13/64] Bug fixes --- .../datamodel/AnalysisSummary.java | 3 +- .../datamodel/PastCasesSummary.java | 40 +++++++++---------- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/AnalysisSummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/AnalysisSummary.java index 13915de369..ff0caea395 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/AnalysisSummary.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/AnalysisSummary.java @@ -49,7 +49,8 @@ public class AnalysisSummary implements DefaultArtifactUpdateGovernor { private static final Set EXCLUDED_KEYWORD_SEARCH_ITEMS = new HashSet<>(); private static final Set ARTIFACT_UPDATE_TYPE_IDS = new HashSet<>(Arrays.asList( - ARTIFACT_TYPE.TSK_PREVIOUSLY_SEEN.getTypeID(), + ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(), + ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID(), ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID(), ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() )); diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/PastCasesSummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/PastCasesSummary.java index d016c0ad19..5d7d998bf0 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/PastCasesSummary.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/PastCasesSummary.java @@ -25,10 +25,11 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.logging.Level; import java.util.stream.Collectors; import java.util.stream.Stream; 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.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException; 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.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; +import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; @@ -104,7 +106,6 @@ public class PastCasesSummary implements DefaultArtifactUpdateGovernor { 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_ASSOCIATED_ARTIFACT = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT); private static final Set CR_DEVICE_TYPE_IDS = new HashSet<>(Arrays.asList( ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID(), @@ -241,30 +242,23 @@ public class PastCasesSummary implements DefaultArtifactUpdateGovernor { } /** - * Given an artifact with a TYPE_ASSOCIATED_ARTIFACT attribute, retrieves - * the related artifact. + * Given a TSK_PREVIOUSLY_SEEN artifact, retrieves it's parent 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. * - * @throws SleuthkitCaseProviderException + * @throws TskCoreException + * @throws NoCurrentCaseException */ - private BlackboardArtifact getParentArtifact(BlackboardArtifact artifact) throws SleuthkitCaseProviderException { - Long parentId = DataSourceInfoUtilities.getLongOrNull(artifact, TYPE_ASSOCIATED_ARTIFACT); - if (parentId == null) { - return null; - } + private BlackboardArtifact getParentArtifact(BlackboardArtifact artifact) throws TskCoreException, NoCurrentCaseException { - SleuthkitCase skCase = caseProvider.get(); - try { - return skCase.getArtifactByArtifactId(parentId); - } catch (TskCoreException ex) { - logger.log(Level.WARNING, - String.format("There was an error fetching the parent artifact of a TSK_PREVIOUSLY SEEN (parent id: %d)", parentId), - ex); - return null; + BlackboardArtifact sourceArtifact = null; + Content content = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID()); + if (content instanceof BlackboardArtifact) { + sourceArtifact = (BlackboardArtifact) content; } + return sourceArtifact; } /** @@ -274,9 +268,10 @@ public class PastCasesSummary implements DefaultArtifactUpdateGovernor { * * @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); if (parent == null) { return false; @@ -294,9 +289,10 @@ public class PastCasesSummary implements DefaultArtifactUpdateGovernor { * * @throws SleuthkitCaseProviderException * @throws TskCoreException + * @throws NoCurrentCaseException */ public PastCasesResult getPastCasesData(DataSource dataSource) - throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException { + throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException, NoCurrentCaseException { if (dataSource == null) { return null; From efbf18a9efa7d3abda4dbe5d3e7c1d824a7c61c3 Mon Sep 17 00:00:00 2001 From: apriestman Date: Thu, 29 Jul 2021 10:41:47 -0400 Subject: [PATCH 14/64] Add correlation type and value to previously seen/unseen artifacts --- .../eventlisteners/CaseEventListener.java | 11 ++++- .../eventlisteners/IngestEventsListener.java | 40 ++++++++++++++----- .../ingestmodule/CentralRepoIngestModule.java | 12 +++++- 3 files changed, 51 insertions(+), 12 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java index 274317fbac..284044c8ae 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java @@ -67,6 +67,8 @@ import org.sleuthkit.datamodel.Blackboard; import org.sleuthkit.datamodel.BlackboardAttribute; 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_CORRELATION_TYPE; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CORRELATION_VALUE; import org.sleuthkit.datamodel.OsAccount; import org.sleuthkit.datamodel.OsAccountInstance; import org.sleuthkit.datamodel.Score; @@ -713,7 +715,8 @@ public final class CaseEventListener implements PropertyChangeListener { // Look up and create artifacts for previously seen accounts if requested if (IngestEventsListener.isFlagSeenDevices()) { - List previousOccurences = dbManager.getArtifactInstancesByTypeValue(CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.OSACCOUNT_TYPE_ID), correlationAttributeInstance.getCorrelationValue()); + CorrelationAttributeInstance.Type osAcctType = CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.OSACCOUNT_TYPE_ID); + List previousOccurences = dbManager.getArtifactInstancesByTypeValue(osAcctType, correlationAttributeInstance.getCorrelationValue()); for (CorrelationAttributeInstance instance : previousOccurences) { if (!instance.getCorrelationCase().getCaseUUID().equals(correlationAttributeInstance.getCorrelationCase().getCaseUUID())) { SleuthkitCase tskCase = osAccount.getSleuthkitCase(); @@ -723,6 +726,12 @@ public final class CaseEventListener implements PropertyChangeListener { new BlackboardAttribute( TSK_SET_NAME, MODULE_NAME, Bundle.CaseEventsListener_prevExists_text()), + new BlackboardAttribute( + TSK_CORRELATION_TYPE, MODULE_NAME, + osAcctType.getDisplayName()), + new BlackboardAttribute( + TSK_CORRELATION_VALUE, MODULE_NAME, + correlationAttributeInstance.getCorrelationValue()), new BlackboardAttribute( TSK_COMMENT, MODULE_NAME, Bundle.CaseEventsListener_prevCaseComment_text())); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java index 840b6586bd..20dc8ff77b 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java @@ -56,6 +56,8 @@ import org.sleuthkit.autopsy.coreutils.ThreadUtils; import static org.sleuthkit.autopsy.ingest.IngestManager.IngestModuleEvent.DATA_ADDED; 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_CORRELATION_TYPE; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CORRELATION_VALUE; import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisEvent; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Image; @@ -208,11 +210,18 @@ public class IngestEventsListener { */ @NbBundle.Messages({"IngestEventsListener.prevTaggedSet.text=Previously Tagged As Notable (Central Repository)", "IngestEventsListener.prevCaseComment.text=Previous Case: "}) - static private void makeAndPostPreviousNotableArtifact(BlackboardArtifact originalArtifact, List caseDisplayNames) { + static private void makeAndPostPreviousNotableArtifact(BlackboardArtifact originalArtifact, List caseDisplayNames, + CorrelationAttributeInstance.Type aType, String value) { Collection attributesForNewArtifact = Arrays.asList( new BlackboardAttribute( TSK_SET_NAME, MODULE_NAME, Bundle.IngestEventsListener_prevTaggedSet_text()), + new BlackboardAttribute( + TSK_CORRELATION_TYPE, MODULE_NAME, + aType.getDisplayName()), + new BlackboardAttribute( + TSK_CORRELATION_VALUE, MODULE_NAME, + value), new BlackboardAttribute( TSK_COMMENT, MODULE_NAME, Bundle.IngestEventsListener_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(",")))); @@ -231,10 +240,17 @@ public class IngestEventsListener { "# {0} - typeName", "# {1} - count", "IngestEventsListener.prevCount.text=Number of previous {0}: {1}"}) - static private void makeAndPostPreviousSeenArtifact(BlackboardArtifact originalArtifact, List caseDisplayNames) { + static private void makeAndPostPreviousSeenArtifact(BlackboardArtifact originalArtifact, List caseDisplayNames, + CorrelationAttributeInstance.Type aType, String value) { Collection attributesForNewArtifact = Arrays.asList(new BlackboardAttribute( - TSK_SET_NAME, MODULE_NAME, - Bundle.IngestEventsListener_prevExists_text()), + TSK_SET_NAME, MODULE_NAME, + Bundle.IngestEventsListener_prevExists_text()), + new BlackboardAttribute( + TSK_CORRELATION_TYPE, MODULE_NAME, + aType.getDisplayName()), + new BlackboardAttribute( + TSK_CORRELATION_VALUE, MODULE_NAME, + value), new BlackboardAttribute( TSK_COMMENT, MODULE_NAME, Bundle.IngestEventsListener_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(",")))); @@ -248,8 +264,14 @@ public class IngestEventsListener { * @param originalArtifact the artifact to create the "previously unseen" item * for */ - static private void makeAndPostPreviouslyUnseenArtifact(BlackboardArtifact originalArtifact) { - Collection attributesForNewArtifact = new ArrayList<>(); + static private void makeAndPostPreviouslyUnseenArtifact(BlackboardArtifact originalArtifact, CorrelationAttributeInstance.Type aType, String value) { + Collection attributesForNewArtifact = Arrays.asList( + new BlackboardAttribute( + TSK_CORRELATION_TYPE, MODULE_NAME, + aType.getDisplayName()), + new BlackboardAttribute( + TSK_CORRELATION_VALUE, MODULE_NAME, + value)); makeAndPostArtifact(BlackboardArtifact.Type.TSK_PREVIOUSLY_UNSEEN, originalArtifact, attributesForNewArtifact, ""); } @@ -486,7 +508,7 @@ public class IngestEventsListener { caseDisplayNames = dbManager.getListCasesHavingArtifactInstancesKnownBad(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); if (!caseDisplayNames.isEmpty()) { makeAndPostPreviousNotableArtifact(bbArtifact, - caseDisplayNames); + caseDisplayNames, eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); } } catch (CorrelationAttributeNormalizationException ex) { LOGGER.log(Level.INFO, String.format("Unable to flag notable item: %s.", eamArtifact.toString()), ex); @@ -507,7 +529,7 @@ public class IngestEventsListener { for (CorrelationAttributeInstance instance : previousOccurences) { if (!instance.getCorrelationCase().getCaseUUID().equals(eamArtifact.getCorrelationCase().getCaseUUID())) { caseDisplayNames = dbManager.getListCasesHavingArtifactInstances(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); - makeAndPostPreviousSeenArtifact(bbArtifact, caseDisplayNames); + makeAndPostPreviousSeenArtifact(bbArtifact, caseDisplayNames, eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); break; } } @@ -530,7 +552,7 @@ public class IngestEventsListener { } } if (previousOccurences.isEmpty()) { - makeAndPostPreviouslyUnseenArtifact(bbArtifact); + makeAndPostPreviouslyUnseenArtifact(bbArtifact, eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); } } catch (CorrelationAttributeNormalizationException ex) { LOGGER.log(Level.INFO, String.format("Unable to flag previously unseen application: %s.", eamArtifact.toString()), ex); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java index fd203915e1..2d9063bb2e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java @@ -52,6 +52,8 @@ import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_PREVI import org.sleuthkit.datamodel.BlackboardAttribute; 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_CORRELATION_TYPE; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CORRELATION_VALUE; import org.sleuthkit.datamodel.HashUtility; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; @@ -151,7 +153,7 @@ final class CentralRepoIngestModule implements FileIngestModule { List caseDisplayNamesList = dbManager.getListCasesHavingArtifactInstancesKnownBad(filesType, md5); HealthMonitor.submitTimingMetric(timingMetric); if (!caseDisplayNamesList.isEmpty()) { - postCorrelatedBadFileToBlackboard(abstractFile, caseDisplayNamesList); + postCorrelatedBadFileToBlackboard(abstractFile, caseDisplayNamesList, filesType, md5); } } catch (CentralRepoException ex) { logger.log(Level.SEVERE, "Error searching database for artifact.", ex); // NON-NLS @@ -332,11 +334,17 @@ final class CentralRepoIngestModule implements FileIngestModule { * @param abstractFile The file from which to create an artifact. * @param caseDisplayNames Case names to be added to a TSK_COMMON attribute. */ - private void postCorrelatedBadFileToBlackboard(AbstractFile abstractFile, List caseDisplayNames) { + private void postCorrelatedBadFileToBlackboard(AbstractFile abstractFile, List caseDisplayNames, CorrelationAttributeInstance.Type aType, String value) { Collection attributes = Arrays.asList( new BlackboardAttribute( TSK_SET_NAME, MODULE_NAME, Bundle.CentralRepoIngestModule_prevTaggedSet_text()), + new BlackboardAttribute( + TSK_CORRELATION_TYPE, MODULE_NAME, + aType.getDisplayName()), + new BlackboardAttribute( + TSK_CORRELATION_VALUE, MODULE_NAME, + value), new BlackboardAttribute( TSK_COMMENT, MODULE_NAME, Bundle.CentralRepoIngestModule_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(",")))); From 96542711fc8dc4173e7223af2a7aec90a1b734cc Mon Sep 17 00:00:00 2001 From: apriestman Date: Thu, 29 Jul 2021 12:03:24 -0400 Subject: [PATCH 15/64] Move past cases to TSK_OTHER_CASES --- .../eventlisteners/CaseEventListener.java | 7 +++++-- .../eventlisteners/IngestEventsListener.java | 17 ++++++++++------- .../ingestmodule/CentralRepoIngestModule.java | 6 +++--- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java index 284044c8ae..43fdfa337d 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java @@ -30,6 +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.NbBundle; import org.openide.util.NbBundle.Messages; @@ -69,6 +70,7 @@ import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COM import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CORRELATION_TYPE; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CORRELATION_VALUE; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_OTHER_CASES; import org.sleuthkit.datamodel.OsAccount; import org.sleuthkit.datamodel.OsAccountInstance; import org.sleuthkit.datamodel.Score; @@ -722,6 +724,7 @@ public final class CaseEventListener implements PropertyChangeListener { SleuthkitCase tskCase = osAccount.getSleuthkitCase(); Blackboard blackboard = tskCase.getBlackboard(); + List caseDisplayNames = dbManager.getListCasesHavingArtifactInstances(osAcctType, correlationAttributeInstance.getCorrelationValue()); Collection attributesForNewArtifact = Arrays.asList( new BlackboardAttribute( TSK_SET_NAME, MODULE_NAME, @@ -733,8 +736,8 @@ public final class CaseEventListener implements PropertyChangeListener { TSK_CORRELATION_VALUE, MODULE_NAME, correlationAttributeInstance.getCorrelationValue()), new BlackboardAttribute( - TSK_COMMENT, MODULE_NAME, - Bundle.CaseEventsListener_prevCaseComment_text())); + TSK_OTHER_CASES, MODULE_NAME, + caseDisplayNames.stream().distinct().collect(Collectors.joining(",")))); BlackboardArtifact newAnalysisResult = osAccount.newAnalysisResult( BlackboardArtifact.Type.TSK_PREVIOUSLY_SEEN, Score.SCORE_LIKELY_NOTABLE, null, Bundle.CaseEventsListener_prevExists_text(), null, attributesForNewArtifact, osAccountInstance.getDataSource().getId()).getAnalysisResult(); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java index 20dc8ff77b..355dc74724 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java @@ -54,10 +54,10 @@ import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_PREVI import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.autopsy.coreutils.ThreadUtils; import static org.sleuthkit.autopsy.ingest.IngestManager.IngestModuleEvent.DATA_ADDED; -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_CORRELATION_TYPE; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CORRELATION_VALUE; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_OTHER_CASES; import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisEvent; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Image; @@ -199,6 +199,10 @@ public class IngestEventsListener { public synchronized static void setCreateCrProperties(boolean value) { createCrProperties = value; } + + static private String createOtherCasesAttrString(List caseDisplayNames) { + return caseDisplayNames.stream().distinct().collect(Collectors.joining(",")); + } /** * Make a "previously seen" artifact based on a new artifact being @@ -212,8 +216,7 @@ public class IngestEventsListener { "IngestEventsListener.prevCaseComment.text=Previous Case: "}) static private void makeAndPostPreviousNotableArtifact(BlackboardArtifact originalArtifact, List caseDisplayNames, CorrelationAttributeInstance.Type aType, String value) { - Collection attributesForNewArtifact = Arrays.asList( - new BlackboardAttribute( + Collection attributesForNewArtifact = Arrays.asList(new BlackboardAttribute( TSK_SET_NAME, MODULE_NAME, Bundle.IngestEventsListener_prevTaggedSet_text()), new BlackboardAttribute( @@ -223,8 +226,8 @@ public class IngestEventsListener { TSK_CORRELATION_VALUE, MODULE_NAME, value), new BlackboardAttribute( - TSK_COMMENT, MODULE_NAME, - Bundle.IngestEventsListener_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(",")))); + TSK_OTHER_CASES, MODULE_NAME, + createOtherCasesAttrString(caseDisplayNames))); makeAndPostArtifact(BlackboardArtifact.Type.TSK_PREVIOUSLY_SEEN, originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevTaggedSet_text()); } @@ -252,8 +255,8 @@ public class IngestEventsListener { TSK_CORRELATION_VALUE, MODULE_NAME, value), new BlackboardAttribute( - TSK_COMMENT, MODULE_NAME, - Bundle.IngestEventsListener_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(",")))); + TSK_OTHER_CASES, MODULE_NAME, + createOtherCasesAttrString(caseDisplayNames))); makeAndPostArtifact(BlackboardArtifact.Type.TSK_PREVIOUSLY_SEEN, originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevExists_text()); } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java index 2d9063bb2e..1f665d8e08 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java @@ -50,7 +50,7 @@ import org.sleuthkit.datamodel.Blackboard; import org.sleuthkit.datamodel.BlackboardArtifact; import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_PREVIOUSLY_SEEN; import org.sleuthkit.datamodel.BlackboardAttribute; -import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_OTHER_CASES; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CORRELATION_TYPE; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CORRELATION_VALUE; @@ -346,8 +346,8 @@ final class CentralRepoIngestModule implements FileIngestModule { TSK_CORRELATION_VALUE, MODULE_NAME, value), new BlackboardAttribute( - TSK_COMMENT, MODULE_NAME, - Bundle.CentralRepoIngestModule_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(",")))); + TSK_OTHER_CASES, MODULE_NAME, + caseDisplayNames.stream().distinct().collect(Collectors.joining(",")))); try { // Create artifact if it doesn't already exist. From 8bdd91fbd155d36e15e8dfed012f290b0ee63808 Mon Sep 17 00:00:00 2001 From: apriestman Date: Thu, 29 Jul 2021 12:06:44 -0400 Subject: [PATCH 16/64] Refactor --- .../eventlisteners/IngestEventsListener.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java index 355dc74724..5621ca8b12 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java @@ -199,10 +199,6 @@ public class IngestEventsListener { public synchronized static void setCreateCrProperties(boolean value) { createCrProperties = value; } - - static private String createOtherCasesAttrString(List caseDisplayNames) { - return caseDisplayNames.stream().distinct().collect(Collectors.joining(",")); - } /** * Make a "previously seen" artifact based on a new artifact being @@ -227,7 +223,7 @@ public class IngestEventsListener { value), new BlackboardAttribute( TSK_OTHER_CASES, MODULE_NAME, - createOtherCasesAttrString(caseDisplayNames))); + caseDisplayNames.stream().distinct().collect(Collectors.joining(",")))); makeAndPostArtifact(BlackboardArtifact.Type.TSK_PREVIOUSLY_SEEN, originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevTaggedSet_text()); } @@ -256,7 +252,7 @@ public class IngestEventsListener { value), new BlackboardAttribute( TSK_OTHER_CASES, MODULE_NAME, - createOtherCasesAttrString(caseDisplayNames))); + caseDisplayNames.stream().distinct().collect(Collectors.joining(",")))); makeAndPostArtifact(BlackboardArtifact.Type.TSK_PREVIOUSLY_SEEN, originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevExists_text()); } From 6f375ec08b7b8aa0374b00f97c094c9a960a3fea Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Thu, 29 Jul 2021 13:38:05 -0400 Subject: [PATCH 17/64] Improvements and fixes --- .../eventlisteners/IngestEventsListener.java | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java index 840b6586bd..938342677e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java @@ -49,8 +49,6 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource; import org.sleuthkit.datamodel.Blackboard; import org.sleuthkit.datamodel.BlackboardArtifact; -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.autopsy.coreutils.ThreadUtils; import static org.sleuthkit.autopsy.ingest.IngestManager.IngestModuleEvent.DATA_ADDED; @@ -209,14 +207,17 @@ public class IngestEventsListener { @NbBundle.Messages({"IngestEventsListener.prevTaggedSet.text=Previously Tagged As Notable (Central Repository)", "IngestEventsListener.prevCaseComment.text=Previous Case: "}) static private void makeAndPostPreviousNotableArtifact(BlackboardArtifact originalArtifact, List caseDisplayNames) { + String prevCases = caseDisplayNames.stream().distinct().collect(Collectors.joining(",")); + String justification = "Previously marked as notable in " + prevCases; Collection attributesForNewArtifact = Arrays.asList( new BlackboardAttribute( TSK_SET_NAME, MODULE_NAME, Bundle.IngestEventsListener_prevTaggedSet_text()), new BlackboardAttribute( TSK_COMMENT, MODULE_NAME, - Bundle.IngestEventsListener_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(",")))); - makeAndPostArtifact(BlackboardArtifact.Type.TSK_PREVIOUSLY_SEEN, originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevTaggedSet_text()); + Bundle.IngestEventsListener_prevCaseComment_text() + prevCases)); + makeAndPostArtifact(BlackboardArtifact.Type.TSK_PREVIOUSLY_NOTABLE, originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevTaggedSet_text(), + Score.SCORE_NOTABLE, justification); } /** @@ -232,13 +233,17 @@ public class IngestEventsListener { "# {1} - count", "IngestEventsListener.prevCount.text=Number of previous {0}: {1}"}) static private void makeAndPostPreviousSeenArtifact(BlackboardArtifact originalArtifact, List caseDisplayNames) { + String prevCases = caseDisplayNames.stream().distinct().collect(Collectors.joining(",")); + String justification = "Previously seen in " + prevCases; Collection attributesForNewArtifact = Arrays.asList(new BlackboardAttribute( TSK_SET_NAME, MODULE_NAME, Bundle.IngestEventsListener_prevExists_text()), new BlackboardAttribute( TSK_COMMENT, MODULE_NAME, - Bundle.IngestEventsListener_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(",")))); - makeAndPostArtifact(BlackboardArtifact.Type.TSK_PREVIOUSLY_SEEN, originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevExists_text()); + Bundle.IngestEventsListener_prevCaseComment_text() + prevCases)); + // ELTODO calculate score + makeAndPostArtifact(BlackboardArtifact.Type.TSK_PREVIOUSLY_SEEN, originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevExists_text(), + Score.SCORE_LIKELY_NOTABLE, justification); } /** @@ -250,7 +255,8 @@ public class IngestEventsListener { */ static private void makeAndPostPreviouslyUnseenArtifact(BlackboardArtifact originalArtifact) { Collection attributesForNewArtifact = new ArrayList<>(); - makeAndPostArtifact(BlackboardArtifact.Type.TSK_PREVIOUSLY_UNSEEN, originalArtifact, attributesForNewArtifact, ""); + makeAndPostArtifact(BlackboardArtifact.Type.TSK_PREVIOUSLY_UNSEEN, originalArtifact, attributesForNewArtifact, "", + Score.SCORE_LIKELY_NOTABLE, "This application has not been previously seen before"); } /** @@ -259,8 +265,11 @@ public class IngestEventsListener { * @param originalArtifact Artifact in current case we want to flag * @param attributesForNewArtifact Attributes to assign to the new artifact * @param configuration The configuration to be specified for the new artifact hit + * @param score sleuthkit.datamodel.Score to be assigned to this artifact + * @param justification Justification string */ - private static void makeAndPostArtifact(BlackboardArtifact.Type newArtifactType, BlackboardArtifact originalArtifact, Collection attributesForNewArtifact, String configuration) { + private static void makeAndPostArtifact(BlackboardArtifact.Type newArtifactType, BlackboardArtifact originalArtifact, Collection attributesForNewArtifact, String configuration, + Score score, String justification) { try { SleuthkitCase tskCase = originalArtifact.getSleuthkitCase(); Blackboard blackboard = tskCase.getBlackboard(); @@ -268,8 +277,8 @@ public class IngestEventsListener { BlackboardArtifact.ARTIFACT_TYPE type = BlackboardArtifact.ARTIFACT_TYPE.fromID(newArtifactType.getTypeID()); if (!blackboard.artifactExists(originalArtifact, type, attributesForNewArtifact)) { BlackboardArtifact newArtifact = originalArtifact.newAnalysisResult( - newArtifactType, Score.SCORE_LIKELY_NOTABLE, - null, configuration, null, attributesForNewArtifact) + newArtifactType, score, + null, configuration, justification, attributesForNewArtifact) .getAnalysisResult(); try { @@ -516,9 +525,11 @@ public class IngestEventsListener { } } - // flag previously unseen apps + // flag previously unseen apps and domains + // ELTODO use new flag instead of flagPreviousItemsEnabled if (flagPreviousItemsEnabled - && eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.INSTALLED_PROGS_TYPE_ID) { + && (eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.INSTALLED_PROGS_TYPE_ID + || eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.DOMAIN_TYPE_ID)) { try { List previousOccurences = dbManager.getArtifactInstancesByTypeValue(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); // make sure the previous instances do not contain current case From 519e98741c48e30032326ee6e3ce6565e2b57558 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Thu, 29 Jul 2021 14:20:49 -0400 Subject: [PATCH 18/64] Fixes --- .../centralrepository/eventlisteners/CaseEventListener.java | 4 ++-- .../eventlisteners/IngestEventsListener.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java index 031b74f70e..bba74a5b2f 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java @@ -66,7 +66,7 @@ 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_COMMENT; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_OTHER_CASES; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CORRELATION_TYPE; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CORRELATION_VALUE; @@ -735,7 +735,7 @@ public final class CaseEventListener implements PropertyChangeListener { TSK_CORRELATION_VALUE, MODULE_NAME, correlationAttributeInstance.getCorrelationValue()), new BlackboardAttribute( - TSK_COMMENT, MODULE_NAME, + TSK_OTHER_CASES, MODULE_NAME, caseDisplayNames.stream().distinct().collect(Collectors.joining(",")))); BlackboardArtifact newAnalysisResult = osAccount.newAnalysisResult( BlackboardArtifact.Type.TSK_PREVIOUSLY_SEEN, Score.SCORE_LIKELY_NOTABLE, diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java index 663eabce8b..ab01bdffbf 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java @@ -55,7 +55,7 @@ import static org.sleuthkit.autopsy.ingest.IngestManager.IngestModuleEvent.DATA_ import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CORRELATION_TYPE; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CORRELATION_VALUE; -import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_OTHER_CASES; import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisEvent; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Image; @@ -222,7 +222,7 @@ public class IngestEventsListener { TSK_CORRELATION_VALUE, MODULE_NAME, value), new BlackboardAttribute( - TSK_COMMENT, MODULE_NAME, + TSK_OTHER_CASES, MODULE_NAME, Bundle.IngestEventsListener_prevCaseComment_text() + prevCases)); makeAndPostArtifact(BlackboardArtifact.Type.TSK_PREVIOUSLY_NOTABLE, originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevTaggedSet_text(), Score.SCORE_NOTABLE, justification); @@ -254,7 +254,7 @@ public class IngestEventsListener { TSK_CORRELATION_VALUE, MODULE_NAME, value), new BlackboardAttribute( - TSK_COMMENT, MODULE_NAME, + TSK_OTHER_CASES, MODULE_NAME, Bundle.IngestEventsListener_prevCaseComment_text() + prevCases)); // ELTODO calculate score makeAndPostArtifact(BlackboardArtifact.Type.TSK_PREVIOUSLY_SEEN, originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevExists_text(), From 33b08b07b4eb48cc37cbb8f028ce532c70893820 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Thu, 29 Jul 2021 14:24:04 -0400 Subject: [PATCH 19/64] Fixes --- .../ingestmodule/CentralRepoIngestModule.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java index 59a3e02d17..d994d802c2 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java @@ -53,7 +53,7 @@ import org.sleuthkit.datamodel.BlackboardAttribute; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CORRELATION_TYPE; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CORRELATION_VALUE; -import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_OTHER_CASES; import org.sleuthkit.datamodel.HashUtility; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; @@ -346,8 +346,8 @@ final class CentralRepoIngestModule implements FileIngestModule { TSK_CORRELATION_VALUE, MODULE_NAME, value), new BlackboardAttribute( - TSK_COMMENT, MODULE_NAME, - Bundle.CentralRepoIngestModule_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(",")))); + TSK_OTHER_CASES, MODULE_NAME, + caseDisplayNames.stream().distinct().collect(Collectors.joining(",")))); try { // Create artifact if it doesn't already exist. From 89347d2b7dc9fcd99280e2f9546ff1e0dc6e88c0 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Thu, 29 Jul 2021 15:59:11 -0400 Subject: [PATCH 20/64] Improvements and bug fixes --- .../eventlisteners/CaseEventListener.java | 21 ++++++++-- .../eventlisteners/IngestEventsListener.java | 32 +++++++++++---- .../ingestmodule/CentralRepoIngestModule.java | 13 +++--- .../datamodel/PastCasesSummary.java | 40 +++++++++++-------- 4 files changed, 73 insertions(+), 33 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java index bba74a5b2f..5d570c6f52 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java @@ -724,6 +724,21 @@ public final class CaseEventListener implements PropertyChangeListener { Blackboard blackboard = tskCase.getBlackboard(); List caseDisplayNames = dbManager.getListCasesHavingArtifactInstances(osAcctType, correlationAttributeInstance.getCorrelationValue()); + + // calculate score + Score score; + int numCases = caseDisplayNames.size(); + if (numCases <= IngestEventsListener.MAX_NUM_PREVIOUS_CASES_FOR_LIKELY_NOTABLE_SCORE) { + score = Score.SCORE_LIKELY_NOTABLE; + } else if (numCases > IngestEventsListener.MAX_NUM_PREVIOUS_CASES_FOR_LIKELY_NOTABLE_SCORE && numCases <= IngestEventsListener.MAX_NUM_PREVIOUS_CASES_FOR_PREV_SEEN_ARTIFACT_CREATION) { + score = Score.SCORE_NONE; + } else { + // don't make an Analysis Result, the artifact is too common. + continue; + } + + String prevCases = caseDisplayNames.stream().distinct().collect(Collectors.joining(",")); + String justification = "Previously seen in cases " + prevCases; Collection attributesForNewArtifact = Arrays.asList( new BlackboardAttribute( TSK_SET_NAME, MODULE_NAME, @@ -736,10 +751,10 @@ public final class CaseEventListener implements PropertyChangeListener { correlationAttributeInstance.getCorrelationValue()), new BlackboardAttribute( TSK_OTHER_CASES, MODULE_NAME, - caseDisplayNames.stream().distinct().collect(Collectors.joining(",")))); + prevCases)); BlackboardArtifact newAnalysisResult = osAccount.newAnalysisResult( - BlackboardArtifact.Type.TSK_PREVIOUSLY_SEEN, Score.SCORE_LIKELY_NOTABLE, - null, Bundle.CaseEventsListener_prevExists_text(), null, attributesForNewArtifact, osAccountInstance.getDataSource().getId()).getAnalysisResult(); + BlackboardArtifact.Type.TSK_PREVIOUSLY_SEEN, score, + null, Bundle.CaseEventsListener_prevExists_text(), justification, attributesForNewArtifact, osAccountInstance.getDataSource().getId()).getAnalysisResult(); try { // index the artifact for keyword search blackboard.postArtifact(newAnalysisResult, MODULE_NAME); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java index ab01bdffbf..54bb73455d 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java @@ -83,6 +83,9 @@ public class IngestEventsListener { private final PropertyChangeListener pcl1 = new IngestModuleEventListener(); private final PropertyChangeListener pcl2 = new IngestJobEventListener(); final Collection recentlyAddedCeArtifacts = new LinkedHashSet<>(); + + static final int MAX_NUM_PREVIOUS_CASES_FOR_LIKELY_NOTABLE_SCORE = 10; + static final int MAX_NUM_PREVIOUS_CASES_FOR_PREV_SEEN_ARTIFACT_CREATION = 20; public IngestEventsListener() { jobProcessingExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat(INGEST_EVENT_THREAD_NAME).build()); @@ -211,7 +214,7 @@ public class IngestEventsListener { static private void makeAndPostPreviousNotableArtifact(BlackboardArtifact originalArtifact, List caseDisplayNames, CorrelationAttributeInstance.Type aType, String value) { String prevCases = caseDisplayNames.stream().distinct().collect(Collectors.joining(",")); - String justification = "Previously marked as notable in " + prevCases; + String justification = "Previously marked as notable in cases " + prevCases; Collection attributesForNewArtifact = Arrays.asList(new BlackboardAttribute( TSK_SET_NAME, MODULE_NAME, Bundle.IngestEventsListener_prevTaggedSet_text()), @@ -223,14 +226,14 @@ public class IngestEventsListener { value), new BlackboardAttribute( TSK_OTHER_CASES, MODULE_NAME, - Bundle.IngestEventsListener_prevCaseComment_text() + prevCases)); + prevCases)); makeAndPostArtifact(BlackboardArtifact.Type.TSK_PREVIOUSLY_NOTABLE, originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevTaggedSet_text(), Score.SCORE_NOTABLE, justification); } /** * Create a "previously seen" hit for a device which was previously seen - * in the central repository. + * in the central repository. NOTE: Artifacts that are too common will be skipped. * * @param originalArtifact the artifact to create the "previously seen" item for * @param caseDisplayNames the case names the artifact was previously seen @@ -242,8 +245,21 @@ public class IngestEventsListener { "IngestEventsListener.prevCount.text=Number of previous {0}: {1}"}) static private void makeAndPostPreviousSeenArtifact(BlackboardArtifact originalArtifact, List caseDisplayNames, CorrelationAttributeInstance.Type aType, String value) { + + // calculate score + Score score; + int numCases = caseDisplayNames.size(); + if (numCases <= MAX_NUM_PREVIOUS_CASES_FOR_LIKELY_NOTABLE_SCORE) { + score = Score.SCORE_LIKELY_NOTABLE; + } else if (numCases > MAX_NUM_PREVIOUS_CASES_FOR_LIKELY_NOTABLE_SCORE && numCases <= MAX_NUM_PREVIOUS_CASES_FOR_PREV_SEEN_ARTIFACT_CREATION) { + score = Score.SCORE_NONE; + } else { + // don't make an Analysis Result, the artifact is too common. + return; + } + String prevCases = caseDisplayNames.stream().distinct().collect(Collectors.joining(",")); - String justification = "Previously seen in " + prevCases; + String justification = "Previously seen in cases " + prevCases; Collection attributesForNewArtifact = Arrays.asList(new BlackboardAttribute( TSK_SET_NAME, MODULE_NAME, Bundle.IngestEventsListener_prevExists_text()), @@ -255,10 +271,9 @@ public class IngestEventsListener { value), new BlackboardAttribute( TSK_OTHER_CASES, MODULE_NAME, - Bundle.IngestEventsListener_prevCaseComment_text() + prevCases)); - // ELTODO calculate score + prevCases)); makeAndPostArtifact(BlackboardArtifact.Type.TSK_PREVIOUSLY_SEEN, originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevExists_text(), - Score.SCORE_LIKELY_NOTABLE, justification); + score, justification); } /** @@ -517,6 +532,9 @@ public class IngestEventsListener { if (!caseDisplayNames.isEmpty()) { makeAndPostPreviousNotableArtifact(bbArtifact, caseDisplayNames, eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); + + // if we have marked this artifact as notable, then skip the analysis of whether it was previously seen + continue; } } catch (CorrelationAttributeNormalizationException ex) { LOGGER.log(Level.INFO, String.format("Unable to flag notable item: %s.", eamArtifact.toString()), ex); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java index d994d802c2..470ee7cd82 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java @@ -48,7 +48,7 @@ import org.sleuthkit.autopsy.ingest.IngestServices; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Blackboard; import org.sleuthkit.datamodel.BlackboardArtifact; -import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_PREVIOUSLY_SEEN; +import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_PREVIOUSLY_NOTABLE; import org.sleuthkit.datamodel.BlackboardAttribute; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CORRELATION_TYPE; @@ -335,6 +335,8 @@ final class CentralRepoIngestModule implements FileIngestModule { * @param caseDisplayNames Case names to be added to a TSK_COMMON attribute. */ private void postCorrelatedBadFileToBlackboard(AbstractFile abstractFile, List caseDisplayNames, CorrelationAttributeInstance.Type aType, String value) { + String prevCases = caseDisplayNames.stream().distinct().collect(Collectors.joining(",")); + String justification = "Previously marked as notable in cases " + prevCases; Collection attributes = Arrays.asList( new BlackboardAttribute( TSK_SET_NAME, MODULE_NAME, @@ -347,14 +349,13 @@ final class CentralRepoIngestModule implements FileIngestModule { value), new BlackboardAttribute( TSK_OTHER_CASES, MODULE_NAME, - caseDisplayNames.stream().distinct().collect(Collectors.joining(",")))); + prevCases)); try { - // Create artifact if it doesn't already exist. - if (!blackboard.artifactExists(abstractFile, TSK_PREVIOUSLY_SEEN, attributes)) { + if (!blackboard.artifactExists(abstractFile, TSK_PREVIOUSLY_NOTABLE, attributes)) { BlackboardArtifact tifArtifact = abstractFile.newAnalysisResult( - BlackboardArtifact.Type.TSK_PREVIOUSLY_SEEN, Score.SCORE_LIKELY_NOTABLE, - null, Bundle.CentralRepoIngestModule_prevTaggedSet_text(), null, attributes) + BlackboardArtifact.Type.TSK_PREVIOUSLY_NOTABLE, Score.SCORE_NOTABLE, + null, Bundle.CentralRepoIngestModule_prevTaggedSet_text(), justification, attributes) .getAnalysisResult(); try { // index the artifact for keyword search diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/PastCasesSummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/PastCasesSummary.java index 5d7d998bf0..e28dbe7dc1 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/PastCasesSummary.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/PastCasesSummary.java @@ -37,6 +37,7 @@ import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_OTHER_CASES; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.SleuthkitCase; @@ -49,7 +50,7 @@ import org.sleuthkit.datamodel.TskCoreException; * ingest process, this code could break. This code expects that the central * repository ingest module: * - * a) Creates a TSK_PREVIOUSLY_SEEN artifact for a file whose hash is in + * a) Creates a TSK_PREVIOUSLY_NOTABLE artifact for a file whose hash is in * the central repository as a notable file. * * b) Creates a TSK_PREVIOUSLY_SEEN artifact for a matching id in the @@ -101,11 +102,12 @@ public class PastCasesSummary implements DefaultArtifactUpdateGovernor { } private static final Set ARTIFACT_UPDATE_TYPE_IDS = new HashSet<>(Arrays.asList( - ARTIFACT_TYPE.TSK_PREVIOUSLY_SEEN.getTypeID() + ARTIFACT_TYPE.TSK_PREVIOUSLY_SEEN.getTypeID(), + ARTIFACT_TYPE.TSK_PREVIOUSLY_NOTABLE.getTypeID() )); 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_OTHER_CASES); private static final Set CR_DEVICE_TYPE_IDS = new HashSet<>(Arrays.asList( ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID(), @@ -115,7 +117,6 @@ public class PastCasesSummary implements DefaultArtifactUpdateGovernor { )); private static final String CASE_SEPARATOR = ","; - private static final String PREFIX_END = ":"; private final SleuthkitCaseProvider caseProvider; private final java.util.logging.Logger logger; @@ -172,9 +173,8 @@ public class PastCasesSummary implements DefaultArtifactUpdateGovernor { } /** - * Gets a list of cases from the TSK_COMMENT of an artifact. The cases - * string is expected to be of a form of "Previous Case: - * case1,case2...caseN". + * Gets a list of cases from the TSK_OTHER_CASES of an artifact. The cases + * string is expected to be of a form of "case1,case2...caseN". * * @param artifact The artifact. * @@ -200,14 +200,7 @@ public class PastCasesSummary implements DefaultArtifactUpdateGovernor { return Collections.emptyList(); } - String commentStr = commentAttr.getValueString(); - - int prefixCharIdx = commentStr.indexOf(PREFIX_END); - if (prefixCharIdx < 0 || prefixCharIdx >= commentStr.length() - 1) { - return Collections.emptyList(); - } - - String justCasesStr = commentStr.substring(prefixCharIdx + 1).trim(); + String justCasesStr = commentAttr.getValueString().trim(); return Stream.of(justCasesStr.split(CASE_SEPARATOR)) .map(String::trim) .collect(Collectors.toList()); @@ -242,9 +235,9 @@ public class PastCasesSummary implements DefaultArtifactUpdateGovernor { } /** - * Given a TSK_PREVIOUSLY_SEEN artifact, retrieves it's parent artifact. + * Given a TSK_PREVIOUSLY_SEEN or TSK_PREVIOUSLY_NOTABLE artifact, retrieves it's parent artifact. * - * @param artifact The input TSK_PREVIOUSLY_SEEN artifact. + * @param artifact The input artifact. * * @return The artifact if found or null if not. * @@ -316,6 +309,19 @@ public class PastCasesSummary implements DefaultArtifactUpdateGovernor { } } + for (BlackboardArtifact artifact : skCase.getBlackboard().getArtifacts(ARTIFACT_TYPE.TSK_PREVIOUSLY_NOTABLE.getTypeID(), dataSource.getId())) { + List cases = getCasesFromArtifact(artifact); + if (cases == null || cases.isEmpty()) { + continue; + } + + if (hasDeviceAssociatedArtifact(artifact)) { + deviceArtifactCases.addAll(cases); + } else { + nonDeviceArtifactCases.addAll(cases); + } + } + return new PastCasesResult( getCaseCounts(deviceArtifactCases.stream()), getCaseCounts(nonDeviceArtifactCases.stream()) From c6531498d54eec503304e7d2e7d2105c65e93243 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Thu, 29 Jul 2021 16:11:15 -0400 Subject: [PATCH 21/64] Added communication accounts to the list of artifacts flagged for previously seen --- .../eventlisteners/IngestEventsListener.java | 6 ++++-- .../datamodel/PastCasesSummary.java | 21 +++++++++---------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java index 54bb73455d..a346c1ac1a 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java @@ -541,13 +541,15 @@ public class IngestEventsListener { } } - // flag previously seen devices + // flag previously seen devices and communication accounts (emails, phones, etc) if (flagPreviousItemsEnabled && (eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.USBID_TYPE_ID || eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.ICCID_TYPE_ID || eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.IMEI_TYPE_ID || eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.IMSI_TYPE_ID - || eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.MAC_TYPE_ID)) { + || eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.MAC_TYPE_ID + || eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.EMAIL_TYPE_ID + || eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.PHONE_TYPE_ID)) { try { // only alert to previous instances when they were in another case List previousOccurences = dbManager.getArtifactInstancesByTypeValue(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/PastCasesSummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/PastCasesSummary.java index e28dbe7dc1..3f02a0bc2d 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/PastCasesSummary.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/PastCasesSummary.java @@ -37,33 +37,32 @@ import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; -import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_OTHER_CASES; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; /** - * Provides information about how a data source relates to a previous case. NOTE: - * This code is fragile and has certain expectations about how the central + * Provides information about how a data source relates to a previous case. + * NOTE: This code is fragile and has certain expectations about how the central * repository handles creating artifacts. So, if the central repository changes * ingest process, this code could break. This code expects that the central * repository ingest module: * - * a) Creates a TSK_PREVIOUSLY_NOTABLE artifact for a file whose hash is in - * the central repository as a notable file. + * a) Creates a TSK_PREVIOUSLY_NOTABLE artifact for a file whose hash is in the + * central repository as a notable file. * - * b) Creates a TSK_PREVIOUSLY_SEEN artifact for a matching id in the - * central repository. + * b) Creates a TSK_PREVIOUSLY_SEEN artifact for a matching id in the central + * repository. * - * c) The created artifact will have a TSK_COMMENT attribute attached where one - * of the sources for the attribute matches + * c) The created artifact will have a TSK_OTHER_CASES attribute attached where + * one of the sources for the attribute matches * CentralRepoIngestModuleFactory.getModuleName(). The module display name at * time of ingest will match CentralRepoIngestModuleFactory.getModuleName() as * well. * - * d) The content of that TSK_COMMENT attribute will be of the form "Previous - * Case: case1,case2...caseN" + * d) The content of that TSK_OTHER_CASES attribute will be of the form + * "case1,case2...caseN" */ public class PastCasesSummary implements DefaultArtifactUpdateGovernor { From 961c379aa7b8e961e7fed59be8c0e54f84f3a319 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Thu, 29 Jul 2021 17:02:48 -0400 Subject: [PATCH 22/64] Added checkbox to flag unique apps --- .../eventlisteners/IngestEventsListener.java | 22 +++++++++++++++++-- .../ingestmodule/Bundle.properties | 1 + .../ingestmodule/Bundle.properties-MERGED | 1 + .../ingestmodule/Bundle_ja.properties | 1 + .../ingestmodule/CentralRepoIngestModule.java | 6 +++++ .../ingestmodule/IngestSettings.java | 19 ++++++++++++++-- .../ingestmodule/IngestSettingsPanel.form | 14 ++++++++++-- .../ingestmodule/IngestSettingsPanel.java | 19 +++++++++++----- 8 files changed, 72 insertions(+), 11 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java index a346c1ac1a..f969060a94 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java @@ -78,6 +78,7 @@ public class IngestEventsListener { private static boolean flagNotableItems; private static boolean flagSeenDevices; private static boolean createCrProperties; + private static boolean flagUniqueArtifacts; private static final String INGEST_EVENT_THREAD_NAME = "Ingest-Event-Listener-%d"; private final ExecutorService jobProcessingExecutor; private final PropertyChangeListener pcl1 = new IngestModuleEventListener(); @@ -191,6 +192,24 @@ public class IngestEventsListener { public synchronized static void setFlagSeenDevices(boolean value) { flagSeenDevices = value; } + + /** + * Configure the listener to flag unique apps or not. + * + * @param value True to flag unique apps; otherwise false. + */ + public synchronized static void setFlagUniqueArtifacts(boolean value) { + flagUniqueArtifacts = value; + } + + /** + * Are unique apps being flagged? + * + * @return True if flagging unique apps; otherwise false. + */ + public synchronized static boolean isFlagUniqueArtifacts() { + return flagUniqueArtifacts; + } /** * Configure the listener to create correlation properties @@ -567,8 +586,7 @@ public class IngestEventsListener { } // flag previously unseen apps and domains - // ELTODO use new flag instead of flagPreviousItemsEnabled - if (flagPreviousItemsEnabled + if (flagUniqueArtifacts && (eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.INSTALLED_PROGS_TYPE_ID || eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.DOMAIN_TYPE_ID)) { try { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/Bundle.properties b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/Bundle.properties index 88832acd4b..156fb6b343 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/Bundle.properties @@ -2,3 +2,4 @@ IngestSettingsPanel.ingestSettingsLabel.text=Ingest Settings IngestSettingsPanel.flagTaggedNotableItemsCheckbox.text=Flag items previously tagged as notable IngestSettingsPanel.flagPreviouslySeenDevicesCheckbox.text=Flag devices and users previously seen in other cases IngestSettingsPanel.createCorrelationPropertiesCheckbox.text=Save items to the Central Repository +IngestSettingsPanel.flagUniqueAppsCheckbox.text=Flag unique apps and domains unseen in other cases diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/Bundle.properties-MERGED index c5ac5ed8db..839209f091 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/Bundle.properties-MERGED @@ -13,3 +13,4 @@ IngestSettingsPanel.ingestSettingsLabel.text=Ingest Settings IngestSettingsPanel.flagTaggedNotableItemsCheckbox.text=Flag items previously tagged as notable IngestSettingsPanel.flagPreviouslySeenDevicesCheckbox.text=Flag devices and users previously seen in other cases IngestSettingsPanel.createCorrelationPropertiesCheckbox.text=Save items to the Central Repository +IngestSettingsPanel.flagUniqueAppsCheckbox.text=Flag unique apps and domains unseen in other cases diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/Bundle_ja.properties index 1899d309b9..47b5abd4ec 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/Bundle_ja.properties @@ -13,3 +13,4 @@ IngestSettingsPanel.createCorrelationPropertiesCheckbox.text=\u30a2\u30a4\u30c6\ IngestSettingsPanel.flagPreviouslySeenDevicesCheckbox.text=\u4ee5\u524d\u306e\u30b1\u30fc\u30b9\u3067\u898b\u3089\u308c\u305f\u30c7\u30d0\u30a4\u30b9\u306b\u30d5\u30e9\u30b0\u3092\u4ed8\u3051\u308b IngestSettingsPanel.flagTaggedNotableItemsCheckbox.text=\u4ee5\u524d\u306b\u6ce8\u76ee\u3059\u3079\u304d\u30bf\u30b0\u4ed8\u3051\u305f\u30a2\u30a4\u30c6\u30e0\u306b\u30d5\u30e9\u30b0\u3092\u4ed8\u3051\u308b IngestSettingsPanel.ingestSettingsLabel.text=\u53d6\u8fbc\u307f\u8a2d\u5b9a +IngestSettingsPanel.flagUniqueAppsCheckbox.text=\u4ee5\u524d\u306e\u30b1\u30fc\u30b9\u3067\u898b\u3089\u308c\u305f\u30c7\u30d0\u30a4\u30b9\u306b\u30d5\u30e9\u30b0\u3092\u4ed8\u3051\u308b diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java index 470ee7cd82..49be6d3d6b 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java @@ -71,6 +71,7 @@ final class CentralRepoIngestModule implements FileIngestModule { private static final String MODULE_NAME = CentralRepoIngestModuleFactory.getModuleName(); static final boolean DEFAULT_FLAG_TAGGED_NOTABLE_ITEMS = false; static final boolean DEFAULT_FLAG_PREVIOUS_DEVICES = false; + static final boolean DEFAULT_FLAG_UNIQUE_DEVICES = false; static final boolean DEFAULT_CREATE_CR_PROPERTIES = true; private final static Logger logger = Logger.getLogger(CentralRepoIngestModule.class.getName()); @@ -85,6 +86,7 @@ final class CentralRepoIngestModule implements FileIngestModule { private final boolean flagPreviouslySeenDevices; private Blackboard blackboard; private final boolean createCorrelationProperties; + private final boolean flagUniqueArtifacts; /** * Instantiate the Central Repository ingest module. @@ -95,6 +97,7 @@ final class CentralRepoIngestModule implements FileIngestModule { flagTaggedNotableItems = settings.isFlagTaggedNotableItems(); flagPreviouslySeenDevices = settings.isFlagPreviousDevices(); createCorrelationProperties = settings.shouldCreateCorrelationProperties(); + flagUniqueArtifacts = settings.isFlagUniqueArtifacts(); } @Override @@ -251,6 +254,9 @@ final class CentralRepoIngestModule implements FileIngestModule { if (IngestEventsListener.getCeModuleInstanceCount() == 1 || !IngestEventsListener.shouldCreateCrProperties()) { IngestEventsListener.setCreateCrProperties(createCorrelationProperties); } + if (IngestEventsListener.getCeModuleInstanceCount() == 1 || !IngestEventsListener.isFlagUniqueArtifacts()) { + IngestEventsListener.setFlagUniqueArtifacts(flagUniqueArtifacts); + } if (CentralRepository.isEnabled() == false) { /* diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestSettings.java index 52d645bcac..e55f09882e 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestSettings.java @@ -1,7 +1,7 @@ /* * Central Repository * - * Copyright 2018 Basis Technology Corp. + * Copyright 2018-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -30,6 +30,7 @@ final class IngestSettings implements IngestModuleIngestJobSettings { private final boolean flagTaggedNotableItems; private final boolean flagPreviousDevices; private final boolean createCorrelationProperties; + private final boolean flagUniqueArtifacts; /** * Instantiate the ingest job settings with default values. @@ -38,6 +39,7 @@ final class IngestSettings implements IngestModuleIngestJobSettings { this.flagTaggedNotableItems = CentralRepoIngestModule.DEFAULT_FLAG_TAGGED_NOTABLE_ITEMS; this.flagPreviousDevices = CentralRepoIngestModule.DEFAULT_FLAG_PREVIOUS_DEVICES; this.createCorrelationProperties = CentralRepoIngestModule.DEFAULT_CREATE_CR_PROPERTIES; + this.flagUniqueArtifacts = CentralRepoIngestModule.DEFAULT_FLAG_UNIQUE_DEVICES; } /** @@ -48,11 +50,14 @@ final class IngestSettings implements IngestModuleIngestJobSettings { * the Central Repository * @param createCorrelationProperties Create correlation properties in the * central repository + * @param flagUniqueArtifacts Flag unique artifacts that have not + * been seen in any other cases */ - IngestSettings(boolean flagTaggedNotableItems, boolean flagPreviousDevices, boolean createCorrelationProperties) { + IngestSettings(boolean flagTaggedNotableItems, boolean flagPreviousDevices, boolean createCorrelationProperties, boolean flagUniqueArtifacts) { this.flagTaggedNotableItems = flagTaggedNotableItems; this.flagPreviousDevices = flagPreviousDevices; this.createCorrelationProperties = createCorrelationProperties; + this.flagUniqueArtifacts = flagUniqueArtifacts; } @Override @@ -86,4 +91,14 @@ final class IngestSettings implements IngestModuleIngestJobSettings { boolean shouldCreateCorrelationProperties() { return createCorrelationProperties; } + + /** + * Are artifacts (apps, domains) previously unseen in other cases to be + * flagged? + * + * @return True if flagging; otherwise false. + */ + public boolean isFlagUniqueArtifacts() { + return flagUniqueArtifacts; + } } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestSettingsPanel.form index b685d08432..102a2635a0 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestSettingsPanel.form @@ -26,10 +26,11 @@ + - + @@ -44,7 +45,9 @@ - + + + @@ -83,5 +86,12 @@ + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestSettingsPanel.java index 2804cf1ce7..5d54bd0f81 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestSettingsPanel.java @@ -1,7 +1,7 @@ /* * Central Repository * - * Copyright 2018 Basis Technology Corp. + * Copyright 2018-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -44,11 +44,13 @@ final class IngestSettingsPanel extends IngestModuleIngestJobSettingsPanel { flagTaggedNotableItemsCheckbox.setSelected(settings.isFlagTaggedNotableItems()); flagPreviouslySeenDevicesCheckbox.setSelected(settings.isFlagPreviousDevices()); createCorrelationPropertiesCheckbox.setSelected(settings.shouldCreateCorrelationProperties()); + flagUniqueAppsCheckbox.setSelected(settings.isFlagUniqueArtifacts()); } @Override public IngestModuleIngestJobSettings getSettings() { - return new IngestSettings(flagTaggedNotableItemsCheckbox.isSelected(), flagPreviouslySeenDevicesCheckbox.isSelected(), createCorrelationPropertiesCheckbox.isSelected()); + return new IngestSettings(flagTaggedNotableItemsCheckbox.isSelected(), flagPreviouslySeenDevicesCheckbox.isSelected(), + createCorrelationPropertiesCheckbox.isSelected(), flagUniqueAppsCheckbox.isSelected()); } /** @@ -64,6 +66,7 @@ final class IngestSettingsPanel extends IngestModuleIngestJobSettingsPanel { flagTaggedNotableItemsCheckbox = new javax.swing.JCheckBox(); flagPreviouslySeenDevicesCheckbox = new javax.swing.JCheckBox(); createCorrelationPropertiesCheckbox = new javax.swing.JCheckBox(); + flagUniqueAppsCheckbox = new javax.swing.JCheckBox(); ingestSettingsLabel.setFont(ingestSettingsLabel.getFont().deriveFont(ingestSettingsLabel.getFont().getStyle() | java.awt.Font.BOLD)); org.openide.awt.Mnemonics.setLocalizedText(ingestSettingsLabel, org.openide.util.NbBundle.getMessage(IngestSettingsPanel.class, "IngestSettingsPanel.ingestSettingsLabel.text")); // NOI18N @@ -74,6 +77,8 @@ final class IngestSettingsPanel extends IngestModuleIngestJobSettingsPanel { org.openide.awt.Mnemonics.setLocalizedText(createCorrelationPropertiesCheckbox, org.openide.util.NbBundle.getMessage(IngestSettingsPanel.class, "IngestSettingsPanel.createCorrelationPropertiesCheckbox.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(flagUniqueAppsCheckbox, org.openide.util.NbBundle.getMessage(IngestSettingsPanel.class, "IngestSettingsPanel.flagUniqueAppsCheckbox.text")); // NOI18N + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( @@ -87,8 +92,9 @@ final class IngestSettingsPanel extends IngestModuleIngestJobSettingsPanel { .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .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(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(createCorrelationPropertiesCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(flagUniqueAppsCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + .addContainerGap(16, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -101,7 +107,9 @@ final class IngestSettingsPanel extends IngestModuleIngestJobSettingsPanel { .addComponent(flagTaggedNotableItemsCheckbox) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(flagPreviouslySeenDevicesCheckbox) - .addContainerGap(47, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(flagUniqueAppsCheckbox) + .addContainerGap(24, Short.MAX_VALUE)) ); }// //GEN-END:initComponents @@ -109,6 +117,7 @@ final class IngestSettingsPanel extends IngestModuleIngestJobSettingsPanel { private javax.swing.JCheckBox createCorrelationPropertiesCheckbox; private javax.swing.JCheckBox flagPreviouslySeenDevicesCheckbox; private javax.swing.JCheckBox flagTaggedNotableItemsCheckbox; + private javax.swing.JCheckBox flagUniqueAppsCheckbox; private javax.swing.JLabel ingestSettingsLabel; // End of variables declaration//GEN-END:variables From a33a573a900f794532b963383e0e042150c605a2 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Thu, 29 Jul 2021 18:04:57 -0400 Subject: [PATCH 23/64] Fix --- .../eventlisteners/IngestEventsListener.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java index f969060a94..3150f79d2b 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java @@ -372,7 +372,8 @@ public class IngestEventsListener { boolean flagNotable = !IngestManager.getInstance().isIngestRunning() || isFlagNotableItems(); boolean flagPrevious = !IngestManager.getInstance().isIngestRunning() || isFlagSeenDevices(); boolean createAttributes = !IngestManager.getInstance().isIngestRunning() || shouldCreateCrProperties(); - jobProcessingExecutor.submit(new DataAddedTask(dbManager, evt, flagNotable, flagPrevious, createAttributes)); + boolean flagUnique = !IngestManager.getInstance().isIngestRunning() || isFlagUniqueArtifacts(); + jobProcessingExecutor.submit(new DataAddedTask(dbManager, evt, flagNotable, flagPrevious, createAttributes, flagUnique)); break; } default: @@ -512,13 +513,15 @@ public class IngestEventsListener { private final boolean flagNotableItemsEnabled; private final boolean flagPreviousItemsEnabled; private final boolean createCorrelationAttributes; + private final boolean flagUniqueItemsEnabled; - private DataAddedTask(CentralRepository db, PropertyChangeEvent evt, boolean flagNotableItemsEnabled, boolean flagPreviousItemsEnabled, boolean createCorrelationAttributes) { + private DataAddedTask(CentralRepository db, PropertyChangeEvent evt, boolean flagNotableItemsEnabled, boolean flagPreviousItemsEnabled, boolean createCorrelationAttributes, boolean flagUnique) { this.dbManager = db; this.event = evt; this.flagNotableItemsEnabled = flagNotableItemsEnabled; this.flagPreviousItemsEnabled = flagPreviousItemsEnabled; this.createCorrelationAttributes = createCorrelationAttributes; + this.flagUniqueItemsEnabled = flagUnique; } @Override @@ -586,7 +589,7 @@ public class IngestEventsListener { } // flag previously unseen apps and domains - if (flagUniqueArtifacts + if (flagUniqueItemsEnabled && (eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.INSTALLED_PROGS_TYPE_ID || eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.DOMAIN_TYPE_ID)) { try { From 7a7fe392f4cea1bdffff2e813718624d75ea43b8 Mon Sep 17 00:00:00 2001 From: apriestman Date: Fri, 30 Jul 2021 11:41:56 -0400 Subject: [PATCH 24/64] Temporary code to flag matching personas --- .../eventlisteners/IngestEventsListener.java | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java index 3150f79d2b..2b59a215b3 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java @@ -42,6 +42,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeIns import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeUtil; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; +import org.sleuthkit.autopsy.centralrepository.datamodel.PersonaAccount; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.ModuleDataEvent; @@ -56,12 +57,14 @@ import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CORRELATION_TYPE; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CORRELATION_VALUE; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_OTHER_CASES; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME; import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisEvent; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Image; import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; +import org.sleuthkit.autopsy.centralrepository.datamodel.Persona; import org.sleuthkit.datamodel.Score; /** @@ -313,7 +316,68 @@ public class IngestEventsListener { makeAndPostArtifact(BlackboardArtifact.Type.TSK_PREVIOUSLY_UNSEEN, originalArtifact, attributesForNewArtifact, "", Score.SCORE_LIKELY_NOTABLE, "This application has not been previously seen before"); } + + /** + * *TEMPORARY* Create a "matching persona" hit for an artifact with an account identifier + * associated with a persona + * + * @param originalArtifact the artifact to create the "previously unseen" item + * for + */ + static private void makeAndPostMatchingPersonaArtifact(BlackboardArtifact originalArtifact, Persona persona, CorrelationAttributeInstance.Type aType, String value) { + Collection attributesForNewArtifact = Arrays.asList( + new BlackboardAttribute( + TSK_CORRELATION_TYPE, MODULE_NAME, + aType.getDisplayName()), + new BlackboardAttribute( + TSK_CORRELATION_VALUE, MODULE_NAME, + value), + new BlackboardAttribute( + TSK_NAME, MODULE_NAME, + persona.getName())); + makeAndPostPersonaArtifact(BlackboardArtifact.Type.TSK_MATCHING_PERSONA, originalArtifact, attributesForNewArtifact, "", + Score.SCORE_LIKELY_NOTABLE, "This account is associated with a persona"); + } + + /** + * *TEMPORARY* Hack to get all the flagged personas associated with the same file to prevent + * duplicates (associate with source file not the account instance artifact). + * Make an artifact to flag the passed in content. + * + * @param originalArtifact Artifact in current case we want to flag + * @param attributesForNewArtifact Attributes to assign to the new artifact + * @param configuration The configuration to be specified for the new artifact hit + * @param score sleuthkit.datamodel.Score to be assigned to this artifact + * @param justification Justification string + */ + private static void makeAndPostPersonaArtifact(BlackboardArtifact.Type newArtifactType, BlackboardArtifact originalArtifact, Collection attributesForNewArtifact, String configuration, + Score score, String justification) { + try { + SleuthkitCase tskCase = originalArtifact.getSleuthkitCase(); + Content originalContent = originalArtifact.getParent(); // Associate artifact with file instead of artifact + Blackboard blackboard = tskCase.getBlackboard(); + // Create artifact if it doesn't already exist. + BlackboardArtifact.ARTIFACT_TYPE type = BlackboardArtifact.ARTIFACT_TYPE.fromID(newArtifactType.getTypeID()); + if (!blackboard.artifactExists(originalContent, type, attributesForNewArtifact)) { + BlackboardArtifact newArtifact = originalContent.newAnalysisResult( + newArtifactType, score, + null, configuration, justification, attributesForNewArtifact) + .getAnalysisResult(); + try { + // index the artifact for keyword search + blackboard.postArtifact(newArtifact, MODULE_NAME); + } catch (Blackboard.BlackboardException ex) { + LOGGER.log(Level.SEVERE, "Unable to index blackboard artifact " + newArtifact.getArtifactID(), ex); //NON-NLS + } + } + } catch (TskCoreException ex) { + LOGGER.log(Level.SEVERE, "Failed to create BlackboardArtifact.", ex); // NON-NLS + } catch (IllegalStateException ex) { + LOGGER.log(Level.SEVERE, "Failed to create BlackboardAttribute.", ex); // NON-NLS + } + } + /** * Make an artifact to flag the passed in artifact. * @@ -588,6 +652,22 @@ public class IngestEventsListener { } } + // *TEMPORARY* If we have a field that could be associated with a persona, check whether it is + // and make an artifact if so. Applicable types should be expanded later. + if (flagPreviousItemsEnabled && + ((eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.EMAIL_TYPE_ID) + || eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.PHONE_TYPE_ID)) { + String accountId = eamArtifact.getCorrelationValue(); + Collection personaMatches = Persona.getPersonaByAccountIdentifierLike(accountId); + for (Persona persona : personaMatches) { + for (PersonaAccount personaAccount : persona.getPersonaAccounts()) { + if (accountId.equalsIgnoreCase(personaAccount.getAccount().getIdentifier())) { + makeAndPostMatchingPersonaArtifact(bbArtifact, persona, eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); + } + } + } + } + // flag previously unseen apps and domains if (flagUniqueItemsEnabled && (eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.INSTALLED_PROGS_TYPE_ID From 0d8aa55292801aade70c09e3f7cd457b9194e3a9 Mon Sep 17 00:00:00 2001 From: apriestman Date: Fri, 30 Jul 2021 12:17:59 -0400 Subject: [PATCH 25/64] Add more attributes and reorder --- .../eventlisteners/IngestEventsListener.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java index 2b59a215b3..10d9260c9b 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java @@ -58,6 +58,7 @@ import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COR import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CORRELATION_VALUE; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_OTHER_CASES; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT; import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisEvent; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Image; @@ -326,15 +327,19 @@ public class IngestEventsListener { */ static private void makeAndPostMatchingPersonaArtifact(BlackboardArtifact originalArtifact, Persona persona, CorrelationAttributeInstance.Type aType, String value) { Collection attributesForNewArtifact = Arrays.asList( + new BlackboardAttribute( + TSK_NAME, MODULE_NAME, + persona.getName()), + new BlackboardAttribute( + TSK_COMMENT, MODULE_NAME, + persona.getComment()), new BlackboardAttribute( TSK_CORRELATION_TYPE, MODULE_NAME, aType.getDisplayName()), new BlackboardAttribute( TSK_CORRELATION_VALUE, MODULE_NAME, - value), - new BlackboardAttribute( - TSK_NAME, MODULE_NAME, - persona.getName())); + value) + ); makeAndPostPersonaArtifact(BlackboardArtifact.Type.TSK_MATCHING_PERSONA, originalArtifact, attributesForNewArtifact, "", Score.SCORE_LIKELY_NOTABLE, "This account is associated with a persona"); } From 732bb308d891c24cad661d9388c73a909d007365 Mon Sep 17 00:00:00 2001 From: apriestman Date: Wed, 4 Aug 2021 08:27:22 -0400 Subject: [PATCH 26/64] Add past cases attribute to persona artifact --- .../eventlisteners/IngestEventsListener.java | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java index 10d9260c9b..ec25890610 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java @@ -325,8 +325,10 @@ public class IngestEventsListener { * @param originalArtifact the artifact to create the "previously unseen" item * for */ - static private void makeAndPostMatchingPersonaArtifact(BlackboardArtifact originalArtifact, Persona persona, CorrelationAttributeInstance.Type aType, String value) { - Collection attributesForNewArtifact = Arrays.asList( + static private void makeAndPostMatchingPersonaArtifact(BlackboardArtifact originalArtifact, Persona persona, + List caseDisplayNames, CorrelationAttributeInstance.Type aType, String value) { + String prevCases = caseDisplayNames.stream().distinct().collect(Collectors.joining(",")); + Collection attributesForNewArtifact = Arrays.asList( new BlackboardAttribute( TSK_NAME, MODULE_NAME, persona.getName()), @@ -338,7 +340,10 @@ public class IngestEventsListener { aType.getDisplayName()), new BlackboardAttribute( TSK_CORRELATION_VALUE, MODULE_NAME, - value) + value), + new BlackboardAttribute( + TSK_OTHER_CASES, MODULE_NAME, + prevCases) ); makeAndPostPersonaArtifact(BlackboardArtifact.Type.TSK_MATCHING_PERSONA, originalArtifact, attributesForNewArtifact, "", Score.SCORE_LIKELY_NOTABLE, "This account is associated with a persona"); @@ -665,11 +670,17 @@ public class IngestEventsListener { String accountId = eamArtifact.getCorrelationValue(); Collection personaMatches = Persona.getPersonaByAccountIdentifierLike(accountId); for (Persona persona : personaMatches) { + // Make sure at least one account is an exact match. + boolean foundExactMatch = false; for (PersonaAccount personaAccount : persona.getPersonaAccounts()) { if (accountId.equalsIgnoreCase(personaAccount.getAccount().getIdentifier())) { - makeAndPostMatchingPersonaArtifact(bbArtifact, persona, eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); + foundExactMatch = true; } } + if (foundExactMatch) { + List caseDisplayNames = persona.getCases().stream().map(p -> p.getDisplayName()).collect(Collectors.toList()); + makeAndPostMatchingPersonaArtifact(bbArtifact, persona, caseDisplayNames, eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); + } } } From 67a908faa76c48849452ddf2c74e3559ea40b2fc Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Tue, 17 Aug 2021 14:58:17 -0400 Subject: [PATCH 27/64] Optimized CR queries --- .../eventlisteners/IngestEventsListener.java | 112 +++++++++++------- 1 file changed, 70 insertions(+), 42 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java index ec25890610..3a667cbe41 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java @@ -67,6 +67,7 @@ import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.centralrepository.datamodel.Persona; import org.sleuthkit.datamodel.Score; +import org.sleuthkit.datamodel.TskData; /** * Listen for ingest events and update entries in the Central Repository @@ -617,23 +618,40 @@ public class IngestEventsListener { try { // Only do something with this artifact if it's unique within the job if (recentlyAddedCeArtifacts.add(eamArtifact.toString())) { + + // Get a list of instances for a given value (hash, email, etc.) + List previousOccurences = new ArrayList<>(); + // check if we are flagging things + if (flagNotableItemsEnabled || flagPreviousItemsEnabled || flagUniqueItemsEnabled) { + try { + previousOccurences = dbManager.getArtifactInstancesByTypeValue(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); + + // ELTODO do we need this? + // make sure the previous instances do not contain current case + for (Iterator 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(); + } + } + } catch (CorrelationAttributeNormalizationException ex) { + LOGGER.log(Level.INFO, String.format("Unable to flag previously seen device: %s.", eamArtifact.toString()), ex); + } + } + // Was it previously marked as 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, // create TSK_PREVIOUSLY_SEEN artifact on BB. if (flagNotableItemsEnabled) { - List caseDisplayNames; - try { - caseDisplayNames = dbManager.getListCasesHavingArtifactInstancesKnownBad(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); - if (!caseDisplayNames.isEmpty()) { - makeAndPostPreviousNotableArtifact(bbArtifact, - caseDisplayNames, eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); - - // if we have marked this artifact as notable, then skip the analysis of whether it was previously seen - continue; - } - } catch (CorrelationAttributeNormalizationException ex) { - LOGGER.log(Level.INFO, String.format("Unable to flag notable item: %s.", eamArtifact.toString()), ex); + List caseDisplayNames = getCaseDisplayNamesForNotable(previousOccurences); + if (!caseDisplayNames.isEmpty()) { + makeAndPostPreviousNotableArtifact(bbArtifact, + caseDisplayNames, eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); + + // if we have marked this artifact as notable, then skip the analysis of whether it was previously seen + continue; } } @@ -646,20 +664,10 @@ public class IngestEventsListener { || eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.MAC_TYPE_ID || eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.EMAIL_TYPE_ID || eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.PHONE_TYPE_ID)) { - try { - // only alert to previous instances when they were in another case - List previousOccurences = dbManager.getArtifactInstancesByTypeValue(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); - List caseDisplayNames; - for (CorrelationAttributeInstance instance : previousOccurences) { - if (!instance.getCorrelationCase().getCaseUUID().equals(eamArtifact.getCorrelationCase().getCaseUUID())) { - caseDisplayNames = dbManager.getListCasesHavingArtifactInstances(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); - makeAndPostPreviousSeenArtifact(bbArtifact, caseDisplayNames, eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); - break; - } - } - } catch (CorrelationAttributeNormalizationException ex) { - LOGGER.log(Level.INFO, String.format("Unable to flag previously seen device: %s.", eamArtifact.toString()), ex); - } + // only alert to previous instances when they were in another case + + List caseDisplayNames = getCaseDisplayNames(previousOccurences); + makeAndPostPreviousSeenArtifact(bbArtifact, caseDisplayNames, eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); } // *TEMPORARY* If we have a field that could be associated with a persona, check whether it is @@ -688,22 +696,10 @@ public class IngestEventsListener { if (flagUniqueItemsEnabled && (eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.INSTALLED_PROGS_TYPE_ID || eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.DOMAIN_TYPE_ID)) { - try { - List previousOccurences = dbManager.getArtifactInstancesByTypeValue(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); - // make sure the previous instances do not contain current case - for (Iterator 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, eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); - } - } catch (CorrelationAttributeNormalizationException ex) { - LOGGER.log(Level.INFO, String.format("Unable to flag previously unseen application: %s.", eamArtifact.toString()), ex); - } + + if (previousOccurences.isEmpty()) { + makeAndPostPreviouslyUnseenArtifact(bbArtifact, eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); + } } if (createCorrelationAttributes) { eamArtifacts.add(eamArtifact); @@ -725,4 +721,36 @@ public class IngestEventsListener { } // DATA_ADDED } } + + /** + * Gets case display names for a list of CorrelationAttributeInstance. + * + * @param occurences List of CorrelationAttributeInstance + * + * @return List of case display names + */ + private List getCaseDisplayNames(List occurences) { + List caseNames = new ArrayList<>(); + for (CorrelationAttributeInstance occurrence : occurences) { + caseNames.add(occurrence.getCorrelationCase().getDisplayName()); + } + return caseNames; + } + + /** + * Gets case display names for only occurrences marked as NOTABLE/BAD. + * + * @param occurences List of CorrelationAttributeInstance + * + * @return List of case display names of NOTABLE/BAD occurences + */ + private List getCaseDisplayNamesForNotable(List occurences) { + List caseNames = new ArrayList<>(); + for (CorrelationAttributeInstance occurrence : occurences) { + if (occurrence.getKnownStatus() == TskData.FileKnown.BAD) { + caseNames.add(occurrence.getCorrelationCase().getDisplayName()); + } + } + return caseNames; + } } From 2b8fcdc14bb8c57af4fb77a1b5665ff003719678 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Tue, 17 Aug 2021 15:49:40 -0400 Subject: [PATCH 28/64] Cleanup --- .../eventlisteners/IngestEventsListener.java | 32 +++++++++---------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java index 3a667cbe41..25040d3571 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java @@ -620,18 +620,17 @@ public class IngestEventsListener { if (recentlyAddedCeArtifacts.add(eamArtifact.toString())) { // Get a list of instances for a given value (hash, email, etc.) - List previousOccurences = new ArrayList<>(); + List previousOccurrences = new ArrayList<>(); // check if we are flagging things if (flagNotableItemsEnabled || flagPreviousItemsEnabled || flagUniqueItemsEnabled) { try { - previousOccurences = dbManager.getArtifactInstancesByTypeValue(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); + previousOccurrences = dbManager.getArtifactInstancesByTypeValue(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); - // ELTODO do we need this? // make sure the previous instances do not contain current case - for (Iterator iterator = previousOccurences.iterator(); iterator.hasNext();) { + for (Iterator iterator = previousOccurrences.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 + // this is the current case - remove the instace from the previousOccurrences list iterator.remove(); } } @@ -645,7 +644,7 @@ public class IngestEventsListener { // if getKnownStatus() is "Unknown" and this artifact instance was marked bad in a previous case, // create TSK_PREVIOUSLY_SEEN artifact on BB. if (flagNotableItemsEnabled) { - List caseDisplayNames = getCaseDisplayNamesForNotable(previousOccurences); + List caseDisplayNames = getCaseDisplayNamesForNotable(previousOccurrences); if (!caseDisplayNames.isEmpty()) { makeAndPostPreviousNotableArtifact(bbArtifact, caseDisplayNames, eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); @@ -664,9 +663,8 @@ public class IngestEventsListener { || eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.MAC_TYPE_ID || eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.EMAIL_TYPE_ID || eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.PHONE_TYPE_ID)) { - // only alert to previous instances when they were in another case - - List caseDisplayNames = getCaseDisplayNames(previousOccurences); + + List caseDisplayNames = getCaseDisplayNames(previousOccurrences); makeAndPostPreviousSeenArtifact(bbArtifact, caseDisplayNames, eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); } @@ -697,7 +695,7 @@ public class IngestEventsListener { && (eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.INSTALLED_PROGS_TYPE_ID || eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.DOMAIN_TYPE_ID)) { - if (previousOccurences.isEmpty()) { + if (previousOccurrences.isEmpty()) { makeAndPostPreviouslyUnseenArtifact(bbArtifact, eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); } } @@ -725,13 +723,13 @@ public class IngestEventsListener { /** * Gets case display names for a list of CorrelationAttributeInstance. * - * @param occurences List of CorrelationAttributeInstance + * @param occurrences List of CorrelationAttributeInstance * * @return List of case display names */ - private List getCaseDisplayNames(List occurences) { + private List getCaseDisplayNames(List occurrences) { List caseNames = new ArrayList<>(); - for (CorrelationAttributeInstance occurrence : occurences) { + for (CorrelationAttributeInstance occurrence : occurrences) { caseNames.add(occurrence.getCorrelationCase().getDisplayName()); } return caseNames; @@ -740,13 +738,13 @@ public class IngestEventsListener { /** * Gets case display names for only occurrences marked as NOTABLE/BAD. * - * @param occurences List of CorrelationAttributeInstance + * @param occurrences List of CorrelationAttributeInstance * - * @return List of case display names of NOTABLE/BAD occurences + * @return List of case display names of NOTABLE/BAD occurrences */ - private List getCaseDisplayNamesForNotable(List occurences) { + private List getCaseDisplayNamesForNotable(List occurrences) { List caseNames = new ArrayList<>(); - for (CorrelationAttributeInstance occurrence : occurences) { + for (CorrelationAttributeInstance occurrence : occurrences) { if (occurrence.getKnownStatus() == TskData.FileKnown.BAD) { caseNames.add(occurrence.getCorrelationCase().getDisplayName()); } From f5963d77f943279787736eeb85b617bf4e40a5d0 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Thu, 19 Aug 2021 17:33:08 -0400 Subject: [PATCH 29/64] Optimized CR code to perform fewer DB queries --- .../datamodel/CorrelationAttributeUtil.java | 253 +++++++++++++----- 1 file changed, 182 insertions(+), 71 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index 61f58628fd..317bb91f4c 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -110,7 +110,7 @@ public class CorrelationAttributeUtil { * @param artifact An artifact. * * @return A list, possibly empty, of correlation attribute instances for - * the artifact. + * the artifact. */ public static List makeCorrAttrsToSave(BlackboardArtifact artifact) { if (SOURCE_TYPES_FOR_CR_INSERT.contains(artifact.getArtifactTypeID())) { @@ -145,68 +145,96 @@ public class CorrelationAttributeUtil { * @param artifact An artifact. * * @return A list, possibly empty, of correlation attribute instances for - * the artifact. + * the artifact. */ public static List makeCorrAttrsForCorrelation(BlackboardArtifact artifact) { List correlationAttrs = new ArrayList<>(); try { BlackboardArtifact sourceArtifact = getCorrAttrSourceArtifact(artifact); if (sourceArtifact != null) { + + List attributes = sourceArtifact.getAttributes(); + int artifactTypeID = sourceArtifact.getArtifactTypeID(); if (artifactTypeID == ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) { - BlackboardAttribute setNameAttr = sourceArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME)); + BlackboardAttribute setNameAttr = getAttribute(attributes, new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME)); if (setNameAttr != null && CorrelationAttributeUtil.getEmailAddressAttrDisplayName().equals(setNameAttr.getValueString())) { - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD, CorrelationAttributeInstance.EMAIL_TYPE_ID); + makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD, CorrelationAttributeInstance.EMAIL_TYPE_ID, attributes); } } else if (DOMAIN_ARTIFACT_TYPE_IDS.contains(artifactTypeID)) { - BlackboardAttribute domainAttr = sourceArtifact.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DOMAIN)); + BlackboardAttribute domainAttr = getAttribute(attributes, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DOMAIN)); if ((domainAttr != null) && !domainsToSkip.contains(domainAttr.getValueString())) { - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN, CorrelationAttributeInstance.DOMAIN_TYPE_ID); + makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN, CorrelationAttributeInstance.DOMAIN_TYPE_ID, attributes); } } else if (artifactTypeID == ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID()) { - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_ID, CorrelationAttributeInstance.USBID_TYPE_ID); - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MAC_ADDRESS, CorrelationAttributeInstance.MAC_TYPE_ID); + // prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times + Case currentCase = Case.getCurrentCaseThrows(); + Content sourceContent = currentCase.getSleuthkitCase().getContentById(artifact.getObjectID()); + Content dataSource = sourceContent.getDataSource(); + makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_ID, CorrelationAttributeInstance.USBID_TYPE_ID, + attributes, sourceContent, dataSource); + makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MAC_ADDRESS, CorrelationAttributeInstance.MAC_TYPE_ID, + attributes, sourceContent, dataSource); } else if (artifactTypeID == ARTIFACT_TYPE.TSK_WIFI_NETWORK.getTypeID()) { - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SSID, CorrelationAttributeInstance.SSID_TYPE_ID); + makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SSID, CorrelationAttributeInstance.SSID_TYPE_ID, attributes); } else if (artifactTypeID == ARTIFACT_TYPE.TSK_WIFI_NETWORK_ADAPTER.getTypeID() || artifactTypeID == ARTIFACT_TYPE.TSK_BLUETOOTH_PAIRING.getTypeID() || artifactTypeID == ARTIFACT_TYPE.TSK_BLUETOOTH_ADAPTER.getTypeID()) { - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MAC_ADDRESS, CorrelationAttributeInstance.MAC_TYPE_ID); + makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MAC_ADDRESS, CorrelationAttributeInstance.MAC_TYPE_ID, attributes); } else if (artifactTypeID == ARTIFACT_TYPE.TSK_DEVICE_INFO.getTypeID()) { - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IMEI, CorrelationAttributeInstance.IMEI_TYPE_ID); - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IMSI, CorrelationAttributeInstance.IMSI_TYPE_ID); - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ICCID, CorrelationAttributeInstance.ICCID_TYPE_ID); + // prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times + Case currentCase = Case.getCurrentCaseThrows(); + Content sourceContent = currentCase.getSleuthkitCase().getContentById(artifact.getObjectID()); + Content dataSource = sourceContent.getDataSource(); + makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IMEI, CorrelationAttributeInstance.IMEI_TYPE_ID, + attributes, sourceContent, dataSource); + makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IMSI, CorrelationAttributeInstance.IMSI_TYPE_ID, + attributes, sourceContent, dataSource); + makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ICCID, CorrelationAttributeInstance.ICCID_TYPE_ID, + attributes, sourceContent, dataSource); } else if (artifactTypeID == ARTIFACT_TYPE.TSK_SIM_ATTACHED.getTypeID()) { - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IMSI, CorrelationAttributeInstance.IMSI_TYPE_ID); - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ICCID, CorrelationAttributeInstance.ICCID_TYPE_ID); + // prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times + Case currentCase = Case.getCurrentCaseThrows(); + Content sourceContent = currentCase.getSleuthkitCase().getContentById(artifact.getObjectID()); + Content dataSource = sourceContent.getDataSource(); + makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IMSI, CorrelationAttributeInstance.IMSI_TYPE_ID, + attributes, sourceContent, dataSource); + makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ICCID, CorrelationAttributeInstance.ICCID_TYPE_ID, + attributes, sourceContent, dataSource); } else if (artifactTypeID == ARTIFACT_TYPE.TSK_WEB_FORM_ADDRESS.getTypeID()) { - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER, CorrelationAttributeInstance.PHONE_TYPE_ID); - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL, CorrelationAttributeInstance.EMAIL_TYPE_ID); + // prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times + Case currentCase = Case.getCurrentCaseThrows(); + Content sourceContent = currentCase.getSleuthkitCase().getContentById(artifact.getObjectID()); + Content dataSource = sourceContent.getDataSource(); + makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER, CorrelationAttributeInstance.PHONE_TYPE_ID, + attributes, sourceContent, dataSource); + makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL, CorrelationAttributeInstance.EMAIL_TYPE_ID, + attributes, sourceContent, dataSource); } else if (artifactTypeID == ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()) { makeCorrAttrFromAcctArtifact(correlationAttrs, sourceArtifact); } else if (artifactTypeID == ARTIFACT_TYPE.TSK_INSTALLED_PROG.getTypeID()) { - BlackboardAttribute setNameAttr = sourceArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH)); + BlackboardAttribute setNameAttr = getAttribute(attributes, new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH)); String pathAttrString = 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, attributes); } 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, attributes); } } else if (artifactTypeID == ARTIFACT_TYPE.TSK_CONTACT.getTypeID() || artifactTypeID == ARTIFACT_TYPE.TSK_CALLLOG.getTypeID() || artifactTypeID == ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()) { - makeCorrAttrsFromCommunicationArtifacts(correlationAttrs, sourceArtifact); + makeCorrAttrsFromCommunicationArtifacts(correlationAttrs, sourceArtifact, attributes); } } } catch (CorrelationAttributeNormalizationException ex) { @@ -227,33 +255,57 @@ public class CorrelationAttributeUtil { } return correlationAttrs; } - + + /** + * Gets a specific attribute from a list of attributes. + * + * @param attributes List of attributes + * @param attributeType Attribute type of interest + * + * @return Attribute of interest, null if not found. + * + * @throws TskCoreException + */ + private static BlackboardAttribute getAttribute(List attributes, BlackboardAttribute.Type attributeType) throws TskCoreException { + for (BlackboardAttribute attribute : attributes) { + if (attribute.getAttributeType().equals(attributeType)) { + return attribute; + } + } + return null; + } + /** * Makes a correlation attribute instance from a phone number attribute of * an artifact. * * @param corrAttrInstances Correlation attributes will be added to this. - * @param artifact An artifact with a phone number attribute. + * @param artifact An artifact with a phone number attribute. * - * @throws TskCoreException If there is an error querying the case database. - * @throws CentralRepoException If there is an error querying the central - * repository. + * @throws TskCoreException If there is an error + * querying the case + * database. + * @throws CentralRepoException If there is an error + * querying the central + * repository. * @throws CorrelationAttributeNormalizationException If there is an error - * in normalizing the attribute. + * in normalizing the + * attribute. */ - private static void makeCorrAttrsFromCommunicationArtifacts(List corrAttrInstances, BlackboardArtifact artifact) throws TskCoreException, CentralRepoException, CorrelationAttributeNormalizationException { + private static void makeCorrAttrsFromCommunicationArtifacts(List corrAttrInstances, BlackboardArtifact artifact, + List attributes) throws TskCoreException, CentralRepoException, CorrelationAttributeNormalizationException { CorrelationAttributeInstance corrAttr = null; /* * Extract the phone number from the artifact attribute. */ String value = null; - if (null != artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER))) { - value = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER)).getValueString(); - } else if (null != artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM))) { - value = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM)).getValueString(); - } else if (null != artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO))) { - value = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO)).getValueString(); + if (null != getAttribute(attributes, new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER))) { + value = getAttribute(attributes, new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER)).getValueString(); + } else if (null != getAttribute(attributes, new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM))) { + value = getAttribute(attributes, new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM)).getValueString(); + } else if (null != getAttribute(attributes, new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO))) { + value = getAttribute(attributes, new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO)).getValueString(); } /* @@ -277,11 +329,11 @@ public class CorrelationAttributeUtil { * @param artifact An artifact. * * @return The associated artifact if the input artifact is a - * "meta-artifact", otherwise the input artifact. + * "meta-artifact", otherwise the input artifact. * * @throws NoCurrentCaseException If there is no open case. - * @throws TskCoreException If there is an error querying thew case - * database. + * @throws TskCoreException If there is an error querying thew case + * database. */ private static BlackboardArtifact getCorrAttrSourceArtifact(BlackboardArtifact artifact) throws NoCurrentCaseException, TskCoreException { BlackboardArtifact sourceArtifact = null; @@ -296,7 +348,7 @@ public class CorrelationAttributeUtil { sourceArtifact = (BlackboardArtifact) content; } } - + if (sourceArtifact == null) { sourceArtifact = artifact; } @@ -312,7 +364,7 @@ public class CorrelationAttributeUtil { * repository by this method. * * @param corrAttrInstances A list of correlation attribute instances. - * @param acctArtifact An account artifact. + * @param acctArtifact An account artifact. * * @return The correlation attribute instance. */ @@ -335,7 +387,7 @@ public class CorrelationAttributeUtil { return; } CentralRepoAccountType crAccountType = optCrAccountType.get(); - + int corrTypeId = crAccountType.getCorrelationTypeId(); CorrelationAttributeInstance.Type corrType = CentralRepository.getInstance().getCorrelationTypeById(corrTypeId); @@ -360,21 +412,28 @@ public class CorrelationAttributeUtil { * artifact. The correlation attribute instance is added to an input list. * * @param corrAttrInstances A list of correlation attribute instances. - * @param artifact An artifact. - * @param artAttrType The type of the atrribute of the artifact that is to - * be made into a correlatin attribute instance. - * @param typeId The type ID for the desired correlation attribute instance. + * @param artifact An artifact. + * @param artAttrType The type of the atrribute of the artifact that + * is to be made into a correlatin attribute + * instance. + * @param typeId The type ID for the desired correlation + * attribute instance. + * @param sourceContent The source content object. + * @param dataSource The data source content object. * * @throws CentralRepoException If there is an error querying the central - * repository. - * @throws TskCoreException If there is an error querying the case database. + * repository. + * @throws TskCoreException If there is an error querying the case + * database. */ - private static void makeCorrAttrFromArtifactAttr(List corrAttrInstances, BlackboardArtifact artifact, ATTRIBUTE_TYPE artAttrType, int typeId) throws CentralRepoException, TskCoreException { - BlackboardAttribute attribute = artifact.getAttribute(new BlackboardAttribute.Type(artAttrType)); + private static void makeCorrAttrFromArtifactAttr(List corrAttrInstances, BlackboardArtifact artifact, ATTRIBUTE_TYPE artAttrType, int typeId, + List attributes, Content sourceContent, Content dataSource) throws CentralRepoException, TskCoreException { + + BlackboardAttribute attribute = getAttribute(attributes, new BlackboardAttribute.Type(artAttrType)); if (attribute != null) { String value = attribute.getValueString(); if ((null != value) && (value.isEmpty() == false)) { - CorrelationAttributeInstance inst = makeCorrAttr(artifact, CentralRepository.getInstance().getCorrelationTypeById(typeId), value); + CorrelationAttributeInstance inst = makeCorrAttr(artifact, CentralRepository.getInstance().getCorrelationTypeById(typeId), value, sourceContent, dataSource); if (inst != null) { corrAttrInstances.add(inst); } @@ -382,12 +441,35 @@ public class CorrelationAttributeUtil { } } + /** + * Makes a correlation attribute instance from a specified attribute of an + * artifact. The correlation attribute instance is added to an input list. + * + * @param corrAttrInstances A list of correlation attribute instances. + * @param artifact An artifact. + * @param artAttrType The type of the atrribute of the artifact that + * is to be made into a correlatin attribute + * instance. + * @param typeId The type ID for the desired correlation + * attribute instance. + * + * @throws CentralRepoException If there is an error querying the central + * repository. + * @throws TskCoreException If there is an error querying the case + * database. + */ + private static void makeCorrAttrFromArtifactAttr(List corrAttrInstances, BlackboardArtifact artifact, ATTRIBUTE_TYPE artAttrType, int typeId, + List attributes) throws CentralRepoException, TskCoreException { + + makeCorrAttrFromArtifactAttr(corrAttrInstances, artifact, artAttrType, typeId, attributes, null, null); + } + /** * Makes a correlation attribute instance of a given type from an artifact. * - * @param artifact The artifact. + * @param artifact The artifact. * @param correlationType the correlation attribute type. - * @param value The correlation attribute value. + * @param value The correlation attribute value. * * TODO (Jira-6088): The methods in this low-level, utility class should * throw exceptions instead of logging them. The reason for this is that the @@ -400,18 +482,47 @@ public class CorrelationAttributeUtil { * @return The correlation attribute instance or null, if an error occurred. */ private static CorrelationAttributeInstance makeCorrAttr(BlackboardArtifact artifact, CorrelationAttributeInstance.Type correlationType, String value) { + return makeCorrAttr(artifact, correlationType, value, null, null); + } + + /** + * Makes a correlation attribute instance of a given type from an artifact. + * + * @param artifact The artifact. + * @param correlationType the correlation attribute type. + * @param value The correlation attribute value. + * @param sourceContent The source content object. + * @param dataSource The data source content object. + * + * TODO (Jira-6088): The methods in this low-level, utility class should + * throw exceptions instead of logging them. The reason for this is that the + * clients of the utility class, not the utility class itself, should be in + * charge of error handling policy, per the Autopsy Coding Standard. Note + * that clients of several of these methods currently cannot determine + * whether receiving a null return value is an error or not, plus null + * checking is easy to forget, while catching exceptions is enforced. + * + * @return The correlation attribute instance or null, if an error occurred. + */ + private static CorrelationAttributeInstance makeCorrAttr(BlackboardArtifact artifact, CorrelationAttributeInstance.Type correlationType, String value, + Content sourceContent, Content dataSource) { try { - Case currentCase = Case.getCurrentCaseThrows(); - Content sourceContent = currentCase.getSleuthkitCase().getContentById(artifact.getObjectID()); + + if (sourceContent == null) { + Case currentCase = Case.getCurrentCaseThrows(); + sourceContent = currentCase.getSleuthkitCase().getContentById(artifact.getObjectID()); + } if (null == sourceContent) { - logger.log(Level.SEVERE, "Error creating artifact instance of type {0}. Failed to load content with ID: {1} associated with artifact with ID: {2}", + 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}", + + if (dataSource == null) { + dataSource = sourceContent.getDataSource(); + } + if (dataSource == 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; } @@ -422,28 +533,28 @@ public class CorrelationAttributeUtil { correlationType, value, correlationCase, - CorrelationDataSource.fromTSKDataSource(correlationCase, ds), + CorrelationDataSource.fromTSKDataSource(correlationCase, dataSource), "", "", TskData.FileKnown.UNKNOWN, sourceContent.getId()); } 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", + 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( - correlationType, - value, - correlationCase, - CorrelationDataSource.fromTSKDataSource(correlationCase, ds), - bbSourceFile.getParentPath() + bbSourceFile.getName(), - "", - TskData.FileKnown.UNKNOWN, - bbSourceFile.getId()); + correlationType, + value, + correlationCase, + CorrelationDataSource.fromTSKDataSource(correlationCase, dataSource), + bbSourceFile.getParentPath() + bbSourceFile.getName(), + "", + TskData.FileKnown.UNKNOWN, + bbSourceFile.getId()); } } catch (TskCoreException ex) { logger.log(Level.SEVERE, String.format("Error getting querying case database (%s)", artifact), ex); // NON-NLS @@ -474,7 +585,7 @@ public class CorrelationAttributeUtil { * checking is easy to forget, while catching exceptions is enforced. * * @return The correlation attribute instance or null, if no such - * correlation attribute instance was found or an error occurred. + * correlation attribute instance was found or an error occurred. */ public static CorrelationAttributeInstance getCorrAttrForFile(AbstractFile file) { From c497f2bfb3dadc056e215d83c1201d5b97cb0e26 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Thu, 19 Aug 2021 21:32:04 -0400 Subject: [PATCH 30/64] Minor --- .../datamodel/CorrelationAttributeUtil.java | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index 317bb91f4c..f823a79d83 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -169,8 +169,7 @@ public class CorrelationAttributeUtil { } } else if (artifactTypeID == ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID()) { // prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times - Case currentCase = Case.getCurrentCaseThrows(); - Content sourceContent = currentCase.getSleuthkitCase().getContentById(artifact.getObjectID()); + Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID()); Content dataSource = sourceContent.getDataSource(); makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_ID, CorrelationAttributeInstance.USBID_TYPE_ID, attributes, sourceContent, dataSource); @@ -187,8 +186,7 @@ public class CorrelationAttributeUtil { } else if (artifactTypeID == ARTIFACT_TYPE.TSK_DEVICE_INFO.getTypeID()) { // prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times - Case currentCase = Case.getCurrentCaseThrows(); - Content sourceContent = currentCase.getSleuthkitCase().getContentById(artifact.getObjectID()); + Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID()); Content dataSource = sourceContent.getDataSource(); makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IMEI, CorrelationAttributeInstance.IMEI_TYPE_ID, attributes, sourceContent, dataSource); @@ -199,8 +197,7 @@ public class CorrelationAttributeUtil { } else if (artifactTypeID == ARTIFACT_TYPE.TSK_SIM_ATTACHED.getTypeID()) { // prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times - Case currentCase = Case.getCurrentCaseThrows(); - Content sourceContent = currentCase.getSleuthkitCase().getContentById(artifact.getObjectID()); + Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID()); Content dataSource = sourceContent.getDataSource(); makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IMSI, CorrelationAttributeInstance.IMSI_TYPE_ID, attributes, sourceContent, dataSource); @@ -209,8 +206,7 @@ public class CorrelationAttributeUtil { } else if (artifactTypeID == ARTIFACT_TYPE.TSK_WEB_FORM_ADDRESS.getTypeID()) { // prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times - Case currentCase = Case.getCurrentCaseThrows(); - Content sourceContent = currentCase.getSleuthkitCase().getContentById(artifact.getObjectID()); + Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID()); Content dataSource = sourceContent.getDataSource(); makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER, CorrelationAttributeInstance.PHONE_TYPE_ID, attributes, sourceContent, dataSource); @@ -509,8 +505,7 @@ public class CorrelationAttributeUtil { try { if (sourceContent == null) { - Case currentCase = Case.getCurrentCaseThrows(); - sourceContent = currentCase.getSleuthkitCase().getContentById(artifact.getObjectID()); + sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID()); } if (null == sourceContent) { logger.log(Level.SEVERE, "Error creating artifact instance of type {0}. Failed to load content with ID: {1} associated with artifact with ID: {2}", From 853575a61ddc62f4f1645c7e141deebb341bb301 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Thu, 19 Aug 2021 22:06:51 -0400 Subject: [PATCH 31/64] Bug fixes --- .../datamodel/CorrelationAttributeUtil.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index f823a79d83..2e023f82c0 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -169,7 +169,7 @@ public class CorrelationAttributeUtil { } } else if (artifactTypeID == ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID()) { // prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times - Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID()); + Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(sourceArtifact.getObjectID()); Content dataSource = sourceContent.getDataSource(); makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_ID, CorrelationAttributeInstance.USBID_TYPE_ID, attributes, sourceContent, dataSource); @@ -186,7 +186,7 @@ public class CorrelationAttributeUtil { } else if (artifactTypeID == ARTIFACT_TYPE.TSK_DEVICE_INFO.getTypeID()) { // prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times - Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID()); + Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(sourceArtifact.getObjectID()); Content dataSource = sourceContent.getDataSource(); makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IMEI, CorrelationAttributeInstance.IMEI_TYPE_ID, attributes, sourceContent, dataSource); @@ -197,7 +197,7 @@ public class CorrelationAttributeUtil { } else if (artifactTypeID == ARTIFACT_TYPE.TSK_SIM_ATTACHED.getTypeID()) { // prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times - Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID()); + Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(sourceArtifact.getObjectID()); Content dataSource = sourceContent.getDataSource(); makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IMSI, CorrelationAttributeInstance.IMSI_TYPE_ID, attributes, sourceContent, dataSource); @@ -206,7 +206,7 @@ public class CorrelationAttributeUtil { } else if (artifactTypeID == ARTIFACT_TYPE.TSK_WEB_FORM_ADDRESS.getTypeID()) { // prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times - Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID()); + Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(sourceArtifact.getObjectID()); Content dataSource = sourceContent.getDataSource(); makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER, CorrelationAttributeInstance.PHONE_TYPE_ID, attributes, sourceContent, dataSource); @@ -338,7 +338,9 @@ public class CorrelationAttributeUtil { if (assocArtifactAttr != null) { sourceArtifact = Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboardArtifact(assocArtifactAttr.getValueLong()); } - } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_PREVIOUSLY_SEEN.getTypeID() == artifact.getArtifactTypeID()) { + } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_PREVIOUSLY_SEEN.getTypeID() == artifact.getArtifactTypeID() + || BlackboardArtifact.ARTIFACT_TYPE.TSK_PREVIOUSLY_NOTABLE.getTypeID() == artifact.getArtifactTypeID() + || BlackboardArtifact.ARTIFACT_TYPE.TSK_PREVIOUSLY_UNSEEN.getTypeID() == artifact.getArtifactTypeID()) { Content content = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID()); if (content instanceof DataArtifact) { sourceArtifact = (BlackboardArtifact) content; From db1f0e020df05fb7cd27f1c5420e5b6d7bd404e8 Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Fri, 27 Aug 2021 02:12:17 -0400 Subject: [PATCH 32/64] Parse unicode characters in shellbags Parse Unicode characters in shellbags --- .../recentactivity/ShellBagParser.java | 6 +++-- thirdparty/rr-full/plugins/shellbags.pl | 24 +++++++++++++------ thirdparty/rr-full/plugins/shellbags_test.pl | 17 ++++++++++--- thirdparty/rr-full/plugins/shellbags_xp.pl | 17 ++++++++++--- thirdparty/rr-full/shellitems.pl | 17 ++++++++++--- 5 files changed, 63 insertions(+), 18 deletions(-) diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ShellBagParser.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ShellBagParser.java index 9d36233407..85c13c6a1d 100755 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ShellBagParser.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ShellBagParser.java @@ -22,10 +22,12 @@ package org.sleuthkit.autopsy.recentactivity; import java.io.BufferedReader; -import java.io.FileReader; import java.io.File; +import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -63,7 +65,7 @@ class ShellBagParser { ShellBagParser sbparser = new ShellBagParser(); - try (BufferedReader reader = new BufferedReader(new FileReader(regfile))) { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(regfile), StandardCharsets.UTF_8))) { String line = reader.readLine(); while (line != null) { line = line.trim(); diff --git a/thirdparty/rr-full/plugins/shellbags.pl b/thirdparty/rr-full/plugins/shellbags.pl index f4400cb4f0..de5009a494 100644 --- a/thirdparty/rr-full/plugins/shellbags.pl +++ b/thirdparty/rr-full/plugins/shellbags.pl @@ -42,6 +42,7 @@ package shellbags; use strict; use Time::Local; +use Encode::Unicode; my %config = (hive => "USRCLASS\.DAT", hivemask => 32, @@ -779,7 +780,7 @@ sub parseFolderEntry { $tag = 0; } else { - $str .= $s; + $str .= $s; $cnt++; } } @@ -799,7 +800,7 @@ sub parseFolderEntry { $tag = 0; } else { - $str .= $s; + $str .= $s; $cnt++; } } @@ -858,13 +859,12 @@ sub parseFolderEntry { my $str = substr($data,$ofs,length($data) - 30); my $longname = (split(/\00\00/,$str,2))[0]; - $longname =~ s/\00//g; if ($longname ne "") { - $item{name} = $longname; + $item{name} = _uniToAscii($longname); } else { - $item{name} = $shortname; + $item{name} = _uniToAscii($shortname); } } return %item; @@ -957,7 +957,7 @@ sub parseFolderEntry2 { $item{name} = (split(/\00\00/,$str,2))[0]; $item{name} =~ s/\13\20/\2D\00/; - $item{name} =~ s/\00//g; + $item{name} = _uniToAscii($item{name}); return %item; } @@ -1024,7 +1024,7 @@ sub shellItem0x52 { $tag = 0; } else { - $item{name} .= $d; + $item{name} .= $d; $cnt += 2; } } @@ -1119,4 +1119,14 @@ sub getNum48 { } } +#--------------------------------------------------------------------- +# _uniToAscii() +#--------------------------------------------------------------------- +sub _uniToAscii { + my $str = $_[0]; + Encode::from_to($str,'UTF-16LE','utf8'); + $str = Encode::decode_utf8($str); + return $str; +} + 1; \ No newline at end of file diff --git a/thirdparty/rr-full/plugins/shellbags_test.pl b/thirdparty/rr-full/plugins/shellbags_test.pl index 7ff3a5a4d5..aa444d2808 100644 --- a/thirdparty/rr-full/plugins/shellbags_test.pl +++ b/thirdparty/rr-full/plugins/shellbags_test.pl @@ -8,6 +8,7 @@ #----------------------------------------------------------- package shellbags_test; use strict; +use Encode::Unicode; require 'shellitems.pl'; @@ -100,7 +101,7 @@ sub traverse { my $type = unpack("C",substr($values{$v},2,1)); my $size = unpack("v",substr($values{$v},0,2)); # probe($values{$v}); - + # Need to first check to see if the parent of the item was a zip folder # and if the 'zipsubfolder' value is set to 1 if (exists ${$parent}{zipsubfolder} && ${$parent}{zipsubfolder} == 1) { @@ -411,12 +412,22 @@ sub parseFolderItem { $longname =~ s/\x00//g; if ($longname ne "") { - $item{name} = $longname; + $item{name} = _uniToAscii($longname); } else { - $item{name} = $shortname; + $item{name} = _uniToAscii($shortname); } return %item; } +#--------------------------------------------------------------------- +# _uniToAscii() +#--------------------------------------------------------------------- +sub _uniToAscii { + my $str = $_[0]; + Encode::from_to($str,'UTF-16LE','utf8'); + $str = Encode::decode_utf8($str); + return $str; +} + 1; diff --git a/thirdparty/rr-full/plugins/shellbags_xp.pl b/thirdparty/rr-full/plugins/shellbags_xp.pl index ce90cc3e7f..d503f1ab07 100644 --- a/thirdparty/rr-full/plugins/shellbags_xp.pl +++ b/thirdparty/rr-full/plugins/shellbags_xp.pl @@ -36,6 +36,7 @@ package shellbags_xp; use strict; use Time::Local; +use Encode::Unicode; my %config = (hive => "NTUSER\.DAT", hivemask => 32, @@ -779,10 +780,10 @@ sub parseFolderEntry { $longname =~ s/\x00//g; if ($longname ne "") { - $item{name} = $longname; + $item{name} = _uniToAscii($longname); } else { - $item{name} = $shortname; + $item{name} = _uniToAscii($shortname); } return %item; } @@ -871,7 +872,7 @@ sub parseFolderEntry2 { $item{name} = (split(/\x00\x00/,$str,2))[0]; $item{name} =~ s/\x13\x20/\x2D\x00/; - $item{name} =~ s/\x00//g; + $item{name} = _uniToAscii($item{name}); return %item; } @@ -931,4 +932,14 @@ sub printData { return @display; } +#--------------------------------------------------------------------- +# _uniToAscii() +#--------------------------------------------------------------------- +sub _uniToAscii { + my $str = $_[0]; + Encode::from_to($str,'UTF-16LE','utf8'); + $str = Encode::decode_utf8($str); + return $str; +} + 1; diff --git a/thirdparty/rr-full/shellitems.pl b/thirdparty/rr-full/shellitems.pl index 5ec51cd6a2..33e03759f7 100644 --- a/thirdparty/rr-full/shellitems.pl +++ b/thirdparty/rr-full/shellitems.pl @@ -27,6 +27,7 @@ # Author: H. Carvey, keydet89@yahoo.com #----------------------------------------------------------- use Time::Local; +use Encode::Unicode; my %guids = ("{bb64f8a7-bee7-4e1a-ab8d-7d8273f7fdb6}" => "Action Center", "{7a979262-40ce-46ff-aeee-7884ac3b6136}" => "Add Hardware", @@ -634,10 +635,10 @@ sub parseFolderEntry { $longname =~ s/\x00//g; if ($longname ne "") { - $item{name} = $longname; + $item{name} = _uniToAscii($longname); } else { - $item{name} = $shortname; + $item{name} = _uniToAscii($shortname); } return %item; } @@ -716,7 +717,7 @@ sub parseFolderEntry2 { $item{name} = (split(/\x00\x00/,$str,2))[0]; $item{name} =~ s/\x13\x20/\x2D\x00/; - $item{name} =~ s/\x00//g; + $item{name} = _uniToAscii($item{name}); return %item; } @@ -837,4 +838,14 @@ sub getNum48 { } } +#--------------------------------------------------------------------- +# _uniToAscii() +#--------------------------------------------------------------------- +sub _uniToAscii { + my $str = $_[0]; + Encode::from_to($str,'UTF-16LE','utf8'); + $str = Encode::decode_utf8($str); + return $str; +} + 1; From 90bda71c1d21a0b30836232bf2288d57c5328580 Mon Sep 17 00:00:00 2001 From: Brian Carrier Date: Fri, 27 Aug 2021 12:06:19 -0400 Subject: [PATCH 33/64] Initial refactor of CorrelationUtils. Not complete --- .../application/OtherOccurrences.java | 2 +- .../datamodel/CorrelationAttributeUtil.java | 285 +++++++++--------- .../eventlisteners/CaseEventListener.java | 4 +- .../application/Annotations.java | 2 +- .../autopsy/datamodel/GetSCOTask.java | 2 +- 5 files changed, 142 insertions(+), 153 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/application/OtherOccurrences.java b/Core/src/org/sleuthkit/autopsy/centralrepository/application/OtherOccurrences.java index 80e4ada388..cd11c19438 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/application/OtherOccurrences.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/application/OtherOccurrences.java @@ -116,7 +116,7 @@ public final class OtherOccurrences { // correlate on blackboard artifact attributes if they exist and supported BlackboardArtifact bbArtifact = getBlackboardArtifactFromNode(node); if (bbArtifact != null && CentralRepository.isEnabled()) { - ret.addAll(CorrelationAttributeUtil.makeCorrAttrsForCorrelation(bbArtifact)); + ret.addAll(CorrelationAttributeUtil.makeCorrAttrsForSearch(bbArtifact)); } // we can correlate based on the MD5 if it is enabled diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index 6d2ff51c01..776220d880 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.Optional; import java.util.Set; import java.util.logging.Level; +import org.openide.util.Exceptions; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; @@ -32,6 +33,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoAccount.Cent import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Account; +import org.sleuthkit.datamodel.AnalysisResult; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute; @@ -69,7 +71,7 @@ public class CorrelationAttributeUtil { * for the email address correlation attribute type. This string is * duplicated in the CorrelationAttributeInstance class. * - * TODO (Jira-6088): We should not have multiple deifnitions of this string. + * TODO (Jira-6088): We should not have multiple definitions of this string. * * @return The display name of the email address correlation attribute type. */ @@ -78,28 +80,6 @@ public class CorrelationAttributeUtil { return Bundle.CorrelationAttributeUtil_emailaddresses_text(); } - // Defines which artifact types act as the sources for CR data. - // Most notably, does not include KEYWORD HIT, CALLLOGS, MESSAGES, CONTACTS - // TSK_INTERESTING_ARTIFACT_HIT (See JIRA-6129 for more details on the - // interesting artifact hit). - // IMPORTANT: This set should be updated for new artifacts types that need to - // be inserted into the CR. - private static final Set SOURCE_TYPES_FOR_CR_INSERT = new HashSet() { - { - addAll(DOMAIN_ARTIFACT_TYPE_IDS); - - add(ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID()); - add(ARTIFACT_TYPE.TSK_WIFI_NETWORK.getTypeID()); - add(ARTIFACT_TYPE.TSK_WIFI_NETWORK_ADAPTER.getTypeID()); - add(ARTIFACT_TYPE.TSK_BLUETOOTH_PAIRING.getTypeID()); - add(ARTIFACT_TYPE.TSK_BLUETOOTH_ADAPTER.getTypeID()); - add(ARTIFACT_TYPE.TSK_DEVICE_INFO.getTypeID()); - add(ARTIFACT_TYPE.TSK_SIM_ATTACHED.getTypeID()); - add(ARTIFACT_TYPE.TSK_WEB_FORM_ADDRESS.getTypeID()); - add(ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()); - add(ARTIFACT_TYPE.TSK_INSTALLED_PROG.getTypeID()); - } - }; /** * Makes zero to many correlation attribute instances from the attributes of @@ -114,17 +94,55 @@ public class CorrelationAttributeUtil { * @return A list, possibly empty, of correlation attribute instances for * the artifact. */ - public static List makeCorrAttrsToSave(BlackboardArtifact artifact) { - if (SOURCE_TYPES_FOR_CR_INSERT.contains(artifact.getArtifactTypeID())) { - // Restrict the correlation attributes to use for saving. - // The artifacts which are suitable for saving are a subset of the - // artifacts that are suitable for correlating. - return makeCorrAttrsForCorrelation(artifact); + public static List makeCorrAttrsToSave(DataArtifact artifact) { + int artifactTypeID = artifact.getArtifactTypeID(); + // @@@ TODO Add a comment about why we do not save these. + // BC: I forget the history on these... + if (artifactTypeID == ARTIFACT_TYPE.TSK_CALLLOG.getTypeID() + || artifactTypeID == ARTIFACT_TYPE.TSK_MESSAGE.getTypeID() + || artifactTypeID == ARTIFACT_TYPE.TSK_CONTACT.getTypeID()) { + return new ArrayList<>(); } - // Return an empty collection. + + return CorrelationAttributeUtil.makeCorrAttrsForSearch(artifact); + } + + //public static List makeCorrAttrsToSave(AbstactFile file) { + // @@@ TODO Call into makeCorrAttrsForSearch(file) when API changes + // AND move logic that perhaps in the ingest module into here. + // return makeCorrAttrsForSearch(file); + //} + + public static List makeCorrAttrsToSave(Content content) { return new ArrayList<>(); } - + + public static List makeCorrAttrsForSearch(Content content) { + return new ArrayList<>(); + } + + public static List makeCorrAttrsForSearch(AnalysisResult artifact) { + try { + if (BlackboardArtifact.Type.TSK_INTERESTING_ARTIFACT_HIT.equals(artifact.getType())) { + BlackboardAttribute assocArtifactAttr = artifact.getAttribute(BlackboardAttribute.Type.TSK_ASSOCIATED_ARTIFACT); + if (assocArtifactAttr != null) { + BlackboardArtifact sourceArtifact = Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboardArtifact(assocArtifactAttr.getValueLong()); + return CorrelationAttributeUtil.makeCorrAttrsForSearch(sourceArtifact); + } + } + Content content = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID()); + + return CorrelationAttributeUtil.makeCorrAttrsForSearch(content); + // @@@ TODO ADD Error Handling + } catch (TskCoreException ex) { + Exceptions.printStackTrace(ex); + } catch (NoCurrentCaseException ex) { + Exceptions.printStackTrace(ex); + } + return new ArrayList<>(); + } + + /** * Makes zero to many correlation attribute instances from the attributes of * artifacts that have correlatable data. The intention of this method is to @@ -149,91 +167,89 @@ public class CorrelationAttributeUtil { * @return A list, possibly empty, of correlation attribute instances for * the artifact. */ - public static List makeCorrAttrsForCorrelation(BlackboardArtifact artifact) { + public static List makeCorrAttrsForSearch(DataArtifact artifact) { List correlationAttrs = new ArrayList<>(); try { - BlackboardArtifact sourceArtifact = getCorrAttrSourceArtifact(artifact); - if (sourceArtifact != null) { + + List attributes = artifact.getAttributes(); - List attributes = sourceArtifact.getAttributes(); - - int artifactTypeID = sourceArtifact.getArtifactTypeID(); - if (artifactTypeID == ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) { - BlackboardAttribute setNameAttr = getAttribute(attributes, new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME)); - if (setNameAttr != null && CorrelationAttributeUtil.getEmailAddressAttrDisplayName().equals(setNameAttr.getValueString())) { - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD, CorrelationAttributeInstance.EMAIL_TYPE_ID, attributes); - } - } else if (DOMAIN_ARTIFACT_TYPE_IDS.contains(artifactTypeID)) { - BlackboardAttribute domainAttr = getAttribute(attributes, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DOMAIN)); - if ((domainAttr != null) - && !domainsToSkip.contains(domainAttr.getValueString())) { - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN, CorrelationAttributeInstance.DOMAIN_TYPE_ID, attributes); - } - } else if (artifactTypeID == ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID()) { - // prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times - Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(sourceArtifact.getObjectID()); - Content dataSource = sourceContent.getDataSource(); - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_ID, CorrelationAttributeInstance.USBID_TYPE_ID, - attributes, sourceContent, dataSource); - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MAC_ADDRESS, CorrelationAttributeInstance.MAC_TYPE_ID, - attributes, sourceContent, dataSource); - - } else if (artifactTypeID == ARTIFACT_TYPE.TSK_WIFI_NETWORK.getTypeID()) { - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SSID, CorrelationAttributeInstance.SSID_TYPE_ID, attributes); - - } else if (artifactTypeID == ARTIFACT_TYPE.TSK_WIFI_NETWORK_ADAPTER.getTypeID() - || artifactTypeID == ARTIFACT_TYPE.TSK_BLUETOOTH_PAIRING.getTypeID() - || artifactTypeID == ARTIFACT_TYPE.TSK_BLUETOOTH_ADAPTER.getTypeID()) { - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MAC_ADDRESS, CorrelationAttributeInstance.MAC_TYPE_ID, attributes); - - } else if (artifactTypeID == ARTIFACT_TYPE.TSK_DEVICE_INFO.getTypeID()) { - // prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times - Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(sourceArtifact.getObjectID()); - Content dataSource = sourceContent.getDataSource(); - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IMEI, CorrelationAttributeInstance.IMEI_TYPE_ID, - attributes, sourceContent, dataSource); - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IMSI, CorrelationAttributeInstance.IMSI_TYPE_ID, - attributes, sourceContent, dataSource); - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ICCID, CorrelationAttributeInstance.ICCID_TYPE_ID, - attributes, sourceContent, dataSource); - - } else if (artifactTypeID == ARTIFACT_TYPE.TSK_SIM_ATTACHED.getTypeID()) { - // prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times - Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(sourceArtifact.getObjectID()); - Content dataSource = sourceContent.getDataSource(); - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IMSI, CorrelationAttributeInstance.IMSI_TYPE_ID, - attributes, sourceContent, dataSource); - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ICCID, CorrelationAttributeInstance.ICCID_TYPE_ID, - attributes, sourceContent, dataSource); - - } else if (artifactTypeID == ARTIFACT_TYPE.TSK_WEB_FORM_ADDRESS.getTypeID()) { - // prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times - Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(sourceArtifact.getObjectID()); - Content dataSource = sourceContent.getDataSource(); - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER, CorrelationAttributeInstance.PHONE_TYPE_ID, - attributes, sourceContent, dataSource); - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL, CorrelationAttributeInstance.EMAIL_TYPE_ID, - attributes, sourceContent, dataSource); - - } else if (artifactTypeID == ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()) { - makeCorrAttrFromAcctArtifact(correlationAttrs, sourceArtifact); - - } else if (artifactTypeID == ARTIFACT_TYPE.TSK_INSTALLED_PROG.getTypeID()) { - BlackboardAttribute setNameAttr = getAttribute(attributes, new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH)); - String pathAttrString = 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, attributes); - } else { - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, CorrelationAttributeInstance.INSTALLED_PROGS_TYPE_ID, attributes); - } - } else if (artifactTypeID == ARTIFACT_TYPE.TSK_CONTACT.getTypeID() - || artifactTypeID == ARTIFACT_TYPE.TSK_CALLLOG.getTypeID() - || artifactTypeID == ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()) { - makeCorrAttrsFromCommunicationArtifacts(correlationAttrs, sourceArtifact, attributes); + int artifactTypeID = artifact.getArtifactTypeID(); + //if (artifactTypeID == ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) { + // BlackboardAttribute setNameAttr = getAttribute(attributes, new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME)); + // if (setNameAttr != null && CorrelationAttributeUtil.getEmailAddressAttrDisplayName().equals(setNameAttr.getValueString())) { + // makeCorrAttrFromArtifactAttr(correlationAttrs, artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD, CorrelationAttributeInstance.EMAIL_TYPE_ID, attributes); + // } + //} else + if (DOMAIN_ARTIFACT_TYPE_IDS.contains(artifactTypeID)) { + BlackboardAttribute domainAttr = getAttribute(attributes, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DOMAIN)); + if ((domainAttr != null) + && !domainsToSkip.contains(domainAttr.getValueString())) { + makeCorrAttrFromArtifactAttr(correlationAttrs, artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN, CorrelationAttributeInstance.DOMAIN_TYPE_ID, attributes); } + } else if (artifactTypeID == ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID()) { + // prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times + Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID()); + Content dataSource = sourceContent.getDataSource(); + makeCorrAttrFromArtifactAttr(correlationAttrs, artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_ID, CorrelationAttributeInstance.USBID_TYPE_ID, + attributes, sourceContent, dataSource); + makeCorrAttrFromArtifactAttr(correlationAttrs, artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MAC_ADDRESS, CorrelationAttributeInstance.MAC_TYPE_ID, + attributes, sourceContent, dataSource); + + } else if (artifactTypeID == ARTIFACT_TYPE.TSK_WIFI_NETWORK.getTypeID()) { + makeCorrAttrFromArtifactAttr(correlationAttrs, artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SSID, CorrelationAttributeInstance.SSID_TYPE_ID, attributes); + + } else if (artifactTypeID == ARTIFACT_TYPE.TSK_WIFI_NETWORK_ADAPTER.getTypeID() + || artifactTypeID == ARTIFACT_TYPE.TSK_BLUETOOTH_PAIRING.getTypeID() + || artifactTypeID == ARTIFACT_TYPE.TSK_BLUETOOTH_ADAPTER.getTypeID()) { + makeCorrAttrFromArtifactAttr(correlationAttrs, artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MAC_ADDRESS, CorrelationAttributeInstance.MAC_TYPE_ID, attributes); + + } else if (artifactTypeID == ARTIFACT_TYPE.TSK_DEVICE_INFO.getTypeID()) { + // prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times + Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID()); + Content dataSource = sourceContent.getDataSource(); + makeCorrAttrFromArtifactAttr(correlationAttrs, artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IMEI, CorrelationAttributeInstance.IMEI_TYPE_ID, + attributes, sourceContent, dataSource); + makeCorrAttrFromArtifactAttr(correlationAttrs, artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IMSI, CorrelationAttributeInstance.IMSI_TYPE_ID, + attributes, sourceContent, dataSource); + makeCorrAttrFromArtifactAttr(correlationAttrs, artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ICCID, CorrelationAttributeInstance.ICCID_TYPE_ID, + attributes, sourceContent, dataSource); + + } else if (artifactTypeID == ARTIFACT_TYPE.TSK_SIM_ATTACHED.getTypeID()) { + // prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times + Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID()); + Content dataSource = sourceContent.getDataSource(); + makeCorrAttrFromArtifactAttr(correlationAttrs, artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IMSI, CorrelationAttributeInstance.IMSI_TYPE_ID, + attributes, sourceContent, dataSource); + makeCorrAttrFromArtifactAttr(correlationAttrs, artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ICCID, CorrelationAttributeInstance.ICCID_TYPE_ID, + attributes, sourceContent, dataSource); + + } else if (artifactTypeID == ARTIFACT_TYPE.TSK_WEB_FORM_ADDRESS.getTypeID()) { + // prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times + Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID()); + Content dataSource = sourceContent.getDataSource(); + makeCorrAttrFromArtifactAttr(correlationAttrs, artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER, CorrelationAttributeInstance.PHONE_TYPE_ID, + attributes, sourceContent, dataSource); + makeCorrAttrFromArtifactAttr(correlationAttrs, artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL, CorrelationAttributeInstance.EMAIL_TYPE_ID, + attributes, sourceContent, dataSource); + + } else if (artifactTypeID == ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()) { + makeCorrAttrFromAcctArtifact(correlationAttrs, artifact); + + } else if (artifactTypeID == ARTIFACT_TYPE.TSK_INSTALLED_PROG.getTypeID()) { + BlackboardAttribute setNameAttr = getAttribute(attributes, new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH)); + String pathAttrString = null; + if (setNameAttr != null) { + pathAttrString = setNameAttr.getValueString(); + } + if (pathAttrString != null && !pathAttrString.isEmpty()) { + makeCorrAttrFromArtifactAttr(correlationAttrs, artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH, CorrelationAttributeInstance.INSTALLED_PROGS_TYPE_ID, attributes); + } else { + makeCorrAttrFromArtifactAttr(correlationAttrs, artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, CorrelationAttributeInstance.INSTALLED_PROGS_TYPE_ID, attributes); + } + } else if (artifactTypeID == ARTIFACT_TYPE.TSK_CONTACT.getTypeID() + || artifactTypeID == ARTIFACT_TYPE.TSK_CALLLOG.getTypeID() + || artifactTypeID == ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()) { + makeCorrAttrsFromCommunicationArtifacts(correlationAttrs, artifact, attributes); } } catch (CorrelationAttributeNormalizationException ex) { logger.log(Level.WARNING, String.format("Error normalizing correlation attribute (%s)", artifact), ex); // NON-NLS @@ -320,40 +336,7 @@ public class CorrelationAttributeUtil { } } - /** - * Gets the associated artifact of a "meta-artifact" such as an "interesting - * artifact hit" or "previously seen" artifact. - * - * @param artifact An artifact. - * - * @return The associated artifact if the input artifact is a - * "meta-artifact", otherwise the input artifact. - * - * @throws NoCurrentCaseException If there is no open case. - * @throws TskCoreException If there is an error querying thew case - * database. - */ - private static BlackboardArtifact getCorrAttrSourceArtifact(BlackboardArtifact artifact) throws NoCurrentCaseException, TskCoreException { - BlackboardArtifact sourceArtifact = null; - if (BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID() == artifact.getArtifactTypeID()) { - BlackboardAttribute assocArtifactAttr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT)); - if (assocArtifactAttr != null) { - sourceArtifact = Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboardArtifact(assocArtifactAttr.getValueLong()); - } - } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_PREVIOUSLY_SEEN.getTypeID() == artifact.getArtifactTypeID() - || BlackboardArtifact.ARTIFACT_TYPE.TSK_PREVIOUSLY_NOTABLE.getTypeID() == artifact.getArtifactTypeID() - || BlackboardArtifact.ARTIFACT_TYPE.TSK_PREVIOUSLY_UNSEEN.getTypeID() == artifact.getArtifactTypeID()) { - Content content = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID()); - if (content instanceof DataArtifact) { - sourceArtifact = (BlackboardArtifact) content; - } - } - if (sourceArtifact == null) { - sourceArtifact = artifact; - } - return sourceArtifact; - } /** * Makes a correlation attribute instance for an account artifact. @@ -615,8 +598,13 @@ public class CorrelationAttributeUtil { } } + // @@@ BC: This seems like it should go into a DB-specific class because it is + // much different from the other methods in this class. It is going to the DB for data. + /** - * Gets the correlation attribute instance for a file. + * Gets the correlation attribute instance for a file. This method goes to the CR + * to get an actual instance. It does not simply package the data from file + * into a generic instance object. * * @param file The file. * @@ -694,7 +682,7 @@ public class CorrelationAttributeUtil { } /** - * Makes a correlation attribute instance for a file. + * Makes a correlation attribute instance for a file. Will include the specific object ID. * * IMPORTANT: The correlation attribute instance is NOT added to the central * repository by this method. @@ -711,7 +699,8 @@ public class CorrelationAttributeUtil { * * @return The correlation attribute instance or null, if an error occurred. */ - public static CorrelationAttributeInstance makeCorrAttrFromFile(AbstractFile file) { + // @@@ TODO: Make this look like other makeCorrAttrsForSearch and return a list + public static CorrelationAttributeInstance makeCorrAttrsForSearch(AbstractFile file) { if (!isSupportedAbstractFileType(file)) { return null; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java index 474ac1cd85..4a1f8ae2c9 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java @@ -456,7 +456,7 @@ public final class CaseEventListener implements PropertyChangeListener { * @param knownStatus The new known status. */ private void setArtifactKnownStatus(BlackboardArtifact bbArtifact, TskData.FileKnown knownStatus) { - List convertedArtifacts = CorrelationAttributeUtil.makeCorrAttrsForCorrelation(bbArtifact); + List convertedArtifacts = CorrelationAttributeUtil.makeCorrAttrsForSearch(bbArtifact); for (CorrelationAttributeInstance eamArtifact : convertedArtifacts) { try { dbManager.setAttributeInstanceKnownStatus(eamArtifact, knownStatus); @@ -528,7 +528,7 @@ public final class CaseEventListener implements PropertyChangeListener { if (!hasTagWithConflictingKnownStatus) { //Get the correlation atttributes that correspond to the current BlackboardArtifactTag if their status should be changed //with the initial set of correlation attributes this should be a single correlation attribute - List convertedArtifacts = CorrelationAttributeUtil.makeCorrAttrsForCorrelation(bbTag.getArtifact()); + List convertedArtifacts = CorrelationAttributeUtil.makeCorrAttrsForSearch(bbTag.getArtifact()); for (CorrelationAttributeInstance eamArtifact : convertedArtifacts) { CentralRepository.getInstance().setAttributeInstanceKnownStatus(eamArtifact, tagName.getKnownStatus()); } diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/application/Annotations.java b/Core/src/org/sleuthkit/autopsy/contentviewers/application/Annotations.java index 67124d1502..f2da95bba6 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/application/Annotations.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/application/Annotations.java @@ -372,7 +372,7 @@ public class Annotations { return new ArrayList<>(); } - List> lookupKeys = CorrelationAttributeUtil.makeCorrAttrsForCorrelation(artifact) + List> lookupKeys = CorrelationAttributeUtil.makeCorrAttrsForSearch(artifact) .stream() .map(cai -> Pair.of(cai.getCorrelationType(), cai.getCorrelationValue())) .collect(Collectors.toList()); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/GetSCOTask.java b/Core/src/org/sleuthkit/autopsy/datamodel/GetSCOTask.java index 5671ca6051..d7e56a11d7 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/GetSCOTask.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/GetSCOTask.java @@ -97,7 +97,7 @@ class GetSCOTask implements Runnable { logger.log(Level.WARNING, "Unable to get correlation type or value to determine value for O column for artifact", ex); } } else { - List listOfPossibleAttributes = CorrelationAttributeUtil.makeCorrAttrsForCorrelation(bbArtifact); + List listOfPossibleAttributes = CorrelationAttributeUtil.makeCorrAttrsForSearch(bbArtifact); if (listOfPossibleAttributes.size() > 1) { //Don't display anything if there is more than 1 correlation property for an artifact but let the user know description = Bundle.GetSCOTask_occurrences_multipleProperties(); From 07f39ddaa698a442768584b353ec94b6ef9a4beb Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Mon, 30 Aug 2021 13:01:17 -0400 Subject: [PATCH 34/64] Address Reviewer Comments Address Reviewer Comments --- thirdparty/rr-full/plugins/shellbags.pl | 12 ++++++------ thirdparty/rr-full/plugins/shellbags_test.pl | 14 ++------------ thirdparty/rr-full/plugins/shellbags_xp.pl | 19 ++++++------------- thirdparty/rr-full/shellitems.pl | 10 +++++----- 4 files changed, 19 insertions(+), 36 deletions(-) diff --git a/thirdparty/rr-full/plugins/shellbags.pl b/thirdparty/rr-full/plugins/shellbags.pl index de5009a494..b0e71ec299 100644 --- a/thirdparty/rr-full/plugins/shellbags.pl +++ b/thirdparty/rr-full/plugins/shellbags.pl @@ -42,7 +42,6 @@ package shellbags; use strict; use Time::Local; -use Encode::Unicode; my %config = (hive => "USRCLASS\.DAT", hivemask => 32, @@ -861,10 +860,10 @@ sub parseFolderEntry { my $longname = (split(/\00\00/,$str,2))[0]; if ($longname ne "") { - $item{name} = _uniToAscii($longname); + $item{name} = Utf16ToUtf8($longname); } else { - $item{name} = _uniToAscii($shortname); + $item{name} = UTF16ToUtf8($shortname); } } return %item; @@ -957,7 +956,7 @@ sub parseFolderEntry2 { $item{name} = (split(/\00\00/,$str,2))[0]; $item{name} =~ s/\13\20/\2D\00/; - $item{name} = _uniToAscii($item{name}); + $item{name} = Utf16ToUtf8($item{name}); return %item; } @@ -1120,13 +1119,14 @@ sub getNum48 { } #--------------------------------------------------------------------- -# _uniToAscii() +# Utf16ToUtf8() #--------------------------------------------------------------------- -sub _uniToAscii { +sub Utf16ToUtf8 { my $str = $_[0]; Encode::from_to($str,'UTF-16LE','utf8'); $str = Encode::decode_utf8($str); return $str; } + 1; \ No newline at end of file diff --git a/thirdparty/rr-full/plugins/shellbags_test.pl b/thirdparty/rr-full/plugins/shellbags_test.pl index aa444d2808..3b068ea3ac 100644 --- a/thirdparty/rr-full/plugins/shellbags_test.pl +++ b/thirdparty/rr-full/plugins/shellbags_test.pl @@ -8,7 +8,6 @@ #----------------------------------------------------------- package shellbags_test; use strict; -use Encode::Unicode; require 'shellitems.pl'; @@ -412,22 +411,13 @@ sub parseFolderItem { $longname =~ s/\x00//g; if ($longname ne "") { - $item{name} = _uniToAscii($longname); + $item{name} = Utf16ToUtf8($longname); } else { - $item{name} = _uniToAscii($shortname); + $item{name} = Utf16ToUtf8($shortname); } return %item; } -#--------------------------------------------------------------------- -# _uniToAscii() -#--------------------------------------------------------------------- -sub _uniToAscii { - my $str = $_[0]; - Encode::from_to($str,'UTF-16LE','utf8'); - $str = Encode::decode_utf8($str); - return $str; -} 1; diff --git a/thirdparty/rr-full/plugins/shellbags_xp.pl b/thirdparty/rr-full/plugins/shellbags_xp.pl index d503f1ab07..4eaea3e58d 100644 --- a/thirdparty/rr-full/plugins/shellbags_xp.pl +++ b/thirdparty/rr-full/plugins/shellbags_xp.pl @@ -36,7 +36,9 @@ package shellbags_xp; use strict; use Time::Local; -use Encode::Unicode; + +require 'shellitems.pl'; + my %config = (hive => "NTUSER\.DAT", hivemask => 32, @@ -780,10 +782,10 @@ sub parseFolderEntry { $longname =~ s/\x00//g; if ($longname ne "") { - $item{name} = _uniToAscii($longname); + $item{name} = Utf16ToUtf8($longname); } else { - $item{name} = _uniToAscii($shortname); + $item{name} = _Utf16ToUtf8($shortname); } return %item; } @@ -872,7 +874,7 @@ sub parseFolderEntry2 { $item{name} = (split(/\x00\x00/,$str,2))[0]; $item{name} =~ s/\x13\x20/\x2D\x00/; - $item{name} = _uniToAscii($item{name}); + $item{name} = Utf16ToUtf8($item{name}); return %item; } @@ -932,14 +934,5 @@ sub printData { return @display; } -#--------------------------------------------------------------------- -# _uniToAscii() -#--------------------------------------------------------------------- -sub _uniToAscii { - my $str = $_[0]; - Encode::from_to($str,'UTF-16LE','utf8'); - $str = Encode::decode_utf8($str); - return $str; -} 1; diff --git a/thirdparty/rr-full/shellitems.pl b/thirdparty/rr-full/shellitems.pl index 33e03759f7..93b71e7c20 100644 --- a/thirdparty/rr-full/shellitems.pl +++ b/thirdparty/rr-full/shellitems.pl @@ -635,10 +635,10 @@ sub parseFolderEntry { $longname =~ s/\x00//g; if ($longname ne "") { - $item{name} = _uniToAscii($longname); + $item{name} = Utf16ToUtf8($longname); } else { - $item{name} = _uniToAscii($shortname); + $item{name} = Utf16ToUtf8($shortname); } return %item; } @@ -717,7 +717,7 @@ sub parseFolderEntry2 { $item{name} = (split(/\x00\x00/,$str,2))[0]; $item{name} =~ s/\x13\x20/\x2D\x00/; - $item{name} = _uniToAscii($item{name}); + $item{name} = Utf16ToUtf8($item{name}); return %item; } @@ -839,9 +839,9 @@ sub getNum48 { } #--------------------------------------------------------------------- -# _uniToAscii() +# Utf16ToUtf8() #--------------------------------------------------------------------- -sub _uniToAscii { +sub Utf16ToUtf8 { my $str = $_[0]; Encode::from_to($str,'UTF-16LE','utf8'); $str = Encode::decode_utf8($str); From 4de91c38fc12fa6fea3223a03b2b0f77769f4f22 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Tue, 31 Aug 2021 16:21:36 -0400 Subject: [PATCH 35/64] First draft --- .../AnalysisResultsContentViewer.java | 65 ++++++++-------- .../AnalysisResultsViewModel.java | 76 +++++-------------- 2 files changed, 47 insertions(+), 94 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentViewer.java index ef623f44cf..afe9387dd2 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentViewer.java @@ -19,33 +19,28 @@ package org.sleuthkit.autopsy.contentviewers.analysisresults; import java.awt.Component; +import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.SwingWorker; import org.openide.nodes.Node; import org.openide.util.NbBundle; import org.openide.util.lookup.ServiceProvider; -import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; +import org.sleuthkit.autopsy.datamodel.TskContentItem; import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchResult; import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker; -import org.sleuthkit.datamodel.AnalysisResult; -import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.Content; -import org.sleuthkit.datamodel.TskCoreException; +import org.sleuthkit.autopsy.datamodel.AnalysisResultItem; /** - * Displays a list of analysis results as a content viewer. + * A content viewer that displays the analysis results for a Content object. */ @ServiceProvider(service = DataContentViewer.class, position = 7) public class AnalysisResultsContentViewer implements DataContentViewer { private static final Logger logger = Logger.getLogger(AnalysisResultsContentPanel.class.getName()); - - // isPreferred value private static final int PREFERRED_VALUE = 3; - private final AnalysisResultsViewModel viewModel = new AnalysisResultsViewModel(); private final AnalysisResultsContentPanel panel = new AnalysisResultsContentPanel(); @@ -87,27 +82,35 @@ public class AnalysisResultsContentViewer implements DataContentViewer { "AnalysisResultsContentViewer_setNode_loadingMessage=Loading...", "AnalysisResultsContentViewer_setNode_errorMessage=There was an error loading results.",}) public synchronized void setNode(Node node) { - // reset the panel panel.reset(); - // if there is a worker running, cancel it if (worker != null) { worker.cancel(true); worker = null; } - // if no node, nothing to do if (node == null) { return; } + TskContentItem contentItem; + AnalysisResultItem analysisResultItem = node.getLookup().lookup(AnalysisResultItem.class); + if (Objects.nonNull(analysisResultItem)) { + + } else { + TskContentItem contentItem = node.getLookup().lookup(TskContentItem.class); + + } + + + // show a loading message panel.showMessage(Bundle.AnalysisResultsContentViewer_setNode_loadingMessage()); + TskContentItem contentItem = node.getLookup().lookup(TskContentItem.class); - // create the worker + worker = new DataFetchWorker<>( - // load a view model from the node - (selectedNode) -> viewModel.getAnalysisResults(selectedNode), + (selectedNode) -> viewModel.getAnalysisResults(node.getLookup().lookup(TskContentItem.class), node.getLookup().lookup(AnalysisResultItem.class), (nodeAnalysisResults) -> { if (nodeAnalysisResults.getResultType() == DataFetchResult.ResultType.SUCCESS) { // if successful, display the results @@ -125,34 +128,26 @@ public class AnalysisResultsContentViewer implements DataContentViewer { @Override public boolean isSupported(Node node) { - if (node == null) { + if (Objects.isNull(node)) { return false; } - // There needs to either be a file with an AnalysisResult or an AnalysisResult in the lookup. - for (Content content : node.getLookup().lookupAll(Content.class)) { - if (content instanceof AnalysisResult) { - return true; - } + AnalysisResultItem analysisResultItem = node.getLookup().lookup(AnalysisResultItem.class); + if (Objects.nonNull(analysisResultItem)) { + return true; + } + + TskContentItem contentItem = node.getLookup().lookup(TskContentItem.class); + if (Objects.isNull(contentItem)) { + return false; + } - if (content == null || content instanceof BlackboardArtifact) { - continue; - } - - try { - if (Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboard().hasAnalysisResults(content.getId())) { - return true; - } - } catch (NoCurrentCaseException | TskCoreException ex) { - logger.log(Level.SEVERE, "Unable to get analysis results for file with obj id " + content.getId(), ex); - } - } - - return false; + return (contentItem.getAnalyisisResults().isEmpty() == false); } @Override public int isPreferred(Node node) { return PREFERRED_VALUE; } + } diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsViewModel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsViewModel.java index 03720e0cbe..7114d1f77b 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsViewModel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsViewModel.java @@ -30,7 +30,10 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.commons.lang3.tuple.Pair; import org.openide.nodes.Node; +import org.openide.util.Exceptions; import org.openide.util.NbBundle; +import org.sleuthkit.autopsy.datamodel.AnalysisResultItem; +import org.sleuthkit.autopsy.datamodel.TskContentItem; import org.sleuthkit.datamodel.AnalysisResult; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.Content; @@ -94,7 +97,7 @@ public class AnalysisResultsViewModel { private final List analysisResults; private final Optional selectedResult; private final Optional aggregateScore; - private final Optional content; + private final Content content; /** * Constructor. @@ -105,7 +108,7 @@ public class AnalysisResultsViewModel { * @param aggregateScore The aggregate score or empty if no score. * @param content The content associated with these results. */ - NodeResults(List analysisResults, Optional selectedResult, Optional aggregateScore, Optional content) { + NodeResults(List analysisResults, Optional selectedResult, Optional aggregateScore, Content content) { this.analysisResults = analysisResults; this.selectedResult = selectedResult; this.aggregateScore = aggregateScore; @@ -146,7 +149,7 @@ public class AnalysisResultsViewModel { * @return The content associated with these results or empty if not * present. */ - Optional getContent() { + Content getContent() { return content; } } @@ -226,6 +229,8 @@ public class AnalysisResultsViewModel { } /** + * RJCTODO + * * Returns the view model data representing the analysis results to be * displayed for the node. * @@ -233,63 +238,16 @@ public class AnalysisResultsViewModel { * * @return The analysis results view model data to display. */ - NodeResults getAnalysisResults(Node node) { - if (node == null) { - return new NodeResults(Collections.emptyList(), Optional.empty(), Optional.empty(), Optional.empty()); - } - + NodeResults getAnalysisResults(TskContentItem contentItem, Optional selectedResult) { + Content content = contentItem.getTskContent(); Optional aggregateScore = Optional.empty(); - Optional nodeContent = Optional.empty(); - // maps id of analysis result to analysis result to prevent duplication - Map allAnalysisResults = new HashMap<>(); - Optional selectedResult = Optional.empty(); - - // Find first content that is not an artifact within node - for (Content content : node.getLookup().lookupAll(Content.class)) { - if (content == null || content instanceof BlackboardArtifact) { - continue; - } - - try { - nodeContent = Optional.of(content); - - // get the aggregate score of that content - aggregateScore = Optional.ofNullable(content.getAggregateScore()); - - // and add all analysis results to mapping - content.getAllAnalysisResults().stream() - .forEach((ar) -> allAnalysisResults.put(ar.getArtifactID(), ar)); - - break; - } catch (TskCoreException ex) { - logger.log(Level.SEVERE, "Unable to get analysis results for content with obj id " + content.getId(), ex); - } + try { + aggregateScore = Optional.ofNullable(content.getAggregateScore()); + + } catch (TskCoreException ex) { + // RJCTODO: log error } - - // Find any analysis results in the node - Collection analysisResults = node.getLookup().lookupAll(AnalysisResult.class); - if (analysisResults.size() > 0) { - - // get any items with a score - List filteredResults = analysisResults.stream() - .collect(Collectors.toList()); - - // add them to the map to display - filteredResults.forEach((ar) -> allAnalysisResults.put(ar.getArtifactID(), ar)); - - // the selected result will be the highest scored analysis result in the node. - selectedResult = filteredResults.stream() - .max((a, b) -> a.getScore().compareTo(b.getScore())); - - // if no aggregate score determined at this point, use the selected result score. - if (!aggregateScore.isPresent()) { - aggregateScore = selectedResult.flatMap(selectedRes -> Optional.ofNullable(selectedRes.getScore())); - } - } - - // get view model representation - List displayAttributes = getOrderedDisplayAttributes(allAnalysisResults.values()); - - return new NodeResults(displayAttributes, selectedResult, aggregateScore, nodeContent); + List displayAttributes = getOrderedDisplayAttributes(contentItem.getAnalyisisResults());; + return new NodeResults(displayAttributes, selectedResult, aggregateScore, content); } } From 93c87cf7ceabc20108ce04370b65a1343e56226d Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Wed, 1 Sep 2021 12:37:26 -0400 Subject: [PATCH 36/64] 7861 Make analysis results content viewer work for data artifacts --- .../autopsy/datamodel/AnalysisResultItem.java | 51 +++++++++++++++++ .../autopsy/datamodel/TskContentItem.java | 56 +++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100755 Core/src/org/sleuthkit/autopsy/datamodel/AnalysisResultItem.java create mode 100755 Core/src/org/sleuthkit/autopsy/datamodel/TskContentItem.java diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AnalysisResultItem.java b/Core/src/org/sleuthkit/autopsy/datamodel/AnalysisResultItem.java new file mode 100755 index 0000000000..442d070f5c --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AnalysisResultItem.java @@ -0,0 +1,51 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2021-2021 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.datamodel; + +import com.google.common.annotations.Beta; +import org.sleuthkit.datamodel.AnalysisResult; + +/** + * An Autopsy Data Model item with an underlying analysis result Sleuth Kit Data + * Model object. + */ +public class AnalysisResultItem extends TskContentItem { + + /** + * Constructs an Autopsy Data Model item with an underlying AnalysisResult + * Sleuth Kit Data Model object. + * + * @param analysisResult The analysis result. + */ + @Beta + AnalysisResultItem(AnalysisResult analysisResult) { + super(analysisResult); + } + + /** + * Gets the underlying analysis result. + * + * @return The analysis result. + */ + @Beta + public AnalysisResult getAnalysisResult() { + return (AnalysisResult) (getTskContent()); + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/TskContentItem.java b/Core/src/org/sleuthkit/autopsy/datamodel/TskContentItem.java new file mode 100755 index 0000000000..999474cc1d --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/TskContentItem.java @@ -0,0 +1,56 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2021-2021 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.datamodel; + +import com.google.common.annotations.Beta; +import org.sleuthkit.datamodel.Content; + +/** + * An Autopsy Data Model item with an underlying Sleuth Kit Data Model object + * that implements the Sleuth Kit Data Model's Content interface. + */ +@Beta +public class TskContentItem { + + private final Content tskContent; + + /** + * Constructs an Autopsy Data Model item with an underlying Sleuth Kit Data + * Model object that implements the Sleuth Kit Data Model's Content + * interface. + * + * @param content The underlying Sleuth Kit Data Model object. + * + */ + @Beta + TskContentItem(Content sleuthKitContent) { + this.tskContent = sleuthKitContent; + } + + /** + * Gets the underlying Sleuth Kit Data Model object. + * + * @return The Sleuth Kit Data Model object. + */ + @Beta + public Content getTskContent() { + return tskContent; + } + +} From ab61ae66638a81e909e23c668e5da499ea26e870 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Wed, 1 Sep 2021 14:53:49 -0400 Subject: [PATCH 37/64] 7852 adjust makeCorrAttrsForSearch(AbstractFile) --- .../AddEditCentralRepoCommentAction.java | 9 +++- .../Bundle.properties-MERGED | 5 +- .../application/OtherOccurrences.java | 1 - .../datamodel/Bundle.properties-MERGED | 16 +++--- .../datamodel/CorrelationAttributeUtil.java | 49 ++++++++----------- .../eventlisteners/CaseEventListener.java | 25 +++++----- 6 files changed, 50 insertions(+), 55 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/AddEditCentralRepoCommentAction.java b/Core/src/org/sleuthkit/autopsy/centralrepository/AddEditCentralRepoCommentAction.java index 5f47487f94..b1069ba5b9 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/AddEditCentralRepoCommentAction.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/AddEditCentralRepoCommentAction.java @@ -19,6 +19,7 @@ package org.sleuthkit.autopsy.centralrepository; import java.awt.event.ActionEvent; +import java.util.List; import java.util.logging.Level; import javax.swing.AbstractAction; import javax.swing.Action; @@ -64,7 +65,13 @@ public final class AddEditCentralRepoCommentAction extends AbstractAction { correlationAttributeInstance = CorrelationAttributeUtil.getCorrAttrForFile(file); if (correlationAttributeInstance == null) { addToDatabase = true; - correlationAttributeInstance = CorrelationAttributeUtil.makeCorrAttrFromFile(file); + final List md5CorrelationAttr = CorrelationAttributeUtil.makeCorrAttrsForSearch(file); + if (!md5CorrelationAttr.isEmpty()) { + //for an abstract file the 'list' of attributes will be a single attribute or empty and is returning a list for consistancy with other makeCorrAttrsForSearch methods per 7852 + correlationAttributeInstance = md5CorrelationAttr.get(0); + } else { + correlationAttributeInstance = null; + } } if (file.getSize() == 0) { putValue(Action.NAME, Bundle.AddEditCentralRepoCommentAction_menuItemText_addEditCentralRepoCommentEmptyFile()); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/centralrepository/Bundle.properties-MERGED index b4f7f835ef..b2320b5408 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/Bundle.properties-MERGED @@ -5,10 +5,7 @@ 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\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. +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. CentralRepoCommentDialog.commentLabel.text=Comment: CentralRepoCommentDialog.okButton.text=&OK CentralRepoCommentDialog.cancelButton.text=C&ancel diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/application/OtherOccurrences.java b/Core/src/org/sleuthkit/autopsy/centralrepository/application/OtherOccurrences.java index cd11c19438..643f5d5de7 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/application/OtherOccurrences.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/application/OtherOccurrences.java @@ -53,7 +53,6 @@ import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifactTag; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.ContentTag; -import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.OsAccount; import org.sleuthkit.datamodel.OsAccountInstance; import org.sleuthkit.datamodel.SleuthkitCase; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Bundle.properties-MERGED index a80f1f7d86..724758847b 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Bundle.properties-MERGED @@ -18,18 +18,18 @@ CentralRepositoryService.serviceName=Central Repository Service CorrelationAttributeInstance.invalidName.message=Invalid database table name. Name must start with a lowercase letter and can only contain lowercase letters, numbers, and '_'. CorrelationAttributeInstance.nullName.message=Database name is null. CorrelationAttributeUtil.emailaddresses.text=Email Addresses -CorrelationType.DOMAIN.displayName=Domains -CorrelationType.EMAIL.displayName=Email Addresses -CorrelationType.FILES.displayName=Files +CorrelationType.DOMAIN.displayName=Domain +CorrelationType.EMAIL.displayName=Email Address +CorrelationType.FILES.displayName=File MD5 CorrelationType.ICCID.displayName=ICCID Number CorrelationType.IMEI.displayName=IMEI Number CorrelationType.IMSI.displayName=IMSI Number -CorrelationType.MAC.displayName=MAC Addresses +CorrelationType.MAC.displayName=MAC Address CorrelationType.OS_ACCOUNT.displayName=Os Account -CorrelationType.PHONE.displayName=Phone Numbers -CorrelationType.PROG_NAME.displayName=Installed Programs -CorrelationType.SSID.displayName=Wireless Networks -CorrelationType.USBID.displayName=USB Devices +CorrelationType.PHONE.displayName=Phone Number +CorrelationType.PROG_NAME.displayName=Installed Program +CorrelationType.SSID.displayName=Wireless Network +CorrelationType.USBID.displayName=USB Device EamArtifactInstances.knownStatus.bad=Bad EamArtifactInstances.knownStatus.known=Known EamArtifactInstances.knownStatus.unknown=Unknown diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index 776220d880..0ad1d8c6ee 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -80,7 +80,6 @@ public class CorrelationAttributeUtil { return Bundle.CorrelationAttributeUtil_emailaddresses_text(); } - /** * Makes zero to many correlation attribute instances from the attributes of * artifacts that have correlatable data. The intention of this method is to @@ -106,23 +105,22 @@ public class CorrelationAttributeUtil { return CorrelationAttributeUtil.makeCorrAttrsForSearch(artifact); } - + //public static List makeCorrAttrsToSave(AbstactFile file) { // @@@ TODO Call into makeCorrAttrsForSearch(file) when API changes // AND move logic that perhaps in the ingest module into here. // return makeCorrAttrsForSearch(file); //} - public static List makeCorrAttrsToSave(Content content) { return new ArrayList<>(); } - + public static List makeCorrAttrsForSearch(Content content) { return new ArrayList<>(); } - + public static List makeCorrAttrsForSearch(AnalysisResult artifact) { - try { + try { if (BlackboardArtifact.Type.TSK_INTERESTING_ARTIFACT_HIT.equals(artifact.getType())) { BlackboardAttribute assocArtifactAttr = artifact.getAttribute(BlackboardAttribute.Type.TSK_ASSOCIATED_ARTIFACT); if (assocArtifactAttr != null) { @@ -131,9 +129,9 @@ public class CorrelationAttributeUtil { } } Content content = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID()); - + return CorrelationAttributeUtil.makeCorrAttrsForSearch(content); - // @@@ TODO ADD Error Handling + // @@@ TODO ADD Error Handling } catch (TskCoreException ex) { Exceptions.printStackTrace(ex); } catch (NoCurrentCaseException ex) { @@ -141,8 +139,7 @@ public class CorrelationAttributeUtil { } return new ArrayList<>(); } - - + /** * Makes zero to many correlation attribute instances from the attributes of * artifacts that have correlatable data. The intention of this method is to @@ -170,7 +167,7 @@ public class CorrelationAttributeUtil { public static List makeCorrAttrsForSearch(DataArtifact artifact) { List correlationAttrs = new ArrayList<>(); try { - + List attributes = artifact.getAttributes(); int artifactTypeID = artifact.getArtifactTypeID(); @@ -336,8 +333,6 @@ public class CorrelationAttributeUtil { } } - - /** * Makes a correlation attribute instance for an account artifact. * @@ -600,11 +595,10 @@ public class CorrelationAttributeUtil { // @@@ BC: This seems like it should go into a DB-specific class because it is // much different from the other methods in this class. It is going to the DB for data. - /** - * Gets the correlation attribute instance for a file. This method goes to the CR - * to get an actual instance. It does not simply package the data from file - * into a generic instance object. + * Gets the correlation attribute instance for a file. This method goes to + * the CR to get an actual instance. It does not simply package the data + * from file into a generic instance object. * * @param file The file. * @@ -682,7 +676,8 @@ public class CorrelationAttributeUtil { } /** - * Makes a correlation attribute instance for a file. Will include the specific object ID. + * Makes a correlation attribute instance for a file. Will include the + * specific object ID. * * IMPORTANT: The correlation attribute instance is NOT added to the central * repository by this method. @@ -700,23 +695,23 @@ public class CorrelationAttributeUtil { * @return The correlation attribute instance or null, if an error occurred. */ // @@@ TODO: Make this look like other makeCorrAttrsForSearch and return a list - public static CorrelationAttributeInstance makeCorrAttrsForSearch(AbstractFile file) { - + public static List makeCorrAttrsForSearch(AbstractFile file) { + List fileTypeList = new ArrayList<>(); // will be an empty or single element list as was decided in 7852 if (!isSupportedAbstractFileType(file)) { - return null; + return fileTypeList; } // We need a hash to make the correlation artifact instance. String md5 = file.getMd5Hash(); if (md5 == null || md5.isEmpty() || HashUtility.isNoDataMd5(md5)) { - return null; + return fileTypeList; } try { CorrelationAttributeInstance.Type filesType = CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.FILES_TYPE_ID); CorrelationCase correlationCase = CentralRepository.getInstance().getCase(Case.getCurrentCaseThrows()); - return new CorrelationAttributeInstance( + fileTypeList.add(new CorrelationAttributeInstance( filesType, file.getMd5Hash(), correlationCase, @@ -724,21 +719,17 @@ public class CorrelationAttributeUtil { file.getParentPath() + file.getName(), "", TskData.FileKnown.UNKNOWN, - file.getId()); - + file.getId())); } catch (TskCoreException ex) { logger.log(Level.SEVERE, String.format("Error querying case database (%s)", file), ex); // NON-NLS - return null; } catch (CentralRepoException ex) { logger.log(Level.SEVERE, String.format("Error querying central repository (%s)", file), ex); // NON-NLS - return null; } catch (CorrelationAttributeNormalizationException ex) { logger.log(Level.WARNING, String.format("Error creating correlation attribute instance (%s)", file), ex); // NON-NLS - return null; } catch (NoCurrentCaseException ex) { logger.log(Level.SEVERE, "Error getting current case", ex); // NON-NLS - return null; } + return fileTypeList; } /** diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java index 4a1f8ae2c9..1f1bd3923f 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java @@ -311,18 +311,18 @@ public final class CaseEventListener implements PropertyChangeListener { * Sets the known status for the correlation attribute instance for the * given abstract file. * - * @param af The abstract file for which to set the correlation - * attribute instance. + * @param af The abstract file for which to set the correlation + * attribute instance. * @param knownStatus The new known status for the correlation attribute - * instance. + * instance. */ private void setContentKnownStatus(AbstractFile af, TskData.FileKnown knownStatus) { - final CorrelationAttributeInstance eamArtifact = CorrelationAttributeUtil.makeCorrAttrFromFile(af); - - if (eamArtifact != null) { + final List md5CorrelationAttr = CorrelationAttributeUtil.makeCorrAttrsForSearch(af); + if (!md5CorrelationAttr.isEmpty()) { + //for an abstract file the 'list' of attributes will be a single attribute or empty and is returning a list for consistancy with other makeCorrAttrsForSearch methods per 7852 // send update to Central Repository db try { - dbManager.setAttributeInstanceKnownStatus(eamArtifact, knownStatus); + dbManager.setAttributeInstanceKnownStatus(md5CorrelationAttr.get(0), knownStatus); } catch (CentralRepoException ex) { LOGGER.log(Level.SEVERE, "Error connecting to Central Repository database while setting artifact known status.", ex); //NON-NLS } @@ -407,7 +407,7 @@ public final class CaseEventListener implements PropertyChangeListener { * for the item. If there are, set known status as notable. If not set * status as unknown. * - * @param content The content for the tag that was added or deleted. + * @param content The content for the tag that was added or deleted. * @param bbArtifact The artifact for the tag that was added or deleted. */ private void handleTagChange(Content content, BlackboardArtifact bbArtifact) { @@ -452,7 +452,7 @@ public final class CaseEventListener implements PropertyChangeListener { * Sets the known status of a blackboard artifact in the central * repository. * - * @param bbArtifact The blackboard artifact to set known status. + * @param bbArtifact The blackboard artifact to set known status. * @param knownStatus The new known status. */ private void setArtifactKnownStatus(BlackboardArtifact bbArtifact, TskData.FileKnown knownStatus) { @@ -566,9 +566,10 @@ public final class CaseEventListener implements PropertyChangeListener { if (!hasTagWithConflictingKnownStatus) { Content taggedContent = contentTag.getContent(); if (taggedContent instanceof AbstractFile) { - final CorrelationAttributeInstance eamArtifact = CorrelationAttributeUtil.makeCorrAttrFromFile((AbstractFile) taggedContent); - if (eamArtifact != null) { - CentralRepository.getInstance().setAttributeInstanceKnownStatus(eamArtifact, tagName.getKnownStatus()); + final List eamArtifact = CorrelationAttributeUtil.makeCorrAttrsForSearch((AbstractFile) taggedContent); + if (!eamArtifact.isEmpty()) { + //for an abstract file the 'list' of attributes will be a single attribute or empty and is returning a list for consistancy with other makeCorrAttrsForSearch methods per 7852 + CentralRepository.getInstance().setAttributeInstanceKnownStatus(eamArtifact.get(0), tagName.getKnownStatus()); } } } From eabef9175d51462adf502991ab8888e7d178eab3 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Wed, 1 Sep 2021 16:28:11 -0400 Subject: [PATCH 38/64] 7861 Make analysis results content viewer work for data artifacts --- .../AnalysisResultsContentViewer.java | 44 +++--- .../AnalysisResultsViewModel.java | 71 +++++++--- .../datamodel/AbstractContentNode.java | 2 +- .../datamodel/BlackboardArtifactNode.java | 128 ++++++++++-------- 4 files changed, 141 insertions(+), 104 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentViewer.java index afe9387dd2..b056eb11db 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentViewer.java @@ -26,12 +26,15 @@ import javax.swing.SwingWorker; import org.openide.nodes.Node; import org.openide.util.NbBundle; import org.openide.util.lookup.ServiceProvider; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.datamodel.TskContentItem; import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchResult; import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker; import org.sleuthkit.datamodel.Content; import org.sleuthkit.autopsy.datamodel.AnalysisResultItem; +import org.sleuthkit.datamodel.TskCoreException; /** * A content viewer that displays the analysis results for a Content object. @@ -82,35 +85,27 @@ public class AnalysisResultsContentViewer implements DataContentViewer { "AnalysisResultsContentViewer_setNode_loadingMessage=Loading...", "AnalysisResultsContentViewer_setNode_errorMessage=There was an error loading results.",}) public synchronized void setNode(Node node) { + // reset the panel panel.reset(); + // if there is a worker running, cancel it if (worker != null) { worker.cancel(true); worker = null; } + // if no node, nothing to do if (node == null) { return; } - TskContentItem contentItem; - AnalysisResultItem analysisResultItem = node.getLookup().lookup(AnalysisResultItem.class); - if (Objects.nonNull(analysisResultItem)) { - - } else { - TskContentItem contentItem = node.getLookup().lookup(TskContentItem.class); - - } - - - // show a loading message panel.showMessage(Bundle.AnalysisResultsContentViewer_setNode_loadingMessage()); - TskContentItem contentItem = node.getLookup().lookup(TskContentItem.class); - + // create the worker worker = new DataFetchWorker<>( - (selectedNode) -> viewModel.getAnalysisResults(node.getLookup().lookup(TskContentItem.class), node.getLookup().lookup(AnalysisResultItem.class), + // load a view model from the node + (selectedNode) -> viewModel.getAnalysisResults(selectedNode), (nodeAnalysisResults) -> { if (nodeAnalysisResults.getResultType() == DataFetchResult.ResultType.SUCCESS) { // if successful, display the results @@ -135,14 +130,21 @@ public class AnalysisResultsContentViewer implements DataContentViewer { AnalysisResultItem analysisResultItem = node.getLookup().lookup(AnalysisResultItem.class); if (Objects.nonNull(analysisResultItem)) { return true; - } - - TskContentItem contentItem = node.getLookup().lookup(TskContentItem.class); - if (Objects.isNull(contentItem)) { - return false; - } + } - return (contentItem.getAnalyisisResults().isEmpty() == false); + TskContentItem contentItem = node.getLookup().lookup(TskContentItem.class); + if (!Objects.isNull(contentItem)) { + Content content = contentItem.getTskContent(); + try { + if (Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboard().hasAnalysisResults(content.getId())) { + return true; + } + } catch (NoCurrentCaseException | TskCoreException ex) { + logger.log(Level.SEVERE, String.format("Error getting analysis results for Content (object ID = %d)", content.getId()), ex); + } + } + + return false; } @Override diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsViewModel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsViewModel.java index 7114d1f77b..508c9966fe 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsViewModel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsViewModel.java @@ -20,9 +20,8 @@ package org.sleuthkit.autopsy.contentviewers.analysisresults; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.List; -import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.logging.Level; import java.util.logging.Logger; @@ -30,18 +29,15 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.commons.lang3.tuple.Pair; import org.openide.nodes.Node; -import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.datamodel.AnalysisResultItem; import org.sleuthkit.autopsy.datamodel.TskContentItem; import org.sleuthkit.datamodel.AnalysisResult; -import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Score; import org.sleuthkit.datamodel.TskCoreException; /** - * * Creates a representation of a list of analysis results gathered from a node. */ public class AnalysisResultsViewModel { @@ -75,7 +71,7 @@ public class AnalysisResultsViewModel { * @return The attributes to display. */ List> getAttributesToDisplay() { - return attributesToDisplay; + return Collections.unmodifiableList(attributesToDisplay); } /** @@ -97,7 +93,7 @@ public class AnalysisResultsViewModel { private final List analysisResults; private final Optional selectedResult; private final Optional aggregateScore; - private final Content content; + private final Optional content; /** * Constructor. @@ -108,7 +104,7 @@ public class AnalysisResultsViewModel { * @param aggregateScore The aggregate score or empty if no score. * @param content The content associated with these results. */ - NodeResults(List analysisResults, Optional selectedResult, Optional aggregateScore, Content content) { + NodeResults(List analysisResults, Optional selectedResult, Optional aggregateScore, Optional content) { this.analysisResults = analysisResults; this.selectedResult = selectedResult; this.aggregateScore = aggregateScore; @@ -121,7 +117,7 @@ public class AnalysisResultsViewModel { * @return The analysis results to be displayed. */ List getAnalysisResults() { - return analysisResults; + return Collections.unmodifiableList(analysisResults); } /** @@ -149,7 +145,7 @@ public class AnalysisResultsViewModel { * @return The content associated with these results or empty if not * present. */ - Content getContent() { + Optional getContent() { return content; } } @@ -229,8 +225,6 @@ public class AnalysisResultsViewModel { } /** - * RJCTODO - * * Returns the view model data representing the analysis results to be * displayed for the node. * @@ -238,16 +232,49 @@ public class AnalysisResultsViewModel { * * @return The analysis results view model data to display. */ - NodeResults getAnalysisResults(TskContentItem contentItem, Optional selectedResult) { - Content content = contentItem.getTskContent(); - Optional aggregateScore = Optional.empty(); - try { - aggregateScore = Optional.ofNullable(content.getAggregateScore()); - - } catch (TskCoreException ex) { - // RJCTODO: log error + NodeResults getAnalysisResults(Node node) { + if (node == null) { + return new NodeResults(Collections.emptyList(), Optional.empty(), Optional.empty(), Optional.empty()); } - List displayAttributes = getOrderedDisplayAttributes(contentItem.getAnalyisisResults());; - return new NodeResults(displayAttributes, selectedResult, aggregateScore, content); + + Content analyzedContent = null; + AnalysisResult selectedAnalysisResult = null; + Score aggregateScore = null; + List analysisResults = Collections.emptyList(); + long selectedObjectId = 0; + try { + AnalysisResultItem analysisResultItem = node.getLookup().lookup(AnalysisResultItem.class); + if (Objects.nonNull(analysisResultItem)) { + /* + * The content represented by the Node is an analysis result. + * Set this analysis result as the analysis result to be + * selected in the content viewer and get the analyzed content + * as the source of the analysis results to display. + */ + selectedAnalysisResult = analysisResultItem.getAnalysisResult(); + selectedObjectId = selectedAnalysisResult.getId(); + analyzedContent = selectedAnalysisResult.getParent(); + } else { + /* + * The content represented by the Node is something other than + * an analysis result. Use it as the source of the analysis + * results to display. + */ + TskContentItem contentItem = node.getLookup().lookup(TskContentItem.class); + analyzedContent = contentItem.getTskContent(); + selectedObjectId = analyzedContent.getId(); + } + aggregateScore = analyzedContent.getAggregateScore(); + analysisResults = analyzedContent.getAllAnalysisResults(); + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, String.format("Error get analysis result data for selected Content (object ID=%d)", selectedObjectId), ex); + } + + /* + * Use the data collected above to construct the view model. + */ + List displayAttributes = getOrderedDisplayAttributes(analysisResults); + return new NodeResults(displayAttributes, Optional.ofNullable(selectedAnalysisResult), Optional.ofNullable(aggregateScore), Optional.ofNullable(analyzedContent)); } + } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentNode.java index 0a43d47102..daf8cd84da 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentNode.java @@ -102,7 +102,7 @@ public abstract class AbstractContentNode extends ContentNode * @param content Underlying Content instances */ AbstractContentNode(T content) { - this(content, Lookups.singleton(content)); + this(content, Lookups.fixed(content, new TskContentItem(content))); } /** diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index e3bad44705..bf57a00caa 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -84,8 +84,8 @@ import org.sleuthkit.datamodel.BlackboardArtifact.Category; import org.sleuthkit.datamodel.Score; /** - * A BlackboardArtifactNode is an AbstractNode implementation that can be used - * to represent an artifact of any type. + * An AbstractNode implementation that can be used to represent an data artifact + * or analysis result of any type. */ public class BlackboardArtifactNode extends AbstractContentNode { @@ -219,17 +219,20 @@ public class BlackboardArtifactNode extends AbstractContentNode artifact.getSleuthkitCase().getContentById(objectID)); - if (content == null) { - return Lookups.fixed(artifact); + if (useAssociatedFile) { + content = getPathIdFile(artifact); } else { - return Lookups.fixed(artifact, content); + long srcObjectID = artifact.getObjectID(); + content = contentCache.get(srcObjectID, () -> artifact.getSleuthkitCase().getContentById(srcObjectID)); } } catch (ExecutionException ex) { - logger.log(Level.SEVERE, MessageFormat.format("Error getting source content (artifact objID={0}", artifact.getId()), ex); //NON-NLS - return Lookups.fixed(artifact); + logger.log(Level.SEVERE, MessageFormat.format("Error getting source/associated content (artifact object ID={0})", artifact.getId()), ex); //NON-NLS } - } - /** - * Creates a Lookup object for this node and populates it with both the - * artifact this node represents and its source content. - * - * @param artifact The artifact this node represents. - * @param lookupIsAssociatedFile True if the Content lookup should be made - * for the associated file instead of the - * parent file. - * - * @return The Lookup. - */ - private static Lookup createLookup(BlackboardArtifact artifact, boolean lookupIsAssociatedFile) { - Content content = null; - if (lookupIsAssociatedFile) { - try { - content = getPathIdFile(artifact); - } catch (ExecutionException ex) { - logger.log(Level.SEVERE, MessageFormat.format("Error getting source content (artifact objID={0}", artifact.getId()), ex); //NON-NLS - content = null; - } - if (content == null) { - return Lookups.fixed(artifact); - } else { - return Lookups.fixed(artifact, content); - } + /* + * Make an Autopsy Data Model wrapper for the artifact. + * + * NOTE: The creation of an Autopsy Data Model independent of the + * NetBeans nodes is a work in progress. At the time this comment is + * being written, this object is only used by the analysis content + * viewer. + */ + TskContentItem artifactItem; + if (artifact instanceof AnalysisResult) { + artifactItem = new AnalysisResultItem((AnalysisResult) artifact); } else { - return createLookup(artifact); + artifactItem = new TskContentItem(artifact); } + /* + * Create the Lookup. + */ + if (content == null) { + return Lookups.fixed(artifact, artifactItem); + } else { + return Lookups.fixed(artifact, artifactItem, content); + } } /** @@ -447,10 +455,10 @@ public class BlackboardArtifactNode extends AbstractContentNode Date: Wed, 1 Sep 2021 16:44:55 -0400 Subject: [PATCH 39/64] 7932 fix method doc for DisplayableItemNode.java --- .../src/org/sleuthkit/autopsy/datamodel/DisplayableItemNode.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNode.java index c6bc88129a..6edba5db30 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNode.java @@ -99,6 +99,7 @@ public abstract class DisplayableItemNode extends AbstractNode { * operation on this artifact type and return some object as the result of * the operation. * + * @param The return type. * @param visitor The visitor, where the type parameter of the visitor is * the type of the object that will be returned as the result * of the visit operation. From 5c205e0e5e193d7714a0259e0ca10d76e2192386 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Wed, 1 Sep 2021 16:58:59 -0400 Subject: [PATCH 40/64] 7861 Make analysis results content viewer work for data artifacts --- .../analysisresults/AnalysisResultsViewModel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsViewModel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsViewModel.java index 508c9966fe..37e4114168 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsViewModel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsViewModel.java @@ -267,7 +267,7 @@ public class AnalysisResultsViewModel { aggregateScore = analyzedContent.getAggregateScore(); analysisResults = analyzedContent.getAllAnalysisResults(); } catch (TskCoreException ex) { - logger.log(Level.SEVERE, String.format("Error get analysis result data for selected Content (object ID=%d)", selectedObjectId), ex); + logger.log(Level.SEVERE, String.format("Error getting analysis result data for selected Content (object ID=%d)", selectedObjectId), ex); } /* From 11d8d7fe9b0bd689fa2eedb506be733ce456edc5 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 2 Sep 2021 11:09:58 -0400 Subject: [PATCH 41/64] move annotations content viewer code --- .../contentviewers/Bundle.properties-MERGED | 3 - .../AnnotationUtils.java} | 74 +++++++++---------- .../AnnotationsContentViewer.form | 0 .../AnnotationsContentViewer.java | 7 +- .../annotations/Bundle.properties-MERGED | 21 ++++++ .../annotations/Bundle_ja.properties | 22 ++++++ .../application/Bundle.properties-MERGED | 18 ----- .../application/Bundle_ja.properties | 19 ----- 8 files changed, 82 insertions(+), 82 deletions(-) rename Core/src/org/sleuthkit/autopsy/contentviewers/{application/Annotations.java => annotations/AnnotationUtils.java} (90%) rename Core/src/org/sleuthkit/autopsy/contentviewers/{ => annotations}/AnnotationsContentViewer.form (100%) rename Core/src/org/sleuthkit/autopsy/contentviewers/{ => annotations}/AnnotationsContentViewer.java (95%) create mode 100755 Core/src/org/sleuthkit/autopsy/contentviewers/annotations/Bundle.properties-MERGED create mode 100644 Core/src/org/sleuthkit/autopsy/contentviewers/annotations/Bundle_ja.properties delete mode 100755 Core/src/org/sleuthkit/autopsy/contentviewers/application/Bundle.properties-MERGED delete mode 100644 Core/src/org/sleuthkit/autopsy/contentviewers/application/Bundle_ja.properties diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED index d17c1766d6..be12157474 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED @@ -15,9 +15,6 @@ # governing permissions and limitations under the License. # -AnnotationsContentViewer.onEmpty=No annotations were found for this particular item. -AnnotationsContentViewer.title=Annotations -AnnotationsContentViewer.toolTip=Displays tags and comments associated with the selected content. ApplicationContentViewer.title=Application ApplicationContentViewer.toolTip=Displays file contents. FXVideoPanel.pauseButton.infoLabel.playbackErr=Unable to play video. diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/application/Annotations.java b/Core/src/org/sleuthkit/autopsy/contentviewers/annotations/AnnotationUtils.java similarity index 90% rename from Core/src/org/sleuthkit/autopsy/contentviewers/application/Annotations.java rename to Core/src/org/sleuthkit/autopsy/contentviewers/annotations/AnnotationUtils.java index 67124d1502..77432b3ffe 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/application/Annotations.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/annotations/AnnotationUtils.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.contentviewers.application; +package org.sleuthkit.autopsy.contentviewers.annotations; import java.util.ArrayList; import java.util.Arrays; @@ -53,76 +53,76 @@ import org.sleuthkit.datamodel.TskCoreException; /** * The business logic for the Annotations content panel. */ -public class Annotations { +public class AnnotationUtils { @NbBundle.Messages({ - "Annotations.title=Annotations", - "Annotations.toolTip=Displays tags and comments associated with the selected content.", - "Annotations.centralRepositoryEntry.title=Central Repository Comments", - "Annotations.centralRepositoryEntryDataLabel.case=Case:", - "Annotations.centralRepositoryEntryDataLabel.type=Type:", - "Annotations.centralRepositoryEntryDataLabel.comment=Comment:", - "Annotations.centralRepositoryEntryDataLabel.path=Path:", - "Annotations.tagEntry.title=Tags", - "Annotations.tagEntryDataLabel.tag=Tag:", - "Annotations.tagEntryDataLabel.tagUser=Examiner:", - "Annotations.tagEntryDataLabel.comment=Comment:", - "Annotations.fileHitEntry.artifactCommentTitle=Artifact Comment", - "Annotations.fileHitEntry.hashSetHitTitle=Hash Set Hit Comments", - "Annotations.fileHitEntry.interestingFileHitTitle=Interesting File Hit Comments", - "Annotations.fileHitEntry.setName=Set Name:", - "Annotations.fileHitEntry.comment=Comment:", - "Annotations.sourceFile.title=Source File", - "Annotations.onEmpty=No annotations were found for this particular item." + "AnnotationUtils.title=Annotations", + "AnnotationUtils.toolTip=Displays tags and comments associated with the selected content.", + "AnnotationUtils.centralRepositoryEntry.title=Central Repository Comments", + "AnnotationUtils.centralRepositoryEntryDataLabel.case=Case:", + "AnnotationUtils.centralRepositoryEntryDataLabel.type=Type:", + "AnnotationUtils.centralRepositoryEntryDataLabel.comment=Comment:", + "AnnotationUtils.centralRepositoryEntryDataLabel.path=Path:", + "AnnotationUtils.tagEntry.title=Tags", + "AnnotationUtils.tagEntryDataLabel.tag=Tag:", + "AnnotationUtils.tagEntryDataLabel.tagUser=Examiner:", + "AnnotationUtils.tagEntryDataLabel.comment=Comment:", + "AnnotationUtils.fileHitEntry.artifactCommentTitle=Artifact Comment", + "AnnotationUtils.fileHitEntry.hashSetHitTitle=Hash Set Hit Comments", + "AnnotationUtils.fileHitEntry.interestingFileHitTitle=Interesting File Hit Comments", + "AnnotationUtils.fileHitEntry.setName=Set Name:", + "AnnotationUtils.fileHitEntry.comment=Comment:", + "AnnotationUtils.sourceFile.title=Source File", + "AnnotationUtils.onEmpty=No annotations were found for this particular item." }) - private static final Logger logger = Logger.getLogger(Annotations.class.getName()); + private static final Logger logger = Logger.getLogger(AnnotationUtils.class.getName()); private static final String EMPTY_HTML = ""; // describing table values for a tag private static final List> TAG_ENTRIES = Arrays.asList( - new ItemEntry<>(Bundle.Annotations_tagEntryDataLabel_tag(), + new ItemEntry<>(Bundle.AnnotationUtils_tagEntryDataLabel_tag(), (tag) -> (tag.getName() != null) ? tag.getName().getDisplayName() : null), - new ItemEntry<>(Bundle.Annotations_tagEntryDataLabel_tagUser(), (tag) -> tag.getUserName()), - new ItemEntry<>(Bundle.Annotations_tagEntryDataLabel_comment(), (tag) -> tag.getComment()) + new ItemEntry<>(Bundle.AnnotationUtils_tagEntryDataLabel_tagUser(), (tag) -> tag.getUserName()), + new ItemEntry<>(Bundle.AnnotationUtils_tagEntryDataLabel_comment(), (tag) -> tag.getComment()) ); private static final SectionConfig TAG_CONFIG - = new SectionConfig<>(Bundle.Annotations_tagEntry_title(), TAG_ENTRIES); + = new SectionConfig<>(Bundle.AnnotationUtils_tagEntry_title(), TAG_ENTRIES); // file set attributes and table configurations private static final List> FILESET_HIT_ENTRIES = Arrays.asList( - new ItemEntry<>(Bundle.Annotations_fileHitEntry_setName(), + new ItemEntry<>(Bundle.AnnotationUtils_fileHitEntry_setName(), (bba) -> tryGetAttribute(bba, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME)), - new ItemEntry<>(Bundle.Annotations_fileHitEntry_comment(), + new ItemEntry<>(Bundle.AnnotationUtils_fileHitEntry_comment(), (bba) -> tryGetAttribute(bba, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT)) ); private static final SectionConfig INTERESTING_FILE_CONFIG - = new SectionConfig<>(Bundle.Annotations_fileHitEntry_interestingFileHitTitle(), FILESET_HIT_ENTRIES); + = new SectionConfig<>(Bundle.AnnotationUtils_fileHitEntry_interestingFileHitTitle(), FILESET_HIT_ENTRIES); private static final SectionConfig HASHSET_CONFIG - = new SectionConfig<>(Bundle.Annotations_fileHitEntry_hashSetHitTitle(), FILESET_HIT_ENTRIES); + = new SectionConfig<>(Bundle.AnnotationUtils_fileHitEntry_hashSetHitTitle(), FILESET_HIT_ENTRIES); private static final SectionConfig ARTIFACT_COMMENT_CONFIG - = new SectionConfig<>(Bundle.Annotations_fileHitEntry_artifactCommentTitle(), FILESET_HIT_ENTRIES); + = new SectionConfig<>(Bundle.AnnotationUtils_fileHitEntry_artifactCommentTitle(), FILESET_HIT_ENTRIES); // central repository attributes and table configuration private static final List> CR_COMMENTS_ENTRIES = Arrays.asList( - new ItemEntry<>(Bundle.Annotations_centralRepositoryEntryDataLabel_case(), + new ItemEntry<>(Bundle.AnnotationUtils_centralRepositoryEntryDataLabel_case(), cai -> (cai.getCorrelationCase() != null) ? cai.getCorrelationCase().getDisplayName() : null), - new ItemEntry<>(Bundle.Annotations_centralRepositoryEntryDataLabel_comment(), cai -> cai.getComment()), - new ItemEntry<>(Bundle.Annotations_centralRepositoryEntryDataLabel_path(), cai -> cai.getFilePath()) + new ItemEntry<>(Bundle.AnnotationUtils_centralRepositoryEntryDataLabel_comment(), cai -> cai.getComment()), + new ItemEntry<>(Bundle.AnnotationUtils_centralRepositoryEntryDataLabel_path(), cai -> cai.getFilePath()) ); private static final SectionConfig CR_COMMENTS_CONFIG - = new SectionConfig<>(Bundle.Annotations_centralRepositoryEntry_title(), CR_COMMENTS_ENTRIES); + = new SectionConfig<>(Bundle.AnnotationUtils_centralRepositoryEntry_title(), CR_COMMENTS_ENTRIES); /* * Private constructor for this utility class. */ - private Annotations() { + private AnnotationUtils() { } @@ -205,7 +205,7 @@ public class Annotations { contentRendered = contentRendered || filesetRendered; } - Element sourceFileSection = appendSection(parent, Bundle.Annotations_sourceFile_title()); + Element sourceFileSection = appendSection(parent, Bundle.AnnotationUtils_sourceFile_title()); sourceFileSection.attr("class", ContentViewerHtmlStyles.getSpacedSectionClassName()); Element sourceFileContainer = sourceFileSection.appendElement("div"); @@ -464,7 +464,7 @@ public class Annotations { * * @return If there was actual content rendered for this set of entries. */ - private static boolean appendEntries(Element parent, Annotations.SectionConfig config, List items, + private static boolean appendEntries(Element parent, AnnotationUtils.SectionConfig config, List items, boolean isSubsection, boolean isFirstSection) { if (items == null || items.isEmpty()) { return false; diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.form b/Core/src/org/sleuthkit/autopsy/contentviewers/annotations/AnnotationsContentViewer.form similarity index 100% rename from Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.form rename to Core/src/org/sleuthkit/autopsy/contentviewers/annotations/AnnotationsContentViewer.form diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/annotations/AnnotationsContentViewer.java similarity index 95% rename from Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java rename to Core/src/org/sleuthkit/autopsy/contentviewers/annotations/AnnotationsContentViewer.java index b61abfceee..d40f4924f0 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/annotations/AnnotationsContentViewer.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.contentviewers; +package org.sleuthkit.autopsy.contentviewers.annotations; import java.awt.Component; import java.util.concurrent.ExecutionException; @@ -28,9 +28,6 @@ import org.openide.nodes.Node; import org.openide.util.lookup.ServiceProvider; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.datamodel.AbstractFile; -import org.sleuthkit.datamodel.BlackboardArtifact; -import org.sleuthkit.datamodel.TskCoreException; -import org.sleuthkit.autopsy.contentviewers.application.Annotations; import org.sleuthkit.autopsy.coreutils.Logger; import org.jsoup.nodes.Document; import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerHtmlStyles; @@ -161,7 +158,7 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data @Override protected String doInBackground() throws Exception { - Document doc = Annotations.buildDocument(node); + Document doc = AnnotationUtils.buildDocument(node); if(isCancelled()) { return null; diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/annotations/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/contentviewers/annotations/Bundle.properties-MERGED new file mode 100755 index 0000000000..f2be329390 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/annotations/Bundle.properties-MERGED @@ -0,0 +1,21 @@ +AnnotationsContentViewer.onEmpty=No annotations were found for this particular item. +AnnotationsContentViewer.title=Annotations +AnnotationsContentViewer.toolTip=Displays tags and comments associated with the selected content. +AnnotationUtils.centralRepositoryEntry.title=Central Repository Comments +AnnotationUtils.centralRepositoryEntryDataLabel.case=Case: +AnnotationUtils.centralRepositoryEntryDataLabel.comment=Comment: +AnnotationUtils.centralRepositoryEntryDataLabel.path=Path: +AnnotationUtils.centralRepositoryEntryDataLabel.type=Type: +AnnotationUtils.fileHitEntry.artifactCommentTitle=Artifact Comment +AnnotationUtils.fileHitEntry.comment=Comment: +AnnotationUtils.fileHitEntry.hashSetHitTitle=Hash Set Hit Comments +AnnotationUtils.fileHitEntry.interestingFileHitTitle=Interesting File Hit Comments +AnnotationUtils.fileHitEntry.setName=Set Name: +AnnotationUtils.onEmpty=No annotations were found for this particular item. +AnnotationUtils.sourceFile.title=Source File +AnnotationUtils.tagEntry.title=Tags +AnnotationUtils.tagEntryDataLabel.comment=Comment: +AnnotationUtils.tagEntryDataLabel.tag=Tag: +AnnotationUtils.tagEntryDataLabel.tagUser=Examiner: +AnnotationUtils.title=Annotations +AnnotationUtils.toolTip=Displays tags and comments associated with the selected content. diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/annotations/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/contentviewers/annotations/Bundle_ja.properties new file mode 100644 index 0000000000..5c3ff1bfb2 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/annotations/Bundle_ja.properties @@ -0,0 +1,22 @@ +#Thu Jul 01 11:56:41 UTC 2021 +AnnotationUtils.centralRepositoryEntry.title=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u306e\u30b3\u30e1\u30f3\u30c8 +AnnotationUtils.centralRepositoryEntryDataLabel.case=\u30b1\u30fc\u30b9\: +AnnotationUtils.centralRepositoryEntryDataLabel.comment=\u30b3\u30e1\u30f3\u30c8\: +AnnotationUtils.centralRepositoryEntryDataLabel.path=\u30d1\u30b9\: +AnnotationUtils.centralRepositoryEntryDataLabel.type=\u30bf\u30a4\u30d7\: +AnnotationUtils.fileHitEntry.artifactCommentTitle=\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u30b3\u30e1\u30f3\u30c8 +AnnotationUtils.fileHitEntry.comment=\u30b3\u30e1\u30f3\u30c8\: +AnnotationUtils.fileHitEntry.hashSetHitTitle=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u30fb\u30d2\u30c3\u30c8\u30b3\u30e1\u30f3\u30c8 +AnnotationUtils.fileHitEntry.interestingFileHitTitle=\u8208\u5473\u6df1\u3044\u30d5\u30a1\u30a4\u30eb\u30d2\u30c3\u30c8\u30b3\u30e1\u30f3\u30c8 +AnnotationUtils.fileHitEntry.setName=\u30bb\u30c3\u30c8\u540d\: +AnnotationUtils.onEmpty=\u3053\u306e\u30a2\u30a4\u30c6\u30e0\u306e\u6ce8\u91c8\u306f\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002 +AnnotationUtils.sourceFile.title=\u30bd\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb +AnnotationUtils.tagEntry.title=\u30bf\u30b0 +AnnotationUtils.tagEntryDataLabel.comment=\u30b3\u30e1\u30f3\u30c8\: +AnnotationUtils.tagEntryDataLabel.tag=\u30bf\u30b0\: +AnnotationUtils.tagEntryDataLabel.tagUser=\u5be9\u67fb\u5b98\uff1a +AnnotationUtils.title=\u30a2\u30ce\u30c6\u30fc\u30b7\u30e7\u30f3 +AnnotationUtils.toolTip=\u9078\u629e\u3057\u305f\u30b3\u30f3\u30c6\u30f3\u30c4\u3068\u95a2\u9023\u4ed8\u3051\u3089\u308c\u3066\u3044\u308b\u30bf\u30b0\u3068\u30b3\u30e1\u30f3\u30c8\u3092\u8868\u793a\u3057\u307e\u3059\u3002 +AnnotationsContentViewer.onEmpty=\u3053\u306e\u30a2\u30a4\u30c6\u30e0\u306e\u6ce8\u91c8\u306f\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002 +AnnotationsContentViewer.title=\u30a2\u30ce\u30c6\u30fc\u30b7\u30e7\u30f3 +AnnotationsContentViewer.toolTip=\u9078\u629e\u3057\u305f\u30b3\u30f3\u30c6\u30f3\u30c4\u3068\u95a2\u9023\u4ed8\u3051\u3089\u308c\u3066\u3044\u308b\u30bf\u30b0\u3068\u30b3\u30e1\u30f3\u30c8\u3092\u8868\u793a\u3057\u307e\u3059\u3002 diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/application/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/contentviewers/application/Bundle.properties-MERGED deleted file mode 100755 index 238576e0c7..0000000000 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/application/Bundle.properties-MERGED +++ /dev/null @@ -1,18 +0,0 @@ -Annotations.centralRepositoryEntry.title=Central Repository Comments -Annotations.centralRepositoryEntryDataLabel.case=Case: -Annotations.centralRepositoryEntryDataLabel.comment=Comment: -Annotations.centralRepositoryEntryDataLabel.path=Path: -Annotations.centralRepositoryEntryDataLabel.type=Type: -Annotations.fileHitEntry.artifactCommentTitle=Artifact Comment -Annotations.fileHitEntry.comment=Comment: -Annotations.fileHitEntry.hashSetHitTitle=Hash Set Hit Comments -Annotations.fileHitEntry.interestingFileHitTitle=Interesting File Hit Comments -Annotations.fileHitEntry.setName=Set Name: -Annotations.onEmpty=No annotations were found for this particular item. -Annotations.sourceFile.title=Source File -Annotations.tagEntry.title=Tags -Annotations.tagEntryDataLabel.comment=Comment: -Annotations.tagEntryDataLabel.tag=Tag: -Annotations.tagEntryDataLabel.tagUser=Examiner: -Annotations.title=Annotations -Annotations.toolTip=Displays tags and comments associated with the selected content. diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/application/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/contentviewers/application/Bundle_ja.properties deleted file mode 100644 index ad13ec51b3..0000000000 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/application/Bundle_ja.properties +++ /dev/null @@ -1,19 +0,0 @@ -#Thu Jul 01 11:56:41 UTC 2021 -Annotations.centralRepositoryEntry.title=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u306e\u30b3\u30e1\u30f3\u30c8 -Annotations.centralRepositoryEntryDataLabel.case=\u30b1\u30fc\u30b9\: -Annotations.centralRepositoryEntryDataLabel.comment=\u30b3\u30e1\u30f3\u30c8\: -Annotations.centralRepositoryEntryDataLabel.path=\u30d1\u30b9\: -Annotations.centralRepositoryEntryDataLabel.type=\u30bf\u30a4\u30d7\: -Annotations.fileHitEntry.artifactCommentTitle=\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u30b3\u30e1\u30f3\u30c8 -Annotations.fileHitEntry.comment=\u30b3\u30e1\u30f3\u30c8\: -Annotations.fileHitEntry.hashSetHitTitle=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u30fb\u30d2\u30c3\u30c8\u30b3\u30e1\u30f3\u30c8 -Annotations.fileHitEntry.interestingFileHitTitle=\u8208\u5473\u6df1\u3044\u30d5\u30a1\u30a4\u30eb\u30d2\u30c3\u30c8\u30b3\u30e1\u30f3\u30c8 -Annotations.fileHitEntry.setName=\u30bb\u30c3\u30c8\u540d\: -Annotations.onEmpty=\u3053\u306e\u30a2\u30a4\u30c6\u30e0\u306e\u6ce8\u91c8\u306f\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002 -Annotations.sourceFile.title=\u30bd\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb -Annotations.tagEntry.title=\u30bf\u30b0 -Annotations.tagEntryDataLabel.comment=\u30b3\u30e1\u30f3\u30c8\: -Annotations.tagEntryDataLabel.tag=\u30bf\u30b0\: -Annotations.tagEntryDataLabel.tagUser=\u5be9\u67fb\u5b98\uff1a -Annotations.title=\u30a2\u30ce\u30c6\u30fc\u30b7\u30e7\u30f3 -Annotations.toolTip=\u9078\u629e\u3057\u305f\u30b3\u30f3\u30c6\u30f3\u30c4\u3068\u95a2\u9023\u4ed8\u3051\u3089\u308c\u3066\u3044\u308b\u30bf\u30b0\u3068\u30b3\u30e1\u30f3\u30c8\u3092\u8868\u793a\u3057\u307e\u3059\u3002 From 417c432a216e8a9d7ab9044feda5eac05ddb90d7 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Fri, 3 Sep 2021 12:46:17 -0400 Subject: [PATCH 42/64] 7963 format IngestEventsListener.java --- .../eventlisteners/IngestEventsListener.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java index 7aa229949e..04275f0e98 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java @@ -70,6 +70,7 @@ import org.sleuthkit.datamodel.Score; */ @NbBundle.Messages({"IngestEventsListener.ingestmodule.name=Central Repository"}) public class IngestEventsListener { + private static final Logger LOGGER = Logger.getLogger(CorrelationAttributeInstance.class.getName()); private static final Set INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.DATA_SOURCE_ANALYSIS_COMPLETED); private static final Set INGEST_MODULE_EVENTS_OF_INTEREST = EnumSet.of(DATA_ADDED); @@ -246,15 +247,15 @@ public class IngestEventsListener { originalArtifact.getArtifactID())); makeAndPostInterestingArtifact(originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevExists_text()); } - - + /** * Make an interesting item artifact to flag the passed in artifact. * * @param originalArtifact Artifact in current case we want to flag * @param attributesForNewArtifact Attributes to assign to the new * Interesting items artifact - * @param configuration The configuration to be specified for the new interesting artifact hit + * @param configuration The configuration to be specified for the + * new interesting artifact hit */ private static void makeAndPostInterestingArtifact(BlackboardArtifact originalArtifact, Collection attributesForNewArtifact, String configuration) { try { @@ -263,8 +264,8 @@ public class IngestEventsListener { Blackboard blackboard = tskCase.getBlackboard(); // Create artifact if it doesn't already exist. if (!blackboard.artifactExists(abstractFile, TSK_INTERESTING_ARTIFACT_HIT, attributesForNewArtifact)) { - BlackboardArtifact newInterestingArtifact = abstractFile.newAnalysisResult( - BlackboardArtifact.Type.TSK_INTERESTING_ARTIFACT_HIT, Score.SCORE_LIKELY_NOTABLE, + BlackboardArtifact newInterestingArtifact = abstractFile.newAnalysisResult( + BlackboardArtifact.Type.TSK_INTERESTING_ARTIFACT_HIT, Score.SCORE_LIKELY_NOTABLE, null, configuration, null, attributesForNewArtifact) .getAnalysisResult(); @@ -368,8 +369,8 @@ public class IngestEventsListener { try { dataSource = ((DataSourceAnalysisEvent) event).getDataSource(); /* - * We only care about Images for the purpose of - * updating hash values. + * We only care about Images for the purpose of updating hash + * values. */ if (!(dataSource instanceof Image)) { return; From 753d1c80376cef837c2b177a9bbf494a86829b3b Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 3 Sep 2021 15:23:40 -0400 Subject: [PATCH 43/64] 7852 clean up --- .../datamodel/CorrelationAttributeUtil.java | 131 +++++++++--------- 1 file changed, 66 insertions(+), 65 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index 0ad1d8c6ee..1d891b5db5 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -1,7 +1,7 @@ /* * Central Repository * - * Copyright 2017-2020 Basis Technology Corp. + * Copyright 2017-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,7 +25,6 @@ import java.util.List; import java.util.Optional; import java.util.Set; import java.util.logging.Level; -import org.openide.util.Exceptions; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; @@ -43,7 +42,6 @@ import org.sleuthkit.datamodel.DataArtifact; import org.sleuthkit.datamodel.HashUtility; import org.sleuthkit.datamodel.InvalidAccountIDException; import org.sleuthkit.datamodel.OsAccount; -import org.sleuthkit.datamodel.OsAccountInstance; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; @@ -57,7 +55,7 @@ public class CorrelationAttributeUtil { private static final List domainsToSkip = Arrays.asList("localhost", "127.0.0.1"); // artifact ids that specifically have a TSK_DOMAIN attribute that should be handled by CR - private static Set DOMAIN_ARTIFACT_TYPE_IDS = new HashSet<>(Arrays.asList( + private static final Set DOMAIN_ARTIFACT_TYPE_IDS = new HashSet<>(Arrays.asList( ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID(), ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID(), ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID(), @@ -80,64 +78,78 @@ public class CorrelationAttributeUtil { return Bundle.CorrelationAttributeUtil_emailaddresses_text(); } - /** - * Makes zero to many correlation attribute instances from the attributes of - * artifacts that have correlatable data. The intention of this method is to - * use the results to save to the CR, not to correlate with them. If you - * want to correlate, please use makeCorrAttrsForCorrelation. An artifact - * that can have correlatable data != An artifact that should be the source - * of data in the CR, so results may be un-necessarily incomplete. - * - * @param artifact An artifact. - * - * @return A list, possibly empty, of correlation attribute instances for - * the artifact. - */ - public static List makeCorrAttrsToSave(DataArtifact artifact) { + private static List makeCorrAttrsToSave(DataArtifact artifact) { int artifactTypeID = artifact.getArtifactTypeID(); - // @@@ TODO Add a comment about why we do not save these. - // BC: I forget the history on these... + //The account fields in these types are expected to be saved in a TSK_ACCOUNT artifact, which will be processed if (artifactTypeID == ARTIFACT_TYPE.TSK_CALLLOG.getTypeID() || artifactTypeID == ARTIFACT_TYPE.TSK_MESSAGE.getTypeID() || artifactTypeID == ARTIFACT_TYPE.TSK_CONTACT.getTypeID()) { return new ArrayList<>(); } - return CorrelationAttributeUtil.makeCorrAttrsForSearch(artifact); } - //public static List makeCorrAttrsToSave(AbstactFile file) { - // @@@ TODO Call into makeCorrAttrsForSearch(file) when API changes - // AND move logic that perhaps in the ingest module into here. - // return makeCorrAttrsForSearch(file); - //} + /** + * Makes zero to many correlation attribute instances from the attributes of + * content objects that have correlatable data. The intention of this method + * is to use the results to save to the CR, not to correlate with them. If + * you want to correlate, please use makeCorrAttrsForSearch. An artifact + * that can have correlatable data != An artifact that should be the source + * of data in the CR, so results may be un-necessarily incomplete. + * + * @param content A Content object. + * + * @return A list, possibly empty, of correlation attribute instances for + * the content. + */ public static List makeCorrAttrsToSave(Content content) { - return new ArrayList<>(); + if (content instanceof DataArtifact) { + return makeCorrAttrsToSave((DataArtifact) content); + } else if (!(content instanceof AnalysisResult)) { + return makeCorrAttrsForSearch(content); + } else { + return new ArrayList<>(); + } } public static List makeCorrAttrsForSearch(Content content) { - return new ArrayList<>(); + if (content instanceof DataArtifact) { + return makeCorrAttrsForSearch((DataArtifact) content); + } else if (content instanceof AnalysisResult) { + return makeCorrAttrsForSearch((AnalysisResult) content); + } else if (content instanceof AbstractFile) { + return makeCorrAttrsForSearch((AbstractFile) content); + } else { + return new ArrayList<>(); + } } - public static List makeCorrAttrsForSearch(AnalysisResult artifact) { + private static List makeCorrAttrsForSearch(AnalysisResult analysisResult) { + List correlationAttrs = new ArrayList<>(); try { - if (BlackboardArtifact.Type.TSK_INTERESTING_ARTIFACT_HIT.equals(artifact.getType())) { - BlackboardAttribute assocArtifactAttr = artifact.getAttribute(BlackboardAttribute.Type.TSK_ASSOCIATED_ARTIFACT); + int artifactTypeID = analysisResult.getArtifactTypeID(); + if (artifactTypeID == ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) { + BlackboardAttribute setNameAttr = analysisResult.getAttribute(BlackboardAttribute.Type.TSK_SET_NAME); + if (setNameAttr != null && CorrelationAttributeUtil.getEmailAddressAttrDisplayName().equals(setNameAttr.getValueString())) { + makeCorrAttrFromArtifactAttr(correlationAttrs, analysisResult, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD, CorrelationAttributeInstance.EMAIL_TYPE_ID, analysisResult.getAttributes()); + } + } else if (artifactTypeID == ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID()) { + BlackboardAttribute assocArtifactAttr = analysisResult.getAttribute(BlackboardAttribute.Type.TSK_ASSOCIATED_ARTIFACT); if (assocArtifactAttr != null) { BlackboardArtifact sourceArtifact = Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboardArtifact(assocArtifactAttr.getValueLong()); return CorrelationAttributeUtil.makeCorrAttrsForSearch(sourceArtifact); } } - Content content = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID()); - - return CorrelationAttributeUtil.makeCorrAttrsForSearch(content); - // @@@ TODO ADD Error Handling + Content content = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(analysisResult.getObjectID()); + correlationAttrs.addAll(CorrelationAttributeUtil.makeCorrAttrsForSearch(content)); } catch (TskCoreException ex) { - Exceptions.printStackTrace(ex); + logger.log(Level.SEVERE, "Failed to get information regarding correlation attributes from AnalysisResult", ex); } catch (NoCurrentCaseException ex) { - Exceptions.printStackTrace(ex); + logger.log(Level.SEVERE, "Attempted to retrieve correlation attributes for search with no currently open case.", ex); + } catch (CentralRepoException ex) { + logger.log(Level.SEVERE, "Failed to get correlation type from central repository.", ex); } - return new ArrayList<>(); + return correlationAttrs; } /** @@ -164,19 +176,13 @@ public class CorrelationAttributeUtil { * @return A list, possibly empty, of correlation attribute instances for * the artifact. */ - public static List makeCorrAttrsForSearch(DataArtifact artifact) { + private static List makeCorrAttrsForSearch(DataArtifact artifact) { List correlationAttrs = new ArrayList<>(); try { List attributes = artifact.getAttributes(); int artifactTypeID = artifact.getArtifactTypeID(); - //if (artifactTypeID == ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) { - // BlackboardAttribute setNameAttr = getAttribute(attributes, new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME)); - // if (setNameAttr != null && CorrelationAttributeUtil.getEmailAddressAttrDisplayName().equals(setNameAttr.getValueString())) { - // makeCorrAttrFromArtifactAttr(correlationAttrs, artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD, CorrelationAttributeInstance.EMAIL_TYPE_ID, attributes); - // } - //} else if (DOMAIN_ARTIFACT_TYPE_IDS.contains(artifactTypeID)) { BlackboardAttribute domainAttr = getAttribute(attributes, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DOMAIN)); if ((domainAttr != null) @@ -305,8 +311,6 @@ public class CorrelationAttributeUtil { */ private static void makeCorrAttrsFromCommunicationArtifacts(List corrAttrInstances, BlackboardArtifact artifact, List attributes) throws TskCoreException, CentralRepoException, CorrelationAttributeNormalizationException { - CorrelationAttributeInstance corrAttr = null; - /* * Extract the phone number from the artifact attribute. */ @@ -318,15 +322,13 @@ public class CorrelationAttributeUtil { } else if (null != getAttribute(attributes, new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO))) { value = getAttribute(attributes, new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO)).getValueString(); } - /* * Normalize the phone number. */ if (value != null && CorrelationAttributeNormalizer.isValidPhoneNumber(value)) { - value = CorrelationAttributeNormalizer.normalizePhone(value); - corrAttr = makeCorrAttr(artifact, CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.PHONE_TYPE_ID), value); + CorrelationAttributeInstance corrAttr = makeCorrAttr(artifact, CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.PHONE_TYPE_ID), value); if (corrAttr != null) { corrAttrInstances.add(corrAttr); } @@ -484,21 +486,21 @@ public class CorrelationAttributeUtil { */ private static CorrelationAttributeInstance makeCorrAttr(BlackboardArtifact artifact, CorrelationAttributeInstance.Type correlationType, String value, Content sourceContent, Content dataSource) { + Content srcContent = sourceContent; + Content dataSrc = dataSource; try { - - if (sourceContent == null) { - sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID()); + if (srcContent == null) { + srcContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID()); } - if (null == sourceContent) { + if (null == srcContent) { 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; } - - if (dataSource == null) { - dataSource = sourceContent.getDataSource(); + if (dataSrc == null) { + dataSrc = srcContent.getDataSource(); } - if (dataSource == null) { + if (dataSrc == 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; @@ -510,24 +512,24 @@ public class CorrelationAttributeUtil { correlationType, value, correlationCase, - CorrelationDataSource.fromTSKDataSource(correlationCase, dataSource), + CorrelationDataSource.fromTSKDataSource(correlationCase, dataSrc), "", "", TskData.FileKnown.UNKNOWN, - sourceContent.getId()); + srcContent.getId()); } else { - if (!(sourceContent instanceof AbstractFile)) { + if (!(srcContent 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; + AbstractFile bbSourceFile = (AbstractFile) srcContent; return new CorrelationAttributeInstance( correlationType, value, correlationCase, - CorrelationDataSource.fromTSKDataSource(correlationCase, dataSource), + CorrelationDataSource.fromTSKDataSource(correlationCase, dataSrc), bbSourceFile.getParentPath() + bbSourceFile.getName(), "", TskData.FileKnown.UNKNOWN, @@ -694,8 +696,7 @@ public class CorrelationAttributeUtil { * * @return The correlation attribute instance or null, if an error occurred. */ - // @@@ TODO: Make this look like other makeCorrAttrsForSearch and return a list - public static List makeCorrAttrsForSearch(AbstractFile file) { + private static List makeCorrAttrsForSearch(AbstractFile file) { List fileTypeList = new ArrayList<>(); // will be an empty or single element list as was decided in 7852 if (!isSupportedAbstractFileType(file)) { return fileTypeList; From a4ccf21c719c9e90a46341c2ace399b79594da6f Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 3 Sep 2021 15:31:55 -0400 Subject: [PATCH 44/64] 7852 further clean up --- .../Bundle.properties-MERGED | 5 +- .../datamodel/CorrelationAttributeUtil.java | 56 ++++++++++--------- 2 files changed, 33 insertions(+), 28 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/centralrepository/Bundle.properties-MERGED index b2320b5408..b4f7f835ef 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/Bundle.properties-MERGED @@ -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 diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index 1d891b5db5..c15edbfd2d 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -105,13 +105,39 @@ public class CorrelationAttributeUtil { public static List makeCorrAttrsToSave(Content content) { if (content instanceof DataArtifact) { return makeCorrAttrsToSave((DataArtifact) content); - } else if (!(content instanceof AnalysisResult)) { - return makeCorrAttrsForSearch(content); - } else { + } else if (content instanceof AnalysisResult) { + //AnalysisResults should already have the correlation attributes they are correlating on saved + //This check replaces the check explicitly excluding keyword hits and interesting items that existed prior to the AnalysisResult designation return new ArrayList<>(); + } else { + return makeCorrAttrsForSearch(content); } } + /** + * Makes zero to many correlation attribute instances from the attributes of + * content that have correlatable data. The intention of this method is to + * use the results to correlate with, not to save. If you want to save, + * please use makeCorrAttrsToSave. An artifact that can have correlatable + * data != An artifact that should be the source of data in the CR, so + * results may be too lenient. + * + * IMPORTANT: The correlation attribute instances are NOT added to the + * central repository by this method. + * + * TODO (Jira-6088): The methods in this low-level, utility class should + * throw exceptions instead of logging them. The reason for this is that the + * clients of the utility class, not the utility class itself, should be in + * charge of error handling policy, per the Autopsy Coding Standard. Note + * that clients of several of these methods currently cannot determine + * whether receiving a null return value is an error or not, plus null + * checking is easy to forget, while catching exceptions is enforced. + * + * @param Content A Content object. + * + * @return A list, possibly empty, of correlation attribute instances for + * the content. + */ public static List makeCorrAttrsForSearch(Content content) { if (content instanceof DataArtifact) { return makeCorrAttrsForSearch((DataArtifact) content); @@ -152,30 +178,6 @@ public class CorrelationAttributeUtil { return correlationAttrs; } - /** - * Makes zero to many correlation attribute instances from the attributes of - * artifacts that have correlatable data. The intention of this method is to - * use the results to correlate with, not to save. If you want to save, - * please use makeCorrAttrsToSave. An artifact that can have correlatable - * data != An artifact that should be the source of data in the CR, so - * results may be too lenient. - * - * IMPORTANT: The correlation attribute instances are NOT added to the - * central repository by this method. - * - * TODO (Jira-6088): The methods in this low-level, utility class should - * throw exceptions instead of logging them. The reason for this is that the - * clients of the utility class, not the utility class itself, should be in - * charge of error handling policy, per the Autopsy Coding Standard. Note - * that clients of several of these methods currently cannot determine - * whether receiving a null return value is an error or not, plus null - * checking is easy to forget, while catching exceptions is enforced. - * - * @param artifact An artifact. - * - * @return A list, possibly empty, of correlation attribute instances for - * the artifact. - */ private static List makeCorrAttrsForSearch(DataArtifact artifact) { List correlationAttrs = new ArrayList<>(); try { From 7434c3fea02eee121a395b3d3d74560fadd305d6 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 3 Sep 2021 16:12:43 -0400 Subject: [PATCH 45/64] 7852 modify SCOtask logic --- .../datamodel/CorrelationAttributeUtil.java | 18 +++++- .../autopsy/datamodel/GetSCOTask.java | 58 ++++--------------- 2 files changed, 26 insertions(+), 50 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index c15edbfd2d..bebf68a874 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -63,6 +63,17 @@ public class CorrelationAttributeUtil { ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID() )); + private static final Set FILE_ARTIFACT_TYPE_IDS = new HashSet<>(Arrays.asList( + ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED.getTypeID(), + ARTIFACT_TYPE.TSK_ENCRYPTION_SUSPECTED.getTypeID(), + ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(), + ARTIFACT_TYPE.TSK_METADATA_EXIF.getTypeID(), + ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID(), + ARTIFACT_TYPE.TSK_OBJECT_DETECTED.getTypeID(), + ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED.getTypeID(), + ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID() + )); + /** * Gets a string that is expected to be the same string that is stored in * the correlation_types table in the central repository as the display name @@ -83,7 +94,8 @@ public class CorrelationAttributeUtil { //The account fields in these types are expected to be saved in a TSK_ACCOUNT artifact, which will be processed if (artifactTypeID == ARTIFACT_TYPE.TSK_CALLLOG.getTypeID() || artifactTypeID == ARTIFACT_TYPE.TSK_MESSAGE.getTypeID() - || artifactTypeID == ARTIFACT_TYPE.TSK_CONTACT.getTypeID()) { + || artifactTypeID == ARTIFACT_TYPE.TSK_CONTACT.getTypeID() + || FILE_ARTIFACT_TYPE_IDS.contains(artifactTypeID)) { return new ArrayList<>(); } return CorrelationAttributeUtil.makeCorrAttrsForSearch(artifact); @@ -191,6 +203,9 @@ public class CorrelationAttributeUtil { && !domainsToSkip.contains(domainAttr.getValueString())) { makeCorrAttrFromArtifactAttr(correlationAttrs, artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN, CorrelationAttributeInstance.DOMAIN_TYPE_ID, attributes); } + } else if (FILE_ARTIFACT_TYPE_IDS.contains(artifactTypeID) && artifact.getParent() instanceof AbstractFile) { + //if it is one of the types in this set we instead want to correlate on the parent file + correlationAttrs.addAll(makeCorrAttrsForSearch((AbstractFile) artifact.getParent())); } else if (artifactTypeID == ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID()) { // prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID()); @@ -199,7 +214,6 @@ public class CorrelationAttributeUtil { attributes, sourceContent, dataSource); makeCorrAttrFromArtifactAttr(correlationAttrs, artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MAC_ADDRESS, CorrelationAttributeInstance.MAC_TYPE_ID, attributes, sourceContent, dataSource); - } else if (artifactTypeID == ARTIFACT_TYPE.TSK_WIFI_NETWORK.getTypeID()) { makeCorrAttrFromArtifactAttr(correlationAttrs, artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SSID, CorrelationAttributeInstance.SSID_TYPE_ID, attributes); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/GetSCOTask.java b/Core/src/org/sleuthkit/autopsy/datamodel/GetSCOTask.java index d7e56a11d7..64b8aa604f 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/GetSCOTask.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/GetSCOTask.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2019-2020 Basis Technology Corp. + * Copyright 2019-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,19 +22,13 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.lang.ref.WeakReference; import java.util.List; -import java.util.logging.Level; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance.Type; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeUtil; -import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; import org.sleuthkit.autopsy.core.UserPreferences; -import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.events.AutopsyEvent; -import org.sleuthkit.datamodel.AbstractFile; -import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.Tag; -import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; /** @@ -46,7 +40,6 @@ class GetSCOTask implements Runnable { private final WeakReference> weakNodeRef; private final PropertyChangeListener listener; - private static final Logger logger = Logger.getLogger(GetSCOTask.class.getName()); GetSCOTask(WeakReference> weakContentRef, PropertyChangeListener listener) { this.weakNodeRef = weakContentRef; @@ -59,7 +52,7 @@ class GetSCOTask implements Runnable { public void run() { AbstractContentNode contentNode = weakNodeRef.get(); - //Check for stale reference or if columns are disabled + //Check for stale reference or if columns are disabled if (contentNode == null || UserPreferences.getHideSCOColumns()) { return; } @@ -72,49 +65,18 @@ class GetSCOTask implements Runnable { //because the Comment column will reflect the presence of comments in the CR when the CR is enabled, but reflect tag comments regardless CorrelationAttributeInstance fileAttribute = contentNode.getCorrelationAttributeInstance(); scoData.setComment(contentNode.getCommentProperty(tags, fileAttribute)); - if (CentralRepository.isEnabled()) { Type type = null; String value = null; String description = Bundle.GetSCOTask_occurrences_defaultDescription(); - if (contentNode instanceof BlackboardArtifactNode) { - BlackboardArtifact bbArtifact = ((BlackboardArtifactNode) contentNode).getArtifact(); - //for specific artifact types we still want to display information for the file instance correlation attribute - if (bbArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED.getTypeID() - || bbArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_SUSPECTED.getTypeID() - || bbArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID() - || bbArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF.getTypeID() - || bbArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() - || bbArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_OBJECT_DETECTED.getTypeID() - || bbArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED.getTypeID() - || bbArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()) { - try { - if (bbArtifact.getParent() instanceof AbstractFile) { - type = CorrelationAttributeInstance.getDefaultCorrelationTypes().get(CorrelationAttributeInstance.FILES_TYPE_ID); - value = ((AbstractFile) bbArtifact.getParent()).getMd5Hash(); - } - } catch (TskCoreException | CentralRepoException ex) { - logger.log(Level.WARNING, "Unable to get correlation type or value to determine value for O column for artifact", ex); - } - } else { - List listOfPossibleAttributes = CorrelationAttributeUtil.makeCorrAttrsForSearch(bbArtifact); - if (listOfPossibleAttributes.size() > 1) { - //Don't display anything if there is more than 1 correlation property for an artifact but let the user know - description = Bundle.GetSCOTask_occurrences_multipleProperties(); - } else if (!listOfPossibleAttributes.isEmpty()) { - //there should only be one item in the list - type = listOfPossibleAttributes.get(0).getCorrelationType(); - value = listOfPossibleAttributes.get(0).getCorrelationValue(); - } - } - } else if (contentNode.getContent() instanceof AbstractFile) { - //use the file instance correlation attribute if the node is not a BlackboardArtifactNode - try { - type = CorrelationAttributeInstance.getDefaultCorrelationTypes().get(CorrelationAttributeInstance.FILES_TYPE_ID); - value = ((AbstractFile) contentNode.getContent()).getMd5Hash(); - } catch (CentralRepoException ex) { - logger.log(Level.WARNING, "Unable to get correlation type to determine value for O column for file", ex); - } + List listOfPossibleAttributes = CorrelationAttributeUtil.makeCorrAttrsForSearch(contentNode.getContent()); + if (listOfPossibleAttributes.size() > 1) { + //Don't display anything if there is more than 1 correlation property for an artifact but let the user know + description = Bundle.GetSCOTask_occurrences_multipleProperties(); + } else if (!listOfPossibleAttributes.isEmpty()) { + //there should only be one item in the list + type = listOfPossibleAttributes.get(0).getCorrelationType(); + value = listOfPossibleAttributes.get(0).getCorrelationValue(); } scoData.setCountAndDescription(contentNode.getCountPropertyAndDescription(type, value, description)); } From 18f7f21c0ff1fd996fb290e9c51e6eb89c8691f3 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 3 Sep 2021 16:57:31 -0400 Subject: [PATCH 46/64] 7852 fix analysis results misidentified in logic as data artifacts --- .../datamodel/CorrelationAttributeUtil.java | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index bebf68a874..5e64e3994b 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -63,17 +63,6 @@ public class CorrelationAttributeUtil { ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID() )); - private static final Set FILE_ARTIFACT_TYPE_IDS = new HashSet<>(Arrays.asList( - ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED.getTypeID(), - ARTIFACT_TYPE.TSK_ENCRYPTION_SUSPECTED.getTypeID(), - ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(), - ARTIFACT_TYPE.TSK_METADATA_EXIF.getTypeID(), - ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID(), - ARTIFACT_TYPE.TSK_OBJECT_DETECTED.getTypeID(), - ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED.getTypeID(), - ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID() - )); - /** * Gets a string that is expected to be the same string that is stored in * the correlation_types table in the central repository as the display name @@ -94,8 +83,7 @@ public class CorrelationAttributeUtil { //The account fields in these types are expected to be saved in a TSK_ACCOUNT artifact, which will be processed if (artifactTypeID == ARTIFACT_TYPE.TSK_CALLLOG.getTypeID() || artifactTypeID == ARTIFACT_TYPE.TSK_MESSAGE.getTypeID() - || artifactTypeID == ARTIFACT_TYPE.TSK_CONTACT.getTypeID() - || FILE_ARTIFACT_TYPE_IDS.contains(artifactTypeID)) { + || artifactTypeID == ARTIFACT_TYPE.TSK_CONTACT.getTypeID()) { return new ArrayList<>(); } return CorrelationAttributeUtil.makeCorrAttrsForSearch(artifact); @@ -178,8 +166,7 @@ public class CorrelationAttributeUtil { return CorrelationAttributeUtil.makeCorrAttrsForSearch(sourceArtifact); } } - Content content = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(analysisResult.getObjectID()); - correlationAttrs.addAll(CorrelationAttributeUtil.makeCorrAttrsForSearch(content)); + correlationAttrs.addAll(CorrelationAttributeUtil.makeCorrAttrsForSearch(analysisResult.getParent())); } catch (TskCoreException ex) { logger.log(Level.SEVERE, "Failed to get information regarding correlation attributes from AnalysisResult", ex); } catch (NoCurrentCaseException ex) { @@ -203,9 +190,6 @@ public class CorrelationAttributeUtil { && !domainsToSkip.contains(domainAttr.getValueString())) { makeCorrAttrFromArtifactAttr(correlationAttrs, artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN, CorrelationAttributeInstance.DOMAIN_TYPE_ID, attributes); } - } else if (FILE_ARTIFACT_TYPE_IDS.contains(artifactTypeID) && artifact.getParent() instanceof AbstractFile) { - //if it is one of the types in this set we instead want to correlate on the parent file - correlationAttrs.addAll(makeCorrAttrsForSearch((AbstractFile) artifact.getParent())); } else if (artifactTypeID == ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID()) { // prefetch all the information as we will be calling makeCorrAttrFromArtifactAttr() multiple times Content sourceContent = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(artifact.getObjectID()); From b043511941b3032425fc0587f239d8aac3f15b09 Mon Sep 17 00:00:00 2001 From: apriestman Date: Tue, 7 Sep 2021 09:36:09 -0400 Subject: [PATCH 47/64] Fix cut-and-paste errors in CorrelationAttributeNormalizationException --- .../datamodel/CorrelationAttributeNormalizer.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeNormalizer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeNormalizer.java index f7d423c85d..300f1019c2 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeNormalizer.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeNormalizer.java @@ -282,7 +282,7 @@ final public class CorrelationAttributeNormalizer { if (imsiWithoutSeperators.matches(validImsiRegex)) { return imsiWithoutSeperators; } else { - throw new CorrelationAttributeNormalizationException("Data provided was not a valid Imsi. : " + data); + throw new CorrelationAttributeNormalizationException("Data provided was not a valid IMSI. : " + data); } } @@ -306,7 +306,7 @@ final public class CorrelationAttributeNormalizer { if (macWithoutSeperators.matches(validMacRegex)) { return macWithoutSeperators; } else { - throw new CorrelationAttributeNormalizationException("Data provided was not a valid Imsi. : " + data); + throw new CorrelationAttributeNormalizationException("Data provided was not a valid MAC address. : " + data); } } @@ -335,7 +335,7 @@ final public class CorrelationAttributeNormalizer { if (imeiWithoutSeperators.matches(validImeiRegex)) { return imeiWithoutSeperators; } else { - throw new CorrelationAttributeNormalizationException("Data provided was not a valid Imsi. : " + data); + throw new CorrelationAttributeNormalizationException("Data provided was not a valid IMEI. : " + data); } } From 3dfc397f6a6c079462c844b963ebdff7794b7e74 Mon Sep 17 00:00:00 2001 From: apriestman Date: Tue, 7 Sep 2021 13:54:51 -0400 Subject: [PATCH 48/64] Add custom MIME type to look for VHD signature in footer --- .../modules/filetypeid/CustomFileTypesManager.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/CustomFileTypesManager.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/CustomFileTypesManager.java index 7175b3f023..57ce4c51b3 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/CustomFileTypesManager.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/CustomFileTypesManager.java @@ -336,6 +336,14 @@ final class CustomFileTypesManager { signatureList.add(new Signature(byteArray, 8L)); fileType = new FileType("application/x.android-hdb", signatureList); autopsyDefinedFileTypes.add(fileType); + + /** + * Add custom type for fixed-size VHDs. + */ + signatureList.clear(); + signatureList.add(new Signature("conectix", 511L, false)); //NON-NLS + fileType = new FileType("application/x-vhd", signatureList); //NON-NLS + autopsyDefinedFileTypes.add(fileType); } catch (IllegalArgumentException ex) { /* From da84ce0e94d1276f87a346c2806b01d3fa1d531d Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Tue, 7 Sep 2021 16:49:51 -0400 Subject: [PATCH 49/64] Minor --- .../autopsy/centralrepository/ingestmodule/Bundle_ja.properties | 1 - 1 file changed, 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/Bundle_ja.properties index 47b5abd4ec..1899d309b9 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/Bundle_ja.properties @@ -13,4 +13,3 @@ IngestSettingsPanel.createCorrelationPropertiesCheckbox.text=\u30a2\u30a4\u30c6\ IngestSettingsPanel.flagPreviouslySeenDevicesCheckbox.text=\u4ee5\u524d\u306e\u30b1\u30fc\u30b9\u3067\u898b\u3089\u308c\u305f\u30c7\u30d0\u30a4\u30b9\u306b\u30d5\u30e9\u30b0\u3092\u4ed8\u3051\u308b IngestSettingsPanel.flagTaggedNotableItemsCheckbox.text=\u4ee5\u524d\u306b\u6ce8\u76ee\u3059\u3079\u304d\u30bf\u30b0\u4ed8\u3051\u305f\u30a2\u30a4\u30c6\u30e0\u306b\u30d5\u30e9\u30b0\u3092\u4ed8\u3051\u308b IngestSettingsPanel.ingestSettingsLabel.text=\u53d6\u8fbc\u307f\u8a2d\u5b9a -IngestSettingsPanel.flagUniqueAppsCheckbox.text=\u4ee5\u524d\u306e\u30b1\u30fc\u30b9\u3067\u898b\u3089\u308c\u305f\u30c7\u30d0\u30a4\u30b9\u306b\u30d5\u30e9\u30b0\u3092\u4ed8\u3051\u308b From 8117d5482c4415e05811213db218a2d0c45de0d7 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Wed, 8 Sep 2021 11:16:08 -0400 Subject: [PATCH 50/64] Bug fix for previously seen --- .../centralrepository/eventlisteners/IngestEventsListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java index 09c02d52fe..1dad86dd90 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java @@ -656,7 +656,7 @@ public class IngestEventsListener { } // flag previously seen devices and communication accounts (emails, phones, etc) - if (flagPreviousItemsEnabled + if (flagPreviousItemsEnabled && !previousOccurrences.isEmpty() && (eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.USBID_TYPE_ID || eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.ICCID_TYPE_ID || eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.IMEI_TYPE_ID From 99d8b420f52b92d7d6c8c2b6c5803c55cbd00744 Mon Sep 17 00:00:00 2001 From: apriestman Date: Wed, 8 Sep 2021 12:13:02 -0400 Subject: [PATCH 51/64] New artifact icons --- .../autopsy/datamodel/utils/IconsUtil.java | 7 +++++++ .../sleuthkit/autopsy/images/previously-seen.png | Bin 0 -> 1107 bytes .../autopsy/images/previously-unseen.png | Bin 0 -> 1168 bytes .../autopsy/report/modules/html/HTMLReport.java | 10 ++++++++++ 4 files changed, 17 insertions(+) create mode 100644 Core/src/org/sleuthkit/autopsy/images/previously-seen.png create mode 100644 Core/src/org/sleuthkit/autopsy/images/previously-unseen.png diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/utils/IconsUtil.java b/Core/src/org/sleuthkit/autopsy/datamodel/utils/IconsUtil.java index de88e41e04..69190cd175 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/utils/IconsUtil.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/utils/IconsUtil.java @@ -127,6 +127,13 @@ public final class IconsUtil { imageFile = "gps-area.png"; //NON-NLS } else if (typeID == ARTIFACT_TYPE.TSK_YARA_HIT.getTypeID()) { imageFile = "yara_16.png"; //NON-NLS + } else if (typeID == ARTIFACT_TYPE.TSK_PREVIOUSLY_SEEN.getTypeID()) { + imageFile = "previously-seen.png"; //NON-NLS + } else if (typeID == ARTIFACT_TYPE.TSK_PREVIOUSLY_UNSEEN.getTypeID()) { + imageFile = "previously-unseen.png"; //NON-NLS + } else if (typeID == ARTIFACT_TYPE.TSK_PREVIOUSLY_NOTABLE.getTypeID()) { + imageFile = "previously-notable.png"; //NON-NLS + //imageFile = "red-circle-exclamation.png"; //NON-NLS } else { imageFile = "artifact-icon.png"; //NON-NLS } diff --git a/Core/src/org/sleuthkit/autopsy/images/previously-seen.png b/Core/src/org/sleuthkit/autopsy/images/previously-seen.png new file mode 100644 index 0000000000000000000000000000000000000000..ed78158beb6f740de378cdeda36d1fcbc212f6ac GIT binary patch literal 1107 zcmV-Z1g!gsP)EX>4Tx04R}tkv&MmKpe$iQ>7vmp%xKw$WR5rf~bh2RIvyaN?V~-2a`)bgeDD1 zii@M*T5#}VvFhOBtgC~oAP9bdxVbqgx=4xtOA0MwJUH&hyL*qjcYshYGu7-E2UN{6 zQt_CW&8>)mR|L?H5JnM_n5iey3mJHhuY36TdKcwc-sk=tJxbnWfKMczWx8PzuMo3h_Ddm_ZjLe&o9B@*C%(!vfC?8=2G`ahO;vwz1sCtYoOfQ^XNP)hJ)c zx~y>C;;fddta(rV!eCxoPIH~+5aL)w0!fIFQN;$zun?tHBgI6D_G2FYLC2pYmrSk= zFmlYJ0u_?u2mgcL-I|5T2{$Pi13F)9`(qdg>;jFNZGRuzcH;!_KLb}<%U`JjGoPf_ zT3X}?=-mb`u3MVC2VCv|15dhSNRH&EDHIC8`x$*x4(PiDx>w!an)^6?05a6o(hYEM z2#gddd(GqBUG2U7d#2gn50%eywf8XBF#rGn32;bRa{vGf6951U69E94oEQKA00(qQ zO+^Rg2OJL-7V3`x-T(jq8FWQhbVF}#ZDnqB07G(RVRU6=Aa`kWXdp*PO;A^X4i^9b z0z64XK~y-)V_={VFp{fLs#rEfmtDJ=ECb9-EK6Sgd)fWq!@X1{dz{9OFJ3*hHJ7xgV_;)U3RLmW ztVphyMO+xt1P2F;ef|2i@!!9Hao@jx=lb{W9|IE;69XF?+fQCz-c>3p zDz!a5JrB_hU}j)oU@$Z^v|(amI{5SFPf=xM<*uJUf8G`p6nxCh&3){{hYyoDI5@%{ zKYm;-Dk^&L>C>l=kquySadFY$;^Nx*>({Rh`T6;#_wL>E`26{E?yFa?LSDUkmBPcr zleTHoCKEwH!R2ghY`c<@lFU#H`2YX^JOu@X(}xZnO8fBPgV?WMzdVo?eEaszE-Ncb zdCi(Nsek|e-SX_&vxO)IaB^~9eD>^_;*1$HWZBu-Uo$c?{z6f}#KgeE!}EUW(xrmz z?Ckm+92}R>1Ci6o$!Q-yKfl!X@83QD{rl(q?c29WjEs=*RZ&stdjJ0Y{NKNSuVQ9q z=FZN}Hg|V-e*?FGfq~&WJ3G7cj~_oS|M>CaDjy%8r>v~(99CA=BfPx4b3T6jsPXaR z$IA>13@_ileQSiQ86zP@L_|1${rWZQ@87@rU%!4;784VD`s>%P^9l+I^CwQ6xQ>Aq Z006lG-IivAq3Zwu002ovPDHLkV1k^B4@Cd~ literal 0 HcmV?d00001 diff --git a/Core/src/org/sleuthkit/autopsy/images/previously-unseen.png b/Core/src/org/sleuthkit/autopsy/images/previously-unseen.png new file mode 100644 index 0000000000000000000000000000000000000000..c08a1e6f3f36cdcafdd06dbe205aba58afed1a8a GIT binary patch literal 1168 zcmV;B1aJF^P)EX>4Tx04R}tkv&MmKpe$iQ>7vmp%xKw$WR5rf~bh2RIvyaN?V~-2a`)bgeDD1 zii@M*T5#}VvFhOBtgC~oAP9bdxVbqgx=4xtOA0MwJUH&hyL*qjcYshYGu7-E2UN{6 zQt_CW&8>)mR|L?H5JnM_n5iey3mJHhuY36TdKcwc-sk=tJxbnWfKMczWx8PzuMo3h_Ddm_ZjLe&o9B@*C%(!vfC?8=2G`ahO;vwz1sCtYoOfQ^XNP)hJ)c zx~y>C;;fddta(rV!eCxoPIH~+5aL)w0!fIFQN;$zun?tHBgI6D_G2FYLC2pYmrSk= zFmlYJ0u_?u2mgcL-I|5T2{$Pi13F)9`(qdg>;jFNZGRuzcH;!_KLb}<%U`JjGoPf_ zT3X}?=-mb`u3MVC2VCv|15dhSNRH&EDHIC8`x$*x4(PiDx>w!an)^6?05a6o(hYEM z2#gddd(GqBUG2U7d#2gn50%eywf8XBF#rGn32;bRa{vGf6951U69E94oEQKA00(qQ zO+^Rg2OJL<1zZOsf&c&j8FWQhbVF}#ZDnqB07G(RVRU6=Aa`kWXdp*PO;A^X4i^9b z0(nV9K~y-)wb5@#6JZ<&@ZWB`oq0TY?N-{-ExQ^uAqkwyk0rf-t0}^cRzT3 zpXbZ-0OXiQ<$I5W9(Xn^&krwNHux)R-Kt!Hp{j#iUg1Wu=zMFPzpr1redcpu@dvNX z85n_eC7D9wn6`RPN{VpAQbJOPf5&Tb1^@t_RMqZB(b);WRUq)vfz!!oFlS((nk~tj zlg5?+FhuKS7vF!;Yknnauv~%scVAy9xJLc0d{@mT+le}j**LqnZS(l525z@I-{bKd zE+{BCWHOlyJkRqC!+b0*F77RxdP{tI6Pj~;n2rMg%=GqA+{kEs7HDW_IF(E$?_(II zCkP@)5JUt3w#?7ZTNf4<)FesX@p`>CDT-27UWx$#I2?`}iA16wAv9pISgbgXujhIG zj3h}GolbWWA=D-a!WEm%_H1%;l2{3-nwpx9N2AfF2%!r;pRbc;+39pTy?ezO*=n_J z)o3(j!C>$uK@j(bhlks;4dU_mZIj9L+~@Ok_Vn~<*DM17kl}E6r_1FU1%PWRmFl|F z=`6|u2%*Ou$JMvDx9@9iZcZbFgtb3lHk)~tW%EgryozC%-|2Mz%mR&#jkjo;eiaA= z{4Fgl$MkxAD**ff08kVK7>030A`y(DsE{N{YJN7M9_ zD2fwCqp>U&i-i?MVN$8oQ5?s|OG``bU0q$=KfrSAc6+5P%a<~lOr Date: Wed, 8 Sep 2021 14:07:41 -0400 Subject: [PATCH 52/64] Switch icons --- .../autopsy/datamodel/utils/IconsUtil.java | 3 +-- .../autopsy/images/previously-seen.png | Bin 1107 -> 6455 bytes .../autopsy/images/previously-unseen.png | Bin 1168 -> 6633 bytes .../report/modules/html/HTMLReport.java | 3 +-- 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/utils/IconsUtil.java b/Core/src/org/sleuthkit/autopsy/datamodel/utils/IconsUtil.java index 69190cd175..58bf8b26d2 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/utils/IconsUtil.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/utils/IconsUtil.java @@ -132,8 +132,7 @@ public final class IconsUtil { } else if (typeID == ARTIFACT_TYPE.TSK_PREVIOUSLY_UNSEEN.getTypeID()) { imageFile = "previously-unseen.png"; //NON-NLS } else if (typeID == ARTIFACT_TYPE.TSK_PREVIOUSLY_NOTABLE.getTypeID()) { - imageFile = "previously-notable.png"; //NON-NLS - //imageFile = "red-circle-exclamation.png"; //NON-NLS + imageFile = "red-circle-exclamation.png"; //NON-NLS } else { imageFile = "artifact-icon.png"; //NON-NLS } diff --git a/Core/src/org/sleuthkit/autopsy/images/previously-seen.png b/Core/src/org/sleuthkit/autopsy/images/previously-seen.png index ed78158beb6f740de378cdeda36d1fcbc212f6ac..1bd707232e0e7824adb9b6e66fe112a683652e70 100644 GIT binary patch literal 6455 zcmeHKc{r478y`_LStCnS(?sbot6`Q*lCccNo=Q%7XXZ5~vo$leq!O}4i&LSJrIaXI zq%19@93>q~bfhdtqHyXIIZpcCL8b5OJKxuJecyl0b-gq5JkRg`-S_i*@B4n&p9|Ih*<;LqP&*|1|?#SW9S+M@Wf#W^i)0+YIJHS9NXLJRd|;je@zML_jhlU1`c z5#(d7!4Wy5bB`p}wphJgP~t)N|XA`K#!rxp<#6deNbWXFtAB^bIpNawn11!Bw2m&J`EVy zus^A1hC&TlfIV;)x3D!+DbojFWSSpdAY2(tM|AG7&$2`OBzLG-bySl_Qw2FkgYJjv z_)32Ug+{+(i7R*OvJ%K!@U2Ndt|sTEderJs%nUh& z_-7muT*s5QrTVZNlWw&3gllp08b6yP^XA7_(sok>*J89cY`*Gg|3gsQvHokZ3&Z=v z5G}j)g0FPi>ux!*AG2ApdGGL?)4y0J>3B#sUO649Upd%ZtD}^bDu=tQaI1<2n_Z`A zw%})jQKd64a?E~idn~G<)Mwh94|7D)~FN~DR_Rw!w zU`m^Sz*803%^7dIy1o9i7CPFW((bbb`FO|53zgPg5k`Rfypbj6xBjuIc+fvZFSbE# zo53Ro)u0Mv^E#0|Hm4OeF4DwZyfd@1q^hAuRB3wAc0DE9#;fVbBLiFSkr0Q8pnU@$%fm~Nap#WVeFb}V(J&8Y+QuJKmw4Zfe1dM8Bsll zEB+~Aaq(kcCt}M>^Ts~|bAL~u(MPv+uaBuj8+S^X;WaL)^tpZKEmj1Dnid$w_YSQN zNqGkxttZaa51RQ}b!2va~g})VR&Ox$AUXj@Nl5ZO08+YZOzQtfH5y&=V4K zI($UGv(EQ-bQR=B5b^Zn$Y2|$gfhZbqu%vR{HX_es6ZwjCy7Lv?hZssq0KHpMQM2fPMOw=PeD}W@Epa z(gM+wu7X4P1!1n^m76whaFHB)rrx!VHiI6w&%Jt9ZISxPHA|{#3B#;~VAx=Jr+B&G9rENTnxR`}gYeyz`4zdU)f z<0o2te121U-aZR`ZbN#xqVFI~-nEqNko?=J~( z8&pIhr9E29!|S@+e;lZIAD;W@soKGMaq)-l1;a3y+8Qo&-mPOeQ&>Vi8ej{VAUc#U zf^q`}v$P5o0jxk!ieQ2qu7HXhD!YzEaM@JkT5|@LA+iAjxDH#zpyyT>FV@yT7MYE- zS_!udr9cFHPzoSI`8WDFLM!Q)X70woC(NP$q4 zK(a(eG08y#B`h(N&|IMaA>#y?!XPOXiGQ{=LAw+)3RryR(}6Z8@(8$*W%1ZY1H z0E5S3NhmBHg(qXC+e51i#wTlmWJ*OyPfREv!r;(Y44?mng+yu_{Mp}EEhJvhV+Y0q zln8^wEYLO>6iAm$cPioqNv8V@l7O5ZCmWfJ94=opVIf0L zN3vO;aH1eFZvw++VL%?phXRp6%(yS`ko_lvuWo08d_pJ+O~?w8vCwH$q$~gmTgc+F zDHDIqNh}tVNrqHr;w(@EGLDHNnUQ2eGMjBiVv(^}i)mDJfkX-jSfGpwB1dx}9unRh zYmNi(C;%Xup$J4Q5d}b`C>+@zH1h`mJisJOqi_{-q0|O=)1#76u^}ovfM=Weo0Cu^ zJOK|y!y-VWI3fyUbq6bFhufs z$&1SeJ*9w5Hk<{XNFZ6@@MJv6f=HNV?+uD2P~OT|aac5NGHf=BVh3>oQ2ucF00+c~ z1e}liq1cE)Kq?e_357f=QWh0LW;#&~2+OHFr#K5)fUF)Sz#v;zDpSR>8sK0ihL)JW z1OE$?XMiw7@Za%#hJIqP7E42f;y_oiD|0i*lKwr<*TA2cJfJouk&46U|6x=AgtMGX zOb5tTC=Q$E-xJ(2IhyPxJnn>42*gDFQUI1rMJiGP1cU5}TL9@exx@+p1RM}*lv7pm zai05?gtcI@iA)erMERQ&2q=OXnS~M%EfX?$%P)JQxhh zbUiF(&4ogjC7frFNW|lU;xBdjm^c3hH_d)3NB@)gbl9Y|jZhQ@RcnCMHAL{Y?!N+@ zWN_xPK!HT~ccD**Ov*Ct1c73noP$m#=%B-VI_ajeL{>=u$In#u{U1F*)Zd+alfK{O z`YzWuDez6;@7eWTu5VJ{o50_*>whK}{PVjqD1e^(LZCO{IJ5l2&|CCuk;8fk3^qqo zcFDogkLp5`ic&hmR@@4Nvu&HNrLjI zfx%{MqSLIsNOzl4tO7K*z+#>b-5*A0aW&_o>*5KFKRM*0?3AoNMAFTZmw%+4uydbb zeUzdFKQ<#6U!9kNjF!I{a4^AZL3)ErP(TfP&Q|)7Re^))OAh}grVl+fXu9eC^xf`~ zZBOOL$M*Rpx*6Yk`}S?Sr&iDE^Xm+XOy_LBejU~!G1i*f+uM86O4Trhe&^xChdCa3 zT7iW59AEU>_}X!VyvLo1Hd`CqT|k9s<^Blk>yRdKPo3M>E?SIvC?h!?!#c)fjT zX(=tadoUz8_`*R)+Xq4Ig7pufd7YM^V`LI34zDap>>X{1S#539C;jzmd3m|#S?@4w zbwRF29#~=@D`1)4`B~oi5s%y3RqT=b^DmfQXRg0&pggO-u}3@_f98xP zf#J8o&u@p7xw(0PvACg6npIMwV{t?!mz$mUA~G#4ZH>ED$xQ3kUkC${*~S|ay017z z?{h?`x5~q+um&)>#R^)s(1QAE*y^J5=dI;#baZs+G!k5u7VG3?Wo50%G4MDH@BZ+$E%X>V+7JYQX1-Q>DQB9Yvz ztE)S;8&D3n%*Y0G^Ur!G3W|LWHTGRvcc>zxzBepAcf`)lZZIMH%KIY@Y0kH=6%~o1 z)bVWr1awK;fGX^HUtc7kn>IK&sFRYCQs4b5^nD?LVK|qg8Gq~QjxlE|*bgxH&s|Zc RGNFWo(QRF5=T>jp^$$pT>?!~N delta 636 zcmV-?0)zdxGSdinJfd$ODs!X{(IT|;KRLCCVUE0x>F>bs+>17_%O)9#9T|< zCVXf7)@{scn8`4YVGdpwXclSl{9^jO?dzX!axY#zwKbQtsAFJbObS%-&#XwUm_=L| z_qJv}`S z(G6f`U|?V{G&HnfVq!Y@^XE@dWo6~ApFe-z78DeG%+1Yx?8Ao-lYclkIKm!3eq1do zDthqg)2EM-4PbI{ana!7;@bJ^*RKuv`T3^z?%nhF{P}b4t5>f=UcGvi!o$OpwrSHQ z6G1`2^_;*1$HWZBu-Uo$c?{z6f}#KgeE!}EUW(xrmz?Ckm+ z92}R>1Ci6o$!Q-yKfl!X@83QD{rl(q?c29WjEs=*RZ&stdjJ0Y{NKNSuVQ9q=FZN} zHg|V-e*?FGfq~&WJ3G7cj~_oS|M>CaDjy%8r>v~(99CA=BUQY-ymLN&{HXEq+j#c`d`0(RTdKyd;06wuk#8D3iBsUoVbpG761Ub W0o|5ngrVyI0000`xXb;%z4!C<`8>~m&F3>S=UmtK_x)Yxd%nNlbxxwYtAncY zJY^URrt0Kq>k0jFuzkIYp*510t1%B_VN#D{oucl8d0j*6Pviw;#$uX5GpP1v*GCe2?ymSkA*u^sC( zwNx(+uUyiu5#v2g5Gd4SKuk;NHzW(>0z=r!S=CzPLGTA3=xz{u_C z-N}jO;@8oI9v?p9ta{sAO;RI_S1d7+iELcqv0j} z+R1t;j*^RSI;!5CuDI|tP#}kjA8Hxddg}-Vn`(5RKmlLVy(R4dBK_!EQSTfgDoNM9<8TL1m}EHB(@~`6zqwqho$mW%MPasQMc87F^ z-nv)`73Fp3^)KhWIvRE7H|G!e zkF(6Z8;$r%R}kkT>o{{dKcsgpJXXi5X;ayvG0XZAJSS<)?o3qi;*@z*&i$lrAIxB9 zPke2HKIOJrHn(jr!NLBxOYqFcuNKgiMw1u!MZC=3T9$QM({8uxb5glMYudd^&0GV< zrR}gzzE(6nJg_nB%m9#QwII2h;d(#4eV)nf5AB2H5ij%)=SE%$Wz9UM7^d4i(iETL z880xso;KK%rh7#szrfO9NvE1QdG+#ceC^xU+XDb!{@#xp6i!h)21}X?z)W5CS>5Q^ zp-_YDb2wcSQLVMZ`G)LgN3{p-3)Y>yk$pOp7pWunNn^8q8Cu1x)Uk|?DsoKmC{0YT z<%2ofw-u)LzEppZSb!kI_J`xn-rvh2h}vH?F6wkK&t$k+^p2q4YxWL(QUXSnCYM~f z&(7<%4_|iKKW)s9eLW2w^Es#|nNeAMlW~yMtDmMjbgI5^V~R^pTT|W2F=vvOD3kwa z+CENl`q=FiX&Q*Lu>ZVE-v;6>564 z#!inHiJX|hox$5`)+TikZ{**N)$9oL`e?oBrQnZ!21my-=DD~AQckvIg$OFnJT$LV zR}Mu_6_Wb&ADt-5IR^U0S5z@7LwlN5HCU^!lmBCMci%L<Edq|OI@M)7#vbrZ+p?vrxJD{PnU6Uk;O0tSIR?K)}eJ3o=gy&gUP}-8E z;-TBSYj=LlyC;R(Z=1A(93Eh^VKBLEEE^klCmWl;nmm*yQ?i@lSi3^6Zk^Y0#O&-j z>Y)wp3N@QgCFD?xl;$`GWP2;_U1ha(k*ZTta?WFa{wttp@bQzpGh5EUm11HqULu*4 zIVOHxrHrIo5Qpo_qf^TxV%^cEtuJ*Hsf{?#kpl-B&nCpJnR+Kx&0c-af!xLSX3Q1u zEQo&pK1%zkU)R7FJ&JP|Bi79*3oN6l7ihZi{K*57Czz#9$|Iza1J>F`F@0q(|I{5g zS}WhAqI#w zHwn&v?bUw^gU#}0LA$Q6%W5*f>kbf^p&7fI%$BC;{jdSbw-7LxWKUcB2@2?pf(R0c_+&IX zA|e76VT$4jHlVR25($mLp>a4Qgg^=-xgwev$rTz(DaJW$K_MW3{LJEU;ZjZ-ofjse zAP~?ze1cr+b~`aNIFUelE~6KU7-%Qx1P@&g1VH037$OpbL*hv2$??#vi_5oYu5dy{ zNKdqw#z$jO7&M3Tw+NxgF8q7GA4UkN(8CYf6BP2o1OR9k4su0?laun#~*&?Zs130RP|Y3#|Xl2S1sDu8YZ;F%->5+D!(B;E|iKoV&<0+LQ=nwbK00v=Ci z$f%^klC9mHC6kQ3<`^vg);!MJ;X_a{KMkVHh^e8cY|yKS~b~50MbM}0hPyNQxMWs z!KIjmZ;gQ$mp-(&=AZ)c?X+j2qJtiscC+C*}77L&wj?dkLE* zlL`)()i0R_NL8dDgtTyQ+y{`3<5NHojk^Ja8s$Wl{58({fnfntq8S}ShdPU?DIJL? zfegs=Bpeb;089yVa|{DV$I5Q-H+CV9DT<&8KrGmu1op z0(3@~QqvZ__M2!wl=tac1^AY4wm^c_ELee~ighDO}$riIT^?Td8|UD>j@T;)$SRq_K9t-1UB z43}ZIW|am8Cjv&#W^zJ0X!#dZ4R|5Z!(qvPw&hyZqr1@?d&U&LnDz0d#H5$P#4{e} zc%=ot@z_$^v)(tY0;zQ60d+}hp0TpOzrO}-W$!ZGt52TD$40pNg@3+V{bF=bKCXI; zh&;4pPV%|CL8}AKwoO^7boB12Z0kMg`HM8v$jiM#q9kL3gQt~XTCj_2^H1=JdOPZS zZNkFBEVt861P2G7`>-)<>3-+>+xwhD44;dd340Saoi?V-OX*K<4VLV8G*UjjfB)>- z;o)I>+`)4Ky@9^SFHza9ZA%7!SUvuC8wMU3Tp% zy~v?>S%!myLtsfs$*L-5W>(hleH6N?Z)#jmdD+ajErSF5owuE)E=j6c?|#nztf@h2 zfJxHB3mrojHd?NGl{)`D>!W4t^>>|}vo4sWkI;+S7vC(N2YVAmx$*Q*rbP0&q^GAx z;X(&ezhXes%BB7@zVm(g@Q8S4v_+QY`+^VC<0*4=h^-IpAoIeU>|Aa0SFYduKT}ao A(*OVf delta 713 zcmV;)0yh2WGmr_8BNYLKX+uL$Nkc;*aB^>EX>4Tx04R~O9R_v*1otr4F_ZWfA_f-) zTn8h9lOPu;e|bqnK~y-)wb5@#6JZ<&@ZWB`oq0TY?N-{-ExQ^uAqkwyk0rf z-t0}^cRzT3pXbZ-0OXiQ<$I5W9(Xn^&krwNHux)Rf8DBFfuX8{TwdWuvFLnjoxiVN zyM5+!VDSg9%^4VhbtRcXbNDN72~{z*Qjd(t*>- zXfS7Bpqeeoo0G>mf@fcM>7gCJ4e6o6YuYe{yn?SP7__nwpMBqtT}bp$k5ruajlj z>2x~1d&L>qYPD|FXf$QPVDKeD5ch_Mhug9Z;_>)xlgael=ks;;^z>-gECT?L;c$4T z%jFscfNLt1>bleEEXo21p~oD@)wj2|?`v*uP9ubbwLf4sn|YRH^GTAtieZ@F>2&_g ze*%q-jkjo;eiaA={4Fgl$MkxAD**ff08kVK7>030A`y(DsE{N{YJN7M9_D2fwCqp>U&i-i?MVN$8oQ5?s|OG``bU0q$=KfrSAc6+5P%a<~l vOr Date: Wed, 8 Sep 2021 14:38:40 -0400 Subject: [PATCH 53/64] Fixed string content page number issue --- .../textcontentviewer/Bundle.properties | 2 +- .../Bundle.properties-MERGED | 2 +- .../StringsContentPanel.form | 15 ++------ .../StringsContentPanel.java | 35 +++---------------- 4 files changed, 9 insertions(+), 45 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/Bundle.properties b/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/Bundle.properties index 341efff6d6..fb7c0f33cc 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/Bundle.properties @@ -8,7 +8,7 @@ StringsContentPanel.selectAllMenuItem.text=Select All StringsContentPanel.currentPageLabel.text_1=1 StringsContentPanel.copyMenuItem.text=Copy StringsContentPanel.ofLabel.text_1=of -StringsContentPanel.totalPageLabel.text_1=100 +StringsContentPanel.totalPageLabel.text_1=1000 StringsContentPanel.languageLabel.toolTipText= StringsContentPanel.languageLabel.text=Script: StringsContentPanel.languageCombo.toolTipText=Language to attempt when interpreting (extracting and decoding) strings from binary data diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/Bundle.properties-MERGED index 024103570d..c859dc8f33 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/Bundle.properties-MERGED @@ -9,7 +9,7 @@ StringsContentPanel.selectAllMenuItem.text=Select All StringsContentPanel.currentPageLabel.text_1=1 StringsContentPanel.copyMenuItem.text=Copy StringsContentPanel.ofLabel.text_1=of -StringsContentPanel.totalPageLabel.text_1=100 +StringsContentPanel.totalPageLabel.text_1=1000 StringsContentPanel.languageLabel.toolTipText= StringsContentPanel.languageLabel.text=Script: StringsContentPanel.languageCombo.toolTipText=Language to attempt when interpreting (extracting and decoding) strings from binary data diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/StringsContentPanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/StringsContentPanel.form index 6253570c82..6c579799b6 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/StringsContentPanel.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/StringsContentPanel.form @@ -103,15 +103,6 @@ - - - - - - - - - @@ -158,13 +149,13 @@ - + - + - + diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/StringsContentPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/StringsContentPanel.java index 750f143e0e..e83dadadef 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/StringsContentPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/StringsContentPanel.java @@ -95,12 +95,11 @@ public class StringsContentPanel extends javax.swing.JPanel { currentPage = 1; currentOffset = 0; this.dataSource = null; - currentPageLabel.setText(""); + currentPageLabel.setText("1"); totalPageLabel.setText(""); prevPageButton.setEnabled(false); nextPageButton.setEnabled(false); outputViewPane.setText(""); // reset the output view - setComponentsVisibility(false); // hides the components that not needed } /** @@ -167,9 +166,6 @@ public class StringsContentPanel extends javax.swing.JPanel { panelPageOfCount.add(jSepMed1); currentPageLabel.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.currentPageLabel.text_1")); // NOI18N - currentPageLabel.setMaximumSize(new java.awt.Dimension(18, 25)); - currentPageLabel.setMinimumSize(new java.awt.Dimension(7, 25)); - currentPageLabel.setPreferredSize(new java.awt.Dimension(18, 25)); panelPageOfCount.add(currentPageLabel); jSepMed2.setPreferredSize(new java.awt.Dimension(5, 0)); @@ -185,9 +181,9 @@ public class StringsContentPanel extends javax.swing.JPanel { panelPageOfCount.add(jSepMed3); totalPageLabel.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.totalPageLabel.text_1")); // NOI18N - totalPageLabel.setMaximumSize(new java.awt.Dimension(21, 25)); - totalPageLabel.setMinimumSize(new java.awt.Dimension(21, 25)); - totalPageLabel.setPreferredSize(new java.awt.Dimension(21, 25)); + totalPageLabel.setMaximumSize(new java.awt.Dimension(25, 25)); + totalPageLabel.setMinimumSize(new java.awt.Dimension(25, 25)); + totalPageLabel.setPreferredSize(new java.awt.Dimension(25, 25)); panelPageOfCount.add(totalPageLabel); jSepMed4.setPreferredSize(new java.awt.Dimension(5, 0)); @@ -409,24 +405,6 @@ public class StringsContentPanel extends javax.swing.JPanel { worker.execute(); } - /** - * To set the visibility of specific components in this class. - * - * @param isVisible whether to show or hide the specific components - */ - private void setComponentsVisibility(boolean isVisible) { - currentPageLabel.setVisible(isVisible); - totalPageLabel.setVisible(isVisible); - ofLabel.setVisible(isVisible); - prevPageButton.setVisible(isVisible); - nextPageButton.setVisible(isVisible); - pageLabel.setVisible(isVisible); - pageLabel2.setVisible(isVisible); - goToPageTextField.setVisible(isVisible); - goToPageLabel.setVisible(isVisible); - languageCombo.setVisible(isVisible); - languageLabel.setVisible(isVisible); - } /** * Swingworker for getting the text from a content object. @@ -509,9 +487,7 @@ public class StringsContentPanel extends javax.swing.JPanel { int totalPage = Math.round((dataSource.getSize() - 1) / PAGE_LENGTH) + 1; totalPageLabel.setText(Integer.toString(totalPage)); - currentPageLabel.setText("1"); outputViewPane.setText(text); // set the output view - setComponentsVisibility(true); // shows the components that not needed outputViewPane.moveCaretPosition(0); setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); @@ -557,10 +533,7 @@ public class StringsContentPanel extends javax.swing.JPanel { prevPageButton.setEnabled(false); currentPage = 1; - totalPageLabel.setText("1"); - currentPageLabel.setText("1"); outputViewPane.setText(text); // set the output view - setComponentsVisibility(true); // shows the components that not needed outputViewPane.moveCaretPosition(0); setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); From 722cb2d898799b066dcaaac24f4c9dbef11c3c6c Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Wed, 8 Sep 2021 15:07:38 -0400 Subject: [PATCH 54/64] 7797 fix analysis result tagging --- .../datamodel/BlackboardArtifactItem.java | 43 +++++++++++++++++++ .../autopsy/datamodel/DataArtifactItem.java | 41 ++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100755 Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactItem.java create mode 100755 Core/src/org/sleuthkit/autopsy/datamodel/DataArtifactItem.java diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactItem.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactItem.java new file mode 100755 index 0000000000..3897e37311 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactItem.java @@ -0,0 +1,43 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2021-2021 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.datamodel; + +import com.google.common.annotations.Beta; +import org.sleuthkit.datamodel.BlackboardArtifact; + +/** + * An abstract super class for an Autopsy Data Model item class with an + * underlying BlackboardArtifact Sleuth Kit Data Model object. + * + * @param The concrete BlackboardArtifact sub class type. + */ +public abstract class BlackboardArtifactItem extends TskContentItem { + + /** + * Constructs an Autopsy Data Model item with an underlying + * BlackboardArtifact Sleuth Kit Data Model object. + * + * @param blackboardArtifact The BlackboardArtifact object. + */ + @Beta + BlackboardArtifactItem(T blackboardArtifact) { + super(blackboardArtifact); + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DataArtifactItem.java b/Core/src/org/sleuthkit/autopsy/datamodel/DataArtifactItem.java new file mode 100755 index 0000000000..c43d3a311c --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DataArtifactItem.java @@ -0,0 +1,41 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2021-2021 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.datamodel; + +import com.google.common.annotations.Beta; +import org.sleuthkit.datamodel.DataArtifact; + +/** + * An Autopsy Data Model item with an underlying DataArtifact Sleuth Kit Data + * Model object. + */ +public class DataArtifactItem extends BlackboardArtifactItem { + + /** + * Constructs an Autopsy Data Model item with an underlying DataArtifact + * Sleuth Kit Data Model object. + * + * @param dataArtifact The DataArtifact object. + */ + @Beta + DataArtifactItem(DataArtifact dataArtifact) { + super(dataArtifact); + } + +} From cae2fd798dae95836415ebe70635ef9686d51972 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Wed, 8 Sep 2021 15:14:02 -0400 Subject: [PATCH 55/64] 7797 fix analysis result tagging --- .../AddBlackboardArtifactTagAction.java | 19 +++++++++-- .../autopsy/actions/AddTagAction.java | 32 +++++++++++++------ .../AnalysisResultsContentViewer.java | 2 +- .../AnalysisResultsViewModel.java | 6 ++-- .../datamodel/AbstractContentNode.java | 2 +- .../autopsy/datamodel/AnalysisResultItem.java | 16 ++-------- .../datamodel/BlackboardArtifactItem.java | 3 +- .../datamodel/BlackboardArtifactNode.java | 17 ++++++---- .../autopsy/datamodel/TskContentItem.java | 16 ++++++---- 9 files changed, 70 insertions(+), 43 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/actions/AddBlackboardArtifactTagAction.java b/Core/src/org/sleuthkit/autopsy/actions/AddBlackboardArtifactTagAction.java index 26d1c7a9bc..06a3e2e39e 100644 --- a/Core/src/org/sleuthkit/autopsy/actions/AddBlackboardArtifactTagAction.java +++ b/Core/src/org/sleuthkit/autopsy/actions/AddBlackboardArtifactTagAction.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2019 Basis Technology Corp. + * Copyright 2013-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -29,6 +29,7 @@ import org.openide.windows.WindowManager; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.datamodel.BlackboardArtifactItem; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.TagName; @@ -46,6 +47,8 @@ import org.sleuthkit.datamodel.TskCoreException; }) public class AddBlackboardArtifactTagAction extends AddTagAction { + private static final long serialVersionUID = 1L; + // This class is a singleton to support multi-selection of nodes, since // org.openide.nodes.NodeOp.findActions(Node[] nodes) will only pick up an Action if every // node in the array returns a reference to the same action object from Node.getActions(boolean). @@ -82,8 +85,14 @@ public class AddBlackboardArtifactTagAction extends AddTagAction { * invocation of addTag(), we don't want to tag the same * BlackboardArtifact more than once, so we dedupe the * BlackboardArtifacts by stuffing them into a HashSet. + * + * RC (9/8/21): The documentation does NOT say that lookupAll() can + * return duplicates. That would be very broken. What motivated this + * "de-duping" ? */ - selectedArtifacts.addAll(Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class)); + for (BlackboardArtifactItem item : Utilities.actionsGlobalContext().lookupAll(BlackboardArtifactItem.class)) { + selectedArtifacts.add(item.getTskContent()); + } } else { for (Content content : getContentToTag()) { if (content instanceof BlackboardArtifact) { @@ -111,4 +120,10 @@ public class AddBlackboardArtifactTagAction extends AddTagAction { } }).start(); } + + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + } diff --git a/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java b/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java index 9c059205f5..725cdb504d 100644 --- a/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java +++ b/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2013-2020 Basis Technology Corp. + * Copyright 2013-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -44,33 +44,40 @@ import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; /** - * An abstract base class for Actions that allow users to tag SleuthKit data + * An abstract base class for Actions that allow users to tag Sleuth Kit data * model objects. */ abstract class AddTagAction extends AbstractAction implements Presenter.Popup { private static final long serialVersionUID = 1L; private static final String NO_COMMENT = ""; - private final Collection content = new HashSet<>(); + private final Collection contentObjsToTag; + /** + * Constructs an instance of an abstract base class for Actions that allow + * users to tag Sleuth Kit data model objects. + * + * @param menuText The menu item text. + */ AddTagAction(String menuText) { super(menuText); + contentObjsToTag = new HashSet<>(); } @Override public JMenuItem getPopupPresenter() { - content.clear(); + contentObjsToTag.clear(); return new TagMenu(); } /** - * Get the collection of content which may have been specified for this + * Getz the collection of content which may have been specified for this * action. Empty collection returned when no content was specified. * * @return The specified content for this action. */ Collection getContentToTag() { - return Collections.unmodifiableCollection(content); + return Collections.unmodifiableCollection(contentObjsToTag); } /** @@ -83,8 +90,8 @@ abstract class AddTagAction extends AbstractAction implements Presenter.Popup { * apply to the Content specified. */ public JMenuItem getMenuForContent(Collection contentToTag) { - content.clear(); - content.addAll(contentToTag); + contentObjsToTag.clear(); + contentObjsToTag.addAll(contentToTag); return new TagMenu(); } @@ -111,6 +118,11 @@ abstract class AddTagAction extends AbstractAction implements Presenter.Popup { */ abstract protected void addTag(TagName tagName, String comment); + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + /** * Instances of this class implement a context menu user interface for * creating or selecting a tag name for a tag and specifying an optional tag @@ -126,7 +138,7 @@ abstract class AddTagAction extends AbstractAction implements Presenter.Popup { super(getActionDisplayName()); // Get the current set of tag names. - Map tagNamesMap = null; + Map tagNamesMap; List standardTagNames = TagsManager.getStandardTagNames(); Map tagSetMenuMap = new HashMap<>(); List standardTagMenuitems = new ArrayList<>(); @@ -240,5 +252,7 @@ abstract class AddTagAction extends AbstractAction implements Presenter.Popup { return tagNameItem; } + } + } diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentViewer.java index b056eb11db..d40f6c2a39 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentViewer.java @@ -132,7 +132,7 @@ public class AnalysisResultsContentViewer implements DataContentViewer { return true; } - TskContentItem contentItem = node.getLookup().lookup(TskContentItem.class); + TskContentItem contentItem = node.getLookup().lookup(TskContentItem.class); if (!Objects.isNull(contentItem)) { Content content = contentItem.getTskContent(); try { diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsViewModel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsViewModel.java index 37e4114168..b470f9dfb7 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsViewModel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsViewModel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2021 Basis Technology Corp. + * Copyright 2021-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -251,7 +251,7 @@ public class AnalysisResultsViewModel { * selected in the content viewer and get the analyzed content * as the source of the analysis results to display. */ - selectedAnalysisResult = analysisResultItem.getAnalysisResult(); + selectedAnalysisResult = analysisResultItem.getTskContent(); selectedObjectId = selectedAnalysisResult.getId(); analyzedContent = selectedAnalysisResult.getParent(); } else { @@ -260,7 +260,7 @@ public class AnalysisResultsViewModel { * an analysis result. Use it as the source of the analysis * results to display. */ - TskContentItem contentItem = node.getLookup().lookup(TskContentItem.class); + TskContentItem contentItem = node.getLookup().lookup(TskContentItem.class); analyzedContent = contentItem.getTskContent(); selectedObjectId = analyzedContent.getId(); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentNode.java index daf8cd84da..2b8428280a 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentNode.java @@ -102,7 +102,7 @@ public abstract class AbstractContentNode extends ContentNode * @param content Underlying Content instances */ AbstractContentNode(T content) { - this(content, Lookups.fixed(content, new TskContentItem(content))); + this(content, Lookups.fixed(content, new TskContentItem<>(content))); } /** diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AnalysisResultItem.java b/Core/src/org/sleuthkit/autopsy/datamodel/AnalysisResultItem.java index 442d070f5c..20ee3652c0 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AnalysisResultItem.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AnalysisResultItem.java @@ -22,30 +22,20 @@ import com.google.common.annotations.Beta; import org.sleuthkit.datamodel.AnalysisResult; /** - * An Autopsy Data Model item with an underlying analysis result Sleuth Kit Data + * An Autopsy Data Model item with an underlying AnalysisResult Sleuth Kit Data * Model object. */ -public class AnalysisResultItem extends TskContentItem { +public class AnalysisResultItem extends BlackboardArtifactItem { /** * Constructs an Autopsy Data Model item with an underlying AnalysisResult * Sleuth Kit Data Model object. * - * @param analysisResult The analysis result. + * @param analysisResult The AnalysisResult object. */ @Beta AnalysisResultItem(AnalysisResult analysisResult) { super(analysisResult); } - /** - * Gets the underlying analysis result. - * - * @return The analysis result. - */ - @Beta - public AnalysisResult getAnalysisResult() { - return (AnalysisResult) (getTskContent()); - } - } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactItem.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactItem.java index 3897e37311..8d4cab5ea5 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactItem.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactItem.java @@ -23,7 +23,8 @@ import org.sleuthkit.datamodel.BlackboardArtifact; /** * An abstract super class for an Autopsy Data Model item class with an - * underlying BlackboardArtifact Sleuth Kit Data Model object. + * underlying BlackboardArtifact Sleuth Kit Data Model object, i.e., a + * DataArtifact or an AnalysisResult. * * @param The concrete BlackboardArtifact sub class type. */ diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 469c069aae..0072654ccb 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -81,6 +81,7 @@ import org.sleuthkit.autopsy.texttranslation.TextTranslationService; import org.sleuthkit.autopsy.datamodel.utils.FileNameTransTask; import org.sleuthkit.datamodel.AnalysisResult; import org.sleuthkit.datamodel.BlackboardArtifact.Category; +import org.sleuthkit.datamodel.DataArtifact; import org.sleuthkit.datamodel.Score; /** @@ -232,7 +233,7 @@ public class BlackboardArtifactNode extends AbstractContentNode artifactItem; if (artifact instanceof AnalysisResult) { artifactItem = new AnalysisResultItem((AnalysisResult) artifact); } else { - artifactItem = new TskContentItem(artifact); + artifactItem = new DataArtifactItem((DataArtifact) artifact); } /* * Create the Lookup. + * + * NOTE: For now, we are putting both the Autopsy Data Model item and + * the Sleuth Kit Data Model item in the Lookup so that code that is not + * aware of the new Autopsy Data Model will still function. */ if (content == null) { return Lookups.fixed(artifact, artifactItem); @@ -385,7 +390,7 @@ public class BlackboardArtifactNode extends AbstractContentNode The type of the underlying Sleuth Kit Data Model object. */ @Beta -public class TskContentItem { +public class TskContentItem { - private final Content tskContent; + private final T content; /** * Constructs an Autopsy Data Model item with an underlying Sleuth Kit Data * Model object that implements the Sleuth Kit Data Model's Content * interface. * - * @param content The underlying Sleuth Kit Data Model object. + * @param content The Sleuth Kit Data Model object. * */ @Beta - TskContentItem(Content sleuthKitContent) { - this.tskContent = sleuthKitContent; + TskContentItem(T content) { + this.content = content; } /** @@ -49,8 +51,8 @@ public class TskContentItem { * @return The Sleuth Kit Data Model object. */ @Beta - public Content getTskContent() { - return tskContent; + public T getTskContent() { + return content; } } From d03c1dc789bef8d0e14579373370c33e1b06202a Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Wed, 8 Sep 2021 15:20:38 -0400 Subject: [PATCH 56/64] 7797 fix analysis result tagging --- Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java | 6 +++--- .../sleuthkit/autopsy/datamodel/AbstractContentNode.java | 3 +-- .../sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java b/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java index 725cdb504d..ff3dc08e04 100644 --- a/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java +++ b/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java @@ -44,7 +44,7 @@ import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; /** - * An abstract base class for Actions that allow users to tag Sleuth Kit data + * An abstract super class for Actions that allow users to tag Sleuth Kit data * model objects. */ abstract class AddTagAction extends AbstractAction implements Presenter.Popup { @@ -54,7 +54,7 @@ abstract class AddTagAction extends AbstractAction implements Presenter.Popup { private final Collection contentObjsToTag; /** - * Constructs an instance of an abstract base class for Actions that allow + * Constructs an instance of an abstract super class for Actions that allow * users to tag Sleuth Kit data model objects. * * @param menuText The menu item text. @@ -71,7 +71,7 @@ abstract class AddTagAction extends AbstractAction implements Presenter.Popup { } /** - * Getz the collection of content which may have been specified for this + * Get the collection of content which may have been specified for this * action. Empty collection returned when no content was specified. * * @return The specified content for this action. diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentNode.java index 2b8428280a..cb4bb9794c 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentNode.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2019 Basis Technology Corp. + * Copyright 2012-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -39,7 +39,6 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeIns import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance.Type; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.datamodel.AnalysisResult; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Score; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 0072654ccb..f11c75784e 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -368,7 +368,7 @@ public class BlackboardArtifactNode extends AbstractContentNode artifactItem; if (artifact instanceof AnalysisResult) { From b8598d0b1413c7aa57db2ce4a3b01bcb5352d20f Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Wed, 8 Sep 2021 16:15:50 -0400 Subject: [PATCH 57/64] 7959 comment out data artifacts ingest pipeline --- .../CentralRepoIngestModuleFactory.java | 18 ++++++++--------- .../ingest/DataArtifactIngestPipeline.java | 8 ++++---- .../autopsy/ingest/IngestJobPipeline.java | 20 +++++++++---------- .../autopsy/ingest/IngestJobSettings.java | 2 +- .../autopsy/ingest/IngestModuleFactory.java | 14 ++++++------- .../autopsy/ingest/IngestModuleTemplate.java | 12 +++++------ 6 files changed, 37 insertions(+), 37 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModuleFactory.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModuleFactory.java index 39c80abefc..22ce22f65f 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModuleFactory.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModuleFactory.java @@ -121,14 +121,14 @@ public class CentralRepoIngestModuleFactory extends IngestModuleFactoryAdapter { throw new IllegalArgumentException("Expected settings argument to be an instance of IngestSettings"); } - @Override - public boolean isDataArtifactIngestModuleFactory() { - return true; - } - - @Override - public DataArtifactIngestModule createDataArtifactIngestModule(IngestModuleIngestJobSettings settings) { - return new CentralRepoDataArtifactIngestModule(); - } +// @Override +// public boolean isDataArtifactIngestModuleFactory() { +// return true; +// } +// +// @Override +// public DataArtifactIngestModule createDataArtifactIngestModule(IngestModuleIngestJobSettings settings) { +// return new CentralRepoDataArtifactIngestModule(); +// } } diff --git a/Core/src/org/sleuthkit/autopsy/ingest/DataArtifactIngestPipeline.java b/Core/src/org/sleuthkit/autopsy/ingest/DataArtifactIngestPipeline.java index 824d7d7fe9..a25485a352 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/DataArtifactIngestPipeline.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/DataArtifactIngestPipeline.java @@ -44,10 +44,10 @@ final class DataArtifactIngestPipeline extends IngestTaskPipeline> acceptModuleTemplate(IngestModuleTemplate template) { Optional> module = Optional.empty(); - if (template.isDataArtifactIngestModuleTemplate()) { - DataArtifactIngestModule ingestModule = template.createDataArtifactIngestModule(); - module = Optional.of(new DataArtifactIngestPipelineModule(ingestModule, template.getModuleName())); - } +// if (template.isDataArtifactIngestModuleTemplate()) { +// DataArtifactIngestModule ingestModule = template.createDataArtifactIngestModule(); +// module = Optional.of(new DataArtifactIngestPipelineModule(ingestModule, template.getModuleName())); +// } return module; } diff --git a/Core/src/org/sleuthkit/autopsy/ingest/IngestJobPipeline.java b/Core/src/org/sleuthkit/autopsy/ingest/IngestJobPipeline.java index c68dde5911..bdaaa9f3a9 100644 --- a/Core/src/org/sleuthkit/autopsy/ingest/IngestJobPipeline.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/IngestJobPipeline.java @@ -368,9 +368,9 @@ final class IngestJobPipeline { if (template.isFileIngestModuleTemplate()) { addModuleTemplateToSortingMap(javaFileModuleTemplates, jythonFileModuleTemplates, template); } - if (template.isDataArtifactIngestModuleTemplate()) { - addModuleTemplateToSortingMap(javaArtifactModuleTemplates, jythonArtifactModuleTemplates, template); - } +// if (template.isDataArtifactIngestModuleTemplate()) { +// addModuleTemplateToSortingMap(javaArtifactModuleTemplates, jythonArtifactModuleTemplates, template); +// } } /** @@ -616,13 +616,13 @@ final class IngestJobPipeline { type = IngestModuleType.MULTIPLE; } } - if (moduleTemplate.isDataArtifactIngestModuleTemplate()) { - if (type == null) { - type = IngestModuleType.DATA_ARTIFACT; - } else { - type = IngestModuleType.MULTIPLE; - } - } +// if (moduleTemplate.isDataArtifactIngestModuleTemplate()) { +// if (type == null) { +// type = IngestModuleType.DATA_ARTIFACT; +// } else { +// type = IngestModuleType.MULTIPLE; +// } +// } return type; } diff --git a/Core/src/org/sleuthkit/autopsy/ingest/IngestJobSettings.java b/Core/src/org/sleuthkit/autopsy/ingest/IngestJobSettings.java index 7de83ded4c..8f2db29849 100644 --- a/Core/src/org/sleuthkit/autopsy/ingest/IngestJobSettings.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/IngestJobSettings.java @@ -318,7 +318,7 @@ public final class IngestJobSettings { // Add modules that are going to be used for this ingest depending on type. for (IngestModuleFactory moduleFactory : allModuleFactories) { - if (moduleFactory.isDataArtifactIngestModuleFactory() || ingestType.equals(IngestType.ALL_MODULES)) { + if (/*moduleFactory.isDataArtifactIngestModuleFactory() ||*/ ingestType.equals(IngestType.ALL_MODULES)) { moduleFactories.add(moduleFactory); } else if (this.ingestType.equals(IngestType.DATA_SOURCE_ONLY) && moduleFactory.isDataSourceIngestModuleFactory()) { moduleFactories.add(moduleFactory); diff --git a/Core/src/org/sleuthkit/autopsy/ingest/IngestModuleFactory.java b/Core/src/org/sleuthkit/autopsy/ingest/IngestModuleFactory.java index e473086d18..15fb96eded 100644 --- a/Core/src/org/sleuthkit/autopsy/ingest/IngestModuleFactory.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/IngestModuleFactory.java @@ -228,7 +228,7 @@ public interface IngestModuleFactory { * * @return A file ingest module instance. */ - default FileIngestModule createFileIngestModule(IngestModuleIngestJobSettings ingestOptions) { + default FileIngestModule createFileIngestModule(IngestModuleIngestJobSettings settings) { throw new UnsupportedOperationException(); } @@ -238,9 +238,9 @@ public interface IngestModuleFactory { * * @return True or false. */ - default boolean isDataArtifactIngestModuleFactory() { - return false; - } +// default boolean isDataArtifactIngestModuleFactory() { +// return false; +// } /** * Creates a data artifact ingest module instance. @@ -267,8 +267,8 @@ public interface IngestModuleFactory { * * @return A file ingest module instance. */ - default DataArtifactIngestModule createDataArtifactIngestModule(IngestModuleIngestJobSettings settings) { - throw new UnsupportedOperationException(); - } +// default DataArtifactIngestModule createDataArtifactIngestModule(IngestModuleIngestJobSettings settings) { +// throw new UnsupportedOperationException(); +// } } diff --git a/Core/src/org/sleuthkit/autopsy/ingest/IngestModuleTemplate.java b/Core/src/org/sleuthkit/autopsy/ingest/IngestModuleTemplate.java index 26285f6439..0bb947c1cd 100644 --- a/Core/src/org/sleuthkit/autopsy/ingest/IngestModuleTemplate.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/IngestModuleTemplate.java @@ -85,13 +85,13 @@ public final class IngestModuleTemplate { return moduleFactory.createFileIngestModule(settings); } - public boolean isDataArtifactIngestModuleTemplate() { - return moduleFactory.isDataArtifactIngestModuleFactory(); - } +// public boolean isDataArtifactIngestModuleTemplate() { +// return moduleFactory.isDataArtifactIngestModuleFactory(); +// } - public DataArtifactIngestModule createDataArtifactIngestModule() { - return moduleFactory.createDataArtifactIngestModule(settings); - } +// public DataArtifactIngestModule createDataArtifactIngestModule() { +// return moduleFactory.createDataArtifactIngestModule(settings); +// } public void setEnabled(boolean enabled) { this.enabled = enabled; From 16a3ca7e72ce328a482d2ad13fdd4dbe764bc360 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Wed, 8 Sep 2021 20:37:52 -0400 Subject: [PATCH 58/64] Removed flagging of previously seen personas --- .../eventlisteners/IngestEventsListener.java | 98 +------------------ 1 file changed, 1 insertion(+), 97 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java index 1dad86dd90..cd9e03c9aa 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java @@ -42,7 +42,6 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeIns import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeUtil; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; -import org.sleuthkit.autopsy.centralrepository.datamodel.PersonaAccount; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.ModuleDataEvent; @@ -57,15 +56,12 @@ import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CORRELATION_TYPE; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CORRELATION_VALUE; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_OTHER_CASES; -import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME; -import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT; import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisEvent; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Image; import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; -import org.sleuthkit.autopsy.centralrepository.datamodel.Persona; import org.sleuthkit.datamodel.Score; import org.sleuthkit.datamodel.TskData; @@ -318,77 +314,7 @@ public class IngestEventsListener { value)); makeAndPostArtifact(BlackboardArtifact.Type.TSK_PREVIOUSLY_UNSEEN, originalArtifact, attributesForNewArtifact, "", Score.SCORE_LIKELY_NOTABLE, "This application has not been previously seen before"); - } - - /** - * *TEMPORARY* Create a "matching persona" hit for an artifact with an account identifier - * associated with a persona - * - * @param originalArtifact the artifact to create the "previously unseen" item - * for - */ - static private void makeAndPostMatchingPersonaArtifact(BlackboardArtifact originalArtifact, Persona persona, - List caseDisplayNames, CorrelationAttributeInstance.Type aType, String value) { - String prevCases = caseDisplayNames.stream().distinct().collect(Collectors.joining(",")); - Collection attributesForNewArtifact = Arrays.asList( - new BlackboardAttribute( - TSK_NAME, MODULE_NAME, - persona.getName()), - new BlackboardAttribute( - TSK_COMMENT, MODULE_NAME, - persona.getComment()), - new BlackboardAttribute( - TSK_CORRELATION_TYPE, MODULE_NAME, - aType.getDisplayName()), - new BlackboardAttribute( - TSK_CORRELATION_VALUE, MODULE_NAME, - value), - new BlackboardAttribute( - TSK_OTHER_CASES, MODULE_NAME, - prevCases) - ); - makeAndPostPersonaArtifact(BlackboardArtifact.Type.TSK_MATCHING_PERSONA, originalArtifact, attributesForNewArtifact, "", - Score.SCORE_LIKELY_NOTABLE, "This account is associated with a persona"); - } - - /** - * *TEMPORARY* Hack to get all the flagged personas associated with the same file to prevent - * duplicates (associate with source file not the account instance artifact). - * Make an artifact to flag the passed in content. - * - * @param originalArtifact Artifact in current case we want to flag - * @param attributesForNewArtifact Attributes to assign to the new artifact - * @param configuration The configuration to be specified for the new artifact hit - * @param score sleuthkit.datamodel.Score to be assigned to this artifact - * @param justification Justification string - */ - private static void makeAndPostPersonaArtifact(BlackboardArtifact.Type newArtifactType, BlackboardArtifact originalArtifact, Collection attributesForNewArtifact, String configuration, - Score score, String justification) { - try { - SleuthkitCase tskCase = originalArtifact.getSleuthkitCase(); - Content originalContent = originalArtifact.getParent(); // Associate artifact with file instead of artifact - Blackboard blackboard = tskCase.getBlackboard(); - // Create artifact if it doesn't already exist. - BlackboardArtifact.ARTIFACT_TYPE type = BlackboardArtifact.ARTIFACT_TYPE.fromID(newArtifactType.getTypeID()); - if (!blackboard.artifactExists(originalContent, type, attributesForNewArtifact)) { - BlackboardArtifact newArtifact = originalContent.newAnalysisResult( - newArtifactType, score, - null, configuration, justification, attributesForNewArtifact) - .getAnalysisResult(); - - try { - // index the artifact for keyword search - blackboard.postArtifact(newArtifact, MODULE_NAME); - } catch (Blackboard.BlackboardException ex) { - LOGGER.log(Level.SEVERE, "Unable to index blackboard artifact " + newArtifact.getArtifactID(), ex); //NON-NLS - } - } - } catch (TskCoreException ex) { - LOGGER.log(Level.SEVERE, "Failed to create BlackboardArtifact.", ex); // NON-NLS - } catch (IllegalStateException ex) { - LOGGER.log(Level.SEVERE, "Failed to create BlackboardAttribute.", ex); // NON-NLS - } - } + } /** * Make an artifact to flag the passed in artifact. @@ -669,28 +595,6 @@ public class IngestEventsListener { makeAndPostPreviousSeenArtifact(bbArtifact, caseDisplayNames, eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); } - // *TEMPORARY* If we have a field that could be associated with a persona, check whether it is - // and make an artifact if so. Applicable types should be expanded later. - if (flagPreviousItemsEnabled && - ((eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.EMAIL_TYPE_ID) - || eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.PHONE_TYPE_ID)) { - String accountId = eamArtifact.getCorrelationValue(); - Collection personaMatches = Persona.getPersonaByAccountIdentifierLike(accountId); - for (Persona persona : personaMatches) { - // Make sure at least one account is an exact match. - boolean foundExactMatch = false; - for (PersonaAccount personaAccount : persona.getPersonaAccounts()) { - if (accountId.equalsIgnoreCase(personaAccount.getAccount().getIdentifier())) { - foundExactMatch = true; - } - } - if (foundExactMatch) { - List caseDisplayNames = persona.getCases().stream().map(p -> p.getDisplayName()).collect(Collectors.toList()); - makeAndPostMatchingPersonaArtifact(bbArtifact, persona, caseDisplayNames, eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); - } - } - } - // flag previously unseen apps and domains if (flagUniqueItemsEnabled && (eamArtifact.getCorrelationType().getId() == CorrelationAttributeInstance.INSTALLED_PROGS_TYPE_ID From 37e4b4a6d87ea7c941af7c3ae09524d571155c0d Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Thu, 9 Sep 2021 09:50:18 -0400 Subject: [PATCH 59/64] Update shellbags_xp.pl Fix output of characters for shellbags_xp --- thirdparty/rr-full/plugins/shellbags_xp.pl | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/thirdparty/rr-full/plugins/shellbags_xp.pl b/thirdparty/rr-full/plugins/shellbags_xp.pl index 4eaea3e58d..25082ea89b 100644 --- a/thirdparty/rr-full/plugins/shellbags_xp.pl +++ b/thirdparty/rr-full/plugins/shellbags_xp.pl @@ -37,9 +37,6 @@ package shellbags_xp; use strict; use Time::Local; -require 'shellitems.pl'; - - my %config = (hive => "NTUSER\.DAT", hivemask => 32, output => "report", @@ -779,13 +776,13 @@ sub parseFolderEntry { $str = substr($data,$ofs,length($data) - 30); my $longname = (split(/\x00\x00/,$str,2))[0]; - $longname =~ s/\x00//g; - + $longname = $longname.chr 0x00; + if ($longname ne "") { $item{name} = Utf16ToUtf8($longname); } else { - $item{name} = _Utf16ToUtf8($shortname); + $item{name} = Utf16ToUtf8($shortname); } return %item; } @@ -934,5 +931,14 @@ sub printData { return @display; } +#--------------------------------------------------------------------- +# Utf16ToUtf8() +#--------------------------------------------------------------------- +sub Utf16ToUtf8 { + my $str = $_[0]; + Encode::from_to($str,'UTF-16LE','utf8'); + my $str2 = Encode::decode_utf8($str); + return $str; +} 1; From 3c7bc6cceff2d185949e319de909c6dc21c7d164 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Thu, 9 Sep 2021 12:01:31 -0400 Subject: [PATCH 60/64] Bug fix --- .../experimental/autoingest/Manifest.java | 31 +++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Manifest.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Manifest.java index c2b7ae5259..4ed7793489 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Manifest.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Manifest.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2011-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -30,30 +30,45 @@ import javax.annotation.concurrent.Immutable; public final class Manifest implements Serializable { private static final long serialVersionUID = 1L; - private final Path filePath; + + // NOTE: Path is not Serializable. That's why we have to have a String as well, + // for scenarios when we send Manifest via ActiveMQ to other nodes. + private transient Path filePath; + private final String filePathString; + private transient Path dataSourcePath; + private final String dataSourcePathString; + private final Date dateFileCreated; private final String caseName; private final String deviceId; - private final Path dataSourcePath; + private final String dataSourceFileName; private final Map manifestProperties; public Manifest(Path manifestFilePath, Date dateFileCreated, String caseName, String deviceId, Path dataSourcePath, Map manifestProperties) { - this.filePath = Paths.get(manifestFilePath.toString()); + this.filePathString = manifestFilePath.toString(); + this.filePath = Paths.get(filePathString); + this.dateFileCreated = new Date(dateFileCreated.getTime()); this.caseName = caseName; this.deviceId = deviceId; if (null != dataSourcePath) { - this.dataSourcePath = Paths.get(dataSourcePath.toString()); + this.dataSourcePathString = dataSourcePath.toString(); + this.dataSourcePath = Paths.get(dataSourcePathString); dataSourceFileName = dataSourcePath.getFileName().toString(); } else { + this.dataSourcePathString = ""; this.dataSourcePath = Paths.get(""); dataSourceFileName = ""; } this.manifestProperties = new HashMap<>(manifestProperties); - } + } public Path getFilePath() { + // after potential deserialization Path will be null because it is transient + if (filePath == null) { + this.filePath = Paths.get(filePathString); + } return this.filePath; } @@ -70,6 +85,10 @@ public final class Manifest implements Serializable { } public Path getDataSourcePath() { + // after potential deserialization Path will be null because it is transient + if (dataSourcePath == null) { + this.dataSourcePath = Paths.get(dataSourcePathString); + } return dataSourcePath; } From 40857660acb63a5e3b8396ae86a76057378d543d Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Thu, 9 Sep 2021 12:02:55 -0400 Subject: [PATCH 61/64] Minor --- .../org/sleuthkit/autopsy/experimental/autoingest/Manifest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Manifest.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Manifest.java index 4ed7793489..a6edfb4415 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Manifest.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Manifest.java @@ -41,7 +41,6 @@ public final class Manifest implements Serializable { private final Date dateFileCreated; private final String caseName; private final String deviceId; - private final String dataSourceFileName; private final Map manifestProperties; From 25005cef460a62945105ba80c935e8d4f5b9e341 Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Thu, 9 Sep 2021 12:03:23 -0400 Subject: [PATCH 62/64] TextViewer tab will now be enabled for Reports --- .../textcontentviewer/TextContentViewer.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextContentViewer.java index d7f853caab..426163ef80 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextContentViewer.java @@ -24,6 +24,7 @@ import org.openide.util.NbBundle.Messages; import org.openide.util.lookup.ServiceProvider; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.BlackboardArtifact; /** * A DataContentViewer that displays text with the TextViewers available. @@ -91,14 +92,10 @@ public class TextContentViewer implements DataContentViewer { if (node == null) { return false; } + // get the node's File, if it has one AbstractFile file = node.getLookup().lookup(AbstractFile.class); - if (file == null) { - return false; - } - - // disable the text content viewer for directories and empty files - if (file.isDir() || file.getSize() == 0) { + if (file != null && (file.isDir() || file.getSize() == 0)) { return false; } From bff0a03f24e97c303a3219d559624691a4bbd9b0 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Thu, 9 Sep 2021 15:29:14 -0400 Subject: [PATCH 63/64] Changed checkbox text --- .../autopsy/centralrepository/ingestmodule/Bundle.properties | 2 +- .../centralrepository/ingestmodule/Bundle.properties-MERGED | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/Bundle.properties b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/Bundle.properties index 156fb6b343..b00d4d5540 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/Bundle.properties @@ -2,4 +2,4 @@ IngestSettingsPanel.ingestSettingsLabel.text=Ingest Settings IngestSettingsPanel.flagTaggedNotableItemsCheckbox.text=Flag items previously tagged as notable IngestSettingsPanel.flagPreviouslySeenDevicesCheckbox.text=Flag devices and users previously seen in other cases IngestSettingsPanel.createCorrelationPropertiesCheckbox.text=Save items to the Central Repository -IngestSettingsPanel.flagUniqueAppsCheckbox.text=Flag unique apps and domains unseen in other cases +IngestSettingsPanel.flagUniqueAppsCheckbox.text=Flag apps and domains not seen in other cases diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/Bundle.properties-MERGED index 839209f091..d15eb90cb2 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/Bundle.properties-MERGED @@ -13,4 +13,4 @@ IngestSettingsPanel.ingestSettingsLabel.text=Ingest Settings IngestSettingsPanel.flagTaggedNotableItemsCheckbox.text=Flag items previously tagged as notable IngestSettingsPanel.flagPreviouslySeenDevicesCheckbox.text=Flag devices and users previously seen in other cases IngestSettingsPanel.createCorrelationPropertiesCheckbox.text=Save items to the Central Repository -IngestSettingsPanel.flagUniqueAppsCheckbox.text=Flag unique apps and domains unseen in other cases +IngestSettingsPanel.flagUniqueAppsCheckbox.text=Flag apps and domains not seen in other cases From ad8d4e7a9deb3d375a4479313ec4741eff9d9c09 Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Thu, 9 Sep 2021 15:50:31 -0400 Subject: [PATCH 64/64] Fixed exception create cc bin nodes --- .../autopsy/datamodel/accounts/Accounts.java | 22 +++++-------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java index bf7ee1caba..9c84b85bfe 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java @@ -1481,7 +1481,7 @@ final public class Accounts implements AutopsyVisitableItem { } } - final private class CreditCardNumberFactory extends ObservingChildren { + final private class CreditCardNumberFactory extends ObservingChildren { private final BinResult bin; @@ -1502,10 +1502,10 @@ final public class Accounts implements AutopsyVisitableItem { } @Override - protected boolean createKeys(List list) { + protected boolean createKeys(List list) { String query - = "SELECT blackboard_artifacts.artifact_id " //NON-NLS + = "SELECT blackboard_artifacts.artifact_obj_id " //NON-NLS + " FROM blackboard_artifacts " //NON-NLS + " JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id " //NON-NLS + " WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.Type.TSK_ACCOUNT.getTypeID() //NON-NLS @@ -1517,7 +1517,7 @@ final public class Accounts implements AutopsyVisitableItem { try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query); ResultSet rs = results.getResultSet();) { while (rs.next()) { - list.add(rs.getLong("artifact_id")); //NON-NLS + list.add(skCase.getBlackboard().getDataArtifactById(rs.getLong("artifact_obj_id"))); //NON-NLS } } catch (TskCoreException | SQLException ex) { LOGGER.log(Level.SEVERE, "Error querying for account artifacts.", ex); //NON-NLS @@ -1527,18 +1527,8 @@ final public class Accounts implements AutopsyVisitableItem { } @Override - protected Node[] createNodesForKey(Long artifactID) { - if (skCase == null) { - return new Node[0]; - } - - try { - DataArtifact art = skCase.getBlackboard().getDataArtifactById(artifactID); - return new Node[]{new AccountArtifactNode(art)}; - } catch (TskCoreException ex) { - LOGGER.log(Level.SEVERE, "Error creating BlackboardArtifactNode for artifact with ID " + artifactID, ex); //NON-NLS - return new Node[0]; - } + protected Node[] createNodesForKey(DataArtifact artifact) { + return new Node[]{new AccountArtifactNode(artifact)}; } }