Autopsy  3.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
EvalURLHistoryObj.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2013 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.modules.stix;
20 
26 
27 import java.util.List;
28 import java.util.ArrayList;
29 
30 import org.mitre.cybox.common_2.AnyURIObjectPropertyType;
31 import org.mitre.cybox.objects.URLHistory;
32 import org.mitre.cybox.objects.URLHistoryEntryType;
33 
37 class EvalURLHistoryObj extends EvaluatableObject {
38 
39  private final URLHistory obj;
40 
41  public EvalURLHistoryObj(URLHistory a_obj, String a_id, String a_spacing) {
42  obj = a_obj;
43  id = a_id;
44  spacing = a_spacing;
45  }
46 
47  @Override
48  public synchronized ObservableResult evaluate() {
49 
50  setWarnings("");
51 
52  if ((obj.getBrowserInformation() == null) && (obj.getURLHistoryEntries() == null)) {
53  return new ObservableResult(id, "URLHistoryObject: No browser info or history entries found", //NON-NLS
54  spacing, ObservableResult.ObservableState.INDETERMINATE, null);
55  }
56 
57  // For displaying what we were looking for in the results
58  String baseSearchString = "";
59  String finalResultsStr = "";
60 
61  // The browser info is the same for each entry
62  boolean haveBrowserName = false;
63  if (obj.getBrowserInformation() != null) {
64  if (obj.getBrowserInformation().getName() != null) {
65  haveBrowserName = true;
66  }
67  baseSearchString = "Browser \"" + obj.getBrowserInformation().getName() + "\""; //NON-NLS
68  }
69 
70  // Matching artifacts
71  List<BlackboardArtifact> finalHits = new ArrayList<BlackboardArtifact>();
72 
73  if (obj.getURLHistoryEntries() != null) {
74 
75  for (URLHistoryEntryType entry : obj.getURLHistoryEntries()) {
76 
77  boolean haveURL = false;
78  boolean haveHostname = false;
79  boolean haveReferrer = false;
80  boolean havePageTitle = false;
81  boolean haveUserProfile = false;
82 
83  setUnsupportedEntryFieldWarnings(entry);
84 
85  // At present, the search string doesn't get reported (because there could be different ones
86  // for multiple URL History Entries) but it's good for debugging.
87  String searchString = baseSearchString;
88 
89  if ((entry.getURL() != null) && (entry.getURL().getValue() != null)) {
90  haveURL = true;
91  if (!searchString.isEmpty()) {
92  searchString += " and "; //NON-NLS
93  }
94  searchString += "URL \"" + entry.getURL().getValue().getValue() + "\""; //NON-NLS
95  }
96 
97  if ((entry.getReferrerURL() != null) && (entry.getReferrerURL().getValue() != null)) {
98  haveReferrer = true;
99  if (!searchString.isEmpty()) {
100  searchString += " and "; //NON-NLS
101  }
102  searchString += "Referrer \"" + entry.getReferrerURL().getValue().getValue() + "\""; //NON-NLS
103  }
104 
105  if (entry.getUserProfileName() != null) {
106  haveUserProfile = true;
107  if (!searchString.isEmpty()) {
108  searchString += " and "; //NON-NLS
109  }
110  searchString += "UserProfile \"" + entry.getUserProfileName().getValue() + "\""; //NON-NLS
111  }
112 
113  if (entry.getPageTitle() != null) {
114  havePageTitle = true;
115  if (!searchString.isEmpty()) {
116  searchString += " and "; //NON-NLS
117  }
118  searchString += "Page title \"" + entry.getPageTitle().getValue() + "\""; //NON-NLS
119  }
120 
121  if ((entry.getHostname() != null) && (entry.getHostname().getHostnameValue() != null)) {
122  haveHostname = true;
123  if (!searchString.isEmpty()) {
124  searchString += " and "; //NON-NLS
125  }
126  searchString += "Hostname \"" + entry.getHostname().getHostnameValue().getValue() + "\""; //NON-NLS
127  }
128 
129  if (!finalResultsStr.isEmpty()) {
130  finalResultsStr += ", ";
131  }
132  finalResultsStr += searchString;
133 
134  if (!(haveURL || haveHostname || haveReferrer
135  || havePageTitle || haveUserProfile || haveBrowserName)) {
136  return new ObservableResult(id, "URLHistoryObject: No evaluatable fields found", //NON-NLS
137  spacing, ObservableResult.ObservableState.INDETERMINATE, null);
138  }
139 
140  try {
141  Case case1 = Case.getCurrentCase();
142  SleuthkitCase sleuthkitCase = case1.getSleuthkitCase();
143  List<BlackboardArtifact> artList
144  = sleuthkitCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY);
145 
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;
153 
154  for (BlackboardAttribute attr : art.getAttributes()) {
155  if ((attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL.getTypeID())
156  && (haveURL)) {
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());
162  } else {
163  addWarning("Non-AnyURIObjectPropertyType found in URL value field"); //NON-NLS
164  }
165  }
166  if ((attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID())
167  && (haveHostname)) {
168  foundHostnameMatch = compareStringObject(entry.getHostname().getHostnameValue(),
169  attr.getValueString());
170  }
171  if ((attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_REFERRER.getTypeID())
172  && (haveReferrer)) {
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());
178  } else {
179  addWarning("Non-AnyURIObjectPropertyType found in URL value field"); //NON-NLS
180  }
181  }
182  if ((attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE.getTypeID())
183  && (havePageTitle)) {
184  //System.out.println("Page title: " + attr.getValueString() + " " + entry.getPageTitle());
185  foundPageTitleMatch = compareStringObject(entry.getPageTitle(),
186  attr.getValueString());
187  }
188  if ((attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME.getTypeID())
189  && (haveUserProfile)) {
190  foundUserProfileMatch = compareStringObject(entry.getUserProfileName(),
191  attr.getValueString());
192  }
193  if ((attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID())
194  && (haveBrowserName)) {
195  foundBrowserNameMatch = compareStringObject(obj.getBrowserInformation().getName(),
196  null, null, attr.getValueString());
197  }
198  }
199 
200  if (((!haveURL) || foundURLMatch)
201  && ((!haveHostname) || foundHostnameMatch)
202  && ((!haveReferrer) || foundReferrerMatch)
203  && ((!havePageTitle) || foundPageTitleMatch)
204  && ((!haveUserProfile) || foundUserProfileMatch)
205  && ((!haveBrowserName) || foundBrowserNameMatch)) {
206  finalHits.add(art);
207  }
208  }
209 
210  } catch (TskCoreException ex) {
211  return new ObservableResult(id, "URLHistoryObject: Exception during evaluation: " + ex.getLocalizedMessage(), //NON-NLS
212  spacing, ObservableResult.ObservableState.INDETERMINATE, null);
213  }
214 
215  }
216 
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")); //NON-NLS
221  }
222  return new ObservableResult(id, "URLHistoryObject: Found at least one match for " + finalResultsStr, //NON-NLS
223  spacing, ObservableResult.ObservableState.TRUE, artData);
224  }
225 
226  // Didn't find any matches
227  return new ObservableResult(id, "URLHistoryObject: No matches found for " + finalResultsStr, //NON-NLS
228  spacing, ObservableResult.ObservableState.FALSE, null);
229 
230  } else if (haveBrowserName) {
231 
232  // It doesn't seem too useful, but we can just search for the browser name
233  // if there aren't any URL entries
234  try {
235  Case case1 = Case.getCurrentCase();
236  SleuthkitCase sleuthkitCase = case1.getSleuthkitCase();
237  List<BlackboardArtifact> artList
238  = sleuthkitCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY);
239 
240  for (BlackboardArtifact art : artList) {
241  boolean foundBrowserNameMatch = false;
242 
243  for (BlackboardAttribute attr : art.getAttributes()) {
244  if ((attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID())
245  && (haveBrowserName)) {
246  foundBrowserNameMatch = compareStringObject(obj.getBrowserInformation().getName(),
247  null, null, attr.getValueString());
248  }
249  }
250 
251  if (foundBrowserNameMatch) {
252  finalHits.add(art);
253  }
254  }
255 
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")); //NON-NLS
260  }
261  return new ObservableResult(id, "URLHistoryObject: Found at least one match", //NON-NLS
262  spacing, ObservableResult.ObservableState.TRUE, artData);
263  }
264 
265  // Didn't find any matches
266  return new ObservableResult(id, "URLHistoryObject: No matches found for " + baseSearchString, //NON-NLS
267  spacing, ObservableResult.ObservableState.FALSE, null);
268  } catch (TskCoreException ex) {
269  return new ObservableResult(id, "URLHistoryObject: Exception during evaluation: " + ex.getLocalizedMessage(), //NON-NLS
270  spacing, ObservableResult.ObservableState.INDETERMINATE, null);
271  }
272 
273  } else {
274  // Nothing to search for
275  return new ObservableResult(id, "URLHistoryObject: No evaluatable fields found", //NON-NLS
276  spacing, ObservableResult.ObservableState.INDETERMINATE, null);
277  }
278 
279  }
280 
285  private void setUnsupportedEntryFieldWarnings(URLHistoryEntryType entry) {
286  List<String> fieldNames = new ArrayList<String>();
287 
288  if (entry.getUserProfileName() != null) {
289  fieldNames.add("User_Profile_Name"); //NON-NLS
290  }
291  if (entry.getVisitCount() != null) {
292  fieldNames.add("Visit_Count"); //NON-NLS
293  }
294  if (entry.getManuallyEnteredCount() != null) {
295  fieldNames.add("Manually_Entered_Count"); //NON-NLS
296  }
297  if (entry.getModificationDateTime() != null) {
298  fieldNames.add("Modification_DateTime"); //NON-NLS
299  }
300  if (entry.getExpirationDateTime() != null) {
301  fieldNames.add("Expiration_DateTime"); //NON-NLS
302  }
303  if (entry.getFirstVisitDateTime() != null) {
304  fieldNames.add("First_Visit_DateTime"); //NON-NLS
305  }
306  if (entry.getLastVisitDateTime() != null) {
307  fieldNames.add("Last_Visit_DateTime"); //NON-NLS
308  }
309 
310  String warningStr = "";
311  for (String name : fieldNames) {
312  if (!warningStr.isEmpty()) {
313  warningStr += ", ";
314  }
315  warningStr += name;
316  }
317 
318  addWarning("Unsupported URL_History_Entry field(s): " + warningStr); //NON-NLS
319  }
320 }

Copyright © 2012-2015 Basis Technology. Generated on: Mon Oct 19 2015
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.