Fix regex search for serialized data column

This commit is contained in:
Matthew Kienow
2018-03-30 19:25:38 -04:00
parent 4c536a1819
commit cb2366d2eb
+21 -2
View File
@@ -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