Malware Analysis Code injection identification [Malware Analysis]

D

Deleted member 65228

Guest
#62
NtProtectVirtualMemory information from my reverse-engineering notes on NTOSKRNL.

1. NtProtectVirtualMemory (NTDLL) is called
2. System call from NTDLL is performed
3. KiSystemCallXx is invoked eventually -> eventually KiSystemServiceRepeat. The whole purpose of these routines is to locate the address of NtProtectVirtualMemory from the KeServiceDescriptorTable (and NtProtectVirtualMemory is not exported by NTOSKRNL therefore an Export Address Table Scan/MmGetSystemRoutineAddress won't work to find the address)
4. MiMakeProtectionMask
5. KiStackAttachProcess is called (non-exported variant of KeStackAttachProcess)
6. Now the Windows Kernel is executing code under the context of the target process from within the NtProtectVirtualMemory routine.
7. MmProtectVirtualMemory is called however depending on an conditional statement, another routine called VslDebugProtectSecureProcessMemory will be used instead
8. KiUnstackDetachProcess (non-exported variant of KeUnstackDetachProcess) 9. Another conditional statement -> MiMakeProtectionMask

The Process Handle (HANDLE) which is passed in will be referenced as an object (PEPROCESS). This is done via ObpReferenceObjectByHandleWithTag (non-exported). This is cleaned up with ObfDereferenceObjectWithTag at the end. The conditional statement regarding MmProtectVirtualMemory and VslDebugProtectSecureProcessMemory involves the PEPROCESS object, therefore I assume it's to do with a value found under the EPROCESS structure (which is an opaque structure therefore we cannot access it normally).

Code:
LOBYTE(PreviousModeByte) = *(_BYTE )(MK_FP(GS, 392i64) + 0x232i64);
That part of code is for checking the PreviousMode for the current thread (KPROCESSOR_MODE -> PreviousMode -> found under the ETHREAD structure which is also opaque and cannot be normally accessed). The PreviousModeByte variable gets the value from the PreviousMode field. The 0x232i64 is the offset for where the PreviousMode entry is for my environment, which would be: Base Address of the ETHREAD for the current thread + 0x232 (offset) = entry for PreviousMode destination in memory. As I've seen other places before, the PreviousMode controls whether user-mode or kernel-mode addresses can be used, because the Windows Kernel treats it as trust integrity level. Therefore, this restriction is enforced to prevent a User-Mode caller from using the Native API with a kernel-mode address. The PreviousMode is changed depending on OS version/patch update.

Here's some notes from NtSuspendProcess notes I've made awhile back.
1. Check the PreviousMode
2. Reference by object from the HANDLE (acquire PEPROCESS from the HANDLE)
3. If the PEPROCESS is successfully acquired (NTSTATUS == STATUS_SUCCESS) then call PsSuspendProcess.
4. Cleanup the PEPROCESS object.
5. Return the NTSTATUS returned by PsSuspendProcess.

PsSuspendProcess:
1. Setup the critical region
2. Check the RundownProtect entry in the EPROCESS structure
3. Enumerate the threads of the process with PsGetNextProcessThread
4. For each thread, calls PsSuspendThread
5. Release the rundown protection
6. Leave critical region
7. Return the NTSTATUS code

PsSuspendThread:
1. KeSuspendThread

KeSuspendThread:
1. KiSuspendThread
 
D

Deleted member 65228

Guest
#65
It could be possible that Comodo HIPS in paranoid mode will detect all known injection techniques? :unsure:
No, it won't. It's impossible for COMODO to block all known code injection techniques and be full-proof with it. Literally impossible. An attacker could just target a specific software package for RCE with traditional methods using unknown/new techniques if they wanted.

For example if there's an application which reads files into memory and the memory has executable rights and there's an exploitable bug in the code then you could potentially force it into executing the contents read into the buffer and thus potentially abuse it for RCE.

Not to mention that COMODO suck at managing software. Bugs everywhere and when they get complaints or requests to change they just ignore it and just some stupid excuse about how they have a sandbox, and even that is not full-proof either of course. Don't blame the engineers only though, blame the person responsible for giving them instructions just as much.

New code injection techniques are invented all the time and existent mitigations can be bypassed depending on numerous factors such as technique and privilege.
 
Joined
Feb 21, 2018
Messages
68
#66
No, it won't. It's impossible for COMODO to block all known code injection techniques and be full-proof with it. Literally impossible. An attacker could just target a specific software package for RCE with traditional methods using unknown/new techniques if they wanted.

For example if there's an application which reads files into memory and the memory has executable rights and there's an exploitable bug in the code then you could potentially force it into executing the contents read into the buffer and thus potentially abuse it for RCE.

Not to mention that COMODO suck at managing software. Bugs everywhere and when they get complaints or requests to change they just ignore it and just some stupid excuse about how they have a sandbox, and even that is not full-proof either of course. Don't blame the engineers only though, blame the person responsible for giving them instructions just as much.

New code injection techniques are invented all the time and existent mitigations can be bypassed depending on numerous factors such as technique and privilege.
MemProtect it could be a more robust solution against code injection?
 
D

Deleted member 65228

Guest
#68
MemProtect it could be a more robust solution against code injection?
Not really IMO. I'd go with COMODO over MemProtect to block code injection any day of the year, even if I am not a COMODO fan at all

MemProtect itself doesn't "prevent code injection", it prevents opening a handle to a process (and a protected process' threads) because it intercepts with a kernel-mode callback dubbed ObRegisterCallbacks. This allows it to strip access rights such as PROCESS_VM_OPERATION (required for remote virtual memory operations e.g. NtAllocateVirtualMemory, NtWriteVirtualMemory) or PROCESS_CREATE_THREAD (required for NtCreateThreadEx for example), and the same with THREAD_ access rights. Due to how it works it does prevent some malware from injecting code but not all code injection attacks which don't have to pass through its monitoring scope.

