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;
 
   38 class EvalURLHistoryObj 
extends EvaluatableObject {
 
   40     private final URLHistory obj;
 
   42     public EvalURLHistoryObj(URLHistory a_obj, String a_id, String a_spacing) {
 
   49     public synchronized ObservableResult evaluate() {
 
   53         if ((obj.getBrowserInformation() == null) && (obj.getURLHistoryEntries() == null)) {
 
   54             return new ObservableResult(
id, 
"URLHistoryObject: No browser info or history entries found", 
 
   55                     spacing, ObservableResult.ObservableState.INDETERMINATE, null);
 
   59         String baseSearchString = 
"";
 
   60         String finalResultsStr = 
"";
 
   63         boolean haveBrowserName = 
false;
 
   64         if (obj.getBrowserInformation() != null) {
 
   65             if (obj.getBrowserInformation().getName() != null) {
 
   66                 haveBrowserName = 
true;
 
   68             baseSearchString = 
"Browser \"" + obj.getBrowserInformation().getName() + 
"\""; 
 
   72         List<BlackboardArtifact> finalHits = 
new ArrayList<BlackboardArtifact>();
 
   74         if (obj.getURLHistoryEntries() != null) {
 
   76             for (URLHistoryEntryType entry : obj.getURLHistoryEntries()) {
 
   78                 boolean haveURL = 
false;
 
   79                 boolean haveHostname = 
false;
 
   80                 boolean haveReferrer = 
false;
 
   81                 boolean havePageTitle = 
false;
 
   82                 boolean haveUserProfile = 
false;
 
   84                 setUnsupportedEntryFieldWarnings(entry);
 
   88                 String searchString = baseSearchString;
 
   90                 if ((entry.getURL() != null) && (entry.getURL().getValue() != null)) {
 
   92                     if (!searchString.isEmpty()) {
 
   93                         searchString += 
" and "; 
 
   95                     searchString += 
"URL \"" + entry.getURL().getValue().getValue() + 
"\""; 
 
   98                 if ((entry.getReferrerURL() != null) && (entry.getReferrerURL().getValue() != null)) {
 
  100                     if (!searchString.isEmpty()) {
 
  101                         searchString += 
" and "; 
 
  103                     searchString += 
"Referrer \"" + entry.getReferrerURL().getValue().getValue() + 
"\""; 
 
  106                 if (entry.getUserProfileName() != null) {
 
  107                     haveUserProfile = 
true;
 
  108                     if (!searchString.isEmpty()) {
 
  109                         searchString += 
" and "; 
 
  111                     searchString += 
"UserProfile \"" + entry.getUserProfileName().getValue() + 
"\""; 
 
  114                 if (entry.getPageTitle() != null) {
 
  115                     havePageTitle = 
true;
 
  116                     if (!searchString.isEmpty()) {
 
  117                         searchString += 
" and "; 
 
  119                     searchString += 
"Page title \"" + entry.getPageTitle().getValue() + 
"\""; 
 
  122                 if ((entry.getHostname() != null) && (entry.getHostname().getHostnameValue() != null)) {
 
  124                     if (!searchString.isEmpty()) {
 
  125                         searchString += 
" and "; 
 
  127                     searchString += 
"Hostname \"" + entry.getHostname().getHostnameValue().getValue() + 
"\""; 
 
  130                 if (!finalResultsStr.isEmpty()) {
 
  131                     finalResultsStr += 
", ";
 
  133                 finalResultsStr += searchString;
 
  135                 if (!(haveURL || haveHostname || haveReferrer
 
  136                         || havePageTitle || haveUserProfile || haveBrowserName)) {
 
  137                     return new ObservableResult(
id, 
"URLHistoryObject: No evaluatable fields found", 
 
  138                             spacing, ObservableResult.ObservableState.INDETERMINATE, null);
 
  142                     Case case1 = Case.getCurrentCaseThrows();
 
  143                     SleuthkitCase sleuthkitCase = case1.getSleuthkitCase();
 
  144                     List<BlackboardArtifact> artList
 
  145                             = sleuthkitCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY);
 
  147                     for (BlackboardArtifact art : artList) {
 
  148                         boolean foundURLMatch = 
false;
 
  149                         boolean foundHostnameMatch = 
false;
 
  150                         boolean foundReferrerMatch = 
false;
 
  151                         boolean foundPageTitleMatch = 
false;
 
  152                         boolean foundUserProfileMatch = 
false;
 
  153                         boolean foundBrowserNameMatch = 
false;
 
  155                         for (BlackboardAttribute attr : art.getAttributes()) {
 
  156                             if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL.getTypeID())
 
  158                                 if (entry.getURL().getValue() instanceof AnyURIObjectPropertyType) {
 
  159                                     foundURLMatch = compareStringObject(entry.getURL().getValue().getValue().toString(),
 
  160                                             entry.getURL().getValue().getCondition(),
 
  161                                             entry.getURL().getValue().getApplyCondition(),
 
  162                                             attr.getValueString());
 
  164                                     addWarning(
"Non-AnyURIObjectPropertyType found in URL value field"); 
 
  167                             if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID())
 
  169                                 foundHostnameMatch = compareStringObject(entry.getHostname().getHostnameValue(),
 
  170                                         attr.getValueString());
 
  172                             if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_REFERRER.getTypeID())
 
  174                                 if (entry.getReferrerURL().getValue() instanceof AnyURIObjectPropertyType) {
 
  175                                     foundReferrerMatch = compareStringObject(entry.getReferrerURL().getValue().getValue().toString(),
 
  176                                             entry.getURL().getValue().getCondition(),
 
  177                                             entry.getURL().getValue().getApplyCondition(),
 
  178                                             attr.getValueString());
 
  180                                     addWarning(
"Non-AnyURIObjectPropertyType found in URL value field"); 
 
  183                             if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE.getTypeID())
 
  184                                     && (havePageTitle)) {
 
  185                                 foundPageTitleMatch = compareStringObject(entry.getPageTitle(),
 
  186                                         attr.getValueString());
 
  188                             if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME.getTypeID())
 
  189                                     && (haveUserProfile)) {
 
  190                                 foundUserProfileMatch = compareStringObject(entry.getUserProfileName(),
 
  191                                         attr.getValueString());
 
  193                             if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID())
 
  194                                     && (haveBrowserName)) {
 
  195                                 foundBrowserNameMatch = compareStringObject(obj.getBrowserInformation().getName(),
 
  196                                         null, null, attr.getValueString());
 
  200                         if (((!haveURL) || foundURLMatch)
 
  201                                 && ((!haveHostname) || foundHostnameMatch)
 
  202                                 && ((!haveReferrer) || foundReferrerMatch)
 
  203                                 && ((!havePageTitle) || foundPageTitleMatch)
 
  204                                 && ((!haveUserProfile) || foundUserProfileMatch)
 
  205                                 && ((!haveBrowserName) || foundBrowserNameMatch)) {
 
  210                 } 
catch (TskCoreException | NoCurrentCaseException ex) {
 
  211                     return new ObservableResult(
id, 
"URLHistoryObject: Exception during evaluation: " + ex.getLocalizedMessage(), 
 
  212                             spacing, ObservableResult.ObservableState.INDETERMINATE, null);
 
  217             if (!finalHits.isEmpty()) {
 
  218                 List<StixArtifactData> artData = 
new ArrayList<StixArtifactData>();
 
  219                 for (BlackboardArtifact a : finalHits) {
 
  220                     artData.add(
new StixArtifactData(a.getObjectID(), id, 
"URLHistory")); 
 
  222                 return new ObservableResult(
id, 
"URLHistoryObject: Found at least one match for " + finalResultsStr, 
 
  223                         spacing, ObservableResult.ObservableState.TRUE, artData);
 
  227             return new ObservableResult(
id, 
"URLHistoryObject: No matches found for " + finalResultsStr, 
 
  228                     spacing, ObservableResult.ObservableState.FALSE, null);
 
  230         } 
else if (haveBrowserName) {
 
  235                 Case case1 = Case.getCurrentCaseThrows();
 
  236                 SleuthkitCase sleuthkitCase = case1.getSleuthkitCase();
 
  237                 List<BlackboardArtifact> artList
 
  238                         = sleuthkitCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY);
 
  240                 for (BlackboardArtifact art : artList) {
 
  241                     boolean foundBrowserNameMatch = 
false;
 
  243                     for (BlackboardAttribute attr : art.getAttributes()) {
 
  244                         if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID())
 
  245                                 && (haveBrowserName)) {
 
  246                             foundBrowserNameMatch = compareStringObject(obj.getBrowserInformation().getName(),
 
  247                                     null, null, attr.getValueString());
 
  251                     if (foundBrowserNameMatch) {
 
  256                 if (!finalHits.isEmpty()) {
 
  257                     List<StixArtifactData> artData = 
new ArrayList<StixArtifactData>();
 
  258                     for (BlackboardArtifact a : finalHits) {
 
  259                         artData.add(
new StixArtifactData(a.getObjectID(), id, 
"URLHistory")); 
 
  261                     return new ObservableResult(
id, 
"URLHistoryObject: Found at least one match", 
 
  262                             spacing, ObservableResult.ObservableState.TRUE, artData);
 
  266                 return new ObservableResult(
id, 
"URLHistoryObject: No matches found for " + baseSearchString, 
 
  267                         spacing, ObservableResult.ObservableState.FALSE, null);
 
  268             } 
catch (TskCoreException | NoCurrentCaseException ex) {
 
  269                 return new ObservableResult(
id, 
"URLHistoryObject: Exception during evaluation: " + ex.getLocalizedMessage(), 
 
  270                         spacing, ObservableResult.ObservableState.INDETERMINATE, null);
 
  275             return new ObservableResult(
id, 
"URLHistoryObject: No evaluatable fields found", 
 
  276                     spacing, ObservableResult.ObservableState.INDETERMINATE, null);
 
  285     private void setUnsupportedEntryFieldWarnings(URLHistoryEntryType entry) {
 
  286         List<String> fieldNames = 
new ArrayList<String>();
 
  288         if (entry.getUserProfileName() != null) {
 
  289             fieldNames.add(
"User_Profile_Name"); 
 
  291         if (entry.getVisitCount() != null) {
 
  292             fieldNames.add(
"Visit_Count"); 
 
  294         if (entry.getManuallyEnteredCount() != null) {
 
  295             fieldNames.add(
"Manually_Entered_Count"); 
 
  297         if (entry.getModificationDateTime() != null) {
 
  298             fieldNames.add(
"Modification_DateTime"); 
 
  300         if (entry.getExpirationDateTime() != null) {
 
  301             fieldNames.add(
"Expiration_DateTime"); 
 
  303         if (entry.getFirstVisitDateTime() != null) {
 
  304             fieldNames.add(
"First_Visit_DateTime"); 
 
  306         if (entry.getLastVisitDateTime() != null) {
 
  307             fieldNames.add(
"Last_Visit_DateTime"); 
 
  310         String warningStr = 
"";
 
  311         for (String name : fieldNames) {
 
  312             if (!warningStr.isEmpty()) {
 
  318         addWarning(
"Unsupported URL_History_Entry field(s): " + warningStr);