/* * Autopsy Forensic Browser * * Copyright 2013 Basis Technology Corp. * Contact: carrier <at> sleuthkit <dot> 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 org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.TskCoreException; import java.util.List; import java.util.ArrayList; import org.mitre.cybox.objects.EmailMessage; import org.mitre.cybox.objects.Address; /** * */ class EvalEmailObj extends EvaluatableObject { private final EmailMessage obj; private List<BlackboardArtifact> finalHits; public EvalEmailObj(EmailMessage a_obj, String a_id, String a_spacing) { obj = a_obj; id = a_id; spacing = a_spacing; finalHits = null; } @Override public synchronized ObservableResult evaluate() { setWarnings(""); List<BlackboardArtifact> toHits = null; boolean hadToFields = false; List<BlackboardArtifact> ccHits = null; boolean hadCcFields = false; List<BlackboardArtifact> fromHits = null; boolean hadFromField = false; List<BlackboardArtifact> subjectHits = null; boolean hadSubjectField = false; if (obj.getHeader() != null) { if ((obj.getHeader().getTo() != null) && (obj.getHeader().getTo().getRecipients() != null) && (!obj.getHeader().getTo().getRecipients().isEmpty())) { for (Address addr : obj.getHeader().getTo().getRecipients()) { if (addr.getAddressValue() != null) { hadToFields = true; try { toHits = findArtifactsBySubstring(addr.getAddressValue(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO); } catch (TskCoreException ex) { addWarning(ex.getLocalizedMessage()); } } } } if ((obj.getHeader().getCC() != null) && (obj.getHeader().getCC().getRecipients() != null) && (!obj.getHeader().getCC().getRecipients().isEmpty())) { for (Address addr : obj.getHeader().getCC().getRecipients()) { if (addr.getAddressValue() != null) { hadCcFields = true; try { ccHits = findArtifactsBySubstring(addr.getAddressValue(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CC); } catch (TskCoreException ex) { addWarning(ex.getLocalizedMessage()); } } } } if ((obj.getHeader().getFrom() != null) && (obj.getHeader().getFrom().getAddressValue() != null)) { hadFromField = true; try { fromHits = findArtifactsBySubstring(obj.getHeader().getFrom().getAddressValue(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM); } catch (TskCoreException ex) { addWarning(ex.getLocalizedMessage()); } } if ((obj.getHeader().getSubject() != null) && (obj.getHeader().getSubject().getValue() != null)) { hadSubjectField = true; try { subjectHits = findArtifactsBySubstring(obj.getHeader().getSubject(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT); } catch (TskCoreException ex) { addWarning(ex.getLocalizedMessage()); } } } // Make sure at least one test had some data if ((!hadToFields) && (!hadFromField) && (!hadCcFields) && (!hadSubjectField)) { return new ObservableResult(id, "EmailMessage: Could not find any parsable EmailMessage fields " //NON-NLS + getPrintableWarnings(), spacing, ObservableResult.ObservableState.INDETERMINATE, null); } // Check if there were more fields that aren't currently supported String fieldNames = getListOfUnsupportedFields(); if (fieldNames.length() > 0) { addWarning("Unsupported field(s) found: " + fieldNames); //NON-NLS } // Find the artifacts that matched all of the fields finalHits = null; boolean finalHitsStarted = false; if (hadToFields) { combineHits(toHits, finalHitsStarted); finalHitsStarted = true; } if (hadCcFields) { combineHits(ccHits, finalHitsStarted); finalHitsStarted = true; } if (hadFromField) { combineHits(fromHits, finalHitsStarted); finalHitsStarted = true; } if (hadSubjectField) { combineHits(subjectHits, finalHitsStarted); finalHitsStarted = true; } if (!finalHitsStarted) { // We didn't find any fields that could be evaluated return new ObservableResult(id, "EmailMessage: EmailObj parsing incomplete " + getPrintableWarnings(), //NON-NLS spacing, ObservableResult.ObservableState.INDETERMINATE, null); } // If there are any artifacts left in finalHits, we have a match if (finalHits.size() > 0) { List<StixArtifactData> artData = new ArrayList<StixArtifactData>(); for (BlackboardArtifact a : finalHits) { artData.add(new StixArtifactData(a.getObjectID(), id, "EmailMessage")); //NON-NLS } return new ObservableResult(id, "EmailMessage: " + finalHits.size() + " matching artifacts found " + getPrintableWarnings(), //NON-NLS spacing, ObservableResult.ObservableState.TRUE, artData); } else { return new ObservableResult(id, "EmailMessage: No matching artifacts found " + getPrintableWarnings(), //NON-NLS spacing, ObservableResult.ObservableState.FALSE, null); } } /** * Add a set of hits to the final set of hits. Removes any artifacts that * aren't found in the new set. The final list is the artifacts found in all * sets. * * @param newHits The new hits to add to the list * @param finalHitsStarted Whether we've started the list or not */ private void combineHits(List<BlackboardArtifact> newHits, boolean finalHitsStarted) { if (finalHitsStarted && (finalHits != null)) { finalHits.retainAll(newHits); } else { finalHits = newHits; } } /** * Test to see if the Email Object has any fields set that we don't support * right now. * * @return a list of unsupported fields found. */ private String getListOfUnsupportedFields() { String fieldNames = ""; if (obj.getHeader() != null) { if (obj.getHeader().getReceivedLines() != null) { fieldNames += "Received_Lines "; //NON-NLS } if (obj.getHeader().getBCC() != null) { fieldNames += "BCC "; //NON-NLS } if (obj.getHeader().getInReplyTo() != null) { fieldNames += "In_Reply_To "; //NON-NLS } if (obj.getHeader().getDate() != null) { fieldNames += "Date "; //NON-NLS } if (obj.getHeader().getMessageID() != null) { fieldNames += "Message_ID "; //NON-NLS } if (obj.getHeader().getSender() != null) { fieldNames += "Sender "; //NON-NLS } if (obj.getHeader().getReplyTo() != null) { fieldNames += "Reply_To "; //NON-NLS } if (obj.getHeader().getErrorsTo() != null) { fieldNames += "Errors_To "; //NON-NLS } if (obj.getHeader().getBoundary() != null) { fieldNames += "Boundary "; //NON-NLS } if (obj.getHeader().getContentType() != null) { fieldNames += "Content_Type "; //NON-NLS } if (obj.getHeader().getMIMEVersion() != null) { fieldNames += "MIME_Version "; //NON-NLS } if (obj.getHeader().getPrecedence() != null) { fieldNames += "Precedence "; //NON-NLS } if (obj.getHeader().getUserAgent() != null) { fieldNames += "User_Agent "; //NON-NLS } if (obj.getHeader().getXMailer() != null) { fieldNames += "X_Mailer "; //NON-NLS } if (obj.getHeader().getXOriginatingIP() != null) { fieldNames += "X_Originiating_IP "; //NON-NLS } if (obj.getHeader().getXPriority() != null) { fieldNames += "X_Priority "; //NON-NLS } } if (obj.getEmailServer() != null) { fieldNames += "Email_Server "; //NON-NLS } if (obj.getRawBody() != null) { fieldNames += "Raw_Body "; //NON-NLS } if (obj.getRawHeader() != null) { fieldNames += "Raw_Header "; //NON-NLS } if (obj.getAttachments() != null) { fieldNames += "Attachments "; //NON-NLS } if (obj.getLinks() != null) { fieldNames += "Links "; //NON-NLS } return fieldNames; } }