├── LICENSE.md ├── README.md ├── malcat ├── README.md ├── obfuscators.yar └── other.yar ├── tutorials └── snippts_and_tricks.md └── yara ├── dotnet ├── anomalies.yar ├── framework_identiciation.yar ├── mal │ ├── mal_net_limecrypter_runpe.yar │ └── mal_net_niximports_loader.yar ├── obf_confuserex.yar ├── obf_eazfuscator.yar ├── obf_net_reactor.yar └── suspicious_indicators.yar ├── other ├── susp_direct_syscall_shellcode_invocation.yar ├── susp_obf_pyarmor.yar └── susp_rlo_exe_extension_spoofing.yar └── thor └── vcruntime140_sideloading.yar /LICENSE.md: -------------------------------------------------------------------------------- 1 | ## Detection Rule License (DRL) 1.1 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this rule set and associated documentation files (the "Rules"), to deal 5 | in the Rules without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Rules, and to permit persons to whom the Rules are furnished to do so, 8 | subject to the following conditions: 9 | 10 | If you share the Rules (including in modified form), you must retain the 11 | following if it is supplied within the Rules: 12 | 13 | 1. identification of the authors(s) ("author" field) of the Rule and any 14 | others designated to receive attribution, in any reasonable manner 15 | requested by the Rule author (including by pseudonym if designated). 16 | 17 | 2. a URI or hyperlink to the Rule set or explicit Rule to the extent 18 | reasonably practicable 19 | 20 | 3. indicate the Rules are licensed under this Detection Rule License, and 21 | include the text of, or the URI or hyperlink to, this Detection Rule 22 | License to the extent reasonably practicable 23 | 24 | If you use the Rules (including in modified form) on data, messages based on 25 | matches with the Rules must retain the following if it is supplied within the 26 | Rules: 27 | 28 | 1. identification of the authors(s) ("author" field) of the Rule and any 29 | others designated to receive attribution, in any reasonable manner 30 | requested by the Rule author (including by pseudonym if designated). 31 | 32 | THE RULES ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 33 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 34 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 35 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 36 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 37 | OUT OF OR IN CONNECTION WITH THE RULES OR THE USE OR OTHER DEALINGS IN THE 38 | RULES. 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # detection rules 2 | 3 | This repository contains my detection rules for all kinds of malware and suspicious software. 4 | I mainly work with Yara. 5 | 6 | 7 | -------------------------------------------------------------------------------- /malcat/README.md: -------------------------------------------------------------------------------- 1 | # Malcat specific rules 2 | 3 | These rules are specifically formatted for the Malware Triage tool [Malcat](https://malcat.fr/) 4 | 5 | ## How to use 6 | 7 | 1. Go to your Malcat install folder and then navigate to `...\data\signatures` 8 | 2. Create a new folder I will name it `custom` 9 | 3. Copy the .yar files from this repository into your folder 10 | 4. In the `signatures` folder create a new .yar file (same name as your folder) 11 | 5. Copy the following code into that .yar file 12 | 13 | ``` 14 | include 'custom/obfuscators.yar' 15 | ``` 16 | *Change `custom` to your folder name* 17 | -------------------------------------------------------------------------------- /malcat/obfuscators.yar: -------------------------------------------------------------------------------- 1 | rule Eazfuscator_String_Encryption : suspicious 2 | { 3 | meta: 4 | name = "Eazfuscator" 5 | category = "obfuscation" 6 | description = "Eazfuscator.NET string encryption" 7 | author = "Jonathan Peters" 8 | created = "2024-01-01" 9 | reliability = 90 10 | tlp = "TLP:white" 11 | sample = "3a9ee09ed965e3aee677043ba42c7fdbece0150ef9d1382c518b4b96bbd0e442" 12 | strings: 13 | $sa1 = "StackFrame" ascii 14 | $sa2 = "StackTrace" ascii 15 | $sa3 = "Enter" ascii 16 | $sa4 = "Exit" ascii 17 | 18 | $op1 = { 11 ?? 18 91 11 ?? 1? 91 1F 10 62 60 11 ?? 1? 91 1E 62 60 11 ?? 17 91 1F 18 62 60 } 19 | $op2 = { D1 28 ?? 00 00 0A 0? 1F 10 63 D1 } 20 | $op3 = { 1F 10 63 D1 28 [3] 0A } 21 | $op4 = { 7B ?? 00 00 04 16 91 02 7B ?? 00 00 04 17 91 1E 62 60 02 7B ?? 00 00 04 18 91 1F 10 62 60 02 7B ?? 00 00 04 19 91 1F 18 62 60 } 22 | condition: 23 | uint16(0) == 0x5a4d and 24 | all of ($sa*) and 25 | ( 26 | 2 of ($op*) or 27 | #op1 == 2 28 | ) 29 | } 30 | 31 | rule Eazfuscator_Code_Virtualization : suspicious 32 | { 33 | meta: 34 | name = "Eazfuscator" 35 | category = "obfuscation" 36 | description = "Eazfuscator.NET code virtualization" 37 | author = "Jonathan Peters" 38 | created = "2024-01-01" 39 | reliability = 90 40 | tlp = "TLP:white" 41 | sample = "53d5c2574c7f70b7aa69243916acf6e43fe4258fbd015660032784e150b3b4fa" 42 | strings: 43 | $sa1 = "BinaryReader" ascii 44 | $sa2 = "GetManifestResourceStream" ascii 45 | $sa3 = "get_HasElementType" ascii 46 | 47 | $op1 = { 28 [2] 00 06 28 [2] 00 06 72 [2] 00 70 ?? 1? 2D 0? 26 26 26 26 2B } 48 | $op2 = { 7E [3] 04 2D 3D D0 [3] 02 28 [3] 0A 6F [3] 0A 72 [3] 70 6F [3] 0A 20 80 00 00 00 8D ?? 00 00 01 25 D0 [3] 04 28 [3] 0A 28 [3] 06 28 [3] 06 80 [3] 04 7E [3] 04 2A } // VM Stream Init 49 | $op3 = { 02 20 [4] 1F 09 73 [4] 7D [3] 04 } 50 | condition: 51 | uint16(0) == 0x5a4d and 52 | all of ($sa*) and 53 | 2 of ($op*) 54 | } 55 | 56 | rule ConfuserEx_Naming_Pattern : suspicious 57 | { 58 | meta: 59 | name = "ConfuserEx" 60 | category = "obfuscation" 61 | description = "ConfuserEx Renaming Pattern" 62 | author = "Jonathan Peters" 63 | created = "2024-01-03" 64 | reliability = 90 65 | strings: 66 | $s1 = "mscoree.dll" ascii 67 | $s2 = "mscorlib" ascii 68 | $s3 = "System.Private.Corlib" ascii 69 | $s4 = "#Strings" ascii 70 | $s5 = { 5F 43 6F 72 [3] 4D 61 69 6E } 71 | 72 | $name_pattern = { E2 ( 80 8? | 81 AA ) E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 80 AE} 73 | condition: 74 | uint16(0) == 0x5a4d 75 | and 2 of ($s*) 76 | and #name_pattern > 5 77 | } 78 | 79 | rule ConfuserEx_Packer : suspicious 80 | { 81 | meta: 82 | name = "ConfuserEx" 83 | category = "obfuscation" 84 | description = "ConfuserEx Packer" 85 | author = "Jonathan Peters" 86 | created = "2024-01-09" 87 | reliability = 90 88 | strings: 89 | $s1 = "GCHandle" ascii 90 | $s2 = "GCHandleType" ascii 91 | 92 | $op1 = { 5A 20 89 C0 3F 14 6A 5E [8-20] 5A 20 FB 56 4D 44 6A 5E 6D 9E } 93 | $op2 = { 20 61 FF 6F 00 13 ?? 06 13 ?? 16 13 [10-20] 20 1F 3F 5E 00 5A } 94 | $op3 = { 16 91 7E [3] 04 17 91 1E 62 60 7E [3] 04 18 91 1F 10 62 60 7E [3] 04 19 91 1F 18 62 } 95 | condition: 96 | uint16(0) == 0x5a4d and 97 | all of ($s*) and 98 | 2 of ($op*) 99 | } 100 | 101 | 102 | 103 | rule Reactor_Indicators : suspicious 104 | { 105 | meta: 106 | name = ".NET Reactor" 107 | category = "obfuscation" 108 | description = "Ezriz .NET Reactor obfuscator" 109 | author = "Jonathan Peters" 110 | created = "2024-01-09" 111 | reliability = 90 112 | strings: 113 | $ = { 33 7B 00 [9] 00 2D 00 [9] 00 2D 00 [9] 00 2D 00 [9] 00 7D 00 } 114 | $ = { 3C 50 72 69 76 61 74 65 49 6D 70 6C 65 6D 65 6E 74 61 74 69 6F 6E 44 65 74 61 69 6C 73 3E 7B [8] 2D [4] 2D [4] 2D [4] 2D [12] 7D } 115 | $ = { 3C 4D 6F 64 75 6C 65 3E 7B [8] 2D [4] 2D [4] 2D [4] 2D [12] 7D } 116 | condition: 117 | uint16(0) == 0x5a4d 118 | and 2 of them 119 | } 120 | -------------------------------------------------------------------------------- /malcat/other.yar: -------------------------------------------------------------------------------- 1 | import "pe" 2 | 3 | rule SingleFileHost_App_Bundle 4 | { 5 | meta: 6 | name = "DotNet" 7 | category = "compiler" 8 | description = "DotNet singlefilehost app bundle" 9 | author = "Jonathan Peters" 10 | created = "2024-01-03" 11 | reliability = 90 12 | strings: 13 | $ = "singlefilehost.exe" ascii 14 | $ = "singlefilehost.pdb" ascii 15 | condition: 16 | uint16(0) == 0x5a4d and 17 | 1 of them and 18 | pe.exports("DotNetRuntimeInfo") and 19 | pe.exports("CLRJitAttachState") 20 | } 21 | -------------------------------------------------------------------------------- /tutorials/snippts_and_tricks.md: -------------------------------------------------------------------------------- 1 | # Yara Snippets and Little Tricks 2 | 3 | 4 | ## Check for string/pattern in PE Section 5 | 6 | ``` 7 |    condition: 8 |       $pattern in (pe.sections[0].raw_data_offset .. pe.sections[0].raw_data_offset + pe.sections[0].raw_data_size) 9 | ``` 10 | ## Check PE Resources for string 11 | 12 | ``` 13 |    condition: 14 |       for any i in (0..pe.number_of_resources-1) : (pe.resources[i].name_string == ".upx") 15 | ``` 16 | 17 | ## Check physical size of first PE section 18 | > [!TIP] 19 | > This is a nice condition to identify a likely packed PE image. Images packed with packers like VMProtect create their first section with a physical size of 0. UPX does something similar with their `UPX0` section. 20 | 21 | ``` 22 |    condition: 23 |       pe.sections[0].raw_data_size == 0 24 | ``` 25 | 26 | ## Convert strings to hexstrings for templating 27 | > [!TIP] 28 | > This can save the effort of building a Regex pattern and benefit performance. For example instead of searching for `_CorDllMain` or `_CorExeMain` or some regex to detect the two we can do the following: 29 | 30 | ``` 31 |    strings: 32 |       $s1 = { 5F 43 6F 72 [3] 4D 61 69 6E } // _Cor???Main 33 | ``` 34 | ## Avoid modules when possible 35 | > [!TIP] 36 | > Modules add convenience at the cost of performance, so I tend to avoid them when possible. For example instead of using `dotnet.is_dotnet` we can just search for some managed imports we expect our sample to have or common strings of a .NET binary like `mscorlib`, `System.Private.Corlib` etc. 37 | 38 | ``` 39 |    strings: 40 |       $s1 = "mscoree.dll" ascii 41 |       $s2 = "mscorlib" ascii 42 |       $s3 = "System.Private.Corlib" ascii 43 |       $s4 = "#Strings" ascii 44 |       $s5 = { 5F 43 6F 72 [3] 4D 61 69 6E } 45 | ``` 46 | -------------------------------------------------------------------------------- /yara/dotnet/anomalies.yar: -------------------------------------------------------------------------------- 1 | import "pe" 2 | 3 | rule SUSP_NET_Large_Static_Array_In_Small_File_Jan24 { 4 | meta: 5 | description = "Detects large static arrays in small .NET files " 6 | author = "Jonathan Peters" 7 | date = "2024-01-11" 8 | reference = "https://github.com/Workingdaturah/Payload-Generator/tree/main" 9 | hash = "7d68bfaed20d4d7cf2516c2b110f460cf113f81872cd0cc531cbfa63a91caa36" 10 | score = 60 11 | strings: 12 | $op = { 5F 5F 53 74 61 74 69 63 41 72 72 61 79 49 6E 69 74 54 79 70 65 53 69 7A 65 3D [6-] 00 } 13 | condition: 14 | uint16(0) == 0x5a4d and 15 | pe.data_directories[pe.IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].virtual_address != 0 and 16 | filesize < 300KB and 17 | #op == 1 18 | } 19 | -------------------------------------------------------------------------------- /yara/dotnet/framework_identiciation.yar: -------------------------------------------------------------------------------- 1 | import "pe" 2 | 3 | rule DOTNET_SingleFileHost_Bundled_App { 4 | meta: 5 | description = "Detects single file host .NET bundled apps." 6 | author = "Jonathan Peters" 7 | date = "2024-01-02" 8 | reference = "https://learn.microsoft.com/en-us/dotnet/core/deploying/single-file" 9 | strings: 10 | $ = "singlefilehost.exe" ascii 11 | $ = "singlefilehost.pdb" ascii 12 | condition: 13 | uint16(0) == 0x5a4d and 14 | 1 of them and 15 | pe.exports("DotNetRuntimeInfo") and 16 | pe.exports("CLRJitAttachState") 17 | } 18 | -------------------------------------------------------------------------------- /yara/dotnet/mal/mal_net_limecrypter_runpe.yar: -------------------------------------------------------------------------------- 1 | rule MAL_NET_LimeCrypter_RunPE_Jan24 2 | { 3 | meta: 4 | description = "Detects LimeCrypter RunPE module. LimeCrypter is an open source .NET based crypter and loader commonly used by threat actors" 5 | author = "Jonathan Peters" 6 | date = "2024-01-16" 7 | reference = "https://github.com/NYAN-x-CAT/Lime-Crypter/tree/master" 8 | hash = "bcc8c679acfc3aabf22ebdb2349b1fabd351a89fd23a716d85154049d352dd12" 9 | score = 80 10 | strings: 11 | $op1 = { 1F 1A 58 1F 1A 58 28 } 12 | $op2 = { 20 B3 00 00 00 8D ?? 00 00 01 13 ?? 11 ?? 16 20 02 00 01 00 } 13 | $op3 = { 11 0? 11 0? 20 00 30 00 00 1F 40 28 ?? 00 00 06 } 14 | $op4 = { 6E 20 FF 7F 00 00 6A FE 02 } 15 | 16 | $s1 = "RawSecurityDescriptor" ascii 17 | $s2 = "CommonAce" ascii 18 | condition: 19 | uint16(0) == 0x5a4d and 20 | all of ($s*) and 21 | 2 of ($op*) 22 | } 23 | -------------------------------------------------------------------------------- /yara/dotnet/mal/mal_net_niximports_loader.yar: -------------------------------------------------------------------------------- 1 | rule MAL_NET_NixImports_Loader_Jan24 { 2 | meta: 3 | description = "Detects open-source NixImports .NET malware loader. A stealthy loader using dynamic import resolving to evade static detection" 4 | author = "Jonathan Peters" 5 | date = "2024-01-12" 6 | reference = "https://github.com/dr4k0nia/NixImports/tree/master" 7 | hash = "dd3f22871879b0bc4990c96d1de957848c7ed0714635bb036c73d8a989fb0b39" 8 | score = 80 9 | strings: 10 | $op1 = { 1F 0A 64 06 1F 11 62 60 } // Hash algorithm 11 | $op2 = { 03 20 4D 5A 90 00 94 4B 2A } // Magic 12 | $op3 = { 20 DE 7A 1F F3 20 F7 1B 18 BC } // Hardcoded function hashes 13 | $op4 = { 20 CE 1F BE 70 20 DF 1F 3E F8 14 } // Hardcoded function hashes 14 | 15 | $sa1 = "OffsetToStringData" ascii 16 | $sa2 = "GetRuntimeMethods" ascii 17 | $sa3 = "netstandard" ascii 18 | condition: 19 | uint16(0) == 0x5a4d and 20 | all of ($sa*) and 21 | 2 of ($op*) 22 | } 23 | -------------------------------------------------------------------------------- /yara/dotnet/obf_confuserex.yar: -------------------------------------------------------------------------------- 1 | rule SUSP_OBF_NET_ConfuserEx_Name_Pattern_Jan24 { 2 | meta: 3 | description = "Detects Naming Pattern used by ConfuserEx. ConfuserEx is a widely used open source obfuscator often found in malware" 4 | author = "Jonathan Peters" 5 | date = "2024-01-03" 6 | reference = "https://github.com/yck1509/ConfuserEx/tree/master" 7 | hash = "2f67f590cabb9c79257d27b578d8bf9d1a278afa96b205ad2b4704e7b9a87ca7" 8 | score = 60 9 | strings: 10 | $s1 = "mscoree.dll" ascii 11 | $s2 = "mscorlib" ascii 12 | $s3 = "System.Private.Corlib" ascii 13 | $s4 = "#Strings" ascii 14 | $s5 = { 5F 43 6F 72 [3] 4D 61 69 6E } 15 | 16 | $name_pattern = { E2 ( 80 8? | 81 AA ) E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 [2] E2 80 AE} 17 | condition: 18 | uint16(0) == 0x5a4d 19 | and 2 of ($s*) 20 | and #name_pattern > 5 21 | } 22 | 23 | rule SUSP_OBF_NET_ConfuserEx_Packer_Jan24 { 24 | meta: 25 | description = "Detects binaries packed with ConfuserEx compression packer. This feature compresses and encrypts the actual image into a stub that unpacks and loads the original image on runtime." 26 | author = "Jonathan Peters" 27 | date = "2024-01-09" 28 | reference = "https://github.com/yck1509/ConfuserEx/tree/master" 29 | hash = "2570bd4c3f564a61d6b3d589126e0940af27715e1e8d95de7863579fbe25f86f" 30 | score = 70 31 | strings: 32 | $s1 = "GCHandle" ascii 33 | $s2 = "GCHandleType" ascii 34 | 35 | $op1 = { 5A 20 89 C0 3F 14 6A 5E [8-20] 5A 20 FB 56 4D 44 6A 5E 6D 9E } 36 | $op2 = { 20 61 FF 6F 00 13 ?? 06 13 ?? 16 13 [10-20] 20 1F 3F 5E 00 5A} 37 | $op3 = { 16 91 7E [3] 04 17 91 1E 62 60 7E [3] 04 18 91 1F 10 62 60 7E [3] 04 19 91 1F 18 62 } 38 | condition: 39 | uint16(0) == 0x5a4d 40 | and all of ($s*) 41 | and 2 of ($op*) 42 | } 43 | -------------------------------------------------------------------------------- /yara/dotnet/obf_eazfuscator.yar: -------------------------------------------------------------------------------- 1 | rule SUSP_OBF_NET_Eazfuscator_String_Encryption_Jan24 2 | { 3 | meta: 4 | description = "Detects .NET images obfuscated with Eazfuscator string encryption. Eazfuscator is a widely used commercial obfuscation solution used by both legitimate software and malware." 5 | author = "Jonathan Peters" 6 | date = "2024-01-01" 7 | reference = "https://www.gapotchenko.com/eazfuscator.net" 8 | hash = "3a9ee09ed965e3aee677043ba42c7fdbece0150ef9d1382c518b4b96bbd0e442" 9 | score = 60 10 | strings: 11 | $sa1 = "StackFrame" ascii 12 | $sa2 = "StackTrace" ascii 13 | $sa3 = "Enter" ascii 14 | $sa4 = "Exit" ascii 15 | 16 | $op1 = { 11 ?? 18 91 11 ?? 1? 91 1F 10 62 60 11 ?? 1? 91 1E 62 60 11 ?? 17 91 1F 18 62 60 } 17 | $op2 = { D1 28 ?? 00 00 0A 0? 1F 10 63 D1 } 18 | $op3 = { 1F 10 63 D1 28 [3] 0A } 19 | $op4 = { 7B ?? 00 00 04 16 91 02 7B ?? 00 00 04 17 91 1E 62 60 02 7B ?? 00 00 04 18 91 1F 10 62 60 02 7B ?? 00 00 04 19 91 1F 18 62 60 } // (int)this.\u0003[0] | ((int)this.\u0003[1] << 8) | ((int)this.\u0003[2] << 0x10) | ((int)this.\u0003[3] << 0x18); 20 | condition: 21 | uint16(0) == 0x5a4d 22 | and all of ($sa*) 23 | and ( 24 | 2 of ($op*) 25 | or 26 | #op1 == 2 27 | ) 28 | } 29 | 30 | rule SUSP_OBF_NET_Eazfuscator_Virtualization_Jan24 31 | { 32 | meta: 33 | description = "Detects .NET images obfuscated with Eazfuscator virtualization protection. Eazfuscator is a widely used commercial obfuscation solution used by both legitimate software and malware." 34 | author = "Jonathan Peters" 35 | date = "2024-01-02" 36 | reference = "https://www.gapotchenko.com/eazfuscator.net" 37 | hash = "53d5c2574c7f70b7aa69243916acf6e43fe4258fbd015660032784e150b3b4fa" 38 | score = 60 39 | strings: 40 | $sa1 = "BinaryReader" ascii 41 | $sa2 = "GetManifestResourceStream" ascii 42 | $sa3 = "get_HasElementType" ascii 43 | 44 | $op1 = { 28 [2] 00 06 28 [2] 00 06 72 [2] 00 70 ?? 1? 2D 0? 26 26 26 26 2B } 45 | $op2 = { 7E [3] 04 2D 3D D0 [3] 02 28 [3] 0A 6F [3] 0A 72 [3] 70 6F [3] 0A 20 80 00 00 00 8D ?? 00 00 01 25 D0 [3] 04 28 [3] 0A 28 [3] 06 28 [3] 06 80 [3] 04 7E [3] 04 2A } // VM Stream Init 46 | $op3 = { 02 20 [4] 1F 09 73 [4] 7D [3] 04 } 47 | condition: 48 | uint16(0) == 0x5a4d 49 | and all of ($sa*) 50 | and 2 of ($op*) 51 | } 52 | -------------------------------------------------------------------------------- /yara/dotnet/obf_net_reactor.yar: -------------------------------------------------------------------------------- 1 | import "pe" 2 | 3 | rule SUSP_OBF_NET_Reactor_Native_Stub_Jan24 { 4 | meta: 5 | description = "Detects native packer stub for version 4.5-4.7 of .NET Reactor. A pirated copy of version 4.5 of this commercial obfuscation solution is used by various malware families like BlackBit, RedLine, AgentTesla etc." 6 | author = "Jonathan Peters" 7 | date = "2024-01-05" 8 | reference = "https://notes.netbytesec.com/2023/08/understand-ransomware-ttps-blackbit.html" 9 | hash = "6e8a7adf680bede7b8429a18815c232004057607fdfbf0f4b0fb1deba71c5df7" 10 | score = 70 11 | strings: 12 | $op = {C6 44 24 18 E0 C6 44 24 19 3B C6 44 24 1A 8D C6 44 24 1B 2A C6 44 24 1C A2 C6 44 24 1D 2A C6 44 24 1E 2A C6 44 24 1F 41 C6 44 24 20 D3 C6 44 24 21 20 C6 44 24 22 64 C6 44 24 23 06 C6 44 24 24 8A C6 44 24 25 F7 C6 44 24 26 3D C6 44 24 27 9D C6 44 24 28 D9 C6 44 24 29 EE C6 44 24 2A 15 C6 44 24 2B 68 C6 44 24 2C F4 C6 44 24 2D 76 C6 44 24 2E B9 C6 44 24 2F 34 C6 44 24 30 BF C6 44 24 31 1E C6 44 24 32 E7 C6 44 24 33 78 C6 44 24 34 98 C6 44 24 35 E9 C6 44 24 36 6F C6 44 24 37 B4} 13 | condition: 14 | for any i in (0..pe.number_of_resources-1) : (pe.resources[i].name_string == "_\x00_\x00") 15 | and $op 16 | } 17 | 18 | rule SUSP_OBF_NET_Reactor_Indicators_Jan24 19 | { 20 | meta: 21 | description = "Detects indicators of .NET Reactors managed obfuscation. Reactor is a commercial obfuscation solution, pirated versions are often abused by threat actors." 22 | author = "Jonathan Peters" 23 | date = "2024-01-09" 24 | reference = "https://www.eziriz.com/dotnet_reactor.htm" 25 | hash = "be842a9de19cfbf42ea5a94e3143d58390a1abd1e72ebfec5deeb8107dddf038" 26 | score = 65 27 | strings: 28 | $ = { 33 7B 00 [9] 00 2D 00 [9] 00 2D 00 [9] 00 2D 00 [9] 00 7D 00 } 29 | $ = { 3C 50 72 69 76 61 74 65 49 6D 70 6C 65 6D 65 6E 74 61 74 69 6F 6E 44 65 74 61 69 6C 73 3E 7B [8] 2D [4] 2D [4] 2D [4] 2D [12] 7D } 30 | $ = { 3C 4D 6F 64 75 6C 65 3E 7B [8] 2D [4] 2D [4] 2D [4] 2D [12] 7D } 31 | condition: 32 | uint16(0) == 0x5a4d 33 | and 2 of them 34 | } 35 | -------------------------------------------------------------------------------- /yara/dotnet/suspicious_indicators.yar: -------------------------------------------------------------------------------- 1 | rule SUSP_NET_Shellcode_Loader_Indicators_Jan24 { 2 | meta: 3 | description = "Detects indicators of shellcode loaders in .NET binaries" 4 | author = "Jonathan Peters" 5 | date = "2024-01-11" 6 | reference = "https://github.com/Workingdaturah/Payload-Generator/tree/main" 7 | hash = "c48752a5b07b58596564f13301276dd5b700bd648a04af2e27d3f78512a06408" 8 | score = 65 9 | strings: 10 | $sa1 = "VirtualProtect" ascii 11 | $sa2 = "VirtualAlloc" ascii 12 | $sa3 = "WriteProcessMemory" ascii 13 | $sa4 = "CreateRemoteThread" ascii 14 | $sa5 = "CreateThread" ascii 15 | $sa6 = "WaitForSingleObject" ascii 16 | 17 | $x = "__StaticArrayInitTypeSize=" ascii 18 | condition: 19 | uint16(0) == 0x5a4d and 20 | 3 of ($sa*) and 21 | #x == 1 22 | } 23 | -------------------------------------------------------------------------------- /yara/other/susp_direct_syscall_shellcode_invocation.yar: -------------------------------------------------------------------------------- 1 | rule SUSP_Direct_Syscall_Shellcode_Invocation_Jan24 { 2 | meta: 3 | description = "Detects direct syscall evasion technqiue using NtProtectVirtualMemory to invoke shellcode" 4 | author = "Jonathan Peters" 5 | date = "2024-01-14" 6 | reference = "https://unprotect.it/technique/evasion-using-direct-syscalls/" 7 | hash = "f7cd214e7460c539d6f8d02b6650098e3983862ff658b76ea02c33f5a45fc836" 8 | score = 65 9 | strings: 10 | $ = { B8 40 00 00 00 67 4C 8D 08 49 89 CA 48 C7 C0 50 00 00 00 0F 05 [4-8] 4C 8D 3D 02 00 00 00 FF E0 } 11 | condition: 12 | all of them and 13 | filesize < 2MB 14 | } 15 | -------------------------------------------------------------------------------- /yara/other/susp_obf_pyarmor.yar: -------------------------------------------------------------------------------- 1 | rule SUSP_OBF_PyArmor_Jan24 2 | { 3 | meta: 4 | description = "Detects PyArmor python code obfuscation. PyArmor is used by various threat actors like BatLoader" 5 | author = "Jonathan Peters" 6 | date = "2024-01-16" 7 | reference = "https://www.trendmicro.com/en_us/research/23/h/batloader-campaigns-use-pyarmor-pro-for-evasion.html" 8 | hash = "2727a418f31e8c0841f8c3e79455067798a1c11c2b83b5c74d2de4fb3476b654" 9 | score = 65 10 | strings: 11 | $ = "__pyarmor__" ascii 12 | $ = "pyarmor_runtime" ascii 13 | $ = "pyarmor(__" ascii 14 | $ = { 50 79 61 72 6D 6F 72 20 [5] 20 28 70 72 6F 29 } 15 | $ = { 5F 5F 61 72 6D 6F 72 5F ( 65 78 69 74 | 77 72 61 70 | 65 6E 74 65 72 ) 5F 5F } 16 | condition: 17 | 2 of them 18 | } 19 | -------------------------------------------------------------------------------- /yara/other/susp_rlo_exe_extension_spoofing.yar: -------------------------------------------------------------------------------- 1 | 2 | rule SUSP_RLO_Exe_Extension_Spoofing_Jan24 { 3 | meta: 4 | description = "Detects Right-To-Left (RLO) Unicode (U+202E) extension spoofing for .exe files" 5 | author = "Jonathan Peters" 6 | date = "2024-01-14" 7 | reference = "https://unprotect.it/technique/right-to-left-override-rlo-extension-spoofing/" 8 | hash = "cae0ab10f7c1afd7941aff767a9b59901270e3de4d44167e932dae0991515487" 9 | score = 70 10 | strings: 11 | $ = { E2 80 AE 76 73 63 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } // csv 12 | $ = { E2 80 AE 66 64 70 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } // pdf 13 | $ = { E2 80 AE 78 73 6C 78 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } // xlsx 14 | $ = { E2 80 AE 78 63 6F 64 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } // docx 15 | $ = { E2 80 AE 70 69 7A ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } // zip 16 | $ = { E2 80 AE 67 6E 70 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } // png 17 | $ = { E2 80 AE 67 65 70 6A ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } // jpeg 18 | $ = { E2 80 AE 67 70 6A ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } // jpg 19 | $ = { E2 80 AE 6E 6C 73 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } // sln 20 | 21 | $ = { E2 80 AE 74 78 74 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 22 | $ = { E2 80 AE 66 64 70 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 23 | $ = { E2 80 AE 78 74 70 70 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 24 | $ = { E2 80 AE 74 64 6f ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 25 | $ = { E2 80 AE 63 74 65 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 26 | $ = { E2 80 AE 66 69 67 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 27 | $ = { E2 80 AE 70 6d 62 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 28 | $ = { E2 80 AE 66 66 69 74 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 29 | $ = { E2 80 AE 67 76 73 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 30 | $ = { E2 80 AE 34 70 6d ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 31 | $ = { E2 80 AE 69 76 61 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 32 | $ = { E2 80 AE 76 6f 6d ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 33 | $ = { E2 80 AE 76 6d 77 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 34 | $ = { E2 80 AE 76 6c 66 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 35 | $ = { E2 80 AE 76 6b 6d ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 36 | $ = { E2 80 AE 33 70 6d ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 37 | $ = { E2 80 AE 76 61 77 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 38 | $ = { E2 80 AE 63 61 61 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 39 | $ = { E2 80 AE 63 61 6c 66 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 40 | $ = { E2 80 AE 67 67 6f ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 41 | $ = { E2 80 AE 61 6d 77 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 42 | $ = { E2 80 AE 72 61 72 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 43 | $ = { E2 80 AE 7a 37 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 44 | $ = { E2 80 AE 7a 67 72 61 74 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 45 | $ = { E2 80 AE 6f 73 69 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 46 | $ = { E2 80 AE 6c 6d 74 68 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 47 | $ = { E2 80 AE 6c 6d 65 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 48 | $ = { E2 80 AE 6d 74 68 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 49 | $ = { E2 80 AE 66 74 72 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 50 | $ = { E2 80 AE 6d 68 63 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 51 | $ = { E2 80 AE 61 74 68 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 52 | $ = { E2 80 AE 6b 6e 6c ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 53 | $ = { E2 80 AE 73 6c 78 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 54 | $ = { E2 80 AE 63 6f 64 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 55 | $ = { E2 80 AE 6d 63 6f 64 ( 2E 2E | 2E ) ( 65 78 65 | 73 63 72 ) } 56 | condition: 57 | 1 of them 58 | } 59 | -------------------------------------------------------------------------------- /yara/thor/vcruntime140_sideloading.yar: -------------------------------------------------------------------------------- 1 | import "pe" 2 | 3 | rule SUSP_VCRuntime_Sideloading_Indicators_Aug23 { 4 | meta: 5 | description = "Detects indicators of .NET based malware sideloading as VCRUNTIME140" 6 | author = "Jonathan Peters" 7 | date = "2023-08-30" 8 | hash = "b4bc73dfe9a781e2fee4978127cb9257bc2ffd67fc2df00375acf329d191ffd6" 9 | score = 75 10 | condition: 11 | (filename == "VCRUNTIME140.dll" or filename == "vcruntime140.dll") 12 | and pe.imports("mscoree.dll", "_CorDllMain") 13 | } 14 | 15 | rule SUSP_VCRuntime_Sideloading_Indicators_1_Aug23 { 16 | meta: 17 | description = "Detects indicators of malware sideloading as VCRUNTIME140" 18 | author = "Jonathan Peters" 19 | date = "2023-08-30" 20 | hash = "b4bc73dfe9a781e2fee4978127cb9257bc2ffd67fc2df00375acf329d191ffd6" 21 | score = 75 22 | strings: 23 | $x = "Wine builtin DLL" ascii 24 | condition: 25 | (filename == "VCRUNTIME140.dll" or filename == "vcruntime140.dll") 26 | and ( pe.number_of_signatures == 0 27 | or not pe.signatures[0].issuer contain "Microsoft Corporation" ) 28 | and not $x 29 | } 30 | --------------------------------------------------------------------------------