diff --git a/Core/src/org/sleuthkit/autopsy/modules/stix/EvalDomainObj.java b/Core/src/org/sleuthkit/autopsy/modules/stix/EvalDomainObj.java new file mode 100644 index 0000000000..f95b34a76d --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/modules/stix/EvalDomainObj.java @@ -0,0 +1,116 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2013 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.modules.stix; + +import java.util.ArrayList; +import java.util.List; +import org.mitre.cybox.common_2.ConditionApplicationEnum; +import org.mitre.cybox.common_2.ConditionTypeEnum; +import org.mitre.cybox.objects.DomainName; +import org.sleuthkit.datamodel.BlackboardArtifact; +import org.sleuthkit.datamodel.BlackboardAttribute; +import org.sleuthkit.datamodel.TskCoreException; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.datamodel.SleuthkitCase; + +/** + * + */ +class EvalDomainObj extends EvaluatableObject { + + private final DomainName obj; + + public EvalDomainObj(DomainName a_obj, String a_id, String a_spacing) { + obj = a_obj; + id = a_id; + spacing = a_spacing; + } + + @Override + public synchronized ObservableResult evaluate() { + + setWarnings(""); + + if (obj.getValue() == null) { + return new ObservableResult(id, "DomainObject: No domain value field found", + spacing, ObservableResult.ObservableState.INDETERMINATE, null); + } + + // Since we have single URL artifacts, ALL and NONE conditions probably don't make sense to test + if (!((obj.getValue().getApplyCondition() == null) + || (obj.getValue().getApplyCondition() == ConditionApplicationEnum.ANY))) { + return new ObservableResult(id, "URIObject: Can not process apply condition " + obj.getValue().getApplyCondition().toString() + + " on URI object", spacing, ObservableResult.ObservableState.INDETERMINATE, null); + } + + // If the condition is not "CONTAINS", add a warning that it's being ignored + if ((obj.getValue().getCondition() != null) + && (obj.getValue().getCondition() != ConditionTypeEnum.CONTAINS)) { + addWarning("Warning: Ignoring condition " + obj.getValue().getCondition().toString() + + " on DomainName - using substring comparison"); + } + + Case case1 = Case.getCurrentCase(); + SleuthkitCase sleuthkitCase = case1.getSleuthkitCase(); + + try { + // Set up the list of matching artifacts + List finalHits = new ArrayList(); + + // Get all the URL artifacts + List artList + = sleuthkitCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT); + + for (BlackboardArtifact art : artList) { + + for (BlackboardAttribute attr : art.getAttributes()) { + if (attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID()) { + String url = attr.getValueString(); + + // Check whether the domain name is a substring of the URL (regardless + // of the condition on the domain name object) + if (compareStringObject(obj.getValue().getValue().toString(), ConditionTypeEnum.CONTAINS, + obj.getValue().getApplyCondition(), url)) { + finalHits.add(art); + } + } + } + } + + if (!finalHits.isEmpty()) { + List artData = new ArrayList(); + for (BlackboardArtifact a : finalHits) { + artData.add(new StixArtifactData(a.getObjectID(), id, "DomainNameObject")); + } + return new ObservableResult(id, "DomainNameObject: Found a match for " + obj.getValue().getValue().toString() + + " " + getPrintableWarnings(), + spacing, ObservableResult.ObservableState.TRUE, artData); + } + + return new ObservableResult(id, "DomainNameObject: Found no matches for " + obj.getValue().getValue().toString() + + " " + getPrintableWarnings(), + spacing, ObservableResult.ObservableState.FALSE, null); + } catch (TskCoreException ex) { + return new ObservableResult(id, "DomainNameObject: Exception during evaluation: " + ex.getLocalizedMessage(), + spacing, ObservableResult.ObservableState.INDETERMINATE, null); + } + + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/modules/stix/EvaluatableObject.java b/Core/src/org/sleuthkit/autopsy/modules/stix/EvaluatableObject.java index 9503131634..4252ad61a5 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/stix/EvaluatableObject.java +++ b/Core/src/org/sleuthkit/autopsy/modules/stix/EvaluatableObject.java @@ -67,6 +67,7 @@ abstract class EvaluatableObject { public void addWarning(String a_newWarning) { if ((warnings == null) || warnings.isEmpty()) { warnings = a_newWarning; + return; } warnings = warnings + ", " + a_newWarning; } diff --git a/Core/src/org/sleuthkit/autopsy/modules/stix/STIXReportModule.java b/Core/src/org/sleuthkit/autopsy/modules/stix/STIXReportModule.java index 10e784c925..5ae619b894 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/stix/STIXReportModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/stix/STIXReportModule.java @@ -55,6 +55,7 @@ import org.mitre.cybox.objects.WindowsNetworkShare; import org.mitre.cybox.objects.AccountObjectType; import org.mitre.cybox.objects.SystemObjectType; import org.mitre.cybox.objects.URLHistory; +import org.mitre.cybox.objects.DomainName; import org.mitre.cybox.objects.WindowsRegistryKey; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.coreutils.ModuleSettings; @@ -306,7 +307,7 @@ public class STIXReportModule implements GeneralReportModule { int count = 0; for (StixArtifactData s : result.getArtifacts()) { - + // Figure out what name to use for this indicator. If it has a title, // use that. Otherwise use the ID. If both are missing, use a // generic heading. @@ -585,6 +586,8 @@ public class STIXReportModule implements GeneralReportModule { evalObj = new EvalSystemObj((SystemObjectType) obj.getProperties(), id, spacing); } else if (obj.getProperties() instanceof URLHistory) { evalObj = new EvalURLHistoryObj((URLHistory) obj.getProperties(), id, spacing); + } else if (obj.getProperties() instanceof DomainName) { + evalObj = new EvalDomainObj((DomainName) obj.getProperties(), id, spacing); } else if (obj.getProperties() instanceof WindowsRegistryKey) { evalObj = new EvalRegistryObj((WindowsRegistryKey) obj.getProperties(), id, spacing, registryFileData); } else { diff --git a/docs/doxygen-user/stix.dox b/docs/doxygen-user/stix.dox index 2d611fdc22..9e9f4fc976 100644 --- a/docs/doxygen-user/stix.dox +++ b/docs/doxygen-user/stix.dox @@ -21,9 +21,13 @@ Quick Start Supported CybOX Objects ======================= + - Address Object - Address_Value +- Domain Name Object + - Value + - Email Message Object - To - CC @@ -83,6 +87,8 @@ Supported CybOX Objects - Win User Account Object - SID + +See http://cybox.mitre.org for more information on CybOX Objects. Limitations ===========