From 2491cd39f0fbd5fd4d63df2bc3ecf05ee608b284 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Fri, 24 Mar 2023 16:38:28 +0100 Subject: [PATCH 001/145] windows_util and encrypted_ioc changes to whitelisting for false positives --- modules/signatures/encrypted_ioc.py | 1 + modules/signatures/windows_utilities.py | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/modules/signatures/encrypted_ioc.py b/modules/signatures/encrypted_ioc.py index dc0470e9..36bee9c3 100644 --- a/modules/signatures/encrypted_ioc.py +++ b/modules/signatures/encrypted_ioc.py @@ -51,6 +51,7 @@ def on_complete(self): "v1.1.4322", "v2.0.50727", "v4.0.30319", + "x10www.digicert.com1", ] dedup = list() extracted_data = False diff --git a/modules/signatures/windows_utilities.py b/modules/signatures/windows_utilities.py index b50ce1f8..1d4def9d 100644 --- a/modules/signatures/windows_utilities.py +++ b/modules/signatures/windows_utilities.py @@ -3,7 +3,7 @@ # See the file 'docs/LICENSE' for copying permission. from lib.cuckoo.common.abstracts import Signature - +import re class UsesWindowsUtilitiesScheduler(Signature): name = "uses_windows_utilities_to_create_scheduled_task" @@ -19,20 +19,26 @@ class UsesWindowsUtilitiesScheduler(Signature): def run(self): utilities = [ - "at ", "at.exe", "schtasks", + "schtasks.exe" + "at" + ] + + whitelist = [ + r"Acrobat DC", ] ret = False cmdlines = self.results["behavior"]["summary"]["executed_commands"] for cmdline in cmdlines: lower = cmdline.lower() - for utility in utilities: - if utility in lower: - self.ttps += ["T1053.005"] if utility == "schtasks" else ["T1053.002"] # MITRE v7,8 - ret = True - self.data.append({"command": cmdline}) + for utility_regex in utilities: + if re.search(utility_regex, lower): + if not any(re.search(whitelist_regex, cmdline) for whitelist_regex in whitelist): + self.ttps += ["T1053.005"] if utility_regex == "schtasks" else ["T1053.002"] # MITRE v7,8 + ret = True + self.data.append({"command": cmdline}) return ret From 681b8fe87994b2f365683980a574ace17eeaeff8 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Fri, 24 Mar 2023 16:47:12 +0100 Subject: [PATCH 002/145] import re2 or re --- modules/signatures/windows_utilities.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/signatures/windows_utilities.py b/modules/signatures/windows_utilities.py index 1d4def9d..4306b5f0 100644 --- a/modules/signatures/windows_utilities.py +++ b/modules/signatures/windows_utilities.py @@ -1,9 +1,12 @@ # Copyright (C) 2010-2015 Cuckoo Foundation. # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org # See the file 'docs/LICENSE' for copying permission. +try: + import re2 as re +except ImportError: + import re from lib.cuckoo.common.abstracts import Signature -import re class UsesWindowsUtilitiesScheduler(Signature): name = "uses_windows_utilities_to_create_scheduled_task" From 20a94515106c5d074fd815e4f923273afef5be95 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Fri, 24 Mar 2023 16:54:51 +0100 Subject: [PATCH 003/145] typo in utilities, windows_utilties --- modules/signatures/windows_utilities.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/signatures/windows_utilities.py b/modules/signatures/windows_utilities.py index 4306b5f0..e5a497f5 100644 --- a/modules/signatures/windows_utilities.py +++ b/modules/signatures/windows_utilities.py @@ -24,8 +24,8 @@ def run(self): utilities = [ "at.exe", "schtasks", - "schtasks.exe" - "at" + "schtasks.exe", + "at ", ] whitelist = [ From 4bcae8642e08b2793304dadd6a632bdf2e79fdff Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Fri, 24 Mar 2023 17:12:20 +0100 Subject: [PATCH 004/145] added whitelist for Internet Explorer since this is not a suspicious command --- modules/signatures/windows_utilities.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/modules/signatures/windows_utilities.py b/modules/signatures/windows_utilities.py index e5a497f5..8f92726b 100644 --- a/modules/signatures/windows_utilities.py +++ b/modules/signatures/windows_utilities.py @@ -193,14 +193,19 @@ def run(self): "xcacls", ] + whitelist = [ + r"Internet Explorer", + ] + ret = False cmdlines = self.results["behavior"]["summary"]["executed_commands"] for cmdline in cmdlines: lower = cmdline.lower() - for utility in utilities: - if utility in lower: - ret = True - self.data.append({"command": cmdline}) + for utility_regex in utilities: + if re.search(utility_regex, lower): + if not any(re.search(whitelist_regex, cmdline) for whitelist_regex in whitelist): + ret = True + self.data.append({"command": cmdline}) return ret From 261453ff5f35bc3b9278e60b73e9f36a5118ef64 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Fri, 24 Mar 2023 17:19:32 +0100 Subject: [PATCH 005/145] added whitelist for Internet Explorer since this is not a suspicious command --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 9bea4330..e075e3fe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ - +test.py .DS_Store From 54bc8abd23ef120c7fcbd91a3f5cbc51fd7024a9 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Fri, 24 Mar 2023 17:37:05 +0100 Subject: [PATCH 006/145] fixed typos in windows_utilities, removed false positives --- modules/signatures/windows_utilities.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/modules/signatures/windows_utilities.py b/modules/signatures/windows_utilities.py index 8f92726b..b132ccea 100644 --- a/modules/signatures/windows_utilities.py +++ b/modules/signatures/windows_utilities.py @@ -83,7 +83,8 @@ def run(self): "netstat", "nslookup", "ping", - "powercfg" "qprocess", + "powercfg", + "qprocess", "query ", "query.exe", "quser", @@ -115,15 +116,18 @@ def run(self): "wmic", "wusa", ] - + whitelist = [ + r"Internet Explorer", + ] ret = False cmdlines = self.results["behavior"]["summary"]["executed_commands"] for cmdline in cmdlines: lower = cmdline.lower() for utility in utilities: - if utility in lower and "-" + utility not in lower: - ret = True - self.data.append({"command": cmdline}) + if re.search(utility, lower): + if utility in lower and "-" + utility not in lower and not any(re.search(whitelist_regex, cmdline) for whitelist_regex in whitelist): + ret = True + self.data.append({"command": cmdline}) return ret From 7b5c57285ed77ba003b7db853bc66fa27b6b2c04 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 29 Mar 2023 14:44:22 +0200 Subject: [PATCH 007/145] test signatures based on strings --- .../credential_access_phishingkit.py | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 modules/signatures/credential_access_phishingkit.py diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py new file mode 100644 index 00000000..bc6c81d1 --- /dev/null +++ b/modules/signatures/credential_access_phishingkit.py @@ -0,0 +1,40 @@ +# Copyright (C) 2023 Eye Security (yasin.tas@eye.security) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from lib.cuckoo.common.abstracts import Signature + +class PhishingKit(Signature): + name = "Phishing_kit_detected" + description = "Phishing Kit Detected, sample is trying to harvest credentials" + severity = 3 + confidence = 100 + weight = 3 + categories = ["credential_access","evasion","infostealer","phishing", "static"] + families = ["PhishingKit"] + authors = ["Yasin Tas", "Eye Security"] + enabled = True + minimum = "1.2" + ttps = ["T1111", "T1193", "T1140"] # MITRE v6 + ttps += ["T1566.001"] # MITRE v6,7,8 + ttps += ["T1606"] # MITRE v7,8 + mbcs = ["C0029.003"] # micro-behaviour + + evented = True + + def run(self): + found_sig = False + if "strings" in self.results: + found_sig = True + return found_sig \ No newline at end of file From 6e7c0ae2152c19cf762ba17a934eb6b2ecae29ff Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Thu, 30 Mar 2023 11:21:18 +0200 Subject: [PATCH 008/145] added phishingkit rule for one type of phishing kit --- .../credential_access_phishingkit.py | 50 ++++++++++++++++--- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index bc6c81d1..9d9a43c8 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -15,12 +15,18 @@ from lib.cuckoo.common.abstracts import Signature +try: + import re2 as re +except ImportError: + import re + +import base64 + class PhishingKit(Signature): - name = "Phishing_kit_detected" + name = "phishing_kit_detected" description = "Phishing Kit Detected, sample is trying to harvest credentials" severity = 3 confidence = 100 - weight = 3 categories = ["credential_access","evasion","infostealer","phishing", "static"] families = ["PhishingKit"] authors = ["Yasin Tas", "Eye Security"] @@ -31,10 +37,40 @@ class PhishingKit(Signature): ttps += ["T1606"] # MITRE v7,8 mbcs = ["C0029.003"] # micro-behaviour - evented = True + def run(self): + + if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": + data = self.results['target']['file']['data'] + regex_base64 = r'value="([^&]+?)">' + decodeString = re.findall(regex_base64,str(data)) + if decodeString: + decoded_url = base64.b64decode(decodeString[0]) + self.data.append({"decoded_url": decoded_url}) + decoded_user = base64.b64decode(decodeString[1]) + self.data.append({"decoded_user": decoded_user}) + return True + + return False + +class JSAtob(Signature): + name = "JS_atob_detected" + description = "JS atob Detected, file is obfuscated" + severity = 2 + confidence = 70 + categories = ["evasion","phishing", "static"] + families = ["PhishingKit"] + authors = ["Yasin Tas", "Eye Security"] + enabled = True + minimum = "1.2" + ttps = ["T1140"] # MITRE v6 + ttps += ["T1566.001"] # MITRE v6,7,8 + mbcs = ["C0029.003"] # micro-behaviour def run(self): - found_sig = False - if "strings" in self.results: - found_sig = True - return found_sig \ No newline at end of file + if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": + data = self.results['target']['file']['data'] + if "atob" in data: + return True + + return False + From 564834cfa71abbc7f2e33fb6eb298d778d647ab9 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Thu, 30 Mar 2023 11:27:09 +0200 Subject: [PATCH 009/145] added phishingkit rule for one type of phishing kit --- modules/signatures/credential_access_phishingkit.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index 9d9a43c8..d44f9724 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -19,7 +19,7 @@ import re2 as re except ImportError: import re - + import base64 class PhishingKit(Signature): @@ -44,11 +44,14 @@ def run(self): regex_base64 = r'value="([^&]+?)">' decodeString = re.findall(regex_base64,str(data)) if decodeString: + self.weight = 1 decoded_url = base64.b64decode(decodeString[0]) self.data.append({"decoded_url": decoded_url}) decoded_user = base64.b64decode(decodeString[1]) self.data.append({"decoded_user": decoded_user}) - return True + if decoded_url and decoded_user: + self.weight = 2 + return True return False @@ -69,7 +72,7 @@ class JSAtob(Signature): def run(self): if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": data = self.results['target']['file']['data'] - if "atob" in data: + if "atob" in data: return True return False From 3dad853ba3c204d87eb736b0b5bca2a042b09dec Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Thu, 30 Mar 2023 11:28:06 +0200 Subject: [PATCH 010/145] added phishingkit rule for one type of phishing kit --- modules/signatures/credential_access_phishingkit.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index d44f9724..a6e9aa41 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -52,6 +52,8 @@ def run(self): if decoded_url and decoded_user: self.weight = 2 return True + else: + return True return False From 1a1a4ff7e7fcde6b646f8fe2f5df0dc2deeb178d Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Fri, 31 Mar 2023 02:48:42 +0200 Subject: [PATCH 011/145] Added second phishing kit detection --- .../credential_access_phishingkit.py | 80 ++++++++++++++++++- 1 file changed, 77 insertions(+), 3 deletions(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index a6e9aa41..e7bcd435 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -20,15 +20,19 @@ except ImportError: import re +try: + from chepy import Chepy +except ImportError: + raise ImportError("Please install chepy") + import base64 -class PhishingKit(Signature): +class PhishingKit0(Signature): name = "phishing_kit_detected" description = "Phishing Kit Detected, sample is trying to harvest credentials" severity = 3 confidence = 100 categories = ["credential_access","evasion","infostealer","phishing", "static"] - families = ["PhishingKit"] authors = ["Yasin Tas", "Eye Security"] enabled = True minimum = "1.2" @@ -51,6 +55,8 @@ def run(self): self.data.append({"decoded_user": decoded_user}) if decoded_url and decoded_user: self.weight = 2 + self.description = "Phishing kit detected, extracted config from sample" + self.families = ["PhishingKit"] return True else: return True @@ -63,7 +69,6 @@ class JSAtob(Signature): severity = 2 confidence = 70 categories = ["evasion","phishing", "static"] - families = ["PhishingKit"] authors = ["Yasin Tas", "Eye Security"] enabled = True minimum = "1.2" @@ -79,3 +84,72 @@ def run(self): return False +class URLDecode(Signature): + name = "JS_decode_detected" + description = "JS decode Detected, file is obfuscated" + severity = 2 + confidence = 70 + categories = ["evasion","phishing", "static"] + authors = ["Yasin Tas", "Eye Security"] + enabled = True + minimum = "1.2" + ttps = ["T1140"] # MITRE v6 + ttps += ["T1566.001"] # MITRE v6,7,8 + mbcs = ["C0029.003"] # micro-behaviour + + def run(self): + if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": + data = self.results['target']['file']['data'] + if "decodeURIComponent" in data: + return True + + return False + +class PhishingKit1(Signature): + name = "phishing_kit_detected" + description = "Phishing Kit Detected, sample is trying to harvest credentials" + severity = 3 + confidence = 100 + categories = ["credential_access","evasion","infostealer","phishing", "static"] + authors = ["Yasin Tas", "Eye Security"] + enabled = True + minimum = "1.2" + ttps = ["T1111", "T1193", "T1140"] # MITRE v6 + ttps += ["T1566.001"] # MITRE v6,7,8 + ttps += ["T1606"] # MITRE v7,8 + mbcs = ["C0029.003"] # micro-behaviour + + def run(self): + if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": + data = self.results['target']['file']['data'] + regex_decodedURL = r"unescape( '([^&]+?)' ) );" + decodeString = re.search(regex_decodedURL,str(data)) + if decodeString: + self.weight = 1 + decoded_string = Chepy(decodeString).url_decode() + self.description = "File obfuscation detected with url decode" + if "atob" in decoded_string: + self.weight += 1 + self.description = "File obfuscation detected with url decode and atob" + if "encoded_string" in decoded_string: + self.weight += 1 + self.description = "File obfuscation detected with url decode, atob and encoded_string" + if "encoded_string" in decoded_string and "atob" in decoded_string: + self.weight = 3 + self.families = ["PhishingKit"] + user_regex = r"var encoded_string = '([^&]+?)';" + url_regex = r"window.atob('([^&]+?)')" + aws_regex = r"window.location.href=\"([^&]+?)\"" + user = re.search(user_regex,decoded_string) + url = re.search(url_regex,decoded_string) + aws = re.search(aws_regex,decoded_string) + if user and url and aws: + self.description = "Phishing kit detected, extracted config from sample" + self.data.append({"decoded_url": base64.b64decode(url)}) + self.data.append({"decoded_user": base64.b64decode(user)}) + self.data.append({"aws_url": aws}) + return True + return True + return False + + From 4fe95ac3d2d9e2db022cdbba87e148756e5e41c9 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Fri, 31 Mar 2023 03:06:36 +0200 Subject: [PATCH 012/145] Added third phishing kit detections and config extractor, made seperate files for suspicious signatures --- .../credential_access_phishingkit.py | 74 ++++++++----------- 1 file changed, 29 insertions(+), 45 deletions(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index e7bcd435..b16245ac 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -28,7 +28,7 @@ import base64 class PhishingKit0(Signature): - name = "phishing_kit_detected" + name = "phishing0_kit_detected" description = "Phishing Kit Detected, sample is trying to harvest credentials" severity = 3 confidence = 100 @@ -63,50 +63,8 @@ def run(self): return False -class JSAtob(Signature): - name = "JS_atob_detected" - description = "JS atob Detected, file is obfuscated" - severity = 2 - confidence = 70 - categories = ["evasion","phishing", "static"] - authors = ["Yasin Tas", "Eye Security"] - enabled = True - minimum = "1.2" - ttps = ["T1140"] # MITRE v6 - ttps += ["T1566.001"] # MITRE v6,7,8 - mbcs = ["C0029.003"] # micro-behaviour - - def run(self): - if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": - data = self.results['target']['file']['data'] - if "atob" in data: - return True - - return False - -class URLDecode(Signature): - name = "JS_decode_detected" - description = "JS decode Detected, file is obfuscated" - severity = 2 - confidence = 70 - categories = ["evasion","phishing", "static"] - authors = ["Yasin Tas", "Eye Security"] - enabled = True - minimum = "1.2" - ttps = ["T1140"] # MITRE v6 - ttps += ["T1566.001"] # MITRE v6,7,8 - mbcs = ["C0029.003"] # micro-behaviour - - def run(self): - if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": - data = self.results['target']['file']['data'] - if "decodeURIComponent" in data: - return True - - return False - class PhishingKit1(Signature): - name = "phishing_kit_detected" + name = "phishing1_kit_detected" description = "Phishing Kit Detected, sample is trying to harvest credentials" severity = 3 confidence = 100 @@ -152,4 +110,30 @@ def run(self): return True return False - +class PhishingKit2(Signature): + name = "phishing2_kit_detected" + description = "Phishing Kit Detected, sample is trying to harvest credentials" + severity = 3 + confidence = 100 + categories = ["credential_access","infostealer","phishing", "static"] + authors = ["Yasin Tas", "Eye Security"] + enabled = True + minimum = "1.2" + ttps = ["T1111", "T1193", "T1140"] # MITRE v6 + ttps += ["T1566.001"] # MITRE v6,7,8 + ttps += ["T1606"] # MITRE v7,8 + + def run(self): + if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": + data = self.results['target']['file']['data'] + url_regex = r"
" + user_regex = r" Date: Fri, 31 Mar 2023 09:47:04 +0200 Subject: [PATCH 013/145] changed windows utilies with helpers --- modules/signatures/windows_utilities.py | 32 ++++++++----------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/modules/signatures/windows_utilities.py b/modules/signatures/windows_utilities.py index b132ccea..7bbde191 100644 --- a/modules/signatures/windows_utilities.py +++ b/modules/signatures/windows_utilities.py @@ -20,31 +20,19 @@ class UsesWindowsUtilitiesScheduler(Signature): evented = True - def run(self): - utilities = [ + filter_processnames = set([ + "at ", "at.exe", "schtasks", "schtasks.exe", - "at ", - ] - - whitelist = [ - r"Acrobat DC", - ] - - ret = False - cmdlines = self.results["behavior"]["summary"]["executed_commands"] - for cmdline in cmdlines: - lower = cmdline.lower() - for utility_regex in utilities: - if re.search(utility_regex, lower): - if not any(re.search(whitelist_regex, cmdline) for whitelist_regex in whitelist): - self.ttps += ["T1053.005"] if utility_regex == "schtasks" else ["T1053.002"] # MITRE v7,8 - ret = True - self.data.append({"command": cmdline}) - - return ret - + ]) + + def on_call(self, call, process): + if process["process_name"].lower() in self.filter_processnames: + self.ttps += ["T1053.005"] if process["process_name"].lower() == "schtasks" else ["T1053.002"] # MITRE v7,8 + ret = True + self.data.append({"command": process["command_line"]}) + return ret class UsesWindowsUtilities(Signature): name = "uses_windows_utilities" From 38c38ee0b118ff420f82e4d4c3ed697959eb1155 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Fri, 31 Mar 2023 10:45:34 +0200 Subject: [PATCH 014/145] Improved regex to extract config out of phishing kits --- .../credential_access_phishingkit.py | 19 ++++++++++--------- modules/signatures/windows_utilities.py | 2 +- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index b16245ac..48409c67 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -80,8 +80,8 @@ class PhishingKit1(Signature): def run(self): if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": data = self.results['target']['file']['data'] - regex_decodedURL = r"unescape( '([^&]+?)' ) );" - decodeString = re.search(regex_decodedURL,str(data)) + regex_decodedURL = r"unescape\( \'([^&]+?)\' \) \);" + decodeString = re.search(regex_decodedURL,str(data)).group(0) if decodeString: self.weight = 1 decoded_string = Chepy(decodeString).url_decode() @@ -95,16 +95,17 @@ def run(self): if "encoded_string" in decoded_string and "atob" in decoded_string: self.weight = 3 self.families = ["PhishingKit"] - user_regex = r"var encoded_string = '([^&]+?)';" - url_regex = r"window.atob('([^&]+?)')" - aws_regex = r"window.location.href=\"([^&]+?)\"" - user = re.search(user_regex,decoded_string) - url = re.search(url_regex,decoded_string) - aws = re.search(aws_regex,decoded_string) + user_regex = r"var encoded_string = \"([^&]+?)\";" + url_regex = r"window.atob\(\'([^&]+?)\'\)" + #this regex can be improved + aws_regex = r'window.location.href="([Hh][Tt][Tt][Pp][Ss]?://(.*)+?)' + user = re.search(user_regex,decoded_string).group(1) + url = re.search(url_regex,decoded_string).group(1) + aws = re.search(aws_regex,decoded_string).group(0).replace("window.location.href=\"","") if user and url and aws: self.description = "Phishing kit detected, extracted config from sample" self.data.append({"decoded_url": base64.b64decode(url)}) - self.data.append({"decoded_user": base64.b64decode(user)}) + self.data.append({"decoded_user": user}) self.data.append({"aws_url": aws}) return True return True diff --git a/modules/signatures/windows_utilities.py b/modules/signatures/windows_utilities.py index 7bbde191..fb88412d 100644 --- a/modules/signatures/windows_utilities.py +++ b/modules/signatures/windows_utilities.py @@ -27,7 +27,7 @@ class UsesWindowsUtilitiesScheduler(Signature): "schtasks.exe", ]) - def on_call(self, call, process): + def on_call(self, _, process): if process["process_name"].lower() in self.filter_processnames: self.ttps += ["T1053.005"] if process["process_name"].lower() == "schtasks" else ["T1053.002"] # MITRE v7,8 ret = True From 8fd9c96346bbfaa964612ce7228cf2b5c91d00c2 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Fri, 31 Mar 2023 10:51:57 +0200 Subject: [PATCH 015/145] renamed phishing kits so its easier to remember them --- modules/signatures/credential_access_phishingkit.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index 48409c67..20fd3750 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -56,7 +56,7 @@ def run(self): if decoded_url and decoded_user: self.weight = 2 self.description = "Phishing kit detected, extracted config from sample" - self.families = ["PhishingKit"] + self.families = ["PhishingKit-0"] return True else: return True @@ -91,10 +91,10 @@ def run(self): self.description = "File obfuscation detected with url decode and atob" if "encoded_string" in decoded_string: self.weight += 1 - self.description = "File obfuscation detected with url decode, atob and encoded_string" + self.description = "File obfuscation detected with url decode and found encoded_string" if "encoded_string" in decoded_string and "atob" in decoded_string: self.weight = 3 - self.families = ["PhishingKit"] + self.families = ["PhishingKit-1"] user_regex = r"var encoded_string = \"([^&]+?)\";" url_regex = r"window.atob\(\'([^&]+?)\'\)" #this regex can be improved @@ -134,7 +134,7 @@ def run(self): if url and user: self.weight = 1 self.description = "Phishing kit detected, extracted config from sample" - self.families = ["PhishingKit"] + self.families = ["PhishingKit-2"] self.data.append({"url": url}) self.data.append({"user": user}) return True \ No newline at end of file From 8023bc3e9cb222f0e9e2ce459043c67da727b5fc Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Fri, 31 Mar 2023 11:45:24 +0200 Subject: [PATCH 016/145] Changed windows utitilies schtask whenever the process schtasks is called. --- modules/signatures/windows_utilities.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/modules/signatures/windows_utilities.py b/modules/signatures/windows_utilities.py index fb88412d..cc4b8882 100644 --- a/modules/signatures/windows_utilities.py +++ b/modules/signatures/windows_utilities.py @@ -21,18 +21,21 @@ class UsesWindowsUtilitiesScheduler(Signature): evented = True filter_processnames = set([ - "at ", - "at.exe", - "schtasks", - "schtasks.exe", - ]) - + "at ", + "at.exe", + "schtasks", + "schtasks.exe", + ]) + def on_call(self, _, process): if process["process_name"].lower() in self.filter_processnames: self.ttps += ["T1053.005"] if process["process_name"].lower() == "schtasks" else ["T1053.002"] # MITRE v7,8 - ret = True - self.data.append({"command": process["command_line"]}) - return ret + cmdlines = self.results["behavior"]["summary"]["executed_commands"] + for cmdline in cmdlines: + lower = cmdline.lower() + if re.search(process["process_name"].lower(), lower): + self.data.append({"command": cmdline}) + return True class UsesWindowsUtilities(Signature): name = "uses_windows_utilities" From 0f429e3c917709072878358be8ff8c58e5654752 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Fri, 31 Mar 2023 12:07:57 +0200 Subject: [PATCH 017/145] small improvements to HTML obfuscations --- modules/signatures/html_obfuscation_static.py | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 modules/signatures/html_obfuscation_static.py diff --git a/modules/signatures/html_obfuscation_static.py b/modules/signatures/html_obfuscation_static.py new file mode 100644 index 00000000..35fe94d1 --- /dev/null +++ b/modules/signatures/html_obfuscation_static.py @@ -0,0 +1,55 @@ +# Copyright (C) 2023 Eye Security (yasin.tas@eye.security) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from lib.cuckoo.common.abstracts import Signature + +class JSAtob(Signature): + name = "JS_atob_detected" + description = "JS atob Detected, file is obfuscated" + severity = 2 + confidence = 70 + categories = ["evasion","phishing", "static"] + authors = ["Yasin Tas", "Eye Security"] + enabled = True + minimum = "1.2" + ttps = ["T1140"] # MITRE v6 + ttps += ["T1566.001"] # MITRE v6,7,8 + mbcs = ["C0029.003"] # micro-behaviour + + def run(self): + if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": + data = self.results['target']['file']['data'] + if "atob" in data: + return True + +class URLDecode(Signature): + name = "JS_decode_detected" + description = "JS decode Detected, file is obfuscated" + severity = 2 + confidence = 70 + categories = ["evasion","phishing", "static"] + authors = ["Yasin Tas", "Eye Security"] + enabled = True + minimum = "1.2" + ttps = ["T1140"] # MITRE v6 + ttps += ["T1566.001"] # MITRE v6,7,8 + mbcs = ["C0029.003"] # micro-behaviour + + def run(self): + if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": + data = self.results['target']['file']['data'] + if "decodeURIComponent" in data: + return True + From 463dd7658037f7a55331347b46be4cd12f4340db Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Fri, 31 Mar 2023 13:22:14 +0200 Subject: [PATCH 018/145] Changed HTML confidence --- .../credential_access_phishingkit.py | 20 ++++++++++++++++++- modules/signatures/html_obfuscation_static.py | 3 ++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index 20fd3750..2c653ed4 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -137,4 +137,22 @@ def run(self): self.families = ["PhishingKit-2"] self.data.append({"url": url}) self.data.append({"user": user}) - return True \ No newline at end of file + return True + +class PhishingKit3(Signature): + name = "phishing2_kit_detected" + description = "Phishing Kit Detected, sample is trying to harvest credentials" + severity = 3 + confidence = 100 + categories = ["credential_access","infostealer","phishing", "static"] + authors = ["Yasin Tas", "Eye Security"] + enabled = True + minimum = "1.2" + ttps = ["T1111", "T1193", "T1140"] # MITRE v6 + ttps += ["T1566.001"] # MITRE v6,7,8 + ttps += ["T1606"] # MITRE v7,8 + + def run(self) + if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": + data = self.results['target']['file']['data'] + \ No newline at end of file diff --git a/modules/signatures/html_obfuscation_static.py b/modules/signatures/html_obfuscation_static.py index 35fe94d1..6a58dea4 100644 --- a/modules/signatures/html_obfuscation_static.py +++ b/modules/signatures/html_obfuscation_static.py @@ -32,7 +32,8 @@ def run(self): if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": data = self.results['target']['file']['data'] if "atob" in data: - return True + times_atob = data.count("atob") + self.confidence = (times_atob * 5) class URLDecode(Signature): name = "JS_decode_detected" From 940d71957c10d50f3d4ac5cacb778c7893e794e0 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Fri, 31 Mar 2023 13:57:12 +0200 Subject: [PATCH 019/145] improvements to phishing kit --- .../credential_access_phishingkit.py | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index 2c653ed4..7d2c23a9 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -81,10 +81,10 @@ def run(self): if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": data = self.results['target']['file']['data'] regex_decodedURL = r"unescape\( \'([^&]+?)\' \) \);" - decodeString = re.search(regex_decodedURL,str(data)).group(0) + decodeString = re.search(regex_decodedURL,str(data)).group(1) if decodeString: self.weight = 1 - decoded_string = Chepy(decodeString).url_decode() + decoded_string = Chepy(decodeString).url_decode().o self.description = "File obfuscation detected with url decode" if "atob" in decoded_string: self.weight += 1 @@ -140,7 +140,34 @@ def run(self): return True class PhishingKit3(Signature): - name = "phishing2_kit_detected" + name = "phishing3_kit_detected" + description = "Phishing Kit Detected, sample is trying to harvest credentials" + severity = 3 + confidence = 100 + categories = ["credential_access","infostealer","phishing", "static"] + authors = ["Yasin Tas", "Eye Security"] + enabled = True + minimum = "1.2" + ttps = ["T1111", "T1193", "T1140"] # MITRE v6 + ttps += ["T1566.001"] # MITRE v6,7,8 + ttps += ["T1606"] # MITRE v7,8 + + def run(self) + if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": + data = self.results['target']['file']['data'] + user = re.search(r"var eml = \"([^&]+?)\";",str(data)) + url_regex = re.search(r'window.atob\(\'([^&]+?)\"\)}`',str(data)) + url_decoded = Chepy(url_regex).base64_decode().o + if user and url_regex: + self.weight = 1 + self.description = "Phishing kit detected, extracted config from sample" + self.families = ["PhishingKit-3"] + self.data.append({"url": url_decoded}) + self.data.append({"user": user}) + return True + +class PhishingKit4(Signature): + name = "phishing4_kit_detected" description = "Phishing Kit Detected, sample is trying to harvest credentials" severity = 3 confidence = 100 @@ -155,4 +182,4 @@ class PhishingKit3(Signature): def run(self) if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": data = self.results['target']['file']['data'] - \ No newline at end of file + # TODO \ No newline at end of file From 324ef17f12b21e65384d44eb976f780a6de5075c Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Fri, 31 Mar 2023 13:59:39 +0200 Subject: [PATCH 020/145] improvements to phishing kit --- modules/signatures/credential_access_phishingkit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index 7d2c23a9..30e1ee69 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -173,7 +173,7 @@ class PhishingKit4(Signature): confidence = 100 categories = ["credential_access","infostealer","phishing", "static"] authors = ["Yasin Tas", "Eye Security"] - enabled = True + enabled = False minimum = "1.2" ttps = ["T1111", "T1193", "T1140"] # MITRE v6 ttps += ["T1566.001"] # MITRE v6,7,8 From 225de0ca60f3f0c61f8576202da0ff5d5c7d35d2 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Fri, 31 Mar 2023 14:02:54 +0200 Subject: [PATCH 021/145] improvements to phishing kit --- modules/signatures/credential_access_phishingkit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index 30e1ee69..214c71e2 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -152,7 +152,7 @@ class PhishingKit3(Signature): ttps += ["T1566.001"] # MITRE v6,7,8 ttps += ["T1606"] # MITRE v7,8 - def run(self) + def run(self): if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": data = self.results['target']['file']['data'] user = re.search(r"var eml = \"([^&]+?)\";",str(data)) From be7d498445a7f30afd104c8ba0501d82928381a9 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Fri, 31 Mar 2023 14:06:47 +0200 Subject: [PATCH 022/145] improvements to phishing kit --- modules/signatures/credential_access_phishingkit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index 214c71e2..d4c7a930 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -179,7 +179,7 @@ class PhishingKit4(Signature): ttps += ["T1566.001"] # MITRE v6,7,8 ttps += ["T1606"] # MITRE v7,8 - def run(self) + def run(self): if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": data = self.results['target']['file']['data'] # TODO \ No newline at end of file From 7c4a2a96904664b0b0c62da0718b1a5b7fa356a8 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Fri, 31 Mar 2023 14:49:44 +0200 Subject: [PATCH 023/145] improvements to phishing kit --- modules/signatures/credential_access_phishingkit.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index d4c7a930..e5652aaa 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -128,7 +128,7 @@ def run(self): if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": data = self.results['target']['file']['data'] url_regex = r"" - user_regex = r"" url = re.search(url_regex,str(data)) user = re.search(user_regex,str(data)) if url and user: @@ -173,7 +173,7 @@ class PhishingKit4(Signature): confidence = 100 categories = ["credential_access","infostealer","phishing", "static"] authors = ["Yasin Tas", "Eye Security"] - enabled = False + enabled = True minimum = "1.2" ttps = ["T1111", "T1193", "T1140"] # MITRE v6 ttps += ["T1566.001"] # MITRE v6,7,8 From 30693f6dd170ec7bb01b921d87c76a18d834285d Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Fri, 31 Mar 2023 15:01:53 +0200 Subject: [PATCH 024/145] changes to file obfuscation --- modules/signatures/html_obfuscation_static.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/signatures/html_obfuscation_static.py b/modules/signatures/html_obfuscation_static.py index 6a58dea4..48d1ad4c 100644 --- a/modules/signatures/html_obfuscation_static.py +++ b/modules/signatures/html_obfuscation_static.py @@ -34,6 +34,8 @@ def run(self): if "atob" in data: times_atob = data.count("atob") self.confidence = (times_atob * 5) + self.data.append({f"Found atob {times_atob} times"}) + return True class URLDecode(Signature): name = "JS_decode_detected" From 3399b256865e1ad1d81906aa8004247bbcb80ce7 Mon Sep 17 00:00:00 2001 From: RoemIko Date: Tue, 4 Apr 2023 20:48:11 +0200 Subject: [PATCH 025/145] Added YARA signature for obfuscated JS --- .../credential_access_phishingkit.py | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index e5652aaa..1909bcba 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -27,8 +27,8 @@ import base64 -class PhishingKit0(Signature): - name = "phishing0_kit_detected" +class PhishHTMLGenahtml(Signature): + name = "phishing_kit_detected" description = "Phishing Kit Detected, sample is trying to harvest credentials" severity = 3 confidence = 100 @@ -56,15 +56,15 @@ def run(self): if decoded_url and decoded_user: self.weight = 2 self.description = "Phishing kit detected, extracted config from sample" - self.families = ["PhishingKit-0"] + self.families = ["Phish:HTML/Gen.a!html"] return True else: return True return False -class PhishingKit1(Signature): - name = "phishing1_kit_detected" +class PhishHTMLGenbhtml(Signature): + name = "phishing_kit_detected" description = "Phishing Kit Detected, sample is trying to harvest credentials" severity = 3 confidence = 100 @@ -94,7 +94,7 @@ def run(self): self.description = "File obfuscation detected with url decode and found encoded_string" if "encoded_string" in decoded_string and "atob" in decoded_string: self.weight = 3 - self.families = ["PhishingKit-1"] + self.families = ["Phish:HTML/Gen.b!html"] user_regex = r"var encoded_string = \"([^&]+?)\";" url_regex = r"window.atob\(\'([^&]+?)\'\)" #this regex can be improved @@ -111,8 +111,8 @@ def run(self): return True return False -class PhishingKit2(Signature): - name = "phishing2_kit_detected" +class PhishHTMLGenchtml(Signature): + name = "phishing_kit_detected" description = "Phishing Kit Detected, sample is trying to harvest credentials" severity = 3 confidence = 100 @@ -134,13 +134,13 @@ def run(self): if url and user: self.weight = 1 self.description = "Phishing kit detected, extracted config from sample" - self.families = ["PhishingKit-2"] + self.families = ["Phish:HTML/Gen.c!html"] self.data.append({"url": url}) self.data.append({"user": user}) return True -class PhishingKit3(Signature): - name = "phishing3_kit_detected" +class PhishHTMLGendhtml(Signature): + name = "phishing_kit_detected" description = "Phishing Kit Detected, sample is trying to harvest credentials" severity = 3 confidence = 100 @@ -161,13 +161,13 @@ def run(self): if user and url_regex: self.weight = 1 self.description = "Phishing kit detected, extracted config from sample" - self.families = ["PhishingKit-3"] + self.families = ["Phish:HTML/Gen.d!html"] self.data.append({"url": url_decoded}) self.data.append({"user": user}) return True -class PhishingKit4(Signature): - name = "phishing4_kit_detected" +class PhishHTMLGenehtml(Signature): + name = "phishing_kit_detected" description = "Phishing Kit Detected, sample is trying to harvest credentials" severity = 3 confidence = 100 From 73b19f5a44e8942c41472d2c546480c4a2c5c598 Mon Sep 17 00:00:00 2001 From: RoemIko Date: Tue, 4 Apr 2023 21:55:06 +0200 Subject: [PATCH 026/145] Added suspicious indicators for html files --- data/yara/binaries/susp_obfuscated_JS.yar | 52 ++++++++++++++++ modules/signatures/suspicious_html.py | 72 +++++++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 data/yara/binaries/susp_obfuscated_JS.yar create mode 100644 modules/signatures/suspicious_html.py diff --git a/data/yara/binaries/susp_obfuscated_JS.yar b/data/yara/binaries/susp_obfuscated_JS.yar new file mode 100644 index 00000000..37868523 --- /dev/null +++ b/data/yara/binaries/susp_obfuscated_JS.yar @@ -0,0 +1,52 @@ +rule SUSP_obfuscated_JS_obfuscatorio +{ + meta: + + author = "@imp0rtp3" + description = "Detect JS obfuscation done by the js obfuscator (often malicious)" + reference = "https://obfuscator.io" + + strings: + + // Beggining of the script + $a1 = "var a0_0x" + $a2 = /var _0x[a-f0-9]{4}/ + + // Strings to search By number of occurences + $b1 = /a0_0x([a-f0-9]{2}){2,4}\('?0x[0-9a-f]{1,3}'?\)/ + $b2 =/[^\w\d]_0x([a-f0-9]{2}){2,4}\('?0x[0-9a-f]{1,3}'?\)[^\w\d]/ + $b3 = /[^\w\d]_0x([a-f0-9]{2}){2,4}\['push'\]\(_0x([a-f0-9]{2}){2,4}\['shift'\]\(\)[^\w\d]/ + $b4 = /!0x1[^\d\w]/ + $b5 = /[^\w\d]function\((_0x([a-f0-9]{2}){2,4},)+_0x([a-f0-9]{2}){2,4}\)\s?\{/ + $b6 = /[^\w\d]_0x([a-f0-9]{2}){2,4}\s?=\s?_0x([a-f0-9]{2}){2,4}[^\w\d]/ + + // generic strings often used by the obfuscator + $c1 = "))),function(){try{var _0x" + $c2 = "=Function('return\\x20(function()\\x20'+'{}.constructor(\\x22return\\x20this\\x22)(\\x20)'+');');" + $c3 = "['atob']=function(" + $c4 = ")['replace'](/=+$/,'');var" + $c5 = "return!![]" + $c6 = "'{}.constructor(\\x22return\\\x20this\\x22)(\\x20)'" + $c7 = "{}.constructor(\x22return\x20this\x22)(\x20)" base64 + $c8 = "while(!![])" + $c9 = "while (!![])" + + // Strong strings + $d1 = /(parseInt\(_0x([a-f0-9]{2}){2,4}\(0x[a-f0-9]{1,5}\)\)\/0x[a-f0-9]{1,2}\)?(\+|\*\()\-?){6}/ + + condition: + $a1 at 0 or + $a2 at 0 or + ( + filesize<1000000 and + ( + (#b1 + #b2) > (filesize \ 200) or + #b3 > 1 or + #b4 > 10 or + #b5 > (filesize \ 2000) or + #b6 > (filesize \ 200) or + 3 of ($c*) or + $d1 + ) + ) +} \ No newline at end of file diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py new file mode 100644 index 00000000..bb6ba36b --- /dev/null +++ b/modules/signatures/suspicious_html.py @@ -0,0 +1,72 @@ +# Copyright (C) 2023 Eye Security (yasin.tas@eye.security) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from lib.cuckoo.common.abstracts import Signature + +class htmlBody(Signature): + name = "suspicious_html_body" + description = "Sample contains suspicious HTML body" + severity = 1 + confidence = 80 + categories = ["phishing", "static"] + authors = ["Yasin Tas", "Eye Security"] + enabled = False + minimum = "1.2" + ttps = ["T1566.001"] # MITRE v6,7,8 + mbcs = ["C0029.003"] # micro-behaviour + + def run(self): + + indicators = ['password', + 'email', + 'username', + ] + + if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": + data = self.results['target']['file']['data'] + for indicator in indicators: + if indicator in data: + self.data.append({f"Found {indicator} in HTML body"}) + return True + return False + +class htmlTitle(Signature): + name = "suspicious_html_title" + description = "Sample contains suspicious HTML title" + severity = 1 + confidence = 80 + categories = ["phishing", "static"] + authors = ["Yasin Tas", "Eye Security"] + enabled = False + minimum = "1.2" + ttps = ["T1566.001"] # MITRE v6,7,8 + mbcs = ["C0029.003"] # micro-behaviour + + def run(self): + + indicators = ['Sign in to your account', + ] + + if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": + data = self.results['target']['file']['data'] + for indicator in indicators: + if indicator in data: + self.data.append({f"Found {indicator} in HTML title"}) + return True + if "" in data: + self.description = "Sample contains empty HTML title" + return True + return False + \ No newline at end of file From 5890235e6aff1bcf7fd7ce7d0967add36af8b10a Mon Sep 17 00:00:00 2001 From: RoemIko Date: Tue, 4 Apr 2023 22:17:07 +0200 Subject: [PATCH 027/145] Added extra YARA rules --- modules/signatures/suspicious_html.py | 31 ++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index bb6ba36b..487d46ed 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -69,4 +69,33 @@ def run(self): self.description = "Sample contains empty HTML title" return True return False - \ No newline at end of file + +class suspiciousHTMLname(Signature): + name = "suspicious_html_name" + description = "Sample contains suspicious HTML name" + severity = 1 + confidence = 80 + categories = ["phishing", "static"] + authors = ["Yasin Tas", "Eye Security"] + enabled = False + minimum = "1.2" + ttps = ["T1566.001"] # MITRE v6,7,8 + mbcs = ["C0029.003"] # micro-behaviour + + def run(self): + + indicators = ['payment', + 'remittence', + 'Invoice', + 'inv', + 'voicemail', + 'remit', + ] + + if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": + name = self.results['target']['file']['name'] + for indicator in indicators: + if indicator in name: + self.data.append({f"Found {indicator} in sample name"}) + return True + \ No newline at end of file From a03ed3212d6ed9cb97d605e1e71bf5d8698e2bb6 Mon Sep 17 00:00:00 2001 From: RoemIko Date: Tue, 4 Apr 2023 22:17:11 +0200 Subject: [PATCH 028/145] Added extra YARA rules --- data/yara/binaries/OneNote_BuildPath.yar | 0 data/yara/binaries/oAuth_Phishing_PDF.yar | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 data/yara/binaries/OneNote_BuildPath.yar create mode 100644 data/yara/binaries/oAuth_Phishing_PDF.yar diff --git a/data/yara/binaries/OneNote_BuildPath.yar b/data/yara/binaries/OneNote_BuildPath.yar new file mode 100644 index 00000000..e69de29b diff --git a/data/yara/binaries/oAuth_Phishing_PDF.yar b/data/yara/binaries/oAuth_Phishing_PDF.yar new file mode 100644 index 00000000..e69de29b From 012db3c6723c093a20d11a59771fdbbc39c42283 Mon Sep 17 00:00:00 2001 From: RoemIko Date: Tue, 4 Apr 2023 22:18:10 +0200 Subject: [PATCH 029/145] Added extra YARA rules --- data/yara/binaries/OneNote_BuildPath.yar | 23 +++++++++++++++++++++ data/yara/binaries/oAuth_Phishing_PDF.yar | 25 +++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/data/yara/binaries/OneNote_BuildPath.yar b/data/yara/binaries/OneNote_BuildPath.yar index e69de29b..d83f3c38 100644 --- a/data/yara/binaries/OneNote_BuildPath.yar +++ b/data/yara/binaries/OneNote_BuildPath.yar @@ -0,0 +1,23 @@ +rule OneNote_BuildPath +{ + meta: + id = "6lPn0V5wZyc2iuEz13uKAZ" + fingerprint = "f8ed9e3cdd5411e2bda7495c8b00b8e69e8f495db97cf542f6a1f3b790bef7a5" + version = "1.0" + first_imported = "2023-02-02" + last_modified = "2023-02-23" + status = "RELEASED" + sharing = "TLP:WHITE" + source = "BARTBLAZE" + author = "@bartblaze" + description = "Identifies malicious OneNote file by build path." + category = "MALWARE" + +strings: + //Z:\build\one\attachment.hta + $path_0 = {5a003a005c006200750069006c0064005c006f006e0065005c006100740074006100630068006d0065006e0074002e00680074006100} + //Z:\builder\O P E N.wsf + $path_1 = {5a003a005c006200750069006c006400650072005c004f00200050002000450020004e002e00770073006600} +condition: + filesize <200KB and any of them +} \ No newline at end of file diff --git a/data/yara/binaries/oAuth_Phishing_PDF.yar b/data/yara/binaries/oAuth_Phishing_PDF.yar index e69de29b..4ee2abcf 100644 --- a/data/yara/binaries/oAuth_Phishing_PDF.yar +++ b/data/yara/binaries/oAuth_Phishing_PDF.yar @@ -0,0 +1,25 @@ +rule oAuth_Phishing_PDF +{ + meta: + id = "789YmThaTvLDaE1V2Oqx7q" + fingerprint = "c367bca866de0b066e291b4e45216cbb68cc23297b002a29ca3c8d640a7db78e" + version = "1.0" + creation_date = "2022-01-01" + first_imported = "2022-02-03" + last_modified = "2022-02-03" + status = "RELEASED" + sharing = "TLP:WHITE" + source = "BARTBLAZE" + author = "@bartblaze" + description = "Identifies potential phishing PDFs that target oAuth." + category = "MALWARE" + reference = "https://twitter.com/ffforward/status/1484127442679836676" + + strings: + $pdf = {25504446} //%PDF + $s1 = "/URI (https://login.microsoftonline.com/common/oauth2/" ascii wide nocase + $s2 = "/URI (https://login.microsoftonline.com/consumers/oauth2" ascii wide nocase + $s3 = "/URI (https://accounts.google.com/o/oauth2" ascii wide nocase + condition: + $pdf at 0 and any of ($s*) +} \ No newline at end of file From 60c4f574f0057507398c23e096195fd2fcb78fec Mon Sep 17 00:00:00 2001 From: RoemIko Date: Tue, 4 Apr 2023 22:47:53 +0200 Subject: [PATCH 030/145] Logic change in html_obfuscation --- modules/signatures/html_obfuscation_static.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/signatures/html_obfuscation_static.py b/modules/signatures/html_obfuscation_static.py index 48d1ad4c..b75f8442 100644 --- a/modules/signatures/html_obfuscation_static.py +++ b/modules/signatures/html_obfuscation_static.py @@ -33,7 +33,9 @@ def run(self): data = self.results['target']['file']['data'] if "atob" in data: times_atob = data.count("atob") - self.confidence = (times_atob * 5) + self.confidence = self.confidence + (times_atob * 5) + if self.confidence => 100: + self.confidence = 100 self.data.append({f"Found atob {times_atob} times"}) return True From 84c7da2d7669523d9ebec0188a8868c842b60800 Mon Sep 17 00:00:00 2001 From: RoemIko Date: Tue, 4 Apr 2023 23:03:12 +0200 Subject: [PATCH 031/145] Logic change in html_obfuscation --- modules/signatures/html_obfuscation_static.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/signatures/html_obfuscation_static.py b/modules/signatures/html_obfuscation_static.py index b75f8442..01000212 100644 --- a/modules/signatures/html_obfuscation_static.py +++ b/modules/signatures/html_obfuscation_static.py @@ -34,7 +34,7 @@ def run(self): if "atob" in data: times_atob = data.count("atob") self.confidence = self.confidence + (times_atob * 5) - if self.confidence => 100: + if self.confidence >= 100: self.confidence = 100 self.data.append({f"Found atob {times_atob} times"}) return True From 1cc840f645aa861d6575be43a1b7b747261a5bd5 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 5 Apr 2023 09:49:32 +0200 Subject: [PATCH 032/145] atob didnt work --- modules/signatures/html_obfuscation_static.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/signatures/html_obfuscation_static.py b/modules/signatures/html_obfuscation_static.py index 01000212..f4ca2ea3 100644 --- a/modules/signatures/html_obfuscation_static.py +++ b/modules/signatures/html_obfuscation_static.py @@ -31,7 +31,8 @@ class JSAtob(Signature): def run(self): if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": data = self.results['target']['file']['data'] - if "atob" in data: + data = str(data) + if "atob" in str(data): times_atob = data.count("atob") self.confidence = self.confidence + (times_atob * 5) if self.confidence >= 100: From af7fd36428c9eb24336cbf7fb2e8bbca4ccf18ee Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 5 Apr 2023 09:59:38 +0200 Subject: [PATCH 033/145] atob didnt work --- modules/signatures/suspicious_html.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index 487d46ed..dc650684 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -15,6 +15,12 @@ from lib.cuckoo.common.abstracts import Signature + +try: + import re2 as re +except ImportError: + import re + class htmlBody(Signature): name = "suspicious_html_body" description = "Sample contains suspicious HTML body" @@ -59,13 +65,15 @@ def run(self): indicators = ['Sign in to your account', ] + title_regex = re.compile(r'/.*<\/title>/i') + if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": data = self.results['target']['file']['data'] for indicator in indicators: if indicator in data: self.data.append({f"Found {indicator} in HTML title"}) return True - if "<title>" in data: + if title_regex.search(data): self.description = "Sample contains empty HTML title" return True return False @@ -86,7 +94,7 @@ def run(self): indicators = ['payment', 'remittence', - 'Invoice', + 'invoice', 'inv', 'voicemail', 'remit', @@ -94,8 +102,9 @@ def run(self): if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": name = self.results['target']['file']['name'] + lower = name.lower() for indicator in indicators: - if indicator in name: + if indicator in lower: self.data.append({f"Found {indicator} in sample name"}) return True \ No newline at end of file From 14879f8c6d7bce92e58af6b8a2392cdb7776f192 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 5 Apr 2023 10:37:59 +0200 Subject: [PATCH 034/145] Add new signutures to phishing kits --- modules/signatures/credential_access_phishingkit.py | 2 +- modules/signatures/suspicious_html.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index 1909bcba..5c6d505e 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -182,4 +182,4 @@ class PhishHTMLGenehtml(Signature): def run(self): if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": data = self.results['target']['file']['data'] - # TODO \ No newline at end of file + regex_user = r'data-emailValue="([^&]+?)"' \ No newline at end of file diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index dc650684..ae7f0355 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -73,7 +73,7 @@ def run(self): if indicator in data: self.data.append({f"Found {indicator} in HTML title"}) return True - if title_regex.search(data): + if not title_regex.search(data): self.description = "Sample contains empty HTML title" return True return False From f89732ef2b1215108a20f2cfbc5fbbaaaf59662f Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 5 Apr 2023 12:07:58 +0200 Subject: [PATCH 035/145] Updated phishing signatures --- data/yara/binaries/HTML_PhishingKit.yar | 32 ++++++++++++++++ .../credential_access_phishingkit.py | 37 +++++++------------ 2 files changed, 45 insertions(+), 24 deletions(-) create mode 100644 data/yara/binaries/HTML_PhishingKit.yar diff --git a/data/yara/binaries/HTML_PhishingKit.yar b/data/yara/binaries/HTML_PhishingKit.yar new file mode 100644 index 00000000..a1b7cb44 --- /dev/null +++ b/data/yara/binaries/HTML_PhishingKit.yar @@ -0,0 +1,32 @@ +rule PhishHTMLGenbhtml { + meta: + description = "YARA detection for Phish:HTML/Gen.b!html" + author = "Yasin Tas, Eye Security" + reference = "Personal Research, Florian Roth yarGen" + date = "2023-04-05" + + strings: + $s1 = "30%25%32%30%25%32%30%25%37%64%25%30%64%25%30%61%25%30%64%25%30%61%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30" ascii /* hex encoded string '0%20%20%7d%0d%0a%0d%0a%20%20%20%20%20%20%20' */ + $s2 = "32%30%25%37%33%25%37%32%25%36%33%25%33%64%25%32%32%25%36%38%25%37%34%25%37%34%25%37%30%25%37%33%25%33%61%25%32%66%25%32%66%25%36" ascii /* hex encoded string '20%73%72%63%3d%22%68%74%74%70%73%3a%2f%2f%6' */ + $s3 = "25%32%30%25%32%30%25%32%30%25%32%30%25%32%65%25%36%32%25%37%34%25%36%65%25%32%64%25%36%66%25%37%35%25%37%34%25%36%63%25%36%39%25" ascii /* hex encoded string '%20%20%20%20%2e%62%74%6e%2d%6f%75%74%6c%69%' */ + $s4 = "32%64%25%36%37%25%37%32%25%36%66%25%37%35%25%37%30%25%32%64%25%36%39%25%37%34%25%36%35%25%36%64%25%32%64%25%37%33%25%37%35%25%36" ascii /* hex encoded string '2d%67%72%6f%75%70%2d%69%74%65%6d%2d%73%75%6' */ + $s5 = "36%33%25%36%66%25%36%65%25%37%34%25%36%35%25%36%65%25%37%34%25%32%64%25%36%63%25%36%37%25%32%64%25%36%33%25%36%35%25%36%65%25%37" ascii /* hex encoded string '63%6f%6e%74%65%6e%74%2d%6c%67%2d%63%65%6e%7' */ + $s6 = "25%32%30%25%32%30%25%37%36%25%36%39%25%37%33%25%36%39%25%36%32%25%36%39%25%36%63%25%36%39%25%37%34%25%37%39%25%33%61%25%32%30%25" ascii /* hex encoded string '%20%20%76%69%73%69%62%69%6c%69%74%79%3a%20%' */ + $s7 = "25%37%30%25%32%64%25%37%34%25%36%35%25%37%38%25%37%34%25%32%62%25%32%65%25%36%39%25%36%65%25%37%30%25%37%35%25%37%34%25%32%64%25" ascii /* hex encoded string '%70%2d%74%65%78%74%2b%2e%69%6e%70%75%74%2d%' */ + $s8 = "36%39%25%36%37%25%36%65%25%32%64%25%37%33%25%36%35%25%36%63%25%36%36%25%32%64%25%37%33%25%36%64%25%32%64%25%36%35%25%36%65%25%36" ascii /* hex encoded string '69%67%6e%2d%73%65%6c%66%2d%73%6d%2d%65%6e%6' */ + $s9 = "66%25%36%39%25%36%65%25%37%34%25%32%64%25%36%63%25%36%37%25%33%61%25%32%30%25%33%39%25%33%39%25%33%32%25%37%30%25%37%38%25%33%62" ascii /* hex encoded string 'f%69%6e%74%2d%6c%67%3a%20%39%39%32%70%78%3b' */ + $s10 = "32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%64%25%36%64%25%36" ascii /* hex encoded string '20%20%20%20%20%20%20%20%20%20%20%20%2d%6d%6' */ + $s11 = "37%36%25%33%65%25%30%64%25%30%61%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32" ascii /* hex encoded string '76%3e%0d%0a%20%20%20%20%20%20%20%20%20%20%2' */ + $s12 = "65%25%33%36%25%33%36%25%33%36%25%33%36%25%33%36%25%33%37%25%32%35%25%30%64%25%30%61%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30" ascii /* hex encoded string 'e%36%36%36%36%36%37%25%0d%0a%20%20%20%20%20' */ + $s13 = "25%36%35%25%33%62%25%30%64%25%30%61%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%37%34%25%36%35%25" ascii /* hex encoded string '%65%3b%0d%0a%20%20%20%20%20%20%20%20%74%65%' */ + $s14 = "36%31%25%36%63%25%32%64%25%36%37%25%37%32%25%36%66%25%37%35%25%37%30%25%33%61%25%32%30%25%33%30%25%33%62%25%30%64%25%30%61%25%32" ascii /* hex encoded string '61%6c%2d%67%72%6f%75%70%3a%20%30%3b%0d%0a%2' */ + $s15 = "30%25%32%30%25%32%30%25%32%30%25%32%65%25%36%66%25%36%36%25%36%36%25%37%33%25%36%35%25%37%34%25%32%64%25%37%33%25%36%64%25%32%64" ascii /* hex encoded string '0%20%20%20%2e%6f%66%66%73%65%74%2d%73%6d%2d' */ + $s16 = "32%25%36%37%25%36%39%25%36%65%25%33%61%25%32%30%25%33%33%25%37%32%25%36%35%25%36%64%25%32%30%25%32%31%25%36%39%25%36%64%25%37%30" ascii /* hex encoded string '2%67%69%6e%3a%20%33%72%65%6d%20%21%69%6d%70' */ + $s17 = "25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%37%61%25%32%64%25%36%39%25%36%65%25%36%34%25%36%35%25" ascii /* hex encoded string '%20%20%20%20%20%20%20%20%7a%2d%69%6e%64%65%' */ + $s18 = "25%36%39%25%36%65%25%32%64%25%37%37%25%36%39%25%36%34%25%37%34%25%36%38%25%33%61%25%33%39%25%33%39%25%33%32%25%37%30%25%37%38%25" ascii /* hex encoded string '%69%6e%2d%77%69%64%74%68%3a%39%39%32%70%78%' */ + $s19 = "25%36%35%25%36%65%25%37%34%25%36%35%25%37%32%25%32%30%25%37%62%25%30%64%25%30%61%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25" ascii /* hex encoded string '%65%6e%74%65%72%20%7b%0d%0a%20%20%20%20%20%' */ + $s20 = "25%32%30%25%32%33%25%36%36%25%33%38%25%36%36%25%33%39%25%36%36%25%36%31%25%33%62%25%30%64%25%30%61%25%32%30%25%32%30%25%32%30%25" ascii /* hex encoded string '%20%23%66%38%66%39%66%61%3b%0d%0a%20%20%20%' */ + condition: + ( uint16(0) == 0x733c and filesize < 7000KB and ( 8 of them ) + ) or ( all of them ) +} \ No newline at end of file diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index 5c6d505e..e67bc58f 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -79,35 +79,24 @@ class PhishHTMLGenbhtml(Signature): def run(self): if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": - data = self.results['target']['file']['data'] - regex_decodedURL = r"unescape\( \'([^&]+?)\' \) \);" - decodeString = re.search(regex_decodedURL,str(data)).group(1) + strings = self.results["target"]['file']["strings"] + data = ''.join(strings) + regex_decodedURL = r"unescape\(\'([^&]+?)\'\)\); " + decodeString = re.search(regex_decodedURL,data).group(1) if decodeString: self.weight = 1 - decoded_string = Chepy(decodeString).url_decode().o + decoded_string = Chepy(decodeString).url_decode().url_decode().o self.description = "File obfuscation detected with url decode" - if "atob" in decoded_string: - self.weight += 1 - self.description = "File obfuscation detected with url decode and atob" - if "encoded_string" in decoded_string: - self.weight += 1 - self.description = "File obfuscation detected with url decode and found encoded_string" - if "encoded_string" in decoded_string and "atob" in decoded_string: + regex_user = r'value="([^&]+?)"' + regex_url = r"url: '([^&]+?)'," + user = re.search(regex_user,decoded_string).group(1) + url = re.search(regex_url,decoded_string).group(1) + if user and url: self.weight = 3 self.families = ["Phish:HTML/Gen.b!html"] - user_regex = r"var encoded_string = \"([^&]+?)\";" - url_regex = r"window.atob\(\'([^&]+?)\'\)" - #this regex can be improved - aws_regex = r'window.location.href="([Hh][Tt][Tt][Pp][Ss]?://(.*)+?)' - user = re.search(user_regex,decoded_string).group(1) - url = re.search(url_regex,decoded_string).group(1) - aws = re.search(aws_regex,decoded_string).group(0).replace("window.location.href=\"","") - if user and url and aws: - self.description = "Phishing kit detected, extracted config from sample" - self.data.append({"decoded_url": base64.b64decode(url)}) - self.data.append({"decoded_user": user}) - self.data.append({"aws_url": aws}) - return True + self.description = "Phishing kit detected, extracted config from sample" + self.data.append({"url": url}) + self.data.apend({"user": user}) return True return False From ea34c69a05b4479f7240a9b0d16f9496269a932f Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 5 Apr 2023 12:57:05 +0200 Subject: [PATCH 036/145] Removed re2 since its deprecated --- modules/signatures/credential_access_phishingkit.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index e67bc58f..3e4a596c 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -15,10 +15,7 @@ from lib.cuckoo.common.abstracts import Signature -try: - import re2 as re -except ImportError: - import re +import re try: from chepy import Chepy @@ -81,8 +78,8 @@ def run(self): if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": strings = self.results["target"]['file']["strings"] data = ''.join(strings) - regex_decodedURL = r"unescape\(\'([^&]+?)\'\)\); " - decodeString = re.search(regex_decodedURL,data).group(1) + regex_decoded = r"unescape\(\'([^&]+?)\'\)\); " + decodeString = re.search(regex_decoded,data).group(1) if decodeString: self.weight = 1 decoded_string = Chepy(decodeString).url_decode().url_decode().o From 5f05070802f17493320eb89af81604341a34b463 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 5 Apr 2023 13:13:08 +0200 Subject: [PATCH 037/145] Regex changes --- modules/signatures/credential_access_phishingkit.py | 11 ++++++----- modules/signatures/suspicious_html.py | 5 +---- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index 3e4a596c..9d8591b7 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -79,21 +79,22 @@ def run(self): strings = self.results["target"]['file']["strings"] data = ''.join(strings) regex_decoded = r"unescape\(\'([^&]+?)\'\)\); " - decodeString = re.search(regex_decoded,data).group(1) + decodeString = re.search(regex_decoded,data) if decodeString: + decodeString = decodeString.group(1) self.weight = 1 decoded_string = Chepy(decodeString).url_decode().url_decode().o self.description = "File obfuscation detected with url decode" regex_user = r'value="([^&]+?)"' regex_url = r"url: '([^&]+?)'," - user = re.search(regex_user,decoded_string).group(1) - url = re.search(regex_url,decoded_string).group(1) + user = re.search(regex_user,decoded_string) + url = re.search(regex_url,decoded_string) if user and url: self.weight = 3 self.families = ["Phish:HTML/Gen.b!html"] self.description = "Phishing kit detected, extracted config from sample" - self.data.append({"url": url}) - self.data.apend({"user": user}) + self.data.append({"url": url.group(1)}) + self.data.apend({"user": user.group(1)}) return True return False diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index ae7f0355..6961bddb 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -16,10 +16,7 @@ from lib.cuckoo.common.abstracts import Signature -try: - import re2 as re -except ImportError: - import re +import re class htmlBody(Signature): name = "suspicious_html_body" From 69f479e0bb8528846e3b0007babc36b73e14a05a Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 5 Apr 2023 13:19:38 +0200 Subject: [PATCH 038/145] typo fixed --- modules/signatures/credential_access_phishingkit.py | 2 +- modules/signatures/suspicious_html.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index 9d8591b7..3123a2df 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -94,7 +94,7 @@ def run(self): self.families = ["Phish:HTML/Gen.b!html"] self.description = "Phishing kit detected, extracted config from sample" self.data.append({"url": url.group(1)}) - self.data.apend({"user": user.group(1)}) + self.data.append({"user": user.group(1)}) return True return False diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index 6961bddb..c2c8b518 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -15,7 +15,6 @@ from lib.cuckoo.common.abstracts import Signature - import re class htmlBody(Signature): From 75f31ae067e7aea03bed190f999b84c47ec22042 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 5 Apr 2023 13:30:40 +0200 Subject: [PATCH 039/145] Yara rules added for HTML --- data/yara/binaries/HTML_PhishingKit.yar | 41 +++++++++++++++++++ .../credential_access_phishingkit.py | 1 - 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/data/yara/binaries/HTML_PhishingKit.yar b/data/yara/binaries/HTML_PhishingKit.yar index a1b7cb44..2d5d8f90 100644 --- a/data/yara/binaries/HTML_PhishingKit.yar +++ b/data/yara/binaries/HTML_PhishingKit.yar @@ -1,3 +1,44 @@ +/* + YARA Rule Set for HTML phishing + Author: Yasin Tas, Eye Security + Date: 2023-04-05 + Identifier: Phish:HTML/Gen.*!html + Reference: Personal Research, Florian Roth yarGen +*/ + +rule PhishHTMLGenahtml { + meta: + description = "YARA detection for Phish:HTML/Gen.a!html" + author = "Yasin Tas, Eye Security" + reference = "Personal Research, Florian Roth yarGen" + date = "2023-04-05" + + strings: + $s1 = "74%20%32%73%20%69%6E%66%69%6E%69%74%65%7D%2E%70%72%6F%67%72%65%73%73%3E%64%69%76%3A%6E%74%68%2D%63%68%69%6C%64%28%31%29%7B%2D%77" ascii /* hex encoded string 't 2s infinite}.progress>div:nth-child(1){-w' */ + $s2 = "31%70%78%20%73%6F%6C%69%64%20%23%30%30%37%38%64%37%3B%62%6F%72%64%65%72%2D%74%6F%70%2D%77%69%64%74%68%3A%30%3B%62%6F%72%64%65%72" ascii /* hex encoded string '1px solid #0078d7;border-top-width:0;border' */ + $s3 = "72%6F%75%70%7B%66%6F%6E%74%2D%77%65%69%67%68%74%3A%37%30%30%7D%74%61%62%6C%65%7B%62%6F%72%64%65%72%2D%63%6F%6C%6C%61%70%73%65%3A" ascii /* hex encoded string 'roup{font-weight:700}table{border-collapse:' */ + $s4 = "73%20%73%68%6F%77%2D%66%72%6F%6D%2D%72%69%67%68%74%7B%66%72%6F%6D%7B%6C%65%66%74%3A%32%30%30%70%78%3B%6F%70%61%63%69%74%79%3A%30" ascii /* hex encoded string 's show-from-right{from{left:200px;opacity:0' */ + $s5 = "63%6F%6C%6F%72%3A%23%62%33%62%33%62%33%3B%62%61%63%6B%67%72%6F%75%6E%64%2D%63%6F%6C%6F%72%3A%72%67%62%61%28%30%2C%30%2C%30%2C%2E" ascii /* hex encoded string 'color:#b3b3b3;background-color:rgba(0,0,0,.' */ + $s6 = "65%2C%2E%69%6E%70%75%74%2D%67%72%6F%75%70%2D%62%74%6E%3A%6C%61%73%74%2D%63%68%69%6C%64%3E%2E%62%74%6E%2D%67%72%6F%75%70%3A%6E%6F" ascii /* hex encoded string 'e,.input-group-btn:last-child>.btn-group:no' */ + $s7 = "3A%35%70%78%3B%77%69%64%74%68%3A%35%70%78%3B%62%61%63%6B%67%72%6F%75%6E%64%2D%63%6F%6C%6F%72%3A%23%30%30%36%37%62%38%3B%7A%2D%69" ascii /* hex encoded string ':5px;width:5px;background-color:#0067b8;z-i' */ + $s8 = "7B%61%6E%69%6D%61%74%69%6F%6E%2D%64%75%72%61%74%69%6F%6E%3A%2E%32%35%73%3B%2D%77%65%62%6B%69%74%2D%61%6E%69%6D%61%74%69%6F%6E%2D" ascii /* hex encoded string '{animation-duration:.25s;-webkit-animation-' */ + $s9 = "31%2E%37%35%72%65%6D%3B%70%61%64%64%69%6E%67%2D%62%6F%74%74%6F%6D%3A%32%2E%33%36%70%78%3B%70%61%64%64%69%6E%67%2D%74%6F%70%3A%32" ascii /* hex encoded string '1.75rem;padding-bottom:2.36px;padding-top:2' */ + $s10 = "2E%31%36%36%36%37%25%7D%2E%63%6F%6C%2D%6D%64%2D%70%75%73%68%2D%31%34%7B%6C%65%66%74%3A%35%38%2E%33%33%33%33%33%25%7D%2E%63%6F%6C" ascii /* hex encoded string '.16667%}.col-md-push-14{left:58.33333%}.col' */ + $s11 = "65%66%74%3A%35%30%25%7D%2E%63%6F%6C%2D%6C%67%2D%6F%66%66%73%65%74%2D%31%33%7B%6D%61%72%67%69%6E%2D%6C%65%66%74%3A%35%34%2E%31%36" ascii /* hex encoded string 'eft:50%}.col-lg-offset-13{margin-left:54.16' */ + $s12 = "66%66%73%65%74%3A%2D%32%70%78%3B%6F%75%74%6C%69%6E%65%3A%35%70%78%20%61%75%74%6F%20%2D%77%65%62%6B%69%74%2D%66%6F%63%75%73%2D%72" ascii /* hex encoded string 'ffset:-2px;outline:5px auto -webkit-focus-r' */ + $s13 = "69%63%61%6C%2D%61%6C%69%67%6E%3A%6D%69%64%64%6C%65%7D%2E%64%69%61%6C%6F%67%2D%6F%75%74%65%72%20%2E%64%69%61%6C%6F%67%2D%6D%69%64" ascii /* hex encoded string 'ical-align:middle}.dialog-outer .dialog-mid' */ + $s14 = "70%61%63%69%74%79%3A%30%7D%7D%40%2D%6D%6F%7A%2D%6B%65%79%66%72%61%6D%65%73%20%70%72%6F%67%72%65%73%73%44%6F%74%7B%30%25%2C%32%30" ascii /* hex encoded string 'pacity:0}}@-moz-keyframes progressDot{0%,20' */ + $s15 = "6E%61%6D%65%3A%68%69%64%65%2D%74%6F%2D%72%69%67%68%74%7D%68%74%6D%6C%5B%64%69%72%3D%6C%74%72%5D%20%2E%61%6E%69%6D%61%74%65%2E%73" ascii /* hex encoded string 'name:hide-to-right}html[dir=ltr] .animate.s' */ + $s16 = "2D%77%65%62%6B%69%74%2D%70%6C%61%63%65%68%6F%6C%64%65%72%2C%69%6E%70%75%74%5B%74%79%70%65%3D%63%6F%6C%6F%72%5D%3A%3A%2D%77%65%62" ascii /* hex encoded string '-webkit-placeholder,input[type=color]::-web' */ + $s17 = "33%70%78%20%32%30%70%78%3B%66%6F%6E%74%2D%73%69%7A%65%3A%31%32%70%78%3B%6C%69%6E%65%2D%68%65%69%67%68%74%3A%31%2E%34%32%38%35%37" ascii /* hex encoded string '3px 20px;font-size:12px;line-height:1.42857' */ + $s18 = "3B%2D%77%65%62%6B%69%74%2D%62%6F%78%2D%73%68%61%64%6F%77%3A%30%20%32%70%78%20%36%70%78%20%72%67%62%61%28%30%2C%30%2C%30%2C%2E%32" ascii /* hex encoded string ';-webkit-box-shadow:0 2px 6px rgba(0,0,0,.2' */ + $s19 = "33%33%33%25%7D%2E%63%6F%6C%2D%6C%67%2D%70%75%73%68%2D%31%35%7B%6C%65%66%74%3A%36%32%2E%35%25%7D%2E%63%6F%6C%2D%6C%67%2D%70%75%73" ascii /* hex encoded string '333%}.col-lg-push-15{left:62.5%}.col-lg-pus' */ + $s20 = "74%69%74%6C%65%2E%74%65%78%74%2D%6D%61%78%6C%69%6E%65%73%2D%34%7B%6D%61%78%2D%68%65%69%67%68%74%3A%38%30%2E%34%35%70%78%3B%6D%61" ascii /* hex encoded string 'title.text-maxlines-4{max-height:80.45px;ma' */ + condition: + ( uint16(0) == 0x733c and filesize < 1000KB and ( 8 of them ) + ) or ( all of them ) +} + rule PhishHTMLGenbhtml { meta: description = "YARA detection for Phish:HTML/Gen.b!html" diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index 3123a2df..f3512311 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -82,7 +82,6 @@ def run(self): decodeString = re.search(regex_decoded,data) if decodeString: decodeString = decodeString.group(1) - self.weight = 1 decoded_string = Chepy(decodeString).url_decode().url_decode().o self.description = "File obfuscation detected with url decode" regex_user = r'value="([^&]+?)"' From b8589a1d33a1d22cb94aa46fbdb155bd1d3ab7c6 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 5 Apr 2023 14:10:50 +0200 Subject: [PATCH 040/145] Added config extractor for Phish:HTML --- .../credential_access_phishingkit.py | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index f3512311..1faef367 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -39,26 +39,28 @@ class PhishHTMLGenahtml(Signature): mbcs = ["C0029.003"] # micro-behaviour def run(self): - if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": - data = self.results['target']['file']['data'] - regex_base64 = r'value="([^&]+?)">' - decodeString = re.findall(regex_base64,str(data)) + strings = self.results['target']['file']['strings'] + regex_decodedURL = r"unescape\( \'([^&]+?)\' \) \);" + data = ''.join(strings) + decodeString = re.search(regex_decodedURL,data) if decodeString: - self.weight = 1 - decoded_url = base64.b64decode(decodeString[0]) - self.data.append({"decoded_url": decoded_url}) - decoded_user = base64.b64decode(decodeString[1]) - self.data.append({"decoded_user": decoded_user}) - if decoded_url and decoded_user: - self.weight = 2 - self.description = "Phishing kit detected, extracted config from sample" + decodeString = decodeString.group(1) + decoded_string = Chepy(decodeString).url_decode().o + self.description = "File obfuscation detected with url decode" + regex_user = r'var encoded_string = "([^&]+?)"' + regex_url = r"var url = window.atob\('([^&]+?)'\)" + regex_post_url = r'window\.location\.href="([^&]+.*)";' + user = re.search(regex_user,decoded_string) + url = re.search(regex_url,decoded_string) + post_url = re.search(regex_post_url,decoded_string) + if user and url and post_url: + self.weight = 3 self.families = ["Phish:HTML/Gen.a!html"] - return True - else: - return True - - return False + self.description = "Phishing kit detected, extracted config from sample" + self.data.append({"url": base64.b64decode(url.group(1)).decode("utf-8")}) + self.data.append({"user": user.group(1)}) + self.data.append({"post_url": post_url.group(1)}) class PhishHTMLGenbhtml(Signature): name = "phishing_kit_detected" From b666f3720434ff03b0db5e32f31d82bcf4328b3a Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 5 Apr 2023 14:17:11 +0200 Subject: [PATCH 041/145] Added config extractor for Phish:HTML --- modules/signatures/credential_access_phishingkit.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index 1faef367..6fe82d91 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -47,7 +47,6 @@ def run(self): if decodeString: decodeString = decodeString.group(1) decoded_string = Chepy(decodeString).url_decode().o - self.description = "File obfuscation detected with url decode" regex_user = r'var encoded_string = "([^&]+?)"' regex_url = r"var url = window.atob\('([^&]+?)'\)" regex_post_url = r'window\.location\.href="([^&]+.*)";' @@ -55,12 +54,15 @@ def run(self): url = re.search(regex_url,decoded_string) post_url = re.search(regex_post_url,decoded_string) if user and url and post_url: - self.weight = 3 + self.weight = 3 self.description = "File obfuscation detected, with url encoding" + self.families = ["Phish:HTML/Gen.a!html"] self.description = "Phishing kit detected, extracted config from sample" self.data.append({"url": base64.b64decode(url.group(1)).decode("utf-8")}) self.data.append({"user": user.group(1)}) self.data.append({"post_url": post_url.group(1)}) + return True + return False class PhishHTMLGenbhtml(Signature): name = "phishing_kit_detected" @@ -85,7 +87,7 @@ def run(self): if decodeString: decodeString = decodeString.group(1) decoded_string = Chepy(decodeString).url_decode().url_decode().o - self.description = "File obfuscation detected with url decode" + self.description = "File obfuscation detected, with url encoding" regex_user = r'value="([^&]+?)"' regex_url = r"url: '([^&]+?)'," user = re.search(regex_user,decoded_string) @@ -126,6 +128,7 @@ def run(self): self.data.append({"url": url}) self.data.append({"user": user}) return True + return False class PhishHTMLGendhtml(Signature): name = "phishing_kit_detected" From eeb9816d37a189b753bbfb79777ba07911e16afa Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 5 Apr 2023 14:36:37 +0200 Subject: [PATCH 042/145] Improvements --- modules/signatures/credential_access_phishingkit.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index 6fe82d91..8e50bd34 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -45,6 +45,7 @@ def run(self): data = ''.join(strings) decodeString = re.search(regex_decodedURL,data) if decodeString: + self.description = "File obfuscation detected, with url encoding" decodeString = decodeString.group(1) decoded_string = Chepy(decodeString).url_decode().o regex_user = r'var encoded_string = "([^&]+?)"' @@ -54,8 +55,7 @@ def run(self): url = re.search(regex_url,decoded_string) post_url = re.search(regex_post_url,decoded_string) if user and url and post_url: - self.weight = 3 self.description = "File obfuscation detected, with url encoding" - + self.weight = 3 self.families = ["Phish:HTML/Gen.a!html"] self.description = "Phishing kit detected, extracted config from sample" self.data.append({"url": base64.b64decode(url.group(1)).decode("utf-8")}) From 65ab8b8ab9d0b8190a17dbd79980edf7d6f0bfba Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 5 Apr 2023 15:25:26 +0200 Subject: [PATCH 043/145] fixed typing --- modules/signatures/credential_access_phishingkit.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index 8e50bd34..3eae53aa 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -40,7 +40,7 @@ class PhishHTMLGenahtml(Signature): def run(self): if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": - strings = self.results['target']['file']['strings'] + strings = self.results["target"]["file"]["strings"] regex_decodedURL = r"unescape\( \'([^&]+?)\' \) \);" data = ''.join(strings) decodeString = re.search(regex_decodedURL,data) @@ -80,7 +80,7 @@ class PhishHTMLGenbhtml(Signature): def run(self): if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": - strings = self.results["target"]['file']["strings"] + strings = self.results["target"]["file"]["strings"] data = ''.join(strings) regex_decoded = r"unescape\(\'([^&]+?)\'\)\); " decodeString = re.search(regex_decoded,data) From 7cf3dc9dcdef32262aacb86cafe16301b814b159 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Fri, 7 Apr 2023 14:18:36 +0200 Subject: [PATCH 044/145] Creating a more generic rule for HTML --- data/yara/binaries/HTML_PhishingKit.yar | 8 +-- .../credential_access_phishingkit.py | 7 ++- modules/signatures/html_obfuscation_static.py | 61 ------------------- modules/signatures/suspicious_html.py | 45 +++++++++++++- 4 files changed, 52 insertions(+), 69 deletions(-) delete mode 100644 modules/signatures/html_obfuscation_static.py diff --git a/data/yara/binaries/HTML_PhishingKit.yar b/data/yara/binaries/HTML_PhishingKit.yar index 2d5d8f90..f518ee75 100644 --- a/data/yara/binaries/HTML_PhishingKit.yar +++ b/data/yara/binaries/HTML_PhishingKit.yar @@ -6,9 +6,9 @@ Reference: Personal Research, Florian Roth yarGen */ -rule PhishHTMLGenahtml { +rule CAPE_HTML_Pish_1 { meta: - description = "YARA detection for Phish:HTML/Gen.a!html" + description = "YARA detection for HTMLPhisher_2023" author = "Yasin Tas, Eye Security" reference = "Personal Research, Florian Roth yarGen" date = "2023-04-05" @@ -39,9 +39,9 @@ rule PhishHTMLGenahtml { ) or ( all of them ) } -rule PhishHTMLGenbhtml { +rule CAPE_HTML_Pish_2 { meta: - description = "YARA detection for Phish:HTML/Gen.b!html" + description = "YARA detection for HTMLPhisher_2023" author = "Yasin Tas, Eye Security" reference = "Personal Research, Florian Roth yarGen" date = "2023-04-05" diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index 3eae53aa..36df2ab9 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -56,7 +56,7 @@ def run(self): post_url = re.search(regex_post_url,decoded_string) if user and url and post_url: self.weight = 3 - self.families = ["Phish:HTML/Gen.a!html"] + self.families = ["HTMLPhisher_2023"] self.description = "Phishing kit detected, extracted config from sample" self.data.append({"url": base64.b64decode(url.group(1)).decode("utf-8")}) self.data.append({"user": user.group(1)}) @@ -94,7 +94,7 @@ def run(self): url = re.search(regex_url,decoded_string) if user and url: self.weight = 3 - self.families = ["Phish:HTML/Gen.b!html"] + self.families = ["HTMLPhisher_2023"] self.description = "Phishing kit detected, extracted config from sample" self.data.append({"url": url.group(1)}) self.data.append({"user": user.group(1)}) @@ -124,7 +124,7 @@ def run(self): if url and user: self.weight = 1 self.description = "Phishing kit detected, extracted config from sample" - self.families = ["Phish:HTML/Gen.c!html"] + self.families = ["HTMLPhisher_2023"] self.data.append({"url": url}) self.data.append({"user": user}) return True @@ -156,6 +156,7 @@ def run(self): self.data.append({"url": url_decoded}) self.data.append({"user": user}) return True + return False class PhishHTMLGenehtml(Signature): name = "phishing_kit_detected" diff --git a/modules/signatures/html_obfuscation_static.py b/modules/signatures/html_obfuscation_static.py deleted file mode 100644 index f4ca2ea3..00000000 --- a/modules/signatures/html_obfuscation_static.py +++ /dev/null @@ -1,61 +0,0 @@ -# Copyright (C) 2023 Eye Security (yasin.tas@eye.security) -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -from lib.cuckoo.common.abstracts import Signature - -class JSAtob(Signature): - name = "JS_atob_detected" - description = "JS atob Detected, file is obfuscated" - severity = 2 - confidence = 70 - categories = ["evasion","phishing", "static"] - authors = ["Yasin Tas", "Eye Security"] - enabled = True - minimum = "1.2" - ttps = ["T1140"] # MITRE v6 - ttps += ["T1566.001"] # MITRE v6,7,8 - mbcs = ["C0029.003"] # micro-behaviour - - def run(self): - if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": - data = self.results['target']['file']['data'] - data = str(data) - if "atob" in str(data): - times_atob = data.count("atob") - self.confidence = self.confidence + (times_atob * 5) - if self.confidence >= 100: - self.confidence = 100 - self.data.append({f"Found atob {times_atob} times"}) - return True - -class URLDecode(Signature): - name = "JS_decode_detected" - description = "JS decode Detected, file is obfuscated" - severity = 2 - confidence = 70 - categories = ["evasion","phishing", "static"] - authors = ["Yasin Tas", "Eye Security"] - enabled = True - minimum = "1.2" - ttps = ["T1140"] # MITRE v6 - ttps += ["T1566.001"] # MITRE v6,7,8 - mbcs = ["C0029.003"] # micro-behaviour - - def run(self): - if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": - data = self.results['target']['file']['data'] - if "decodeURIComponent" in data: - return True - diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index c2c8b518..2268742b 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -103,4 +103,47 @@ def run(self): if indicator in lower: self.data.append({f"Found {indicator} in sample name"}) return True - \ No newline at end of file + +class JSAtob(Signature): + name = "JS_atob_detected" + description = "JS atob Detected, file is obfuscated" + severity = 2 + confidence = 70 + categories = ["evasion","phishing", "static"] + authors = ["Yasin Tas", "Eye Security"] + enabled = True + minimum = "1.2" + ttps = ["T1140"] # MITRE v6 + ttps += ["T1566.001"] # MITRE v6,7,8 + mbcs = ["C0029.003"] # micro-behaviour + + def run(self): + if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": + data = self.results['target']['file']['data'] + data = str(data) + if "atob" in str(data): + times_atob = data.count("atob") + self.confidence = self.confidence + (times_atob * 5) + if self.confidence >= 100: + self.confidence = 100 + self.data.append({f"Found atob {times_atob} times"}) + return True + +class URLDecode(Signature): + name = "JS_decode_detected" + description = "JS decode Detected, file is obfuscated" + severity = 2 + confidence = 70 + categories = ["evasion","phishing", "static"] + authors = ["Yasin Tas", "Eye Security"] + enabled = True + minimum = "1.2" + ttps = ["T1140"] # MITRE v6 + ttps += ["T1566.001"] # MITRE v6,7,8 + mbcs = ["C0029.003"] # micro-behaviour + + def run(self): + if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": + data = self.results['target']['file']['data'] + if "decodeURIComponent" in data: + return True \ No newline at end of file From a5759518f6eccd30bd627b51846ab5af43d9eb76 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Fri, 7 Apr 2023 14:33:14 +0200 Subject: [PATCH 045/145] Added Yara trigger for binaries --- modules/signatures/suspicious_html.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index 2268742b..1f5ef362 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -24,7 +24,7 @@ class htmlBody(Signature): confidence = 80 categories = ["phishing", "static"] authors = ["Yasin Tas", "Eye Security"] - enabled = False + enabled = True minimum = "1.2" ttps = ["T1566.001"] # MITRE v6,7,8 mbcs = ["C0029.003"] # micro-behaviour @@ -51,7 +51,7 @@ class htmlTitle(Signature): confidence = 80 categories = ["phishing", "static"] authors = ["Yasin Tas", "Eye Security"] - enabled = False + enabled = True minimum = "1.2" ttps = ["T1566.001"] # MITRE v6,7,8 mbcs = ["C0029.003"] # micro-behaviour @@ -81,7 +81,7 @@ class suspiciousHTMLname(Signature): confidence = 80 categories = ["phishing", "static"] authors = ["Yasin Tas", "Eye Security"] - enabled = False + enabled = True minimum = "1.2" ttps = ["T1566.001"] # MITRE v6,7,8 mbcs = ["C0029.003"] # micro-behaviour @@ -105,7 +105,7 @@ def run(self): return True class JSAtob(Signature): - name = "JS_atob_detected" + name = "suspicous_js_atob" description = "JS atob Detected, file is obfuscated" severity = 2 confidence = 70 @@ -130,7 +130,7 @@ def run(self): return True class URLDecode(Signature): - name = "JS_decode_detected" + name = "suspicous_url_decode" description = "JS decode Detected, file is obfuscated" severity = 2 confidence = 70 From 05739136d1031e079abc6d2fd20eee89ffe335dc Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Fri, 7 Apr 2023 14:55:59 +0200 Subject: [PATCH 046/145] Added HTMLPhish_3 signature --- modules/signatures/binary_yara.py | 38 +++++++++++++++ .../credential_access_phishingkit.py | 46 +++++++++++-------- modules/signatures/suspicious_html.py | 15 ++++-- 3 files changed, 76 insertions(+), 23 deletions(-) create mode 100644 modules/signatures/binary_yara.py diff --git a/modules/signatures/binary_yara.py b/modules/signatures/binary_yara.py new file mode 100644 index 00000000..3a15b1e5 --- /dev/null +++ b/modules/signatures/binary_yara.py @@ -0,0 +1,38 @@ +# Copyright (C) 2023 Eye Security (yasin.tas@eye.security) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from lib.cuckoo.common.abstracts import Signature + +class BinaryTriggeredYARA(Signature): + name = "binary_yara" + description = "Binary file triggered YARA rule" + severity = 3 + confidence = 50 + weight = 1 + categories = ["static"] + authors = ["Yasin Tas", "Eye Security"] + minimum = "1.3" + + def run(self): + if self.results["target"]["file"]["yara"]: + self.description = "Binary file triggered YARA rule(s)" + yara_triggered = self.results["target"]["file"]["yara"] + if len(yara_triggered) > 1: + self.description = "Binary file triggered multiple YARA rule(s)" + for yara in yara_triggered: + self.data.append({"Binary triggered YARA rule": yara["name"]}) + return True + + return False \ No newline at end of file diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index 36df2ab9..1055dd3b 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -24,7 +24,7 @@ import base64 -class PhishHTMLGenahtml(Signature): +class HTMLPhisher_0(Signature): name = "phishing_kit_detected" description = "Phishing Kit Detected, sample is trying to harvest credentials" severity = 3 @@ -64,7 +64,7 @@ def run(self): return True return False -class PhishHTMLGenbhtml(Signature): +class HTMLPhisher_1(Signature): name = "phishing_kit_detected" description = "Phishing Kit Detected, sample is trying to harvest credentials" severity = 3 @@ -101,7 +101,7 @@ def run(self): return True return False -class PhishHTMLGenchtml(Signature): +class HTMLPhisher_2(Signature): name = "phishing_kit_detected" description = "Phishing Kit Detected, sample is trying to harvest credentials" severity = 3 @@ -116,21 +116,31 @@ class PhishHTMLGenchtml(Signature): def run(self): if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": - data = self.results['target']['file']['data'] - url_regex = r"" - user_regex = r"" - url = re.search(url_regex,str(data)) - user = re.search(user_regex,str(data)) - if url and user: - self.weight = 1 - self.description = "Phishing kit detected, extracted config from sample" - self.families = ["HTMLPhisher_2023"] - self.data.append({"url": url}) - self.data.append({"user": user}) - return True + strings = self.results["target"]["file"]["strings"] + regex_decodedURL = r"unescape\( \'([^&]+?)\' \) \);" + data = ''.join(strings) + decodeString = re.search(regex_decodedURL,data) + if decodeString: + decodeString = decodeString.group(1) + decoded_string = Chepy(decodeString).url_decode().url_decode().o + self.description = "File obfuscation detected, with url encoding" + regex_user = r'var encoded_string = "([^&]+?)"' + regex_url = r"var url = window.atob\('([^&]+?)'\)" + regex_aws_url = r'window\.location\.href="([^&]+.*)' + user = re.search(regex_user,decoded_string) + url = re.search(regex_url,decoded_string) + post_url = re.search(regex_aws_url,decoded_string) + if user and url and post_url: + self.weight = 3 + self.families = ["Phish:HTML/Gen.b!html"] + self.description = "Phishing kit detected, extracted config from sample" + self.data.append({"post_url": post_url.group(1)}) + self.data.append({"url": base64.b64decode(url.group(1))}) + self.data.append({"user": user.group(1)}) + return True return False - -class PhishHTMLGendhtml(Signature): + +class HTMLPhisher_3(Signature): name = "phishing_kit_detected" description = "Phishing Kit Detected, sample is trying to harvest credentials" severity = 3 @@ -158,7 +168,7 @@ def run(self): return True return False -class PhishHTMLGenehtml(Signature): +class HTMLPhisher_4(Signature): name = "phishing_kit_detected" description = "Phishing Kit Detected, sample is trying to harvest credentials" severity = 3 diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index 1f5ef362..81103e98 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -37,7 +37,8 @@ def run(self): ] if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": - data = self.results['target']['file']['data'] + strings = self.results["target"]["file"]["strings"] + data = ''.join(strings) for indicator in indicators: if indicator in data: self.data.append({f"Found {indicator} in HTML body"}) @@ -64,7 +65,8 @@ def run(self): title_regex = re.compile(r'/.*<\/title>/i') if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": - data = self.results['target']['file']['data'] + strings = self.results["target"]["file"]["strings"] + data = ''.join(strings) for indicator in indicators: if indicator in data: self.data.append({f"Found {indicator} in HTML title"}) @@ -94,6 +96,7 @@ def run(self): 'inv', 'voicemail', 'remit', + 'voice', ] if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": @@ -119,8 +122,8 @@ class JSAtob(Signature): def run(self): if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": - data = self.results['target']['file']['data'] - data = str(data) + strings = self.results["target"]["file"]["strings"] + data = ''.join(strings) if "atob" in str(data): times_atob = data.count("atob") self.confidence = self.confidence + (times_atob * 5) @@ -128,6 +131,7 @@ def run(self): self.confidence = 100 self.data.append({f"Found atob {times_atob} times"}) return True + return False class URLDecode(Signature): name = "suspicous_url_decode" @@ -146,4 +150,5 @@ def run(self): if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": data = self.results['target']['file']['data'] if "decodeURIComponent" in data: - return True \ No newline at end of file + return True + return False \ No newline at end of file From f9f1f005d2a4514f9fe45783b433cd4dd3f97593 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Fri, 7 Apr 2023 15:00:02 +0200 Subject: [PATCH 047/145] Minor fixes --- modules/signatures/credential_access_phishingkit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index 1055dd3b..19f72622 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -135,7 +135,7 @@ def run(self): self.families = ["Phish:HTML/Gen.b!html"] self.description = "Phishing kit detected, extracted config from sample" self.data.append({"post_url": post_url.group(1)}) - self.data.append({"url": base64.b64decode(url.group(1))}) + self.data.append({"url": base64.b64decode(url.group(1)).decode("utf-8")}) self.data.append({"user": user.group(1)}) return True return False From 68fb63275c947ed3cf31072dd40b477459f1cf15 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Fri, 7 Apr 2023 15:24:33 +0200 Subject: [PATCH 048/145] PR for psishing rules --- modules/signatures/suspicious_html.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index 81103e98..24a7f601 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -34,6 +34,8 @@ def run(self): indicators = ['password', 'email', 'username', + 'encoded_string', + 'url', ] if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": From ec553c5e6234127e477006e71d23ebd7050c4ae1 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Fri, 7 Apr 2023 15:28:29 +0200 Subject: [PATCH 049/145] typos --- data/yara/binaries/HTML_PhishingKit.yar | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/yara/binaries/HTML_PhishingKit.yar b/data/yara/binaries/HTML_PhishingKit.yar index f518ee75..62cdb1ee 100644 --- a/data/yara/binaries/HTML_PhishingKit.yar +++ b/data/yara/binaries/HTML_PhishingKit.yar @@ -6,7 +6,7 @@ Reference: Personal Research, Florian Roth yarGen */ -rule CAPE_HTML_Pish_1 { +rule CAPEHTML_Phish_1 { meta: description = "YARA detection for HTMLPhisher_2023" author = "Yasin Tas, Eye Security" @@ -39,7 +39,7 @@ rule CAPE_HTML_Pish_1 { ) or ( all of them ) } -rule CAPE_HTML_Pish_2 { +rule CAPEHTML_Phish_2 { meta: description = "YARA detection for HTMLPhisher_2023" author = "Yasin Tas, Eye Security" From 9ae1e2ccffa881a061e432662163b28e43cbb88a Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Fri, 7 Apr 2023 15:30:35 +0200 Subject: [PATCH 050/145] typos --- modules/signatures/binary_yara.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/modules/signatures/binary_yara.py b/modules/signatures/binary_yara.py index 3a15b1e5..eb9f8a98 100644 --- a/modules/signatures/binary_yara.py +++ b/modules/signatures/binary_yara.py @@ -17,7 +17,7 @@ class BinaryTriggeredYARA(Signature): name = "binary_yara" - description = "Binary file triggered YARA rule" + description = "Binary file triggered multiple YARA rule(s)" severity = 3 confidence = 50 weight = 1 @@ -27,10 +27,9 @@ class BinaryTriggeredYARA(Signature): def run(self): if self.results["target"]["file"]["yara"]: - self.description = "Binary file triggered YARA rule(s)" yara_triggered = self.results["target"]["file"]["yara"] - if len(yara_triggered) > 1: - self.description = "Binary file triggered multiple YARA rule(s)" + if len(yara_triggered) == 1: + self.description = "Binary file triggered YARA rule" for yara in yara_triggered: self.data.append({"Binary triggered YARA rule": yara["name"]}) return True From e70790b43ed9c47fbe17ce57ad42e006ea83afda Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Fri, 7 Apr 2023 15:35:04 +0200 Subject: [PATCH 051/145] Improved phishing kit extractor --- .../credential_access_phishingkit.py | 70 +------------------ 1 file changed, 2 insertions(+), 68 deletions(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index 19f72622..ab4a2631 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -47,7 +47,7 @@ def run(self): if decodeString: self.description = "File obfuscation detected, with url encoding" decodeString = decodeString.group(1) - decoded_string = Chepy(decodeString).url_decode().o + decoded_string = Chepy(decodeString).url_decode().url_decode().o regex_user = r'var encoded_string = "([^&]+?)"' regex_url = r"var url = window.atob\('([^&]+?)'\)" regex_post_url = r'window\.location\.href="([^&]+.*)";' @@ -117,71 +117,5 @@ class HTMLPhisher_2(Signature): def run(self): if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": strings = self.results["target"]["file"]["strings"] - regex_decodedURL = r"unescape\( \'([^&]+?)\' \) \);</script>" data = ''.join(strings) - decodeString = re.search(regex_decodedURL,data) - if decodeString: - decodeString = decodeString.group(1) - decoded_string = Chepy(decodeString).url_decode().url_decode().o - self.description = "File obfuscation detected, with url encoding" - regex_user = r'var encoded_string = "([^&]+?)"' - regex_url = r"var url = window.atob\('([^&]+?)'\)" - regex_aws_url = r'window\.location\.href="([^&]+.*)' - user = re.search(regex_user,decoded_string) - url = re.search(regex_url,decoded_string) - post_url = re.search(regex_aws_url,decoded_string) - if user and url and post_url: - self.weight = 3 - self.families = ["Phish:HTML/Gen.b!html"] - self.description = "Phishing kit detected, extracted config from sample" - self.data.append({"post_url": post_url.group(1)}) - self.data.append({"url": base64.b64decode(url.group(1)).decode("utf-8")}) - self.data.append({"user": user.group(1)}) - return True - return False - -class HTMLPhisher_3(Signature): - name = "phishing_kit_detected" - description = "Phishing Kit Detected, sample is trying to harvest credentials" - severity = 3 - confidence = 100 - categories = ["credential_access","infostealer","phishing", "static"] - authors = ["Yasin Tas", "Eye Security"] - enabled = True - minimum = "1.2" - ttps = ["T1111", "T1193", "T1140"] # MITRE v6 - ttps += ["T1566.001"] # MITRE v6,7,8 - ttps += ["T1606"] # MITRE v7,8 - - def run(self): - if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": - data = self.results['target']['file']['data'] - user = re.search(r"var eml = \"([^&]+?)\";",str(data)) - url_regex = re.search(r'window.atob\(\'([^&]+?)\"\)}`',str(data)) - url_decoded = Chepy(url_regex).base64_decode().o - if user and url_regex: - self.weight = 1 - self.description = "Phishing kit detected, extracted config from sample" - self.families = ["Phish:HTML/Gen.d!html"] - self.data.append({"url": url_decoded}) - self.data.append({"user": user}) - return True - return False - -class HTMLPhisher_4(Signature): - name = "phishing_kit_detected" - description = "Phishing Kit Detected, sample is trying to harvest credentials" - severity = 3 - confidence = 100 - categories = ["credential_access","infostealer","phishing", "static"] - authors = ["Yasin Tas", "Eye Security"] - enabled = True - minimum = "1.2" - ttps = ["T1111", "T1193", "T1140"] # MITRE v6 - ttps += ["T1566.001"] # MITRE v6,7,8 - ttps += ["T1606"] # MITRE v7,8 - - def run(self): - if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": - data = self.results['target']['file']['data'] - regex_user = r'data-emailValue="([^&]+?)"' \ No newline at end of file + pass \ No newline at end of file From 567f019cbc53868e25bcd2a5e324077e7330e677 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Fri, 7 Apr 2023 15:46:21 +0200 Subject: [PATCH 052/145] Minor fixes in Yara over binary --- modules/signatures/binary_yara.py | 12 ++++++------ modules/signatures/suspicious_html.py | 26 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/modules/signatures/binary_yara.py b/modules/signatures/binary_yara.py index eb9f8a98..67069b71 100644 --- a/modules/signatures/binary_yara.py +++ b/modules/signatures/binary_yara.py @@ -28,10 +28,10 @@ class BinaryTriggeredYARA(Signature): def run(self): if self.results["target"]["file"]["yara"]: yara_triggered = self.results["target"]["file"]["yara"] - if len(yara_triggered) == 1: - self.description = "Binary file triggered YARA rule" - for yara in yara_triggered: - self.data.append({"Binary triggered YARA rule": yara["name"]}) - return True - + if yara_triggered != []: + if len(yara_triggered) == 1: + self.description = "Binary file triggered YARA rule" + for yara in yara_triggered: + self.data.append({"Binary triggered YARA rule": yara["name"]}) + return True return False \ No newline at end of file diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index 24a7f601..f0c837cf 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -153,4 +153,30 @@ def run(self): data = self.results['target']['file']['data'] if "decodeURIComponent" in data: return True + return False + +class jsUnescape(Signature): + name = "suspicous_js_unescape" + description = "JS unescape Detected, file is obfuscated" + severity = 2 + confidence = 70 + categories = ["evasion","phishing", "static"] + authors = ["Yasin Tas", "Eye Security"] + enabled = True + minimum = "1.2" + ttps = ["T1140"] # MITRE v6 + ttps += ["T1566.001"] # MITRE v6,7,8 + mbcs = ["C0029.003"] # micro-behaviour + + def run(self): + if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": + strings = self.results["target"]["file"]["strings"] + data = ''.join(strings) + if "unescape" in str(data): + times_unescape = data.count("unescape") + self.confidence = self.confidence + (times_unescape * 5) + if self.confidence >= 100: + self.confidence = 100 + self.data.append({f"Found unescape {times_unescape} times"}) + return True return False \ No newline at end of file From aeacac397019765b1f8c70d023aa2d2b155cb180 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Fri, 7 Apr 2023 16:05:20 +0200 Subject: [PATCH 053/145] Minor fixes in Yara over binary --- modules/signatures/credential_access_phishingkit.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index ab4a2631..5742e3a1 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -108,7 +108,7 @@ class HTMLPhisher_2(Signature): confidence = 100 categories = ["credential_access","infostealer","phishing", "static"] authors = ["Yasin Tas", "Eye Security"] - enabled = True + enabled = False minimum = "1.2" ttps = ["T1111", "T1193", "T1140"] # MITRE v6 ttps += ["T1566.001"] # MITRE v6,7,8 @@ -118,4 +118,7 @@ def run(self): if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": strings = self.results["target"]["file"]["strings"] data = ''.join(strings) - pass \ No newline at end of file + regex = r'value="([^&]+?)"' + payload = re.findall(regex,data) + if payload: + pass From 28492d82e123a8b47d40650b3d188f68d6b3ce19 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Fri, 7 Apr 2023 16:32:26 +0200 Subject: [PATCH 054/145] testing --- .../credential_access_phishingkit.py | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index 5742e3a1..ca4f3b75 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -101,24 +101,3 @@ def run(self): return True return False -class HTMLPhisher_2(Signature): - name = "phishing_kit_detected" - description = "Phishing Kit Detected, sample is trying to harvest credentials" - severity = 3 - confidence = 100 - categories = ["credential_access","infostealer","phishing", "static"] - authors = ["Yasin Tas", "Eye Security"] - enabled = False - minimum = "1.2" - ttps = ["T1111", "T1193", "T1140"] # MITRE v6 - ttps += ["T1566.001"] # MITRE v6,7,8 - ttps += ["T1606"] # MITRE v7,8 - - def run(self): - if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": - strings = self.results["target"]["file"]["strings"] - data = ''.join(strings) - regex = r'value="([^&]+?)"' - payload = re.findall(regex,data) - if payload: - pass From 25eed602dfe3e1d9c6c247b9ef4367e8b446d7e5 Mon Sep 17 00:00:00 2001 From: RoemIko <yasin.tas@eye.security> Date: Fri, 7 Apr 2023 21:57:56 +0200 Subject: [PATCH 055/145] Minor changes --- modules/signatures/binary_yara.py | 2 +- .../credential_access_phishingkit.py | 4 ++ modules/signatures/suspicious_html.py | 41 ++++++++++++------- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/modules/signatures/binary_yara.py b/modules/signatures/binary_yara.py index 67069b71..662a0209 100644 --- a/modules/signatures/binary_yara.py +++ b/modules/signatures/binary_yara.py @@ -33,5 +33,5 @@ def run(self): self.description = "Binary file triggered YARA rule" for yara in yara_triggered: self.data.append({"Binary triggered YARA rule": yara["name"]}) - return True + return True return False \ No newline at end of file diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index ca4f3b75..76c95e06 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -40,6 +40,8 @@ class HTMLPhisher_0(Signature): def run(self): if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": + if "strings" not in self.results["target"]["file"] or self.results["target"]["file"]["strings"] == []: + return False strings = self.results["target"]["file"]["strings"] regex_decodedURL = r"unescape\( \'([^&]+?)\' \) \);</script>" data = ''.join(strings) @@ -80,6 +82,8 @@ class HTMLPhisher_1(Signature): def run(self): if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": + if "strings" not in self.results["target"]["file"] or self.results["target"]["file"]["strings"] == []: + return False strings = self.results["target"]["file"]["strings"] data = ''.join(strings) regex_decoded = r"unescape\(\'([^&]+?)\'\)\); </script>" diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index f0c837cf..8c4a3094 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -31,14 +31,17 @@ class htmlBody(Signature): def run(self): - indicators = ['password', - 'email', - 'username', - 'encoded_string', - 'url', + indicators = [ + 'password', + 'email', + 'username', + 'encoded_string', + 'url', ] if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": + if "strings" not in self.results["target"]["file"] or self.results["target"]["file"]["strings"] == []: + return False strings = self.results["target"]["file"]["strings"] data = ''.join(strings) for indicator in indicators: @@ -61,12 +64,15 @@ class htmlTitle(Signature): def run(self): - indicators = ['Sign in to your account', + indicators = [ + 'Sign in to your account', ] title_regex = re.compile(r'/<title>.*<\/title>/i') if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": + if "strings" not in self.results["target"]["file"] or self.results["target"]["file"]["strings"] == []: + return False strings = self.results["target"]["file"]["strings"] data = ''.join(strings) for indicator in indicators: @@ -92,13 +98,14 @@ class suspiciousHTMLname(Signature): def run(self): - indicators = ['payment', - 'remittence', - 'invoice', - 'inv', - 'voicemail', - 'remit', - 'voice', + indicators = [ + 'payment', + 'remittence', + 'invoice', + 'inv', + 'voicemail', + 'remit', + 'voice', ] if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": @@ -124,6 +131,8 @@ class JSAtob(Signature): def run(self): if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": + if "strings" not in self.results["target"]["file"] or self.results["target"]["file"]["strings"] == []: + return False strings = self.results["target"]["file"]["strings"] data = ''.join(strings) if "atob" in str(data): @@ -150,7 +159,9 @@ class URLDecode(Signature): def run(self): if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": - data = self.results['target']['file']['data'] + if "strings" not in self.results["target"]["file"] or self.results["target"]["file"]["strings"] == []: + return False + data = self.results['target']['file']['strings'] if "decodeURIComponent" in data: return True return False @@ -170,6 +181,8 @@ class jsUnescape(Signature): def run(self): if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": + if "strings" not in self.results["target"]["file"] or self.results["target"]["file"]["strings"] == []: + return False strings = self.results["target"]["file"]["strings"] data = ''.join(strings) if "unescape" in str(data): From 2c225bd399c22001a5323fd16898330b118ec1e1 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 12 Apr 2023 09:19:11 +0200 Subject: [PATCH 056/145] Changes to rules --- modules/signatures/credential_access_phishingkit.py | 7 +++++-- modules/signatures/suspicious_html.py | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index 76c95e06..09cfd1df 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -86,8 +86,11 @@ def run(self): return False strings = self.results["target"]["file"]["strings"] data = ''.join(strings) - regex_decoded = r"unescape\(\'([^&]+?)\'\)\); </script>" - decodeString = re.search(regex_decoded,data) + regex_decoded_variant_0 = r"unescape\(\'([^&]+?)\'\)\); </script>" + regex_decoded_variant_1 = r"unescape\( \'([^&]+?)\' \) \);</script>" + decodeString = re.search(regex_decoded_variant_0,data) + if not decodeString: + decoded_string = re.search(regex_decoded_variant_1, data) if decodeString: decodeString = decodeString.group(1) decoded_string = Chepy(decodeString).url_decode().url_decode().o diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index 8c4a3094..ec10be21 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -115,6 +115,7 @@ def run(self): if indicator in lower: self.data.append({f"Found {indicator} in sample name"}) return True + return False class JSAtob(Signature): name = "suspicous_js_atob" From 97574d9ca3743abe01e3f3304d981d774a294281 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 12 Apr 2023 09:21:12 +0200 Subject: [PATCH 057/145] Changes to rules --- modules/signatures/binary_yara.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/signatures/binary_yara.py b/modules/signatures/binary_yara.py index 662a0209..34909c19 100644 --- a/modules/signatures/binary_yara.py +++ b/modules/signatures/binary_yara.py @@ -33,5 +33,5 @@ def run(self): self.description = "Binary file triggered YARA rule" for yara in yara_triggered: self.data.append({"Binary triggered YARA rule": yara["name"]}) - return True + return True return False \ No newline at end of file From df3f3e7fbe6995af89685b8f9125ed5aa4846623 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 12 Apr 2023 10:20:35 +0200 Subject: [PATCH 058/145] Changes to rules --- modules/signatures/windows_utilities.py | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/signatures/windows_utilities.py b/modules/signatures/windows_utilities.py index cc4b8882..7c6e719d 100644 --- a/modules/signatures/windows_utilities.py +++ b/modules/signatures/windows_utilities.py @@ -36,6 +36,7 @@ def on_call(self, _, process): if re.search(process["process_name"].lower(), lower): self.data.append({"command": cmdline}) return True + return False class UsesWindowsUtilities(Signature): name = "uses_windows_utilities" From b51fe8a0f46e934d180fd8f34307d923f0818c1b Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 12 Apr 2023 10:43:07 +0200 Subject: [PATCH 059/145] Changes to rules --- modules/signatures/suspicious_html.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index ec10be21..eb0f31eb 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -24,7 +24,7 @@ class htmlBody(Signature): confidence = 80 categories = ["phishing", "static"] authors = ["Yasin Tas", "Eye Security"] - enabled = True + enabled = False minimum = "1.2" ttps = ["T1566.001"] # MITRE v6,7,8 mbcs = ["C0029.003"] # micro-behaviour @@ -57,7 +57,7 @@ class htmlTitle(Signature): confidence = 80 categories = ["phishing", "static"] authors = ["Yasin Tas", "Eye Security"] - enabled = True + enabled = False minimum = "1.2" ttps = ["T1566.001"] # MITRE v6,7,8 mbcs = ["C0029.003"] # micro-behaviour @@ -91,7 +91,7 @@ class suspiciousHTMLname(Signature): confidence = 80 categories = ["phishing", "static"] authors = ["Yasin Tas", "Eye Security"] - enabled = True + enabled = False minimum = "1.2" ttps = ["T1566.001"] # MITRE v6,7,8 mbcs = ["C0029.003"] # micro-behaviour @@ -109,7 +109,7 @@ def run(self): ] if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": - name = self.results['target']['file']['name'] + name = self.results["target"]["file"]["name"] lower = name.lower() for indicator in indicators: if indicator in lower: @@ -124,7 +124,7 @@ class JSAtob(Signature): confidence = 70 categories = ["evasion","phishing", "static"] authors = ["Yasin Tas", "Eye Security"] - enabled = True + enabled = False minimum = "1.2" ttps = ["T1140"] # MITRE v6 ttps += ["T1566.001"] # MITRE v6,7,8 From f795c27118da86832115d1eaa03c3952b89ed627 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 12 Apr 2023 10:47:22 +0200 Subject: [PATCH 060/145] Changes to rules --- modules/signatures/suspicious_html.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index eb0f31eb..0a5e74eb 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -152,7 +152,7 @@ class URLDecode(Signature): confidence = 70 categories = ["evasion","phishing", "static"] authors = ["Yasin Tas", "Eye Security"] - enabled = True + enabled = False minimum = "1.2" ttps = ["T1140"] # MITRE v6 ttps += ["T1566.001"] # MITRE v6,7,8 @@ -174,7 +174,7 @@ class jsUnescape(Signature): confidence = 70 categories = ["evasion","phishing", "static"] authors = ["Yasin Tas", "Eye Security"] - enabled = True + enabled = False minimum = "1.2" ttps = ["T1140"] # MITRE v6 ttps += ["T1566.001"] # MITRE v6,7,8 From 2e6ef1c1c3b24aff603237c2c9ccf9acecbac0fb Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 12 Apr 2023 10:50:47 +0200 Subject: [PATCH 061/145] Changes to rules --- modules/signatures/suspicious_html.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index 0a5e74eb..4a084d0d 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -174,7 +174,7 @@ class jsUnescape(Signature): confidence = 70 categories = ["evasion","phishing", "static"] authors = ["Yasin Tas", "Eye Security"] - enabled = False + enabled = True minimum = "1.2" ttps = ["T1140"] # MITRE v6 ttps += ["T1566.001"] # MITRE v6,7,8 @@ -191,6 +191,6 @@ def run(self): self.confidence = self.confidence + (times_unescape * 5) if self.confidence >= 100: self.confidence = 100 - self.data.append({f"Found unescape {times_unescape} times"}) + self.data.append({f"Found unescape {str(times_unescape)} times"}) return True return False \ No newline at end of file From 33fd62238f8f8f690d9b52105fd98ed17440035c Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 12 Apr 2023 10:55:40 +0200 Subject: [PATCH 062/145] Changes to rules --- modules/signatures/suspicious_html.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index 4a084d0d..3dd00337 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -188,9 +188,11 @@ def run(self): data = ''.join(strings) if "unescape" in str(data): times_unescape = data.count("unescape") - self.confidence = self.confidence + (times_unescape * 5) - if self.confidence >= 100: + confidence = self.confidence + (times_unescape * 5) + if confidence >= 100: self.confidence = 100 - self.data.append({f"Found unescape {str(times_unescape)} times"}) + else: + self.confidence = confidence + self.data.append({f"Found unescape {times_unescape} times"}) return True return False \ No newline at end of file From fe9d7631b2040bc67cc4e6a8b1383521bfb01241 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 12 Apr 2023 11:00:33 +0200 Subject: [PATCH 063/145] Changes to rules --- modules/signatures/suspicious_html.py | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index 3dd00337..cc57cf5d 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -24,7 +24,7 @@ class htmlBody(Signature): confidence = 80 categories = ["phishing", "static"] authors = ["Yasin Tas", "Eye Security"] - enabled = False + enabled = True minimum = "1.2" ttps = ["T1566.001"] # MITRE v6,7,8 mbcs = ["C0029.003"] # micro-behaviour @@ -57,7 +57,7 @@ class htmlTitle(Signature): confidence = 80 categories = ["phishing", "static"] authors = ["Yasin Tas", "Eye Security"] - enabled = False + enabled = True minimum = "1.2" ttps = ["T1566.001"] # MITRE v6,7,8 mbcs = ["C0029.003"] # micro-behaviour @@ -91,7 +91,7 @@ class suspiciousHTMLname(Signature): confidence = 80 categories = ["phishing", "static"] authors = ["Yasin Tas", "Eye Security"] - enabled = False + enabled = True minimum = "1.2" ttps = ["T1566.001"] # MITRE v6,7,8 mbcs = ["C0029.003"] # micro-behaviour @@ -124,7 +124,7 @@ class JSAtob(Signature): confidence = 70 categories = ["evasion","phishing", "static"] authors = ["Yasin Tas", "Eye Security"] - enabled = False + enabled = True minimum = "1.2" ttps = ["T1140"] # MITRE v6 ttps += ["T1566.001"] # MITRE v6,7,8 @@ -152,7 +152,7 @@ class URLDecode(Signature): confidence = 70 categories = ["evasion","phishing", "static"] authors = ["Yasin Tas", "Eye Security"] - enabled = False + enabled = True minimum = "1.2" ttps = ["T1140"] # MITRE v6 ttps += ["T1566.001"] # MITRE v6,7,8 @@ -174,7 +174,7 @@ class jsUnescape(Signature): confidence = 70 categories = ["evasion","phishing", "static"] authors = ["Yasin Tas", "Eye Security"] - enabled = True + enabled = False minimum = "1.2" ttps = ["T1140"] # MITRE v6 ttps += ["T1566.001"] # MITRE v6,7,8 @@ -186,13 +186,6 @@ def run(self): return False strings = self.results["target"]["file"]["strings"] data = ''.join(strings) - if "unescape" in str(data): - times_unescape = data.count("unescape") - confidence = self.confidence + (times_unescape * 5) - if confidence >= 100: - self.confidence = 100 - else: - self.confidence = confidence - self.data.append({f"Found unescape {times_unescape} times"}) + if "unescape" in data: return True return False \ No newline at end of file From c2e4d809c43aed8836e0aec07502b32db4759300 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 12 Apr 2023 11:03:57 +0200 Subject: [PATCH 064/145] Changes to rules --- modules/signatures/suspicious_html.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index cc57cf5d..894386a7 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -174,7 +174,7 @@ class jsUnescape(Signature): confidence = 70 categories = ["evasion","phishing", "static"] authors = ["Yasin Tas", "Eye Security"] - enabled = False + enabled = True minimum = "1.2" ttps = ["T1140"] # MITRE v6 ttps += ["T1566.001"] # MITRE v6,7,8 From 191c2746ec3bf53541c39731f95230f06b5663e3 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 12 Apr 2023 11:11:57 +0200 Subject: [PATCH 065/145] Changes to rules --- modules/signatures/credential_access_phishingkit.py | 2 +- modules/signatures/suspicious_html.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index 09cfd1df..aeb9ecf3 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -90,7 +90,7 @@ def run(self): regex_decoded_variant_1 = r"unescape\( \'([^&]+?)\' \) \);</script>" decodeString = re.search(regex_decoded_variant_0,data) if not decodeString: - decoded_string = re.search(regex_decoded_variant_1, data) + decodeString = re.search(regex_decoded_variant_1, data) if decodeString: decodeString = decodeString.group(1) decoded_string = Chepy(decodeString).url_decode().url_decode().o diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index 894386a7..e0965e2c 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -149,7 +149,7 @@ class URLDecode(Signature): name = "suspicous_url_decode" description = "JS decode Detected, file is obfuscated" severity = 2 - confidence = 70 + confidence = 80 categories = ["evasion","phishing", "static"] authors = ["Yasin Tas", "Eye Security"] enabled = True @@ -171,7 +171,7 @@ class jsUnescape(Signature): name = "suspicous_js_unescape" description = "JS unescape Detected, file is obfuscated" severity = 2 - confidence = 70 + confidence = 80 categories = ["evasion","phishing", "static"] authors = ["Yasin Tas", "Eye Security"] enabled = True From 7dd3b27c3549ac115fd00fc6b654ee60ea192fdf Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 12 Apr 2023 11:18:38 +0200 Subject: [PATCH 066/145] Changes to rules --- .../credential_access_phishingkit.py | 44 ++++++++++--------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index aeb9ecf3..2db0e1cd 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -86,25 +86,27 @@ def run(self): return False strings = self.results["target"]["file"]["strings"] data = ''.join(strings) - regex_decoded_variant_0 = r"unescape\(\'([^&]+?)\'\)\); </script>" - regex_decoded_variant_1 = r"unescape\( \'([^&]+?)\' \) \);</script>" - decodeString = re.search(regex_decoded_variant_0,data) - if not decodeString: - decodeString = re.search(regex_decoded_variant_1, data) - if decodeString: - decodeString = decodeString.group(1) - decoded_string = Chepy(decodeString).url_decode().url_decode().o - self.description = "File obfuscation detected, with url encoding" - regex_user = r'value="([^&]+?)"' - regex_url = r"url: '([^&]+?)'," - user = re.search(regex_user,decoded_string) - url = re.search(regex_url,decoded_string) - if user and url: - self.weight = 3 - self.families = ["HTMLPhisher_2023"] - self.description = "Phishing kit detected, extracted config from sample" - self.data.append({"url": url.group(1)}) - self.data.append({"user": user.group(1)}) - return True - return False + regex_decoded = [ + r"unescape\(\'([^&]+?)\'\)\); </script>", + r"unescape\( \'([^&]+?)\' \) \);</script>", + r"unescape\(\'([^&]+?)\'\) \);</script>", + + for regex in regex_decoded: + decodeString = re.search(regex,data) + if decodeString: + decodeString = decodeString.group(1) + decoded_string = Chepy(decodeString).url_decode().url_decode().o + self.description = "File obfuscation detected, with url encoding" + regex_user = r'value="([^&]+?)"' + regex_url = r"url: '([^&]+?)'," + user = re.search(regex_user,decoded_string) + url = re.search(regex_url,decoded_string) + if user and url: + self.weight = 3 + self.families = ["HTMLPhisher_2023"] + self.description = "Phishing kit detected, extracted config from sample" + self.data.append({"url": url.group(1)}) + self.data.append({"user": user.group(1)}) + return True + return False From 4df423ba137e0ca38055fe9e519a3969e7dac488 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 12 Apr 2023 13:06:01 +0200 Subject: [PATCH 067/145] Changes to rules --- modules/signatures/credential_access_phishingkit.py | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index 2db0e1cd..068a8198 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -90,6 +90,7 @@ def run(self): r"unescape\(\'([^&]+?)\'\)\); </script>", r"unescape\( \'([^&]+?)\' \) \);</script>", r"unescape\(\'([^&]+?)\'\) \);</script>", + r"unescape\( \'([^&]+?)\'\) \);</script>", for regex in regex_decoded: decodeString = re.search(regex,data) From ab6bd64ce02d936be7685484d9691df6050f9d9a Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 12 Apr 2023 13:06:59 +0200 Subject: [PATCH 068/145] Changes to rules --- modules/signatures/credential_access_phishingkit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index 068a8198..12c3d423 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -91,7 +91,7 @@ def run(self): r"unescape\( \'([^&]+?)\' \) \);</script>", r"unescape\(\'([^&]+?)\'\) \);</script>", r"unescape\( \'([^&]+?)\'\) \);</script>", - + ] for regex in regex_decoded: decodeString = re.search(regex,data) if decodeString: From 7851a9df305477ac59e913c42da6447dd1fd1273 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 12 Apr 2023 13:13:03 +0200 Subject: [PATCH 069/145] Changes to rules --- modules/signatures/suspicious_html.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index e0965e2c..16337a06 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -121,7 +121,7 @@ class JSAtob(Signature): name = "suspicous_js_atob" description = "JS atob Detected, file is obfuscated" severity = 2 - confidence = 70 + confidence = 80 categories = ["evasion","phishing", "static"] authors = ["Yasin Tas", "Eye Security"] enabled = True From daabb82abb474e6f5fb8472557f0e4a2f5c845d1 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 19 Apr 2023 14:40:56 +0200 Subject: [PATCH 070/145] Improved YARA removed old rules, added new ones --- .yara-ci.yml | 3 +- data/yara/binaries/HTML_PhishingKit.yar | 73 ------------------- data/yara/binaries/OneNote_BuildPath.yar | 23 ------ .../credential_access_phishingkit.py | 13 +++- modules/signatures/suspicious_html.py | 38 ++++++++-- 5 files changed, 46 insertions(+), 104 deletions(-) delete mode 100644 data/yara/binaries/HTML_PhishingKit.yar delete mode 100644 data/yara/binaries/OneNote_BuildPath.yar diff --git a/.yara-ci.yml b/.yara-ci.yml index edd784f5..5433d0d9 100644 --- a/.yara-ci.yml +++ b/.yara-ci.yml @@ -10,6 +10,7 @@ false_positives: - rule: "shellcode_stack_strings" - rule: "shellcode_get_eip" - rule: "shellcode_peb_parsing" + - rule: "shellcode_patterns" - rule: "lsadump" - rule: "UPX" - - rule: "INDICATOR_EXE_Packed_Dotfuscator" + - rule: "INDICATOR_EXE_Packed_Dotfuscator" \ No newline at end of file diff --git a/data/yara/binaries/HTML_PhishingKit.yar b/data/yara/binaries/HTML_PhishingKit.yar deleted file mode 100644 index 62cdb1ee..00000000 --- a/data/yara/binaries/HTML_PhishingKit.yar +++ /dev/null @@ -1,73 +0,0 @@ -/* - YARA Rule Set for HTML phishing - Author: Yasin Tas, Eye Security - Date: 2023-04-05 - Identifier: Phish:HTML/Gen.*!html - Reference: Personal Research, Florian Roth yarGen -*/ - -rule CAPEHTML_Phish_1 { - meta: - description = "YARA detection for HTMLPhisher_2023" - author = "Yasin Tas, Eye Security" - reference = "Personal Research, Florian Roth yarGen" - date = "2023-04-05" - - strings: - $s1 = "74%20%32%73%20%69%6E%66%69%6E%69%74%65%7D%2E%70%72%6F%67%72%65%73%73%3E%64%69%76%3A%6E%74%68%2D%63%68%69%6C%64%28%31%29%7B%2D%77" ascii /* hex encoded string 't 2s infinite}.progress>div:nth-child(1){-w' */ - $s2 = "31%70%78%20%73%6F%6C%69%64%20%23%30%30%37%38%64%37%3B%62%6F%72%64%65%72%2D%74%6F%70%2D%77%69%64%74%68%3A%30%3B%62%6F%72%64%65%72" ascii /* hex encoded string '1px solid #0078d7;border-top-width:0;border' */ - $s3 = "72%6F%75%70%7B%66%6F%6E%74%2D%77%65%69%67%68%74%3A%37%30%30%7D%74%61%62%6C%65%7B%62%6F%72%64%65%72%2D%63%6F%6C%6C%61%70%73%65%3A" ascii /* hex encoded string 'roup{font-weight:700}table{border-collapse:' */ - $s4 = "73%20%73%68%6F%77%2D%66%72%6F%6D%2D%72%69%67%68%74%7B%66%72%6F%6D%7B%6C%65%66%74%3A%32%30%30%70%78%3B%6F%70%61%63%69%74%79%3A%30" ascii /* hex encoded string 's show-from-right{from{left:200px;opacity:0' */ - $s5 = "63%6F%6C%6F%72%3A%23%62%33%62%33%62%33%3B%62%61%63%6B%67%72%6F%75%6E%64%2D%63%6F%6C%6F%72%3A%72%67%62%61%28%30%2C%30%2C%30%2C%2E" ascii /* hex encoded string 'color:#b3b3b3;background-color:rgba(0,0,0,.' */ - $s6 = "65%2C%2E%69%6E%70%75%74%2D%67%72%6F%75%70%2D%62%74%6E%3A%6C%61%73%74%2D%63%68%69%6C%64%3E%2E%62%74%6E%2D%67%72%6F%75%70%3A%6E%6F" ascii /* hex encoded string 'e,.input-group-btn:last-child>.btn-group:no' */ - $s7 = "3A%35%70%78%3B%77%69%64%74%68%3A%35%70%78%3B%62%61%63%6B%67%72%6F%75%6E%64%2D%63%6F%6C%6F%72%3A%23%30%30%36%37%62%38%3B%7A%2D%69" ascii /* hex encoded string ':5px;width:5px;background-color:#0067b8;z-i' */ - $s8 = "7B%61%6E%69%6D%61%74%69%6F%6E%2D%64%75%72%61%74%69%6F%6E%3A%2E%32%35%73%3B%2D%77%65%62%6B%69%74%2D%61%6E%69%6D%61%74%69%6F%6E%2D" ascii /* hex encoded string '{animation-duration:.25s;-webkit-animation-' */ - $s9 = "31%2E%37%35%72%65%6D%3B%70%61%64%64%69%6E%67%2D%62%6F%74%74%6F%6D%3A%32%2E%33%36%70%78%3B%70%61%64%64%69%6E%67%2D%74%6F%70%3A%32" ascii /* hex encoded string '1.75rem;padding-bottom:2.36px;padding-top:2' */ - $s10 = "2E%31%36%36%36%37%25%7D%2E%63%6F%6C%2D%6D%64%2D%70%75%73%68%2D%31%34%7B%6C%65%66%74%3A%35%38%2E%33%33%33%33%33%25%7D%2E%63%6F%6C" ascii /* hex encoded string '.16667%}.col-md-push-14{left:58.33333%}.col' */ - $s11 = "65%66%74%3A%35%30%25%7D%2E%63%6F%6C%2D%6C%67%2D%6F%66%66%73%65%74%2D%31%33%7B%6D%61%72%67%69%6E%2D%6C%65%66%74%3A%35%34%2E%31%36" ascii /* hex encoded string 'eft:50%}.col-lg-offset-13{margin-left:54.16' */ - $s12 = "66%66%73%65%74%3A%2D%32%70%78%3B%6F%75%74%6C%69%6E%65%3A%35%70%78%20%61%75%74%6F%20%2D%77%65%62%6B%69%74%2D%66%6F%63%75%73%2D%72" ascii /* hex encoded string 'ffset:-2px;outline:5px auto -webkit-focus-r' */ - $s13 = "69%63%61%6C%2D%61%6C%69%67%6E%3A%6D%69%64%64%6C%65%7D%2E%64%69%61%6C%6F%67%2D%6F%75%74%65%72%20%2E%64%69%61%6C%6F%67%2D%6D%69%64" ascii /* hex encoded string 'ical-align:middle}.dialog-outer .dialog-mid' */ - $s14 = "70%61%63%69%74%79%3A%30%7D%7D%40%2D%6D%6F%7A%2D%6B%65%79%66%72%61%6D%65%73%20%70%72%6F%67%72%65%73%73%44%6F%74%7B%30%25%2C%32%30" ascii /* hex encoded string 'pacity:0}}@-moz-keyframes progressDot{0%,20' */ - $s15 = "6E%61%6D%65%3A%68%69%64%65%2D%74%6F%2D%72%69%67%68%74%7D%68%74%6D%6C%5B%64%69%72%3D%6C%74%72%5D%20%2E%61%6E%69%6D%61%74%65%2E%73" ascii /* hex encoded string 'name:hide-to-right}html[dir=ltr] .animate.s' */ - $s16 = "2D%77%65%62%6B%69%74%2D%70%6C%61%63%65%68%6F%6C%64%65%72%2C%69%6E%70%75%74%5B%74%79%70%65%3D%63%6F%6C%6F%72%5D%3A%3A%2D%77%65%62" ascii /* hex encoded string '-webkit-placeholder,input[type=color]::-web' */ - $s17 = "33%70%78%20%32%30%70%78%3B%66%6F%6E%74%2D%73%69%7A%65%3A%31%32%70%78%3B%6C%69%6E%65%2D%68%65%69%67%68%74%3A%31%2E%34%32%38%35%37" ascii /* hex encoded string '3px 20px;font-size:12px;line-height:1.42857' */ - $s18 = "3B%2D%77%65%62%6B%69%74%2D%62%6F%78%2D%73%68%61%64%6F%77%3A%30%20%32%70%78%20%36%70%78%20%72%67%62%61%28%30%2C%30%2C%30%2C%2E%32" ascii /* hex encoded string ';-webkit-box-shadow:0 2px 6px rgba(0,0,0,.2' */ - $s19 = "33%33%33%25%7D%2E%63%6F%6C%2D%6C%67%2D%70%75%73%68%2D%31%35%7B%6C%65%66%74%3A%36%32%2E%35%25%7D%2E%63%6F%6C%2D%6C%67%2D%70%75%73" ascii /* hex encoded string '333%}.col-lg-push-15{left:62.5%}.col-lg-pus' */ - $s20 = "74%69%74%6C%65%2E%74%65%78%74%2D%6D%61%78%6C%69%6E%65%73%2D%34%7B%6D%61%78%2D%68%65%69%67%68%74%3A%38%30%2E%34%35%70%78%3B%6D%61" ascii /* hex encoded string 'title.text-maxlines-4{max-height:80.45px;ma' */ - condition: - ( uint16(0) == 0x733c and filesize < 1000KB and ( 8 of them ) - ) or ( all of them ) -} - -rule CAPEHTML_Phish_2 { - meta: - description = "YARA detection for HTMLPhisher_2023" - author = "Yasin Tas, Eye Security" - reference = "Personal Research, Florian Roth yarGen" - date = "2023-04-05" - - strings: - $s1 = "30%25%32%30%25%32%30%25%37%64%25%30%64%25%30%61%25%30%64%25%30%61%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30" ascii /* hex encoded string '0%20%20%7d%0d%0a%0d%0a%20%20%20%20%20%20%20' */ - $s2 = "32%30%25%37%33%25%37%32%25%36%33%25%33%64%25%32%32%25%36%38%25%37%34%25%37%34%25%37%30%25%37%33%25%33%61%25%32%66%25%32%66%25%36" ascii /* hex encoded string '20%73%72%63%3d%22%68%74%74%70%73%3a%2f%2f%6' */ - $s3 = "25%32%30%25%32%30%25%32%30%25%32%30%25%32%65%25%36%32%25%37%34%25%36%65%25%32%64%25%36%66%25%37%35%25%37%34%25%36%63%25%36%39%25" ascii /* hex encoded string '%20%20%20%20%2e%62%74%6e%2d%6f%75%74%6c%69%' */ - $s4 = "32%64%25%36%37%25%37%32%25%36%66%25%37%35%25%37%30%25%32%64%25%36%39%25%37%34%25%36%35%25%36%64%25%32%64%25%37%33%25%37%35%25%36" ascii /* hex encoded string '2d%67%72%6f%75%70%2d%69%74%65%6d%2d%73%75%6' */ - $s5 = "36%33%25%36%66%25%36%65%25%37%34%25%36%35%25%36%65%25%37%34%25%32%64%25%36%63%25%36%37%25%32%64%25%36%33%25%36%35%25%36%65%25%37" ascii /* hex encoded string '63%6f%6e%74%65%6e%74%2d%6c%67%2d%63%65%6e%7' */ - $s6 = "25%32%30%25%32%30%25%37%36%25%36%39%25%37%33%25%36%39%25%36%32%25%36%39%25%36%63%25%36%39%25%37%34%25%37%39%25%33%61%25%32%30%25" ascii /* hex encoded string '%20%20%76%69%73%69%62%69%6c%69%74%79%3a%20%' */ - $s7 = "25%37%30%25%32%64%25%37%34%25%36%35%25%37%38%25%37%34%25%32%62%25%32%65%25%36%39%25%36%65%25%37%30%25%37%35%25%37%34%25%32%64%25" ascii /* hex encoded string '%70%2d%74%65%78%74%2b%2e%69%6e%70%75%74%2d%' */ - $s8 = "36%39%25%36%37%25%36%65%25%32%64%25%37%33%25%36%35%25%36%63%25%36%36%25%32%64%25%37%33%25%36%64%25%32%64%25%36%35%25%36%65%25%36" ascii /* hex encoded string '69%67%6e%2d%73%65%6c%66%2d%73%6d%2d%65%6e%6' */ - $s9 = "66%25%36%39%25%36%65%25%37%34%25%32%64%25%36%63%25%36%37%25%33%61%25%32%30%25%33%39%25%33%39%25%33%32%25%37%30%25%37%38%25%33%62" ascii /* hex encoded string 'f%69%6e%74%2d%6c%67%3a%20%39%39%32%70%78%3b' */ - $s10 = "32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%64%25%36%64%25%36" ascii /* hex encoded string '20%20%20%20%20%20%20%20%20%20%20%20%2d%6d%6' */ - $s11 = "37%36%25%33%65%25%30%64%25%30%61%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32" ascii /* hex encoded string '76%3e%0d%0a%20%20%20%20%20%20%20%20%20%20%2' */ - $s12 = "65%25%33%36%25%33%36%25%33%36%25%33%36%25%33%36%25%33%37%25%32%35%25%30%64%25%30%61%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30" ascii /* hex encoded string 'e%36%36%36%36%36%37%25%0d%0a%20%20%20%20%20' */ - $s13 = "25%36%35%25%33%62%25%30%64%25%30%61%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%37%34%25%36%35%25" ascii /* hex encoded string '%65%3b%0d%0a%20%20%20%20%20%20%20%20%74%65%' */ - $s14 = "36%31%25%36%63%25%32%64%25%36%37%25%37%32%25%36%66%25%37%35%25%37%30%25%33%61%25%32%30%25%33%30%25%33%62%25%30%64%25%30%61%25%32" ascii /* hex encoded string '61%6c%2d%67%72%6f%75%70%3a%20%30%3b%0d%0a%2' */ - $s15 = "30%25%32%30%25%32%30%25%32%30%25%32%65%25%36%66%25%36%36%25%36%36%25%37%33%25%36%35%25%37%34%25%32%64%25%37%33%25%36%64%25%32%64" ascii /* hex encoded string '0%20%20%20%2e%6f%66%66%73%65%74%2d%73%6d%2d' */ - $s16 = "32%25%36%37%25%36%39%25%36%65%25%33%61%25%32%30%25%33%33%25%37%32%25%36%35%25%36%64%25%32%30%25%32%31%25%36%39%25%36%64%25%37%30" ascii /* hex encoded string '2%67%69%6e%3a%20%33%72%65%6d%20%21%69%6d%70' */ - $s17 = "25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25%37%61%25%32%64%25%36%39%25%36%65%25%36%34%25%36%35%25" ascii /* hex encoded string '%20%20%20%20%20%20%20%20%7a%2d%69%6e%64%65%' */ - $s18 = "25%36%39%25%36%65%25%32%64%25%37%37%25%36%39%25%36%34%25%37%34%25%36%38%25%33%61%25%33%39%25%33%39%25%33%32%25%37%30%25%37%38%25" ascii /* hex encoded string '%69%6e%2d%77%69%64%74%68%3a%39%39%32%70%78%' */ - $s19 = "25%36%35%25%36%65%25%37%34%25%36%35%25%37%32%25%32%30%25%37%62%25%30%64%25%30%61%25%32%30%25%32%30%25%32%30%25%32%30%25%32%30%25" ascii /* hex encoded string '%65%6e%74%65%72%20%7b%0d%0a%20%20%20%20%20%' */ - $s20 = "25%32%30%25%32%33%25%36%36%25%33%38%25%36%36%25%33%39%25%36%36%25%36%31%25%33%62%25%30%64%25%30%61%25%32%30%25%32%30%25%32%30%25" ascii /* hex encoded string '%20%23%66%38%66%39%66%61%3b%0d%0a%20%20%20%' */ - condition: - ( uint16(0) == 0x733c and filesize < 7000KB and ( 8 of them ) - ) or ( all of them ) -} \ No newline at end of file diff --git a/data/yara/binaries/OneNote_BuildPath.yar b/data/yara/binaries/OneNote_BuildPath.yar deleted file mode 100644 index d83f3c38..00000000 --- a/data/yara/binaries/OneNote_BuildPath.yar +++ /dev/null @@ -1,23 +0,0 @@ -rule OneNote_BuildPath -{ - meta: - id = "6lPn0V5wZyc2iuEz13uKAZ" - fingerprint = "f8ed9e3cdd5411e2bda7495c8b00b8e69e8f495db97cf542f6a1f3b790bef7a5" - version = "1.0" - first_imported = "2023-02-02" - last_modified = "2023-02-23" - status = "RELEASED" - sharing = "TLP:WHITE" - source = "BARTBLAZE" - author = "@bartblaze" - description = "Identifies malicious OneNote file by build path." - category = "MALWARE" - -strings: - //Z:\build\one\attachment.hta - $path_0 = {5a003a005c006200750069006c0064005c006f006e0065005c006100740074006100630068006d0065006e0074002e00680074006100} - //Z:\builder\O P E N.wsf - $path_1 = {5a003a005c006200750069006c006400650072005c004f00200050002000450020004e002e00770073006600} -condition: - filesize <200KB and any of them -} \ No newline at end of file diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index 12c3d423..9928320f 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -31,6 +31,11 @@ class HTMLPhisher_0(Signature): confidence = 100 categories = ["credential_access","evasion","infostealer","phishing", "static"] authors = ["Yasin Tas", "Eye Security"] + references = [ + "https://securelist.com/phishing-kit-market-whats-inside-off-the-shelf-phishing-packages/106149/", + "https://socradar.io/what-is-a-phishing-kit/" + "https://github.com/SteveD3/kit_hunter/tree/master/tag_files" + ] enabled = True minimum = "1.2" ttps = ["T1111", "T1193", "T1140"] # MITRE v6 @@ -73,6 +78,11 @@ class HTMLPhisher_1(Signature): confidence = 100 categories = ["credential_access","evasion","infostealer","phishing", "static"] authors = ["Yasin Tas", "Eye Security"] + references = [ + "https://securelist.com/phishing-kit-market-whats-inside-off-the-shelf-phishing-packages/106149/", + "https://socradar.io/what-is-a-phishing-kit/" + "https://github.com/SteveD3/kit_hunter/tree/master/tag_files" + ] enabled = True minimum = "1.2" ttps = ["T1111", "T1193", "T1140"] # MITRE v6 @@ -109,5 +119,4 @@ def run(self): self.data.append({"url": url.group(1)}) self.data.append({"user": user.group(1)}) return True - return False - + return False \ No newline at end of file diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index 16337a06..b71982f3 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -24,6 +24,12 @@ class htmlBody(Signature): confidence = 80 categories = ["phishing", "static"] authors = ["Yasin Tas", "Eye Security"] + references = [ + "https://securelist.com/phishing-kit-market-whats-inside-off-the-shelf-phishing-packages/106149/", + "https://socradar.io/what-is-a-phishing-kit/" + "https://github.com/SteveD3/kit_hunter/tree/master/tag_files" + ] + references = [""] enabled = True minimum = "1.2" ttps = ["T1566.001"] # MITRE v6,7,8 @@ -37,6 +43,8 @@ def run(self): 'username', 'encoded_string', 'url', + 'emails' + '// remove email, and put ur mailer code', ] if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": @@ -57,6 +65,11 @@ class htmlTitle(Signature): confidence = 80 categories = ["phishing", "static"] authors = ["Yasin Tas", "Eye Security"] + references = [ + "https://securelist.com/phishing-kit-market-whats-inside-off-the-shelf-phishing-packages/106149/", + "https://socradar.io/what-is-a-phishing-kit/" + "https://github.com/SteveD3/kit_hunter/tree/master/tag_files" + ] enabled = True minimum = "1.2" ttps = ["T1566.001"] # MITRE v6,7,8 @@ -91,6 +104,11 @@ class suspiciousHTMLname(Signature): confidence = 80 categories = ["phishing", "static"] authors = ["Yasin Tas", "Eye Security"] + references = [ + "https://securelist.com/phishing-kit-market-whats-inside-off-the-shelf-phishing-packages/106149/", + "https://socradar.io/what-is-a-phishing-kit/" + "https://github.com/SteveD3/kit_hunter/tree/master/tag_files" + ] enabled = True minimum = "1.2" ttps = ["T1566.001"] # MITRE v6,7,8 @@ -124,6 +142,11 @@ class JSAtob(Signature): confidence = 80 categories = ["evasion","phishing", "static"] authors = ["Yasin Tas", "Eye Security"] + references = [ + "https://securelist.com/phishing-kit-market-whats-inside-off-the-shelf-phishing-packages/106149/", + "https://socradar.io/what-is-a-phishing-kit/" + "https://github.com/SteveD3/kit_hunter/tree/master/tag_files" + ] enabled = True minimum = "1.2" ttps = ["T1140"] # MITRE v6 @@ -137,11 +160,6 @@ def run(self): strings = self.results["target"]["file"]["strings"] data = ''.join(strings) if "atob" in str(data): - times_atob = data.count("atob") - self.confidence = self.confidence + (times_atob * 5) - if self.confidence >= 100: - self.confidence = 100 - self.data.append({f"Found atob {times_atob} times"}) return True return False @@ -152,6 +170,11 @@ class URLDecode(Signature): confidence = 80 categories = ["evasion","phishing", "static"] authors = ["Yasin Tas", "Eye Security"] + references = [ + "https://securelist.com/phishing-kit-market-whats-inside-off-the-shelf-phishing-packages/106149/", + "https://socradar.io/what-is-a-phishing-kit/" + "https://github.com/SteveD3/kit_hunter/tree/master/tag_files" + ] enabled = True minimum = "1.2" ttps = ["T1140"] # MITRE v6 @@ -174,6 +197,11 @@ class jsUnescape(Signature): confidence = 80 categories = ["evasion","phishing", "static"] authors = ["Yasin Tas", "Eye Security"] + references = [ + "https://securelist.com/phishing-kit-market-whats-inside-off-the-shelf-phishing-packages/106149/", + "https://socradar.io/what-is-a-phishing-kit/" + "https://github.com/SteveD3/kit_hunter/tree/master/tag_files" + ] enabled = True minimum = "1.2" ttps = ["T1140"] # MITRE v6 From 03eafaff94a2a9a48fee978e7d142464cb944694 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 19 Apr 2023 14:43:51 +0200 Subject: [PATCH 071/145] Removed signatures as they are integrated with YARA --- modules/signatures/suspicious_html.py | 83 --------------------------- 1 file changed, 83 deletions(-) diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index b71982f3..76ae4f27 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -133,87 +133,4 @@ def run(self): if indicator in lower: self.data.append({f"Found {indicator} in sample name"}) return True - return False - -class JSAtob(Signature): - name = "suspicous_js_atob" - description = "JS atob Detected, file is obfuscated" - severity = 2 - confidence = 80 - categories = ["evasion","phishing", "static"] - authors = ["Yasin Tas", "Eye Security"] - references = [ - "https://securelist.com/phishing-kit-market-whats-inside-off-the-shelf-phishing-packages/106149/", - "https://socradar.io/what-is-a-phishing-kit/" - "https://github.com/SteveD3/kit_hunter/tree/master/tag_files" - ] - enabled = True - minimum = "1.2" - ttps = ["T1140"] # MITRE v6 - ttps += ["T1566.001"] # MITRE v6,7,8 - mbcs = ["C0029.003"] # micro-behaviour - - def run(self): - if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": - if "strings" not in self.results["target"]["file"] or self.results["target"]["file"]["strings"] == []: - return False - strings = self.results["target"]["file"]["strings"] - data = ''.join(strings) - if "atob" in str(data): - return True - return False - -class URLDecode(Signature): - name = "suspicous_url_decode" - description = "JS decode Detected, file is obfuscated" - severity = 2 - confidence = 80 - categories = ["evasion","phishing", "static"] - authors = ["Yasin Tas", "Eye Security"] - references = [ - "https://securelist.com/phishing-kit-market-whats-inside-off-the-shelf-phishing-packages/106149/", - "https://socradar.io/what-is-a-phishing-kit/" - "https://github.com/SteveD3/kit_hunter/tree/master/tag_files" - ] - enabled = True - minimum = "1.2" - ttps = ["T1140"] # MITRE v6 - ttps += ["T1566.001"] # MITRE v6,7,8 - mbcs = ["C0029.003"] # micro-behaviour - - def run(self): - if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": - if "strings" not in self.results["target"]["file"] or self.results["target"]["file"]["strings"] == []: - return False - data = self.results['target']['file']['strings'] - if "decodeURIComponent" in data: - return True - return False - -class jsUnescape(Signature): - name = "suspicous_js_unescape" - description = "JS unescape Detected, file is obfuscated" - severity = 2 - confidence = 80 - categories = ["evasion","phishing", "static"] - authors = ["Yasin Tas", "Eye Security"] - references = [ - "https://securelist.com/phishing-kit-market-whats-inside-off-the-shelf-phishing-packages/106149/", - "https://socradar.io/what-is-a-phishing-kit/" - "https://github.com/SteveD3/kit_hunter/tree/master/tag_files" - ] - enabled = True - minimum = "1.2" - ttps = ["T1140"] # MITRE v6 - ttps += ["T1566.001"] # MITRE v6,7,8 - mbcs = ["C0029.003"] # micro-behaviour - - def run(self): - if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": - if "strings" not in self.results["target"]["file"] or self.results["target"]["file"]["strings"] == []: - return False - strings = self.results["target"]["file"]["strings"] - data = ''.join(strings) - if "unescape" in data: - return True return False \ No newline at end of file From 33a4e35f2a7a793683d8604f502783d4449247a8 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 19 Apr 2023 14:47:48 +0200 Subject: [PATCH 072/145] Improved Binary YARA --- modules/signatures/binary_yara.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/modules/signatures/binary_yara.py b/modules/signatures/binary_yara.py index 34909c19..3482f235 100644 --- a/modules/signatures/binary_yara.py +++ b/modules/signatures/binary_yara.py @@ -17,21 +17,25 @@ class BinaryTriggeredYARA(Signature): name = "binary_yara" - description = "Binary file triggered multiple YARA rule(s)" + description = "Binary file triggered YARA rule" severity = 3 - confidence = 50 + confidence = 80 weight = 1 categories = ["static"] authors = ["Yasin Tas", "Eye Security"] minimum = "1.3" def run(self): + count = 0 if self.results["target"]["file"]["yara"]: yara_triggered = self.results["target"]["file"]["yara"] if yara_triggered != []: - if len(yara_triggered) == 1: - self.description = "Binary file triggered YARA rule" for yara in yara_triggered: self.data.append({"Binary triggered YARA rule": yara["name"]}) + count += 1 + if count > 1: + self.description = "Binary file triggered multiple YARA rules" + if count > 3: + self.weight = 3 return True return False \ No newline at end of file From c3f0c81c71a063c1b5e450aef55d593c241ede97 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 19 Apr 2023 15:04:17 +0200 Subject: [PATCH 073/145] Improved YARA removed old rules, added new ones --- data/yara/binaries/HTMLPhisher_2023.yar | 116 ++++++++++ data/yara/binaries/OneNote.yar | 276 ++++++++++++++++++++++++ 2 files changed, 392 insertions(+) create mode 100644 data/yara/binaries/HTMLPhisher_2023.yar create mode 100644 data/yara/binaries/OneNote.yar diff --git a/data/yara/binaries/HTMLPhisher_2023.yar b/data/yara/binaries/HTMLPhisher_2023.yar new file mode 100644 index 00000000..ee3d7dad --- /dev/null +++ b/data/yara/binaries/HTMLPhisher_2023.yar @@ -0,0 +1,116 @@ +/* + YARA Rule Set for HTML phishing + Author: Yasin Tas, Eye Security + Date: 2023-04-05 + Identifier: HTMLPhisher_2023 + Reference: Personal Research +*/ +rule susp_documentwrite_HTML { + meta: + description = "Detection for document.write in HTML files" + author = "Yasin Tas, Eye Security" + reference = "Personal Research" + + strings: + $html_magic = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } + $script_magic0 = { 3C 73 63 72 69 70 74 3E } + $script_magic1 = { 3C 73 63 72 69 70 74 20 } + + $document_write = { 64 6F 63 75 6D 65 6E 74 2E 77 72 69 74 65 } + + condition: + $html_magic or $script_magic0 or $script_magic1 at 0 + and $document_write +} + +rule susp_obfuscated_HTML_atob_btoa { + meta: + description = "Detection for JS atob in HTML files" + author = "Yasin Tas, Eye Security" + reference = "Personal Research" + + strings: + $html_magic = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } + $script_magic0 = { 3C 73 63 72 69 70 74 3E } + $script_magic1 = { 3C 73 63 72 69 70 74 20 } + + $atob = { 61 74 6f 62 } + $btoa = { 62 74 6f 61 } + + condition: + $html_magic or $script_magic0 or $script_magic1 at 0 + and ($atob or $btoa) +} + +rule susp_obfuscated_HTML_eval { + meta: + description = "Detection for JS eval in HTML files" + author = "Yasin Tas, Eye Security" + reference = "Personal Research" + + strings: + $html_magic = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } + $script_magic0 = { 3C 73 63 72 69 70 74 3E } + $script_magic1 = { 3C 73 63 72 69 70 74 20 } + + $eval = { 65 76 61 6c } + + condition: + $html_magic or $script_magic0 or $script_magic1 at 0 + and $eval +} + +rule susp_obfuscated_HTML_fromCharCode { + meta: + description = "Detection for JS fromCharcode in HTML files" + author = "Yasin Tas, Eye Security" + reference = "Personal Research" + + strings: + $html_magic = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } + $script_magic0 = { 3C 73 63 72 69 70 74 3E } + $script_magic1 = { 3C 73 63 72 69 70 74 20 } + + $fromCharCode = { 66 72 6f 6d 43 68 61 72 43 6f 64 65 } + + condition: + $html_magic or $script_magic0 or $script_magic1 at 0 + and $fromCharCode +} + +rule susp_obfuscated_HTML_unescape_escape { + meta: + description = "Detection for JS escape or unescape in HTML files" + author = "Yasin Tas, Eye Security" + reference = "Personal Research" + + strings: + $html_magic = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } + $script_magic0 = { 3C 73 63 72 69 70 74 3E } + $script_magic1 = { 3C 73 63 72 69 70 74 20 } + + $unescape = { 75 6e 65 73 63 61 70 65 } + $escape = { 65 73 63 61 70 65 } + + condition: + $html_magic or $script_magic0 or $script_magic1 at 0 + and ($unescape or $escape) +} + +rule susp_obfuscated_HTML_decodeURIComponent { + meta: + description = "Detection for JS decodeURIComponent in HTML files" + author = "Yasin Tas, Eye Security" + reference = "Personal Research" + + strings: + $html_magic = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } + $script_magic0 = { 3C 73 63 72 69 70 74 3E } + $script_magic1 = { 3C 73 63 72 69 70 74 20 } + + $decodeURIComponent = { 64 65 63 6f 64 65 55 52 49 43 6f 6d 70 6f 6e 65 6e 74 } + + condition: + $html_magic or $script_magic0 or $script_magic1 at 0 + and $decodeURIComponent +} diff --git a/data/yara/binaries/OneNote.yar b/data/yara/binaries/OneNote.yar new file mode 100644 index 00000000..819cfbe1 --- /dev/null +++ b/data/yara/binaries/OneNote.yar @@ -0,0 +1,276 @@ +/* + YARA Rule Set for OneNote Files +*/ +rule susp_embedded_OneNote_files{ + meta: + description = "Detects suspicious embedded files in OneNote files" + author = "Yasin Tas, Eye Security" + reference = "Personal Research" + date = "2023-01-27" + + strings: + // + + condition: + any of them +} +rule SUSP_Email_Suspicious_OneNote_Attachment_Jan23_1 { + meta: + description = "Detects suspicious OneNote attachment that embeds suspicious payload, e.g. an executable (FPs possible if the PE is attached separately)" + author = "Florian Roth (Nextron Systems)" + reference = "Internal Research" + date = "2023-01-27" + score = 65 + strings: + /* OneNote FileDataStoreObject GUID https://blog.didierstevens.com/ */ + $ge1 = "5xbjvWUmEUWkxI1NC3qer" + $ge2 = "cW471lJhFFpMSNTQt6nq" + $ge3 = "nFuO9ZSYRRaTEjU0Lep6s" + /* PE file DOS header */ + $sp1 = "VGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1vZG" + $sp2 = "RoaXMgcHJvZ3JhbSBjYW5ub3QgYmUgcnVuIGluIERPUyBtb2Rl" + $sp3 = "UaGlzIHByb2dyYW0gY2Fubm90IGJlIHJ1biBpbiBET1MgbW9kZ" + $sp4 = "VGhpcyBwcm9ncmFtIG11c3QgYmUgcnVuIHVuZGVy" + $sp5 = "RoaXMgcHJvZ3JhbSBtdXN0IGJlIHJ1biB1bmRlc" + $sp6 = "UaGlzIHByb2dyYW0gbXVzdCBiZSBydW4gdW5kZX" + /* @echo off */ + $se1 = "QGVjaG8gb2Zm" + $se2 = "BlY2hvIG9mZ" + $se3 = "AZWNobyBvZm" + /* <HTA:APPLICATION */ + $se4 = "PEhUQTpBUFBMSUNBVElPTi" + $se5 = "xIVEE6QVBQTElDQVRJT04g" + $se6 = "8SFRBOkFQUExJQ0FUSU9OI" + /* LNK file magic header */ + $se7 = "TAAAAAEUAg" + $se8 = "wAAAABFAIA" + $se9 = "MAAAAARQCA" + condition: + filesize < 5MB + and 1 of ($ge*) + and 1 of ($s*) +} + +rule SUSP_Email_Suspicious_OneNote_Attachment_Jan23_2 { + meta: + description = "Detects suspicious OneNote attachment that has a file name often used in phishing attacks" + author = "Florian Roth (Nextron Systems)" + reference = "Internal Research" + date = "2023-01-27" + score = 65 + strings: + /* .one\n\n5FJce */ + $hc1 = { 2E 6F 6E 65 22 0D 0A 0D 0A 35 46 4A 63 65 } + $x01 = " attachment; filename=\"Invoice" nocase + $x02 = " attachment; filename=\"ORDER" nocase + $x03 = " attachment; filename=\"PURCHASE" nocase + $x04 = " attachment; filename=\"SHIP" nocase + condition: + filesize < 5MB + and $hc1 + and 1 of ($x*) +} + +rule SUSP_OneNote_Embedded_FileDataStoreObject_Type_Jan23_1 { + meta: + description = "Detects suspicious embedded file types in OneNote files" + author = "Florian Roth" + reference = "https://blog.didierstevens.com/" + date = "2023-01-27" + modified = "2023-02-27" + score = 65 + strings: + /* GUID FileDataStoreObject https://blog.didierstevens.com/ */ + $x1 = { e7 16 e3 bd 65 26 11 45 a4 c4 8d 4d 0b 7a 9e ac + ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? + ?? ?? ?? ?? 4d 5a } // PE + $x2 = { e7 16 e3 bd 65 26 11 45 a4 c4 8d 4d 0b 7a 9e ac + ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? + ?? ?? ?? ?? [0-4] 40 65 63 68 6f } // @echo off + $x3 = { e7 16 e3 bd 65 26 11 45 a4 c4 8d 4d 0b 7a 9e ac + ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? + ?? ?? ?? ?? [0-4] 40 45 43 48 4f } // @ECHO OFF + $x4 = { e7 16 e3 bd 65 26 11 45 a4 c4 8d 4d 0b 7a 9e ac + ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? + ?? ?? ?? ?? [0-4] 4F 6E 20 45 } // On Error Resume + $x5 = { e7 16 e3 bd 65 26 11 45 a4 c4 8d 4d 0b 7a 9e ac + ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? + ?? ?? ?? ?? [0-4] 6F 6E 20 65 } // on error resume + $x6 = { e7 16 e3 bd 65 26 11 45 a4 c4 8d 4d 0b 7a 9e ac + ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? + ?? ?? ?? ?? 4c 00 00 00 } // LNK file + $x7 = { e7 16 e3 bd 65 26 11 45 a4 c4 8d 4d 0b 7a 9e ac + ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? + ?? ?? ?? ?? 49 54 53 46 } // CHM file + $x8 = { e7 16 e3 bd 65 26 11 45 a4 c4 8d 4d 0b 7a 9e ac + ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? + ?? ?? ?? ?? [6-200] 3C 68 74 61 3A } // hta: + $x9 = { e7 16 e3 bd 65 26 11 45 a4 c4 8d 4d 0b 7a 9e ac + ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? + ?? ?? ?? ?? [6-200] 3C 48 54 41 3A } // HTA: + $x10 = { e7 16 e3 bd 65 26 11 45 a4 c4 8d 4d 0b 7a 9e ac + ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? + ?? ?? ?? ?? [6-200] 3C 6A 6F 62 20 } // WSF file "<job " + condition: + filesize < 10MB and 1 of them +} + +rule SUSP_OneNote_Embedded_FileDataStoreObject_Type_Jan23_2 { + meta: + description = "Detects suspicious embedded file types in OneNote files" + author = "Florian Roth (Nextron Systems)" + reference = "https://blog.didierstevens.com/" + date = "2023-01-27" + score = 65 + strings: + /* GUID FileDataStoreObject https://blog.didierstevens.com/ */ + $a1 = { 00 e7 16 e3 bd 65 26 11 45 a4 c4 8d 4d 0b 7a 9e ac } + $s1 = "<HTA:APPLICATION " + condition: + filesize < 5MB + and $a1 + and 1 of ($s*) +} + +rule SUSP_OneNote_Win_Script_Encoding_Feb23 { + meta: + description = "Presence of Windows Script Encoding Header in a OneNote file with embedded files" + author = "delivr.to" + date = "2023-02-19" + score = 60 + strings: + /* [MS-ONESTORE] File Header */ + $one = { E4 52 5C 7B 8C D8 A7 4D AE B1 53 78 D0 29 96 D3 } + + /* FileDataStoreObject GUID */ + $fdso = { 00 e7 16 e3 bd 65 26 11 45 a4 c4 8d 4d 0b 7a 9e ac } + + /* Windows Script Encoding Header */ + $wse = { 23 40 7E 5E } + + condition: + filesize < 5MB and + ($one at 0) and + $fdso and + $wse +} + +rule SUSP_OneNote_Repeated_FileDataReference_Feb23 { + meta: + description = "Repeated references to files embedded in OneNote file. May indicate multiple copies of file hidden under image, as leveraged by Qakbot et al." + author = "delivr.to" + date = "2023-02-17" + score = 60 + strings: + /* [MS-ONESTORE] File Header */ + $one = { E4 52 5C 7B 8C D8 A7 4D AE B1 53 78 D0 29 96 D3 } + + /* FileDataStoreObject GUID */ + $fdso = { 00 e7 16 e3 bd 65 26 11 45 a4 c4 8d 4d 0b 7a 9e ac } + + /* FileDataReference <ifndf>{GUID} */ + /* https://interoperability.blob.core.windows.net/files/MS-ONESTORE/%5bMS-ONESTORE%5d.pdf */ + $fref = { 3C 00 69 00 66 00 6E 00 64 00 66 00 3E 00 7B 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 2D 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 2D 00 ?? 00 ?? 00 ?? 00 ?? 00 2D 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? } + + condition: + filesize < 5MB and + ($one at 0) and + $fdso and + #fref > (#fdso * 4) +} + +rule SUSP_OneNote_RTLO_Character_Feb23 { + meta: + description = "Presence of RTLO Unicode Character in a OneNote file with embedded files" + author = "delivr.to" + date = "2023-02-17" + score = 60 + strings: + /* [MS-ONESTORE] File Header */ + $one = { E4 52 5C 7B 8C D8 A7 4D AE B1 53 78 D0 29 96 D3 } + + /* FileDataStoreObject GUID */ + $fdso = { 00 e7 16 e3 bd 65 26 11 45 a4 c4 8d 4d 0b 7a 9e ac } + + /* RTLO */ + $rtlo = { 00 2E 20 } + + condition: + filesize < 5MB and + ($one at 0) and + $fdso and + $rtlo +} + +rule OneNote_EmbeddedFiles_NoPictures +{ + meta: + author = "Nicholas Dhaeyer - @DhaeyerWolf" + date_created = "2023-02-14 - <3" + date_last_modified = "2023-02-17" + description = "OneNote files that contain embedded files that are not pictures." + reference = "https://blog.didierstevens.com/2023/01/22/analyzing-malicious-onenote-documents/" + yarahub_uuid = "d0c4f0e6-adbe-4953-a2df-91427a561e97" + date = "2023-02-14" + yarahub_license = "CC0 1.0" + yarahub_rule_matching_tlp = "TLP:WHITE" + yarahub_rule_sharing_tlp = "TLP:WHITE" + yarahub_reference_md5 = "52486a446dd4fc5842a47b57d3febec7" + + strings: + $start = { e4 52 5c 7b 8c d8 a7 4d ae b1 53 78 d0 29 96 d3 } //beginning of a OneNote file + + $EmbeddedFileGUID = { E7 16 E3 BD 65 26 11 45 A4 C4 8D 4D 0B 7A 9E AC } + $PNG = { E7 16 E3 BD 65 26 11 45 A4 C4 8D 4D 0B 7A 9E AC ?? ?? ?? ?? ?? ?? ?? ?? 00 00 00 00 00 00 00 00 00 00 00 00 89 50 4E 47 0D 0A 1A 0A } + $JPG = { E7 16 E3 BD 65 26 11 45 A4 C4 8D 4D 0B 7A 9E AC ?? ?? ?? ?? ?? ?? ?? ?? 00 00 00 00 00 00 00 00 00 00 00 00 FF D8 FF } + $JPG20001 = { E7 16 E3 BD 65 26 11 45 A4 C4 8D 4D 0B 7A 9E AC ?? ?? ?? ?? ?? ?? ?? ?? 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 6A 50 20 20 0D 0A 87 0A } + $JPG20002 = { E7 16 E3 BD 65 26 11 45 A4 C4 8D 4D 0B 7A 9E AC ?? ?? ?? ?? ?? ?? ?? ?? 00 00 00 00 00 00 00 00 00 00 00 00 FF 4F FF 51 } + $BMP = { E7 16 E3 BD 65 26 11 45 A4 C4 8D 4D 0B 7A 9E AC ?? ?? ?? ?? ?? ?? ?? ?? 00 00 00 00 00 00 00 00 00 00 00 00 42 4D } + $GIF = { E7 16 E3 BD 65 26 11 45 A4 C4 8D 4D 0B 7A 9E AC ?? ?? ?? ?? ?? ?? ?? ?? 00 00 00 00 00 00 00 00 00 00 00 00 47 49 46 } + + condition: + $start at 0 and $EmbeddedFileGUID and (#EmbeddedFileGUID > #PNG + #JPG + #JPG20001 + #JPG20002 + #BMP + #GIF) +} + +rule OneNote_Malicious_Paths +{ + meta: + author = "Nicholas Dhaeyer - @DhaeyerWolf" + date_created = "2023-02-23" + date_last_modified = "2023-02-23" + description = "Looks for OneNote Files with known malicious strings" + + strings: + $start = { e4 52 5c 7b 8c d8 a7 4d ae b1 53 78 d0 29 96 d3 } //beginning of a OneNote file + + //Start of malicious strings + $hex_string1 = { 5a 00 3a 00 5c 00 62 00 75 00 69 00 6c 00 64 00 65 00 72 00 5c } // Z:\builder\ + $hex_string2 = { 5a 00 3a 00 5c 00 62 00 75 00 69 00 6c 00 64 00 5c } // Z:\build\ + + condition: + $start at 0 and ($hex_string1 or $hex_string2) +} + +rule OneNote_BuildPath +{ + meta: + id = "6lPn0V5wZyc2iuEz13uKAZ" + fingerprint = "f8ed9e3cdd5411e2bda7495c8b00b8e69e8f495db97cf542f6a1f3b790bef7a5" + version = "1.0" + first_imported = "2023-02-02" + last_modified = "2023-02-23" + status = "RELEASED" + sharing = "TLP:WHITE" + source = "BARTBLAZE" + author = "@bartblaze" + description = "Identifies malicious OneNote file by build path." + category = "MALWARE" + +strings: + //Z:\build\one\attachment.hta + $path_0 = {5a003a005c006200750069006c0064005c006f006e0065005c006100740074006100630068006d0065006e0074002e00680074006100} + //Z:\builder\O P E N.wsf + $path_1 = {5a003a005c006200750069006c006400650072005c004f00200050002000450020004e002e00770073006600} +condition: + filesize <200KB and any of them +} \ No newline at end of file From f2f4d7fabfffec758985ab645b1eca142d157d94 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 19 Apr 2023 15:20:31 +0200 Subject: [PATCH 074/145] Improved title Signatures --- data/yara/binaries/HTMLPhisher_2023.yar | 1 + modules/signatures/suspicious_html.py | 13 ++++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/data/yara/binaries/HTMLPhisher_2023.yar b/data/yara/binaries/HTMLPhisher_2023.yar index ee3d7dad..035fdccd 100644 --- a/data/yara/binaries/HTMLPhisher_2023.yar +++ b/data/yara/binaries/HTMLPhisher_2023.yar @@ -5,6 +5,7 @@ Identifier: HTMLPhisher_2023 Reference: Personal Research */ + rule susp_documentwrite_HTML { meta: description = "Detection for document.write in HTML files" diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index 76ae4f27..c4836a95 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -78,10 +78,11 @@ class htmlTitle(Signature): def run(self): indicators = [ - 'Sign in to your account', + 'Please wait', + 'Sign in', ] - title_regex = re.compile(r'/<title>.*<\/title>/i') + title_regex = re.compile(r'<\s*title[^>]*>(.*?)<\/\s*title\s*>') if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": if "strings" not in self.results["target"]["file"] or self.results["target"]["file"]["strings"] == []: @@ -89,9 +90,11 @@ def run(self): strings = self.results["target"]["file"]["strings"] data = ''.join(strings) for indicator in indicators: - if indicator in data: - self.data.append({f"Found {indicator} in HTML title"}) - return True + if title_regex.search(data): + title = title_regex.search(data).group(1) + if indicator in title: + self.data.append({f"Found {indicator} in HTML title"}) + return True if not title_regex.search(data): self.description = "Sample contains empty HTML title" return True From 4f6d9906b8796b070e2aba71b9de66d3fa8e245a Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 19 Apr 2023 15:49:06 +0200 Subject: [PATCH 075/145] Improved title Signatures --- modules/signatures/binary_yara.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/modules/signatures/binary_yara.py b/modules/signatures/binary_yara.py index 3482f235..9149e6e8 100644 --- a/modules/signatures/binary_yara.py +++ b/modules/signatures/binary_yara.py @@ -27,15 +27,15 @@ class BinaryTriggeredYARA(Signature): def run(self): count = 0 - if self.results["target"]["file"]["yara"]: - yara_triggered = self.results["target"]["file"]["yara"] - if yara_triggered != []: - for yara in yara_triggered: - self.data.append({"Binary triggered YARA rule": yara["name"]}) - count += 1 - if count > 1: - self.description = "Binary file triggered multiple YARA rules" - if count > 3: - self.weight = 3 + + yara_triggered = self.results["target"]["file"]["yara"] + if yara_triggered != []: + for yara in yara_triggered: + self.data.append({"Binary triggered YARA rule": yara["name"]}) + count += 1 + if count > 1: + self.description = "Binary file triggered multiple YARA rules" + if count > 3: + self.weight = 3 return True return False \ No newline at end of file From 5de335f31d73b6518b9ed3eca3f040ebd2a906e9 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 19 Apr 2023 15:50:06 +0200 Subject: [PATCH 076/145] Improved binary_yara Signatures --- modules/signatures/binary_yara.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/signatures/binary_yara.py b/modules/signatures/binary_yara.py index 9149e6e8..f22a7872 100644 --- a/modules/signatures/binary_yara.py +++ b/modules/signatures/binary_yara.py @@ -35,7 +35,7 @@ def run(self): count += 1 if count > 1: self.description = "Binary file triggered multiple YARA rules" - if count > 3: + elif count > 3: self.weight = 3 return True return False \ No newline at end of file From 768c1df63d788bed1f2dab430e0e2d3e6d224e8d Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 19 Apr 2023 15:52:09 +0200 Subject: [PATCH 077/145] WIP --- data/yara/binaries/OneNote.yar | 2 ++ 1 file changed, 2 insertions(+) diff --git a/data/yara/binaries/OneNote.yar b/data/yara/binaries/OneNote.yar index 819cfbe1..59ad61b2 100644 --- a/data/yara/binaries/OneNote.yar +++ b/data/yara/binaries/OneNote.yar @@ -1,6 +1,7 @@ /* YARA Rule Set for OneNote Files */ +/* WIP rule susp_embedded_OneNote_files{ meta: description = "Detects suspicious embedded files in OneNote files" @@ -14,6 +15,7 @@ rule susp_embedded_OneNote_files{ condition: any of them } +*/ rule SUSP_Email_Suspicious_OneNote_Attachment_Jan23_1 { meta: description = "Detects suspicious OneNote attachment that embeds suspicious payload, e.g. an executable (FPs possible if the PE is attached separately)" From caa212e4c8350d45462adce7f1a9b77d01068384 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 19 Apr 2023 15:59:30 +0200 Subject: [PATCH 078/145] WIP --- modules/signatures/binary_yara.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/signatures/binary_yara.py b/modules/signatures/binary_yara.py index f22a7872..a88108e4 100644 --- a/modules/signatures/binary_yara.py +++ b/modules/signatures/binary_yara.py @@ -38,4 +38,5 @@ def run(self): elif count > 3: self.weight = 3 return True - return False \ No newline at end of file + else: + return False \ No newline at end of file From 57a50529b1c1fe9ec7ce6323f62a6cda85ca0436 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 19 Apr 2023 16:07:47 +0200 Subject: [PATCH 079/145] WIP --- modules/signatures/binary_yara.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/signatures/binary_yara.py b/modules/signatures/binary_yara.py index a88108e4..d62dbc9e 100644 --- a/modules/signatures/binary_yara.py +++ b/modules/signatures/binary_yara.py @@ -33,10 +33,10 @@ def run(self): for yara in yara_triggered: self.data.append({"Binary triggered YARA rule": yara["name"]}) count += 1 - if count > 1: - self.description = "Binary file triggered multiple YARA rules" - elif count > 3: - self.weight = 3 + if count > 1: + self.description = "Binary file triggered multiple YARA rules" + elif count > 3: + self.weight = 3 return True else: return False \ No newline at end of file From 73c829ebf07069524ed47d932c4022348c8e0975 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 19 Apr 2023 16:14:51 +0200 Subject: [PATCH 080/145] YARA improvements --- data/yara/binaries/HTMLPhisher_2023.yar | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/data/yara/binaries/HTMLPhisher_2023.yar b/data/yara/binaries/HTMLPhisher_2023.yar index 035fdccd..9a5695fe 100644 --- a/data/yara/binaries/HTMLPhisher_2023.yar +++ b/data/yara/binaries/HTMLPhisher_2023.yar @@ -20,7 +20,7 @@ rule susp_documentwrite_HTML { $document_write = { 64 6F 63 75 6D 65 6E 74 2E 77 72 69 74 65 } condition: - $html_magic or $script_magic0 or $script_magic1 at 0 + ($html_magic or $script_magic0 or $script_magic1 at 0) and $document_write } @@ -39,7 +39,7 @@ rule susp_obfuscated_HTML_atob_btoa { $btoa = { 62 74 6f 61 } condition: - $html_magic or $script_magic0 or $script_magic1 at 0 + ($html_magic or $script_magic0 or $script_magic1 at 0) and ($atob or $btoa) } @@ -57,8 +57,8 @@ rule susp_obfuscated_HTML_eval { $eval = { 65 76 61 6c } condition: - $html_magic or $script_magic0 or $script_magic1 at 0 - and $eval + ($html_magic or $script_magic0 or $script_magic1 at 0) + and ($eval) } rule susp_obfuscated_HTML_fromCharCode { @@ -75,7 +75,7 @@ rule susp_obfuscated_HTML_fromCharCode { $fromCharCode = { 66 72 6f 6d 43 68 61 72 43 6f 64 65 } condition: - $html_magic or $script_magic0 or $script_magic1 at 0 + ($html_magic or $script_magic0 or $script_magic1 at 0) and $fromCharCode } @@ -94,7 +94,7 @@ rule susp_obfuscated_HTML_unescape_escape { $escape = { 65 73 63 61 70 65 } condition: - $html_magic or $script_magic0 or $script_magic1 at 0 + ($html_magic or $script_magic0 or $script_magic1 at 0) and ($unescape or $escape) } @@ -112,6 +112,6 @@ rule susp_obfuscated_HTML_decodeURIComponent { $decodeURIComponent = { 64 65 63 6f 64 65 55 52 49 43 6f 6d 70 6f 6e 65 6e 74 } condition: - $html_magic or $script_magic0 or $script_magic1 at 0 + ($html_magic or $script_magic0 or $script_magic1 at 0) and $decodeURIComponent } From 5c8119084ef2fbc0aedfba4875fcf37f19c7cde7 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 19 Apr 2023 16:21:32 +0200 Subject: [PATCH 081/145] YARA improvements --- data/yara/binaries/HTMLPhisher_2023.yar | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/data/yara/binaries/HTMLPhisher_2023.yar b/data/yara/binaries/HTMLPhisher_2023.yar index 9a5695fe..12dadcba 100644 --- a/data/yara/binaries/HTMLPhisher_2023.yar +++ b/data/yara/binaries/HTMLPhisher_2023.yar @@ -13,14 +13,15 @@ rule susp_documentwrite_HTML { reference = "Personal Research" strings: - $html_magic = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } + $html_magic0 = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } + $html_magic1 = { 3C 68 74 6D 6C 3E } $script_magic0 = { 3C 73 63 72 69 70 74 3E } $script_magic1 = { 3C 73 63 72 69 70 74 20 } $document_write = { 64 6F 63 75 6D 65 6E 74 2E 77 72 69 74 65 } condition: - ($html_magic or $script_magic0 or $script_magic1 at 0) + ($html_magic0 or $html_magic1 or $script_magic0 or $script_magic1 at 0) and $document_write } @@ -39,7 +40,7 @@ rule susp_obfuscated_HTML_atob_btoa { $btoa = { 62 74 6f 61 } condition: - ($html_magic or $script_magic0 or $script_magic1 at 0) + ($html_magic0 or $html_magic1 or $script_magic0 or $script_magic1 at 0) and ($atob or $btoa) } @@ -57,7 +58,7 @@ rule susp_obfuscated_HTML_eval { $eval = { 65 76 61 6c } condition: - ($html_magic or $script_magic0 or $script_magic1 at 0) + ($html_magic0 or $html_magic1 or $script_magic0 or $script_magic1 at 0) and ($eval) } @@ -75,7 +76,7 @@ rule susp_obfuscated_HTML_fromCharCode { $fromCharCode = { 66 72 6f 6d 43 68 61 72 43 6f 64 65 } condition: - ($html_magic or $script_magic0 or $script_magic1 at 0) + ($html_magic0 or $html_magic1 or $script_magic0 or $script_magic1 at 0) and $fromCharCode } @@ -94,7 +95,7 @@ rule susp_obfuscated_HTML_unescape_escape { $escape = { 65 73 63 61 70 65 } condition: - ($html_magic or $script_magic0 or $script_magic1 at 0) + ($html_magic0 or $html_magic1 or $script_magic0 or $script_magic1 at 0) and ($unescape or $escape) } @@ -112,6 +113,6 @@ rule susp_obfuscated_HTML_decodeURIComponent { $decodeURIComponent = { 64 65 63 6f 64 65 55 52 49 43 6f 6d 70 6f 6e 65 6e 74 } condition: - ($html_magic or $script_magic0 or $script_magic1 at 0) + ($html_magic0 or $html_magic1 or $script_magic0 or $script_magic1 at 0) and $decodeURIComponent } From ac0e8b74b2500f7bd3480e7f0524f87c064a5411 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 19 Apr 2023 16:27:36 +0200 Subject: [PATCH 082/145] YARA improvements --- data/yara/binaries/HTMLPhisher_2023.yar | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/data/yara/binaries/HTMLPhisher_2023.yar b/data/yara/binaries/HTMLPhisher_2023.yar index 12dadcba..d163889c 100644 --- a/data/yara/binaries/HTMLPhisher_2023.yar +++ b/data/yara/binaries/HTMLPhisher_2023.yar @@ -32,7 +32,8 @@ rule susp_obfuscated_HTML_atob_btoa { reference = "Personal Research" strings: - $html_magic = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } + $html_magic0 = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } + $html_magic1 = { 3C 68 74 6D 6C 3E } $script_magic0 = { 3C 73 63 72 69 70 74 3E } $script_magic1 = { 3C 73 63 72 69 70 74 20 } @@ -51,7 +52,8 @@ rule susp_obfuscated_HTML_eval { reference = "Personal Research" strings: - $html_magic = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } + $html_magic0 = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } + $html_magic1 = { 3C 68 74 6D 6C 3E } $script_magic0 = { 3C 73 63 72 69 70 74 3E } $script_magic1 = { 3C 73 63 72 69 70 74 20 } @@ -69,7 +71,8 @@ rule susp_obfuscated_HTML_fromCharCode { reference = "Personal Research" strings: - $html_magic = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } + $html_magic0 = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } + $html_magic1 = { 3C 68 74 6D 6C 3E } $script_magic0 = { 3C 73 63 72 69 70 74 3E } $script_magic1 = { 3C 73 63 72 69 70 74 20 } @@ -87,7 +90,8 @@ rule susp_obfuscated_HTML_unescape_escape { reference = "Personal Research" strings: - $html_magic = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } + $html_magic0 = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } + $html_magic1 = { 3C 68 74 6D 6C 3E } $script_magic0 = { 3C 73 63 72 69 70 74 3E } $script_magic1 = { 3C 73 63 72 69 70 74 20 } @@ -106,7 +110,8 @@ rule susp_obfuscated_HTML_decodeURIComponent { reference = "Personal Research" strings: - $html_magic = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } + $html_magic0 = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } + $html_magic1 = { 3C 68 74 6D 6C 3E } $script_magic0 = { 3C 73 63 72 69 70 74 3E } $script_magic1 = { 3C 73 63 72 69 70 74 20 } From 89a339b1e9db96f0e4ec17a88dead991f4fd051a Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 19 Apr 2023 16:35:06 +0200 Subject: [PATCH 083/145] improvements --- modules/signatures/binary_yara.py | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/signatures/binary_yara.py b/modules/signatures/binary_yara.py index d62dbc9e..5000e999 100644 --- a/modules/signatures/binary_yara.py +++ b/modules/signatures/binary_yara.py @@ -21,6 +21,7 @@ class BinaryTriggeredYARA(Signature): severity = 3 confidence = 80 weight = 1 + enabled = True categories = ["static"] authors = ["Yasin Tas", "Eye Security"] minimum = "1.3" From 2ca29ecb7d1838f017ce745c2322df425460b612 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Wed, 19 Apr 2023 16:39:09 +0200 Subject: [PATCH 084/145] improvements --- modules/signatures/suspicious_html.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index c4836a95..7ffad1bf 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -89,15 +89,15 @@ def run(self): return False strings = self.results["target"]["file"]["strings"] data = ''.join(strings) - for indicator in indicators: - if title_regex.search(data): + if not title_regex.search(data): + self.description = "Sample contains empty HTML title" + return True + else: + for indicator in indicators: title = title_regex.search(data).group(1) if indicator in title: self.data.append({f"Found {indicator} in HTML title"}) return True - if not title_regex.search(data): - self.description = "Sample contains empty HTML title" - return True return False class suspiciousHTMLname(Signature): From 08c32f3756dd16776e1f5bf6b21362f5815a6ae3 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Thu, 20 Apr 2023 08:59:21 +0200 Subject: [PATCH 085/145] WIP --- modules/signatures/suspicious_html.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index 7ffad1bf..639e577d 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -29,7 +29,6 @@ class htmlBody(Signature): "https://socradar.io/what-is-a-phishing-kit/" "https://github.com/SteveD3/kit_hunter/tree/master/tag_files" ] - references = [""] enabled = True minimum = "1.2" ttps = ["T1566.001"] # MITRE v6,7,8 @@ -45,18 +44,22 @@ def run(self): 'url', 'emails' '// remove email, and put ur mailer code', - ] + ] if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": - if "strings" not in self.results["target"]["file"] or self.results["target"]["file"]["strings"] == []: + if "strings" not in self.results["target"]["file"]: return False - strings = self.results["target"]["file"]["strings"] - data = ''.join(strings) - for indicator in indicators: - if indicator in data: - self.data.append({f"Found {indicator} in HTML body"}) - return True + else: + strings = self.results["target"]["file"]["strings"] + data = ''.join(strings) + for indicator in indicators: + if indicator in data: + self.data.append({f"Found {indicator} in HTML body"}) + return True + else: + return False return False + class htmlTitle(Signature): name = "suspicious_html_title" @@ -70,7 +73,7 @@ class htmlTitle(Signature): "https://socradar.io/what-is-a-phishing-kit/" "https://github.com/SteveD3/kit_hunter/tree/master/tag_files" ] - enabled = True + enabled = False minimum = "1.2" ttps = ["T1566.001"] # MITRE v6,7,8 mbcs = ["C0029.003"] # micro-behaviour @@ -112,7 +115,7 @@ class suspiciousHTMLname(Signature): "https://socradar.io/what-is-a-phishing-kit/" "https://github.com/SteveD3/kit_hunter/tree/master/tag_files" ] - enabled = True + enabled = False minimum = "1.2" ttps = ["T1566.001"] # MITRE v6,7,8 mbcs = ["C0029.003"] # micro-behaviour From a0974504a2ebfc538f653032d6b6870e21c2a58f Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Thu, 20 Apr 2023 12:54:43 +0200 Subject: [PATCH 086/145] WIP --- modules/signatures/suspicious_html.py | 74 +++++++++++++-------------- 1 file changed, 35 insertions(+), 39 deletions(-) diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index 639e577d..3ab761d1 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -30,36 +30,33 @@ class htmlBody(Signature): "https://github.com/SteveD3/kit_hunter/tree/master/tag_files" ] enabled = True + evented = True minimum = "1.2" ttps = ["T1566.001"] # MITRE v6,7,8 mbcs = ["C0029.003"] # micro-behaviour + + - def run(self): + def run(self): + packages = ['html', 'edge', 'chrome', 'firefox'] indicators = [ - 'password', - 'email', - 'username', - 'encoded_string', - 'url', - 'emails' - '// remove email, and put ur mailer code', + 'password', + 'email', + 'username', + 'encoded_string', + 'url', + '// remove email, and put ur mailer code', ] - - if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": - if "strings" not in self.results["target"]["file"]: - return False - else: + if self.results["info"]["package"] in packages: + if "strings" in self.results["target"]["file"]: strings = self.results["target"]["file"]["strings"] data = ''.join(strings) for indicator in indicators: if indicator in data: - self.data.append({f"Found {indicator} in HTML body"}) - return True - else: - return False - return False - + self.add_match(None, 'string', indicator) + return self.has_matches() + class htmlTitle(Signature): name = "suspicious_html_title" @@ -80,6 +77,7 @@ class htmlTitle(Signature): def run(self): + packages = ['html', 'edge', 'chrome', 'firefox'] indicators = [ 'Please wait', 'Sign in', @@ -87,21 +85,20 @@ def run(self): title_regex = re.compile(r'<\s*title[^>]*>(.*?)<\/\s*title\s*>') - if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": - if "strings" not in self.results["target"]["file"] or self.results["target"]["file"]["strings"] == []: - return False - strings = self.results["target"]["file"]["strings"] - data = ''.join(strings) - if not title_regex.search(data): - self.description = "Sample contains empty HTML title" - return True - else: - for indicator in indicators: - title = title_regex.search(data).group(1) - if indicator in title: - self.data.append({f"Found {indicator} in HTML title"}) - return True - return False + if self.results["info"]["package"] in packages: + if "strings" in self.results["target"]["file"]: + strings = self.results["target"]["file"]["strings"] + data = ''.join(strings) + if not title_regex.search(data): + self.description = "Sample contains empty HTML title" + self.add_match(None, 'string', 'Empty HTML title') + else: + for indicator in indicators: + title = title_regex.search(data).group(1) + if indicator in title: + self.add_match(None, 'string', f'Found {indicator} in HTML title') + + return self.has_matches() class suspiciousHTMLname(Signature): name = "suspicious_html_name" @@ -121,7 +118,7 @@ class suspiciousHTMLname(Signature): mbcs = ["C0029.003"] # micro-behaviour def run(self): - + packages = ['html', 'edge', 'chrome', 'firefox'] indicators = [ 'payment', 'remittence', @@ -132,11 +129,10 @@ def run(self): 'voice', ] - if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": + if self.results["info"]["package"] in packages: name = self.results["target"]["file"]["name"] lower = name.lower() for indicator in indicators: if indicator in lower: - self.data.append({f"Found {indicator} in sample name"}) - return True - return False \ No newline at end of file + self.add_match(None, 'string', f'Found {indicator} in HTML name') + return self.has_matches() \ No newline at end of file From c418a49d58f98e3354efec6fd50b02d8689cf150 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Thu, 20 Apr 2023 12:57:25 +0200 Subject: [PATCH 087/145] WIP --- modules/signatures/suspicious_html.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index 3ab761d1..161aa41a 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -54,7 +54,7 @@ def run(self): data = ''.join(strings) for indicator in indicators: if indicator in data: - self.add_match(None, 'string', indicator) + self.add_match(None, 'string', f'Found string {indicator} in HTML body') return self.has_matches() @@ -89,13 +89,13 @@ def run(self): if "strings" in self.results["target"]["file"]: strings = self.results["target"]["file"]["strings"] data = ''.join(strings) - if not title_regex.search(data): + title = title_regex.search(data) + if not title: self.description = "Sample contains empty HTML title" self.add_match(None, 'string', 'Empty HTML title') else: for indicator in indicators: - title = title_regex.search(data).group(1) - if indicator in title: + if indicator in title.group(1): self.add_match(None, 'string', f'Found {indicator} in HTML title') return self.has_matches() From fd8747f80e6ef7857f18bf3889993fbddec997c7 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Thu, 20 Apr 2023 13:07:13 +0200 Subject: [PATCH 088/145] WIP: Enabled HTML title rule --- modules/signatures/suspicious_html.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index 161aa41a..9a79bfb7 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -70,7 +70,7 @@ class htmlTitle(Signature): "https://socradar.io/what-is-a-phishing-kit/" "https://github.com/SteveD3/kit_hunter/tree/master/tag_files" ] - enabled = False + enabled = True minimum = "1.2" ttps = ["T1566.001"] # MITRE v6,7,8 mbcs = ["C0029.003"] # micro-behaviour From adaad3bfe590a6986b92e10d003869bc597e4509 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Thu, 20 Apr 2023 13:10:50 +0200 Subject: [PATCH 089/145] WIP: Enabled HTML indicators --- modules/signatures/suspicious_html.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index 9a79bfb7..582c09e0 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -98,7 +98,7 @@ def run(self): if indicator in title.group(1): self.add_match(None, 'string', f'Found {indicator} in HTML title') - return self.has_matches() + return self.has_matches() class suspiciousHTMLname(Signature): name = "suspicious_html_name" @@ -112,7 +112,7 @@ class suspiciousHTMLname(Signature): "https://socradar.io/what-is-a-phishing-kit/" "https://github.com/SteveD3/kit_hunter/tree/master/tag_files" ] - enabled = False + enabled = True minimum = "1.2" ttps = ["T1566.001"] # MITRE v6,7,8 mbcs = ["C0029.003"] # micro-behaviour From 067005cc8468dea138a46baa75708d05f4edca44 Mon Sep 17 00:00:00 2001 From: Yasin Tas <yasin.tas@eye.security> Date: Thu, 20 Apr 2023 13:52:01 +0200 Subject: [PATCH 090/145] Added extra domains --- data/yara/binaries/HTMLPhisher_2023.yar | 1 + data/yara/binaries/OneNote.yar | 33 ++++++++++++++++++++ modules/signatures/network_dns_suspicious.py | 7 ++++- modules/signatures/suspicious_html.py | 10 ++++-- 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/data/yara/binaries/HTMLPhisher_2023.yar b/data/yara/binaries/HTMLPhisher_2023.yar index d163889c..f72f270c 100644 --- a/data/yara/binaries/HTMLPhisher_2023.yar +++ b/data/yara/binaries/HTMLPhisher_2023.yar @@ -5,6 +5,7 @@ Identifier: HTMLPhisher_2023 Reference: Personal Research */ +// TODO: Add base64 encoded strings detection rule susp_documentwrite_HTML { meta: diff --git a/data/yara/binaries/OneNote.yar b/data/yara/binaries/OneNote.yar index 59ad61b2..635d7bd2 100644 --- a/data/yara/binaries/OneNote.yar +++ b/data/yara/binaries/OneNote.yar @@ -16,6 +16,39 @@ rule susp_embedded_OneNote_files{ any of them } */ +rule Microsoft_OneNote_with_Suspicious_String +{ + meta: + author = "InQuest Labs" + description = "This signature detects Microsoft OneNote files containing suspicious strings." + created_date = "2023-02-24" + updated_date = "2023-02-24" + blog_reference = "https://inquest.net/blog/2023/02/27/youve-got-malware-rise-threat-actors-using-microsoft-onenote-malicious-campaigns" + labs_reference = "N/A" + labs_pivot = "N/A" + samples = "660870c3f3e8ff105e5cc06b3b3d04436118fc67533c93d0df56bde359e335d0" + + strings: + $suspicious_00 = "<script" nocase ascii wide + $suspicious_01 = "cmd.exe" nocase ascii wide + $suspicious_02 = "CreateObject" nocase ascii wide + $suspicious_03 = "CreateProcess" nocase ascii wide + $suspicious_04 = "echo off" nocase ascii wide + $suspicious_05 = "ExecuteCmdAsync" nocase ascii wide + $suspicious_06 = "mshta" nocase ascii wide + $suspicious_07 = "msiexec" nocase ascii wide + $suspicious_08 = "powershell" nocase ascii wide + $suspicious_09 = "regsvr32" nocase ascii wide + $suspicious_10 = "rundll32" nocase ascii wide + $suspicious_11 = "schtasks" nocase ascii wide + $suspicious_12 = "SetEnvironmentVariable" nocase ascii wide + $suspicious_13 = "winmgmts" nocase ascii wide + $suspicious_14 = "Wscript" nocase ascii wide + $suspicious_15 = "WshShell" nocase ascii wide + condition: + uint32be(0) == 0xE4525C7B and any of ($suspicious*) +} + rule SUSP_Email_Suspicious_OneNote_Attachment_Jan23_1 { meta: description = "Detects suspicious OneNote attachment that embeds suspicious payload, e.g. an executable (FPs possible if the PE is attached separately)" diff --git a/modules/signatures/network_dns_suspicious.py b/modules/signatures/network_dns_suspicious.py index d84cdbeb..e9463da5 100644 --- a/modules/signatures/network_dns_suspicious.py +++ b/modules/signatures/network_dns_suspicious.py @@ -563,7 +563,12 @@ def run(self): (".*\\.pw$", "Palau domain TLD"), (".*\\.ru$", "Russian Federation domain TLD"), (".*\\.su$", "Soviet Union domain TLD"), - (".*\\.top$", "Generic top level domain TLD"), + (".*\\.top$", "Generic top level domain TLD") + (".*\\.tk$", "Tokelau domain TLD"), + (".*\\.ua$", "Ukraine domain TLD"), + (".*\\.xyz$", "Generic top level domain TLD"), + (".*\\.za$", "South Africa domain TLD"), + (".*\\.ng$", "Nigeria domain TLD"), ] queried_domains = [] diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index 582c09e0..17c51b70 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -21,7 +21,7 @@ class htmlBody(Signature): name = "suspicious_html_body" description = "Sample contains suspicious HTML body" severity = 1 - confidence = 80 + confidence = 100 categories = ["phishing", "static"] authors = ["Yasin Tas", "Eye Security"] references = [ @@ -47,6 +47,9 @@ def run(self): 'encoded_string', 'url', '// remove email, and put ur mailer code', + 'headers' + 'tokenName', + 'var' ] if self.results["info"]["package"] in packages: if "strings" in self.results["target"]["file"]: @@ -54,7 +57,7 @@ def run(self): data = ''.join(strings) for indicator in indicators: if indicator in data: - self.add_match(None, 'string', f'Found string {indicator} in HTML body') + self.add_match(None, 'string', f'Found {indicator} in HTML body') return self.has_matches() @@ -62,7 +65,7 @@ class htmlTitle(Signature): name = "suspicious_html_title" description = "Sample contains suspicious HTML title" severity = 1 - confidence = 80 + confidence = 100 categories = ["phishing", "static"] authors = ["Yasin Tas", "Eye Security"] references = [ @@ -81,6 +84,7 @@ def run(self): indicators = [ 'Please wait', 'Sign in', + '<title>', # Empty title ] title_regex = re.compile(r'<\s*title[^>]*>(.*?)<\/\s*title\s*>') From ede9c3c96fd5364d499528f8ddce87e33f17994d Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Thu, 20 Apr 2023 16:30:47 +0200 Subject: [PATCH 091/145] updated YARA --- data/yara/binaries/HTMLPhisher_2023.yar | 12 ++++++------ modules/signatures/suspicious_html.py | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/data/yara/binaries/HTMLPhisher_2023.yar b/data/yara/binaries/HTMLPhisher_2023.yar index f72f270c..9f6bb9ef 100644 --- a/data/yara/binaries/HTMLPhisher_2023.yar +++ b/data/yara/binaries/HTMLPhisher_2023.yar @@ -22,7 +22,7 @@ rule susp_documentwrite_HTML { $document_write = { 64 6F 63 75 6D 65 6E 74 2E 77 72 69 74 65 } condition: - ($html_magic0 or $html_magic1 or $script_magic0 or $script_magic1 at 0) + ($html_magic0 at 0 or $html_magic1 at 0 or $script_magic0 at 0 or $script_magic1 at 0) and $document_write } @@ -42,7 +42,7 @@ rule susp_obfuscated_HTML_atob_btoa { $btoa = { 62 74 6f 61 } condition: - ($html_magic0 or $html_magic1 or $script_magic0 or $script_magic1 at 0) + ($html_magic0 at 0 or $html_magic1 at 0 or $script_magic0 at 0 or $script_magic1 at 0) and ($atob or $btoa) } @@ -61,7 +61,7 @@ rule susp_obfuscated_HTML_eval { $eval = { 65 76 61 6c } condition: - ($html_magic0 or $html_magic1 or $script_magic0 or $script_magic1 at 0) + ($html_magic0 at 0 or $html_magic1 at 0 or $script_magic0 at 0 or $script_magic1 at 0) and ($eval) } @@ -80,7 +80,7 @@ rule susp_obfuscated_HTML_fromCharCode { $fromCharCode = { 66 72 6f 6d 43 68 61 72 43 6f 64 65 } condition: - ($html_magic0 or $html_magic1 or $script_magic0 or $script_magic1 at 0) + ($html_magic0 at 0 or $html_magic1 at 0 or $script_magic0 at 0 or $script_magic1 at 0) and $fromCharCode } @@ -100,7 +100,7 @@ rule susp_obfuscated_HTML_unescape_escape { $escape = { 65 73 63 61 70 65 } condition: - ($html_magic0 or $html_magic1 or $script_magic0 or $script_magic1 at 0) + ($html_magic0 at 0 or $html_magic1 at 0 or $script_magic0 at 0 or $script_magic1 at 0) and ($unescape or $escape) } @@ -119,6 +119,6 @@ rule susp_obfuscated_HTML_decodeURIComponent { $decodeURIComponent = { 64 65 63 6f 64 65 55 52 49 43 6f 6d 70 6f 6e 65 6e 74 } condition: - ($html_magic0 or $html_magic1 or $script_magic0 or $script_magic1 at 0) + ($html_magic0 at 0 or $html_magic1 at 0 or $script_magic0 at 0 or $script_magic1 at 0) and $decodeURIComponent } diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index 17c51b70..42bf7e7a 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -49,7 +49,7 @@ def run(self): '// remove email, and put ur mailer code', 'headers' 'tokenName', - 'var' + 'headers', ] if self.results["info"]["package"] in packages: if "strings" in self.results["target"]["file"]: From fcd067d7d25a1d0bbc0d56ac9ca7b2f184947c2b Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Mon, 24 Apr 2023 13:00:43 +0200 Subject: [PATCH 092/145] merged new rules --- data/yara/binaries/HTMLPhisher_2023.yar | 124 --------- data/yara/binaries/OneNote.yar | 311 ---------------------- data/yara/binaries/oAuth_Phishing_PDF.yar | 25 -- data/yara/binaries/susp_obfuscated_JS.yar | 52 ---- 4 files changed, 512 deletions(-) delete mode 100644 data/yara/binaries/HTMLPhisher_2023.yar delete mode 100644 data/yara/binaries/OneNote.yar delete mode 100644 data/yara/binaries/oAuth_Phishing_PDF.yar delete mode 100644 data/yara/binaries/susp_obfuscated_JS.yar diff --git a/data/yara/binaries/HTMLPhisher_2023.yar b/data/yara/binaries/HTMLPhisher_2023.yar deleted file mode 100644 index 9f6bb9ef..00000000 --- a/data/yara/binaries/HTMLPhisher_2023.yar +++ /dev/null @@ -1,124 +0,0 @@ -/* - YARA Rule Set for HTML phishing - Author: Yasin Tas, Eye Security - Date: 2023-04-05 - Identifier: HTMLPhisher_2023 - Reference: Personal Research -*/ -// TODO: Add base64 encoded strings detection - -rule susp_documentwrite_HTML { - meta: - description = "Detection for document.write in HTML files" - author = "Yasin Tas, Eye Security" - reference = "Personal Research" - - strings: - $html_magic0 = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } - $html_magic1 = { 3C 68 74 6D 6C 3E } - $script_magic0 = { 3C 73 63 72 69 70 74 3E } - $script_magic1 = { 3C 73 63 72 69 70 74 20 } - - $document_write = { 64 6F 63 75 6D 65 6E 74 2E 77 72 69 74 65 } - - condition: - ($html_magic0 at 0 or $html_magic1 at 0 or $script_magic0 at 0 or $script_magic1 at 0) - and $document_write -} - -rule susp_obfuscated_HTML_atob_btoa { - meta: - description = "Detection for JS atob in HTML files" - author = "Yasin Tas, Eye Security" - reference = "Personal Research" - - strings: - $html_magic0 = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } - $html_magic1 = { 3C 68 74 6D 6C 3E } - $script_magic0 = { 3C 73 63 72 69 70 74 3E } - $script_magic1 = { 3C 73 63 72 69 70 74 20 } - - $atob = { 61 74 6f 62 } - $btoa = { 62 74 6f 61 } - - condition: - ($html_magic0 at 0 or $html_magic1 at 0 or $script_magic0 at 0 or $script_magic1 at 0) - and ($atob or $btoa) -} - -rule susp_obfuscated_HTML_eval { - meta: - description = "Detection for JS eval in HTML files" - author = "Yasin Tas, Eye Security" - reference = "Personal Research" - - strings: - $html_magic0 = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } - $html_magic1 = { 3C 68 74 6D 6C 3E } - $script_magic0 = { 3C 73 63 72 69 70 74 3E } - $script_magic1 = { 3C 73 63 72 69 70 74 20 } - - $eval = { 65 76 61 6c } - - condition: - ($html_magic0 at 0 or $html_magic1 at 0 or $script_magic0 at 0 or $script_magic1 at 0) - and ($eval) -} - -rule susp_obfuscated_HTML_fromCharCode { - meta: - description = "Detection for JS fromCharcode in HTML files" - author = "Yasin Tas, Eye Security" - reference = "Personal Research" - - strings: - $html_magic0 = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } - $html_magic1 = { 3C 68 74 6D 6C 3E } - $script_magic0 = { 3C 73 63 72 69 70 74 3E } - $script_magic1 = { 3C 73 63 72 69 70 74 20 } - - $fromCharCode = { 66 72 6f 6d 43 68 61 72 43 6f 64 65 } - - condition: - ($html_magic0 at 0 or $html_magic1 at 0 or $script_magic0 at 0 or $script_magic1 at 0) - and $fromCharCode -} - -rule susp_obfuscated_HTML_unescape_escape { - meta: - description = "Detection for JS escape or unescape in HTML files" - author = "Yasin Tas, Eye Security" - reference = "Personal Research" - - strings: - $html_magic0 = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } - $html_magic1 = { 3C 68 74 6D 6C 3E } - $script_magic0 = { 3C 73 63 72 69 70 74 3E } - $script_magic1 = { 3C 73 63 72 69 70 74 20 } - - $unescape = { 75 6e 65 73 63 61 70 65 } - $escape = { 65 73 63 61 70 65 } - - condition: - ($html_magic0 at 0 or $html_magic1 at 0 or $script_magic0 at 0 or $script_magic1 at 0) - and ($unescape or $escape) -} - -rule susp_obfuscated_HTML_decodeURIComponent { - meta: - description = "Detection for JS decodeURIComponent in HTML files" - author = "Yasin Tas, Eye Security" - reference = "Personal Research" - - strings: - $html_magic0 = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } - $html_magic1 = { 3C 68 74 6D 6C 3E } - $script_magic0 = { 3C 73 63 72 69 70 74 3E } - $script_magic1 = { 3C 73 63 72 69 70 74 20 } - - $decodeURIComponent = { 64 65 63 6f 64 65 55 52 49 43 6f 6d 70 6f 6e 65 6e 74 } - - condition: - ($html_magic0 at 0 or $html_magic1 at 0 or $script_magic0 at 0 or $script_magic1 at 0) - and $decodeURIComponent -} diff --git a/data/yara/binaries/OneNote.yar b/data/yara/binaries/OneNote.yar deleted file mode 100644 index 635d7bd2..00000000 --- a/data/yara/binaries/OneNote.yar +++ /dev/null @@ -1,311 +0,0 @@ -/* - YARA Rule Set for OneNote Files -*/ -/* WIP -rule susp_embedded_OneNote_files{ - meta: - description = "Detects suspicious embedded files in OneNote files" - author = "Yasin Tas, Eye Security" - reference = "Personal Research" - date = "2023-01-27" - - strings: - // - - condition: - any of them -} -*/ -rule Microsoft_OneNote_with_Suspicious_String -{ - meta: - author = "InQuest Labs" - description = "This signature detects Microsoft OneNote files containing suspicious strings." - created_date = "2023-02-24" - updated_date = "2023-02-24" - blog_reference = "https://inquest.net/blog/2023/02/27/youve-got-malware-rise-threat-actors-using-microsoft-onenote-malicious-campaigns" - labs_reference = "N/A" - labs_pivot = "N/A" - samples = "660870c3f3e8ff105e5cc06b3b3d04436118fc67533c93d0df56bde359e335d0" - - strings: - $suspicious_00 = "{GUID} */ - /* https://interoperability.blob.core.windows.net/files/MS-ONESTORE/%5bMS-ONESTORE%5d.pdf */ - $fref = { 3C 00 69 00 66 00 6E 00 64 00 66 00 3E 00 7B 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 2D 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 2D 00 ?? 00 ?? 00 ?? 00 ?? 00 2D 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? } - - condition: - filesize < 5MB and - ($one at 0) and - $fdso and - #fref > (#fdso * 4) -} - -rule SUSP_OneNote_RTLO_Character_Feb23 { - meta: - description = "Presence of RTLO Unicode Character in a OneNote file with embedded files" - author = "delivr.to" - date = "2023-02-17" - score = 60 - strings: - /* [MS-ONESTORE] File Header */ - $one = { E4 52 5C 7B 8C D8 A7 4D AE B1 53 78 D0 29 96 D3 } - - /* FileDataStoreObject GUID */ - $fdso = { 00 e7 16 e3 bd 65 26 11 45 a4 c4 8d 4d 0b 7a 9e ac } - - /* RTLO */ - $rtlo = { 00 2E 20 } - - condition: - filesize < 5MB and - ($one at 0) and - $fdso and - $rtlo -} - -rule OneNote_EmbeddedFiles_NoPictures -{ - meta: - author = "Nicholas Dhaeyer - @DhaeyerWolf" - date_created = "2023-02-14 - <3" - date_last_modified = "2023-02-17" - description = "OneNote files that contain embedded files that are not pictures." - reference = "https://blog.didierstevens.com/2023/01/22/analyzing-malicious-onenote-documents/" - yarahub_uuid = "d0c4f0e6-adbe-4953-a2df-91427a561e97" - date = "2023-02-14" - yarahub_license = "CC0 1.0" - yarahub_rule_matching_tlp = "TLP:WHITE" - yarahub_rule_sharing_tlp = "TLP:WHITE" - yarahub_reference_md5 = "52486a446dd4fc5842a47b57d3febec7" - - strings: - $start = { e4 52 5c 7b 8c d8 a7 4d ae b1 53 78 d0 29 96 d3 } //beginning of a OneNote file - - $EmbeddedFileGUID = { E7 16 E3 BD 65 26 11 45 A4 C4 8D 4D 0B 7A 9E AC } - $PNG = { E7 16 E3 BD 65 26 11 45 A4 C4 8D 4D 0B 7A 9E AC ?? ?? ?? ?? ?? ?? ?? ?? 00 00 00 00 00 00 00 00 00 00 00 00 89 50 4E 47 0D 0A 1A 0A } - $JPG = { E7 16 E3 BD 65 26 11 45 A4 C4 8D 4D 0B 7A 9E AC ?? ?? ?? ?? ?? ?? ?? ?? 00 00 00 00 00 00 00 00 00 00 00 00 FF D8 FF } - $JPG20001 = { E7 16 E3 BD 65 26 11 45 A4 C4 8D 4D 0B 7A 9E AC ?? ?? ?? ?? ?? ?? ?? ?? 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 6A 50 20 20 0D 0A 87 0A } - $JPG20002 = { E7 16 E3 BD 65 26 11 45 A4 C4 8D 4D 0B 7A 9E AC ?? ?? ?? ?? ?? ?? ?? ?? 00 00 00 00 00 00 00 00 00 00 00 00 FF 4F FF 51 } - $BMP = { E7 16 E3 BD 65 26 11 45 A4 C4 8D 4D 0B 7A 9E AC ?? ?? ?? ?? ?? ?? ?? ?? 00 00 00 00 00 00 00 00 00 00 00 00 42 4D } - $GIF = { E7 16 E3 BD 65 26 11 45 A4 C4 8D 4D 0B 7A 9E AC ?? ?? ?? ?? ?? ?? ?? ?? 00 00 00 00 00 00 00 00 00 00 00 00 47 49 46 } - - condition: - $start at 0 and $EmbeddedFileGUID and (#EmbeddedFileGUID > #PNG + #JPG + #JPG20001 + #JPG20002 + #BMP + #GIF) -} - -rule OneNote_Malicious_Paths -{ - meta: - author = "Nicholas Dhaeyer - @DhaeyerWolf" - date_created = "2023-02-23" - date_last_modified = "2023-02-23" - description = "Looks for OneNote Files with known malicious strings" - - strings: - $start = { e4 52 5c 7b 8c d8 a7 4d ae b1 53 78 d0 29 96 d3 } //beginning of a OneNote file - - //Start of malicious strings - $hex_string1 = { 5a 00 3a 00 5c 00 62 00 75 00 69 00 6c 00 64 00 65 00 72 00 5c } // Z:\builder\ - $hex_string2 = { 5a 00 3a 00 5c 00 62 00 75 00 69 00 6c 00 64 00 5c } // Z:\build\ - - condition: - $start at 0 and ($hex_string1 or $hex_string2) -} - -rule OneNote_BuildPath -{ - meta: - id = "6lPn0V5wZyc2iuEz13uKAZ" - fingerprint = "f8ed9e3cdd5411e2bda7495c8b00b8e69e8f495db97cf542f6a1f3b790bef7a5" - version = "1.0" - first_imported = "2023-02-02" - last_modified = "2023-02-23" - status = "RELEASED" - sharing = "TLP:WHITE" - source = "BARTBLAZE" - author = "@bartblaze" - description = "Identifies malicious OneNote file by build path." - category = "MALWARE" - -strings: - //Z:\build\one\attachment.hta - $path_0 = {5a003a005c006200750069006c0064005c006f006e0065005c006100740074006100630068006d0065006e0074002e00680074006100} - //Z:\builder\O P E N.wsf - $path_1 = {5a003a005c006200750069006c006400650072005c004f00200050002000450020004e002e00770073006600} -condition: - filesize <200KB and any of them -} \ No newline at end of file diff --git a/data/yara/binaries/oAuth_Phishing_PDF.yar b/data/yara/binaries/oAuth_Phishing_PDF.yar deleted file mode 100644 index 4ee2abcf..00000000 --- a/data/yara/binaries/oAuth_Phishing_PDF.yar +++ /dev/null @@ -1,25 +0,0 @@ -rule oAuth_Phishing_PDF -{ - meta: - id = "789YmThaTvLDaE1V2Oqx7q" - fingerprint = "c367bca866de0b066e291b4e45216cbb68cc23297b002a29ca3c8d640a7db78e" - version = "1.0" - creation_date = "2022-01-01" - first_imported = "2022-02-03" - last_modified = "2022-02-03" - status = "RELEASED" - sharing = "TLP:WHITE" - source = "BARTBLAZE" - author = "@bartblaze" - description = "Identifies potential phishing PDFs that target oAuth." - category = "MALWARE" - reference = "https://twitter.com/ffforward/status/1484127442679836676" - - strings: - $pdf = {25504446} //%PDF - $s1 = "/URI (https://login.microsoftonline.com/common/oauth2/" ascii wide nocase - $s2 = "/URI (https://login.microsoftonline.com/consumers/oauth2" ascii wide nocase - $s3 = "/URI (https://accounts.google.com/o/oauth2" ascii wide nocase - condition: - $pdf at 0 and any of ($s*) -} \ No newline at end of file diff --git a/data/yara/binaries/susp_obfuscated_JS.yar b/data/yara/binaries/susp_obfuscated_JS.yar deleted file mode 100644 index 37868523..00000000 --- a/data/yara/binaries/susp_obfuscated_JS.yar +++ /dev/null @@ -1,52 +0,0 @@ -rule SUSP_obfuscated_JS_obfuscatorio -{ - meta: - - author = "@imp0rtp3" - description = "Detect JS obfuscation done by the js obfuscator (often malicious)" - reference = "https://obfuscator.io" - - strings: - - // Beggining of the script - $a1 = "var a0_0x" - $a2 = /var _0x[a-f0-9]{4}/ - - // Strings to search By number of occurences - $b1 = /a0_0x([a-f0-9]{2}){2,4}\('?0x[0-9a-f]{1,3}'?\)/ - $b2 =/[^\w\d]_0x([a-f0-9]{2}){2,4}\('?0x[0-9a-f]{1,3}'?\)[^\w\d]/ - $b3 = /[^\w\d]_0x([a-f0-9]{2}){2,4}\['push'\]\(_0x([a-f0-9]{2}){2,4}\['shift'\]\(\)[^\w\d]/ - $b4 = /!0x1[^\d\w]/ - $b5 = /[^\w\d]function\((_0x([a-f0-9]{2}){2,4},)+_0x([a-f0-9]{2}){2,4}\)\s?\{/ - $b6 = /[^\w\d]_0x([a-f0-9]{2}){2,4}\s?=\s?_0x([a-f0-9]{2}){2,4}[^\w\d]/ - - // generic strings often used by the obfuscator - $c1 = "))),function(){try{var _0x" - $c2 = "=Function('return\\x20(function()\\x20'+'{}.constructor(\\x22return\\x20this\\x22)(\\x20)'+');');" - $c3 = "['atob']=function(" - $c4 = ")['replace'](/=+$/,'');var" - $c5 = "return!![]" - $c6 = "'{}.constructor(\\x22return\\\x20this\\x22)(\\x20)'" - $c7 = "{}.constructor(\x22return\x20this\x22)(\x20)" base64 - $c8 = "while(!![])" - $c9 = "while (!![])" - - // Strong strings - $d1 = /(parseInt\(_0x([a-f0-9]{2}){2,4}\(0x[a-f0-9]{1,5}\)\)\/0x[a-f0-9]{1,2}\)?(\+|\*\()\-?){6}/ - - condition: - $a1 at 0 or - $a2 at 0 or - ( - filesize<1000000 and - ( - (#b1 + #b2) > (filesize \ 200) or - #b3 > 1 or - #b4 > 10 or - #b5 > (filesize \ 2000) or - #b6 > (filesize \ 200) or - 3 of ($c*) or - $d1 - ) - ) -} \ No newline at end of file From 2989e8c6fd0ec73bd3f5b49a7d9e45cf943d490c Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Thu, 4 May 2023 14:36:58 +0200 Subject: [PATCH 093/145] Disabled rules that generate too much noise --- modules/signatures/antisandbox_unhook.py | 2 +- modules/signatures/exploit_heapspray.py | 1 + modules/signatures/malware_data_encryption.py | 2 +- modules/signatures/ransomware_filemodifications.py | 1 + modules/signatures/stack_pivot.py | 1 + 5 files changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/signatures/antisandbox_unhook.py b/modules/signatures/antisandbox_unhook.py index 8c7aaef3..c1424032 100644 --- a/modules/signatures/antisandbox_unhook.py +++ b/modules/signatures/antisandbox_unhook.py @@ -39,7 +39,7 @@ def __init__(self, *args, **kwargs): self.is_url_analysis = False if self.results.get("target", {}).get("category", "") == "url": self.is_url_analysis = True - self.safelistprocs = ["acrord32.exe"] + self.safelistprocs = ["acrord32.exe", "acrobat.exe"] def on_call(self, call, process): if process["process_name"].lower() in self.safelistprocs: diff --git a/modules/signatures/exploit_heapspray.py b/modules/signatures/exploit_heapspray.py index 33a961a7..9d03d902 100644 --- a/modules/signatures/exploit_heapspray.py +++ b/modules/signatures/exploit_heapspray.py @@ -24,6 +24,7 @@ class ExploitHeapspray(Signature): categories = ["exploit"] authors = ["Cuckoo Technologies", "Kevin Ross"] minimum = "1.3" + enabled = False evented = True ttps = ["T1203"] # MITRE v6,7,8 mbcs = ["OB0009", "E1203"] diff --git a/modules/signatures/malware_data_encryption.py b/modules/signatures/malware_data_encryption.py index fe1147cf..2de457e0 100644 --- a/modules/signatures/malware_data_encryption.py +++ b/modules/signatures/malware_data_encryption.py @@ -37,7 +37,7 @@ def __init__(self, *args, **kwargs): self.compname = str() self.username = str() self.buffers = set() - self.safelistprocs = ["winword.exe", "excel.exe", "powerpnt.exe"] + self.safelistprocs = ["winword.exe", "excel.exe", "powerpoint.exe", "acrobat.exe", "acrobat.exe"] def on_call(self, call, process): if process["process_name"].lower() not in self.safelistprocs: diff --git a/modules/signatures/ransomware_filemodifications.py b/modules/signatures/ransomware_filemodifications.py index 48f30e36..eba5969e 100644 --- a/modules/signatures/ransomware_filemodifications.py +++ b/modules/signatures/ransomware_filemodifications.py @@ -30,6 +30,7 @@ class RansomwareFileModifications(Signature): authors = ["Kevin Ross"] minimum = "1.3" evented = True + enabled = False ttps = ["T1486"] # MITRE v6,7,8 mbcs = ["OB0008", "E1486"] diff --git a/modules/signatures/stack_pivot.py b/modules/signatures/stack_pivot.py index 1179e709..1c20a9a5 100644 --- a/modules/signatures/stack_pivot.py +++ b/modules/signatures/stack_pivot.py @@ -21,6 +21,7 @@ class StackPivot(Signature): description = "Stack pivoting was detected when using a critical API" severity = 3 confidence = 100 + enabled = False categories = ["exploit"] authors = ["Optiv"] minimum = "1.3" From fb3c91470aeb111843d0e70adfdd75ba00ad0183 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Thu, 4 May 2023 14:53:53 +0200 Subject: [PATCH 094/145] changed rules for cookie gathering --- modules/signatures/infostealer_cookies.py | 28 ++++++++++++++++------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/modules/signatures/infostealer_cookies.py b/modules/signatures/infostealer_cookies.py index 1eeecbb2..f6a42ea1 100644 --- a/modules/signatures/infostealer_cookies.py +++ b/modules/signatures/infostealer_cookies.py @@ -23,10 +23,15 @@ class CookiesStealer(Signature): categories = ["infostealer"] authors = ["bartblaze"] minimum = "0.5" + evented = True ttps = ["T1539"] # MITRE v6,7,8 - def run(self): - indicators = [ + filter_apinames = ["NtQueryValueKey"] + + def __init__(self, *args, **kwargs): + Signature.__init__(self, *args, **kwargs) + self.data = [] + self.indicators = [ ".*\\\\Chromium\\\\User Data\\\\.*\\\\Cookies$", ".*\\\\Google\\\\Chrome\\\\User Data\\\\.*\\\\Cookies$", ".*\\\\Microsoft\\\\Windows\\\\INetCookies$", @@ -39,11 +44,18 @@ def run(self): ".*\\\\Opera Software\\\\Opera Stable\\\\Cookies$", ".*\\\\Brave-Browser\\\\User Data\\\\.*\\\\Cookies$", ] - - for indicator in indicators: - match = self.check_file(pattern=indicator, regex=True) - if match: - self.data.append({"cookie": match}) - return True + self.safe_indicators = ["chrome.exe", + "firefox.exe", + "opera.exe", + "msedge.exe", + "acrobat.exe" + ] + def on_call(self, call, process): + if process["process_name"] not in self.safe_indicators: + for indicator in self.indicators: + match = self.check_file(pattern=indicator, regex=True) + if match: + self.data.append({"cookie": match}) + return True return False From 646c3eff75e28ba81997b2f3a296c98e7d068b70 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Fri, 5 May 2023 10:38:17 +0200 Subject: [PATCH 095/145] Typo fix in suspicious_tld --- modules/signatures/network_dns_suspicious.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/signatures/network_dns_suspicious.py b/modules/signatures/network_dns_suspicious.py index e9463da5..9034a225 100644 --- a/modules/signatures/network_dns_suspicious.py +++ b/modules/signatures/network_dns_suspicious.py @@ -563,7 +563,7 @@ def run(self): (".*\\.pw$", "Palau domain TLD"), (".*\\.ru$", "Russian Federation domain TLD"), (".*\\.su$", "Soviet Union domain TLD"), - (".*\\.top$", "Generic top level domain TLD") + (".*\\.top$", "Generic top level domain TLD"), (".*\\.tk$", "Tokelau domain TLD"), (".*\\.ua$", "Ukraine domain TLD"), (".*\\.xyz$", "Generic top level domain TLD"), From 20683124aa78f7b8f0304d595558a230f250484c Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 10 May 2023 10:55:28 +0200 Subject: [PATCH 096/145] Accidentally removed some rules --- modules/signatures/malware_data_encryption.py | 2 +- modules/signatures/ransomware_filemodifications.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/signatures/malware_data_encryption.py b/modules/signatures/malware_data_encryption.py index 2de457e0..b5bddf00 100644 --- a/modules/signatures/malware_data_encryption.py +++ b/modules/signatures/malware_data_encryption.py @@ -37,7 +37,7 @@ def __init__(self, *args, **kwargs): self.compname = str() self.username = str() self.buffers = set() - self.safelistprocs = ["winword.exe", "excel.exe", "powerpoint.exe", "acrobat.exe", "acrobat.exe"] + self.safelistprocs = ["winword.exe", "excel.exe", "powerpoint.exe", "acrobat.exe"] def on_call(self, call, process): if process["process_name"].lower() not in self.safelistprocs: diff --git a/modules/signatures/ransomware_filemodifications.py b/modules/signatures/ransomware_filemodifications.py index 650ad28e..1fd5240f 100644 --- a/modules/signatures/ransomware_filemodifications.py +++ b/modules/signatures/ransomware_filemodifications.py @@ -30,7 +30,7 @@ class RansomwareFileModifications(Signature): authors = ["Kevin Ross"] minimum = "1.3" evented = True - enabled = False + enabled = True ttps = ["T1486"] # MITRE v6,7,8 mbcs = ["OB0008", "E1486"] From b681cea5c6c229f4fec4661c9ced12bcc0d38b74 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 10 May 2023 10:55:39 +0200 Subject: [PATCH 097/145] Accidentally removed some rules --- data/yara/binaries/HTMLPhisher_2023.yar | 111 +++++++++ data/yara/binaries/OneNote.yar | 287 ++++++++++++++++++++++ data/yara/binaries/oAuth_Phishing_PDF.yar | 25 ++ data/yara/binaries/susp_obfuscated_JS.yar | 50 ++++ 4 files changed, 473 insertions(+) create mode 100644 data/yara/binaries/HTMLPhisher_2023.yar create mode 100644 data/yara/binaries/OneNote.yar create mode 100644 data/yara/binaries/oAuth_Phishing_PDF.yar create mode 100644 data/yara/binaries/susp_obfuscated_JS.yar diff --git a/data/yara/binaries/HTMLPhisher_2023.yar b/data/yara/binaries/HTMLPhisher_2023.yar new file mode 100644 index 00000000..9f1433e8 --- /dev/null +++ b/data/yara/binaries/HTMLPhisher_2023.yar @@ -0,0 +1,111 @@ +/* + YARA Rule Set for HTML phishing + Author: Yasin Tas, Eye Security + Date: 2023-04-05 + Identifier: HTMLPhisher_2023 + Reference: Personal Research +*/ + +rule susp_documentwrite_HTML { + meta: + description = "Detection for document.write in HTML files" + author = "Yasin Tas, Eye Security" + reference = "Personal Research" + + strings: + $html_magic0 = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } + $html_magic1 = { 3C 68 74 6D 6C 3E } + $script_magic0 = { 3C 73 63 72 69 70 74 3E } + $script_magic1 = { 3C 73 63 72 69 70 74 20 } + $document_write = { 64 6F 63 75 6D 65 6E 74 2E 77 72 69 74 65 } + condition: + ($html_magic* at 0 or $script_magic* at 0) + and $document_write +} + +rule susp_obfuscated_HTML_atob_btoa { + meta: + description = "Detection for JS atob in HTML files" + author = "Yasin Tas, Eye Security" + reference = "Personal Research" + + strings: + $html_magic0 = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } + $html_magic1 = { 3C 68 74 6D 6C 3E } + $script_magic0 = { 3C 73 63 72 69 70 74 3E } + $script_magic1 = { 3C 73 63 72 69 70 74 20 } + $atob = { 61 74 6f 62 } + $btoa = { 62 74 6f 61 } + condition: + ($html_magic* at 0 or $script_magic* at 0) + and ($atob or $btoa) +} + +rule susp_obfuscated_HTML_eval { + meta: + description = "Detection for JS eval in HTML files" + author = "Yasin Tas, Eye Security" + reference = "Personal Research" + + strings: + $html_magic0 = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } + $html_magic1 = { 3C 68 74 6D 6C 3E } + $script_magic0 = { 3C 73 63 72 69 70 74 3E } + $script_magic1 = { 3C 73 63 72 69 70 74 20 } + $eval = { 65 76 61 6c } + condition: + ($html_magic* at 0 or $script_magic* at 0) + and ($eval) +} + +rule susp_obfuscated_HTML_fromCharCode { + meta: + description = "Detection for JS fromCharcode in HTML files" + author = "Yasin Tas, Eye Security" + reference = "Personal Research" + + strings: + $html_magic0 = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } + $html_magic1 = { 3C 68 74 6D 6C 3E } + $script_magic0 = { 3C 73 63 72 69 70 74 3E } + $script_magic1 = { 3C 73 63 72 69 70 74 20 } + $fromCharCode = { 66 72 6f 6d 43 68 61 72 43 6f 64 65 } + condition: + ($html_magic* at 0 or $script_magic* at 0) + and $fromCharCode +} + +rule susp_obfuscated_HTML_unescape_escape { + meta: + description = "Detection for JS escape or unescape in HTML files" + author = "Yasin Tas, Eye Security" + reference = "Personal Research" + + strings: + $html_magic0 = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } + $html_magic1 = { 3C 68 74 6D 6C 3E } + $script_magic0 = { 3C 73 63 72 69 70 74 3E } + $script_magic1 = { 3C 73 63 72 69 70 74 20 } + $unescape = { 75 6e 65 73 63 61 70 65 } + $escape = { 65 73 63 61 70 65 } + condition: + ($html_magic* at 0 or $script_magic* at 0) + and ($unescape or $escape) +} + +rule susp_obfuscated_HTML_decodeURIComponent { + meta: + description = "Detection for JS decodeURIComponent in HTML files" + author = "Yasin Tas, Eye Security" + reference = "Personal Research" + + strings: + $html_magic0 = { 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 3E } + $html_magic1 = { 3C 68 74 6D 6C 3E } + $script_magic0 = { 3C 73 63 72 69 70 74 3E } + $script_magic1 = { 3C 73 63 72 69 70 74 20 } + $decodeURIComponent = { 64 65 63 6f 64 65 55 52 49 43 6f 6d 70 6f 6e 65 6e 74 } + condition: + ($html_magic* at 0 or $script_magic* at 0) + and $decodeURIComponent +} diff --git a/data/yara/binaries/OneNote.yar b/data/yara/binaries/OneNote.yar new file mode 100644 index 00000000..76a3e389 --- /dev/null +++ b/data/yara/binaries/OneNote.yar @@ -0,0 +1,287 @@ +/* + YARA Rule Set for OneNote Files +*/ + +rule Microsoft_OneNote_with_Suspicious_String +{ + meta: + author = "InQuest Labs" + description = "This signature detects Microsoft OneNote files containing suspicious strings." + created_date = "2023-02-24" + updated_date = "2023-02-24" + blog_reference = "https://inquest.net/blog/2023/02/27/youve-got-malware-rise-threat-actors-using-microsoft-onenote-malicious-campaigns" + labs_reference = "N/A" + labs_pivot = "N/A" + samples = "660870c3f3e8ff105e5cc06b3b3d04436118fc67533c93d0df56bde359e335d0" + + strings: + $suspicious_00 = "{GUID} */ + /* https://interoperability.blob.core.windows.net/files/MS-ONESTORE/%5bMS-ONESTORE%5d.pdf */ + $fref = { 3C 00 69 00 66 00 6E 00 64 00 66 00 3E 00 7B 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 2D 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 2D 00 ?? 00 ?? 00 ?? 00 ?? 00 2D 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? 00 ?? } + condition: + filesize < 5MB and + ($one at 0) and + $fdso and + #fref > (#fdso * 4) +} + +rule SUSP_OneNote_RTLO_Character_Feb23 { + meta: + description = "Presence of RTLO Unicode Character in a OneNote file with embedded files" + author = "delivr.to" + date = "2023-02-17" + score = 60 + strings: + /* [MS-ONESTORE] File Header */ + $one = { E4 52 5C 7B 8C D8 A7 4D AE B1 53 78 D0 29 96 D3 } + /* FileDataStoreObject GUID */ + $fdso = { 00 e7 16 e3 bd 65 26 11 45 a4 c4 8d 4d 0b 7a 9e ac } + /* RTLO */ + $rtlo = { 00 2E 20 } + condition: + filesize < 5MB and + ($one at 0) and + $fdso and + $rtlo +} + +rule OneNote_EmbeddedFiles_NoPictures +{ + meta: + author = "Nicholas Dhaeyer - @DhaeyerWolf" + date_created = "2023-02-14 - <3" + date_last_modified = "2023-02-17" + description = "OneNote files that contain embedded files that are not pictures." + reference = "https://blog.didierstevens.com/2023/01/22/analyzing-malicious-onenote-documents/" + yarahub_uuid = "d0c4f0e6-adbe-4953-a2df-91427a561e97" + date = "2023-02-14" + yarahub_license = "CC0 1.0" + yarahub_rule_matching_tlp = "TLP:WHITE" + yarahub_rule_sharing_tlp = "TLP:WHITE" + yarahub_reference_md5 = "52486a446dd4fc5842a47b57d3febec7" + + strings: + $start = { e4 52 5c 7b 8c d8 a7 4d ae b1 53 78 d0 29 96 d3 } //beginning of a OneNote file + + $EmbeddedFileGUID = { E7 16 E3 BD 65 26 11 45 A4 C4 8D 4D 0B 7A 9E AC } + $PNG = { E7 16 E3 BD 65 26 11 45 A4 C4 8D 4D 0B 7A 9E AC ?? ?? ?? ?? ?? ?? ?? ?? 00 00 00 00 00 00 00 00 00 00 00 00 89 50 4E 47 0D 0A 1A 0A } + $JPG = { E7 16 E3 BD 65 26 11 45 A4 C4 8D 4D 0B 7A 9E AC ?? ?? ?? ?? ?? ?? ?? ?? 00 00 00 00 00 00 00 00 00 00 00 00 FF D8 FF } + $JPG20001 = { E7 16 E3 BD 65 26 11 45 A4 C4 8D 4D 0B 7A 9E AC ?? ?? ?? ?? ?? ?? ?? ?? 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 6A 50 20 20 0D 0A 87 0A } + $JPG20002 = { E7 16 E3 BD 65 26 11 45 A4 C4 8D 4D 0B 7A 9E AC ?? ?? ?? ?? ?? ?? ?? ?? 00 00 00 00 00 00 00 00 00 00 00 00 FF 4F FF 51 } + $BMP = { E7 16 E3 BD 65 26 11 45 A4 C4 8D 4D 0B 7A 9E AC ?? ?? ?? ?? ?? ?? ?? ?? 00 00 00 00 00 00 00 00 00 00 00 00 42 4D } + $GIF = { E7 16 E3 BD 65 26 11 45 A4 C4 8D 4D 0B 7A 9E AC ?? ?? ?? ?? ?? ?? ?? ?? 00 00 00 00 00 00 00 00 00 00 00 00 47 49 46 } + condition: + $start at 0 and $EmbeddedFileGUID and (#EmbeddedFileGUID > #PNG + #JPG + #JPG20001 + #JPG20002 + #BMP + #GIF) +} + +rule OneNote_Malicious_Paths +{ + meta: + author = "Nicholas Dhaeyer - @DhaeyerWolf" + date_created = "2023-02-23" + date_last_modified = "2023-02-23" + description = "Looks for OneNote Files with known malicious strings" + + strings: + $start = { e4 52 5c 7b 8c d8 a7 4d ae b1 53 78 d0 29 96 d3 } //beginning of a OneNote file + + //Start of malicious strings + $hex_string1 = { 5a 00 3a 00 5c 00 62 00 75 00 69 00 6c 00 64 00 65 00 72 00 5c } // Z:\builder\ + $hex_string2 = { 5a 00 3a 00 5c 00 62 00 75 00 69 00 6c 00 64 00 5c } // Z:\build\ + + condition: + $start at 0 and ($hex_string1 or $hex_string2) +} + +rule OneNote_BuildPath +{ + meta: + id = "6lPn0V5wZyc2iuEz13uKAZ" + fingerprint = "f8ed9e3cdd5411e2bda7495c8b00b8e69e8f495db97cf542f6a1f3b790bef7a5" + version = "1.0" + first_imported = "2023-02-02" + last_modified = "2023-02-23" + status = "RELEASED" + sharing = "TLP:WHITE" + source = "BARTBLAZE" + author = "@bartblaze" + description = "Identifies malicious OneNote file by build path." + category = "MALWARE" + +strings: + //Z:\build\one\attachment.hta + $path_0 = {5a003a005c006200750069006c0064005c006f006e0065005c006100740074006100630068006d0065006e0074002e00680074006100} + //Z:\builder\O P E N.wsf + $path_1 = {5a003a005c006200750069006c006400650072005c004f00200050002000450020004e002e00770073006600} +condition: + filesize <200KB and any of them +} \ No newline at end of file diff --git a/data/yara/binaries/oAuth_Phishing_PDF.yar b/data/yara/binaries/oAuth_Phishing_PDF.yar new file mode 100644 index 00000000..4ee2abcf --- /dev/null +++ b/data/yara/binaries/oAuth_Phishing_PDF.yar @@ -0,0 +1,25 @@ +rule oAuth_Phishing_PDF +{ + meta: + id = "789YmThaTvLDaE1V2Oqx7q" + fingerprint = "c367bca866de0b066e291b4e45216cbb68cc23297b002a29ca3c8d640a7db78e" + version = "1.0" + creation_date = "2022-01-01" + first_imported = "2022-02-03" + last_modified = "2022-02-03" + status = "RELEASED" + sharing = "TLP:WHITE" + source = "BARTBLAZE" + author = "@bartblaze" + description = "Identifies potential phishing PDFs that target oAuth." + category = "MALWARE" + reference = "https://twitter.com/ffforward/status/1484127442679836676" + + strings: + $pdf = {25504446} //%PDF + $s1 = "/URI (https://login.microsoftonline.com/common/oauth2/" ascii wide nocase + $s2 = "/URI (https://login.microsoftonline.com/consumers/oauth2" ascii wide nocase + $s3 = "/URI (https://accounts.google.com/o/oauth2" ascii wide nocase + condition: + $pdf at 0 and any of ($s*) +} \ No newline at end of file diff --git a/data/yara/binaries/susp_obfuscated_JS.yar b/data/yara/binaries/susp_obfuscated_JS.yar new file mode 100644 index 00000000..2302b518 --- /dev/null +++ b/data/yara/binaries/susp_obfuscated_JS.yar @@ -0,0 +1,50 @@ +rule SUSP_obfuscated_JS_obfuscatorio +{ + meta: + + author = "@imp0rtp3" + description = "Detect JS obfuscation done by the js obfuscator (often malicious)" + reference = "https://obfuscator.io" + + strings: + // Beggining of the script + $a1 = "var a0_0x" + $a2 = /var _0x[a-f0-9]{4}/ + + // Strings to search By number of occurences + $b1 = /a0_0x([a-f0-9]{2}){2,4}\('?0x[0-9a-f]{1,3}'?\)/ + $b2 =/[^\w\d]_0x([a-f0-9]{2}){2,4}\('?0x[0-9a-f]{1,3}'?\)[^\w\d]/ + $b3 = /[^\w\d]_0x([a-f0-9]{2}){2,4}\['push'\]\(_0x([a-f0-9]{2}){2,4}\['shift'\]\(\)[^\w\d]/ + $b4 = /!0x1[^\d\w]/ + $b5 = /[^\w\d]function\((_0x([a-f0-9]{2}){2,4},)+_0x([a-f0-9]{2}){2,4}\)\s?\{/ + $b6 = /[^\w\d]_0x([a-f0-9]{2}){2,4}\s?=\s?_0x([a-f0-9]{2}){2,4}[^\w\d]/ + + // generic strings often used by the obfuscator + $c1 = "))),function(){try{var _0x" + $c2 = "=Function('return\\x20(function()\\x20'+'{}.constructor(\\x22return\\x20this\\x22)(\\x20)'+');');" + $c3 = "['atob']=function(" + $c4 = ")['replace'](/=+$/,'');var" + $c5 = "return!![]" + $c6 = "'{}.constructor(\\x22return\\\x20this\\x22)(\\x20)'" + $c7 = "{}.constructor(\x22return\x20this\x22)(\x20)" base64 + $c8 = "while(!![])" + $c9 = "while (!![])" + // Strong strings + $d1 = /(parseInt\(_0x([a-f0-9]{2}){2,4}\(0x[a-f0-9]{1,5}\)\)\/0x[a-f0-9]{1,2}\)?(\+|\*\()\-?){6}/ + + condition: + $a1 at 0 or + $a2 at 0 or + ( + filesize<1000000 and + ( + (#b1 + #b2) > (filesize \ 200) or + #b3 > 1 or + #b4 > 10 or + #b5 > (filesize \ 2000) or + #b6 > (filesize \ 200) or + 3 of ($c*) or + $d1 + ) + ) +} \ No newline at end of file From 1d183c03fef940407035ccda707482ff13b016a5 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 10 May 2023 11:05:08 +0200 Subject: [PATCH 098/145] Accidentally removed some rules --- data/yara/binaries/HTMLPhisher_2023.yar | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/data/yara/binaries/HTMLPhisher_2023.yar b/data/yara/binaries/HTMLPhisher_2023.yar index 9f1433e8..4ae5e415 100644 --- a/data/yara/binaries/HTMLPhisher_2023.yar +++ b/data/yara/binaries/HTMLPhisher_2023.yar @@ -19,7 +19,7 @@ rule susp_documentwrite_HTML { $script_magic1 = { 3C 73 63 72 69 70 74 20 } $document_write = { 64 6F 63 75 6D 65 6E 74 2E 77 72 69 74 65 } condition: - ($html_magic* at 0 or $script_magic* at 0) + ($html_magic0 at 0 or $html_magic1 at 0 or $script_magic0 at 0 or $script_magic1 at 0) and $document_write } @@ -37,7 +37,7 @@ rule susp_obfuscated_HTML_atob_btoa { $atob = { 61 74 6f 62 } $btoa = { 62 74 6f 61 } condition: - ($html_magic* at 0 or $script_magic* at 0) + ($html_magic0 at 0 or $html_magic1 at 0 or $script_magic0 at 0 or $script_magic1 at 0) and ($atob or $btoa) } @@ -54,7 +54,7 @@ rule susp_obfuscated_HTML_eval { $script_magic1 = { 3C 73 63 72 69 70 74 20 } $eval = { 65 76 61 6c } condition: - ($html_magic* at 0 or $script_magic* at 0) + ($html_magic0 at 0 or $html_magic1 at 0 or $script_magic0 at 0 or $script_magic1 at 0) and ($eval) } @@ -71,7 +71,7 @@ rule susp_obfuscated_HTML_fromCharCode { $script_magic1 = { 3C 73 63 72 69 70 74 20 } $fromCharCode = { 66 72 6f 6d 43 68 61 72 43 6f 64 65 } condition: - ($html_magic* at 0 or $script_magic* at 0) + ($html_magic0 at 0 or $html_magic1 at 0 or $script_magic0 at 0 or $script_magic1 at 0) and $fromCharCode } @@ -89,7 +89,7 @@ rule susp_obfuscated_HTML_unescape_escape { $unescape = { 75 6e 65 73 63 61 70 65 } $escape = { 65 73 63 61 70 65 } condition: - ($html_magic* at 0 or $script_magic* at 0) + ($html_magic0 at 0 or $html_magic1 at 0 or $script_magic0 at 0 or $script_magic1 at 0) and ($unescape or $escape) } @@ -106,6 +106,6 @@ rule susp_obfuscated_HTML_decodeURIComponent { $script_magic1 = { 3C 73 63 72 69 70 74 20 } $decodeURIComponent = { 64 65 63 6f 64 65 55 52 49 43 6f 6d 70 6f 6e 65 6e 74 } condition: - ($html_magic* at 0 or $script_magic* at 0) + ($html_magic0 at 0 or $html_magic1 at 0 or $script_magic0 at 0 or $script_magic1 at 0) and $decodeURIComponent } From 178b7294b047d0e18b29ef18b991b39e0f0fb568 Mon Sep 17 00:00:00 2001 From: RoemIko Date: Wed, 10 May 2023 15:11:44 +0200 Subject: [PATCH 099/145] added new yara rule --- data/yara/binaries/Maldoc_PDF.yar | 489 ++++++++++++++++++++++++++++++ 1 file changed, 489 insertions(+) create mode 100644 data/yara/binaries/Maldoc_PDF.yar diff --git a/data/yara/binaries/Maldoc_PDF.yar b/data/yara/binaries/Maldoc_PDF.yar new file mode 100644 index 00000000..6e5b5540 --- /dev/null +++ b/data/yara/binaries/Maldoc_PDF.yar @@ -0,0 +1,489 @@ +/* + This Yara ruleset is under the GNU-GPLv2 license (http://www.gnu.org/licenses/gpl-2.0.html) and open to any user or organization, as long as you use it under this license. + +*/ + +rule malicious_author : PDF raw +{ + meta: + author = "Glenn Edwards (@hiddenillusion)" + version = "0.1" + weight = 5 + + strings: + $magic = { 25 50 44 46 } + + $reg0 = /Creator.?\(yen vaw\)/ + $reg1 = /Title.?\(who cis\)/ + $reg2 = /Author.?\(ser pes\)/ + condition: + $magic in (0..1024) and all of ($reg*) +} + +rule suspicious_version : PDF raw +{ + meta: + author = "Glenn Edwards (@hiddenillusion)" + version = "0.1" + weight = 3 + + strings: + $magic = { 25 50 44 46 } + $ver = /%PDF-1.\d{1}/ + condition: + $magic in (0..1024) and not $ver +} + +rule suspicious_creation : PDF raw +{ + meta: + author = "Glenn Edwards (@hiddenillusion)" + version = "0.1" + weight = 2 + + strings: + $magic = { 25 50 44 46 } + $header = /%PDF-1\.(3|4|6)/ + + $create0 = /CreationDate \(D:20101015142358\)/ + $create1 = /CreationDate \(2008312053854\)/ + condition: + $magic in (0..1024) and $header and 1 of ($create*) +} + +rule multiple_filtering : PDF raw +{ +meta: +author = "Glenn Edwards (@hiddenillusion)" +version = "0.2" +weight = 3 + + strings: + $magic = { 25 50 44 46 } + $attrib = /\/Filter.*(\/ASCIIHexDecode\W+|\/LZWDecode\W+|\/ASCII85Decode\W+|\/FlateDecode\W+|\/RunLengthDecode){2}/ + // left out: /CCITTFaxDecode, JBIG2Decode, DCTDecode, JPXDecode, Crypt + + condition: + $magic in (0..1024) and $attrib +} + +rule suspicious_title : PDF raw +{ + meta: + author = "Glenn Edwards (@hiddenillusion)" + version = "0.1" + weight = 4 + + strings: + $magic = { 25 50 44 46 } + $header = /%PDF-1\.(3|4|6)/ + + $title0 = "who cis" + $title1 = "P66N7FF" + $title2 = "Fohcirya" + condition: + $magic in (0..1024) and $header and 1 of ($title*) +} + +rule suspicious_author : PDF raw +{ + meta: + author = "Glenn Edwards (@hiddenillusion)" + version = "0.1" + weight = 4 + + strings: + $magic = { 25 50 44 46 } + $header = /%PDF-1\.(3|4|6)/ + + $author0 = "Ubzg1QUbzuzgUbRjvcUb14RjUb1" + $author1 = "ser pes" + $author2 = "Miekiemoes" + $author3 = "Nsarkolke" + condition: + $magic in (0..1024) and $header and 1 of ($author*) +} + +rule suspicious_producer : PDF raw +{ + meta: + author = "Glenn Edwards (@hiddenillusion)" + version = "0.1" + weight = 2 + + strings: + $magic = { 25 50 44 46 } + $header = /%PDF-1\.(3|4|6)/ + + $producer0 = /Producer \(Scribus PDF Library/ + $producer1 = "Notepad" + condition: + $magic in (0..1024) and $header and 1 of ($producer*) +} + +rule suspicious_creator : PDF raw +{ + meta: + author = "Glenn Edwards (@hiddenillusion)" + version = "0.1" + weight = 3 + + strings: + $magic = { 25 50 44 46 } + $header = /%PDF-1\.(3|4|6)/ + + $creator0 = "yen vaw" + $creator1 = "Scribus" + $creator2 = "Viraciregavi" + condition: + $magic in (0..1024) and $header and 1 of ($creator*) +} + +rule possible_exploit : PDF raw +{ + meta: + author = "Glenn Edwards (@hiddenillusion)" + version = "0.1" + weight = 3 + + strings: + $magic = { 25 50 44 46 } + + $attrib0 = /\/JavaScript / + $attrib3 = /\/ASCIIHexDecode/ + $attrib4 = /\/ASCII85Decode/ + + $action0 = /\/Action/ + $action1 = "Array" + $shell = "A" + $cond0 = "unescape" + $cond1 = "String.fromCharCode" + + $nop = "%u9090%u9090" + condition: + $magic in (0..1024) and (2 of ($attrib*)) or ($action0 and #shell > 10 and 1 of ($cond*)) or ($action1 and $cond0 and $nop) +} + +rule shellcode_blob_metadata : PDF raw +{ + meta: + author = "Glenn Edwards (@hiddenillusion)" + version = "0.1" + description = "When there's a large Base64 blob inserted into metadata fields it often indicates shellcode to later be decoded" + weight = 4 + strings: + $magic = { 25 50 44 46 } + + $reg_keyword = /\/Keywords.?\(([a-zA-Z0-9]{200,})/ //~6k was observed in BHEHv2 PDF exploits holding the shellcode + $reg_author = /\/Author.?\(([a-zA-Z0-9]{200,})/ + $reg_title = /\/Title.?\(([a-zA-Z0-9]{200,})/ + $reg_producer = /\/Producer.?\(([a-zA-Z0-9]{200,})/ + $reg_creator = /\/Creator.?\(([a-zA-Z0-9]{300,})/ + $reg_create = /\/CreationDate.?\(([a-zA-Z0-9]{200,})/ + + condition: + $magic in (0..1024) and 1 of ($reg*) +} + +rule suspicious_js : PDF raw +{ + meta: + author = "Glenn Edwards (@hiddenillusion)" + version = "0.1" + weight = 3 + + strings: + $magic = { 25 50 44 46 } + + $attrib0 = /\/OpenAction / + $attrib1 = /\/JavaScript / + + $js0 = "eval" + $js1 = "Array" + $js2 = "String.fromCharCode" + + condition: + $magic in (0..1024) and all of ($attrib*) and 2 of ($js*) +} + +rule suspicious_launch_action : PDF raw +{ + meta: + author = "Glenn Edwards (@hiddenillusion)" + version = "0.1" + weight = 2 + + strings: + $magic = { 25 50 44 46 } + + $attrib0 = /\/Launch/ + $attrib1 = /\/URL / + $attrib2 = /\/Action/ + $attrib3 = /\/OpenAction/ + $attrib4 = /\/F / + + condition: + $magic in (0..1024) and 3 of ($attrib*) +} + +rule suspicious_embed : PDF raw +{ + meta: + author = "Glenn Edwards (@hiddenillusion)" + version = "0.1" + ref = "https://feliam.wordpress.com/2010/01/13/generic-pdf-exploit-hider-embedpdf-py-and-goodbye-av-detection-012010/" + weight = 2 + + strings: + $magic = { 25 50 44 46 } + + $meth0 = /\/Launch/ + $meth1 = /\/GoTo(E|R)/ //means go to embedded or remote + $attrib0 = /\/URL / + $attrib1 = /\/Action/ + $attrib2 = /\/Filespec/ + + condition: + $magic in (0..1024) and 1 of ($meth*) and 2 of ($attrib*) +} + +rule suspicious_obfuscation : PDF raw +{ + meta: + author = "Glenn Edwards (@hiddenillusion)" + version = "0.1" + weight = 2 + + strings: + $magic = { 25 50 44 46 } + $reg = /\/\w#[a-zA-Z0-9]{2}#[a-zA-Z0-9]{2}/ + + condition: + $magic in (0..1024) and #reg > 5 +} + +rule invalid_XObject_js : PDF raw +{ + meta: + author = "Glenn Edwards (@hiddenillusion)" + description = "XObject's require v1.4+" + ref = "https://blogs.adobe.com/ReferenceXObjects/" + version = "0.1" + weight = 2 + + strings: + $magic = { 25 50 44 46 } + $ver = /%PDF-1\.[4-9]/ + + $attrib0 = /\/XObject/ + $attrib1 = /\/JavaScript/ + + condition: + $magic in (0..1024) and not $ver and all of ($attrib*) +} + +rule invalid_trailer_structure : PDF raw +{ + meta: + author = "Glenn Edwards (@hiddenillusion)" + version = "0.1" + weight = 1 + + strings: + $magic = { 25 50 44 46 } + // Required for a valid PDF + $reg0 = /trailer\r?\n?.*\/Size.*\r?\n?\.*/ + $reg1 = /\/Root.*\r?\n?.*startxref\r?\n?.*\r?\n?%%EOF/ + + condition: + $magic in (0..1024) and not $reg0 and not $reg1 +} + +rule multiple_versions : PDF raw +{ + meta: + author = "Glenn Edwards (@hiddenillusion)" + version = "0.1" + description = "Written very generically and doesn't hold any weight - just something that might be useful to know about to help show incremental updates to the file being analyzed" + weight = 1 + + strings: + $magic = { 25 50 44 46 } + $s0 = "trailer" + $s1 = "%%EOF" + + condition: + $magic in (0..1024) and #s0 > 1 and #s1 > 1 +} + +rule js_wrong_version : PDF raw +{ + meta: + author = "Glenn Edwards (@hiddenillusion)" + description = "JavaScript was introduced in v1.3" + ref = "http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/pdf_reference_1-7.pdf" + version = "0.1" + weight = 2 + + strings: + $magic = { 25 50 44 46 } + $js = /\/JavaScript/ + $ver = /%PDF-1\.[3-9]/ + + condition: + $magic in (0..1024) and $js and not $ver +} + +rule JBIG2_wrong_version : PDF raw +{ + meta: + author = "Glenn Edwards (@hiddenillusion)" + description = "JBIG2 was introduced in v1.4" + ref = "http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/pdf_reference_1-7.pdf" + version = "0.1" + weight = 1 + + strings: + $magic = { 25 50 44 46 } + $js = /\/JBIG2Decode/ + $ver = /%PDF-1\.[4-9]/ + + condition: + $magic in (0..1024) and $js and not $ver +} + +rule FlateDecode_wrong_version : PDF raw +{ + meta: + author = "Glenn Edwards (@hiddenillusion)" + description = "Flate was introduced in v1.2" + ref = "http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/pdf_reference_1-7.pdf" + version = "0.1" + weight = 1 + + strings: + $magic = { 25 50 44 46 } + $js = /\/FlateDecode/ + $ver = /%PDF-1\.[2-9]/ + + condition: + $magic in (0..1024) and $js and not $ver +} + +rule embed_wrong_version : PDF raw +{ + meta: + author = "Glenn Edwards (@hiddenillusion)" + description = "EmbeddedFiles were introduced in v1.3" + ref = "http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/pdf_reference_1-7.pdf" + version = "0.1" + weight = 1 + + strings: + $magic = { 25 50 44 46 } + $embed = /\/EmbeddedFiles/ + $ver = /%PDF-1\.[3-9]/ + + condition: + $magic in (0..1024) and $embed and not $ver +} + +rule invalid_xref_numbers : PDF raw +{ + meta: + author = "Glenn Edwards (@hiddenillusion)" + version = "0.1" + description = "The first entry in a cross-reference table is always free and has a generation number of 65,535" + notes = "This can be also be in a stream..." + weight = 1 + + strings: + $magic = { 25 50 44 46 } + $reg0 = /xref\r?\n?.*\r?\n?.*65535\sf/ + $reg1 = /endstream.*\r?\n?endobj.*\r?\n?startxref/ + condition: + $magic in (0..1024) and not $reg0 and not $reg1 +} + +rule js_splitting : PDF raw +{ + meta: + author = "Glenn Edwards (@hiddenillusion)" + version = "0.1" + description = "These are commonly used to split up JS code" + weight = 2 + + strings: + $magic = { 25 50 44 46 } + $js = /\/JavaScript/ + $s0 = "getAnnots" + $s1 = "getPageNumWords" + $s2 = "getPageNthWord" + $s3 = "this.info" + + condition: + $magic in (0..1024) and $js and 1 of ($s*) +} + +rule header_evasion : PDF raw +{ + meta: + author = "Glenn Edwards (@hiddenillusion)" + description = "3.4.1, 'File Header' of Appendix H states that ' Acrobat viewers require only that the header appear somewhere within the first 1024 bytes of the file.' Therefore, if you see this trigger then any other rule looking to match the magic at 0 won't be applicable" + ref = "http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/pdf_reference_1-7.pdf" + version = "0.1" + weight = 3 + + strings: + $magic = { 25 50 44 46 } + condition: + $magic in (5..1024) and #magic == 1 +} + +rule BlackHole_v2 : PDF raw +{ + meta: + author = "Glenn Edwards (@hiddenillusion)" + version = "0.1" + ref = "http://fortknoxnetworks.blogspot.no/2012/10/blackhhole-exploit-kit-v-20-url-pattern.html" + weight = 3 + + strings: + $magic = { 25 50 44 46 } + $content = "Index[5 1 7 1 9 4 23 4 50" + + condition: + $magic in (0..1024) and $content +} + + +rule XDP_embedded_PDF : PDF raw +{ + meta: + author = "Glenn Edwards (@hiddenillusion)" + version = "0.1" + ref = "http://blog.9bplus.com/av-bypass-for-malicious-pdfs-using-xdp" + weight = 1 + + strings: + $s1 = "" + $s3 = "" + $header0 = "%PDF" + $header1 = "JVBERi0" + + condition: + all of ($s*) and 1 of ($header*) +} + +rule PDF_Embedded_Exe : PDF +{ + meta: + ref = "https://github.com/jacobsoo/Yara-Rules/blob/master/PDF_Embedded_Exe.yar" + strings: + $header = {25 50 44 46} + $Launch_Action = {3C 3C 2F 53 2F 4C 61 75 6E 63 68 2F 54 79 70 65 2F 41 63 74 69 6F 6E 2F 57 69 6E 3C 3C 2F 46} + $exe = {3C 3C 2F 45 6D 62 65 64 64 65 64 46 69 6C 65 73} + condition: + $header at 0 and $Launch_Action and $exe +} \ No newline at end of file From 383c44ad29a74083c5310ea3eeac43a7e3393b61 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 10 May 2023 16:15:52 +0200 Subject: [PATCH 100/145] Enabled some rules --- modules/feeds/bad_ssl_certs.py | 2 +- modules/signatures/exploit_heapspray.py | 2 +- modules/signatures/log4shell.py | 2 +- modules/signatures/network_questionable_host.py | 2 +- modules/signatures/stack_pivot.py | 6 +++--- modules/signatures/suspicious_html.py | 1 + 6 files changed, 8 insertions(+), 7 deletions(-) diff --git a/modules/feeds/bad_ssl_certs.py b/modules/feeds/bad_ssl_certs.py index 44d5923a..0e6c0a2b 100644 --- a/modules/feeds/bad_ssl_certs.py +++ b/modules/feeds/bad_ssl_certs.py @@ -9,7 +9,7 @@ class AbuseCH_SSL(Feed): # Results dict key value / exception handling / logging name name = "Bad_SSL_Certs" # Change the below line to enable this feed - enabled = False + enabled = True def __init__(self): super().__init__(self) diff --git a/modules/signatures/exploit_heapspray.py b/modules/signatures/exploit_heapspray.py index 9d03d902..64add0e9 100644 --- a/modules/signatures/exploit_heapspray.py +++ b/modules/signatures/exploit_heapspray.py @@ -24,7 +24,7 @@ class ExploitHeapspray(Signature): categories = ["exploit"] authors = ["Cuckoo Technologies", "Kevin Ross"] minimum = "1.3" - enabled = False + enabled = True evented = True ttps = ["T1203"] # MITRE v6,7,8 mbcs = ["OB0009", "E1203"] diff --git a/modules/signatures/log4shell.py b/modules/signatures/log4shell.py index 381d642d..6db12b6f 100644 --- a/modules/signatures/log4shell.py +++ b/modules/signatures/log4shell.py @@ -32,7 +32,7 @@ class Log4j(Signature): categories = ["malware"] authors = ["Busra Yenidogan"] minimum = "0.5" - enabled = False + enabled = True def run(self): httpitems = self.results.get("network", {}).get("http", []) diff --git a/modules/signatures/network_questionable_host.py b/modules/signatures/network_questionable_host.py index fb8cf28c..a3d143ec 100644 --- a/modules/signatures/network_questionable_host.py +++ b/modules/signatures/network_questionable_host.py @@ -47,7 +47,7 @@ class NetworkQuestionableHost(Signature): authors = ["Zane C. Bowers-Hadley"] minimum = "1.3" mbcs = ["B0030"] - enabled = False + enabled = True filter_analysistypes = set(["file"]) diff --git a/modules/signatures/stack_pivot.py b/modules/signatures/stack_pivot.py index 1c20a9a5..cda73560 100644 --- a/modules/signatures/stack_pivot.py +++ b/modules/signatures/stack_pivot.py @@ -19,9 +19,9 @@ class StackPivot(Signature): name = "stack_pivot" description = "Stack pivoting was detected when using a critical API" - severity = 3 - confidence = 100 - enabled = False + severity = 1 + confidence = 50 + enabled = True categories = ["exploit"] authors = ["Optiv"] minimum = "1.3" diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index 42bf7e7a..ebc05382 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -131,6 +131,7 @@ def run(self): 'voicemail', 'remit', 'voice', + 'statement', ] if self.results["info"]["package"] in packages: From 46840694861b888a03e5063a50d8b5a6e50487c0 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 24 May 2023 14:48:16 +0200 Subject: [PATCH 101/145] Added safelist domain for network_payload_download.py, due to FP --- modules/signatures/network_payload_download.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/modules/signatures/network_payload_download.py b/modules/signatures/network_payload_download.py index f51b2e47..ac3c5df8 100644 --- a/modules/signatures/network_payload_download.py +++ b/modules/signatures/network_payload_download.py @@ -15,6 +15,7 @@ from lib.cuckoo.common.abstracts import Signature +from data.safelist.domains import domain_passlist class NetworkDocumentFile(Signature): name = "network_document_file" @@ -59,9 +60,12 @@ def __init__(self, *args, **kwargs): def on_call(self, _, process): pname = process["process_name"].lower() if pname in self.proc_list: - if self.pid: - self.mark_call() - return True + if self.get_argument(process) in domain_passlist: + return None + else: + if self.pid: + self.mark_call() + return True class NetworkEXE(Signature): From c92b7af23a88bd54801910887082e11ec4c83ca8 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 24 May 2023 14:58:36 +0200 Subject: [PATCH 102/145] minor changes --- modules/signatures/network_payload_download.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/modules/signatures/network_payload_download.py b/modules/signatures/network_payload_download.py index ac3c5df8..b339702d 100644 --- a/modules/signatures/network_payload_download.py +++ b/modules/signatures/network_payload_download.py @@ -57,13 +57,15 @@ def __init__(self, *args, **kwargs): "powershell.exe", ] - def on_call(self, _, process): + def on_call(self, call, process): pname = process["process_name"].lower() if pname in self.proc_list: - if self.get_argument(process) in domain_passlist: - return None - else: - if self.pid: + if self.pid: + if call["api"].startswith("InternetCrackUrlA"): + self.url = self.get_argument(call, "Url") + if self.url in domain_passlist: + return False + else: self.mark_call() return True From 1e8a379263605bb5f3adcc40a7d44df5e3b47474 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 24 May 2023 15:05:22 +0200 Subject: [PATCH 103/145] network_docfile_http added domain passlist to reduce FP --- modules/signatures/network_docfile_http.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/modules/signatures/network_docfile_http.py b/modules/signatures/network_docfile_http.py index 0d8af33f..599b14b2 100644 --- a/modules/signatures/network_docfile_http.py +++ b/modules/signatures/network_docfile_http.py @@ -15,6 +15,7 @@ from lib.cuckoo.common.abstracts import Signature +from data.safelist.domains import domain_passlist class NetworkDocumentHTTP(Signature): name = "network_document_http" @@ -54,19 +55,24 @@ def on_call(self, call, process): addit = None if call["api"] == "URLDownloadToFileW": buff = self.get_argument(call, "URL") - addit = {"http_downloadurl": "%s_URLDownloadToFileW_%s" % (pname, buff)} + if buff not in domain_passlist: + addit = {"http_downloadurl": "%s_URLDownloadToFileW_%s" % (pname, buff)} if call["api"] == "HttpOpenRequestW": buff = self.get_argument(call, "Path") - addit = {"http_request_path": "%s_HttpOpenRequestW_%s" % (pname, buff)} + if buff not in domain_passlist: + addit = {"http_request_path": "%s_HttpOpenRequestW_%s" % (pname, buff)} if call["api"] == "InternetCrackUrlW": buff = self.get_argument(call, "Url") - addit = {"http_request": "%s_InternetCrackUrlW_%s" % (pname, buff)} + if buff not in domain_passlist: + addit = {"http_request": "%s_InternetCrackUrlW_%s" % (pname, buff)} if call["api"] == "InternetCrackUrlA": buff = self.get_argument(call, "Url") - addit = {"http_request": "%s_InternetCrackUrlA_%s" % (pname, buff)} + if buff not in domain_passlist: + addit = {"http_request": "%s_InternetCrackUrlA_%s" % (pname, buff)} if call["api"] == "WSASend": buff = self.get_argument(call, "Buffer").lower() - addit = {"http_request": "%s_WSASend_%s" % (pname, buff)} + if buff not in domain_passlist: + addit = {"http_request": "%s_WSASend_%s" % (pname, buff)} if addit and addit not in self.data: self.data.append(addit) if self.pid: From 21dad31b9c0ec4b87f76c939112071574ee54223 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 24 May 2023 15:10:44 +0200 Subject: [PATCH 104/145] network_docfile_http added domain passlist to reduce FP --- modules/signatures/network_docfile_http.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/modules/signatures/network_docfile_http.py b/modules/signatures/network_docfile_http.py index 599b14b2..c8c46dbf 100644 --- a/modules/signatures/network_docfile_http.py +++ b/modules/signatures/network_docfile_http.py @@ -55,24 +55,19 @@ def on_call(self, call, process): addit = None if call["api"] == "URLDownloadToFileW": buff = self.get_argument(call, "URL") - if buff not in domain_passlist: - addit = {"http_downloadurl": "%s_URLDownloadToFileW_%s" % (pname, buff)} + addit = {"http_downloadurl": "%s_URLDownloadToFileW_%s" % (pname, buff)} if call["api"] == "HttpOpenRequestW": buff = self.get_argument(call, "Path") - if buff not in domain_passlist: - addit = {"http_request_path": "%s_HttpOpenRequestW_%s" % (pname, buff)} + addit = {"http_request_path": "%s_HttpOpenRequestW_%s" % (pname, buff)} if call["api"] == "InternetCrackUrlW": buff = self.get_argument(call, "Url") - if buff not in domain_passlist: - addit = {"http_request": "%s_InternetCrackUrlW_%s" % (pname, buff)} + addit = {"http_request": "%s_InternetCrackUrlW_%s" % (pname, buff)} if call["api"] == "InternetCrackUrlA": buff = self.get_argument(call, "Url") - if buff not in domain_passlist: - addit = {"http_request": "%s_InternetCrackUrlA_%s" % (pname, buff)} + addit = {"http_request": "%s_InternetCrackUrlA_%s" % (pname, buff)} if call["api"] == "WSASend": buff = self.get_argument(call, "Buffer").lower() - if buff not in domain_passlist: - addit = {"http_request": "%s_WSASend_%s" % (pname, buff)} + addit = {"http_request": "%s_WSASend_%s" % (pname, buff)} if addit and addit not in self.data: self.data.append(addit) if self.pid: @@ -86,6 +81,7 @@ def on_complete(self): and "http_request" in self.data[0] and self.data[0]["http_request"].startswith("acrord32.exe_WSASend_get /10/rdr/enu/win/nooem/none/message.zip") and self.check_url("http://acroipm.adobe.com/10/rdr/ENU/win/nooem/none/message.zip") + and self.data[0]["http_request"] in domain_passlist ): return False From b6bd8d0f6a872dd2a550a6afc5692a591d911fb0 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 24 May 2023 15:17:31 +0200 Subject: [PATCH 105/145] network_docfile_http added domain passlist to reduce FP --- modules/signatures/network_docfile_http.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/modules/signatures/network_docfile_http.py b/modules/signatures/network_docfile_http.py index c8c46dbf..3e72c42b 100644 --- a/modules/signatures/network_docfile_http.py +++ b/modules/signatures/network_docfile_http.py @@ -55,16 +55,25 @@ def on_call(self, call, process): addit = None if call["api"] == "URLDownloadToFileW": buff = self.get_argument(call, "URL") - addit = {"http_downloadurl": "%s_URLDownloadToFileW_%s" % (pname, buff)} + if buff in domain_passlist: + return None + else: + addit = {"http_downloadurl": "%s_URLDownloadToFileW_%s" % (pname, buff)} if call["api"] == "HttpOpenRequestW": buff = self.get_argument(call, "Path") addit = {"http_request_path": "%s_HttpOpenRequestW_%s" % (pname, buff)} if call["api"] == "InternetCrackUrlW": buff = self.get_argument(call, "Url") - addit = {"http_request": "%s_InternetCrackUrlW_%s" % (pname, buff)} + if buff in domain_passlist: + return None + else: + addit = {"http_request": "%s_InternetCrackUrlW_%s" % (pname, buff)} if call["api"] == "InternetCrackUrlA": buff = self.get_argument(call, "Url") - addit = {"http_request": "%s_InternetCrackUrlA_%s" % (pname, buff)} + if buff in domain_passlist: + return None + else: + addit = {"http_request": "%s_InternetCrackUrlA_%s" % (pname, buff)} if call["api"] == "WSASend": buff = self.get_argument(call, "Buffer").lower() addit = {"http_request": "%s_WSASend_%s" % (pname, buff)} @@ -81,7 +90,6 @@ def on_complete(self): and "http_request" in self.data[0] and self.data[0]["http_request"].startswith("acrord32.exe_WSASend_get /10/rdr/enu/win/nooem/none/message.zip") and self.check_url("http://acroipm.adobe.com/10/rdr/ENU/win/nooem/none/message.zip") - and self.data[0]["http_request"] in domain_passlist ): return False From 5a648f3dfa7dd8217afb0635f71e7a87b8ca68bb Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 24 May 2023 15:26:36 +0200 Subject: [PATCH 106/145] network_docfile_http added domain passlist to reduce FP --- modules/signatures/network_docfile_http.py | 25 ++++++++++------------ 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/modules/signatures/network_docfile_http.py b/modules/signatures/network_docfile_http.py index 3e72c42b..229099cc 100644 --- a/modules/signatures/network_docfile_http.py +++ b/modules/signatures/network_docfile_http.py @@ -15,8 +15,6 @@ from lib.cuckoo.common.abstracts import Signature -from data.safelist.domains import domain_passlist - class NetworkDocumentHTTP(Signature): name = "network_document_http" description = "A document file initiated network communications indicative of a potential exploit or payload download" @@ -48,6 +46,7 @@ def __init__(self, *args, **kwargs): "acrord32.exe", "acrord64.exe", ] + self.domain_passlist_bool = False def on_call(self, call, process): pname = process["process_name"].lower() @@ -55,25 +54,16 @@ def on_call(self, call, process): addit = None if call["api"] == "URLDownloadToFileW": buff = self.get_argument(call, "URL") - if buff in domain_passlist: - return None - else: - addit = {"http_downloadurl": "%s_URLDownloadToFileW_%s" % (pname, buff)} + addit = {"http_downloadurl": "%s_URLDownloadToFileW_%s" % (pname, buff)} if call["api"] == "HttpOpenRequestW": buff = self.get_argument(call, "Path") addit = {"http_request_path": "%s_HttpOpenRequestW_%s" % (pname, buff)} if call["api"] == "InternetCrackUrlW": buff = self.get_argument(call, "Url") - if buff in domain_passlist: - return None - else: - addit = {"http_request": "%s_InternetCrackUrlW_%s" % (pname, buff)} + addit = {"http_request": "%s_InternetCrackUrlW_%s" % (pname, buff)} if call["api"] == "InternetCrackUrlA": buff = self.get_argument(call, "Url") - if buff in domain_passlist: - return None - else: - addit = {"http_request": "%s_InternetCrackUrlA_%s" % (pname, buff)} + addit = {"http_request": "%s_InternetCrackUrlA_%s" % (pname, buff)} if call["api"] == "WSASend": buff = self.get_argument(call, "Buffer").lower() addit = {"http_request": "%s_WSASend_%s" % (pname, buff)} @@ -92,6 +82,13 @@ def on_complete(self): and self.check_url("http://acroipm.adobe.com/10/rdr/ENU/win/nooem/none/message.zip") ): return False + if ( + len(self.data) == 1 + and "http_request" in self.data[0] + and self.data[0]["http_request"].startswith("winword.exe_InternetCrackUrlA_https://self.events.data.microsoft.com/OneCollector/1.0/") + and self.check_url("https://self.events.data.microsoft.com/OneCollector/1.0/") + ): + return False if self.data: return True From d0bd0a116d0f6a4dc0fc6e588132ca69ef34af0d Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 24 May 2023 15:31:02 +0200 Subject: [PATCH 107/145] network_docfile_http added domain passlist to reduce FP --- modules/signatures/network_docfile_http.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/signatures/network_docfile_http.py b/modules/signatures/network_docfile_http.py index 229099cc..a39e206c 100644 --- a/modules/signatures/network_docfile_http.py +++ b/modules/signatures/network_docfile_http.py @@ -82,10 +82,9 @@ def on_complete(self): and self.check_url("http://acroipm.adobe.com/10/rdr/ENU/win/nooem/none/message.zip") ): return False - if ( + elif ( len(self.data) == 1 and "http_request" in self.data[0] - and self.data[0]["http_request"].startswith("winword.exe_InternetCrackUrlA_https://self.events.data.microsoft.com/OneCollector/1.0/") and self.check_url("https://self.events.data.microsoft.com/OneCollector/1.0/") ): return False From 140591f0aeec40adbf5df184de25dda775713d90 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 24 May 2023 15:36:20 +0200 Subject: [PATCH 108/145] network_docfile_http added domain passlist to reduce FP --- modules/signatures/network_docfile_http.py | 24 ++++++++++++++-------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/modules/signatures/network_docfile_http.py b/modules/signatures/network_docfile_http.py index a39e206c..102a6d83 100644 --- a/modules/signatures/network_docfile_http.py +++ b/modules/signatures/network_docfile_http.py @@ -15,6 +15,8 @@ from lib.cuckoo.common.abstracts import Signature +from data.safelist.domains import domain_passlist + class NetworkDocumentHTTP(Signature): name = "network_document_http" description = "A document file initiated network communications indicative of a potential exploit or payload download" @@ -54,16 +56,25 @@ def on_call(self, call, process): addit = None if call["api"] == "URLDownloadToFileW": buff = self.get_argument(call, "URL") - addit = {"http_downloadurl": "%s_URLDownloadToFileW_%s" % (pname, buff)} + if buff in domain_passlist: + self.domain_passlist_bool = True + else: + addit = {"http_downloadurl": "%s_URLDownloadToFileW_%s" % (pname, buff)} if call["api"] == "HttpOpenRequestW": buff = self.get_argument(call, "Path") addit = {"http_request_path": "%s_HttpOpenRequestW_%s" % (pname, buff)} if call["api"] == "InternetCrackUrlW": buff = self.get_argument(call, "Url") - addit = {"http_request": "%s_InternetCrackUrlW_%s" % (pname, buff)} + if buff in domain_passlist: + self.domain_passlist_bool = True + else: + addit = {"http_request": "%s_InternetCrackUrlW_%s" % (pname, buff)} if call["api"] == "InternetCrackUrlA": buff = self.get_argument(call, "Url") - addit = {"http_request": "%s_InternetCrackUrlA_%s" % (pname, buff)} + if buff in domain_passlist: + self.domain_passlist_bool = True + else: + addit = {"http_request": "%s_InternetCrackUrlA_%s" % (pname, buff)} if call["api"] == "WSASend": buff = self.get_argument(call, "Buffer").lower() addit = {"http_request": "%s_WSASend_%s" % (pname, buff)} @@ -80,12 +91,7 @@ def on_complete(self): and "http_request" in self.data[0] and self.data[0]["http_request"].startswith("acrord32.exe_WSASend_get /10/rdr/enu/win/nooem/none/message.zip") and self.check_url("http://acroipm.adobe.com/10/rdr/ENU/win/nooem/none/message.zip") - ): - return False - elif ( - len(self.data) == 1 - and "http_request" in self.data[0] - and self.check_url("https://self.events.data.microsoft.com/OneCollector/1.0/") + or self.domain_passlist_bool == True ): return False From 0c41980bf4cb099a2e30cacdddc840711ae1372f Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 24 May 2023 15:41:37 +0200 Subject: [PATCH 109/145] network_docfile_http added domain passlist to reduce FP --- modules/signatures/network_docfile_http.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/signatures/network_docfile_http.py b/modules/signatures/network_docfile_http.py index 102a6d83..b26f71c4 100644 --- a/modules/signatures/network_docfile_http.py +++ b/modules/signatures/network_docfile_http.py @@ -90,11 +90,13 @@ def on_complete(self): len(self.data) == 1 and "http_request" in self.data[0] and self.data[0]["http_request"].startswith("acrord32.exe_WSASend_get /10/rdr/enu/win/nooem/none/message.zip") - and self.check_url("http://acroipm.adobe.com/10/rdr/ENU/win/nooem/none/message.zip") - or self.domain_passlist_bool == True + and self.check_url("http://acroipm.adobe.com/10/rdr/ENU/win/nooem/none/message.zip") ): return False - + + if self.domain_passlist_bool == True: + return False + if self.data: return True From df109c0a25bfd2f0582912f7b3ef402e655789d6 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 24 May 2023 15:49:29 +0200 Subject: [PATCH 110/145] network_docfile_http added domain passlist to reduce FP --- modules/signatures/network_docfile_http.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/modules/signatures/network_docfile_http.py b/modules/signatures/network_docfile_http.py index b26f71c4..490fd020 100644 --- a/modules/signatures/network_docfile_http.py +++ b/modules/signatures/network_docfile_http.py @@ -48,7 +48,6 @@ def __init__(self, *args, **kwargs): "acrord32.exe", "acrord64.exe", ] - self.domain_passlist_bool = False def on_call(self, call, process): pname = process["process_name"].lower() @@ -56,8 +55,8 @@ def on_call(self, call, process): addit = None if call["api"] == "URLDownloadToFileW": buff = self.get_argument(call, "URL") - if buff in domain_passlist: - self.domain_passlist_bool = True + if any(domain in buff for domain in domain_passlist): + return None else: addit = {"http_downloadurl": "%s_URLDownloadToFileW_%s" % (pname, buff)} if call["api"] == "HttpOpenRequestW": @@ -65,14 +64,14 @@ def on_call(self, call, process): addit = {"http_request_path": "%s_HttpOpenRequestW_%s" % (pname, buff)} if call["api"] == "InternetCrackUrlW": buff = self.get_argument(call, "Url") - if buff in domain_passlist: - self.domain_passlist_bool = True + if any(domain in buff for domain in domain_passlist): + return None else: addit = {"http_request": "%s_InternetCrackUrlW_%s" % (pname, buff)} if call["api"] == "InternetCrackUrlA": buff = self.get_argument(call, "Url") - if buff in domain_passlist: - self.domain_passlist_bool = True + if any(domain in buff for domain in domain_passlist): + return None else: addit = {"http_request": "%s_InternetCrackUrlA_%s" % (pname, buff)} if call["api"] == "WSASend": @@ -94,9 +93,6 @@ def on_complete(self): ): return False - if self.domain_passlist_bool == True: - return False - if self.data: return True From fe01aea70c87dab3b8c9f7ff79cc0a56aea85055 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 24 May 2023 15:57:07 +0200 Subject: [PATCH 111/145] http_request added domain passlist to reduce FP --- modules/signatures/http_request.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/signatures/http_request.py b/modules/signatures/http_request.py index b5cc7b6a..0353e1b2 100644 --- a/modules/signatures/http_request.py +++ b/modules/signatures/http_request.py @@ -46,7 +46,7 @@ def on_call(self, call, process): host = self.get_argument(call, "ServerName") port = self.get_argument(call, "ServerPort") self.lasthost = host - if host in domain_passlist: + if any(domain in host for domain in domain_passlist) : return None if host not in self.request: self.request[host] = dict() @@ -56,7 +56,7 @@ def on_call(self, call, process): elif call["api"].startswith("HttpOpenRequest"): handle = str(self.get_argument(call, "InternetHandle")) # Sanity check - if self.lasthost in domain_passlist: + if any(domain in self.lasthost for domain in domain_passlist): return None if self.lasthost and handle == self.request[self.lasthost]["curhandle"]: uri = self.get_argument(call, "Path") From da7bec555e80620fcd39f6b52b218da3d56f31f1 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 24 May 2023 16:07:29 +0200 Subject: [PATCH 112/145] http_request added domain passlist to reduce FP --- modules/signatures/http_request.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/modules/signatures/http_request.py b/modules/signatures/http_request.py index 0353e1b2..37fedd4f 100644 --- a/modules/signatures/http_request.py +++ b/modules/signatures/http_request.py @@ -66,17 +66,23 @@ def on_call(self, call, process): elif call["api"] == "WinHttpGetProxyForUrl": url = self.get_argument(call, "Url") if url: - for wlhost in domain_passlist: - self.urls.add(url) - if self.pid: - self.mark_call() + if any(domain in url for domain in domain_passlist): + return None + else: + for wlhost in domain_passlist: + self.urls.add(url) + if self.pid: + self.mark_call() elif call["api"].startswith("InternetOpenUrl"): url = self.get_argument(call, "URL") if url: - for wlhost in domain_passlist: - self.urls.add(url) - if self.pid: - self.mark_call() + if any(domain in url for domain in domain_passlist): + return None + else: + for wlhost in domain_passlist: + self.urls.add(url) + if self.pid: + self.mark_call() def on_complete(self): ret = False From 0d33a51001ec7b5d3ba7f46c0257edbb9cb0235a Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 24 May 2023 16:19:58 +0200 Subject: [PATCH 113/145] Changed the condition of vmdetect.yar since it triggered 2 many FP's --- data/yara/binaries/vmdetect.yar | 2 +- modules/signatures/http_request.py | 14 ++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/data/yara/binaries/vmdetect.yar b/data/yara/binaries/vmdetect.yar index 8e0a7c85..f2c8bf3d 100644 --- a/data/yara/binaries/vmdetect.yar +++ b/data/yara/binaries/vmdetect.yar @@ -78,5 +78,5 @@ rule vmdetect $virtualbox_mac_1c = "080027" condition: - any of them + 2 of them } diff --git a/modules/signatures/http_request.py b/modules/signatures/http_request.py index 37fedd4f..89fa1f52 100644 --- a/modules/signatures/http_request.py +++ b/modules/signatures/http_request.py @@ -69,20 +69,18 @@ def on_call(self, call, process): if any(domain in url for domain in domain_passlist): return None else: - for wlhost in domain_passlist: - self.urls.add(url) - if self.pid: - self.mark_call() + self.urls.add(url) + if self.pid: + self.mark_call() elif call["api"].startswith("InternetOpenUrl"): url = self.get_argument(call, "URL") if url: if any(domain in url for domain in domain_passlist): return None else: - for wlhost in domain_passlist: - self.urls.add(url) - if self.pid: - self.mark_call() + self.urls.add(url) + if self.pid: + self.mark_call() def on_complete(self): ret = False From 222093b4f6fe373f83a2ae4175b276299c859501 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 24 May 2023 16:25:51 +0200 Subject: [PATCH 114/145] Changed the condition of vmdetect.yar since it triggered 2 many FP's --- data/yara/binaries/vmdetect.yar | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/data/yara/binaries/vmdetect.yar b/data/yara/binaries/vmdetect.yar index f2c8bf3d..69d40cc5 100644 --- a/data/yara/binaries/vmdetect.yar +++ b/data/yara/binaries/vmdetect.yar @@ -36,11 +36,12 @@ rule vmdetect $vmware17 = "vmicshutdown" nocase $vmware18 = "vmicexchange" nocase $vmware19 = "vmdebug" nocase - $vmware20 = "vmmouse" nocase + $vmware20 = "vmmouse.sys" nocase $vmware21 = "vmtools" nocase $vmware22 = "VMMEMCTL" nocase $vmware23 = "vmx86" nocase $vmware24 = "vmware" nocase + $vmware25 = "VMware Virtual IDE Hard Drive" ascii wide $virtualpc1 = "vpcbus" nocase $virtualpc2 = "vpc-s3" nocase $virtualpc3 = "vpcuhub" nocase @@ -77,6 +78,12 @@ rule vmdetect $virtualbox_mac_1b = "08:00:27" $virtualbox_mac_1c = "080027" + //Drivers + $vbox_driver_1 = "SOFTWARE\\Oracle\\VirtualBox Guest Additions" nocase ascii wide + $vbox_driver_2 = "SOFTWARE\\\\Oracle\\\\VirtualBox Guest Additions" nocase ascii wide + $miscvm1 = "SYSTEM\\ControlSet001\\Services\\Disk\\Enum" nocase ascii wide + $miscvm2 = "SYSTEM\\\\ControlSet001\\\\Services\\\\Disk\\\\Enum" nocase ascii wide + condition: 2 of them } From 78af3455d92a3e35e80cd22ca6e8638caacda3e4 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Thu, 25 May 2023 10:30:00 +0200 Subject: [PATCH 115/145] antivm signature changed so that winword is whitelisted, this rule probably needs changing since it will not see files that are being pulled from the internet --- modules/signatures/antivm_generic_system.py | 33 ++++++++++++++++----- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/modules/signatures/antivm_generic_system.py b/modules/signatures/antivm_generic_system.py index 175cbae7..dfd37d51 100644 --- a/modules/signatures/antivm_generic_system.py +++ b/modules/signatures/antivm_generic_system.py @@ -28,12 +28,31 @@ class AntiVMSystem(Signature): ttps += ["U1332"] # Unprotect mbcs = ["OB0001", "B0009", "B0009.005", "OB0007", "E1082"] mbcs += ["OC0008", "C0036", "C0036.005"] # micro-behaviour + evented = True - def run(self): - if self.check_read_key( - pattern=".*\\\\SYSTEM\\\\(CurrentControlSet|ControlSet001)\\\\Control\\\\SystemInformation\\\\SystemManufacturer$", - regex=True, - ): - return True + filter_category = set([ + "registry", + ]) - return False + def __init__(self, *args, **kwargs): + Signature.__init__(self, *args, **kwargs) + self.data = [] + self.office_proc_list = [ + "wordview.exe", + "winword.exe", + "excel.exe", + "powerpnt.exe", + "outlook.exe", + "acrord32.exe", + "acrord64.exe", + ] + def on_call(self, call, process): + pname = process["process_name"].lower() + if pname in self.office_proc_list: + return False + else: + self.check_read_key( + pattern=".*\\\\SYSTEM\\\\(CurrentControlSet|ControlSet001)\\\\Control\\\\SystemInformation\\\\SystemManufacturer$", + regex=True, + ) + return True From c9b76d45a2edb6f84f1cde79fbba8907c54f43ef Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Thu, 25 May 2023 10:51:07 +0200 Subject: [PATCH 116/145] changed more antivm --- modules/signatures/antisandbox_unhook.py | 2 +- modules/signatures/antivm_generic_disk.py | 11 +++++++++++ modules/signatures/antivm_generic_system.py | 11 ++++++----- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/modules/signatures/antisandbox_unhook.py b/modules/signatures/antisandbox_unhook.py index c1424032..f186e702 100644 --- a/modules/signatures/antisandbox_unhook.py +++ b/modules/signatures/antisandbox_unhook.py @@ -39,7 +39,7 @@ def __init__(self, *args, **kwargs): self.is_url_analysis = False if self.results.get("target", {}).get("category", "") == "url": self.is_url_analysis = True - self.safelistprocs = ["acrord32.exe", "acrobat.exe"] + self.safelistprocs = ["acrord32.exe", "acrobat.exe", "excel.exe"] def on_call(self, call, process): if process["process_name"].lower() in self.safelistprocs: diff --git a/modules/signatures/antivm_generic_disk.py b/modules/signatures/antivm_generic_disk.py index bcd033bf..77697b8e 100644 --- a/modules/signatures/antivm_generic_disk.py +++ b/modules/signatures/antivm_generic_disk.py @@ -37,6 +37,15 @@ def __init__(self, *args, **kwargs): Signature.__init__(self, *args, **kwargs) self.lastprocess = 0 self.handles = dict() + self.office_proc_list = [ + "wordview.exe", + "winword.exe", + "excel.exe", + "powerpnt.exe", + "outlook.exe", + "acrord32.exe", + "acrord64.exe", + ] def on_call(self, call, process): ioctls = [ @@ -50,6 +59,8 @@ def on_call(self, call, process): if process is not self.lastprocess: self.handles = dict() self.lastprocess = process + if process["process_name"].lower() in self.office_proc_list: + return False if call["api"] == "NtDuplicateObject" and call["status"]: tgtarg = self.get_argument(call, "TargetHandle") diff --git a/modules/signatures/antivm_generic_system.py b/modules/signatures/antivm_generic_system.py index dfd37d51..5f92313a 100644 --- a/modules/signatures/antivm_generic_system.py +++ b/modules/signatures/antivm_generic_system.py @@ -50,9 +50,10 @@ def on_call(self, call, process): pname = process["process_name"].lower() if pname in self.office_proc_list: return False - else: - self.check_read_key( - pattern=".*\\\\SYSTEM\\\\(CurrentControlSet|ControlSet001)\\\\Control\\\\SystemInformation\\\\SystemManufacturer$", - regex=True, - ) + if self.check_read_key( + pattern=".*\\\\SYSTEM\\\\(CurrentControlSet|ControlSet001)\\\\Control\\\\SystemInformation\\\\SystemManufacturer$", + regex=True, + ): return True + + return False From 98aba33279c3b0a073dd02efe95b66f6079273e7 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Thu, 25 May 2023 10:55:46 +0200 Subject: [PATCH 117/145] changed enumerating processes, Acrobat enumerates these for some reason --- modules/signatures/infostealer_cookies.py | 3 ++- modules/signatures/process_discovery.py | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/signatures/infostealer_cookies.py b/modules/signatures/infostealer_cookies.py index f6a42ea1..a9eeee6c 100644 --- a/modules/signatures/infostealer_cookies.py +++ b/modules/signatures/infostealer_cookies.py @@ -48,7 +48,8 @@ def __init__(self, *args, **kwargs): "firefox.exe", "opera.exe", "msedge.exe", - "acrobat.exe" + "acrobat.exe", + "excel.exe", ] def on_call(self, call, process): if process["process_name"] not in self.safe_indicators: diff --git a/modules/signatures/process_discovery.py b/modules/signatures/process_discovery.py index 6b44025a..9c281d05 100644 --- a/modules/signatures/process_discovery.py +++ b/modules/signatures/process_discovery.py @@ -32,10 +32,15 @@ class EmumeratesRunningProcesses(Signature): def __init__(self, *args, **kwargs): Signature.__init__(self, *args, **kwargs) self.enumeratedpids = [] + self.safelist = [ + "acrobat.exe", + ] def on_call(self, call, process): procname = self.get_argument(call, "ProcessName") procpid = self.get_argument(call, "ProcessId") + if procname in self.safelist: + return False if procpid and procname: if procpid not in self.enumeratedpids and procpid != "0": self.enumeratedpids.append(procpid) From 64407f9195343046b44368762406030a9eb0db6d Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Thu, 25 May 2023 12:03:39 +0200 Subject: [PATCH 118/145] changed enumerating processes, Acrobat enumerates these for some reason --- modules/signatures/antisandbox_unhook.py | 2 +- modules/signatures/antivm_generic_system.py | 9 ++++----- modules/signatures/infostealer_cookies.py | 1 + 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/signatures/antisandbox_unhook.py b/modules/signatures/antisandbox_unhook.py index f186e702..5a5dddc0 100644 --- a/modules/signatures/antisandbox_unhook.py +++ b/modules/signatures/antisandbox_unhook.py @@ -39,7 +39,7 @@ def __init__(self, *args, **kwargs): self.is_url_analysis = False if self.results.get("target", {}).get("category", "") == "url": self.is_url_analysis = True - self.safelistprocs = ["acrord32.exe", "acrobat.exe", "excel.exe"] + self.safelistprocs = ["acrord32.exe", "acrobat.exe", "excel.exe", "winword.exe", "powerpnt.exe", "outlook.exe"] def on_call(self, call, process): if process["process_name"].lower() in self.safelistprocs: diff --git a/modules/signatures/antivm_generic_system.py b/modules/signatures/antivm_generic_system.py index 5f92313a..b7d9bd62 100644 --- a/modules/signatures/antivm_generic_system.py +++ b/modules/signatures/antivm_generic_system.py @@ -50,10 +50,9 @@ def on_call(self, call, process): pname = process["process_name"].lower() if pname in self.office_proc_list: return False - if self.check_read_key( + else: + self.check_read_key( pattern=".*\\\\SYSTEM\\\\(CurrentControlSet|ControlSet001)\\\\Control\\\\SystemInformation\\\\SystemManufacturer$", regex=True, - ): - return True - - return False + ) + return True \ No newline at end of file diff --git a/modules/signatures/infostealer_cookies.py b/modules/signatures/infostealer_cookies.py index a9eeee6c..69f8ebf4 100644 --- a/modules/signatures/infostealer_cookies.py +++ b/modules/signatures/infostealer_cookies.py @@ -50,6 +50,7 @@ def __init__(self, *args, **kwargs): "msedge.exe", "acrobat.exe", "excel.exe", + "winword.exe", ] def on_call(self, call, process): if process["process_name"] not in self.safe_indicators: From 870c6097adc74714b7a2c819b4abb13364ba0c93 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Thu, 25 May 2023 13:02:43 +0200 Subject: [PATCH 119/145] changed enumerating processes, Acrobat enumerates these for some reason --- modules/signatures/antivm_generic_system.py | 2 +- modules/signatures/infostealer_cookies.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/signatures/antivm_generic_system.py b/modules/signatures/antivm_generic_system.py index b7d9bd62..c9b82ddc 100644 --- a/modules/signatures/antivm_generic_system.py +++ b/modules/signatures/antivm_generic_system.py @@ -46,7 +46,7 @@ def __init__(self, *args, **kwargs): "acrord32.exe", "acrord64.exe", ] - def on_call(self, call, process): + def on_call(self, _, process): pname = process["process_name"].lower() if pname in self.office_proc_list: return False diff --git a/modules/signatures/infostealer_cookies.py b/modules/signatures/infostealer_cookies.py index 69f8ebf4..ea2e4e2e 100644 --- a/modules/signatures/infostealer_cookies.py +++ b/modules/signatures/infostealer_cookies.py @@ -52,7 +52,7 @@ def __init__(self, *args, **kwargs): "excel.exe", "winword.exe", ] - def on_call(self, call, process): + def on_call(self, _, process): if process["process_name"] not in self.safe_indicators: for indicator in self.indicators: match = self.check_file(pattern=indicator, regex=True) From 63bf3f7e5988ce33d6fd2c564c7aa386be702653 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Thu, 25 May 2023 13:17:31 +0200 Subject: [PATCH 120/145] Changed processname to lower in infostealer cookies --- modules/signatures/infostealer_cookies.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/signatures/infostealer_cookies.py b/modules/signatures/infostealer_cookies.py index ea2e4e2e..176824e3 100644 --- a/modules/signatures/infostealer_cookies.py +++ b/modules/signatures/infostealer_cookies.py @@ -53,7 +53,7 @@ def __init__(self, *args, **kwargs): "winword.exe", ] def on_call(self, _, process): - if process["process_name"] not in self.safe_indicators: + if process["process_name"].lower() not in self.safe_indicators: for indicator in self.indicators: match = self.check_file(pattern=indicator, regex=True) if match: From af526c41b88a1734a85df141d58937d63b3b5159 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Thu, 25 May 2023 13:32:04 +0200 Subject: [PATCH 121/145] antivm system logic error fixed added if statement --- modules/signatures/antivm_generic_disk.py | 5 +++-- modules/signatures/antivm_generic_system.py | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/modules/signatures/antivm_generic_disk.py b/modules/signatures/antivm_generic_disk.py index 77697b8e..7789b455 100644 --- a/modules/signatures/antivm_generic_disk.py +++ b/modules/signatures/antivm_generic_disk.py @@ -48,6 +48,9 @@ def __init__(self, *args, **kwargs): ] def on_call(self, call, process): + if process["process_name"].lower() in self.office_proc_list: + return False + ioctls = [ 0x2D1400, # IOCTL_STORAGE_QUERY_PROPERTY 0x70000, # IOCTL_DISK_GET_DRIVE_GEOMETRY @@ -59,8 +62,6 @@ def on_call(self, call, process): if process is not self.lastprocess: self.handles = dict() self.lastprocess = process - if process["process_name"].lower() in self.office_proc_list: - return False if call["api"] == "NtDuplicateObject" and call["status"]: tgtarg = self.get_argument(call, "TargetHandle") diff --git a/modules/signatures/antivm_generic_system.py b/modules/signatures/antivm_generic_system.py index c9b82ddc..3403dc43 100644 --- a/modules/signatures/antivm_generic_system.py +++ b/modules/signatures/antivm_generic_system.py @@ -51,8 +51,10 @@ def on_call(self, _, process): if pname in self.office_proc_list: return False else: - self.check_read_key( + match = self.check_read_key( pattern=".*\\\\SYSTEM\\\\(CurrentControlSet|ControlSet001)\\\\Control\\\\SystemInformation\\\\SystemManufacturer$", regex=True, ) + + if match: return True \ No newline at end of file From 60758c7055e226c3a2548b137cf8923bd79b1be3 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Thu, 25 May 2023 14:00:05 +0200 Subject: [PATCH 122/145] added whitelist in infostealer cookie --- modules/signatures/infostealer_cookies.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/modules/signatures/infostealer_cookies.py b/modules/signatures/infostealer_cookies.py index 176824e3..ff05ce43 100644 --- a/modules/signatures/infostealer_cookies.py +++ b/modules/signatures/infostealer_cookies.py @@ -53,11 +53,10 @@ def __init__(self, *args, **kwargs): "winword.exe", ] def on_call(self, _, process): - if process["process_name"].lower() not in self.safe_indicators: - for indicator in self.indicators: - match = self.check_file(pattern=indicator, regex=True) - if match: - self.data.append({"cookie": match}) - return True - - return False + if process["process_name"].lower() in self.safe_indicators: + return False + for indicator in self.indicators: + match = self.check_file(pattern=indicator, regex=True) + if match: + self.data.append({"cookie": match}) + return True From 46dfa7af1bf6979e84ad1550a10758fa12bf8ba9 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Thu, 25 May 2023 14:10:33 +0200 Subject: [PATCH 123/145] added whitelist in infostealer cookie --- modules/signatures/infostealer_cookies.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/signatures/infostealer_cookies.py b/modules/signatures/infostealer_cookies.py index ff05ce43..25879bab 100644 --- a/modules/signatures/infostealer_cookies.py +++ b/modules/signatures/infostealer_cookies.py @@ -53,10 +53,11 @@ def __init__(self, *args, **kwargs): "winword.exe", ] def on_call(self, _, process): - if process["process_name"].lower() in self.safe_indicators: + pname = process["process_name"].lower() + if pname in self.safe_indicators: return False for indicator in self.indicators: match = self.check_file(pattern=indicator, regex=True) if match: - self.data.append({"cookie": match}) + self.data.append({f"Process: {pname} read the following cookie: {match}"}) return True From 42a079a63b1e1b4499db84961283c09903d0d5c8 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Thu, 25 May 2023 14:15:24 +0200 Subject: [PATCH 124/145] added whitelist in infostealer cookie --- modules/signatures/infostealer_cookies.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/signatures/infostealer_cookies.py b/modules/signatures/infostealer_cookies.py index 25879bab..57f83c9d 100644 --- a/modules/signatures/infostealer_cookies.py +++ b/modules/signatures/infostealer_cookies.py @@ -59,5 +59,5 @@ def on_call(self, _, process): for indicator in self.indicators: match = self.check_file(pattern=indicator, regex=True) if match: - self.data.append({f"Process: {pname} read the following cookie: {match}"}) + self.data.append({"Process: {pname} read the following cookie: {match}"}) return True From c325fd78627c9ab727f8e2b01e6062722933967a Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Thu, 25 May 2023 14:20:48 +0200 Subject: [PATCH 125/145] added whitelist in infostealer cookie --- modules/signatures/infostealer_cookies.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/modules/signatures/infostealer_cookies.py b/modules/signatures/infostealer_cookies.py index 57f83c9d..259962e9 100644 --- a/modules/signatures/infostealer_cookies.py +++ b/modules/signatures/infostealer_cookies.py @@ -52,12 +52,15 @@ def __init__(self, *args, **kwargs): "excel.exe", "winword.exe", ] - def on_call(self, _, process): + def on_call(self, call, process): pname = process["process_name"].lower() if pname in self.safe_indicators: return False for indicator in self.indicators: match = self.check_file(pattern=indicator, regex=True) if match: - self.data.append({"Process: {pname} read the following cookie: {match}"}) - return True + self.add_match(process, 'api', match) + # self.data.append({"cookie": match}) + # return True + def on_complete(self): + return self.has_matches() From 3d8bd137d1781041bfefd31d2df98181079cb2bc Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Thu, 25 May 2023 14:32:46 +0200 Subject: [PATCH 126/145] added whitelist in infostealer cookie --- modules/signatures/infostealer_cookies.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/modules/signatures/infostealer_cookies.py b/modules/signatures/infostealer_cookies.py index 259962e9..1388c04b 100644 --- a/modules/signatures/infostealer_cookies.py +++ b/modules/signatures/infostealer_cookies.py @@ -56,11 +56,13 @@ def on_call(self, call, process): pname = process["process_name"].lower() if pname in self.safe_indicators: return False - for indicator in self.indicators: - match = self.check_file(pattern=indicator, regex=True) - if match: - self.add_match(process, 'api', match) - # self.data.append({"cookie": match}) - # return True + else: + for indicator in self.indicators: + match = self.check_file(pattern=indicator, regex=True) + if match: + self.add_match(process, 'api', match) + self.data.append("cookie " + match) + self.data.append("process " + pname) + def on_complete(self): return self.has_matches() From e0cbcf7a90f912a77ed82f5edaabfd4be8ae5bc8 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Thu, 25 May 2023 14:42:08 +0200 Subject: [PATCH 127/145] added whitelist in infostealer cookie --- modules/signatures/infostealer_cookies.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/signatures/infostealer_cookies.py b/modules/signatures/infostealer_cookies.py index 1388c04b..a6450450 100644 --- a/modules/signatures/infostealer_cookies.py +++ b/modules/signatures/infostealer_cookies.py @@ -58,11 +58,9 @@ def on_call(self, call, process): return False else: for indicator in self.indicators: - match = self.check_file(pattern=indicator, regex=True) + match = self.check_key(pattern=indicator, regex=True) if match: - self.add_match(process, 'api', match) - self.data.append("cookie " + match) - self.data.append("process " + pname) + self.add_match(process, 'registry', indicator) def on_complete(self): return self.has_matches() From 22b55ee6ccbb7bf2edbe35728af301200ba5c9bc Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Thu, 25 May 2023 14:45:06 +0200 Subject: [PATCH 128/145] added whitelist in infostealer cookie --- modules/signatures/infostealer_cookies.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/signatures/infostealer_cookies.py b/modules/signatures/infostealer_cookies.py index a6450450..42486b8d 100644 --- a/modules/signatures/infostealer_cookies.py +++ b/modules/signatures/infostealer_cookies.py @@ -26,7 +26,7 @@ class CookiesStealer(Signature): evented = True ttps = ["T1539"] # MITRE v6,7,8 - filter_apinames = ["NtQueryValueKey"] + filter_apinames = set(["NtQueryValueKey"]) def __init__(self, *args, **kwargs): Signature.__init__(self, *args, **kwargs) @@ -57,10 +57,11 @@ def on_call(self, call, process): if pname in self.safe_indicators: return False else: - for indicator in self.indicators: - match = self.check_key(pattern=indicator, regex=True) - if match: - self.add_match(process, 'registry', indicator) + if call["api"] == "NtQueryValueKey": + for indicator in self.indicators: + match = self.check_file(pattern=indicator, regex=True) + if match: + self.add_match(process, 'file', match) def on_complete(self): return self.has_matches() From b204936d6fc179689e3d2bf277607cc593f66a9a Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Thu, 25 May 2023 14:50:02 +0200 Subject: [PATCH 129/145] Rewrote antivm system --- modules/signatures/antivm_generic_system.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/signatures/antivm_generic_system.py b/modules/signatures/antivm_generic_system.py index 3403dc43..ffaff04a 100644 --- a/modules/signatures/antivm_generic_system.py +++ b/modules/signatures/antivm_generic_system.py @@ -57,4 +57,7 @@ def on_call(self, _, process): ) if match: - return True \ No newline at end of file + self.add_match(process, 'registry', match) + + def on_complete(self): + return self.has_matches() \ No newline at end of file From 468cfe6cfa4348632e3106ba1b9afb55a436e06d Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Thu, 25 May 2023 15:00:34 +0200 Subject: [PATCH 130/145] added whitelist in infostealer cookie --- modules/signatures/infostealer_cookies.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/signatures/infostealer_cookies.py b/modules/signatures/infostealer_cookies.py index 42486b8d..722615e6 100644 --- a/modules/signatures/infostealer_cookies.py +++ b/modules/signatures/infostealer_cookies.py @@ -26,7 +26,7 @@ class CookiesStealer(Signature): evented = True ttps = ["T1539"] # MITRE v6,7,8 - filter_apinames = set(["NtQueryValueKey"]) + filter_apinames = set(["NtQueryAttributesFile"]) def __init__(self, *args, **kwargs): Signature.__init__(self, *args, **kwargs) @@ -57,7 +57,7 @@ def on_call(self, call, process): if pname in self.safe_indicators: return False else: - if call["api"] == "NtQueryValueKey": + if call["api"] == "NtQueryAttributesFile": for indicator in self.indicators: match = self.check_file(pattern=indicator, regex=True) if match: From 300dc25488c7fc9af7f45f2a029b6e8ee3a966d4 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Thu, 25 May 2023 15:10:02 +0200 Subject: [PATCH 131/145] added whitelist in infostealer cookie --- modules/signatures/infostealer_cookies.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/modules/signatures/infostealer_cookies.py b/modules/signatures/infostealer_cookies.py index 722615e6..f7299df2 100644 --- a/modules/signatures/infostealer_cookies.py +++ b/modules/signatures/infostealer_cookies.py @@ -57,11 +57,10 @@ def on_call(self, call, process): if pname in self.safe_indicators: return False else: - if call["api"] == "NtQueryAttributesFile": - for indicator in self.indicators: - match = self.check_file(pattern=indicator, regex=True) - if match: - self.add_match(process, 'file', match) + for indicator in self.indicators: + match = self.check_argument_call(call, pattern=indicator, api="NtQueryAttributesFile", category="filesystem", regex=True) + if match: + self.add_match(process, 'file', match) def on_complete(self): return self.has_matches() From 2e3f61f61e9e8ab9a8ea01479be8a3a7c0dc87f9 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Thu, 25 May 2023 15:17:41 +0200 Subject: [PATCH 132/145] Rewrote antivm system --- modules/signatures/antivm_generic_system.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/modules/signatures/antivm_generic_system.py b/modules/signatures/antivm_generic_system.py index ffaff04a..dc9ef93b 100644 --- a/modules/signatures/antivm_generic_system.py +++ b/modules/signatures/antivm_generic_system.py @@ -46,18 +46,17 @@ def __init__(self, *args, **kwargs): "acrord32.exe", "acrord64.exe", ] - def on_call(self, _, process): + def on_call(self, call, process): pname = process["process_name"].lower() if pname in self.office_proc_list: return False else: - match = self.check_read_key( - pattern=".*\\\\SYSTEM\\\\(CurrentControlSet|ControlSet001)\\\\Control\\\\SystemInformation\\\\SystemManufacturer$", - regex=True, - ) - + match = self.check_argument_call(call, + pattern=".*\\\\SYSTEM\\\\(CurrentControlSet|ControlSet001)\\\\Control\\\\SystemInformation\\\\SystemManufacturer$", + category="registry", + regex=True) if match: - self.add_match(process, 'registry', match) + self.add_match(process, "registry", match) def on_complete(self): return self.has_matches() \ No newline at end of file From 126b8a4dd0ef95738688b621ae8327445122986e Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 31 May 2023 10:05:42 +0200 Subject: [PATCH 133/145] generic disk antivm FP tuning --- modules/signatures/antivm_generic_disk.py | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/signatures/antivm_generic_disk.py b/modules/signatures/antivm_generic_disk.py index 7789b455..23a2b1bf 100644 --- a/modules/signatures/antivm_generic_disk.py +++ b/modules/signatures/antivm_generic_disk.py @@ -45,6 +45,7 @@ def __init__(self, *args, **kwargs): "outlook.exe", "acrord32.exe", "acrord64.exe", + "acrobat.exe", ] def on_call(self, call, process): From 7f97223bfa8baa08242cdda7da68ac5204354019 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 31 May 2023 10:27:17 +0200 Subject: [PATCH 134/145] generic CPU antivm FP tuning --- modules/signatures/antivm_generic_cpu.py | 38 +++++++++++++++++---- modules/signatures/antivm_generic_system.py | 1 - 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/modules/signatures/antivm_generic_cpu.py b/modules/signatures/antivm_generic_cpu.py index dcced0d2..b7c84c5b 100644 --- a/modules/signatures/antivm_generic_cpu.py +++ b/modules/signatures/antivm_generic_cpu.py @@ -29,9 +29,35 @@ class AntiVMCPU(Signature): mbcs = ["OB0001", "B0009", "B0009.005", "B0009.024", "OB0007", "E1082"] mbcs += ["OC0008", "C0036", "C0036.005"] # micro-behaviour - def run(self): - if self.check_read_key( - pattern=r".*\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\[^\\]+\\ProcessorNameString$", regex=True - ): - return True - return False + filter_apinames = set([ + "RegQueryValueExW", + "RegQueryValueExA", + "NtQueryValueKey", + ]) + filter_categories = set(["registry"]) + + def __init__(self, *args, **kwargs): + Signature.__init__(self, *args, **kwargs) + self.safe_proc_list = [ + "wordview.exe", + "winword.exe", + "excel.exe", + "powerpnt.exe", + "outlook.exe", + "acrord32.exe", + "acrord64.exe", + "acrobat.exe", + ] + + def on_call(self, call, process): + if process["process_name"].lower() in self.office_proc_list: + return False + else: + match = self.check_read_key( + pattern=r".*\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\[^\\]+\\ProcessorNameString$", regex=True + ) + if match: + self.add_match(process, "registry", match) + + def on_complete(self): + return self.has_matches() \ No newline at end of file diff --git a/modules/signatures/antivm_generic_system.py b/modules/signatures/antivm_generic_system.py index dc9ef93b..3e96b318 100644 --- a/modules/signatures/antivm_generic_system.py +++ b/modules/signatures/antivm_generic_system.py @@ -36,7 +36,6 @@ class AntiVMSystem(Signature): def __init__(self, *args, **kwargs): Signature.__init__(self, *args, **kwargs) - self.data = [] self.office_proc_list = [ "wordview.exe", "winword.exe", From bd28feac6912766bdf2a55ade34de0a08b1335e0 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 31 May 2023 10:41:38 +0200 Subject: [PATCH 135/145] stealth file FP tuning --- modules/signatures/process_discovery.py | 7 +++++++ modules/signatures/stealth_file.py | 1 + 2 files changed, 8 insertions(+) diff --git a/modules/signatures/process_discovery.py b/modules/signatures/process_discovery.py index 9c281d05..5ab18b9c 100644 --- a/modules/signatures/process_discovery.py +++ b/modules/signatures/process_discovery.py @@ -34,6 +34,13 @@ def __init__(self, *args, **kwargs): self.enumeratedpids = [] self.safelist = [ "acrobat.exe", + "winword.exe", + "excel.exe", + "powerpnt.exe", + "outlook.exe", + "acrord32.exe", + "acrord64.exe", + "wordview.exe", ] def on_call(self, call, process): diff --git a/modules/signatures/stealth_file.py b/modules/signatures/stealth_file.py index ae13c3bb..3c634f4c 100644 --- a/modules/signatures/stealth_file.py +++ b/modules/signatures/stealth_file.py @@ -120,6 +120,7 @@ def on_complete(self): r"^[A-Z]?:\\Users\\[^\\]+\\AppData\\Local\\Microsoft\\Feeds\\.*", r"^[A-Z]?:\\Users\\[^\\]+\\AppData\\Local\\Microsoft\\Feeds Cache\\$", r"^[A-Z]?:\\Users\\[^\\]+\\AppData\\Local\\Microsoft\\Feeds Cache\\index\.dat$", + r"^[A-Z]?:\\Users\\[^\\]+\\AppData\\Roaming\\Microsoft\\Templates\\~$Normal\.dotm", r"^[A-Z]?:\\Users\\[^\\]+\\AppData\\Roaming\\Microsoft\\Windows\\IETldCache\\$", r"^[A-Z]?:\\Users\\[^\\]+\\AppData\\Roaming\\Microsoft\\Windows\\IETldCache\\index\.dat$", r"^[A-Z]?:\\Users\\[^\\]+\\AppData\\Roaming\\Microsoft\\Windows\\IECompatUACache\\Low$", From a8a9974e68b046214307063eaee319741bb72e77 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 31 May 2023 13:17:43 +0200 Subject: [PATCH 136/145] stealth file FP tuning --- modules/signatures/stealth_file.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/signatures/stealth_file.py b/modules/signatures/stealth_file.py index 3c634f4c..20a12b80 100644 --- a/modules/signatures/stealth_file.py +++ b/modules/signatures/stealth_file.py @@ -120,7 +120,7 @@ def on_complete(self): r"^[A-Z]?:\\Users\\[^\\]+\\AppData\\Local\\Microsoft\\Feeds\\.*", r"^[A-Z]?:\\Users\\[^\\]+\\AppData\\Local\\Microsoft\\Feeds Cache\\$", r"^[A-Z]?:\\Users\\[^\\]+\\AppData\\Local\\Microsoft\\Feeds Cache\\index\.dat$", - r"^[A-Z]?:\\Users\\[^\\]+\\AppData\\Roaming\\Microsoft\\Templates\\~$Normal\.dotm", + r"^[A-Z]?:\\Users\\[^\\]+\\AppData\\Roaming\\Microsoft\\Templates\\~\$Normal\.dotm", r"^[A-Z]?:\\Users\\[^\\]+\\AppData\\Roaming\\Microsoft\\Windows\\IETldCache\\$", r"^[A-Z]?:\\Users\\[^\\]+\\AppData\\Roaming\\Microsoft\\Windows\\IETldCache\\index\.dat$", r"^[A-Z]?:\\Users\\[^\\]+\\AppData\\Roaming\\Microsoft\\Windows\\IECompatUACache\\Low$", From c9c04585f5f96407f87ad9d4f9017dd3e3fb9574 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 31 May 2023 13:58:06 +0200 Subject: [PATCH 137/145] procmem_yara signature lowered severity as nothing goes past 3 --- modules/signatures/procmem_yara.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/signatures/procmem_yara.py b/modules/signatures/procmem_yara.py index 62f1e57c..11b776b9 100644 --- a/modules/signatures/procmem_yara.py +++ b/modules/signatures/procmem_yara.py @@ -19,7 +19,7 @@ class Procmem_Yara(Signature): name = "procmem_yara" description = "Yara rule detections observed from a process memory dump/dropped files/CAPE" - severity = 4 + severity = 3 categories = ["malware"] authors = ["KillerInstinct"] minimum = "0.5" @@ -57,10 +57,10 @@ def run(self): if hits: for pid, rule in hits: - if rule.lower() in suspicious and self.severity == 4: + if rule.lower() in suspicious and self.severity == 3: + self.severity = 4 + elif rule.lower() in malicious and self.severity <= 4: self.severity = 5 - elif rule.lower() in malicious and self.severity <= 5: - self.severity = 6 self.data.append({"Hit": "PID %s trigged the Yara rule '%s'" % (pid, rule)}) return True From 68b09d58624397e03ca64bb070f314b83ac7320c Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Wed, 31 May 2023 14:02:30 +0200 Subject: [PATCH 138/145] antivm network added adobe --- modules/signatures/antivm_network_adapter.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/signatures/antivm_network_adapter.py b/modules/signatures/antivm_network_adapter.py index 5b5396f4..c5ced70f 100644 --- a/modules/signatures/antivm_network_adapter.py +++ b/modules/signatures/antivm_network_adapter.py @@ -41,6 +41,9 @@ def __init__(self, *args, **kwargs): "winword.exe", "excel.exe", "powerpnt.exe", + "acrord32.exe", + "acrord64.exe", + "acrobat.exe", ] def on_call(self, _, process): From 3467d2400ce431abb3705b7fe4a86a1776c3bdaf Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Thu, 1 Jun 2023 10:09:23 +0200 Subject: [PATCH 139/145] browser_proxy FP tuning added whitelisted processes --- modules/signatures/browser_proxy.py | 55 ++++++++++++++----------- modules/signatures/process_discovery.py | 2 + modules/signatures/suspicious_html.py | 4 +- 3 files changed, 33 insertions(+), 28 deletions(-) diff --git a/modules/signatures/browser_proxy.py b/modules/signatures/browser_proxy.py index 6820cbee..10c0acfc 100644 --- a/modules/signatures/browser_proxy.py +++ b/modules/signatures/browser_proxy.py @@ -34,41 +34,46 @@ class ModifyProxy(Signature): filter_analysistypes = set(["file"]) - def run(self): - ignore = False - # will need to turn this into an evented signature later, as IE will read the existing value of some of these entries - # and write them back as the same value - reg_indicators = [ + def __init__(self, *args, **kwargs): + Signature.__init__(self, *args, **kwargs) + self.proc_safelist = [ + "acrobat.exe", + "winword.exe", + "excel.exe", + "powerpnt.exe", + "outlook.exe", + "acrord32.exe", + "acrord64.exe", + "wordview.exe", + "adobearm.exe", + "ai.exe", + ] + self.indicators = [ ".*\\\\SOFTWARE\\\\(Wow6432Node\\\\)?Microsoft\\\\Windows\\\\CurrentVersion\\\\Internet\\ Settings\\\\ProxyEnable$", ".*\\\\SOFTWARE\\\\(Wow6432Node\\\\)?Microsoft\\\\Windows\\\\CurrentVersion\\\\Internet\\ Settings\\\\ProxyServer$", ".*\\\\SOFTWARE\\\\(Wow6432Node\\\\)?Microsoft\\\\Windows\\\\CurrentVersion\\\\Internet\\ Settings\\\\ZoneMap\\\\ProxyBypass$", ".*\\\\SOFTWARE\\\\(Wow6432Node\\\\)?Microsoft\\\\Windows\\\\CurrentVersion\\\\Internet\\ Settings\\\\ProxyOverride$", ".*\\\\SOFTWARE\\\\(Wow6432Node\\\\)?Microsoft\\\\Windows\\\\CurrentVersion\\\\Internet\\ Settings\\\\Wpad\\\\.*", ] - whitelist = [ + self.whitelist = [ ".*\\\\SOFTWARE\\\\(Wow6432Node\\\\)?Microsoft\\\\Windows\\\\CurrentVersion\\\\Internet\\ Settings\\\\Wpad\\\\WpadLastNetwork$", ".*\\\\SOFTWARE\\\\(Wow6432Node\\\\)?Microsoft\\\\Windows\\\\CurrentVersion\\\\Internet\\ Settings\\\\Wpad\\\\[^\\\\]*\\\\WpadDecisionReason$", ".*\\\\SOFTWARE\\\\(Wow6432Node\\\\)?Microsoft\\\\Windows\\\\CurrentVersion\\\\Internet\\ Settings\\\\Wpad\\\\[^\\\\]*\\\\WpadDecisionTime$", ".*\\\\SOFTWARE\\\\(Wow6432Node\\\\)?Microsoft\\\\Windows\\\\CurrentVersion\\\\Internet\\ Settings\\\\Wpad\\\\[^\\\\]*\\\\WpadDecision$", ".*\\\\SOFTWARE\\\\(Wow6432Node\\\\)?Microsoft\\\\Windows\\\\CurrentVersion\\\\Internet\\ Settings\\\\Wpad\\\\[^\\\\]*\\\\WpadNetworkName$", ] - # Get rid of a PDF false positive - if "file" in self.results.get("target", {}): - if "PDF" in self.results["target"]["file"].get("type", "") or self.results["info"]["package"] == "pdf": - ignore = True - - if ignore: + def on_call(self, call, process): + if process["process_name"].lower() in self.proc_safelist: return False - - for indicator in reg_indicators: - matches = self.check_write_key(pattern=indicator, regex=True, all=True) - if matches: - for match in matches: - foundwhite = False - for white in whitelist: - if re.match(white, match, re.IGNORECASE): - foundwhite = True - if not foundwhite: - return True - - return False + else: + for indicator in self.indicators: + matches = self.check_write_key(pattern=indicator, regex=True, all=True) + if matches: + for match in matches: + foundwhite = False + for white in self.whitelist: + if re.match(white, match, re.IGNORECASE): + foundwhite = True + if not foundwhite: + self.mark_call() + return True diff --git a/modules/signatures/process_discovery.py b/modules/signatures/process_discovery.py index 5ab18b9c..0bcc6e67 100644 --- a/modules/signatures/process_discovery.py +++ b/modules/signatures/process_discovery.py @@ -41,6 +41,8 @@ def __init__(self, *args, **kwargs): "acrord32.exe", "acrord64.exe", "wordview.exe", + "adobearm.exe", + "ai.exe", ] def on_call(self, call, process): diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index ebc05382..9562bf16 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -34,9 +34,6 @@ class htmlBody(Signature): minimum = "1.2" ttps = ["T1566.001"] # MITRE v6,7,8 mbcs = ["C0029.003"] # micro-behaviour - - - def run(self): packages = ['html', 'edge', 'chrome', 'firefox'] @@ -85,6 +82,7 @@ def run(self): 'Please wait', 'Sign in', '', # Empty title + 'Redirecting', ] title_regex = re.compile(r'<\s*title[^>]*>(.*?)<\/\s*title\s*>') From 9bc2b95b41356172864a61deba6a870cb5753b89 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Thu, 1 Jun 2023 10:13:00 +0200 Subject: [PATCH 140/145] browser_proxy FP tuning added whitelisted processes --- modules/signatures/process_discovery.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/modules/signatures/process_discovery.py b/modules/signatures/process_discovery.py index 0bcc6e67..43a4a4e0 100644 --- a/modules/signatures/process_discovery.py +++ b/modules/signatures/process_discovery.py @@ -50,12 +50,13 @@ def on_call(self, call, process): procpid = self.get_argument(call, "ProcessId") if procname in self.safelist: return False - if procpid and procname: - if procpid not in self.enumeratedpids and procpid != "0": - self.enumeratedpids.append(procpid) - self.data.append({"process": "%s with pid %s" % (procname, procpid)}) - if self.pid: - self.mark_call() + else: + if procpid and procname: + if procpid not in self.enumeratedpids and procpid != "0": + self.enumeratedpids.append(procpid) + self.data.append({"process": "%s with pid %s" % (procname, procpid)}) + if self.pid: + self.mark_call() def on_complete(self): if len(self.enumeratedpids) > 5: From 95939bf38df5c13442c912efe1a364308f44d0f3 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Thu, 1 Jun 2023 10:43:16 +0200 Subject: [PATCH 141/145] browser_proxy FP tuning added whitelisted processes --- modules/signatures/process_discovery.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/signatures/process_discovery.py b/modules/signatures/process_discovery.py index 43a4a4e0..7fc7ba02 100644 --- a/modules/signatures/process_discovery.py +++ b/modules/signatures/process_discovery.py @@ -48,7 +48,7 @@ def __init__(self, *args, **kwargs): def on_call(self, call, process): procname = self.get_argument(call, "ProcessName") procpid = self.get_argument(call, "ProcessId") - if procname in self.safelist: + if process["process_name"].lower() in self.safelist: return False else: if procpid and procname: From 1d1d32456574ad346d34c3ed3d91ceaaeebe1fca Mon Sep 17 00:00:00 2001 From: RoemIko Date: Mon, 5 Jun 2023 09:38:47 +0200 Subject: [PATCH 142/145] changed code naming for standardization in suspicioushtml --- modules/signatures/suspicious_html.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index 9562bf16..549022a1 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -17,7 +17,7 @@ import re -class htmlBody(Signature): +class suspiciousHRML_Body(Signature): name = "suspicious_html_body" description = "Sample contains suspicious HTML body" severity = 1 @@ -58,7 +58,7 @@ def run(self): return self.has_matches() -class htmlTitle(Signature): +class suspiciousHTML_Title(Signature): name = "suspicious_html_title" description = "Sample contains suspicious HTML title" severity = 1 @@ -102,7 +102,7 @@ def run(self): return self.has_matches() -class suspiciousHTMLname(Signature): +class suspiciousHTML_Filename(Signature): name = "suspicious_html_name" description = "Sample contains suspicious HTML name" severity = 1 From d4e7227a4e2532688bc0a0cc9b0a7999554a17d0 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Fri, 16 Jun 2023 19:05:57 +0200 Subject: [PATCH 143/145] added another phishing kit extractor --- modules/signatures/browser_proxy.py | 1 + .../credential_access_phishingkit.py | 48 +++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/modules/signatures/browser_proxy.py b/modules/signatures/browser_proxy.py index 10c0acfc..5e0c17a1 100644 --- a/modules/signatures/browser_proxy.py +++ b/modules/signatures/browser_proxy.py @@ -62,6 +62,7 @@ def __init__(self, *args, **kwargs): ".*\\\\SOFTWARE\\\\(Wow6432Node\\\\)?Microsoft\\\\Windows\\\\CurrentVersion\\\\Internet\\ Settings\\\\Wpad\\\\[^\\\\]*\\\\WpadDecision$", ".*\\\\SOFTWARE\\\\(Wow6432Node\\\\)?Microsoft\\\\Windows\\\\CurrentVersion\\\\Internet\\ Settings\\\\Wpad\\\\[^\\\\]*\\\\WpadNetworkName$", ] + def on_call(self, call, process): if process["process_name"].lower() in self.proc_safelist: return False diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index 9928320f..a1ac2065 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -102,6 +102,54 @@ def run(self): r"unescape\(\'([^&]+?)\'\) \);", r"unescape\( \'([^&]+?)\'\) \);", ] + for regex in regex_decoded: + decodeString = re.search(regex,data) + if decodeString: + decodeString = decodeString.group(1) + decoded_string = Chepy(decodeString).url_decode().url_decode().o + self.description = "File obfuscation detected, with url encoding" + regex_user = r'value="([^&]+?)"' + regex_url = r"url: '([^&]+?)'," + user = re.search(regex_user,decoded_string) + url = re.search(regex_url,decoded_string) + if user and url: + self.weight = 3 + self.families = ["HTMLPhisher_2023"] + self.description = "Phishing kit detected, extracted config from sample" + self.data.append({"url": url.group(1)}) + self.data.append({"user": user.group(1)}) + return True + return False + +class HTMLPhisher_2(Signature): + name = "phishing_kit_detected" + description = "Phishing Kit Detected, sample is trying to harvest credentials" + severity = 3 + confidence = 100 + categories = ["credential_access","evasion","infostealer","phishing", "static"] + authors = ["Yasin Tas", "Eye Security"] + references = [ + "https://securelist.com/phishing-kit-market-whats-inside-off-the-shelf-phishing-packages/106149/", + "https://socradar.io/what-is-a-phishing-kit/" + "https://github.com/SteveD3/kit_hunter/tree/master/tag_files" + ] + enabled = True + minimum = "1.2" + ttps = ["T1111", "T1193", "T1140"] # MITRE v6 + ttps += ["T1566.001"] # MITRE v6,7,8 + ttps += ["T1606"] # MITRE v7,8 + mbcs = ["C0029.003"] # micro-behaviour + + def run(self): + if self.results["info"]["package"] == "edge" or self.results["info"]["package"] == "html": + if "strings" not in self.results["target"]["file"] or self.results["target"]["file"]["strings"] == []: + return False + strings = self.results["target"]["file"]["strings"] + data = ''.join(strings) + regex_decoded = [ + r"", + r"", + ] for regex in regex_decoded: decodeString = re.search(regex,data) if decodeString: From 12717f55663a805dfbabd467a72faead364fd770 Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Fri, 16 Jun 2023 19:35:52 +0200 Subject: [PATCH 144/145] Logic typo in html phish --- .../credential_access_phishingkit.py | 33 +++++++------------ 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/modules/signatures/credential_access_phishingkit.py b/modules/signatures/credential_access_phishingkit.py index a1ac2065..43097bc5 100644 --- a/modules/signatures/credential_access_phishingkit.py +++ b/modules/signatures/credential_access_phishingkit.py @@ -146,25 +146,16 @@ def run(self): return False strings = self.results["target"]["file"]["strings"] data = ''.join(strings) - regex_decoded = [ - r"", - r"", - ] - for regex in regex_decoded: - decodeString = re.search(regex,data) - if decodeString: - decodeString = decodeString.group(1) - decoded_string = Chepy(decodeString).url_decode().url_decode().o - self.description = "File obfuscation detected, with url encoding" - regex_user = r'value="([^&]+?)"' - regex_url = r"url: '([^&]+?)'," - user = re.search(regex_user,decoded_string) - url = re.search(regex_url,decoded_string) - if user and url: - self.weight = 3 - self.families = ["HTMLPhisher_2023"] - self.description = "Phishing kit detected, extracted config from sample" - self.data.append({"url": url.group(1)}) - self.data.append({"user": user.group(1)}) - return True + + regex_user = r"" + regex_url = r"" + user = re.search(regex_user,data) + url = re.search(regex_url,data) + if user and url: + self.weight = 3 + self.families = ["HTMLPhisher_2023"] + self.description = "Phishing kit detected, extracted config from sample" + self.data.append({"url": url.group(1)}) + self.data.append({"user": user.group(1)}) + return True return False \ No newline at end of file From 9b95a87e174429ae023c46e30f8a818146c5a6fb Mon Sep 17 00:00:00 2001 From: Yasin Tas Date: Fri, 16 Jun 2023 20:19:36 +0200 Subject: [PATCH 145/145] added Remmitance as sus --- modules/signatures/suspicious_html.py | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/signatures/suspicious_html.py b/modules/signatures/suspicious_html.py index 549022a1..18e91656 100644 --- a/modules/signatures/suspicious_html.py +++ b/modules/signatures/suspicious_html.py @@ -124,6 +124,7 @@ def run(self): indicators = [ 'payment', 'remittence', + 'remmitance ' 'invoice', 'inv', 'voicemail',