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);