Exploitation Using Client-Side Attacks
111
How Browser-Based Exploits Work
Browser exploits are similar to any traditional exploit but with one major dif-
ference: the method used for shellcode delivery. In a traditional exploit, the
attacker’s entire goal is to gain remote code execution and deliver a malicious
payload. In browser exploits, the most traditional way to gain remote code
execution is through an exploitation technique called
heap spraying
. But
before examining heap spraying in detail, let’s talk about what the
heap
is
and how it’s used.
The heap is memory that is unallocated and used by the application as
needed for the duration of the program’s runtime. The application will allo-
cate whatever memory is necessary to complete whatever task is at hand. The
heap is based on how much memory your computer has available and has used
through the entire application’s life cycle. The location of memory allocated
at runtime is not known in advance, so as attackers, we would not know where
to place our shellcode. Hackers can’t simply call a memory address and
hope to land at the payload—the randomness of memory allocated by the
heap prevents this, and this randomness was a major challenge before heap
spraying was discovered.
Before moving on, you also need to understand the concept of a
no-
operation instruction (NOP)
and
NOP slide
. NOPs are covered in detail in
Chapter 15, but we’ll cover the basics here because they are important to
understanding how heap spraying works. A NOP is an assembly instruction
that says, “Do nothing and move to the next instruction.” A NOP slide com-
prises multiple NOPs adjacent to each other in memory, basically taking up
space. If a program’s execution flow encounters a series of NOP instructions,
it will linearly “slide” down to the end of them to the next instruction. A
NOP, in the Intel x86 architecture, has an opcode of 90, commonly seen in
exploit code as
\x90
.
The heap spraying technique involves filling the heap with a known
repeating pattern of NOP slides and your shellcode until you fill the entire
memory space with this known value. You’ll recall that memory in the heap is
dynamically allocated at program runtime. This is usually done via JavaScript,
which causes the browser’s allocated memory to grow significantly. The attacker
fills large blocks of memory with NOP slides and shellcode directly after them.
When program execution flow is altered and randomly jumps somewhere
into memory, there is a good chance of hitting a NOP slide and eventually
hitting the shellcode. Instead of looking for a needle in a haystack—that is,
the shellcode in memory—heap spraying offers an 85 to 90 percent chance
of the exploit being successful.
This technique changed the game in browser exploitation and in the
reliability of exploiting browser bugs. We will not be covering the actual code
behind heap spraying, because it’s an advanced exploitation topic, but you
should know the basics so that you can understand how these browser-based
exploits work. Before we begin launching our first browser exploit, let’s look
at what actually happens behind the scenes when an exploit is launched.