Skip to content

Commit

Permalink
Merge branch 'master' into pr/464
Browse files Browse the repository at this point in the history
  • Loading branch information
doomedraven committed Oct 29, 2024
2 parents 0d72369 + cae67ad commit 143bcc3
Show file tree
Hide file tree
Showing 11 changed files with 533 additions and 356 deletions.
284 changes: 149 additions & 135 deletions modules/signatures/all/static_pe_anomaly.py

Large diffs are not rendered by default.

35 changes: 19 additions & 16 deletions modules/signatures/windows/bypass_uac.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def __init__(self, *args, **kwargs):
def on_call(self, call, process):
if call["api"].startswith("RegQueryValueEx"):
pname = process["process_name"]
if pname.lower() == "eventvwr.exe":
if process["process_name"].lower() == "eventvwr.exe":
fullname = self.get_argument(call, "FullName")
data = self.get_argument(call, "Data")
if "\classes\mscfile\shell\open\command" in fullname.lower():
Expand Down Expand Up @@ -91,7 +91,7 @@ def run(self):
ret = False

keys = [
".*\\\\Software\\\\Classes\\\\Folder\\\\shell\\\\open\\\\command\\\\DelegateExecute$",
r".*\\Software\\Classes\\Folder\\shell\\open\\command\\DelegateExecute$",
]

for check in keys:
Expand Down Expand Up @@ -157,7 +157,7 @@ def on_call(self, call, process):
self.inf = True

def on_complete(self):
cmdlines = self.results["behavior"]["summary"]["executed_commands"]
cmdlines = self.results.get("behavior", {}).get("summary", {}).get("executed_commands", [])
for cmdline in cmdlines:
lower = cmdline.lower()
if self.inf and "cmstp" in lower and ".inf" in lower:
Expand All @@ -182,7 +182,7 @@ class UACBypassFodhelper(Signature):

def run(self):
ret = False
reg_indicators = ["HKEY_CURRENT_USER\\\\Software\\\\Classes\\\\ms-settings\\\\shell \\\\open\\\\command\\\\*."]
reg_indicators = [r"HKEY_CURRENT_USER\\Software\\Classes\\ms-settings\\shell \\open\\command\\*."]

for indicator in reg_indicators:
match = self.check_write_key(pattern=indicator, regex=True)
Expand All @@ -206,9 +206,9 @@ class UACBypassCMSTPCOM(Signature):
def run(self):
# CMSTPLUA, CMLUAUTIL, Connection Manager LUA Host Object
indicators = [
".*\\\\Windows\\\\(SysWOW64|System32)\\\\DllHost\.exe.*\/Processid:(\{)?3E5FC7F9-9A51-4367-9063-A120244FBEC7(\})?",
".*\\\\Windows\\\\(SysWOW64|System32)\\\\DllHost\.exe.*\/Processid:(\{)?3E000D72-A845-4CD9-BD83-80C07C3B881F(\})?",
".*\\\\Windows\\\\(SysWOW64|System32)\\\\DllHost\.exe.*\/Processid:(\{)?BA126F01-2166-11D1-B1D0-00805FC1270E(\})?",
".*\\Windows\\(SysWOW64|System32)\\DllHost\.exe.*\/Processid:(\{)?3E5FC7F9-9A51-4367-9063-A120244FBEC7(\})?",
".*\\Windows\\(SysWOW64|System32)\\DllHost\.exe.*\/Processid:(\{)?3E000D72-A845-4CD9-BD83-80C07C3B881F(\})?",
".*\\Windows\\(SysWOW64|System32)\\DllHost\.exe.*\/Processid:(\{)?BA126F01-2166-11D1-B1D0-00805FC1270E(\})?",
]

for indicator in indicators:
Expand All @@ -218,6 +218,8 @@ def run(self):
return True

return False


