Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not Equals (!=) Expressions #301

Merged

Conversation

slincoln-aiq
Copy link
Contributor

This PR introduces using "not equals" expressions, such as !=, over the not_token for the convert_condition_field_eq_val() method and all the convert_condition_field_eq_val_*() methods.

This is done by using a context manager inside convert_condition_field_eq_val() . The convert_condition_field_eq_val() method will first check if:

  1. The current condition has a parent, grandparent, ...etc ConditionNOT
  2. The convert_not_as_not_eq class flag is True

The resulting bool value is passed to the context manager as the use_negated_expressions arg, the the method carries on like normal. If use_negated_expressions is True, the following expressions will be temporarily swapped with their 'not equals' counterpart while converting the condition using the convert_condition_field_eq_val_*() methods, then swapped back after the conversion is complete:

self.eq_expression = self.not_eq_expression
self.re_expression = self.not_re_expression
self.cidr_expression = self.not_cidr_expression
self.startswith_expression = self.not_startswith_expression
self.case_sensitive_startswith_expression = self.case_sensitive_not_startswith_expression
self.endswith_expression = self.not_endswith_expression
self.case_sensitive_endswith_expression = self.case_sensitive_not_endswith_expression
self.contains_expression = self.not_contains_expression
self.case_sensitive_contains_expression = self.case_sensitive_not_contains_expression

I have also added tests for this new logic in the test_conversion_base file.

To use this functionality, the backend developer should set the not equals expressions listed above in their backend, and set convert_not_as_not_eq = True.

Here is an example of a passing test using the current logic with the not_token:

def test_convert_not(test_backend):
    assert (
        test_backend.convert(
            SigmaCollection.from_yaml(
                """
            title: Test
            status: test
            logsource:
                category: test_category
                product: test_product
            detection:
                sel:
                    fieldA: value1
                condition: not sel
        """
            )
        )
        == ['not mappedA="value1"']
    )

vs using the new not_eq logic:

def test_convert_not_as_not_eq(test_backend, monkeypatch):
   """Test that NOT conditions are converted using not_eq expressions when convert_not_as_not_eq is True"""
   monkeypatch.setattr(test_backend, "convert_not_as_not_eq", True)
   monkeypatch.setattr(test_backend, "not_eq_token", "!=")
   monkeypatch.setattr(test_backend, "not_eq_expression", "{field}{backend.not_eq_token}{value}")
   assert (
       test_backend.convert(
           SigmaCollection.from_yaml(
               """
           title: Test
           status: test
           logsource:
               category: test_category
               product: test_product
           detection:
               sel:
                   fieldA: value1
               condition: not sel
       """
           )
       )
       == ['mappedA!="value1"']
   )

@thomaspatzke thomaspatzke merged commit f5cb2bf into SigmaHQ:main Nov 10, 2024
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants