Autopsy  4.17.0
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-2018 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.report.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;
34 
38 class EvalURLHistoryObj extends EvaluatableObject {
39 
40  private final URLHistory obj;
41 
42  public EvalURLHistoryObj(URLHistory a_obj, String a_id, String a_spacing) {
43  obj = a_obj;
44  id = a_id;
45  spacing = a_spacing;
46  }
47 
48  @Override
49  public synchronized ObservableResult evaluate() {
50 
51  setWarnings("");
52 
53  if ((obj.getBrowserInformation() == null) && (obj.getURLHistoryEntries() == null)) {
54  return new ObservableResult(id, "URLHistoryObject: No browser info or history entries found", //NON-NLS
55  spacing, ObservableResult.ObservableState.INDETERMINATE, null);
56  }
57 
58  // For displaying what we were looking for in the results
59  String baseSearchString = "";
60  String finalResultsStr = "";
61 
62  // The browser info is the same for each entry
63  boolean haveBrowserName = false;
64  if (obj.getBrowserInformation() != null) {
65  if (obj.getBrowserInformation().getName() != null) {
66  haveBrowserName = true;
67  }
68  baseSearchString = "Browser \"" + obj.getBrowserInformation().getName() + "\""; //NON-NLS
69  }
70 
71  // Matching artifacts
72  List<BlackboardArtifact> finalHits = new ArrayList<BlackboardArtifact>();
73 
74  if (obj.getURLHistoryEntries() != null) {
75 
76  for (URLHistoryEntryType entry : obj.getURLHistoryEntries()) {
77 
78  boolean haveURL = false;
79  boolean haveHostname = false;
80  boolean haveReferrer = false;
81  boolean havePageTitle = false;
82  boolean haveUserProfile = false;
83 
84  setUnsupportedEntryFieldWarnings(entry);
85 
86  // At present, the search string doesn't get reported (because there could be different ones
87  // for multiple URL History Entries) but it's good for debugging.
88  String searchString = baseSearchString;
89 
90  if ((entry.getURL() != null) && (entry.getURL().getValue() != null)) {
91  haveURL = true;
92  if (!searchString.isEmpty()) {
93  searchString += " and "; //NON-NLS
94  }
95  searchString += "URL \"" + entry.getURL().getValue().getValue() + "\""; //NON-NLS
96  }
97 
98  if ((entry.getReferrerURL() != null) && (entry.getReferrerURL().getValue() != null)) {
99  haveReferrer = true;
100  if (!searchString.isEmpty()) {
101  searchString += " and "; //NON-NLS
102  }
103  searchString += "Referrer \"" + entry.getReferrerURL().getValue().getValue() + "\""; //NON-NLS
104  }
105 
106  if (entry.getUserProfileName() != null) {
107  haveUserProfile = true;
108  if (!searchString.isEmpty()) {
109  searchString += " and "; //NON-NLS
110  }
111  searchString += "UserProfile \"" + entry.getUserProfileName().getValue() + "\""; //NON-NLS
112  }
113 
114  if (entry.getPageTitle() != null) {
115  havePageTitle = true;
116  if (!searchString.isEmpty()) {
117  searchString += " and "; //NON-NLS
118  }
119  searchString += "Page title \"" + entry.getPageTitle().getValue() + "\""; //NON-NLS
120  }
121 
122  if ((entry.getHostname() != null) && (entry.getHostname().getHostnameValue() != null)) {
123  haveHostname = true;
124  if (!searchString.isEmpty()) {
125  searchString += " and "; //NON-NLS
126  }
127  searchString += "Hostname \"" + entry.getHostname().getHostnameValue().getValue() + "\""; //NON-NLS
128  }
129 
130  if (!finalResultsStr.isEmpty()) {
131  finalResultsStr += ", ";
132  }
133  finalResultsStr += searchString;
134 
135  if (!(haveURL || haveHostname || haveReferrer
136  || havePageTitle || haveUserProfile || haveBrowserName)) {
137  return new ObservableResult(id, "URLHistoryObject: No evaluatable fields found", //NON-NLS
138  spacing, ObservableResult.ObservableState.INDETERMINATE, null);
139  }
140 
141  try {
142  Case case1 = Case.getCurrentCaseThrows();
143  SleuthkitCase sleuthkitCase = case1.getSleuthkitCase();
144  List<BlackboardArtifact> artList
145  = sleuthkitCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY);
146 
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;
154 
155  for (BlackboardAttribute attr : art.getAttributes()) {
156  if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL.getTypeID())
157  && (haveURL)) {
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());
163  } else {
164  addWarning("Non-AnyURIObjectPropertyType found in URL value field"); //NON-NLS
165  }
166  }
167  if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID())
168  && (haveHostname)) {
169  foundHostnameMatch = compareStringObject(entry.getHostname().getHostnameValue(),
170  attr.getValueString());
171  }
172  if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_REFERRER.getTypeID())
173  && (haveReferrer)) {
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());
179  } else {
180  addWarning("Non-AnyURIObjectPropertyType found in URL value field"); //NON-NLS
181  }
182  }
183  if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE.getTypeID())
184  && (havePageTitle)) {
185  foundPageTitleMatch = compareStringObject(entry.getPageTitle(),
186  attr.getValueString());
187  }
188  if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME.getTypeID())
189  && (haveUserProfile)) {
190  foundUserProfileMatch = compareStringObject(entry.getUserProfileName(),
191  attr.getValueString());
192  }
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());
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 | NoCurrentCaseException 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.getCurrentCaseThrows();
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.getAttributeType().getTypeID() == 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 | NoCurrentCaseException 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-2021 Basis Technology. Generated on: Tue Jan 19 2021
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.