Payload Components
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[2]. 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.
Subsections
|