I am writing some rootkit detection code as part of a kernel driver. I need an API that will give me a pointer to a KPROCESS structure so that I can walk thru the process list to find ALL process (including hidden ones). Of course I am pre-supposing that there is linkeage in the KTHREAD structure that doesn’t get messed up or the process would stop executing, which seems a certainty. I need something fool proof.
I have code to walk thru the EPROCESS list, but I see that it can be subverted by changing pointers, etc.
Does anyone have a suggestion?
> I need an API that will give me a pointer to a KPROCESS structure so that I can
walk thru the process list to find ALL process (including hidden ones)
Pointless exercise - the very concept of hiding a process relies upon removing it from the process list. Therefore, walking the process list is not going to lead you anywhere. What you have to walk is the list of threads.Please note that this technique is not as easy as it seems to be at the first glance - imagine what happens if a thread or process gets added to/removed from the list while you walking it. Therefore, you have to obtain a spinlock somehow. What you can do is to call KeWaitxxx with the parameter indicating that wait/set is an atomic operation
( all dispatcher objects in the system are protected by a single spinlock, and if wait/set is meant to be an atomic operation, KeWaitxxx returns at DISPATCH_LEVEL with dispatcher database spinlock being held) …
I have code to walk thru the EPROCESS list, but I see that it can be subverted
by changing pointers, etc.
Remember one simple thing - there is no run-time detection technique that cannot be subverted. Please note that rootkit can get loaded before the OS, place itself in a memory that the OS is just unaware of, and, at this point, it is in control of everything that happens on the target machine. Therefore, all rootkit detection can get done only on “best-effort basis”…
Anton Bassov
Here are some suggestions
-enum list of processes and threads by following the TypeList list entry of
the OBJECT_TYPE,
-use process creation callback routines, thread creation callback routines,
load image callback routines
-use NtQuerySystemInformation with SystemProcessInformation, with
SystemProcessesAndThreadsInformation ,
-create lists of all handles using different methods and see to what objects
they belong
-create lists of all objects using different methods and see to what
processes they belong (CreatorUniqueProcess)
-query the current process and the current thread at any time you want
-usermode toolhelp API, PSAPI
and compare these results to your master list. The more fantasy you have the
more ways you will discoiver to find out about the existence of processes.
Thus, every attempt of a rootkit to hide an object introduces many more ways
to reveal itself. You are at an advantage because your rootkit detection is
read-only but the rootkit needs to modify the kernel, they will need heavy
duty kernel patching. But yes, it remains a best-effort approach which
doesn’t mean you can’t do a very good job.
/Daniel
wrote in message news:xxxxx@ntdev…
>I am writing some rootkit detection code as part of a kernel driver. I
>need an API that will give me a pointer to a KPROCESS structure so that I
>can walk thru the process list to find ALL process (including hidden ones).
>Of course I am pre-supposing that there is linkeage in the KTHREAD
>structure that doesn’t get messed up or the process would stop executing,
>which seems a certainty. I need something fool proof.
>
> I have code to walk thru the EPROCESS list, but I see that it can be
> subverted by changing pointers, etc.
>
> Does anyone have a suggestion?
>
> The more fantasy you have the more ways you will discoiver to find out about
the existence of processes.
You don’t really need that much fantasy here - what you have to do is to list all threads, get their process IDs, and compare them to the list of processes. Once thread is a basic scheduling unit, it just cannot get removed from the thread list without losing the ability to run. The “only” problem is that a rootkit may change a process pointer so that you will believe that
a given thread runs in context of some other process that is on the list of processes (in fact, it may modify things in such way that it will become a thread that runs in context of another process -although it is not as easy as it sounds to be, the whole thing is still feasible)…
Anton Bassov
xxxxx@hotmail.com wrote:
Once thread is a basic scheduling unit, it just cannot get removed
from the thread list without losing the ability to run.
(Elaborating on the statement in your previous post:)
If a root kit virtualizes the whole user machine, it runs “outside” the
OS. It will not show up in the thread list and also could make sure it
is not be detectable in any other way within the system.
(You would need at least external hardware to possibly detect it.)
Hint 1 The begining of EPROCESS is the KPROCESS, so if you can find one you
find both. Hint 2: These things have changed at hofix time, so trying to
walk them is a great exercise in crashing the system, but useless otherwise.
–
Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr
Remove StopSpam to reply
wrote in message news:xxxxx@ntdev…
>I am writing some rootkit detection code as part of a kernel driver. I
>need an API that will give me a pointer to a KPROCESS structure so that I
>can walk thru the process list to find ALL process (including hidden ones).
>Of course I am pre-supposing that there is linkeage in the KTHREAD
>structure that doesn’t get messed up or the process would stop executing,
>which seems a certainty. I need something fool proof.
>
> I have code to walk thru the EPROCESS list, but I see that it can be
> subverted by changing pointers, etc.
>
> Does anyone have a suggestion?
>
It sounds like I may need to revert to my original plan, which was to retrieve the process list using the 7 different interfaces/techniques I know, and compare. Any process found on the combined result, but missing on one or more of the interfaces, would be considered as “hidden”.
Sadly, management has given me just five days on this one, due to a surprise customer deadline.
I was looking for a more simplistic approach, since they also need my DLL Injection detector working in that same timeframe, and it isn’t quite done yet
At least these guys don’t point out the cot, blanket, and pillow provided onsite and expect you to work around the clock until you simply drop, like my last employer. That outfit even had a weird presentation about “Doing Everest Without Oxygen”. No pay compensates for that environment (If you recognize what I have described, then I have worked with you in a former life).
Don, I hadn’t observed the offsets changing with hotfixes, but I am aware they definitely have changed with every major OS version since NT4 (I have the structure definitions for NT4, W2K, XP, 2K3, and finally just found Vista, and the structure layouts and offsets are different for every one of them - I dynamically adjust for that).
Note: I am also not currently concerned about detecting Rootkits that virtulize the entire OS, like Joanna’s “Blue Pill”, since the performance hit in some areas makes them agonizing obvious (Large PIO transfers are at least 50x slower, and if they don’t intercept PIO transfers I can detect them). So far that category seems to be not used because they are too obvious.
wrote in message news:xxxxx@ntdev…
>
> Don, I hadn’t observed the offsets changing with hotfixes, but I am aware
> they definitely have changed with every major OS version since NT4 (I have
> the structure definitions for NT4, W2K, XP, 2K3, and finally just found
> Vista, and the structure layouts and offsets are different for every one
> of them - I dynamically adjust for that).
>
In some cases the offsets have changed and in some cases the types have
changed, i.e. UNICODE_STRING becomes PUNICODE_STRING. I do wish Microsoft
would provide better ways to get data about the processes on the system,
etc. but mining the PEPROCESS/KPROCESS structs is a disaster waiting to
happen.
–
Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr
Remove StopSpam to reply
wrote in message news:xxxxx@ntdev…
> Sadly, management has given me just five days on this one, due to a surprise customer deadline.
so much for being timestore.com …
–PA
>thread is a basic scheduling unit, it just cannot get removed from the thread
list
From dispatcher ready lists - yes.
From Ob’s object lists - no, it can.
More so, on many Windows versions (all pre-2003 IIRC) Ob’s per-type lists
require the GlobalFlag bit to be set, and are not maintained otherwise.
–
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com
> From Ob’s object lists - no, it can.
Who cares about the object list??? There is a very slim chance that this list will even be maintained, in the first place. Certainly you have to walk the dispatcher list…
Anton Bassov