class UACBypassWindowsBackup(Signature):
name = "uac_bypass_windows_Backup"
description = "Attempts to use Windows Backup and Restore (sdclt.exe) to bypass UAC"
Expand All @@ -227,26 +229,27 @@ class UACBypassWindowsBackup(Signature):
minimum = "0.5"
evented = True
ttps = ["T1548", "T1548.002"]
references = ["https://github.com/hfiref0x/UACME",
"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/privilege_escalation_uac_bypass_via_sdclt.toml"]
references = [
"https://github.com/hfiref0x/UACME",
"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/privilege_escalation_uac_bypass_via_sdclt.toml",
]

filter_apinames = set(["CreateProcessInternalW"])

def on_call(self, call, process):
pname = process["process_name"].lower()

# Checking parent process for false positives.
if pname == "sdclt.exe":
if call["api"] == "CreateProcessInternalW":
cmdline = self.get_argument(call, "CommandLine")
lower = cmdline.lower()
if any(process in lower for process in ("control.exe", "werfault.exe", "wermgr.exe", "sdclt.exe")):
return False
if process["process_name"].lower() == "sdclt.exe" and call["api"] == "CreateProcessInternalW":
cmdline = self.get_argument(call, "CommandLine")
lower = cmdline.lower()
if any(process in lower for process in ("control.exe", "werfault.exe", "wermgr.exe", "sdclt.exe")):
return False

def on_complete(self):
cmdlines = self.results.get("behavior", {}).get("summary", {}).get("executed_commands")
for cmdline in cmdlines:
lower = cmdline.lower()
if "sdclt.exe" in lower and "/kickoffelev" in lower:
return True
return False
return False
9 changes: 5 additions & 4 deletions modules/signatures/windows/credential_access.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ def run(self):

return ret


class AccessWindowsPasswordsVault(Signature):
name = "access_windows_passwords_vault"
description = "Attempts to access Vault passwords via PowerShell"
Expand All @@ -95,7 +96,8 @@ class AccessWindowsPasswordsVault(Signature):
evented = True
ttps = ["T1059"]
references = [
"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/credential_access_access_to_windows_passwords_vault_via_powershell.toml"]
"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/credential_access_access_to_windows_passwords_vault_via_powershell.toml"
]

filter_apinames = set(["CreateProcessInternalW"])

Expand All @@ -111,9 +113,8 @@ def on_call(self, call, process):
return False

def on_complete(self):
cmdlines = self.results.get("behavior", {}).get("summary", {}).get("executed_commands")
for cmdline in cmdlines:
for cmdline in self.results.get("behavior", {}).get("summary", {}).get("executed_commands", []):
lower = cmdline.lower()
if "powershell" in lower and any(arg in lower for arg in ("passwordvault", "retrievepassword", "retrieveall")):
return True
return False
return False
88 changes: 53 additions & 35 deletions modules/signatures/windows/credential_dumping.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,10 @@ class RegistryCredentialStoreAccess(Signature):

def run(self):
ret = False
reg_indicators = [
"HKEY_LOCAL_MACHINE\\\\SAM$",
"HKEY_LOCAL_MACHINE\\\\SYSTEM$",
]
reg_indicators = (
r"HKEY_LOCAL_MACHINE\\SAM$",
r"HKEY_LOCAL_MACHINE\\SYSTEM$",
)

for indicator in reg_indicators:
match = self.check_key(pattern=indicator, regex=True)
Expand All @@ -147,9 +147,7 @@ class RegistryLSASecretsAccess(Signature):
mbcs = ["OB0005"]

def run(self):
indicators = [
"HKEY_LOCAL_MACHINE\\\\SECURITY\\\\Policy\\\\Secrets$",
]
indicators = (r"HKEY_LOCAL_MACHINE\\SECURITY\\Policy\\Secrets$",)

for indicator in indicators:
match = self.check_key(pattern=indicator, regex=True)
Expand All @@ -173,11 +171,11 @@ class FileCredentialStoreAccess(Signature):
mbcs = ["OB0005"]

def run(self):
indicators = [
".*\\\\Windows\\\\repair\\\\sam",
".*\\\\Windows\\\\System32\\\\config\\\\RegBack\\\\SAM",
".*\\\\Windows\\\\system32\\\\config\\\\SAM",
]
indicators = (
r".*\\Windows\\repair\\sam",
r".*\\Windows\\System32\\config\\RegBack\\SAM",
r".*\\Windows\\system32\\config\\SAM",
)

