Getting Familiar with the Kernel

Deep dive into Important Kernel Structures and Attributes

One of the most important terms that require to really get familiar with the kernel is data structures, you can think of structures as a recipe, and objects as the baked good itself.

When talking about Structs and memory, we need to keep reminding ourselves that a struct is a collection of data types, which are referred to as the members of the struct, and they are arranged in a fixed order. And if we keep in mind, that each member has its own size, since the order is fixed, the end of one member + one byte would be the start of the next member, all we would need in order to navigate inside a structure in pure memory is an address of a member in the struct, and the offsets of the other desired members of the struct.

When performing arbitrary read and write, the memory that is available to us, is at its most raw form, and as such, the key point to understand regarding structs, is that in case we know an address in the memory in which a structure resides, and we are familiar with how the structure is arranged, we will be able to access each of its members freely. Data structures in the kernel are representations of the objects we see in user-mode such as processes, threads, tokens, handles and etc. they contain the pure “guts”of the objects, that later will be manipulated to allow us executing our attacks. We’ll start by understanding a key structure that doesn’t represent a running object, rather than describe the link between the same data structures, and its symbol is _LIST_ENTRY, which later will be used as part of our navigation system in the kernel memory space.

_LIST_ENTRY:

The _LIST_ENTRY struct is used as an attribute in some of the structures that we’re going to get familiar with, using the following command we can view _LIST_ENTRY definition in WinDbg:

The structure contains two fields, each of them is 8 bytes pointer to another _LIST_ENTRY structures. The most important thing about this structure is that it allows to create bio-directional linked lists of the same data structure, which provide applications and drivers the necessary information to iterate through objects of the list. The Flink field is pointing to the next element in the list while Blink field pointing to the previous element on the list. (F- Forward , B- Backward) _LIST_ENTRY will be used a lot in this research and code in order to locate target processes, threads, handles and every structure that implements the design of doubly-linked list. To better clarify, let us take for example the next structure that we are going to talk about – the _EPROCESS – which represents Process objects in the kernel space. We are going to talk about the structure in the part of this section, but for now know that _EPROCESS is part of a doubly-linked list of all processes, so if we get into the structure _LIST_ENTRY which located in some _EPROCESS in the kernel, Flink field will point on the next _EPROCESS structure, and Blink on the previous _EPROCESS on the list. It is important to mention that the Flink pointer is pointing on other _LIST_ENTRY structure located in the next structure on the list, as described by the figure below:

The pointer Flink is pointing to the same field in the next process, as well as the Blink which pointing to the Flink field in the previous process.

This key point is important to understand, since we would not treat the _LIST_ENTRY pointer provided as the head of the object, but as an offset inside the object which has to be decreased from the pointer value in order to reach the objects head.

_EX_FAST_REF:

The structure is a special pointer in the Windows Kernel which hold pointer to another object. Let’s investigate the structure itself:

Usually, the Object field contains a pointer which point to the object itself, Value would contain the value of the object and the RefCnt field is the reference counter, therefore, in order to dereference the pointer correctly, those bits need to be masked out after reading the pointer. When we said “those bits” we mean to the least significant bits of the pointer value. In our research the _EX_FAST_REF will be used in the context of _EPROCESS struct, and will point to the Access Token of the process.

_PS_PROTECTION:

Have you ever heard about the term PPL? Or Process Protection? If not, keep reading this article, we hope our explanation on the attack section would suffice. The feature is implemented as the structure _PS_PROTECTION, and defined with the following fields:

The values of the members of this struct, are all of Enum types, which will, as their name suggest, specify the level of protection , the types of protections and the Signer of the protection (AntiMalware,Lsa,Windows etc)

The size of this structure is 1 byte, and all its fields contains 3, 1, 4 bits respectively, that defined the protection for specific process / service. Later we’ll use this structure to temper with the protection in order to perform operation on specific process / service.

_HANDLE_TABLE:

As implied from the structure name, _HANDLE_TABLE is a structure used to hold and manage all the handles of specific process, lets overview the structure fields:

The most important information about this structure is that TableCode acts as a pointer to the base of the actual handle list of the process.

_HANDLE_TABLE_ENTRY:

_HANDLE_TABLE_ENTRY is the structure used to hold a Handle, an object that define an access control for objects to other objects in the OS. the _HANDLE_TABLE is basically a list of _HANDLE_TABLE_ENTRYs. From our offensive perspective, this structure is a target for modification since it holds the data required to change the access rights to specific object, we will come back to this structure shortly when going deep into the offensive section of this research. From WinDbg perspective it defined as the following:

All those members of _HANDLE_TABLE_ENTRY struct are defining a Handle of a process, the most interesting one is GrantAccessBits, which describes the access rights provided to a process which hold the handle in its _HANDLE_TABLE, for other objects.

_EPROCESS:

As described above, the _EPROCESS structure is the object which contains the data of a running process in the Windows Kernel and will be in our project as one of the main targets for attributes modification. Using WinDbg, we can view how the structure is defined and get some idea of potential targets for modifications, in our analysis we’ll focus on several attributes of the structures since most of them are of scope for our research:

Now it’s the time to explain some of the fields defined in _EPROCESS structure, which will be used later in our attacks:

1.ActiveProcessLinks – the field is a _LIST_ENTRY struct which points to the next and previous processes in doubly-linked list of all the running process on the machine. Since the kernel memory space is not managed, it is no so straight forward to just iterate over its memory, with the ActiveProcessLinks field we able to iterate on all the running processes once we got an address of any process.

2.Token – As the name implies, this field is a pointer to _EX_FAST_REF struct, which holds the access token of the process. In Windows, each user has its own access token produced when authenticating, and then attached to processes upon execution, the token and its data are implemented at the _EX_FAST_REF struct.

3.ObjectTable – An attribute that represents a pointer to the _HANDLE_TABLE structure of the process, the structure is used to manage and point on all handles of specific process.

4.ThreadListHead – Another field contains _LIST_ENTRY structure. The structure is part of doubly linked list (the first on the list) of objects of the type _ETHREAD ,which later will allow us to iterate through all the process threads.

5.Protection – A field in the size of a single byte which contains a _PS_PROTECTION structure which contains essential data and configuration of the process protection.

_ETHREAD:

Like _EPROCESS, you can guess that _ETHREAD is the executive object for threads in Windows OS. Just like _EPROCESS , the first member of _ETHREAD is a member of type _KTHREAD which represents the thread in case its context is switched from executive to kernel mode. For every process in the operation has at least 1 thread, and it’s _ETHREAD object will be linked to the _EPROCESS by its member ThreadListHead which points to a _LIST_ENTRY struct within the _ETHREAD object structure (described in _EPROCESS) with all the other threads created by the process (or for the process … XD). The structure defined as the following:

We are not going to dig deeper on all of the struct members, for now, the only one we are interested in is the Tcb member. Tcb = Thread Control Block, which is a structure (_KTHREAD) and contains thread-specific data required for managing the thread in Windows OS.

_KTHREAD:

As described in _ETHREAD, _KTHREAD is the data structure contain the information for managing specific thread in its kernel context (and called Tcb in _ETHREAD). What we mean by that , is that the values of this structure allow to not only to control the thread flow, but its status, APC and much more.

Exploring this structure was very interesting task, since we’ve noticed a lot of members that only by their name can be a potential target. But for our project we’ll focus only on the member TrapFrame, which may hold the values of all registers at the system in specific situations.

More on that later.

Last updated