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);
772 List<Result> filteredResults =
new ArrayList<>();
773 for (
Result file : currentResults) {
775 filteredResults.add(file);
778 return filteredResults;
782 "SearchFiltering.PreviouslyNotableFilter.desc=Previously marked as notable in central repository"
786 return Bundle.SearchFiltering_PreviouslyNotableFilter_desc();
812 String queryStr =
"(obj_id IN (SELECT obj_id from blackboard_artifacts WHERE artifact_id IN "
813 +
"(SELECT artifact_id FROM blackboard_attributes WHERE artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()
814 +
" AND attribute_type_ID = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() +
" "
815 +
"AND (" + hashSetPart +
"))))";
822 "FileSearchFiltering.HashSetFilter.desc=Hash set hits in set(s): {0}",})
850 String queryStr =
"(obj_id IN (SELECT obj_id from blackboard_artifacts WHERE artifact_id IN "
851 +
"(SELECT artifact_id FROM blackboard_attributes WHERE artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID()
852 +
" AND attribute_type_ID = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() +
" "
853 +
"AND (" + intItemSetPart +
"))))";
860 "SearchFiltering.InterestingItemSetFilter.desc=Interesting item hits in set(s): {0}",})
888 String queryStr =
"(obj_id IN (SELECT obj_id from blackboard_artifacts WHERE artifact_id IN "
889 +
"(SELECT artifact_id FROM blackboard_attributes WHERE artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_OBJECT_DETECTED.getTypeID()
890 +
" AND attribute_type_ID = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION.getTypeID() +
" "
891 +
"AND (" + objTypePart +
"))))";
898 "SearchFiltering.ObjectDetectionFilter.desc=Objects detected in set(s): {0}",})
928 String hashsetQueryPart =
"";
929 String tagQueryPart =
"";
930 String intItemQueryPart =
"";
934 hashsetQueryPart =
" (known = " + TskData.FileKnown.BAD.getFileKnownValue() +
") ";
939 intItemQueryPart =
" (obj_id IN (SELECT obj_id from blackboard_artifacts WHERE artifact_type_id = "
940 + BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID() +
")) ";
945 tagQueryPart =
"(obj_id IN (SELECT obj_id FROM content_tags))";
948 tagQueryPart =
"(obj_id IN (SELECT obj_id FROM content_tags WHERE tag_name_id IN (SELECT tag_name_id FROM tag_names WHERE knownStatus = "
949 + TskData.FileKnown.BAD.getFileKnownValue() +
")))";
952 tagQueryPart =
"(obj_id IN (SELECT obj_id FROM content_tags WHERE tag_name_id IN (SELECT tag_name_id FROM tag_names WHERE knownStatus != "
953 + TskData.FileKnown.BAD.getFileKnownValue() +
")))";
956 String queryStr = hashsetQueryPart;
957 if (!intItemQueryPart.isEmpty()) {
958 if (!queryStr.isEmpty()) {
961 queryStr += intItemQueryPart;
963 if (!tagQueryPart.isEmpty()) {
964 if (!queryStr.isEmpty()) {
967 queryStr += tagQueryPart;
974 "SearchFiltering.ScoreFilter.desc=Score(s) of : {0}",})
977 return Bundle.SearchFiltering_ScoreFilter_desc(
1002 for (TagName tagName : tagNames) {
1003 if (!tagIDs.isEmpty()) {
1006 tagIDs += tagName.getId();
1009 String queryStr =
"(obj_id IN (SELECT obj_id FROM content_tags WHERE tag_name_id IN (" + tagIDs +
")))";
1014 @NbBundle.Messages({
1015 "# {0} - tag names",
1016 "FileSearchFiltering.TagsFilter.desc=Tagged {0}",
1017 "FileSearchFiltering.TagsFilter.or=, ",})
1021 for (TagName name : tagNames) {
1022 if (!desc.isEmpty()) {
1023 desc += Bundle.FileSearchFiltering_TagsFilter_or();
1025 desc += name.getDisplayName();
1027 return Bundle.FileSearchFiltering_TagsFilter_desc(desc);
1039 return "(obj_id IN (SELECT obj_id from blackboard_artifacts WHERE artifact_id IN "
1040 +
"(SELECT artifact_id FROM blackboard_attributes WHERE artifact_type_id = "
1041 + BlackboardArtifact.ARTIFACT_TYPE.TSK_USER_CONTENT_SUSPECTED.getTypeID() +
")))";
1044 @NbBundle.Messages({
1045 "FileSearchFiltering.UserCreatedFilter.desc=that contain EXIF data",})
1048 return Bundle.FileSearchFiltering_UserCreatedFilter_desc();
1074 if (centralRepoDb == null) {
1075 throw new DiscoveryException(
"Can not run Previously Notable filter with null Central Repository DB");
1080 if (currentResults.isEmpty()) {
1085 List<Result> notableResults =
new ArrayList<>();
1090 for (
Result result : currentResults) {
1099 notableResults.add(result);
1103 return notableResults;
1109 @NbBundle.Messages({
1110 "FileSearchFiltering.PreviouslyNotableFilter.desc=that were previously marked as notable",})
1113 return Bundle.FileSearchFiltering_PreviouslyNotableFilter_desc();
1124 return "known!=" + TskData.FileKnown.KNOWN.getFileKnownValue();
1127 @NbBundle.Messages({
1128 "FileSearchFiltering.KnownFilter.desc=which are not known"})
1131 return Bundle.FileSearchFiltering_KnownFilter_desc();
1142 @NbBundle.Messages({
1143 "FileSearchFiltering.concatenateSetNamesForDisplay.comma=, ",})
1146 for (String setName : setNames) {
1147 if (!desc.isEmpty()) {
1148 desc += Bundle.FileSearchFiltering_concatenateSetNamesForDisplay_comma();
1165 for (String setName : setNames) {
1166 if (!result.isEmpty()) {
1169 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