Direct Kernel Object Manipulation (DKOM)
In this post, we talk about manipulating the _EPROCESS structure in the kernel and how to hide processes.
Overview
In most cases, rootkits can hide a process by exploiting various kernel structures such as _EPROCESS
.
EPROCESS is a kernel memory structure that describes system-related processes, in fact, every process that runs on the system has a unique _EPROCESS object that is stored somewhere in the kernel.
This object contains various things like process ID or structures like _PEB (Process Environment Block)
.
Using Windbg, we can see the _EPROCESS
structure
|
|
One of the important fields of this structure is ActiveProcessLinks
, which is a pointer to another structure called LIST_ENTRY
.
|
|
LIST_ENTRY is actually a double link list that contains two fields FLINK (forward link)
and BLINK (backward link)
that refer to the elements before and after it.
All processes have their own core objects in the form of the EPROCESS core structure. All those EPROCESS objects are stored in a doubly linked list.
In fact, when we request the list of running processes from the operating system, Windows uses
LIST_ENTRY
structures through the doubly linked list ofEPROCESS
nodes and retrieves the information of each process.
According to the above content, rootkits can hide a process from the user’s view by manipulating the connections of the nodes
If we separate EPROCESS 2 from the previous node (EPROCESS 1) and the next node (EPROCESS 3) in the doubly linked list
, the process in question becomes practically invisible to all userland APIs that retrieve the running processes of the system.
Example
For this lab, we run a sample process like a calculator and try to hide it
Using Windbg
and in kernel mode, we can get more information about the process we want
|
|
According to the output of the above command, the EPROCESS
structure is located at ffff958f8f611080
|
|
As you can see, ActiveProcessLinks is a doubly linked list filled with two pointers (Flink and Blink)
.
We can read those values with dt _list_entry ffff958f8f611080+448
or just dq ffff958f8f611080+448 L2
:
|
|
Now we can find the previous and next EPROCESS
nodes that Calculator.exe
points to.
FLINK
points to 0xffff958f`8b9c2708BLINK
points to 0xffff958f`8e4b3748
We can check the process image name referenced by calculator FLINK at 0xffff958f`8b9c2708
|
|
We do the same for BLINK:
|
|
So far, we noticed that our process is located between two processes, svchost.exe and ApplicationFrameHost.exe
.
Using the following formula, we can get the PIDs of each process
|
|
Change links
The table below is the FLINK
and BLINK
pointers of our target processes
Image | PID | EPROCESS | ActiveProcessLinks | Flink | Blink |
---|---|---|---|---|---|
svchost.exe | a08 | ffff958f8b9c22c0 | ffff958f`8b9c2708 | ffff958f`8b9a3508 | ffff958f`8f6114c8 |
Calculator.exe | 17c8 | ffff958f8f611080 | ffff958f`8f6114c8 | 0xffff958f`8b9c2708 | 0xffff958f`8e4b3748 |
ApplicationFrameHost.exe | 17b0 | ffff958f8e4b3300 | ffff958f`8e4b3748 | 0xffff958f`8f6114c8 | 0xffff958f`8e4be4c8 |
To manipulate these connections and remove the Calculator.exe
process from it, we must change the following values
Change the value of FLINK
svchost.exe
in ffff958f`8b9c2708 to FLINKApplicationFrameHost.exe
in ffff958f`8e4b3748Change the value of BLINK
ApplicationFrameHost.exe
at ffff958f`8e4b3748+8 to FLINKsvchost.exe
at ffff958f`8b9c2708.
+8 because LIST_ENTRY has two FLINK/BLINK fields and each is 8 bytes
|
|
Once the memory is modified, I see that our target process is invisible
References
- Manipulating ActiveProcessLinks to Hide Processes in Userland
- Understanding Windows DKOM(Direct Kernel Object Manipulation) techniques
- When malware meets rootkits
- blackhat - DKOM (Direct Kernel Object Manipulation)
- [windows] kernel internals
- DKOM
- New Milestones for Deep Panda: Log4Shell and Digitally Signed Fire Chili Rootkits