Well that is assuming unless they use PsSetCreateThreadNotifyRoutine/Ex, PsSetLoadImageNotifyRoutine/Ex as well at-least. They could use those to intercept unwanted thread creation and module loading for protected processes. There's also registry techniques to get a process to call LoadLibraryA/W and load a third-party DLL (thank Microsoft with user32.dll for that one)... There's also standard methods like DLL hijacking so when the process starts up and loads its dependencies one of them is actually a rogue copy.

I guess the DLL hijacking stuff isn't really the same as dynamic RCE because it's handled before execution so it happens on-execution but still.

Use it if you want to and I don't really know of better alternatives like it which I can recommend because it seems all alike to it just do the exact same thing. Personally I don't use it. These are just my opinion though so please don't let me put you off from using what you feel comfortable with using.
 
Last edited by a moderator:
D

Deleted member 65228

Guest
#70
@Opcode, have you read other articles written by A. Ionescu?
http://www.alex-ionescu.com/publications/
http://www.alex-ionescu.com/publications/Recon/
for example, recon2015.pdf (Hooking Nirvana) might be interesting to you.
I saw it when it was published and thank you for asking my friend :)

This is gold. Thanks for sharing the knowledge and the time spent on writing everything :)
I think a revision is in order, maybe something a lot more in depth. I didn't cover shell-code/code-cave properly nor proper manual mapping and other thread hijacking techniques. Also this is only Windows so it couldn't hurt for me to do some writing for OS X internals and code injection.

On OS X you don't have DLLs but there's "dynlibs" which can be injected.

The problem is I want it to help security researchers, not malware authors learn how to do code injection... So it's tricky for me to outline which topic in the thread covers what and to what extent, how it is worded, etc. I remember when I wrote this thread I had to do it over the course of around a week.

Thanks for your kind words as well my friend :)