19 package org.sleuthkit.autopsy.modules.stix;
 
   27 import java.util.List;
 
   28 import java.util.ArrayList;
 
   30 import org.mitre.cybox.common_2.AnyURIObjectPropertyType;
 
   31 import org.mitre.cybox.objects.URLHistory;
 
   32 import org.mitre.cybox.objects.URLHistoryEntryType;
 
   37 class EvalURLHistoryObj 
extends EvaluatableObject {
 
   39     private final URLHistory obj;
 
   41     public EvalURLHistoryObj(URLHistory a_obj, String a_id, String a_spacing) {
 
   48     public synchronized ObservableResult evaluate() {
 
   52         if ((obj.getBrowserInformation() == null) && (obj.getURLHistoryEntries() == null)) {
 
   53             return new ObservableResult(
id, 
"URLHistoryObject: No browser info or history entries found", 
 
   54                     spacing, ObservableResult.ObservableState.INDETERMINATE, null);
 
   58         String baseSearchString = 
"";
 
   59         String finalResultsStr = 
"";
 
   62         boolean haveBrowserName = 
false;
 
   63         if (obj.getBrowserInformation() != null) {
 
   64             if (obj.getBrowserInformation().getName() != null) {
 
   65                 haveBrowserName = 
true;
 
   67             baseSearchString = 
"Browser \"" + obj.getBrowserInformation().getName() + 
"\""; 
 
   71         List<BlackboardArtifact> finalHits = 
new ArrayList<BlackboardArtifact>();
 
   73         if (obj.getURLHistoryEntries() != null) {
 
   75             for (URLHistoryEntryType entry : obj.getURLHistoryEntries()) {
 
   77                 boolean haveURL = 
false;
 
   78                 boolean haveHostname = 
false;
 
   79                 boolean haveReferrer = 
false;
 
   80                 boolean havePageTitle = 
false;
 
   81                 boolean haveUserProfile = 
false;
 
   83                 setUnsupportedEntryFieldWarnings(entry);
 
   87                 String searchString = baseSearchString;
 
   89                 if ((entry.getURL() != null) && (entry.getURL().getValue() != null)) {
 
   91                     if (!searchString.isEmpty()) {
 
   92                         searchString += 
" and "; 
 
   94                     searchString += 
"URL \"" + entry.getURL().getValue().getValue() + 
"\""; 
 
   97                 if ((entry.getReferrerURL() != null) && (entry.getReferrerURL().getValue() != null)) {
 
   99                     if (!searchString.isEmpty()) {
 
  100                         searchString += 
" and "; 
 
  102                     searchString += 
"Referrer \"" + entry.getReferrerURL().getValue().getValue() + 
"\""; 
 
  105                 if (entry.getUserProfileName() != null) {
 
  106                     haveUserProfile = 
true;
 
  107                     if (!searchString.isEmpty()) {
 
  108                         searchString += 
" and "; 
 
  110                     searchString += 
"UserProfile \"" + entry.getUserProfileName().getValue() + 
"\""; 
 
  113                 if (entry.getPageTitle() != null) {
 
  114                     havePageTitle = 
true;
 
  115                     if (!searchString.isEmpty()) {
 
  116                         searchString += 
" and "; 
 
  118                     searchString += 
"Page title \"" + entry.getPageTitle().getValue() + 
"\""; 
 
  121                 if ((entry.getHostname() != null) && (entry.getHostname().getHostnameValue() != null)) {
 
  123                     if (!searchString.isEmpty()) {
 
  124                         searchString += 
" and "; 
 
  126                     searchString += 
"Hostname \"" + entry.getHostname().getHostnameValue().getValue() + 
"\""; 
 
  129                 if (!finalResultsStr.isEmpty()) {
 
  130                     finalResultsStr += 
", ";
 
  132                 finalResultsStr += searchString;
 
  134                 if (!(haveURL || haveHostname || haveReferrer
 
  135                         || havePageTitle || haveUserProfile || haveBrowserName)) {
 
  136                     return new ObservableResult(
id, 
"URLHistoryObject: No evaluatable fields found", 
 
  137                             spacing, ObservableResult.ObservableState.INDETERMINATE, null);
 
  141                     Case case1 = Case.getCurrentCase();
 
  142                     SleuthkitCase sleuthkitCase = case1.getSleuthkitCase();
 
  143                     List<BlackboardArtifact> artList
 
  144                             = sleuthkitCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY);
 
  146                     for (BlackboardArtifact art : artList) {
 
  147                         boolean foundURLMatch = 
false;
 
  148                         boolean foundHostnameMatch = 
false;
 
  149                         boolean foundReferrerMatch = 
false;
 
  150                         boolean foundPageTitleMatch = 
false;
 
  151                         boolean foundUserProfileMatch = 
false;
 
  152                         boolean foundBrowserNameMatch = 
false;
 
  154                         for (BlackboardAttribute attr : art.getAttributes()) {
 
  155                             if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL.getTypeID())
 
  157                                 if (entry.getURL().getValue() instanceof AnyURIObjectPropertyType) {
 
  158                                     foundURLMatch = compareStringObject(entry.getURL().getValue().getValue().toString(),
 
  159                                             entry.getURL().getValue().getCondition(),
 
  160                                             entry.getURL().getValue().getApplyCondition(),
 
  161                                             attr.getValueString());
 
  163                                     addWarning(
"Non-AnyURIObjectPropertyType found in URL value field"); 
 
  166                             if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID())
 
  168                                 foundHostnameMatch = compareStringObject(entry.getHostname().getHostnameValue(),
 
  169                                         attr.getValueString());
 
  171                             if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_REFERRER.getTypeID())
 
  173                                 if (entry.getReferrerURL().getValue() instanceof AnyURIObjectPropertyType) {
 
  174                                     foundReferrerMatch = compareStringObject(entry.getReferrerURL().getValue().getValue().toString(),
 
  175                                             entry.getURL().getValue().getCondition(),
 
  176                                             entry.getURL().getValue().getApplyCondition(),
 
  177                                             attr.getValueString());
 
  179                                     addWarning(
"Non-AnyURIObjectPropertyType found in URL value field"); 
 
  182                             if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE.getTypeID())
 
  183                                     && (havePageTitle)) {
 
  184                                 foundPageTitleMatch = compareStringObject(entry.getPageTitle(),
 
  185                                         attr.getValueString());
 
  187                             if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME.getTypeID())
 
  188                                     && (haveUserProfile)) {
 
  189                                 foundUserProfileMatch = compareStringObject(entry.getUserProfileName(),
 
  190                                         attr.getValueString());
 
  192                             if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID())
 
  193                                     && (haveBrowserName)) {
 
  194                                 foundBrowserNameMatch = compareStringObject(obj.getBrowserInformation().getName(),
 
  195                                         null, null, attr.getValueString());
 
  199                         if (((!haveURL) || foundURLMatch)
 
  200                                 && ((!haveHostname) || foundHostnameMatch)
 
  201                                 && ((!haveReferrer) || foundReferrerMatch)
 
  202                                 && ((!havePageTitle) || foundPageTitleMatch)
 
  203                                 && ((!haveUserProfile) || foundUserProfileMatch)
 
  204                                 && ((!haveBrowserName) || foundBrowserNameMatch)) {
 
  209                 } 
catch (TskCoreException ex) {
 
  210                     return new ObservableResult(
id, 
"URLHistoryObject: Exception during evaluation: " + ex.getLocalizedMessage(), 
 
  211                             spacing, ObservableResult.ObservableState.INDETERMINATE, null);
 
  216             if (!finalHits.isEmpty()) {
 
  217                 List<StixArtifactData> artData = 
new ArrayList<StixArtifactData>();
 
  218                 for (BlackboardArtifact a : finalHits) {
 
  219                     artData.add(
new StixArtifactData(a.getObjectID(), id, 
"URLHistory")); 
 
  221                 return new ObservableResult(
id, 
"URLHistoryObject: Found at least one match for " + finalResultsStr, 
 
  222                         spacing, ObservableResult.ObservableState.TRUE, artData);
 
  226             return new ObservableResult(
id, 
"URLHistoryObject: No matches found for " + finalResultsStr, 
 
  227                     spacing, ObservableResult.ObservableState.FALSE, null);
 
  229         } 
else if (haveBrowserName) {
 
  234                 Case case1 = Case.getCurrentCase();
 
  235                 SleuthkitCase sleuthkitCase = case1.getSleuthkitCase();
 
  236                 List<BlackboardArtifact> artList
 
  237                         = sleuthkitCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY);
 
  239                 for (BlackboardArtifact art : artList) {
 
  240                     boolean foundBrowserNameMatch = 
false;
 
  242                     for (BlackboardAttribute attr : art.getAttributes()) {
 
  243                         if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID())
 
  244                                 && (haveBrowserName)) {
 
  245                             foundBrowserNameMatch = compareStringObject(obj.getBrowserInformation().getName(),
 
  246                                     null, null, attr.getValueString());
 
  250                     if (foundBrowserNameMatch) {
 
  255                 if (!finalHits.isEmpty()) {
 
  256                     List<StixArtifactData> artData = 
new ArrayList<StixArtifactData>();
 
  257                     for (BlackboardArtifact a : finalHits) {
 
  258                         artData.add(
new StixArtifactData(a.getObjectID(), id, 
"URLHistory")); 
 
  260                     return new ObservableResult(
id, 
"URLHistoryObject: Found at least one match", 
 
  261                             spacing, ObservableResult.ObservableState.TRUE, artData);
 
  265                 return new ObservableResult(
id, 
"URLHistoryObject: No matches found for " + baseSearchString, 
 
  266                         spacing, ObservableResult.ObservableState.FALSE, null);
 
  267             } 
catch (TskCoreException ex) {
 
  268                 return new ObservableResult(
id, 
"URLHistoryObject: Exception during evaluation: " + ex.getLocalizedMessage(), 
 
  269                         spacing, ObservableResult.ObservableState.INDETERMINATE, null);
 
  274             return new ObservableResult(
id, 
"URLHistoryObject: No evaluatable fields found", 
 
  275                     spacing, ObservableResult.ObservableState.INDETERMINATE, null);
 
  284     private void setUnsupportedEntryFieldWarnings(URLHistoryEntryType entry) {
 
  285         List<String> fieldNames = 
new ArrayList<String>();
 
  287         if (entry.getUserProfileName() != null) {
 
  288             fieldNames.add(
"User_Profile_Name"); 
 
  290         if (entry.getVisitCount() != null) {
 
  291             fieldNames.add(
"Visit_Count"); 
 
  293         if (entry.getManuallyEnteredCount() != null) {
 
  294             fieldNames.add(
"Manually_Entered_Count"); 
 
  296         if (entry.getModificationDateTime() != null) {
 
  297             fieldNames.add(
"Modification_DateTime"); 
 
  299         if (entry.getExpirationDateTime() != null) {
 
  300             fieldNames.add(
"Expiration_DateTime"); 
 
  302         if (entry.getFirstVisitDateTime() != null) {
 
  303             fieldNames.add(
"First_Visit_DateTime"); 
 
  305         if (entry.getLastVisitDateTime() != null) {
 
  306             fieldNames.add(
"Last_Visit_DateTime"); 
 
  309         String warningStr = 
"";
 
  310         for (String name : fieldNames) {
 
  311             if (!warningStr.isEmpty()) {
 
  317         addWarning(
"Unsupported URL_History_Entry field(s): " + warningStr);