rapid7 / metasploit-framework

Metasploit Framework
https://www.metasploit.com/
Other
34.04k stars 13.95k forks source link

Process migration #15123

Closed ghost closed 3 years ago

ghost commented 3 years ago

I would like to know why the process migration does not work in the System 4, among others, even with system privileges? is it really impossible to migrate to windows kernel pid 4?

github-actions[bot] commented 3 years ago

Hi!

This issue has been left open with no activity for a while now.

We get a lot of issues, so we currently close issues after 60 days of inactivity. It’s been at least 30 days since the last update here. If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!

As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request.

kkent030315 commented 3 years ago

Well, seems like no one could answer this, I will answer. To clarify, I am not familiar with the meterpreter.

The System Process on Windows

The system process, which has always PID 4, is not the normal process, it is a part of the NT kernel. It is created when the very first step of initialization phase of NT kernel.

As you can see the process created on PspInitPhase0: image

It actually is the ntoskrnl.exe image

Also note that the system process is to hold NT-Kernel related components such as the system-drivers (base addresses are kernel virtual address): image

Now it is too much to let you know that the system process is the special one.

Meterpreter Process Migration

Thinking of how the process migration on the meterpreter works will make sense why it does not work on the specific system-related processes.

See metasploit-framework/blob/master/lib/rex/post/meterpreter/client_core.rb#L589 which the migration function defined.

It does:

  1. OpenProcess to open process handle of target process with necessary privileges
  2. VirtualAllocEx with RWX to allocate virtual memory for the payload on the target process
  3. WriteProcessMemory to send payload on the allocated virtual memory of target process above
  4. CreateRemoteThread to invoke payload (create thread of the target process with start address of the payload)

This is the standard way of code-injection against normal windows user-processes. But as I said, system process is not the normal process, which means OpenProcess (with the necessary privileges to inject payload) will always fail as well as the another system-related processes.