for indicator in indicators:
match = self.check_file(pattern=indicator, regex=True)
Expand All @@ -201,11 +199,11 @@ class FileCredentialStoreWrite(Signature):
mbcs = ["OB0005"]

def run(self):
indicators = [
".*\\\\Windows\\\\repair\\\\sam",
".*\\\\Windows\\\\System32\\\\config\\\\RegBack\\\\SAM",
".*\\\\Windows\\\\system32\\\\config\\\\SAM",
]
indicators = (
r".*\\Windows\\repair\\sam",
r".*\\Windows\\System32\\config\\RegBack\\SAM",
r".*\\Windows\\system32\\config\\SAM",
)

for indicator in indicators:
match = self.check_write_file(pattern=indicator, regex=True)
Expand All @@ -215,6 +213,7 @@ def run(self):

return False


class DumpLSAViaWindowsErrorReporting(Signature):
name = "dump_lsa_via_windows_error_reporting"
description = "Attempts to create LSASS crash dump via Windows Error Reporting process"
Expand All @@ -225,19 +224,18 @@ class DumpLSAViaWindowsErrorReporting(Signature):
evented = True
ttps = ["T1003"]
references = [
"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/credential_access_lsa_dump_via_windows_error_reporting.toml"]
"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/credential_access_lsa_dump_via_windows_error_reporting.toml"
]

filter_apinames = set(["NtCreateFile"])

def on_call(self, call, process):
pname = process["process_name"].lower()

# Checking parent process for false positives.
if pname in ["WerFaultSecure.exe", "WerFault.exe"]:
if call["api"] == "NtCreateFile":
filename = self.get_argument(call, "FileName")
if filename.endswith(".dmp") and "lsass_" in filename:
return True
if process["process_name"].lower() in ("WerFaultSecure.exe", "WerFault.exe") and call["api"] == "NtCreateFile":
filename = self.get_argument(call, "FileName")
if filename.endswith(".dmp") and "lsass_" in filename:
return True


class KerberosCredentialAccessViaRubeus(Signature):
name = "kerberos_credential_access_via_rubeus"
Expand All @@ -249,17 +247,37 @@ class KerberosCredentialAccessViaRubeus(Signature):
evented = True
ttps = ["T1003"]
references = [
"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/credential_access_potential_credential_access_via_rubeus.toml"]
"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/credential_access_potential_credential_access_via_rubeus.toml"
]

def run(self):
cmdlines = self.results.get("behavior", {}).get("summary", {}).get("executed_commands")
for cmdline in cmdlines:
for cmdline in self.results.get("behavior", {}).get("summary", {}).get("executed_commands", []):
lower = cmdline.lower()
if "rebeus" in lower and any(arg in lower for arg in ("asreproast", "dump /service:krbtgt", "dump /luid",
"kerberoast", "createnetonly /program", "ptt /ticket",
"/impersonateuser", "renew /ticket", "asktgt /user",
"asktgs /ticket", "harvest /interval", "s4u /user",
"s4u /ticket", "hash /password", "tgtdeleg", "tgtdeleg /target",
"golden /des", "golden /rc4", "golden /aes128", "golden /aes256", "changpw /ticket")):
if "rebeus" in lower and any(
arg in lower
for arg in (
"asreproast",
"dump /service:krbtgt",
"dump /luid",
"kerberoast",
"createnetonly /program",
"ptt /ticket",
"/impersonateuser",
"renew /ticket",
"asktgt /user",
"asktgs /ticket",
"harvest /interval",
"s4u /user",
"s4u /ticket",
"hash /password",
"tgtdeleg",
"tgtdeleg /target",
"golden /des",
"golden /rc4",
"golden /aes128",
"golden /aes256",
"changpw /ticket",
)
):
return True
return False
return False
24 changes: 18 additions & 6 deletions modules/signatures/windows/deletes_consolehost_history.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,31 @@ class DeletesExecutedFiles(Signature):
authors = ["@para0x0dise"]
minimum = "1.2"
ttps = ["T1070.003"]
references = ["https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_suspicious_powershell_console_history_deletion.toml"]
references = [
"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_suspicious_powershell_console_history_deletion.toml"
]
evented = True

