theflakes/sigma_to_wazuh

Issue with Or Translation with negate=Yes regex

Opened this issue · 8 comments

With Using the default Core sigma rule set there is an issue with the following rule when its translated:

Original Sigma rule:
https://github.com/SigmaHQ/sigma/blob/master/rules/windows/process_creation/proc_creation_win_hktl_relay_attacks_tools.yml

What I noticed:

  • The sigma rule is split into 4 seperate rules, and the logic of the script splits it at the 2nd indent if the sigma rule
  • The 4th rule (200531 referenced bellow) is a "known good" filter of hotpotato
  • When this is split into its own rule by the script, it creates a negate='yes' filter for the event
  • with a negate=yes regex being the only criteria for the rule, it will match every instance of the <if_sid> list creating many logs
<rule id="200521" level="15">
        <info type="link">https://github.com/SigmaHQ/sigma/tree/master/rules/windows/process_creation/proc_creation_win_hktl_relay_attacks_tools.yml</info>
        <!--Sigma Rule Author: Florian Roth (Nextron Systems)-->
        <!--Description: Detects different hacktools used for relay attacks on Windows for privilege escalation-->
        <!--Date: 2021/07/24-->
        <!--Status: test-->
        <!--ID: 5589ab4f-a767-433c-961d-c91f3f704db1-->
        <mitre>
            <id>attack.execution</id>
            <id>attack.t1557.001</id>
        </mitre>
        <description>Potential SMB Relay Attack Tool Execution</description>
        <options>no_full_log</options>
        <group>process_creation,windows,</group>
        <if_sid>18100, 60000, 60001, 60002, 60003, 60004, 60006, 60007, 60008, 60009, 60010, 60011, 60012</if_sid>
        <field name="win.eventdata.image" negate="yes" type="pcre2">(?i)HotPotatoes6</field>
        <field name="win.eventdata.image" negate="yes" type="pcre2">(?i)HotPotatoes7</field>
        <field name="win.eventdata.image" negate="yes" type="pcre2">(?i)(?:HotPotatoes\ )</field>
    </rule>

Potential resolutions:

  • create an exception for filters being their own rules
  • check if a created rule has only negate=yes and if it does, don't allow it

I'm not sure when I'll return to working on this unfortunately. I've moved to other solutions for rule writing. There are just too many logic limitations with OSSEC/Wazuh rules that I haven't time to push through right now.

Its complicated converting from a more expressive rule writing syntax to OSSEC/Wazuh. Where I ended up is trying to break Sigma rules down into passing sets, basically a tree structure that can be logically walked and create a Wazuh rule for each branch, but it isn't complete and you will see issues like what you ran into here.

totally understood.

I also just wanted some documentation of this issue in case someone runs into it in the future.

Thanks for doing a lot of the original heavy lifting for this project though! Wazuh logic is really limiting unfortunately. They're working on updating it I hear, but its slow moving and probably not for another year.

I've seen some other people using chainsaw to process sigma logic locally on the device so there are other options out there.

I've moved to other solutions for rule writing.

@theflakes, сan you tell what you're using?

Still supporting legacy Wazuh rules but mostly in teaching labs.

Using Sigma in SecurityOnion playbooks.

Also using Elastalert and ELK alerts. No perfect solution that's open unfortunately. Wazuh still does the job but really wish it had OR logic between two statements in a rule.

I added a filter to filter out any "1 of" that also includes "and" logic. This removes ~ 460 Sigma rules from conversion.

This won't fix all of the logic translation problems, but it will reduce them a good bit.

If I could use DeMorgan's Law to move all OR logic rules to AND, I could more easily convert Sigma to Wazuh. But, Wazuh would need to support two levels of negation which it doesn't unfortunately.

@theflakes, What if you split all conditions into separate rules and сombine it at the end.

<rule level=1>
<if_sid>selection_pe|selection_script|selection_juicypotato_enum</if_sid>
 <field name="win.eventdata.image" negate="no" type="pcre2">(?i)HotPotatoes6</field>

<rule level=1>
<if_sid>selection_pe|selection_script|selection_juicypotato_enum</if_sid>
 <field name="win.eventdata.image" negate="no" type="pcre2">(?i)HotPotatoes7</field>

<rule level=1>
<if_sid>selection_pe|selection_script|selection_juicypotato_enum</if_sid>
 <field name="win.eventdata.image" negate="no" type="pcre2">(?i)HotPotatoes </field>

With level !=0 you can change levels of negation

I've implemented not propagation so that everything that is negated is explicitly so; e.g. not (selection and other) -> not selection and not other. This should remove some negation conversion errors.

The main issue is still ORs and 1_of's. Again, because of Wazuh limitations. i.e. need to create a rule per each new field that is ORed with other fields.

Have also filtered out cidr Sigma rules as converting this to Wazuh will need some thought.

@theflakes, What if you split all conditions into separate rules and сombine it at the end.

<rule level=1>
<if_sid>selection_pe|selection_script|selection_juicypotato_enum</if_sid>
 <field name="win.eventdata.image" negate="no" type="pcre2">(?i)HotPotatoes6</field>

<rule level=1>
<if_sid>selection_pe|selection_script|selection_juicypotato_enum</if_sid>
 <field name="win.eventdata.image" negate="no" type="pcre2">(?i)HotPotatoes7</field>

<rule level=1>
<if_sid>selection_pe|selection_script|selection_juicypotato_enum</if_sid>
 <field name="win.eventdata.image" negate="no" type="pcre2">(?i)HotPotatoes </field>

With level !=0 you can change levels of negation

I've thought about this but not enough. I think maybe two passes over each sigma rule. Just not sure and will require a good bit of rewrite.

  • Maybe, first pass, just create all Wazuh field logic entries and cache them.
  • Second pass, build the Wazuh rule(s).