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

Can you manipulate A Rule's condition when represented as an AST #69

Open
hop-along-polly opened this issue May 12, 2023 · 2 comments
Open

Comments

@hop-along-polly
Copy link

After parsing a Yara Ruleset into a ast.RuleSet is there a way to manipulate a rule's condition?

Take this sample ruleset

rule rule_1 {
    strings:
        $header_v2 = {50 02}
        $header_v3 = {50 03}
        $header_v4 = {50 04}
        $header_v5 = {50 05}

    condition: (
        for any of them: ($ at 0)
    )
}

rule rule_2 {
    strings:
        $pattern_v4_4 = {8c 05 65 23 61 6c [0-32] 90}
        $pattern_v4_5 = {8c 06 65 52 65 63 [0-32] 90}

    condition:
        any of them
}

I would like to make rule_2's condition rule_1 and any of them however I can't find an ast.Condition or any similar struct to do this. Here is the code I have so far for getting the rules condition. Now that I have it is there a way to modify it?

r2 := r.Rules[1]
for _, cond := range r2.Condition.Children() {
    fmt.Println("Condition", cond)
}
@gazunder
Copy link
Contributor

Hey @hop-along-polly

You can create a new condition and replace the old one. Here is how to do it:

First, create a new condition. This code snippet creates an ast.Operation which represents the logical AND of rule_1 and any of them:

c := &ast.Operation{
    Operator: ast.OpAnd,
    Operands: []ast.Expression{
        &ast.Identifier{Identifier: "rule_1"},
        &ast.Of{
            Quantifier: ast.KeywordAny,
            Strings:    ast.KeywordThem,
        },
    },
}

This ast.Operation is the equivalent of the YARA expression rule_1 and any of them.

Once you have created this new condition, you can replace the existing condition in the rule. Assuming that the rule you want to modify is the second one in your ruleset (indexed at 1 in the slice), you can do:

rs.Rules[1].Condition = c

This will replace the condition of the second rule with your new condition. If we write the source of the ruleset we will get:

rule rule_1 {
  strings:
    $header_v2 = { 50 02 }
    $header_v3 = { 50 03 }
    $header_v4 = { 50 04 }
    $header_v5 = { 50 05 }
  condition:
    (for any of them : ($ at 0))
}

rule rule_2 {
  strings:
    $pattern_v4_4 = { 8C 05 65 23 61 6C [0-32] 90 }
    $pattern_v4_5 = { 8C 06 65 52 65 63 [0-32] 90 }
  condition:
    rule_1 and any of them
}

Additionally you could just modify the condition in place instead of replacing it. Please let me know if you need any further clarification.

@hop-along-polly
Copy link
Author

I have a similar question for overwriting a Rules string values. It seems you can't use an ast.TextString as an ast.String value. Is it similar to conditions where I need to use smaller abstractions to build up to the correct implementation of the ast.String interface?

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