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

Suggestion. #114

Closed
DpoBoceka opened this issue Jul 17, 2018 · 6 comments
Closed

Suggestion. #114

DpoBoceka opened this issue Jul 17, 2018 · 6 comments

Comments

@DpoBoceka
Copy link

DpoBoceka commented Jul 17, 2018

During the usage of sigma-language I got stuck describing cases when there is "NOT" and ("TRUE" and "TRUE") logic. I thought of suggested way of handling them as more like a workaround so I tried to add more readability to it. Also, the rules which are "united" by the common attack technique, but devided by different logsources of events, are tricky to combine into one rule. So, the main downsides of current realisation, as I see it, are:

  1. Not obvious implementation of "NOT" directive.
  2. The concept of putting "logsource" field on top of the rule isn't quite flexible - the events provided by various logs sources can't live "under the same roof".
  3. Hard to filter the cases, when few fildes have to contain specific values simultaneously(!) and only then they are to be false positives.
    Here's the example which describes abusing bitstransfer technique:
title: BITS Jobs
description: 
    general: Detects usage of bitsadmin downloading a file
    mitre:
        id: T1197
        tactic:
          - Defense Evasion
          - Persistence  

detection:
    selection1:
        Logsource: 'Microsoft-Windows-Sysmon/Operational'
        EventID: 1
        Image: '*\bitsadmin.exe'

    selection2:
        Logsource: 'Microsoft-Windows-Bits-Client/Operational'
        EventID:
          - 3      
          - 59
          - 60
    
    selection3:
        Logsource: 'System'
        EventID: 7040
        Service: 'Background Intelligent Transfer Service'

    condition: 1 of selection*

level: medium

Presumably, the engineer who'd be analysing it shouldn't experience inconvenience - the rule is brief and readable. I don't see why we should devide it into pieces given the fact that each part is telling the same thing. Regarding the discomfort with current "not" in the condition filed:

title: 
description: 
    general: Running code in the context of another process may allow access to the process's memory, system/network resources, and possibly elevated privileges
    mitre:
        id: T1055 
        tactic:
          - Defense Evasion
          - Privilege Escalation

detection:
    selection1:
        Logsource: 'Microsoft-Windows-Sysmon/Operational'
        EventID: 8
        SourceImage: 
          - NOT '*\VBoxTray.exe'
        TargetImage: 
          - NOT '*\csrss.exe'
       #(StartFunction: NOT 'EtwpNotificationThread' AND SourceImage: NOT '*\\rundll32.exe')
    
    condition: 1 of selection*

level: medium

Here's when the problem pops up - I don't know how to describe the last line in the selection1 yet. Of course, we already can solve it in directive "condition", but what if we have a dozen selections, then my "condition" would be bulky.
Can we consider some of my thoughts? The appearance of sigma-rules would be more simplistic, I believe.

@thomaspatzke
Copy link
Member

Hi! Thank you for the feedback! Here some answers:

Also, the rules which are "united" by the common attack technique, but devided by different logsources of events, are tricky to combine into one rule.

You can combine multiple rules in one file with rule collections. In collection you can also define common rule parts with the action attribute set to global, which are automatically incorporated into following rules. We already used this in various rules, e.g. this one.

This also solves the following problem:

The concept of putting "logsource" field on top of the rule isn't quite flexible - the events provided by various logs sources can't live "under the same roof".

Factually, the original intention of collection was this problem.

Presumably, the engineer who'd be analysing it shouldn't experience inconvenience - the rule is brief and readable. I don't see why we should devide it into pieces given the fact that each part is telling the same thing.

I don't know exactly what you mean here. The rule should work fine.

Here's when the problem pops up - I don't know how to describe the last line in the selection1 yet. Of course, we already can solve it in directive "condition", but what if we have a dozen selections, then my "condition" would be bulky.

The problem with the proposed NOT syntax in the value definitions is the missing separation of condition and values, which has some advantages:

  • It fits better into the YAML standard. The NOT tokens inside the values would be part of the string, require some special handling.
  • Currently values aren't parsed, but used as defined. Further need for parsing other parts of the rule would increase complexity.
  • Users would have to look at different parts of the rule to determine the final condition.

The example you named could be solved by:

...
detection:
    selection1:
        Logsource: 'Microsoft-Windows-Sysmon/Operational'
        EventID: 8
    filter:
        SourceImage: 
          - NOT '*\VBoxTray.exe'
        TargetImage: 
          - NOT '*\csrss.exe'
       #(StartFunction: NOT 'EtwpNotificationThread' AND SourceImage: NOT '*\\rundll32.exe')
    
    condition: selection and not filter
...

Even if the filters would be separated in multiple definitions, the condition could be written in the following way: 1 of selection* and not all of filter*

@DpoBoceka
Copy link
Author

DpoBoceka commented Jul 18, 2018

