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.getAttributeType().getTypeID() == 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.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID())
168 foundHostnameMatch = compareStringObject(entry.getHostname().getHostnameValue(),
169 attr.getValueString());
171 if ((attr.getAttributeType().getTypeID() == 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.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE.getTypeID())
183 && (havePageTitle)) {
184 foundPageTitleMatch = compareStringObject(entry.getPageTitle(),
185 attr.getValueString());
187 if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME.getTypeID())
188 && (haveUserProfile)) {
189 foundUserProfileMatch = compareStringObject(entry.getUserProfileName(),
190 attr.getValueString());
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());
199 if (((!haveURL) || foundURLMatch)
200 && ((!haveHostname) || foundHostnameMatch)
201 && ((!haveReferrer) || foundReferrerMatch)
202 && ((!havePageTitle) || foundPageTitleMatch)
203 && ((!haveUserProfile) || foundUserProfileMatch)
204 && ((!haveBrowserName) || foundBrowserNameMatch)) {
209 }
catch (TskCoreException ex) {
210 return new ObservableResult(
id,
"URLHistoryObject: Exception during evaluation: " + ex.getLocalizedMessage(),
211 spacing, ObservableResult.ObservableState.INDETERMINATE, null);
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"));
221 return new ObservableResult(
id,
"URLHistoryObject: Found at least one match for " + finalResultsStr,
222 spacing, ObservableResult.ObservableState.TRUE, artData);
226 return new ObservableResult(
id,
"URLHistoryObject: No matches found for " + finalResultsStr,
227 spacing, ObservableResult.ObservableState.FALSE, null);
229 }
else if (haveBrowserName) {
234 Case case1 = Case.getCurrentCase();
235 SleuthkitCase sleuthkitCase = case1.getSleuthkitCase();
236 List<BlackboardArtifact> artList
237 = sleuthkitCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY);
239 for (BlackboardArtifact art : artList) {
240 boolean foundBrowserNameMatch =
false;
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());
250 if (foundBrowserNameMatch) {
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"));
260 return new ObservableResult(
id,
"URLHistoryObject: Found at least one match",
261 spacing, ObservableResult.ObservableState.TRUE, artData);
265 return new ObservableResult(
id,
"URLHistoryObject: No matches found for " + baseSearchString,
266 spacing, ObservableResult.ObservableState.FALSE, null);
267 }
catch (TskCoreException ex) {
268 return new ObservableResult(
id,
"URLHistoryObject: Exception during evaluation: " + ex.getLocalizedMessage(),
269 spacing, ObservableResult.ObservableState.INDETERMINATE, null);
274 return new ObservableResult(
id,
"URLHistoryObject: No evaluatable fields found",
275 spacing, ObservableResult.ObservableState.INDETERMINATE, null);
284 private void setUnsupportedEntryFieldWarnings(URLHistoryEntryType entry) {
285 List<String> fieldNames =
new ArrayList<String>();
287 if (entry.getUserProfileName() != null) {
288 fieldNames.add(
"User_Profile_Name");
290 if (entry.getVisitCount() != null) {
291 fieldNames.add(
"Visit_Count");
293 if (entry.getManuallyEnteredCount() != null) {
294 fieldNames.add(
"Manually_Entered_Count");
296 if (entry.getModificationDateTime() != null) {
297 fieldNames.add(
"Modification_DateTime");
299 if (entry.getExpirationDateTime() != null) {
300 fieldNames.add(
"Expiration_DateTime");
302 if (entry.getFirstVisitDateTime() != null) {
303 fieldNames.add(
"First_Visit_DateTime");
305 if (entry.getLastVisitDateTime() != null) {
306 fieldNames.add(
"Last_Visit_DateTime");
309 String warningStr =
"";
310 for (String name : fieldNames) {
311 if (!warningStr.isEmpty()) {
317 addWarning(
"Unsupported URL_History_Entry field(s): " + warningStr);