community
community copied to clipboard
Create injection_writememory.py
Sigs for detecting WriteProcessMemory to a remote process.
Example from APT29 EnvyScout/ROOTSAW dropped GraphicalNeutrino (https://go.recordedfuture.com/hubfs/reports/cta-2023-0127.pdf)
Thanks - I think there is some overlap here with one of the few api sigs in the main repo:
modules/signatures/CAPE.py
class CAPE_Injection(Signature):
name = "injection_inter_process"
description = "Behavioural detection: Injection (inter-process)"
severity = 3
categories = ["injection"]
authors = ["kevoreilly"]
minimum = "1.3"
evented = True
ttps = ["T1055"] # MITRE v6,7,8
mbcs = ["OB0006", "E1055"]
def __init__(self, *args, **kwargs):
Signature.__init__(self, *args, **kwargs)
self.lastprocess = None
self.process_handles = None
self.write_handles = None
self.injection_detected = False
filter_categories = set(["process"])
def on_call(self, call, process):
if process is not self.lastprocess:
if self.process_handles:
for handle in self.process_handles:
if handle in self.write_handles:
self.injection_detected = True
self.process_handles = set()
self.write_handles = set()
self.lastprocess = process
if call["api"] in ("CreateProcessInternalW", "OpenProcess", "NtOpenProcess"):
phandle = self.get_argument(call, "ProcessHandle")
self.process_handles.add(phandle)
elif call["api"] in ("NtWriteVirtualMemory", "NtWow64WriteVirtualMemory64", "WriteProcessMemory", "NtMapViewOfSection"):
whandle = self.get_argument(call, "ProcessHandle")
self.write_handles.add(whandle)
def on_complete(self):
if self.injection_detected:
return True
elif self.process_handles:
for handle in self.process_handles:
if handle in self.write_handles:
return True
I haven't checked to look whether the above is detected by this signature and if not why not.
It doesn't (21a0b617431850a9ea2698515c277cbd95de4e59c493d0d8f194f3808eb16354 Instructions.iso). While most injection techniques are covered I sometimes am finding they don't fire on these behaviours potentially because of how it is being done instead of the typical chain. That is why I have done this (and others in testing) breaking down anomalies like these. For example in this case writing to the memory of the other process and then others resuming the thread in the other process.
so maybe we want to merge them as they are related but not the same? thoughts?
Yes of course we should merge what we haven't got and clean up what we have to maximise coverage.
Historically there was an additional use for the signatures in 'CAPE.py' as they were used as triggers for package selection... back a long time ago. Now we don't need a special set of signatures to trigger packages so I think the best way is probably to remove CAPE.py completely and ensure that Kevin's sigs here cover everything we need. If not we can add to them as needs be.
Let me test these and the CAPE.py sigs against Kevin's samples as well as my own 'injection' test set and I will try to consolidate them all. I don't mind doing that after this is merged.
Thanks
El jue, 7 mar 2024, 10:58, kevoreilly @.***> escribió:
Yes of course we should merge what we haven't got and clean up what we have to maximise coverage.
Historically there was an additional use for the signatures in 'CAPE.py' as they were used as triggers for package selection... back a long time ago. Now we don't need a special set of signatures to trigger packages so I think the best way is probably to remove CAPE.py completely and ensure that Kevin's sigs here cover everything we need. If not we can add to them as needs be.
Let me test these and the CAPE.py sigs against Kevin's samples as well as my own 'injection' test set and I will try to consolidate them all. I don't mind doing that after this is merged.
— Reply to this email directly, view it on GitHub https://github.com/CAPESandbox/community/pull/401#issuecomment-1983146483, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAOFH36TCPG6RSU6KL7IXYDYXA22RAVCNFSM6AAAAABD4N3FQGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSOBTGE2DMNBYGM . You are receiving this because you commented.Message ID: @.***>
@kevross33 any reason why these signatures do not include the api NtWriteVirtualMemory? Incidentally this function and the two you have included are the three for which injected data is captured by the monitor.
Will just be an omission on my part and can be added. In terms of the wider conversation the CAPE sigs for injection still very useful for identifying source/target injection when they fire and often with higher confidence.
The sigs I have created/creating (most still being worked on as not had time but will submit soon) more about identifying components/anomalies around injections that are useful for identifying injection/malicious unpacking occurring by sub-components. I.e. messing with another process' permissions, writing into it and starting a thread. Really they are just a safety net.
On Mon, 11 Mar 2024 at 17:18, kevoreilly @.***> wrote:
@kevross33 https://github.com/kevross33 any reason why these signatures do not include the api NtWriteVirtualMemory? Incidentally this function and the two you have included are the three for which injected data is captured by the monitor.
— Reply to this email directly, view it on GitHub https://github.com/CAPESandbox/community/pull/401#issuecomment-1989005238, or unsubscribe https://github.com/notifications/unsubscribe-auth/AASNPNNOY4Z2U5K42YZR63DYXXRNBAVCNFSM6AAAAABD4N3FQGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSOBZGAYDKMRTHA . You are receiving this because you were mentioned.Message ID: @.***>
I will add this api and make sure the net is sound 👌
There is a slight complication here in that the API calls shown in your initial screenshot are Windows internal calls from within the CreateProcess API. This function is normally hooked but in the case of rundll32 this API happens to be redirected by 'Application Compatibility' or the Microsoft Shim Engine.
2024-04-10 15:04:40,409 [root] DEBUG: 5192: Monitor initialised: 32-bit capemon loaded in process 5192 at 0x726f0000, thread 4868, image base 0x650000, stack from 0x634000-0x640000
2024-04-10 15:04:40,409 [root] DEBUG: 5192: Commandline: "C:\Windows\system32\rundll32.exe" "C:\21a0b617431850a9ea269851\BUGSPLAT.DLL",#1
2024-04-10 15:04:40,424 [root] DEBUG: 5192: hook_api: Warning - CoCreateInstance export address 0x773156BD differs from GetProcAddress -> 0x76B988E0 (combase.dll::0xe88e0)
2024-04-10 15:04:40,424 [root] DEBUG: 5192: hook_api: Warning - CoCreateInstanceEx export address 0x773156FC differs from GetProcAddress -> 0x76BD3020 (combase.dll::0x123020)
2024-04-10 15:04:40,424 [root] DEBUG: 5192: hook_api: Warning - CoGetClassObject export address 0x77315C8C differs from GetProcAddress -> 0x76BCD870 (combase.dll::0x11d870)
2024-04-10 15:04:40,424 [root] DEBUG: 5192: hook_api: Warning - UpdateProcThreadAttribute export address 0x75D1FD46 differs from GetProcAddress -> 0x7713D580 (KERNELBASE.dll::0xfd580)
2024-04-10 15:04:40,424 [root] DEBUG: 5192: hook_api: Warning - CreateProcessA export address 0x75CB2D90 differs from GetProcAddress -> 0x729A18A0 (AcLayers.DLL::0x218a0)
2024-04-10 15:04:40,440 [root] DEBUG: 5192: hook_api: Warning - CreateProcessW export address 0x75C988E0 differs from GetProcAddress -> 0x729A1AE0 (AcLayers.DLL::0x21ae0)
2024-04-10 15:04:40,440 [root] DEBUG: 5192: hook_api: Warning - WinExec export address 0x75CDCF20 differs from GetProcAddress -> 0x729A1DA0 (AcLayers.DLL::0x21da0)
2024-04-10 15:04:40,440 [root] DEBUG: 5192: hook_api: Warning - CLSIDFromProgID export address 0x77314EF6 differs from GetProcAddress -> 0x76B44FD0 (combase.dll::0x94fd0)
I have previously experimented with ignoring these redirections in hooks but this caused detonation issues. I am currently researching whether a certain subset of these might be ignored, such as those for APIs from kernel32 like this one. I will hopefully reach a conclusion soon.
Not that this means the signature is problematic - but it's certainly worth noting the signal used here as an example is a false positive and this is not malware injecting into anything but Windows internal mechanics.