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.getAttributeTypeID() == 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.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID())
168 foundHostnameMatch = compareStringObject(entry.getHostname().getHostnameValue(),
169 attr.getValueString());
171 if ((attr.getAttributeTypeID() == 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.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE.getTypeID())
183 && (havePageTitle)) {
185 foundPageTitleMatch = compareStringObject(entry.getPageTitle(),
186 attr.getValueString());
188 if ((attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME.getTypeID())
189 && (haveUserProfile)) {
190 foundUserProfileMatch = compareStringObject(entry.getUserProfileName(),
191 attr.getValueString());
193 if ((attr.getAttributeTypeID() == 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 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.getCurrentCase();
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.getAttributeTypeID() == 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 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);