Detecting JanelaRAT with Yara and THOR

by Sep 15, 2023

In the last weeks, we observed an increase in .NET based malware using DLL sideloading. A prominent example is JanelaRAT, a recent campaign targeting Latin American FinTech users.
Their initial attack involves a phishing email, mainly in Portuguese language. The user is tricked into running a VisualBasic script, which then downloads the legitimate app used for sideloading and the payload posing as a legitimate DLL file.

In the JanelaRAT cases, we looked into, they used vmnat.exe, a component of VMWare, to load their payload posing as vcruntime140.dll. The legitimate DLL is a component of the Microsoft Visual C++ Runtime. Since they use a legitimately signed VMWare executable to load the DLL, the process is much less noisy than bringing their own loader or using Powershell, for example. In the following, we will look at these cases of DLL sideloading and how we can detect it using Yara and THOR.

Detecting sideloading

While this form of sideloading saves some effort for the attacker, it also opens up some detection vectors for us as defenders. For officially distributed components with known names and certificates like vcruntime140.dll, we can check for files matching that name, which are not signed by Microsoft. Not all Microsoft-released binaries contain digital signature information inside the PE image. Some Windows components, for example, are verified through catalog files, therefore this needs to be evaluated on a case-by-case basis. In our case, the legitimate DLL file is signed by Microsoft thus, we conclude that unsigned or improperly signed files appearing to be vcruntime140.dll are considered suspicious.

import "pe"

rule SUSP_VCRuntime_Sideloading_Indicators_1_Aug23 {
   meta:
      description = "Detects indicators of .NET based malware sideloading as an unsigned VCRUNTIME140"
      author = "Jonathan Peters"
      date = "2023-08-30"
      hash = "b4bc73dfe9a781e2fee4978127cb9257bc2ffd67fc2df00375acf329d191ffd6"
      score = 75
   strings:
      $x = "Wine builtin DLL" ascii
   condition:
      (filename == "VCRUNTIME140.dll" or filename == "vcruntime140.dll")
      and ( pe.number_of_signatures == 0
      or not pe.signatures[0].issuer contains "Microsoft Corporation" )
      and not $x
}

Note that filename is an external variable available in THOR but not standard Yara

In our Yara rule, we check for the expected filename. Next, we verify if the PE image has any signatures. If the PE has no signatures, the rule will trigger. The following condition checks if the first signature in the PE was issued by Microsoft Corporation, which indicates a legitimately signed version of the DLL. If the issuer does not contain Microsoft Corporation, the file will be deemed suspicious and trigger the rule. We added another condition to avoid false positives for DLLs used in Wine, a framework used to run Windows applications on Linux based systems.

While this approach is effective, it has one downside: Yara cannot verify the validity of a PE signature. In case the target binary was illegitimately signed with an invalid certificate posing as Microsoft Corporation the rule would not trigger. In an ideal case, the invalid certificate should already be suspicious and trigger other detections or prevent execution of the binary.

When we compared the malicious DLL to a legitimate copy of the DLL, we noticed an interesting difference in the imports. Since JanelaRAT is written in C# and compiled as a .NET Framework DLL, it references the .NET runtime. The legitimate vcruntime140.dll is a native x86-64 compiled binary that does not import any .NET runtime components. A managed DLL compiled using .NET Framework usually imports the _CorDllMain function from mscoree.dll, which serves as a native entry point that initializes the CLR and resolves the managed entry point of the .NET code. A legitimate version of vcruntime140.dll will never import mscoree.dll!_CorDllMain. Therefore, we can consider any version of the DLL importing that specific function suspicious.

import "pe"

rule SUSP_VCRuntime_Sideloading_Indicators_Aug23 {
   meta:
      description = "Detects indicators of .NET based malware sideloading as VCRUNTIME140 with .NET DLL imports"
      author = "Jonathan Peters"
      date = "2023-08-30"
      hash = "b4bc73dfe9a781e2fee4978127cb9257bc2ffd67fc2df00375acf329d191ffd6"
      score = 75
   condition:
      (filename == "VCRUNTIME140.dll" or filename == "vcruntime140.dll")
      and pe.imports("mscoree.dll", "_CorDllMain")
}

Note that filename is an external variable available in THOR but not standard Yara

In our Yara rule, we check for the filename and then use the PE module to check if the binary imports the previously mentioned CLR initialization function; if that is the case, the rule will trigger. While we have primarily observed JanelaRAT detections with this rule, it also triggers on other .NET based sideloading payloads for this specific DLL.

