From aa69c5882306c213835280c01d803a6242a12c60 Mon Sep 17 00:00:00 2001 From: kevross33 Date: Sat, 28 Feb 2026 01:53:38 +0000 Subject: [PATCH 1/2] Create sig for likely ransomware asynchronous encryption --- .../ransomware_asynchronous_encryption.py | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 modules/signatures/windows/ransomware_asynchronous_encryption.py diff --git a/modules/signatures/windows/ransomware_asynchronous_encryption.py b/modules/signatures/windows/ransomware_asynchronous_encryption.py new file mode 100644 index 00000000..59e0c57b --- /dev/null +++ b/modules/signatures/windows/ransomware_asynchronous_encryption.py @@ -0,0 +1,62 @@ +# Copyright (C) 2026 Kevin Ross, identification of the behavior covered in this signature and some of the signature was generated by Gemini +# +# 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 RansomwareIOCPAsynchronousEncryption(Signature): + name = "ransomware_iocp_asynchronous_encryption" + description = "Binds a large number of files to I/O Completion Ports (IOCP), possible ransomware asynchronous encryption" + severity = 4 + confidence = 80 + categories = ["ransomware"] + authors = ["Kevin Ross", "Gemini"] + minimum = "1.3" + evented = True + ttps = ["T1486"] + + filter_apinames = {"NtSetInformationFile"} + + def __init__(self, *args, **kwargs): + Signature.__init__(self, *args, **kwargs) + self.iocp_files = set() + self.example_file = None + + def on_call(self, call, process): + info_class = self.get_argument(call, "FileInformationClass") + + if info_class == 30 or str(info_class) == "30" or str(info_class).upper() == "FILECOMPLETIONINFORMATION": + filepath = self.get_argument(call, "HandleName") + + if isinstance(filepath, str) and "\\" in filepath: + filepath_lower = filepath.lower() + + # Ignore system devices/pipes + if "\\??\\" in filepath_lower or "\\device\\" in filepath_lower: + return + + if filepath_lower not in self.iocp_files: + self.iocp_files.add(filepath_lower) + if len(self.iocp_files) <= 15: + self.mark_call() + + def on_complete(self): + ret = False + if len(self.iocp_files) > 50: + self.data.append({ + "total_files_bound_to_iocp": len(self.iocp_files), + }) + ret = True + + return ret From c732b05a3b05cdd0fa1553f170cfc122335af924 Mon Sep 17 00:00:00 2001 From: kevross33 Date: Sat, 7 Mar 2026 22:43:36 +0000 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- .../windows/ransomware_asynchronous_encryption.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/signatures/windows/ransomware_asynchronous_encryption.py b/modules/signatures/windows/ransomware_asynchronous_encryption.py index 59e0c57b..ec46857d 100644 --- a/modules/signatures/windows/ransomware_asynchronous_encryption.py +++ b/modules/signatures/windows/ransomware_asynchronous_encryption.py @@ -52,11 +52,9 @@ def on_call(self, call, process): self.mark_call() def on_complete(self): - ret = False if len(self.iocp_files) > 50: self.data.append({ "total_files_bound_to_iocp": len(self.iocp_files), }) - ret = True - - return ret + return True + return False