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

Excluding matches with regex #1452

Closed
eth0izzle opened this issue Feb 21, 2021 · 4 comments
Closed

Excluding matches with regex #1452

eth0izzle opened this issue Feb 21, 2021 · 4 comments

Comments

@eth0izzle
Copy link

I'm trying to NOT match a rule if it contains a particular string. I know the regexp engine doesn't support negative lookaheads so we have to get creative. I came across #584 but I can't see to get it to work.

rule username_password_uri : authentication
{
    strings:
        $match = /([\w+]{1,24})(:\/\/)([^$][^\s";\/\/]{1,}):([^$][^\s";]{1,})@[-a-zA-Z0-9@:%._\+~#=]{1,256}[a-zA-Z0-9()]{1,24}([^\s"]+)/ fullword
        $not = /([\w+]{1,24})(:\/\/)(username|user|test):(password|pass|test)@[-a-zA-Z0-9@:%._\+~#=]{1,256}[a-zA-Z0-9()]{1,24}([^\s"]+)/ fullword

    condition:
        for any i in (1..#match) : ( @match[i] != @not[i] )
}

Given

https://shouldmatch:[email protected]
https://username:[email protected]

I would expect $match to match both of those lines, which it does. But $not does NOT match the 2nd line so the rule shouldn't include it. Any ideas?

@merces
Copy link
Contributor

merces commented Feb 21, 2021

I'd create a private rule and negate it in the main rule this way:

private rule default_field_names {
    strings:
        $field_names = /([\w+]{1,24})(:\/\/)(username|user|test):(password|pass|test)@[-a-zA-Z0-9@:%._\+~#=]{1,256}[a-zA-Z0-9()]{1,24}([^\s"]+)/ fullword
    condition:
        $field_names
}

rule username_password_uri : authentication {
    strings:
        $match = /([\w+]{1,24})(:\/\/)([^$][^\s";\/\/]{1,}):([^$][^\s";]{1,})@[-a-zA-Z0-9@:%._\+~#=]{1,256}[a-zA-Z0-9()]{1,24}([^\s"]+)/ fullword
    condition:
        $match and not default_field_names
}

Since it's a private rule, it can only be referenced by other rules. This way maybe you could also reduce the complexity of field_names. Perhaps something like $field_names = /(username|user|test):(password|pass|test)/ is enough.

@eth0izzle
Copy link
Author

eth0izzle commented Feb 21, 2021

Thanks @merces. I couldn't get that to work either. Turns out my example rule was sort-of correct but it's matching on the whole file, not on each match instance. So username_password_uri will match correctly on https://shouldmatch:[email protected] but default_field_names will also match on https://username:[email protected], canceling each other out and not returning a match.

I want to do:

condition
    $match and not $match matches /(username|user|test):(password|pass|test)/

but that doesn't look possible. Any ideas?

@eth0izzle
Copy link
Author

I used a meta tag in the end that contains a list of patterns that it SHOULDN'T match against and filtered them out in code after yara returns its matches.

@wxsBSD
Copy link
Collaborator

wxsBSD commented Feb 27, 2021

I know you closed this but $match and not $not should work just fine here.

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

3 participants