For interested researchers: The samples we used to develop the above Yara rules can be found in the Indicators of Compromise (IOCs) section at the end of the post.

Scanning your own Network

If you want to scan your network for indicators of compromise using our public rules, you can use our free THOR-Lite scanner to quickly scan your environment. The THOR-Lite scanner runs on Windows, Linux, and MacOS and offers free scanning using our open-source Yara ruleset, including the rules shown in this post.

For more advanced needs, we also offer the fully featured THOR scanner, using our large private Yara and Sigma rulesets covering thousands of generic signatures, anomalies, obfuscation techniques, and suspicious properties, including additional detections for JanelaRAT’s payloads and Visual Basic Script based downloaders.

The THOR scanner offers deeper scanning with additional scan modules for Windows Registry, Eventlog, and SHIM Cache. It also supports legacy platforms like Windows XP, 2003, 2008, and additional platforms like IBM AIX. Check the THOR-Lite page for a more detailed feature comparison.

Credits

Indicators of Compromise (IOCs)

Type Indicator
SHA256 b4bc73dfe9a781e2fee4978127cb9257bc2ffd67fc2df00375acf329d191ffd6
SHA256 4c9f5d36ceeae70848cdca9329cee05c43421a64d1d992593953a257c6901505
SHA256 d542786f8d50c8d452e3c51bc5de0f30d55694021a94e828799e088f7e9c5f62
SHA256 0f3aec715e8fd1978e1a0f58a2fa64b33e969dd618173499c08c87951a741a92
SHA256 429d9c18f433163bf1098bc11f5ef686247c4bf2bc600784fe1227bfe78c806d
SHA256 88a1e4fd41b48fbb160e45c0afcda4ed67f47b924129010fa45466197d9f7960
SHA256 b8c57b4ea66313b1b625ff15dec4031a08b983cc34be0794b9c4310737cb36cb
SHA256 43756c1c563bbb73aa623aa24d28e571fe081e0f2391677cda2a715369698189
SHA256 c2719f9d2d69d1ed5c0a77254cd5661c523906ed9f474ef8ee702dd8f4bcee93
SHA256 b4055b467a5511b4c2cef17ffd859e1a77bcbd68d3f275d43d394561140f0c6c
SHA256 0c873439bc0af08fdf0c335c5a94752413fd096c0c2f1138f17e786bc5ce59c3
SHA256 fcb35e7afde47c4c4b6f33ed0f8720a50881f41bf0de53dac79148af6d6d1fbe
SHA256 6c8264750f725e769d2cf344315eefdd2f74724c3395d8bd1ad594fa55a2c8f6
SHA256 4f3cd4d69d9e603cc9026c08661683d0651050569c968c263f740c52710af258
SHA256 51b39d733787e9aa38031ef661de7d6c4d65d91e3de21ba73049387737de0f4b
SHA256 8e4a5f0497a97e5f89c687d189b70be5659ed62cef788acb0fafc8cdfe86ac1d
SHA256 23bfb3be3495e3987bc705b5bc48724b590023f4102f963e2af27148707cddc0
SHA256 7cfcd2f432c686dc648bef79e1483b90093f6d14777c06bcc96a963577af5393
SHA256 6a4814e7dd85199e5b85e8a0519520b2bff16c39131ecc2bd28f6b3cde007cb6
SHA256 6e4f4fd529bae2f22bc9186bfb732b5bac67c8ae2c1f9a4abfff4f961629dd20
SHA256 f3e29f902d8db9da1f8af9ec2184b40654bd9cfd1597628f9e2303b3493f1976
SHA256 116218f88e4e9f34432154cc050605a2a1f9d081ba28a9874ef6bfc4a62307ba
SHA256 9031dd5ff47abfda2fa5cbaf71d40bbae2f978435208942c9a21254bb3d0c93f
SHA256 3edd0792dc2aa14133a254ce77b4e9bf842b410ff74871a55012001ae593bfec
SHA256 bffdea38bfb3e16046a707f313396a97ec49b23cf6c504543fa810f69b62fdeb
SHA256 87c8d7abada860d657f8bdc5e8ad6abce265f12cf921e080b7714b1996bb1b77
SHA256 fa87bb1ca9d683cfc8d0f4f41c98f7804004efcbfe80674d9be7e7f9380ee6bf
SHA256 24f2344bb9680c77188b63c3a5edff547dabb5aafd284dbea893d10f2a13d9ce
SHA256 56de1aea9e993a729f748d2e405eec0457aeeca8e48053c3fce68eac6a07b5ad
SHA256 a574d6961acf4b6ff58e3483cc52e16d59971a4926540b868c6cd6d79d27b890
SHA256 84b98c70c94fb835c749f44beb6e87c8987cf181d37744e3eb96b6c685b4de70
SHA256 3f6a455ad6c3b82182644b44cd1b718cd9426fc41f084f24daaa5da1d3050027
SHA256 5cd7cf487542c781b133b02101e08a1d5e1953b044692ed0326434dc5d94c693
SHA256 234fcc8a55491633121e6012f973bd6619e3267e82e84b5b2eda75073ce8dd61
SHA256 ab86a1e884b0e6ba10d9bfa71a6fff30a91cfc885671470a49c648824d8aa79f
SHA256 9c1c125442d44bab0e556e1f77c710561d818ccb1a2dda8e76accc6b1661135e
SHA256 c4b06ef9ad3b0c556a21ba95f3faa898afc32cbf03b7dd83df28a38297296a1d
SHA256 bca6ea026cf0e8bbb02940bdff162b90b0d780b7dd8c9184276f83ea1a1587d9
SHA256 b6d78d3dfe4e60ae76de90c7f96dbda98d7c601b3500121923d08ec579f81529
SHA256 ea5a5dd9b89a9238faa52829c10f8cd38ccf01150928a6f24b06c79fa926d83f
SHA256 1e3e8c05051dd434b6069c212ee5c93603ca98fe27c024c0b1e7affb61937b54
SHA256 99bf058ca85da62359a4138039382e67d7cae5ff8ee8d9deeb80e5dffa7dbe6a
SHA256 079ee055b833a515f7fb0d5e7964ebf4f78457de7215f44e3d14a8a0b01a41fc
SHA256 fbec4b5c6e0a889fb9fa29ec61d3017d260eb91812290b5af6ae4e10fec9de71
SHA256 fe56c6db22ed7138e72a31cb394904a8823608dd039436e61cff215f024e67d9
SHA256 b38c1054bb3925fd0eaa4d68b2ebae25851560d815f1734723eca3424772bb15
SHA256 ce64683225ea467359d0b16a7a6e1b16320e2983458bc3e1ac9ca543f5e5138a
SHA256 bbd9f9c57330cf7810812f58f1ef141ee8a89718d37fc9396d47b5937426d455
SHA256 ee7260184be50599dbf30d32621ed793628c2db2566834dd68acdd1b5c6465f0
SHA256 74c2519f841b9210867d8cc50c672b6c2df3234e4591b1d764abd927b195c642
SHA256 4499c31ff4ffbbdc5a72957bd42d41e56ea94933f31b94415cbddde96c033aa3
SHA256 192a806734f11e8f9afa15e8070ca51513e7687a91815d63c368860fe335a4a3
SHA256 408b7382d3ccbab8d9fc977205a1cb6cf8cc77b08827a0abf3b0c85434517be5
SHA256 c13ee25534e38968c880fb8c99206d1e89ebe2a304f9f96599f3846c3dfa14a9
SHA256 64ec8802842cba92ad046d9e56b7dbee0ae15e550ba2e5b311609ebfd01802cb
SHA256 441dfaa0dc64a23b01fa9028bc42fe3dc2f7b72730a2d5862aaffe031d497f9c
SHA256 2d921b87bbe5a860028c5c37286e701f5cd0232a0b98bbced18b6ce457a8efde
SHA256 aa59998e0565710d6de31020c12910b50b5fd936a4c4cf58e9f1456e73f23f9c
SHA256 9a289ae5a8aa5650c5e389321f887b33c8e356d6329958c419c6645ad5bb7877
SHA256 aa2ddccf9ebe2dd5cd78770f4f57e06a85bb3e142cf5284601c1e5f10ca41825
SHA256 14893bbcfef8d1b835587e6873105a6af243441059f3d927881ece5f7a1b0430

About the author:

Jonathan Peters

Jonathan Peters works as a Threat Researcher and Detection Engineer. He has a background in software development and is experienced in .NET, primarily developing obfuscation and deobfuscation solutions. Jonathan began reverse-engineering software in 2015, which eventually led him to malware analysis. Due to his interest in malware analysis and detection solutions, he began writing his own tools and Yara rules. He engages with the cybersecurity community as @cod3nym on Twitter.

Newsletter

New blog posts
(~1 email/month)

GDPR Cookie Consent with Real Cookie Banner