diff --git a/lib/msf/core/db_manager/note.rb b/lib/msf/core/db_manager/note.rb index 0f60ccb707..6003b73374 100644 --- a/lib/msf/core/db_manager/note.rb +++ b/lib/msf/core/db_manager/note.rb @@ -31,8 +31,27 @@ module Msf::DBManager::Note search_term = opts.delete(:search_term) if search_term && !search_term.empty? - column_search_conditions = Msf::Util::DBManager.create_all_column_search_conditions(Mdm::Note, search_term) - wspace.notes.includes(:host).where(opts).where(column_search_conditions) + all_columns_except_data_expression = Msf::Util::DBManager.create_all_column_search_conditions(Mdm::Note, search_term, ["data"]) + + # The data column is serialized so an Arel regex-based search is created following + # somewhat from the Mdm search scope. If data appears to be serialized it is decoded for the regex match. + # The Mdm search scope used 'BAh7%' which doesn't appears to result in matches against simple string + # values that have been serialized, so this was changed to 'BAh%'. The decoded binary data is then + # converted to a text value to be used for the regex match. + serialized_prefix = 'BAh%' + re_search_term = "(?mi)#{search_term}" + arel_table = Mdm::Note.arel_table + regex_data = Arel::Nodes::Regexp.new(arel_table[:data], Arel::Nodes.build_quoted(re_search_term)) + data_no_base64_expression = arel_table.grouping(arel_table[:data].does_not_match(serialized_prefix).and(regex_data)) + + decode_func = Arel::Nodes::NamedFunction.new("decode", [arel_table[:data], Arel::Nodes.build_quoted('base64')]) + convert_from_func = Arel::Nodes::NamedFunction.new("convert_from", [decode_func, Arel::Nodes.build_quoted('UTF8')]) + regex_data_base64 = Arel::Nodes::Regexp.new(convert_from_func, Arel::Nodes.build_quoted(re_search_term)) + data_base64_expression = arel_table.grouping(arel_table[:data].matches(serialized_prefix).and(regex_data_base64)) + + data_column_expression = data_no_base64_expression.or(data_base64_expression) + column_search_expression = all_columns_except_data_expression.or(data_column_expression) + wspace.notes.includes(:host).where(opts).where(column_search_expression) else wspace.notes.includes(:host).where(opts) end