Added OsAccount to CR

Add OsAccount Code to CR
This commit is contained in:
Mark McKinnon 2021-06-28 13:21:04 -04:00
parent 475e8ecece
commit 4a66ea26ae
7 changed files with 157 additions and 47 deletions

View File

@ -31,6 +31,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.logging.Level;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTimeZone;
@ -52,6 +53,9 @@ 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;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
@ -69,6 +73,43 @@ public final class OtherOccurrences {
private OtherOccurrences() {
}
public static Collection<CorrelationAttributeInstance> getCorrelationAttributeFromOsAccount(Node node, OsAccount osAccount) {
Collection<CorrelationAttributeInstance> ret = new ArrayList<>();
Optional<String> osAccountAddr = osAccount.getAddr();
if (osAccountAddr.isPresent()) {
try {
for (OsAccountInstance instance : osAccount.getOsAccountInstances()) {
DataSource osAccountDataSource = instance.getDataSource();
try {
CorrelationCase correlationCase = CentralRepository.getInstance().getCase(Case.getCurrentCaseThrows());
CorrelationAttributeInstance correlationAttributeInstance = new CorrelationAttributeInstance(
CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.OSACCOUNT_TYPE_ID),
osAccountAddr.get(),
correlationCase,
CorrelationDataSource.fromTSKDataSource(correlationCase, instance.getDataSource()),
"",
"",
TskData.FileKnown.KNOWN,
osAccount.getId());
ret.add(correlationAttributeInstance);
} catch (CentralRepoException ex) {
logger.log(Level.SEVERE, String.format("Cannot get central repository for OsAccount: %s.", osAccountAddr.get()), ex); //NON-NLS
} catch (NoCurrentCaseException ex) {
logger.log(Level.WARNING, String.format("Exception while getting open case looking up osAccount %s.", osAccountAddr.get()), ex); //NON-NLS
} catch (CorrelationAttributeNormalizationException ex) {
logger.log(Level.SEVERE, String.format("Exception with Correlation Attribute Normalization for osAccount %s.", osAccountAddr.get()), ex); //NON-NLS
}
}
} catch (TskCoreException ex) {
logger.log(Level.INFO, String.format("Unable to check create CorrelationAttribtueInstance for osAccount %s.", osAccountAddr.get()), ex);
}
}
return ret;
}
/**
* Determine what attributes can be used for correlation based on the node.
* If EamDB is not enabled, get the default Files correlation.

View File

@ -18,6 +18,7 @@
*/
package org.sleuthkit.autopsy.centralrepository.contentviewer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
@ -37,6 +38,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.OsAccount;
import org.sleuthkit.datamodel.TskException;
/**
@ -60,7 +62,11 @@ class OtherOccurrencesNodeWorker extends SwingWorker<OtherOccurrencesData, Void>
@Override
protected OtherOccurrencesData doInBackground() throws Exception {
OsAccount osAccount = node.getLookup().lookup(OsAccount.class);
AbstractFile file = OtherOccurrences.getAbstractFileFromNode(node);
if (osAccount != null) {
file = node.getLookup().lookup(AbstractFile.class);
}
String deviceId = "";
String dataSourceName = "";
Map<String, CorrelationCase> caseNames = new HashMap<>();
@ -77,8 +83,12 @@ class OtherOccurrencesNodeWorker extends SwingWorker<OtherOccurrencesData, Void>
// @@@ Review this behavior
return null;
}
Collection<CorrelationAttributeInstance> correlationAttributes = OtherOccurrences.getCorrelationAttributesFromNode(node, file);
Collection<CorrelationAttributeInstance> correlationAttributes = new ArrayList<>();
if (osAccount != null) {
correlationAttributes = OtherOccurrences.getCorrelationAttributeFromOsAccount(node, osAccount);
} else {
correlationAttributes = OtherOccurrences.getCorrelationAttributesFromNode(node, file);
}
int totalCount = 0;
Set<String> dataSources = new HashSet<>();
for (CorrelationAttributeInstance corAttr : correlationAttributes) {

View File

@ -25,6 +25,7 @@ CorrelationType.ICCID.displayName=ICCID Number
CorrelationType.IMEI.displayName=IMEI Number
CorrelationType.IMSI.displayName=IMSI Number
CorrelationType.MAC.displayName=MAC Addresses
CorrelationType.OS_ACCOUNT.displayName=Os Account
CorrelationType.PHONE.displayName=Phone Numbers
CorrelationType.PROG_NAME.displayName=Installed Programs
CorrelationType.SSID.displayName=Wireless Networks

View File

@ -279,7 +279,8 @@ public class CorrelationAttributeInstance implements Serializable {
"CorrelationType.IMEI.displayName=IMEI Number",
"CorrelationType.IMSI.displayName=IMSI Number",
"CorrelationType.PROG_NAME.displayName=Installed Programs",
"CorrelationType.ICCID.displayName=ICCID Number"})
"CorrelationType.ICCID.displayName=ICCID Number",
"CorrelationType.OS_ACCOUNT.displayName=Os Account"})
public static List<CorrelationAttributeInstance.Type> getDefaultCorrelationTypes() throws CentralRepoException {
List<CorrelationAttributeInstance.Type> defaultCorrelationTypes = new ArrayList<>();
@ -294,6 +295,7 @@ public class CorrelationAttributeInstance implements Serializable {
defaultCorrelationTypes.add(new CorrelationAttributeInstance.Type(IMSI_TYPE_ID, Bundle.CorrelationType_IMSI_displayName(), "imsi_number", true, true)); //NON-NLS
defaultCorrelationTypes.add(new CorrelationAttributeInstance.Type(ICCID_TYPE_ID, Bundle.CorrelationType_ICCID_displayName(), "iccid_number", true, true)); //NON-NLS
defaultCorrelationTypes.add(new CorrelationAttributeInstance.Type(INSTALLED_PROGS_TYPE_ID, Bundle.CorrelationType_PROG_NAME_displayName(), "installed_programs", true, true)); //NON-NLS
defaultCorrelationTypes.add(new CorrelationAttributeInstance.Type(OSACCOUNT_TYPE_ID, Bundle.CorrelationType_OS_ACCOUNT_displayName(), "os_accounts", true, true)); //NON-NLS
// Create Correlation Types for Accounts.
int correlationTypeId = ADDITIONAL_TYPES_BASE_ID;

View File

@ -1,4 +1,7 @@
caseeventlistener.evidencetag=Evidence
CaseEventsListener.module.name=Central Repository
CaseEventsListener.prevCaseComment.text=Users seen in previous cases
CaseEventsListener.prevExists.text=Previously Seen Users (Central Repository)
CentralRepositoryNotificationDialog.bulletHeader=This data is used to:
CentralRepositoryNotificationDialog.bulletOne=Ignore common items (files, domains, and accounts)
CentralRepositoryNotificationDialog.bulletThree=Create personas that group accounts

View File

@ -21,6 +21,8 @@ package org.sleuthkit.autopsy.centralrepository.eventlisteners;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Arrays;
import java.util.Collection;
import java.util.EnumSet;
import java.util.List;
import java.util.Optional;
@ -28,8 +30,10 @@ import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.stream.Collectors;
import org.apache.commons.lang.StringUtils;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
@ -60,8 +64,15 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException;
import org.sleuthkit.datamodel.Tag;
import org.sleuthkit.autopsy.events.AutopsyEvent;
import org.sleuthkit.datamodel.Blackboard;
import org.sleuthkit.datamodel.BlackboardAttribute;
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT;
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT;
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME;
import org.sleuthkit.datamodel.OsAccount;
import org.sleuthkit.datamodel.OsAccountInstance;
import org.sleuthkit.datamodel.Score;
import org.sleuthkit.datamodel.SleuthkitCase;
/**
* Listen for case events and update entries in the Central Repository database
@ -81,7 +92,8 @@ public final class CaseEventListener implements PropertyChangeListener {
Case.Events.DATA_SOURCE_ADDED,
Case.Events.TAG_DEFINITION_CHANGED,
Case.Events.CURRENT_CASE,
Case.Events.DATA_SOURCE_NAME_CHANGED, Case.Events.OS_ACCOUNTS_ADDED);
Case.Events.DATA_SOURCE_NAME_CHANGED,
Case.Events.OS_ACCT_INSTANCES_ADDED);
public CaseEventListener() {
jobProcessingExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat(CASE_EVENT_THREAD_NAME).build());
@ -138,9 +150,10 @@ public final class CaseEventListener implements PropertyChangeListener {
break;
case OS_ACCT_INSTANCES_ADDED: {
if (((AutopsyEvent) evt).getSourceType() == AutopsyEvent.SourceType.LOCAL) {
jobProcessingExecutor.submit(new OsAccountInstancesAddedTask(dbManager, evt));
jobProcessingExecutor.submit(new OsAccountInstancesAddedTask(dbManager, evt));
}
}
break;
}
}
@ -300,10 +313,10 @@ 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);
@ -396,7 +409,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) {
@ -441,7 +454,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) {
@ -646,10 +659,14 @@ public final class CaseEventListener implements PropertyChangeListener {
} // CURRENT_CASE
}
@NbBundle.Messages({"CaseEventsListener.module.name=Central Repository",
"CaseEventsListener.prevCaseComment.text=Users seen in previous cases",
"CaseEventsListener.prevExists.text=Previously Seen Users (Central Repository)"})
private final class OsAccountInstancesAddedTask implements Runnable {
private final CentralRepository dbManager;
private final PropertyChangeEvent event;
private final String MODULE_NAME = Bundle.CaseEventsListener_module_name();
private OsAccountInstancesAddedTask(CentralRepository db, PropertyChangeEvent evt) {
dbManager = db;
@ -662,46 +679,73 @@ public final class CaseEventListener implements PropertyChangeListener {
return;
}
final OsAcctInstancesAddedEvent osAcctInstancesAddedEvent = (OsAcctInstancesAddedEvent) event;
List<OsAccountInstance> addedOsAccountNew = osAcctInstancesAddedEvent.getOsAccountInstances();
for (OsAccountInstance osAccountInstance: addedOsAccountNew) {
try {
OsAccount osAccount = osAccountInstance.getOsAccount();
Optional<String> accountAddr = osAccount.getAddr();
// Check address if it is null or one of the ones below we want to ignore it since they will always be one a windows system
// and they are not unique
if (!accountAddr.isPresent() || accountAddr.get().equals("S-1-5-18") || accountAddr.get().equals("S-1-5-19") || accountAddr.get().equals("S-1-5-20")) {
return;
}
final OsAcctInstancesAddedEvent osAcctInstancesAddedEvent = (OsAcctInstancesAddedEvent) event;
List<OsAccountInstance> addedOsAccountNew = osAcctInstancesAddedEvent.getOsAccountInstances();
for (OsAccountInstance osAccountInstance : addedOsAccountNew) {
try {
OsAccount osAccount = osAccountInstance.getOsAccount();
Optional<String> accountAddr = osAccount.getAddr();
// Check address if it is null or one of the ones below we want to ignore it since they will always be one a windows system
// and they are not unique
if (!accountAddr.isPresent() || accountAddr.get().equals("S-1-5-18") || accountAddr.get().equals("S-1-5-19") || accountAddr.get().equals("S-1-5-20")) {
return;
}
try {
CorrelationCase correlationCase = CentralRepository.getInstance().getCase(Case.getCurrentCaseThrows());
CorrelationAttributeInstance correlationAttributeInstance = new CorrelationAttributeInstance(
CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.OSACCOUNT_TYPE_ID),
accountAddr.get(),
correlationCase,
CorrelationDataSource.fromTSKDataSource(correlationCase, osAccountInstance.getDataSource()),
"",
"",
TskData.FileKnown.KNOWN,
osAccount.getId());
CorrelationCase correlationCase = CentralRepository.getInstance().getCase(Case.getCurrentCaseThrows());
CorrelationAttributeInstance correlationAttributeInstance = new CorrelationAttributeInstance(
CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.OSACCOUNT_TYPE_ID),
accountAddr.get(),
correlationCase,
CorrelationDataSource.fromTSKDataSource(correlationCase, osAccountInstance.getDataSource()),
"",
"",
TskData.FileKnown.KNOWN,
osAccount.getId());
dbManager.addArtifactInstance(correlationAttributeInstance);
} catch (CentralRepoException ex) {
LOGGER.log(Level.SEVERE, "Cannot get central repository for OsAccount: " + "OsAccount", ex); //NON-NLS
} catch (NoCurrentCaseException ex) {
LOGGER.log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS
} catch (CorrelationAttributeNormalizationException ex) {
LOGGER.log(Level.SEVERE, "Exception with Correlation Attribute Normalization.", ex); //NON-NLS
dbManager.addArtifactInstance(correlationAttributeInstance);
List<CorrelationAttributeInstance> previousOccurences = dbManager.getArtifactInstancesByTypeValue(CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.OSACCOUNT_TYPE_ID), correlationAttributeInstance.getCorrelationValue());
List<String> caseDisplayNames;
for (CorrelationAttributeInstance instance : previousOccurences) {
if (!instance.getCorrelationCase().getCaseUUID().equals(correlationAttributeInstance.getCorrelationCase().getCaseUUID())) {
caseDisplayNames = dbManager.getListCasesHavingArtifactInstances(correlationAttributeInstance.getCorrelationType(), correlationAttributeInstance.getCorrelationValue());
SleuthkitCase tskCase = osAccount.getSleuthkitCase();
Blackboard blackboard = tskCase.getBlackboard();
Collection<BlackboardAttribute> attributesForNewArtifact = Arrays.asList(
new BlackboardAttribute(
TSK_SET_NAME, MODULE_NAME,
Bundle.CaseEventsListener_prevExists_text()),
new BlackboardAttribute(
TSK_COMMENT, MODULE_NAME,
Bundle.CaseEventsListener_prevCaseComment_text()));
BlackboardArtifact newAnalysisResult = osAccount.newAnalysisResult(
BlackboardArtifact.Type.TSK_INTERESTING_ARTIFACT_HIT, Score.SCORE_LIKELY_NOTABLE,
null, Bundle.CaseEventsListener_prevExists_text(), null, attributesForNewArtifact, osAccountInstance.getDataSource().getId()).getAnalysisResult();
try {
// index the artifact for keyword search
blackboard.postArtifact(newAnalysisResult, MODULE_NAME);
} catch (Blackboard.BlackboardException ex) {
LOGGER.log(Level.SEVERE, "Unable to index blackboard artifact " + newAnalysisResult.getArtifactID(), ex); //NON-NLS
}
}
}
} catch (CentralRepoException ex) {
LOGGER.log(Level.SEVERE, String.format("Cannot get central repository for OsAccount: %s.", accountAddr.get()), ex); //NON-NLS
} catch (NoCurrentCaseException ex) {
LOGGER.log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS
} catch (CorrelationAttributeNormalizationException ex) {
LOGGER.log(Level.SEVERE, "Exception with Correlation Attribute Normalization.", ex); //NON-NLS
}
} catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "Cannot get central repository for OsAccount: " + "OsAccount", ex);
}
} catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "Cannot get central repository for OsAccount: " + "OsAccount", ex);
}
LOGGER.log(Level.INFO, "Error connecting to Central Repository database."); //NON-NLS
}
}
}
private final class DataSourceNameChangedTask implements Runnable {
@ -739,4 +783,3 @@ public final class CaseEventListener implements PropertyChangeListener {
} // DATA_SOURCE_NAME_CHANGED
}
}

View File

@ -397,6 +397,11 @@ public final class FileTypes implements AutopsyVisitableItem {
return content.newDataArtifact(artifactType, attributesList, osAccountId);
}
@Override
public DataArtifact newDataArtifact(BlackboardArtifact.Type artifactType, Collection<BlackboardAttribute> attributesList, Long osAccountId, long dataSourceId) throws TskCoreException {
return content.newDataArtifact(artifactType, attributesList, osAccountId, dataSourceId);
}
@Override
public DataArtifact newDataArtifact(BlackboardArtifact.Type artifactType, Collection<BlackboardAttribute> attributesList) throws TskCoreException {
return content.newDataArtifact(artifactType, attributesList);
@ -467,6 +472,11 @@ public final class FileTypes implements AutopsyVisitableItem {
return content.newAnalysisResult(type, score, string, string1, string2, clctn);
}
@Override
public AnalysisResultAdded newAnalysisResult(BlackboardArtifact.Type type, Score score, String string, String string1, String string2, Collection<BlackboardAttribute> clctn, long dataSourceId) throws TskCoreException {
return content.newAnalysisResult(type, score, string, string1, string2, clctn, dataSourceId);
}
@Override
public Score getAggregateScore() throws TskCoreException {
return content.getAggregateScore();