Search code examples
yara

YARA: Match string without a specific substring


I'm trying to create a YARA rule which matches a URL plus one arbitrary directory, while excluding a specific directory. For example, it needs to match any of these:

https://example.com/foo
https://example.com/bar
https://example.com/eggs
https://example.com/eggsAndHam
https://example.com/greenEggs
https://example.com/anythingatall

But specifically not this:

https://example.com/baz

To complicate things, the file must match if it contains a URL with an arbitrary directory in addition to the exuded URL. So a file that contained the following would match:

https://example.com/ougsrhoiujrnae
https://example.com/baz

As would the following:

https://example.com/biuhOIUYui

But not the following by itself:

https://example.com/baz

This would be trivial if YARA supported negative lookaheads like https:\/\/example\.com\/(?!baz), but it does not. Is there a way to accomplish this in YARA?


Solution

  • One way to accomplish this if you know the length of the first part of the string is:

    1. select the strings with a regular expression
    2. loop through the returned offsets
    3. for each offset, add the length of the known part of the string
    4. check if the offset + known string length is followed by the string we want to exclude, and exclude it if so

    For the above example, we know that https://example.com is 19 bytes long, and we can exclude the match if it is followed by the string /bar:

    rule url_not_ending_in_bar
    {
        strings:
            $url = /https:\/\/example\.com\/\w*/
            $exclude = "/bar"
    
        condition:
            for any i in (1..#url): (
                not $exclude at @url[i] + 19
            )
    }