Autopsy  4.4
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 
22 import org.sleuthkit.datamodel.SleuthkitCase;
23 import org.sleuthkit.datamodel.BlackboardArtifact;
24 import org.sleuthkit.datamodel.BlackboardAttribute;
25 import org.sleuthkit.datamodel.TskCoreException;
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.getAttributeType().getTypeID() == 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.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID())
167  && (haveHostname)) {
168  foundHostnameMatch = compareStringObject(entry.getHostname().getHostnameValue(),
169  attr.getValueString());
170  }
171  if ((attr.getAttributeType().getTypeID() == 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.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE.getTypeID())
183  && (havePageTitle)) {
184  foundPageTitleMatch = compareStringObject(entry.getPageTitle(),
185  attr.getValueString());
186  }
187  if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME.getTypeID())
188  && (haveUserProfile)) {
189  foundUserProfileMatch = compareStringObject(entry.getUserProfileName(),
190  attr.getValueString());
191  }
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());
196  }
197  }
198 
199  if (((!haveURL) || foundURLMatch)
200  && ((!haveHostname) || foundHostnameMatch)
201  && ((!haveReferrer) || foundReferrerMatch)
202  && ((!havePageTitle) || foundPageTitleMatch)
203  && ((!haveUserProfile) || foundUserProfileMatch)
204  && ((!haveBrowserName) || foundBrowserNameMatch)) {
205  finalHits.add(art);
206  }
207  }
208 
209  } catch (TskCoreException ex) {
210  return new ObservableResult(id, "URLHistoryObject: Exception during evaluation: " + ex.getLocalizedMessage(), //NON-NLS
211  spacing, ObservableResult.ObservableState.INDETERMINATE, null);
212  }
213 
214  }
215 
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")); //NON-NLS
220  }
221  return new ObservableResult(id, "URLHistoryObject: Found at least one match for " + finalResultsStr, //NON-NLS
222  spacing, ObservableResult.ObservableState.TRUE, artData);
223  }
224 
225  // Didn't find any matches
226  return new ObservableResult(id, "URLHistoryObject: No matches found for " + finalResultsStr, //NON-NLS
227  spacing, ObservableResult.ObservableState.FALSE, null);
228 
229  } else if (haveBrowserName) {
230 
231  // It doesn't seem too useful, but we can just search for the browser name
232  // if there aren't any URL entries
233  try {
234  Case case1 = Case.getCurrentCase();
235  SleuthkitCase sleuthkitCase = case1.getSleuthkitCase();
236  List<BlackboardArtifact> artList
237  = sleuthkitCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY);
238 
239  for (BlackboardArtifact art : artList) {
240  boolean foundBrowserNameMatch = false;
241 
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());
247  }
248  }
249 
250  if (foundBrowserNameMatch) {
251  finalHits.add(art);
252  }
253  }
254 
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")); //NON-NLS
259  }
260  return new ObservableResult(id, "URLHistoryObject: Found at least one match", //NON-NLS
261  spacing, ObservableResult.ObservableState.TRUE, artData);
262  }
263 
264  // Didn't find any matches
265  return new ObservableResult(id, "URLHistoryObject: No matches found for " + baseSearchString, //NON-NLS
266  spacing, ObservableResult.ObservableState.FALSE, null);
267  } catch (TskCoreException ex) {
268  return new ObservableResult(id, "URLHistoryObject: Exception during evaluation: " + ex.getLocalizedMessage(), //NON-NLS
269  spacing, ObservableResult.ObservableState.INDETERMINATE, null);
270  }
271 
272  } else {
273  // Nothing to search for
274  return new ObservableResult(id, "URLHistoryObject: No evaluatable fields found", //NON-NLS
275  spacing, ObservableResult.ObservableState.INDETERMINATE, null);
276  }
277 
278  }
279 
284  private void setUnsupportedEntryFieldWarnings(URLHistoryEntryType entry) {
285  List<String> fieldNames = new ArrayList<String>();
286 
287  if (entry.getUserProfileName() != null) {
288  fieldNames.add("User_Profile_Name"); //NON-NLS
289  }
290  if (entry.getVisitCount() != null) {
291  fieldNames.add("Visit_Count"); //NON-NLS
292  }
293  if (entry.getManuallyEnteredCount() != null) {
294  fieldNames.add("Manually_Entered_Count"); //NON-NLS
295  }
296  if (entry.getModificationDateTime() != null) {
297  fieldNames.add("Modification_DateTime"); //NON-NLS
298  }
299  if (entry.getExpirationDateTime() != null) {
300  fieldNames.add("Expiration_DateTime"); //NON-NLS
301  }
302  if (entry.getFirstVisitDateTime() != null) {
303  fieldNames.add("First_Visit_DateTime"); //NON-NLS
304  }
305  if (entry.getLastVisitDateTime() != null) {
306  fieldNames.add("Last_Visit_DateTime"); //NON-NLS
307  }
308 
309  String warningStr = "";
310  for (String name : fieldNames) {
311  if (!warningStr.isEmpty()) {
312  warningStr += ", ";
313  }
314  warningStr += name;
315  }
316 
317  addWarning("Unsupported URL_History_Entry field(s): " + warningStr); //NON-NLS
318  }
319 }

Copyright © 2012-2016 Basis Technology. Generated on: Tue Jun 13 2017
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.