Title: CompFoo pt' 8: Attacks and Defenses 4
1Comp-Foo pt. 8Attacks and Defenses 4
- Buffer Overflows
- Types
- Heap overflows
- Stack overflows
- Exploitation
- Variable attack
- Ret overwrite
- Return into libc
- Format Strings
- Vulnerable function family
- Exploitation
- EIP overwrite
- GOT overwrite
- .dtors overwrite
- Sensitive data disclosure
2Buffer Overflows
- Hello, my name is AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAA
3Basic Overflow Theory
- In a buffer overflow flaw, a certain amount of
space is set aside in memory. This is known as a
buffer. If the program does not check to see that
the data being placed in the buffer is of an
appropriate size and attempts to write anyway,
the data will overflow into other parts of
memory, changing them. - If this data eventually overwrites program
control information, (and it most likely will!)
the program flow can be altered. This is often
used to change the return address stored by a
program and point to arbitrary code written by an
attacker.
4Basic Overflow Theory
5Heap overflows
- Heap overflows involve overflowing large chunks
of memory allocated for data storage by a
program, usually for a variable attack or a
function pointer.
6Stack overflows
- Overflows usually occur in stack memory, where a
program stores small bits of data, usually
variables. The stack also contains some data
which determines the flow of the program, which
can be overwritten.
7Exploitation
- There are several ways to use a buffer overflow
vulnerability to leverage control over program
flow. - The first, and simplest, is a variable attack.
8zOMG Video?!
9So what just happened there?
- Well, that was a video!
- Okay, seriously, the program attempted to write
the value I provided it into memory, but did not
check its length. I was able to overflow the
bounds of one variable, and overwrite another. - That, friends, is a variable attack!
10Next step
- Now that you understand (I hope) how a variable
attack style exploit works, let's move on to a
ret address overwrite!
11Ret Address Overwrite
- When a function is called, a program places the
address after the call instruction on the stack.
Once the function finishes executing, it takes
the stored address, or ret address, from the
stack, and continues execution at that memory
location. - But what if we were to overwrite that stored
address? It is, after all, on the stack!
12Ret Address Overwrite
- Once the function returns, the program will
attempt to execute whatever is at the memory
address we provide, even if it's garbage. As
such, we can reliably produce a crash by making
the program suffer a segmentation fault. - Additionally, we can point to an arbitrary memory
address where we know some code we want to
execute is located.
13Typical exploitation is as follows
- Attacker stores shellcode in either the buffer or
an environment variable, and then gets its memory
location - Attacker overflows the program, overwriting the
stored ret address with the address of the
shellcode - The shellcode executes, performing some action
14Wait, shellcode?
- Named for its usual action of launching a shell,
often with elevated privileges, shellcode is
simply machine code to be placed into memory for
execution. - Shellcode generally has two parts to it A sled,
and a payload.
15Shellcode, cont.
- The sled is usually made with many NOP (no
operation) instructions. The idea is that because
memory locations tend to vary a little bit and
processors are very picky about their
instructions, the process will land in the NOPs,
and sled along until it reaches the actual
instructions.
16Shellcode, cont.
- The payload, often referred to as the shellcode,
is the set of instructions to be called.
17Shellcode goes where?
- Shellcode can go anywhere in memory, although the
most popular places are in the stack (before or
after the ret address overwrite) and in an
environment variable. - However, the portions of memory set aside for
data are identifiable as such by the processor,
so many operating systems and even some
architectures now have non-executable data
sections. - This is not, however, a foolproof solution.
18The better fool
- Very few programs are entirely self-contained,
especially in Linux systems. - Instead, they rely on libraries which are loaded
into memory prior to program execution. - See where this is going?
19Return into libc
- When we overwrite the ret address, we will
specify the location of a function from our
library (in Linux systems, this is libc). The
most commonly used one is system(). - What we need to do, then, is to specify a
location in memory where our string argument is
directly after the memory address of the function
we're executing (and a 4-byte junk return
address), and if all goes correctly, we will
simply make a library call, like
system(/bin/sh).
20Ret2libc sled?
- Why sure!
- The library functions won't change memory
addresses, but the location of your string often
will, so you can use redundant slashes as a sort
of sled. - For example
- /////////////////////////////////////////////////
/////////bin/sh - is functionally equivalent to
- /bin/sh
21Buffer Overflow Defenses
- Special compilers like StackGuard
- A non-executable stack (as we discussed earlier)
- But most important, good programming
habits!Remember, be careful when using static
buffers to store user data, and don't use known
vulnerable functions like gets()
22Format String Vulnerabilities
23Format String Vulnerabilities
- When a function such as printf() is called
without secondary arguments, any format string
identifiers in the string will pop data from the
stack and perform their specified functions with
them. - As such, when you have a call that looks like
- printf(argv1)
- you have some issues.
24Format function family
- fprintf prints to a FILE stream
- printf - prints to the stdout' stream
- sprintf - prints into a string
- snprintf - prints into a string with length
checking - vfprintf - print to a FILE stream from a va arg
structure - vprintf - prints to stdout' from a va arg
structure - vsprintf - prints to a string from a va arg
structure - vsnprintf - prints to a string with length
checking from a va arg structure - Relatives
- setproctitle - set argv
- syslog - output to the syslog facility
- others like err, verr, warn, vwarn
This frame taken from team teso's paper on format
string vulns. A copy can be found at
http//www.pulltheplug.org/wargames/vortex/teso_fo
rmat.txt
25Why this is exploitable pt. 1
- Well, first off, we can crash the program by
specifying multiple s identifiers. This will
continually pull 4-byte chunks off the stack,
interpret them as memory addresses, and attempt
to print them as strings. - Eventually the program will come across something
that it can't correctly interpret as a string,
and crash.
26Why this is exploitable pt. 2
- At some point, the program will be pulling things
off of the stack that we put there! - As such, we can specify an arbitrary memory
location and read it off as a string. That's
really useful when you have sensitive info stored
in memory.
27Why this is exploitable, pt. 3
- The n identifier writes the number of bytes
printed to the address pulled from memory. - So not only can we read from arbitrary memory
locations... we can write to them!
28Typical exploitation is as follows
- A string like AAAA.08x.08x.08x.08x.08x.08x.
08x is entered into the program to find out how
much data must be pulled from the stack before
user data is used - A target for overwriting is chosen, and the
number of bytes that must be written to overwrite
with the correct value is calculated - Once the offset has been figured out, a string
like \xc0\xc8\xff\xbf\xbe\xc8\xff\xbf_498x.58x.
08x.n.n is used to overwrite the address, 2
bytes at a time
29EIP overwrite
- Works the same as with a buffer overflow
- Harder to do, memory location of EIP must be
known exactly - Rarely feasible
30GOT entry overwrite
- Involves overwriting an entry in the Global
Offset Table (which holds pointers to functions
used in a program) - Memory locations for the pointers can be found by
running objdump -R ltprogramgt - Often the easiest and cleanest method of
exploitationHowever, the function whose pointer
was overwritten must be called after the
overwrite, or the exploitation will not work
correctly.
31.dtors overwrite
- DTORS, short for destructors, is a pointer to a
cleanup routine for a program (usually empty)
which is executed after the normal cleanup and
before the program exits - Can be found with objdump -h ltprogramgt
- Can be overwritten similarly to GOT entries
- Requires only that the victim program has been
compiled and linked with GNU tools (common)
32For more info...
- Read
- Smashing the Stack for Fun and Profitby Aleph
One - Exploiting Format Stringsby Team Teso/scut
- Heap Overflowsby w00w00