Killing a userland process from kernel mode

Hi. First, i want to do a quick introduction about me to avoid conflicts. I work on the security area, more specifically as exploit writer and as reverse engineer. So, im not trying to implement none of this things in a comercial driver.

Well, with that said, i wanna ask you driver’s gurus, how can i suspend the execution of a process from kernel mode? This is my scenary. Im executing code in kernel mode, and i have almost the whole SSDT hooked and a userland process talking with a driver who constantly keep checking the hooks.

Im facing a few approaches to do this… i started disassembling NtTerminateProcess, NtSuspendProcess, etc… to see what they do, and to try to implement it by myself and i’ve saw that Ps/KeSuspendThread seems to be a nice option cause i can get the ETHREAD of the process that i want.

So, has somebody something to say about this to help me in this approach?

And, if anybody knows, or can think another way (not too big, im doing all this with an asm bytechar) to stop the process execution (i dont mind if it crashes)'ll be very valuable to me.

PS:Just remember that i cant use most of the native Apis, so i have to do it by hand (i could parse ntoskrnl.exe directly from disk, but thats not a good idea in this sittuation)

Thank you in advance

.aLS

This list is for Windows drivers; you’re writing shellcode. That aside, I don’t really even understand what you are asking. Are you saying that you are wondering how to kill a process from the kernel without using any of the kernel API, and that it’s ok if the method trashes the machine, but it has to be small, and ideally, shellcode? How about your very own KeBugCheckEx(), or just incur a page fault at IRQL == 2?

Exactly what are you researching?

mm

mm

“This list is for Windows drivers; you’re writing shellcode.”

So? im at ring 0, and im asking questions about ring 0, i think that maybe somebody here can have an idea about how to do this. If you can answer the question, great!, i will be thankful. If not, its ok, but try to be usefull or avoid posting.

“That aside, I don’t really even understand what you are asking.”
Ok, i’ll explain you again later.

"Are you saying that you are wondering how to kill a process from the kernel without using any of the kernel API, and that it’s ok if the method trashes the machine, but it has to be small, and ideally, shellcode?

I didnt said that, please, re-read my original post. I said:
“And, if anybody knows, or can think another way (not too big, im doing all this with an asm bytechar) to stop the process execution (i dont mind if it crashes)'ll be very valuable to me.”

That means: 1 - I dont mind if the *process* crashes, 2 - The note between parenthesis was just informative. I dont want a shellcode, i just wanna know if somebody knows a way to do this with DKOM and 3 - With “not too big” i did mean that i already thought things like switching to the process context to inject a thread or to patch something into the process memory space.

Also, english isnt my first language so maybe some thing could generate misunderstandings. Sorry about it.

.aLS

That depends on when(in which place) are you going to stop the process: perhaps at creation time, mapping time, running,…?

-----Mensaje original-----
De: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] En nombre de xxxxx@gmail.com
Enviado el: jueves, 20 de septiembre de 2007 14:51
Para: Windows System Software Devs Interest List
Asunto: [ntdev] Killing a userland process from kernel mode

Hi. First, i want to do a quick introduction about me to avoid conflicts. I work on the security area, more specifically as exploit writer and as reverse engineer. So, im not trying to implement none of this things in a comercial driver.

Well, with that said, i wanna ask you driver’s gurus, how can i suspend the execution of a process from kernel mode? This is my scenary. Im executing code in kernel mode, and i have almost the whole SSDT hooked and a userland process talking with a driver who constantly keep checking the hooks.

Im facing a few approaches to do this… i started disassembling NtTerminateProcess, NtSuspendProcess, etc… to see what they do, and to try to implement it by myself and i’ve saw that Ps/KeSuspendThread seems to be a nice option cause i can get the ETHREAD of the process that i want.

So, has somebody something to say about this to help me in this approach?

And, if anybody knows, or can think another way (not too big, im doing all this with an asm bytechar) to stop the process execution (i dont mind if it crashes)'ll be very valuable to me.