Hi! Thank you for help.

Even if the filters would be separated in multiple definitions, the condition could be written in the following way: 1 of selection* and not all of filter*

But I don't want my filters to be applied to ALL selections of the rule. If I have, say, 10 selections and 10 filters, which are independent from each other, I should place:

condition: (selection1 and not filter1) or (selection2 and not filter2) or ... etc..

In collection you can also define common rule parts with the action attribute set to global, which are automatically incorporated into following rules.

So, in a nutshell, all that it does is moving 'condition' on top of the rule. How is that helpful? And the strings about logsources are still duplicated, why wouldn't we use just one simple line in lieu of 3? The logsource filed is to be parsed and inserted into SIEM search all the same..

`logsource:`
    product: windows
    service: security

`logsource:` 'Security'

It fits better into the YAML standard. The NOT tokens inside the values would be part of the string, require some special handling.

I agree here, but I just said that it is preferable for viewers to attach "NOT' right to the filed_name than condition (which can be in every part of the rule, as you showed me, so one should locate it first and scroll back every time one look the rule futher through)

@DpoBoceka
Copy link
Author

and also, if I use Filter section I have to describe the logsource fields again. Every time. It costs me 3 lines. If I'd have 10 selections and 10 filters I'd waste 60(!) lines for copy-pasting. If we switch to my way - there will be just 10 selections with filters in them and there will be only 10 lines about logsource.
Isn't that KISS?

@thomaspatzke
Copy link
Member

But I don't want my filters to be applied to ALL selections of the rule. If I have, say, 10 selections and 10 filters, which are independent from each other, I should place:
condition: (selection1 and not filter1) or (selection2 and not filter2) or ... etc..

Ah, I understand! Yes, that is really some work to type in, but on the other side it precisely describes the logic and we keep the separation between values and the logic expression. I think about a possible shortcut for such constructs inside of the condition. Some kind of loop could be a solution. On the other side we try to keep Sigma as simple as possible (also for developers of tools) and especially don't add solutions for issues that appear only for a minority of rules.

So, in a nutshell, all that it does is moving 'condition' on top of the rule.

Not only, the log source definition is inherited by the rules following the global definition.

How is that helpful? And the strings about logsources are still duplicated

The matching of the Logsource field in the rule is not intended and necessary. For this purpose, log source definitions should be used. With log source definitions you can define indices and conditions in a separate environment-specific configuration file. This is necessary to be able to write Sigma rules independent from SIEM-specific circumstances.

Indeed, different rules from different log sources have to be written in separate Sigma rules inside a collection. But this is only minor additional type work with usage of global definitions.

I agree here, but I just said that it is preferable for viewers to attach "NOT' right to the filed_name than condition (which can be in every part of the rule, as you showed me, so one should locate it first and scroll back every time one look the rule futher through)

In the public rule repository the definition name prefix filter is used to indicate filtering (example). This is quite obvious, at least after the reader has seen the condition and works with existing constructs without adding further complexity to the language.

@DpoBoceka
Copy link
Author

On the other side we try to keep Sigma as simple as possible (also for developers of tools) and especially don't add solutions for issues that appear only for a minority of rules.

From my point of view that adds some difficulties aswell - the parsing tool has to be taught the logic about handling such global directives - how fields should be inherited, when it might be overwritten etc. It has to know about all theese global features and be able to adapt to appended ones, cause the more we use sigma the more features we might be in need with later.
On the other hand, if we add in just ability to understand lines like:
Field_name: ! 'some_data_to_be_filtered'
we'd save up some time.

This is quite obvious, at least after the reader has seen the condition and works with existing constructs without adding further complexity to the language.

What if my condition, unlike the one you mentioned, isn't described as a "looped function", what if it has complex logic with no repeat. So the reader would be forced to look at that condition again and again, because it is tricky to remember by heart.
We shouldn't consider such cases as flaws of 'minority', now, should we?

@thomaspatzke
Copy link
Member

From my point of view that adds some difficulties aswell - the parsing tool has to be taught the logic about handling such global directives

Definitely! This was an extension vs redundancy decision. Without this mechanism many rules would have to be duplicated. So we added it, despite of the increased complexity.

We shouldn't consider such cases as flaws of 'minority', now, should we?

So, we have currently 198 rule files in this repository, only two of them have such lenghty search/filter condition. This is a minority. Furthermore, I have talked with few Sigma users in the recent time and no one mentioned such issues. I think I will ask explicitely for this in the next time. If this is a systematical problem an extension would make sense.

By the way, we recently removed some kind of similar feature (not null values) for exactly the same reasons. Allowing not operators in values would add some further issues that have to be considered:

  • How to handle strings that begin with the literal string not?
  • How to handle quoting of strings? YAML has different semantics for different quotes or if none are given at all.

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

No branches or pull requests

2 participants