|Informative Information for the Uninformed|
Next: Migration Up: Windows Kernel-mode Payload Fundamentals Previous: Resolving Symbols   Contents
This chapter will outline four distinct components that can be used in conjunction with one another to produce a logical kernel-mode payload. Unlike user-mode vulnerabilities, kernel-mode vulnerabilities tend to be a bit more involved when it comes to considerations that must be made when attempting to execute code after successfully exploiting a target. These concerns include things like IRQL considerations, setting up code for execution, gracefully continuing execution, and what action to actually perform. Some of these steps have parallels to user-mode payloads, but others do not.
The first consideration that must be made when implementing a kernel-mode payload is whether or not the IRQL that the payload will be running at is a concern. For instance, if the payload will be making use of functions that require the processor to be running at PASSIVE_LEVEL, then it may be necessary to ensure that the processor is transitioned to a safe IRQL. This consideration is also dependent on the vulnerability in question as to whether or not the IRQL will even be a problem. For scenarios where it is a problem, a migration payload component can be used to ensure that the code that requires a specific IRQL is executed in a safe manner.
The second consideration involves staging either a R3 payload (or secondary R0 payload) to another location for execution. This payload component is encapsulated by a stager which has parallels to payload stagers found in typical user-mode payloads. Unlike user-mode payloads, though, kernel-mode stagers are typically designed to execute code in another context, such as in a user-mode process or in another kernel-mode thread context. As such, stagers may sometimes overlap with the purpose of the migration component, such as when the act of staging leads to the stage executing at a safe IRQL, and can therefore be considered a superset of a migration component in that case.
The third consideration has to do with how the payload gracefully restores execution after it has completed. This portion of a kernel-mode payload is classified as the recovery component. In short, the recovery component of a payload finds a way to make sure that the kernel does not crash or otherwise become unusable. If the kernel were to crash, any code that the payload had intended to execute may not actually get a chance to run depending on how the payload is structured. As such, recovery is one of the most volatile and critical aspects of a kernel-mode payload.
Finally, and most importantly, the fourth component of a kernel-mode payload is the stage component. It is this component that actually performs the real work of the payload. For instance, a stage component might detect that it's running in the context of lsass.exe and create a reverse shell in user-mode. As another example of a stage component, eEye demonstrated a keyboard hook that sent keystrokes back in ICMP echo responses from the host. Stages have a very broad definition.
The following sections will explain each one of the four payload
components in detail and offer techniques and implementations that
can be used under certain situations.