From c75f59ea8d8767ee69d0ca05bc5ed6c44a8a5fd9 Mon Sep 17 00:00:00 2001 From: Mohannad Raafat <62453654+para0x0dise@users.noreply.github.com> Date: Thu, 31 Oct 2024 23:57:10 +0300 Subject: [PATCH 1/3] Create abuse_hvci.py --- modules/signatures/windows/abuse_hvci.py | 141 +++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 modules/signatures/windows/abuse_hvci.py diff --git a/modules/signatures/windows/abuse_hvci.py b/modules/signatures/windows/abuse_hvci.py new file mode 100644 index 00000000..c3a0f5d7 --- /dev/null +++ b/modules/signatures/windows/abuse_hvci.py @@ -0,0 +1,141 @@ +from lib.cuckoo.common.abstracts import Signature + +class PendingFileRenameOperations(Signature): + name = "pendingfilerenameoperations_Operations" + description = "Attempts to hijack existing resources for execution and persistence using PendingFileRename operation" + severity = 3 + categories = ["evasion", "execution", "persistence"] + authors = ["@para0x0dise"] + minimum = "0.5" + evented = True + ttps = ["T1112", "T1562", "T1562.001"] + references = [ + "https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_allowprotectedrenames_registry_modification.toml", + ] + + filter_apinames = set(["RegSetValueExA", "RegSetValueExW"]) + + def __init__(self, *args, **kwargs): + Signature.__init__(self, *args, **kwargs) + self.detected = False + def on_call(self, call, process): + if not any(path in process["module_path"] for path in ("\\Program Files\\", "\\Program Files (86)\\")): + if call["api"] in ("RegSetValueExA", "RegSetValueExW"): + regKeyPath = self.get_argument(call, "FullName").lower() + buf = self.get_argument(call, "Buffer") + if "allowprotectedrenames" in regKeyPath and buf == "1": + self.data.append({"regkey": regKeyPath}) + self.detected = True + def on_complete(self): + if self.detected: + return True + return False + + +class DisableDriverViaHVCIDisallowedImages(Signature): + name = "disable_driver_via_hvcidisallowedimages" + description = "Attempt to disable a driver via HVCIDisallowedImages" + severity = 3 + categories = ["evasion"] + authors = ["@para0x0dise"] + minimum = "0.5" + evented = True + ttps = ["T1112"] + references = [ + "https://x.com/yarden_shafir/status/1822667605175324787", + "https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_attempt_to_disable_driver_via_hvcidisallowedimages.toml" + ] + + filter_apinames = set(["RegSetValueExA", "RegSetValueExW"]) + + def __init__(self, *args, **kwargs): + Signature.__init__(self, *args, **kwargs) + self.detected = False + + def on_call(self, call, _): + if call["api"] in ("RegSetValueExA", "RegSetValueExW"): + regKeyPath = self.get_argument(call, "FullName").lower() + buf = self.get_argument(call, "Buffer") + if "hvcidisallowedimages" in regKeyPath and ".sys" in buf: + self.data.append({"Value": buf}) + self.detected = True + + def on_complete(self): + if self.detected: + self.data.append({"Value": self.buf}) + return True + return False + +class DisableDriverViaBlocklist(Signature): + name = "disable_driver_via_blocklist" + description = "Attempt to disable a driver Microsoft policy that prevents a blacklist of known vulnerable drivers" + severity = 3 + categories = ["evasion"] + authors = ["@para0x0dise"] + minimum = "0.5" + evented = True + ttps = ["T1112"] + references = [ + "https://www.unknowncheats.me/forum/anti-cheat-bypass/524561-windows-11-blacklisteddrivers-fix.html", "https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_attempt_to_disable_windows_driver_blocklist_via_registry.toml" + ] + + filter_apinames = set(["RegSetValueExA", "RegSetValueExW"]) + + def __init__(self, *args, **kwargs): + Signature.__init__(self, *args, **kwargs) + self.detected = False + self.falseProcess = ( + "securityhealthservice", "ikernel.exe" + ) + + def on_call(self, call, process): + if not process["process_name"].lower() in self.falseProcess: + if call["api"] in ("RegSetValueExA", "RegSetValueExW"): + regKeyPath = self.get_argument(call, "FullName").lower() + buf = self.get_argument(call, "Buffer") + if "\\ci\\config\\vulnerabledriverblocklistenable" in regKeyPath and buf == '0': + self.data.append({"regkey": regKeyPath}) + self.detected = True + + def on_complete(self): + if self.detected: + return True + return False + +class DisableHypervisorProtectedCodeIntegrity(Signature): + name = "disable_hypervisor_protected_code_integrity" + description = "Attempt to disable Hypervisor-protected Code Integrity to load unsigned drivers" + severity = 3 + categories = ["evasion"] + authors = ["@para0x0dise"] + minimum = "0.5" + evented = True + ttps = ["T1112"] + references = [ + "https://www.unknowncheats.me/forum/anti-cheat-bypass/524561-windows-11-blacklisteddrivers-fix.html", + "https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_disabling_hypervisor_protected_code_integrity_via_registry.toml" + ] + + filter_apinames = set(["RegSetValueExA", "RegSetValueExW"]) + + def __init__(self, *args, **kwargs): + Signature.__init__(self, *args, **kwargs) + self.detected = False + self.falseProcess = ( + "deviceenroller.exe", "omadmclient.exe", "svchost.exe", "securityhealthservice.exe", + "mbamessagecenter.exe", "aisuite3.exe", "ikernel.exe", "regedit.exe" + ) + + def on_call(self, call, process): + if not process["process_name"].lower in self.falseProcess: + if call["api"] in ("RegSetValueExA", "RegSetValueExW"): + regKeyPath = self.get_argument(call, "FullName").lower() + buf = self.get_argument(call, "Buffer") + if any(key in regKeyPath for key in ("\\deviceguard\\hypervisorenforcedcodeintegrity","\\deviceguard\\scenarios\\hypervisorenforcedcodeintegrity\\enabled")) and buf == '0': + self.data.append({"regkey": regKeyPath}) + self.detected = True + + def on_complete(self): + if self.detected: + return True + return False \ No newline at end of file From 64cceca4843b64ecf045943ce9fdbbadb8fe0310 Mon Sep 17 00:00:00 2001 From: Mohannad Raafat <62453654+para0x0dise@users.noreply.github.com> Date: Thu, 31 Oct 2024 23:57:16 +0300 Subject: [PATCH 2/3] Update lolbas.py --- modules/signatures/windows/lolbas.py | 44 +++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/modules/signatures/windows/lolbas.py b/modules/signatures/windows/lolbas.py index c4965089..fec8ff02 100644 --- a/modules/signatures/windows/lolbas.py +++ b/modules/signatures/windows/lolbas.py @@ -481,7 +481,7 @@ class LOLBAS_ExecuteBinaryViaInternetExplorerExporter(Signature): def __init__(self, *args, **kwargs): Signature.__init__(self, *args, **kwargs) self.detected = False - self.blacklistedNames = ["mozcrt19.dll", "mozsqlite3.dll", "sqlite3.dll"] + self.blacklistedNames = ("mozcrt19.dll", "mozsqlite3.dll", "sqlite3.dll") self.whitelistedDirectories = [ "\\program files (x86)\\", "\\program files\\", @@ -568,3 +568,45 @@ def run(self): return True return False + +class LOLBAS_ExecuteBinaryViaPcalua(Signature): + name = "execute_binary_via_pcalua" + description = "Attempts to execute a binary using Microsoft Program Compatibility Assistant binary" + severity = 3 + categories = ["bypass", "execution"] + authors = ["@para0x0dise"] + minimum = "1.2" + ttps = ["T1218"] + references = ["https://lolbas-project.github.io/lolbas/Binaries/Pcalua/"] + evented = True + + def run(self): + cmdlines = self.results.get("behavior", {}).get("summary", {}).get("executed_commands", []) + for cmdline in cmdlines: + lower = cmdline.lower() + if "pcalua.exe" in lower and "-a" in lower and not "-d" in lower: + self.data.append({"command": cmdline}) + return True + + return False + +class LOLBAS_ExecuteBinaryViaCDB(Signature): + name = "execute_binary_via_pcalua" + description = "Attempts to execute a binary using Microsoft Windows Debugging utility cdb.exe" + severity = 3 + categories = ["bypass", "execution"] + authors = ["@para0x0dise"] + minimum = "1.2" + ttps = ["T1218"] + references = ["https://lolbas-project.github.io/lolbas/OtherMSBinaries/Cdb/"] + evented = True + + def run(self): + cmdlines = self.results.get("behavior", {}).get("summary", {}).get("executed_commands", []) + for cmdline in cmdlines: + lower = cmdline.lower() + if "cdb.exe" in lower and any(arg in lower for arg in ("-cf", "-c", "-pd")): + self.data.append({"command": cmdline}) + return True + + return False \ No newline at end of file From bd09c8d139d142183a45e870ac87c2f50248b474 Mon Sep 17 00:00:00 2001 From: Mohannad Raafat <62453654+para0x0dise@users.noreply.github.com> Date: Thu, 31 Oct 2024 23:57:18 +0300 Subject: [PATCH 3/3] Update misc.py --- modules/signatures/windows/misc.py | 115 ++++++++++++++++++++++++++++- 1 file changed, 113 insertions(+), 2 deletions(-) diff --git a/modules/signatures/windows/misc.py b/modules/signatures/windows/misc.py index 35c2a318..62f34793 100644 --- a/modules/signatures/windows/misc.py +++ b/modules/signatures/windows/misc.py @@ -257,7 +257,7 @@ def __init__(self, *args, **kwargs): self.detected = False def on_call(self, call, process): - if process["process_name"] in ("wscript.exe", "cscript.exe") and call["api"] == "CreateProcessInternalW": + if process["process_name"].lower() in ("wscript.exe", "cscript.exe") and call["api"] == "CreateProcessInternalW": cmdline = self.get_argument(call, "CommandLine") lower = cmdline.lower() if ( @@ -268,4 +268,115 @@ def on_call(self, call, process): self.detected = True def on_complete(self): - return self.detected + if self.detected: + return True + return False + +class AMSIBypassViaCOMRegistry(Signature): + name = "amsi_bypass_via_com_registry" + description = "Attempts to disable the Microsoft Antimalware Scan Interface via registry" + severity = 3 + categories = ["evasion"] + authors = ["@para0x0dise"] + minimum = "0.5" + evented = True + ttps = ["T1562"] + references = [ + "https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_amsi_bypass_via_com_registry_modification.toml", + "https://blog.sonicwall.com/en-us/2023/03/asyncrat-variant-includes-cryptostealer-capabilites/" + ] + + filter_apinames = set(["RegSetValueExA", "RegSetValueExW"]) + + def __init__(self, *args, **kwargs): + Signature.__init__(self, *args, **kwargs) + self.detected = False + + def on_call(self, call, _): + if call["api"] in ("RegSetValueExA", "RegSetValueExW"): + regKeyPath = self.get_argument(call, "FullName").lower() + buf = self.get_argument(call, "Buffer") + if "{fdb00e52-a214-4aa1-8fba-4357bb0072ec}\\inprocserver" in regKeyPath and buf != "amsi.dll": + self.data.append({"Value": buf}) + self.detected = True + + def on_complete(self): + if self.detected: + return True + return False + +class LoadDLLViaControlPanel(Signature): + name = "load_dll_via_control_panel" + description = "Attempt to load malicious DLL when Control Panel is executed" + severity = 3 + categories = ["evasion", "bypass"] + authors = ["@para0x0dise"] + minimum = "0.5" + evented = True + ttps = ["T1218"] + references = [ + "https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_dll_control_panel_items_registry_modification.toml" + ] + + filter_apinames = set(["RegSetValueExA", "RegSetValueExW"]) + + def __init__(self, *args, **kwargs): + Signature.__init__(self, *args, **kwargs) + self.detected = False + self.falseProcess = ( + "svchost.exe", "drvinst.exe", "msiexec.exe" + ) + + def on_call(self, call, process): + if not (process["process_name"].lower in self.falseProcess or + "windows\\system32\\driverstore\\filerepository" in process["module_path"].lower): + + if call["api"] in ("RegSetValueExA", "RegSetValueExW"): + regKeyPath = self.get_argument(call, "FullName").lower() + buf = self.get_argument(call, "Buffer") + type = self.get_argument(call, "Type") + + if any(key in regKeyPath for key in ("software\\microsoft\\windows\\currentversion\\control panel\\cpls","software\\microsoft\\windows\\currentversion\\control panel\\cpls\\")) and not buf != '' and not type != '4': + self.data.append({"regkey": regKeyPath}) + self.detected = True + + def on_complete(self): + if self.detected: + return True + return False + +class DLLHijackingViaWaaSMedicSvcCOMTypeLib(Signature): + name = "dll_hijacking_via_waas_medic_svc_com_typelib" + description = "Attempts to load malicious DLL via WaaSMedicSvc COM TypeLib" + severity = 3 + categories = ["evasion", "persistence"] + authors = ["@para0x0dise"] + minimum = "0.5" + evented = True + ttps = ["T1546"] + references = [ + "https://blog.scrt.ch/2023/03/17/bypassing-ppl-in-userland-again/", + "https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_waasmedicsvc_com_type_lib_hijack.toml" + + ] + + filter_apinames = set(["RegSetValueExA", "RegSetValueExW"]) + + def __init__(self, *args, **kwargs): + Signature.__init__(self, *args, **kwargs) + self.detected = False + + def on_call(self, call, process): + if not "\\Windows\\System32\\svchost.exe" in process["module_name"]: + if call["api"] in ("RegSetValueExA", "RegSetValueExW"): + regKeyPath = self.get_argument(call, "FullName").lower() + buf = self.get_argument(call, "Buffer") + if ("\\software\\classes\\typelib\\{3ff1aab8-f3d8-11d4-825d-00104b3646c0}\\" in regKeyPath and + buf.endswith(".dll")) and not buf.endswith("WaaSMedicPS.dll"): + self.data.append({"Value": buf}) + self.detected = True + + def on_complete(self): + if self.detected: + return True + return False \ No newline at end of file