grafana/pySigma-backend-loki

Certain modifiers raise exceptions

Closed this issue · 1 comments

Given the following Sigma rule, the Loki backend raises an exception. The problem is on the |gte modifier, which we didn't have a proper test for either. Note that removing the modifier will produce a correct query and other backends produce correct queries. Other modifiers like lt, lte and gt also raise errors.

title: title
description: description
author: author
date: 2024/05/21
tags:
  - attack.initial_access
logsource:
  product: aws
  service: cloudtrail
detection:
  selection:
    fieldA: value_a
    fieldB|gte: 0.8
  keywords:
    - "Something something happened"
  condition: selection and keywords
level: high
Raised exception
$ sigma convert -t loki --without-pipeline -s test.yaml
Parsing Sigma rules  [####################################]  100%
Traceback (most recent call last):
  File "/somewhere/.pyenv/versions/3.12.3/bin/sigma", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/somewhere/.pyenv/versions/3.12.3/lib/python3.12/site-packages/sigma/cli/main.py", line 76, in main
    cli()
  File "/somewhere/.pyenv/versions/3.12.3/lib/python3.12/site-packages/click/core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/somewhere/.pyenv/versions/3.12.3/lib/python3.12/site-packages/click/core.py", line 1078, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "/somewhere/.pyenv/versions/3.12.3/lib/python3.12/site-packages/click/core.py", line 1688, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/somewhere/.pyenv/versions/3.12.3/lib/python3.12/site-packages/click/core.py", line 1434, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/somewhere/.pyenv/versions/3.12.3/lib/python3.12/site-packages/click/core.py", line 783, in invoke
    return __callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/somewhere/.pyenv/versions/3.12.3/lib/python3.12/site-packages/sigma/cli/convert.py", line 281, in convert
    result = backend.convert(rule_collection, format, correlation_method)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/somewhere/.pyenv/versions/3.12.3/lib/python3.12/site-packages/sigma/conversion/base.py", line 168, in convert
    self.convert_rule(rule, output_format or self.default_format)
  File "/somewhere/.pyenv/versions/3.12.3/lib/python3.12/site-packages/sigma/backends/loki/loki.py", line 744, in convert_rule
    (index, self.convert_condition(cond, states[index]))  # type: ignore[arg-type]
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/somewhere/.pyenv/versions/3.12.3/lib/python3.12/site-packages/sigma/conversion/base.py", line 515, in convert_condition
    return self.convert_condition_and(cond, state)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/somewhere/.pyenv/versions/3.12.3/lib/python3.12/site-packages/sigma/backends/loki/loki.py", line 896, in convert_condition_and
    return joiner.join(
           ^^^^^^^^^^^^
  File "/somewhere/.pyenv/versions/3.12.3/lib/python3.12/site-packages/sigma/backends/loki/loki.py", line 897, in <genexpr>
    (
  File "/somewhere/.pyenv/versions/3.12.3/lib/python3.12/site-packages/sigma/backends/loki/loki.py", line 900, in <genexpr>
    self.convert_condition(arg, state)  # type: ignore
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/somewhere/.pyenv/versions/3.12.3/lib/python3.12/site-packages/sigma/conversion/base.py", line 515, in convert_condition
    return self.convert_condition_and(cond, state)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/somewhere/.pyenv/versions/3.12.3/lib/python3.12/site-packages/sigma/backends/loki/loki.py", line 896, in convert_condition_and
    return joiner.join(
           ^^^^^^^^^^^^
  File "/somewhere/.pyenv/versions/3.12.3/lib/python3.12/site-packages/sigma/backends/loki/loki.py", line 897, in <genexpr>
    (
  File "/somewhere/.pyenv/versions/3.12.3/lib/python3.12/site-packages/sigma/backends/loki/loki.py", line 900, in <genexpr>
    self.convert_condition(arg, state)  # type: ignore
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/somewhere/.pyenv/versions/3.12.3/lib/python3.12/site-packages/sigma/conversion/base.py", line 519, in convert_condition
    return self.convert_condition_field_eq_val(cond, state)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/somewhere/.pyenv/versions/3.12.3/lib/python3.12/site-packages/sigma/backends/loki/loki.py", line 953, in convert_condition_field_eq_val
    return super().convert_condition_field_eq_val(cond, state)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/somewhere/.pyenv/versions/3.12.3/lib/python3.12/site-packages/sigma/conversion/base.py", line 431, in convert_condition_field_eq_val
    return self.convert_condition_field_compare_op_val(cond, state)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/somewhere/.pyenv/versions/3.12.3/lib/python3.12/site-packages/sigma/conversion/base.py", line 1474, in convert_condition_field_compare_op_val
    return self.compare_op_expression.format(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'format' (while converting rule ./test.yaml)

Looks like the compare_op_expression on the backend isn't being set correctly - it should be {field}{operator}{value} (regardless of whether it is negated or not).

Rather than adding a test for each modifier, I think this would also be a good opportunity to write a unit test that automatically enumerates all the modifiers (using this mapping) and check which ones we expect to work aren't (or, if we know we don't support them, that an appropriate error is being raised - unlike this AttributeError).