PS:Just remember that i cant use most of the native Apis, so i have to do it by hand (i could parse ntoskrnl.exe directly from disk, but thats not a good idea in this sittuation)

Thank you in advance

.aLS


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

“That depends on when(in which place) are you going to stop the process: perhaps at creation time, mapping time, running,…?”

That´s true, it is running.

.aLS

For testing purposes, a classic way to do this, as used by many ‘malware’ out there, is to inject an ExitProcess call on the thread resume address.

I assume you are aware of the propper way to write to an arbitrary user process from kernel without crassing, and about the implications of closing unexpectedly any process.

I would not do that in a commercial software but it may be used for testing concepts.

-----Mensaje original-----
De: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] En nombre de xxxxx@gmail.com
Enviado el: jueves, 20 de septiembre de 2007 18:39
Para: Windows System Software Devs Interest List
Asunto: RE:[ntdev] Killing a userland process from kernel mode

“That depends on when(in which place) are you going to stop the process: perhaps at creation time, mapping time, running,…?”

That?s true, it is running.

.aLS


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Ok, first at all, thank you for your reply.

Yes it would work, i ve done that before. But as i said in my second post:

"3 - With “not too big” i did mean that i already thought things like switching to the process context to inject a thread or to patch something into the process memory space. "

But, i ve discarded it due to two problems: It snt very small. and the most important one: I dont know how to do that with DKOM… remember that in this scenary i cant use the native APIs.

I would like to add that i know this is a uncommon situation. As i said in my first post im not trying to do a commercial driver at all, im just appealing to your kernel mode knowledge to find any thoughts to work on.

Thank you all again, and please, keep throwing ideas.

.aLS

As long as you do it for the research purposes, you can try the following:

  1. Get the address of ZwTerminateProcess(). Once ntdll.dll is mapped into the address space of any process (apparently, apart from the Idle and “System” processes, but even if you do it in context of a system thread, you can always attach yourself to any other process with KeStackAttachProcess), you can always arrive to the address of the sought export by parsing PE headers.

  2. Get the service index that corresponds to ZwTerminateProcess(). All stubs from ntdll.dll start with the line MOV EAX, ServiceIndex, which applies to any version and flavour of Windows NT. This is a 5-byte instruction, with MOV EAX opcode as the first byte and the service index as remaining 4 bytes. Therefore, in order to get the service index that corresponds to some particular native API function, all you have to do is to read 4 bytes from the address, located 1 byte away from the beginning of the stub. Once you have discovered the service index, you can arrive to the address
    of ZwTerminateProcess()'s actual implementation via SSDT.

  3. Get target process’s EPROCESS with PsLookupProcessByProcessId(), and then pass it to
    ObOpenObjectByPointer() in order to get a handle -as long as you don’t specify OBJ_KERNEL_HANDLE, a handle will be user-mode one, and refer to some entry in the handle table of a caller process (even if you attach a system thread to some process with user-mode representation, all handles that it opens will, apparently, refer to the host process, rather than to the system one).

  4. Call ZwTerminateProcess() by its address. Once your call does not go via the system service dispatcher, ‘PreviousMode’ in caller’s ETHREAD will not get updated (if you don’t mind dealing directly with ETHREAD, you can even explicitly set it to the UserMode before calling ZwTerminateProcess()).

To summarize, from ZwTerminateProcess()'s perspective everything will look as if process X made a user-mode code call to TerminateProcess() in order to terminate process Y, and passed a user-mode handle on this call.

Try it this way - although there could be some not-so-obvious at this moment issues here, I just do not immediately see any reason why it should not work…

Anton Bassov

Wow man, thats a post! :smiley: Really, thank you for the time to answer.

xxxxx@hotmail.com wrote:

As long as you do it for the research purposes, you can try the following:

  1. Get the address of ZwTerminateProcess(). Once ntdll.dll is mapped into the address space of any process (apparently, apart from the Idle and “System” processes, but even if you do it in context of a system thread, you can always attach yourself to any other process with KeStackAttachProcess), you can always arrive to the address of the sought export by parsing PE headers.

  2. Get the service index that corresponds to ZwTerminateProcess(). All stubs from ntdll.dll start with the line MOV EAX, ServiceIndex, which applies to any version and flavour of Windows NT. This is a 5-byte instruction, with MOV EAX opcode as the first byte and the service index as remaining 4 bytes. Therefore, in order to get the service index that corresponds to some particular native API function, all you have to do is to read 4 bytes from the address, located 1 byte away from the beginning of the stub. Once you have discovered the service index, you can arrive to the address
    of ZwTerminateProcess()'s actual implementation via SSDT.

  3. Get target process’s EPROCESS with PsLookupProcessByProcessId(), and then pass it to
    ObOpenObjectByPointer() in order to get a handle -as long as you don’t specify OBJ_KERNEL_HANDLE, a handle will be user-mode one, and refer to some entry in the handle table of a caller process (even if you attach a system thread to some process with user-mode representation, all handles that it opens will, apparently, refer to the host process, rather than to the system one).

  4. Call ZwTerminateProcess() by its address. Once your call does not go via the system service dispatcher, ‘PreviousMode’ in caller’s ETHREAD will not get updated (if you don’t mind dealing directly with ETHREAD, you can even explicitly set it to the UserMode before calling ZwTerminateProcess()).

To summarize, from ZwTerminateProcess()'s perspective everything will look as if process X made a user-mode code call to TerminateProcess() in order to terminate process Y, and passed a user-mode handle on this call.

Try it this way - although there could be some not-so-obvious at this moment issues here, I just do not immediately see any reason why it should not work…

Anton Bassov

Ok, thats a good idea, but, as i said before, i have most of the native
APIs hooked right there on the SSDT, so, the address that i’ll get doing
that will actually be the one of the hook function. I’ve done things
like that previously, but i’ve faced it parsing directly ntoskrnl.exe
from disk.

Anyway, thats a good idea to have in mind, specially when the
ntoskrnl.exe file 've been modified on disk.
I will take a look to that functions to see what can i get.

Thank you again.

.aLS

> as i said before, i have most of the native

APIs hooked right there on the SSDT, so, the address that i’ll get doing
that will actually be the one of the hook function.

Actually, as far as they implement “conventional” SSDT hooking, you can unhook them and restore the original addresses pretty easily. I don’t want to give you precise instructions how it can get done
(in fact, I just don’t want to explain it in public - otherwise, those who hook SSDT may find a way to
make unhooking more complex task than it currently is, i.e. do some extra instruction relocation). However, I will still give you a direction - just keep in mind that INT1 may be used not only for debugging…

Anton Bassov

xxxxx@hotmail.com wrote:

> as i said before, i have most of the native
> APIs hooked right there on the SSDT, so, the address that i’ll get doing
> that will actually be the one of the hook function.
>

Actually, as far as they implement “conventional” SSDT hooking, you can unhook them and restore the original addresses pretty easily. I don’t want to give you precise instructions how it can get done
(in fact, I just don’t want to explain it in public - otherwise, those who hook SSDT may find a way to
make unhooking more complex task than it currently is, i.e. do some extra instruction relocation). However, I will still give you a direction - just keep in mind that INT1 may be used not only for debugging…

Anton Bassov

:smiley: yeah well, i dont think that restoring the sdt could be a problematic
topic, after all, ive talked about a way to do that before and there is
a lot of public information available (mostly on anti-rootkits
techniques). The problem here is that there is an user mode process
talking with a driver who check the hooks all the time, that’s actually
why i want to suspend its execution

.aLS

> The problem here is that there is an user mode process

talking with a driver who check the hooks all the time, that’s actually
why i want to suspend its execution

Again, INT 1 is your friend here - you can set a breakpoint on memory access via debug registers, and, hence, fool the checking thread - it will believe that its hook is still there. Unfortunately, we have only 4 debug registers, but, luckily for you, you have to fool this thread only in respect of ZwTerminateProcess(), so that only one register is needed. Another way of doing the same thing lies with hooking page fault handler (INT 14). In other words, things are not as complex as you present them…

Anton Bassov