19 package org.sleuthkit.autopsy.discovery.search;
21 import java.text.SimpleDateFormat;
34 import java.util.ArrayList;
35 import java.util.Arrays;
36 import java.util.Collection;
37 import java.util.Collections;
38 import java.util.Date;
39 import java.util.List;
40 import java.util.Locale;
41 import java.util.StringJoiner;
42 import java.util.concurrent.TimeUnit;
43 import java.util.stream.Collectors;
44 import org.openide.util.NbBundle;
49 import org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
71 String combinedQuery =
"";
73 if (!filter.getWhereClause().isEmpty()) {
74 if (!combinedQuery.isEmpty()) {
75 combinedQuery +=
" AND ";
77 combinedQuery +=
"(" + filter.getWhereClause() +
")";
81 if (combinedQuery.isEmpty()) {
86 return getResultList(filters, combinedQuery, caseDb, centralRepoDb);
87 }
catch (TskCoreException ex) {
108 List<Result> resultList =
new ArrayList<>();
109 List<AbstractFile> sqlResults = caseDb.findAllFilesWhere(combinedQuery);
112 if (sqlResults.isEmpty()) {
117 for (AbstractFile abstractFile : sqlResults) {
123 if (filter.useAlternateFilter()) {
124 resultList = filter.applyAlternateFilter(resultList, caseDb, centralRepoDb);
127 if (resultList.isEmpty()) {
144 private static List<BlackboardAttribute.ATTRIBUTE_TYPE>
dateAttributes
146 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME,
147 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
148 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED
166 static String createAttributeTypeClause() {
167 StringJoiner joiner =
new StringJoiner(
",");
169 joiner.add(
"\'" + type.getTypeID() +
"\'");
171 return "attribute_type_id IN (" + joiner.toString() +
")";
176 return createAttributeTypeClause()
177 +
" AND (value_int64 BETWEEN " + startDate +
" AND " + endDate +
")";
180 @NbBundle.Messages({
"SearchFiltering.dateRangeFilter.lable=Activity date ",
182 "SearchFiltering.dateRangeFilter.after=after: {0}",
184 "SearchFiltering.dateRangeFilter.before=before: {0}",
185 "SearchFiltering.dateRangeFilter.and= and "})
190 desc += Bundle.SearchFiltering_dateRangeFilter_after(
new SimpleDateFormat(
"yyyy/MM/dd", Locale.getDefault()).format(
new Date(TimeUnit.SECONDS.toMillis(startDate))));
192 if (endDate < 10000000000L) {
193 if (!desc.isEmpty()) {
194 desc += Bundle.SearchFiltering_dateRangeFilter_and();
196 desc += Bundle.SearchFiltering_dateRangeFilter_before(
new SimpleDateFormat(
"yyyy/MM/dd", Locale.getDefault()).format(
new Date(TimeUnit.SECONDS.toMillis(endDate))));
198 if (!desc.isEmpty()) {
199 desc = Bundle.SearchFiltering_dateRangeFilter_lable() + desc;
210 private final Collection<ARTIFACT_TYPE>
types;
228 return Collections.unmodifiableCollection(types);
232 StringJoiner joiner =
new StringJoiner(
",");
233 for (ARTIFACT_TYPE type : types) {
234 joiner.add(
"\'" + type.getTypeID() +
"\'");
242 return "artifact_type_id IN (" + joiner +
")";
248 String
getWhereClause(List<ARTIFACT_TYPE> nonVisibleArtifactTypesToInclude) {
250 for (ARTIFACT_TYPE type : nonVisibleArtifactTypesToInclude) {
251 joiner.add(
"\'" + type.getTypeID() +
"\'");
253 return "artifact_type_id IN (" + joiner +
")";
256 @NbBundle.Messages({
"# {0} - artifactTypes",
257 "SearchFiltering.artifactTypeFilter.desc=Result type(s): {0}",
258 "SearchFiltering.artifactTypeFilter.or=, "})
262 for (ARTIFACT_TYPE type : types) {
263 if (!desc.isEmpty()) {
264 desc += Bundle.SearchFiltering_artifactTypeFilter_or();
266 desc += type.getDisplayName();
268 desc = Bundle.SearchFiltering_artifactTypeFilter_desc(desc);
292 String queryStr =
"";
294 if (!queryStr.isEmpty()) {
298 queryStr +=
"(size > \'" + size.getMinBytes() +
"\' AND size <= \'" + size.getMaxBytes() +
"\')";
300 queryStr +=
"(size >= \'" + size.getMinBytes() +
"\')";
308 "SearchFiltering.SizeFilter.desc=Size(s): {0}",
309 "SearchFiltering.SizeFilter.or=, "})
314 if (!desc.isEmpty()) {
315 desc += Bundle.SearchFiltering_SizeFilter_or();
317 desc += size.getSizeGroup();
319 desc = Bundle.SearchFiltering_SizeFilter_desc(desc);
366 return "parent_path NOT LIKE \'%" +
getSearchStr() +
"%\'";
372 "SearchFiltering.ParentSearchTerm.fullString= (exact)",
373 "SearchFiltering.ParentSearchTerm.subString= (substring)",
374 "SearchFiltering.ParentSearchTerm.includeString= (include)",
375 "SearchFiltering.ParentSearchTerm.excludeString= (exclude)",})
380 returnString += Bundle.SearchFiltering_ParentSearchTerm_fullString();
382 returnString += Bundle.SearchFiltering_ParentSearchTerm_subString();
385 returnString += Bundle.SearchFiltering_ParentSearchTerm_includeString();
387 returnString += Bundle.SearchFiltering_ParentSearchTerm_excludeString();
442 String includeQueryStr =
"";
443 String excludeQueryStr =
"";
445 if (searchTerm.isIncluded()) {
446 if (!includeQueryStr.isEmpty()) {
447 includeQueryStr +=
" OR ";
449 includeQueryStr += searchTerm.getSQLForTerm();
451 if (!excludeQueryStr.isEmpty()) {
452 excludeQueryStr +=
" AND ";
454 excludeQueryStr += searchTerm.getSQLForTerm();
457 if (!includeQueryStr.isEmpty()) {
458 includeQueryStr =
"(" + includeQueryStr +
")";
460 if (!excludeQueryStr.isEmpty()) {
461 excludeQueryStr =
"(" + excludeQueryStr +
")";
463 if (includeQueryStr.isEmpty() || excludeQueryStr.isEmpty()) {
464 return includeQueryStr + excludeQueryStr;
466 return includeQueryStr +
" AND " + excludeQueryStr;
472 "SearchFiltering.ParentFilter.desc=Paths matching: {0}",
473 "SearchFiltering.ParentFilter.or=, ",
474 "SearchFiltering.ParentFilter.exact=(exact match)",
475 "SearchFiltering.ParentFilter.substring=(substring)",
476 "SearchFiltering.ParentFilter.included=(included)",
477 "SearchFiltering.ParentFilter.excluded=(excluded)"})
482 if (!desc.isEmpty()) {
483 desc += Bundle.SearchFiltering_ParentFilter_or();
485 if (searchTerm.isFullPath()) {
486 desc += searchTerm.getSearchStr() + Bundle.SearchFiltering_ParentFilter_exact();
488 desc += searchTerm.getSearchStr() + Bundle.SearchFiltering_ParentFilter_substring();
490 if (searchTerm.isIncluded()) {
491 desc += Bundle.SearchFiltering_ParentFilter_included();
493 desc += Bundle.SearchFiltering_ParentFilter_excluded();
496 desc = Bundle.SearchFiltering_ParentFilter_desc(desc);
519 String queryStr =
"";
520 for (DataSource ds : dataSources) {
521 if (!queryStr.isEmpty()) {
524 queryStr +=
"\'" + ds.getId() +
"\'";
526 queryStr =
"data_source_obj_id IN (" + queryStr +
")";
532 "SearchFiltering.DataSourceFilter.desc=Data source(s): {0}",
533 "SearchFiltering.DataSourceFilter.or=, ",
534 "# {0} - Data source name",
535 "# {1} - Data source ID",
536 "SearchFiltering.DataSourceFilter.datasource={0}({1})",})
540 for (DataSource ds : dataSources) {
541 if (!desc.isEmpty()) {
542 desc += Bundle.SearchFiltering_DataSourceFilter_or();
544 desc += Bundle.SearchFiltering_DataSourceFilter_datasource(ds.getName(), ds.getId());
546 desc = Bundle.SearchFiltering_DataSourceFilter_desc(desc);
572 String queryStr =
"(obj_id IN (SELECT obj_id from blackboard_artifacts WHERE artifact_id IN "
573 +
"(SELECT artifact_id FROM blackboard_attributes WHERE artifact_type_id = 9 AND attribute_type_ID = 37 "
574 +
"AND (" + keywordListPart +
"))))";
581 "SearchFiltering.KeywordListFilter.desc=Keywords in list(s): {0}",})
610 this.categories =
new ArrayList<>();
611 this.categories.add(category);
616 String queryStr =
"";
617 for (
Type cat : categories) {
618 for (String type : cat.getMediaTypes()) {
619 if (!queryStr.isEmpty()) {
622 queryStr +=
"\'" + type +
"\'";
625 queryStr =
"mime_type IN (" + queryStr +
")";
631 "SearchFiltering.FileTypeFilter.desc=Type: {0}",
632 "SearchFiltering.FileTypeFilter.or=, ",})
636 for (
Type cat : categories) {
637 if (!desc.isEmpty()) {
638 desc += Bundle.SearchFiltering_FileTypeFilter_or();
640 desc += cat.toString();
642 desc = Bundle.SearchFiltering_FileTypeFilter_desc(desc);
680 freqAttr.addAttributeToResults(currentResults, caseDb, centralRepoDb);
683 List<Result> frequencyResults =
new ArrayList<>();
684 for (
Result file : currentResults) {
685 if (frequencies.contains(file.getFrequency())) {
686 frequencyResults.add(file);
689 return frequencyResults;
694 "SearchFiltering.FrequencyFilter.desc=Past occurrences: {0}",
695 "SearchFiltering.FrequencyFilter.or=, ",})
700 if (!desc.isEmpty()) {
701 desc += Bundle.SearchFiltering_FrequencyFilter_or();
703 desc += freq.toString();
705 return Bundle.SearchFiltering_FrequencyFilter_desc(desc);
716 throw new UnsupportedOperationException(
"Not supported, this is an alternative filter.");
727 List<Result> filteredResults =
new ArrayList<>();
728 for (
Result result : currentResults) {
730 ResultDomain domain = (ResultDomain) result;
732 filteredResults.add(domain);
735 filteredResults.add(result);
738 return filteredResults;
742 "SearchFiltering.KnownAccountTypeFilter.desc=Only domains with known account type"
746 return Bundle.SearchFiltering_KnownAccountTypeFilter_desc();
758 throw new UnsupportedOperationException(
"Not supported, this is an alternative filter.");
770 previouslyNotableAttr.addAttributeToResults(currentResults, caseDb, centralRepoDb);
771 List<Result> filteredResults =
new ArrayList<>();
772 for (
Result file : currentResults) {
774 filteredResults.add(file);
777 return filteredResults;
781 "SearchFiltering.PreviouslyNotableFilter.desc=Previously marked as notable in central repository"
785 return Bundle.SearchFiltering_PreviouslyNotableFilter_desc();
811 String queryStr =
"(obj_id IN (SELECT obj_id from blackboard_artifacts WHERE artifact_id IN "
812 +
"(SELECT artifact_id FROM blackboard_attributes WHERE artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()
813 +
" AND attribute_type_ID = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() +
" "
814 +
"AND (" + hashSetPart +
"))))";
821 "FileSearchFiltering.HashSetFilter.desc=Hash set hits in set(s): {0}",})
849 String queryStr =
"(obj_id IN (SELECT obj_id from blackboard_artifacts WHERE artifact_id IN "
850 +
"(SELECT artifact_id FROM blackboard_attributes WHERE artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID()
851 +
" AND attribute_type_ID = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() +
" "
852 +
"AND (" + intItemSetPart +
"))))";
859 "SearchFiltering.InterestingItemSetFilter.desc=Interesting item hits in set(s): {0}",})
887 String queryStr =
"(obj_id IN (SELECT obj_id from blackboard_artifacts WHERE artifact_id IN "
888 +
"(SELECT artifact_id FROM blackboard_attributes WHERE artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_OBJECT_DETECTED.getTypeID()
889 +
" AND attribute_type_ID = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION.getTypeID() +
" "
890 +
"AND (" + objTypePart +
"))))";
897 "SearchFiltering.ObjectDetectionFilter.desc=Objects detected in set(s): {0}",})
927 String hashsetQueryPart =
"";
928 String tagQueryPart =
"";
929 String intItemQueryPart =
"";
933 hashsetQueryPart =
" (known = " + TskData.FileKnown.BAD.getFileKnownValue() +
") ";
938 intItemQueryPart =
" (obj_id IN (SELECT obj_id from blackboard_artifacts WHERE artifact_type_id = "
939 + BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID() +
")) ";
944 tagQueryPart =
"(obj_id IN (SELECT obj_id FROM content_tags))";
947 tagQueryPart =
"(obj_id IN (SELECT obj_id FROM content_tags WHERE tag_name_id IN (SELECT tag_name_id FROM tag_names WHERE knownStatus = "
948 + TskData.FileKnown.BAD.getFileKnownValue() +
")))";
951 tagQueryPart =
"(obj_id IN (SELECT obj_id FROM content_tags WHERE tag_name_id IN (SELECT tag_name_id FROM tag_names WHERE knownStatus != "
952 + TskData.FileKnown.BAD.getFileKnownValue() +
")))";
955 String queryStr = hashsetQueryPart;
956 if (!intItemQueryPart.isEmpty()) {
957 if (!queryStr.isEmpty()) {
960 queryStr += intItemQueryPart;
962 if (!tagQueryPart.isEmpty()) {
963 if (!queryStr.isEmpty()) {
966 queryStr += tagQueryPart;
973 "SearchFiltering.ScoreFilter.desc=Score(s) of : {0}",})
976 return Bundle.SearchFiltering_ScoreFilter_desc(
1001 for (TagName tagName : tagNames) {
1002 if (!tagIDs.isEmpty()) {
1005 tagIDs += tagName.getId();
1008 String queryStr =
"(obj_id IN (SELECT obj_id FROM content_tags WHERE tag_name_id IN (" + tagIDs +
")))";
1013 @NbBundle.Messages({
1014 "# {0} - tag names",
1015 "FileSearchFiltering.TagsFilter.desc=Tagged {0}",
1016 "FileSearchFiltering.TagsFilter.or=, ",})
1020 for (TagName name : tagNames) {
1021 if (!desc.isEmpty()) {
1022 desc += Bundle.FileSearchFiltering_TagsFilter_or();
1024 desc += name.getDisplayName();
1026 return Bundle.FileSearchFiltering_TagsFilter_desc(desc);
1038 return "(obj_id IN (SELECT obj_id from blackboard_artifacts WHERE artifact_id IN "
1039 +
"(SELECT artifact_id FROM blackboard_attributes WHERE artifact_type_id = "
1040 + BlackboardArtifact.ARTIFACT_TYPE.TSK_USER_CONTENT_SUSPECTED.getTypeID() +
")))";
1043 @NbBundle.Messages({
1044 "FileSearchFiltering.UserCreatedFilter.desc=that contain EXIF data",})
1047 return Bundle.FileSearchFiltering_UserCreatedFilter_desc();
1073 if (centralRepoDb == null) {
1074 throw new DiscoveryException(
"Can not run Previously Notable filter with null Central Repository DB");
1079 if (currentResults.isEmpty()) {
1084 List<Result> notableResults =
new ArrayList<>();
1089 for (
Result result : currentResults) {
1098 notableResults.add(result);
1102 return notableResults;
1108 @NbBundle.Messages({
1109 "FileSearchFiltering.PreviouslyNotableFilter.desc=that were previously marked as notable",})
1112 return Bundle.FileSearchFiltering_PreviouslyNotableFilter_desc();
1123 return "known!=" + TskData.FileKnown.KNOWN.getFileKnownValue();
1126 @NbBundle.Messages({
1127 "FileSearchFiltering.KnownFilter.desc=which are not known"})
1130 return Bundle.FileSearchFiltering_KnownFilter_desc();
1141 @NbBundle.Messages({
1142 "FileSearchFiltering.concatenateSetNamesForDisplay.comma=, ",})
1145 for (String setName : setNames) {
1146 if (!desc.isEmpty()) {
1147 desc += Bundle.FileSearchFiltering_concatenateSetNamesForDisplay_comma();
1164 for (String setName : setNames) {
1165 if (!result.isEmpty()) {
1168 result +=
"value_text = \'" + setName +
"\'";
static String concatenateNamesForSQL(List< String > setNames)
static List< BlackboardAttribute.ATTRIBUTE_TYPE > dateAttributes
final List< Score > scores
FrequencyFilter(List< Frequency > frequencies)
staticfinal long NO_MAXIMUM
ParentFilter(List< ParentSearchTerm > parentSearchTerms)
final Collection< ARTIFACT_TYPE > types
final List< String > listNames
HashSetFilter(List< String > setNames)
ArtifactTypeFilter(Collection< ARTIFACT_TYPE > types)
ParentSearchTerm(String searchStr, boolean isFullPath, boolean isIncluded)
Collection< ARTIFACT_TYPE > getTypes()
static List< CorrelationAttributeInstance.Type > getDefaultCorrelationTypes()
ObjectDetectionFilter(List< String > typeNames)
List< Result > applyAlternateFilter(List< Result > currentResults, SleuthkitCase caseDb, CentralRepository centralRepoDb)
boolean useAlternateFilter()
KeywordListFilter(List< String > listNames)
final List< String > setNames
boolean hasKnownAccountType()
ArtifactDateRangeFilter(Long startDate, Long endDate)
List< Result > applyAlternateFilter(List< Result > currentResults, SleuthkitCase caseDb, CentralRepository centralRepoDb)
FileTypeFilter(Type category)
Long getCountArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value)
boolean useAlternateFilter()
AbstractFile getFirstInstance()
static String concatenateSetNamesForDisplay(List< String > setNames)
final List< DataSource > dataSources
final List< ParentSearchTerm > parentSearchTerms
boolean useAlternateFilter()
SizeFilter(List< FileSize > fileSizes)
StringJoiner joinStandardArtifactTypes()
List< Result > applyAlternateFilter(List< Result > currentResults, SleuthkitCase caseDb, CentralRepository centralRepoDb)
ScoreFilter(List< Score > scores)
final List< String > typeNames
final List< FileSize > fileSizes
List< Result > applyAlternateFilter(List< Result > currentResults, SleuthkitCase caseDb, CentralRepository centralRepoDb)
boolean useAlternateFilter()
final List< Frequency > frequencies
DataSourceFilter(List< DataSource > dataSources)
InterestingFileSetFilter(List< String > setNames)
FileTypeFilter(List< Type > categories)
static List< Result > getResultList(List< AbstractFilter > filters, String combinedQuery, SleuthkitCase caseDb, CentralRepository centralRepoDb)
final List< String > setNames
static final int FILES_TYPE_ID
final List< Type > categories