filter_apinames = set(["NtDeleteFile", "DeleteFileA", "DeleteFileW"])

def __init__(self, *args, **kwargs):
Signature.__init__(self, *args, **kwargs)
self.isDeleted = False
self.blacklistedApps = ["powershell.exe", "rundll32.exe", "regsvr32.exe", "cmd.exe", "wscript.exe",
"cscript.exe", "mshta.exe", "winword.exe", "excel.exe"]
self.blacklistedApps = (
"powershell.exe",
"rundll32.exe",
"regsvr32.exe",
"cmd.exe",
"wscript.exe",
"cscript.exe",
"mshta.exe",
"winword.exe",
"excel.exe",
)
self.blacklistedPaths = ["\\users\\", "\\windows\\temp\\", "\\programdata\\", "\\windows\\microsoft.net\\"]

def on_call(self, call, process):
if call["api"] == "NtDeleteFile" or call["api"] == "DeleteFileA" or call["api"] == "DeleteFileW":
if call["api"] in ("NtDeleteFile", "DeleteFileA", "DeleteFileW"):
if "ConsoleHost_history.txt" in self.get_argument(call, "FileName"):
self.isDeleted = True
if self.pid:
Expand All @@ -32,7 +44,7 @@ def on_complete(self):

# Verify True Positives
if self.isDeleted:
for proc in self.results.get("behavior", {}).get("processtree"):
for proc in self.results.get("behavior", {}).get("processtree", []):
if proc.get("name") in self.blacklistedApps or proc["module_path"].lower() in self.blacklistedPaths:
return True
return False
return False
22 changes: 13 additions & 9 deletions modules/signatures/windows/exploit_spooler.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ def run(self):
]

ret = False
cmdlines = self.results["behavior"]["summary"]["executed_commands"]
for cmdline in cmdlines:
for cmdline in self.results.get("behavior", {}).get("summary", {}).get("executed_commands", []):
lower = cmdline.lower()
for spool in spooler:
if spool in lower:
Expand All @@ -53,7 +52,7 @@ class SpoolerAccess(Signature):

def run(self):
indicators = [
".*\\\\Windows\\\\System32\\\\spool\\\\.*",
r".*\\Windows\\System32\\spool\\.*",
]

for indicator in indicators:
Expand All @@ -64,6 +63,7 @@ def run(self):

return False


class EscalatePrivilegeViaNTLMRelay(Signature):
name = "escalate_privilege_via_ntlm_relay"
description = "Attempts to coerce a local NTLM authentication via HTTP using Printer Spooler service as a target"
Expand All @@ -72,15 +72,19 @@ class EscalatePrivilegeViaNTLMRelay(Signature):
authors = ["@para0x0dise"]
minimum = "1.2"
ttps = ["T1068"]
references = ["https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/privilege_escalation_privilege_escalation_via_ntlmrelay2self.toml"]
references = [
"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/privilege_escalation_privilege_escalation_via_ntlmrelay2self.toml"
]
evented = True

def run(self):
cmdlines = self.results.get("behavior", {}).get("summary", {}).get("executed_commands")
for cmdline in cmdlines:
for cmdline in self.results.get("behavior", {}).get("summary", {}).get("executed_commands", []):
lower = cmdline.lower()

if ("rundll32.exe" in lower and "davclnt.dll,davsetcookie" in lower
and any(arg in lower for arg in ("/print/pipe/", "/pipe/spoolss", "/pipe/srvsvc"))):
if (
"rundll32.exe" in lower
and any(arg in lower for arg in ("davclnt.dll,davsetcookie"))
and any(arg in lower for arg in ("/print/pipe/", "/pipe/spoolss", "/pipe/srvsvc"))
):
return True
return False
return False
Loading

0 comments on commit 143bcc3

Please sign in to comment.