diff --git a/data/yara/memory/kraken-cryptor.yar b/data/yara/memory/kraken-cryptor.yar new file mode 100644 index 000000000..0dd017077 --- /dev/null +++ b/data/yara/memory/kraken-cryptor.yar @@ -0,0 +1,24 @@ +rule kraken_cryptor_config +{ + meta: + author = "brae" + description = "Kraken Cryptor configuration identified" + + strings: + $project = /\"project\"\:\{[^\}]*\}/ + $module = /\"module\"\:\{[^\}]*\}/ + // $core = /\"core\"\:\{[^\}]*\}/ + $core = /\"core\"\:\{/ + $publickey = /\"public_key\"\:\"[^\"]*\"/ + $supportemail1 = /\"support_email_1\"\:\"[^\"]*\"/ + $supportemail2 = /\"support_email_2\"\:\"[^\"]*\"/ + $price = /\"price\"\:[^\,]*/ + $priceunit = /\"price_unit\"\:\"[^\"]*\"/ + $extension = /\"new_extension\"\:\"[^\"]*\"/ + $help_name = /\"name\"\:\"[^\"]*\"/ + $help_extension = /\"extension\"\:\"[^\"]*\"/ + + condition: + // all of ($project, $module, $core) + 3 of them +} diff --git a/modules/signatures/cross/js_eval.py b/modules/signatures/cross/js_eval.py index 77039eb60..b11b71add 100644 --- a/modules/signatures/cross/js_eval.py +++ b/modules/signatures/cross/js_eval.py @@ -18,6 +18,9 @@ def on_call(self, call, process): if call["arguments"]["type"] == "eval code": self.severity = 3 self.description = "Executed javascript and unpacks itself" + + if "VBScript" in call["arguments"]["type"]: + self.description = "Executes VBScript" self.mark_call() return True diff --git a/modules/signatures/extractor/krakencryptor.py b/modules/signatures/extractor/krakencryptor.py new file mode 100644 index 000000000..911d3e7fe --- /dev/null +++ b/modules/signatures/extractor/krakencryptor.py @@ -0,0 +1,39 @@ +from cuckoo.common.abstracts import Extractor + +from roach import Structure, uint8, uint32, rsa, procmem + +class KrakenCryptorConfig(Extractor): + yara_rules = "kraken_cryptor_config" + minimum = "2.0.5" + + def handle_yara(self, filepath, match): + # Handle project section + sproject = match.strings("project")[0] + for l in sproject.split(","): + if "version" in l: + self.version = l.split(":")[1].strip(",") + + # Handle module section + smodule = match.strings("module")[0] + + + # Handle core section + self.pubkey = match.strings("publickey")[0].split(":")[1].strip('",') + + self.emails = [match.strings("supportemail1")[0].split(":")[1].strip('",'), match.strings("supportemail2")[0].split(":")[1].strip('",')] + + sprice = match.strings("price")[0].split(":")[1].strip('",') + spriceunit = match.strings("priceunit")[0].split(":")[1].strip('",') + self.price = sprice + " " + spriceunit + + self.extension = match.strings("extension")[0].split(":")[1].strip('",') + + self.helpfile = match.strings("help_name")[1].split(":")[1].strip('",') + "." + match.strings("help_extension")[0].split(":")[1].strip('",') + + self.push_config({ + "family": "Kraken Cryptor", + "pubkey": self.pubkey, + "url": self.emails, + "type": "Ransom price: " + self.price + "\nRansom note: " + self.helpfile, + "ransom_text": self.helpfile + }) diff --git a/modules/signatures/windows/rat_njrat.py b/modules/signatures/windows/rat_njrat.py index 58d882e8b..2738aaa95 100644 --- a/modules/signatures/windows/rat_njrat.py +++ b/modules/signatures/windows/rat_njrat.py @@ -23,5 +23,10 @@ def on_complete(self): match = self.check_file(pattern=indicator, regex=True) if match: self.mark_ioc("file", match) - + if self.has_marks(): + self.mark_config({ + "family": "njRAT (also known as Bladabindi)", + "type": "Samples creates artifacts known to be associated with the njRAT Trojan", + "url": "https://blog.malwarebytes.com/detections/backdoor-njrat/" + }) return self.has_marks() diff --git a/modules/signatures/windows/trojan_bifrost.py b/modules/signatures/windows/trojan_bifrost.py new file mode 100644 index 000000000..296d30c51 --- /dev/null +++ b/modules/signatures/windows/trojan_bifrost.py @@ -0,0 +1,39 @@ +from lib.cuckoo.common.abstracts import Signature + +class BifrostTrojan(Signature): + # This signature is intended to catch references to the HKEY_LOCAL_MACHINE\SOFTWARE\Bifrost registry key, based on observations of a sample. + # It may be too specific to be widely applicable, and could potentially be extended to catch references in direct registry operations. However + # the malware sample observed did not reach the stage of execution which actually made changes to the registry, but sections of the path could be + # observed in buffers injected into explorer.exe. + name = "trojan_bifrost" + description = "Includes registry keys related to the Bifrost Trojan backdoor" + severity = 5 + categories = ["trojan"] + authors = ["Brae"] + minimum = "2.0" + + filter_apinames = [ + "NtWriteVirtualmemory", + "WriteProcessMemory", + ] + + process_handles = ["0xffffffff", "0xffffffffffffffff"] + + def on_call(self, call, process): + proc_handle = call["arguments"]["process_handle"] + + if len(call["arguments"]["buffer"]) > 0 and proc_handle not in self.process_handles: + injected_pid = call["arguments"]["process_identifier"] + call_process = self.get_process_by_pid(injected_pid) + + if not call_process or call_process["ppid"] != process["pid"]: + if "SOFTWARE\Bifrost" in call["arguments"]["buffer"]: + self.mark_config({ + "family":"Bifrost Trojan", + "url":"https://www.symantec.com/connect/blogs/retrospective-tour-backdoorbifrose", + "type":"Contains references to registry keys associated with the Bifrost remote access trojan" + }) + + + def on_complete(self): + return self.has_marks()