diff --git a/modules/signatures/windows/injection_thread.py b/modules/signatures/windows/injection_thread.py index 0800022c..8a4cf69e 100644 --- a/modules/signatures/windows/injection_thread.py +++ b/modules/signatures/windows/injection_thread.py @@ -54,3 +54,44 @@ def on_call(self, call, process): def on_complete(self): return self.ret + + +class ApcInjection(Signature): + name = "apc_injection" + description = "Queues an Asynchronous Procedure Call (APC) to a thread, indicative of injection" + severity = 3 + confidence = 80 + categories = ["injection", "evasion"] + authors = ["Kevin Ross"] + minimum = "1.3" + evented = True + ttps = ["T1055", "T1055.004"] + mbcs = ["E1055", "E1055.004"] + + filter_apinames = {"NtQueueApcThread", "QueueUserAPC"} + + def __init__(self, *args, **kwargs): + Signature.__init__(self, *args, **kwargs) + self.ret = False + self.apc_targets = set() + + def on_call(self, call, process): + if call["api"] == "NtQueueApcThread": + target_thread = self.get_argument(call, "ThreadId") + apc_routine = self.get_argument(call, "ApcRoutine") + else: + target_thread = self.get_argument(call, "ThreadHandle") + apc_routine = self.get_argument(call, "pfnAPC") + + if target_thread and apc_routine: + pid = process.get("process_id") + targetpid = self.get_argument(call, "ProcessId") + + if str(apc_routine) != "0x00000000" and str(pid) != str(targetpid): + if target_thread not in self.apc_targets: + self.apc_targets.add(target_thread) + self.mark_call() + self.ret = True + + def on_complete(self): + return self.ret