(I don't dig into but do not forget PP and PPL)

Conclusion

It is impossible to migrate into the specific system-related processes. System(4) is completely impossible, processes such as csrss or lsass is actually possible but need high privileges.

github-actions[bot] commented 3 years ago

Hi!

This issue has been left open with no activity for a while now.

We get a lot of issues, so we currently close issues after 60 days of inactivity. It’s been at least 30 days since the last update here. If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!

As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request.

github-actions[bot] commented 3 years ago

Hi again!

It’s been 60 days since anything happened on this issue, so we are going to close it. Please keep in mind that I’m only a robot, so if I’ve closed this issue in error please feel free to reopen this issue or create a new one if you need anything else.

As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request.

gabriel-maxx commented 3 years ago

Well, seems like no one could answer this, I will answer. To clarify, I am not familiar with the meterpreter.

The System Process on Windows

The system process, which has always PID 4, is not the normal process, it is a part of the NT kernel. It is created when the very first step of initialization phase of NT kernel.

As you can see the process created on PspInitPhase0: image

It actually is the ntoskrnl.exe image

Also note that the system process is to hold NT-Kernel related components such as the system-drivers (base addresses are kernel virtual address): image

Now it is too much to let you know that the system process is the special one.

Meterpreter Process Migration

Thinking of how the process migration on the meterpreter works will make sense why it does not work on the specific system-related processes.

See metasploit-framework/blob/master/lib/rex/post/meterpreter/client_core.rb#L589 which the migration function defined.

It does:

  1. OpenProcess to open process handle of target process with necessary privileges
  2. VirtualAllocEx with RWX to allocate virtual memory for the payload on the target process
  3. WriteProcessMemory to send payload on the allocated virtual memory of target process above
  4. CreateRemoteThread to invoke payload (create thread of the target process with start address of the payload)

This is the standard way of code-injection against normal windows user-processes. But as I said, system process is not the normal process, which means OpenProcess (with the necessary privileges to inject payload) will always fail as well as the another system-related processes.

(I don't dig into but do not forget PP and PPL)

Conclusion

It is impossible to migrate into the specific system-related processes. System(4) is completely impossible, processes such as csrss or lsass is actually possible but need high privileges.

Hi, it's me, thanks for answering, but I still have a few questions to clear up: you're right ntoskrnl.exe is special, but that doesn't mean it's impossible, because you said the migration process is basically: OpenProcess,VirtualAllocEx,WriteProcessMemory, CreateRemoteThread, but these 4 little steps have alternatives to kernel mode,for ex: MmCopyVirtualMemory,memmove,PsCreateSystemThread, NtWriteVirtualMemory,NtReadVirtualMemory, KeAttachProces, ZwCurrentProcess, ZwOpenProcess,etc,etc

so it would need a kernel exploit and some modifications to the migration module maybe, am I right?

i tried lsass and it works the problem is csrss and ntoskrnl, access is denied

kkent030315 commented 3 years ago

Hello @NightRaidGamer

Hi, it's me, thanks for answering, but I still have a few questions to clear up: you're right ntoskrnl.exe is special, but that doesn't mean it's impossible, because you said the migration process is basically:

so it would need a kernel exploit and some modifications to the migration module maybe, am I right?

Nope, I can say this for sure that it's impossible to migrate it to the ntoskrnl.exe at all, since it's not the essentially "process". it's just a container of various resources needed to run NT Kernel & System. Handles for just example.

The ntoskrnl does not have any VAD entries. codes running on the NT will run at the CPL0 with kernel mappings. thus it is technically impossible to create ntoskrnl's "process" VAD entries and none of syscall APIs (e.g., as you said NtWriteVirt) are not designed to allow create any process VAD entries for ntoskrnl.

i tried lsass and it works the problem is csrss and ntoskrnl, access is denied

Unlike ntoskrnl, lsass & csrss is a system process which acts as the normal processes(it is the normal process). but you will need the >=NT AUTHORITY\System privilege in order to open a process handle. (it is because of the security architecture of Windows, you can find tons of great articles about the privileges!)

gabriel-maxx commented 3 years ago

Hello @NightRaidGamer

Hi, it's me, thanks for answering, but I still have a few questions to clear up: you're right ntoskrnl.exe is special, but that doesn't mean it's impossible, because you said the migration process is basically:

so it would need a kernel exploit and some modifications to the migration module maybe, am I right?

Nope, I can say this for sure that it's impossible to migrate it to the ntoskrnl.exe at all, since it's not the essentially "process". it's just a container of various resources needed to run NT Kernel & System. Handles for just example.

The ntoskrnl does not have any VAD entries. codes running on the NT will run at the CPL0 with kernel mappings. thus it is technically impossible to create ntoskrnl's "process" VAD entries and none of syscall APIs (e.g., as you said NtWriteVirt) are not designed to allow create any process VAD entries for ntoskrnl.

i tried lsass and it works the problem is csrss and ntoskrnl, access is denied

Unlike ntoskrnl, lsass & csrss is a system process which acts as the normal processes(it is the normal process). but you will need the >=NT AUTHORITY\System privilege in order to open a process handle. (it is because of the security architecture of Windows, you can find tons of great articles about the privileges!)

you are right it is not possible to migrate to a process running on CPL0 but is it possible to make a meterpreter shell run on CPL0 using some other method? what I'm trying to say is that it's not about migrating anymore, it's about making / creating

you said that csrss is a normal process that only needs NT AUTHORITY\System, but even with this privilege I can't migrate to it, what do you think is happening?

kkent030315 commented 3 years ago

you are right it is not possible to migrate to a process running on CPL0 but is it possible to make a meterpreter shell run on CPL0 using some other method? what I'm trying to say is that it's not about migrating anymore, it's about making / creating

Yes.

you said that csrss is a normal process that only needs NT AUTHORITY\System, but even with this privilege I can't migrate to it, what do you think is happening?

Did you make sure you have SeDebugPrivilege? it's needed.

gabriel-maxx commented 3 years ago

you are right it is not possible to migrate to a process running on CPL0 but is it possible to make a meterpreter shell run on CPL0 using some other method? what I'm trying to say is that it's not about migrating anymore, it's about making / creating

Yes.

you said that csrss is a normal process that only needs NT AUTHORITY\System, but even with this privilege I can't migrate to it, what do you think is happening?

Did you make sure you have SeDebugPrivilege? it's needed.

Could you explain this to me: once, when I asked here on github, I was told that a kernel exploit simply changes the Meterpreter process token so that it runs under NT AUTHORITY \ SYSTEM, effectively elevating privileges directly into the kernel area, but that doesn't make meterpreter run in kernel mode, it's still in userland, so could you clarify better, how to make meterpreter run in kernel mode? in short..

meterpreter > getprivs

Enabled Process Privileges

Name

SeChangeNotifyPrivilege SeCreateGlobalPrivilege SeCreatePagefilePrivilege SeCreateSymbolicLinkPrivilege SeDebugPrivilege SeImpersonatePrivilege SeIncreaseBasePriorityPrivilege SeBackupPrivilege SeIncreaseQuotaPrivilege SeIncreaseWorkingSetPrivilege SeLoadDriverPrivilege SeLockMemoryPrivilege SeManageVolumePrivilege SeProfileSingleProcessPrivilege SeRemoteShutdownPrivilege SeRestorePrivilege SeSecurityPrivilege SeShutdownPrivilege SeSystemEnvironmentPrivilege SeSystemProfilePrivilege SeSystemtimePrivilege SeTakeOwnershipPrivilege SeTimeZonePrivilege SeUndockPrivilege

meterpreter > migrate 592 (csrss.exe) [*] Migrating from 5952 to 592... [-] core_migrate: Operation failed: Access is denied.

tested on windows 10 19042 20H2

kkent030315 commented 3 years ago

Could you explain this to me: once, when I asked here on github, I was told that a kernel exploit simply changes the Meterpreter process token so that it runs under NT AUTHORITY \ SYSTEM, effectively elevating privileges directly into the kernel area, but that doesn't make meterpreter run in kernel mode, it's still in userland, so could you clarify better, how to make meterpreter run in kernel mode? in short..

TL;DR

So,

so that it runs under NT AUTHORITY \ SYSTEM, effectively elevating privileges directly into the kernel area

This is not correct, because it is just privilege system of Windows, not the privilege of kernel. kernel executions are defined on the hardware-level architecture, to be more detailed, the PTEs of the process has no access to kernel PTEs (PTE means page table entry).

So if you execute the instruction which tries to access certainly "valid" kernel virtual memory in usermode - you will get access violation exception (of course). This is because the PTEs of the process is not granted to access kernel PTEs. (U/S bits) This is the very basics of how is isolated between kernel and user.

Thus we cannot actually "run" kernel code in usermode unless you have an ability to execute code inside of kernel. e.g., specially crafted instruction bytecodes a.k.a. shellcode which will be executed indirectly in kernel.

However, running kernel codes inside usermode is impossible by hardware-level limitation (but you probably manipulate the whole PTEs on the computer will allow you to access KVAs through usermode PTEs by 0.0000...1 chance. not the realistic.) - but running usermode codes in kernelmode is technically possible, and is the main topic of exploiting capcom.sys. Intel has an hardware-level implementation of preventing it by SMEP.

meterpreter > migrate 592 (csrss.exe) [*] Migrating from 5952 to 592... [-] core_migrate: Operation failed: Access is denied.

tested on windows 10 19042 20H2

Ok, I thought you are at the Windows 7 or lower, my bad. After Windows 8 (I don't remember the actual version), csrss.exe has WinTcb (PPL - Protected Process Lite) protection.

image

So it's not possible unless you have an ability of kernel-level execution. You probably try lsass.exe instead.

gabriel-maxx commented 3 years ago

Ok, I thought you are at the Windows 7 or lower, my bad. After Windows 8 (I don't remember the actual version), csrss.exe has WinTcb (PPL - Protected Process Lite) protection.

image

So it's not possible unless you have an ability of kernel-level execution. You probably try lsass.exe instead.

True, I realized that I can't migrate to protected processes either and Issas.exe worked because it wasn't protected, but running at kernel level, as you said, it's possible, but I ran capcom and dell kernel exploit, and I'm still not possible to migrate, capcom and dell have a kernel-level execution capability, right?

kkent030315 commented 3 years ago

capcom and dell have a kernel-level execution capability, right?

I never digged in the DELL exploit but yes capcom exploit has an ability to execute code in kernel. however, if you are desired to do your specially crafted code run in kernel - you have to write in C or C++, or craft assembly. capcom calls usermode function pointer (or call pointer as the function) with disabling SMEP.

gabriel-maxx commented 3 years ago

capcom and dell have a kernel-level execution capability, right?

I never digged in the DELL exploit but yes capcom exploit has an ability to execute code in kernel. however, if you are desired to do your specially crafted code run in kernel - you have to write in C or C++, or craft assembly. capcom calls usermode function pointer (or call pointer as the function) with disabling SMEP.

you are right it is not possible to migrate to a process running on CPL0 but is it possible to make a meterpreter shell run on CPL0 using some other method? what I'm trying to say is that it's not about migrating anymore, it's about making / creating

Yes.

what makes me a little confused is this: you said that we can run a meterpreter shell in kernel mode, but when we use the capcom module in metasploit, it doesn't do that right? or does? why if it doesn't do what needs to be changed to make the meterpreter shell run in kernel mode?

kkent030315 commented 3 years ago

what makes me a little confused is this: you said that we can run a meterpreter shell in kernel mode, but when we use the capcom module in metasploit, it doesn't do that right? or does? why if it doesn't do what needs to be changed to make the meterpreter shell run in kernel mode?

I honestly don't know what's the "meterpreter shell" but it does.

https://github.com/rapid7/metasploit-framework/blob/e577de41d42597bc3b176a907fd19176fe987018/external/source/exploits/capcom_sys_exec/capcom_sys_exec/capcom_sys_exec.c#L34-L41

This kernel shellcode above will be executed at capcom driver as

using capcom_user_function_t = void(__stdcall*)(void* pfnMmGetSystemRoutineAddress, void* context);

:)

gabriel-maxx commented 3 years ago

what makes me a little confused is this: you said that we can run a meterpreter shell in kernel mode, but when we use the capcom module in metasploit, it doesn't do that right? or does? why if it doesn't do what needs to be changed to make the meterpreter shell run in kernel mode?

I honestly don't know what's the "meterpreter shell" but it does.

https://github.com/rapid7/metasploit-framework/blob/e577de41d42597bc3b176a907fd19176fe987018/external/source/exploits/capcom_sys_exec/capcom_sys_exec/capcom_sys_exec.c#L34-L41

This kernel shellcode above will be executed at capcom driver as

using capcom_user_function_t = void(__stdcall*)(void* pfnMmGetSystemRoutineAddress, void* context);

:)

is there a limit on the size of the shellcode capcom runs?

you said you don't know what a meterpreter shell is, as far as i know it's an advanced shellcode with several possibilities.

i did a test regarding migrating to csrss.exe removed the ppl from the process and tried to migrate, and gave me "BSOD crtitical process die", another type of micrososoft security?

kkent030315 commented 3 years ago

The "shellcode" I mean is a instruction bytecodes of x64 assembly.

i did a test regarding migrating to csrss.exe removed the ppl from the process and tried to migrate, and gave me "BSOD crtitical process die", another type of micrososoft security?

Install WinDbg or WinDbg Preview from Microsoft Store and open the crashdump then do !analyze. Unless you provide information I cannot give you the correct answer but it sounds like the migration made process crash due to something went wrong and csrss.exe died which is the critical process.


Not related

When a critical process died - it makes the bugcheck 0x000000EF. It's one of trick and not the actual bug of Windows but setting an arbitrary(or self) process as a "critical process" and killing the process makes BSOD intentionally.

gabriel-maxx commented 3 years ago

The "shellcode" I mean is a instruction bytecodes of x64 assembly.

i did a test regarding migrating to csrss.exe removed the ppl from the process and tried to migrate, and gave me "BSOD crtitical process die", another type of micrososoft security?

Install WinDbg or WinDbg Preview from Microsoft Store and open the crashdump then do !analyze. Unless you provide information I cannot give you the correct answer but it sounds like the migration made process crash due to something went wrong and csrss.exe died which is the critical process.

Not related

When a critical process died - it makes the bugcheck 0x000000EF. It's one of trick and not the actual bug of Windows but setting an arbitrary(or self) process as a "critical process" and killing the process makes BSOD intentionally.

so after removing ppl from some processes, wininit that couldn't migrate before, now it can, but processes like csrss, smss, gave me BSOD, here is csrss crashdump:

Microsoft (R) Windows Debugger Version 10.0.20348.1 AMD64 Copyright (c) Microsoft Corporation. All rights reserved.

Loading Dump File [C:\Users\Kevin\Desktop\MEMORY.DMP] Kernel Bitmap Dump File: Kernel address space is available, User address space may not be available.

Symbol search path is: srv* Executable search path is: Windows 10 Kernel Version 19041 MP (2 procs) Free x64 Product: WinNt, suite: TerminalServer SingleUserTS Edition build lab: 19041.1.amd64fre.vb_release.191206-1406 Machine Name: Kernel base = 0xfffff80721600000 PsLoadedModuleList = 0xfffff8072222a310 Debug session time: Sun Sep 12 10:02:18.508 2021 (UTC - 3:00) System Uptime: 0 days 0:13:13.863 Loading Kernel Symbols ............................................................... ....Page 1086fe not present in the dump file. Type ".hh dbgerr004" for details ............................................................ ............................................. Loading User Symbols ...................... Loading unloaded module list ......... For analysis of this file, run !analyze -v 0: kd> !analyze -v


CRITICAL_PROCESS_DIED (ef) A critical system process died Arguments: Arg1: ffff8d0327f0f140, Process object or thread object Arg2: 0000000000000000, If this is 0, a process died. If this is 1, a thread died. Arg3: 0000000000000000 Arg4: 0000000000000000

Debugging Details:

Page 1086fe not present in the dump file. Type ".hh dbgerr004" for details

KEY_VALUES_STRING: 1

Key  : Analysis.CPU.mSec
Value: 9015

Key  : Analysis.DebugAnalysisProvider.CPP
Value: Create: 8007007e on KEVIN--DEV

Key  : Analysis.DebugData
Value: CreateObject

Key  : Analysis.DebugModel
Value: CreateObject

Key  : Analysis.Elapsed.mSec
Value: 34186

Key  : Analysis.Init.CPU.mSec
Value: 2530

Key  : Analysis.Init.Elapsed.mSec
Value: 117226

Key  : Analysis.Memory.CommitPeak.Mb
Value: 78

Key  : Analysis.System
Value: CreateObject

Key  : CriticalProcessDied.ExceptionCode
Value: 2d341080

Key  : CriticalProcessDied.Process
Value: csrss.exe

Key  : WER.OS.Branch
Value: vb_release

Key  : WER.OS.Timestamp
Value: 2019-12-06T14:06:00Z

Key  : WER.OS.Version
Value: 10.0.19041.1

ADDITIONAL_XML: 1

OS_BUILD_LAYERS: 1

BUGCHECK_CODE: ef

BUGCHECK_P1: ffff8d0327f0f140

BUGCHECK_P2: 0

BUGCHECK_P3: 0

BUGCHECK_P4: 0

PROCESS_NAME: csrss.exe

CRITICAL_PROCESS: csrss.exe

EXCEPTION_RECORD: 0000000000000001 -- (.exr 0x1) Cannot read Exception record @ 0000000000000001

ERROR_CODE: (NTSTATUS) 0x2d341080 -

BLACKBOXBSD: 1 (!blackboxbsd)

BLACKBOXNTFS: 1 (!blackboxntfs)

BLACKBOXPNP: 1 (!blackboxpnp)

BLACKBOXWINLOGON: 1

STACK_TEXT:
fffff08e1c101a58 fffff80721f07302 : 00000000000000ef ffff8d0327f0f140 0000000000000000 0000000000000000 : nt!KeBugCheckEx fffff08e1c101a60 fffff80721dd7693 : 0000000000000001 fffff80721860ea5 0000000000000002 fffff80721860dcf : nt!PspCatchCriticalBreak+0x10e fffff08e1c101b00 fffff80721c4a9b0 : ffff8d0300000000 0000000000000000 ffff8d0327f0f140 ffff8d0327f0f578 : nt!PspTerminateAllThreads+0x1edc87 fffff08e1c101b70 fffff80721c4a7ac : ffff8d0327f0f140 0000000000000001 ffffffffffffffff 0000000000000000 : nt!PspTerminateProcess+0xe0 fffff08e1c101bb0 fffff80721a05eb5 : ffff8d0327f0f140 ffff8d032d341080 fffff08e1c101ca0 fffff80721d15c82 : nt!NtTerminateProcess+0x9c fffff08e1c101c20 fffff807219f83a0 : fffff80721a3007f fffff08e1c102a00 fffff08e1c102a00 ffffffffffffffff : nt!KiSystemServiceCopyEnd+0x25 fffff08e1c101db8 fffff80721a3007f : fffff08e1c102a00 fffff08e1c102a00 ffffffffffffffff ffffffffffffffff : nt!KiServiceLinkage fffff08e1c101dc0 fffff80721b1bb72 : 0000000000000001 fffff08e1c1024b0 000001f80d3303b9 0000000000000001 : nt!KiDispatchException+0x1de85f fffff08e1c102480 fffff807219f4fbb : 0000000000000000 0000000000000000 0000000000000000 0000000000000000 : nt!KiRaiseException+0x2b2 fffff08e1c102b00 fffff80721a05eb5 : ffff8d032d341080 000001f80b0227c0 fffff08e00000000 ffff8d032d341080 : nt!NtRaiseException+0x7b fffff08e1c102c40 000001f80d336030 : 0000000000000000 0000000000039000 000001f80b02fb80 000001f80d330014 : nt!KiSystemServiceCopyEnd+0x25 000000d3315fdb40 0000000000000000 : 0000000000039000 000001f80b02fb80 000001f80d330014 000001f80b02fb80 : 0x000001f8`0d336030

SYMBOL_NAME: nt!PspCatchCriticalBreak+10e

MODULE_NAME: nt

IMAGE_NAME: ntkrnlmp.exe

STACK_COMMAND: .thread ; .cxr ; kb

BUCKET_ID_FUNC_OFFSET: 10e

FAILURE_BUCKET_ID: 0xEF_csrss.exe_BUGCHECK_CRITICAL_PROCESS_2d341080_nt!PspCatchCriticalBreak

OS_VERSION: 10.0.19041.1

BUILDLAB_STR: vb_release

OSPLATFORM_TYPE: x64

OSNAME: Windows 10

FAILURE_ID_HASH: {ac91a01d-ca48-7888-fb57-0d536a1406d1}

Followup: MachineOwner

gabriel-maxx commented 3 years ago

@kkent030315 forgot to ask, if i disable or bypass the patch guard, can i interact and migrate to ntoskrnl.exe somehow? I say this because I've never touched anything related to patchguard, but i heard it's the heart and soul of windows and if you disable it, everything can be done with ntoskrnl.exe maybe?

kkent030315 commented 3 years ago

forgot to ask, if i disable or bypass the patch guard, can i interact and migrate to ntoskrnl.exe somehow?

Nope. it is impossible by architecture of operating system. it's not related to the PatchGuard.

gabriel-maxx commented 2 years ago

@kkent030315 I have one last question related to ntoskrnl.exe. it is impossible to migrate to ntoskrnl.exe using the migration module. but how about injecting a dll in ntoskrnl.exe, would it be possible? I removed the protection from the process and tried to inject a dll using the process hacker, but it gave me an error, I noticed that there are several dlls running in ntoskrnl.exe, something tells me that it is possible to inject a dll, in some other way, the what would you say?

kkent030315 commented 2 years ago

@kkent030315 I have one last question related to ntoskrnl.exe. it is impossible to migrate to ntoskrnl.exe using the migration module. but how about injecting a dll in ntoskrnl.exe, would it be possible? I removed the protection from the process and tried to inject a dll using the process hacker, but it gave me an error, I noticed that there are several dlls running in ntoskrnl.exe, something tells me that it is possible to inject a dll, in some other way, the what would you say?

At the NT kernel, the drivers are the exact same design with DLLs of a process. so we can say driver=DLL. however the kernel does not have a PEB(and so on) that usually contains DLLs loaded in the process, because PEB is a process's user-mode representation.

image

Manually injecting kernel drivers is possible(if we have a potential vulnerabilities at anywhere) and there are lots of example implementations dropped on the GitHub repos.

gabriel-maxx commented 2 years ago

@kkent030315 thanks for all your knowledge