YARA: XOR Strings

Published: 2018-10-06
Last Updated: 2018-10-07 17:57:58 UTC
by Didier Stevens (Version: 1)
6 comment(s)

I did not notice this in August when YARA 3.8.0 was released, but a new string search feature was introduced: XOR searching.

Here is an example:

    rule xor_test {
        strings:
            $a = "http://isc.sans.edu" xor
        condition:
            $a
    }

By using string keyword "xor" with a string, the YARA engine will search for all byte sequences that match any 1-byte key XOR-encoded versions of this string (except for "key" 0x00).

In this example, file test-xor.txt contains a URL encoded with XOR key 0x41 (A).

With option -s, the encoded string is displayed:

String modifier "xor" can be used together with string modifiers "ascii", "wide" and "nocase".

It can not be used with regular expressions, although no error or warning is displayed:

    rule xor_test_re {
        strings:
            $a = /http:\/\/[a-z]+\.com/ xor
        condition:
            $a
    }

It does work if the regular expression is literal:

    rule xor_test_re {
        strings:
            $a = /http:\/\/didierstevens\.com/ xor
        condition:
            $a
    }

But I don't see the use case for this.

 

Didier Stevens
Senior handler
Microsoft MVP
blog.DidierStevens.com DidierStevensLabs.com

Keywords: XOR YARA
6 comment(s)

Comments

Hello,
I guess something like this might be usefull:

rule xor_dll_injection_imports : feature obfuscation
{
meta:
author = "Michal Ambroz"
description = "Detects API used for DLL injection obfuscated by single-byte xor"

strings:
$api_01 = "OpenProcess" xor
$api_02 = "GetProcessAddress" xor
$api_03 = "VirtualAllocEx" xor
$api_04 = "WriteProcessMemory" xor
$api_05 = "GetModuleHandleA" xor
$api_06 = "LoadLibraryA" xor
$api_07 = "CreateRemoteThread" xor
$api_08 = "VirtualProtect" xor
$api_09 = "advapi32.dll" xor

condition:
//Contains all of the strings
any of them
}
Thank you Didier - I havn't noticed this functionality so far.

It is just pity that the --print-strings displays only the match and not the original string.
For example:

$ cat win_obfuscated_calls.yara
rule xor_dll_injection_imports : feature obfuscation
{
meta:
author = "Michal Ambroz"
description = "Detects API used for DLL injection obfuscated by single-byte xor"

strings:
$api_01 = "OpenProcess" xor
$api_02 = "GetProcessAddress" xor
$api_03 = "VirtualAllocEx" xor
$api_04 = "WriteProcessMemory" xor
$api_05 = "GetModuleHandleA" xor
$api_06 = "LoadLibraryA" xor
$api_07 = "CreateRemoteThread" xor
$api_08 = "VirtualProtect" xor
$api_09 = "advapi32.dll" xor

condition:
//Contains any of the strings
any of them
}

$ yara -s win_obfuscated_calls.yara 8ac1a9d4a9b6f0fc23d481e0db29de18bf596071418611c52a0bd0942103776a
0x2bc34:$api_08: Lshno{vJhun\x7Fyn
0x2bd80:$api_08: Lshno{vJhun\x7Fyn
0x2c414:$api_08: Lshno{vJhun\x7Fyn
0x2c5e8:$api_08: Lshno{vJhun\x7Fyn

So as a practical hint - it is usefull to name the strings in yara with something meaningfull:
$ cat win_obfuscated_calls.yara
rule xor_dll_injection_imports : feature obfuscation
{
meta:
author = "Michal Ambroz"
description = "Detects API used for DLL injection obfuscated by single-byte xor"

strings:
$api_OpenProcess = "OpenProcess" xor
$api_GetProcessAddress = "GetProcessAddress" xor
$api_VirtualAllocEx = "VirtualAllocEx" xor
$api_WriteProcessMemory = "WriteProcessMemory" xor
$api_GerModuleHandleA = "GetModuleHandleA" xor
$api_LoadLibraryA = "LoadLibraryA" xor
$api_CreateRemoteThread = "CreateRemoteThread" xor
$api_VirtualProtect = "VirtualProtect" xor
$dll_advapi32_dll = "advapi32.dll" xor

condition:
//Contains any of the strings
any of them
}

$ yara -s win_obfuscated_calls.yara 8ac1a9d4a9b6f0fc23d481e0db29de18bf596071418611c52a0bd0942103776a
xor_dll_injection_imports 8ac1a9d4a9b6f0fc23d481e0db29de18bf596071418611c52a0bd0942103776a
0x2bc34:$api_VirtualProtect: Lshno{vJhun\x7Fyn
0x2bd80:$api_VirtualProtect: Lshno{vJhun\x7Fyn
0x2c414:$api_VirtualProtect: Lshno{vJhun\x7Fyn
0x2c5e8:$api_VirtualProtect: Lshno{vJhun\x7Fyn

Michal Ambroz
So you know of any speed baseline tests done against this option?
Minor point: there is a missing "+" in the first regular-expression example. After adding the "+", I was able to duplicate everything. I went to <https://yara.readthedocs.io/en/v3.8.1/writingrules.html>, and it didn't seem to mention xor not working with non-literal regular expressions. I am guessing a regular expression that can be treated as a string works as a string, so xor would work then. I think the documentation should clarify the intent.
No. And in general, I don't know of any public, extensive performance tests.
I've tried to do this before, and a lot of parameters have an impact. I'll try to summarize it in a diary entry.
Thanks for pointing out to typo robv, I fixed it.

The YARA documentation only mentions string modifier xor for strings, not for regular expressions.
Hence I expected an error message when I would use it with a regex, but that is not the case.

Diary Archives