Understanding Stack Smashing & Manipulation: Fault Attacks for Security, Study notes of Advanced Computer Architecture

An overview of fault attacks, specifically stack smashing, in the context of information security. It covers the history and significance of these attacks, the anatomy of a stack, and methods for exploitation and defense. The slides include examples of buffer overflow vulnerabilities and the use of shellcode.

Typology: Study notes

2010/2011

Uploaded on 09/07/2011

home-alone
home-alone 🇬🇧

4

(1)

18 documents

1 / 19

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Fault Attacks
IIn general, software only works when you program it correctly.
IYou can test the functional correctness only in terms of how you expect
the user to behave.
IBut what about if someone tampers with or rewrites the code or variables
while the program is running ?
IFor example, tampering with control flow or arithmetic operations ?
IThis scenario allows us to mount an active attack:
IPhysically tamper with the hardware or software environment that is
executing the algorithm.
IFor example, provoke random or targeted memory errors, or even force
the program to crash and core dump.
IThe attack can be permanently destructive or just introduce transient
faults.
IContrast this with passive, side-channel attacks where we are only
allowed to monitor computation, not change it.
Dan Page
COMSM0213: Information Security Slide 2
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13

Partial preview of the text

Download Understanding Stack Smashing & Manipulation: Fault Attacks for Security and more Study notes Advanced Computer Architecture in PDF only on Docsity!

Fault Attacks

I In general, software only works when you program it correctly.

I You can test the functional correctness only in terms of how you expect

the user to behave.

I But what about if someone tampers with or rewrites the code or variables

while the program is running?

I For example, tampering with control flow or arithmetic operations?

I This scenario allows us to mount an active attack:

I Physically tamper with the hardware or software environment that is

executing the algorithm.

I For example, provoke random or targeted memory errors, or even force

the program to crash and core dump.

I The attack can be permanently destructive or just introduce transient

faults.

I Contrast this with passive, side-channel attacks where we are only

allowed to monitor computation, not change it.

Dan Page

Pointer Manipulation (1)

char* p

’’Good data’’

’’Bad data’’

Output

Input

Faults

Program User

Dan Page

Stack Smashing: Attack (1)

I Processes running on operating systems are assigned a region of

(virtual) memory.

I The memory region is constructed in a standard way:

high addresses low addresses

Uninitialised

Stack Heap

Initialised Data

Instructions

I Traditionally, the stack grows downwards and the heap grows

upwards.

Dan Page

Stack Smashing: Attack (2)

I We are interested specifically in the stack:

I Used as a means of performing function calls.

I Used for temporary storage, for example when a program runs out of

free registers.

I The stack is divided up into stack frames:

local variables return address caller−save GPR return address callee−save GPR

temporaries caller−save GPR

argument nargument 1argument 0saved FP argument nargument 1argument 0

incoming arguments

next frame

outgoing arguments

previous frame FP current frame SP high addresses low addresses

Dan Page

Stack Smashing: Attack (4)

I Simplifying things, the example stack looks something like:

return address

saved FP

high addresses

return address

saved FP return address

saved FP

low addresses

argcargv buffer &buffer&argv[1]

srcdst

main f strcpy

I There are a few crucial features to note:

I The array buffer only holds 32 bytes; if we overflow outside buffer,

we start to overwrite critical stack content.

I If we overwrite the return address, the program gets confused about

where to branch to when the function returns.

I If an attacker can overwrite the return address, he can branch to any

address he wants ...

Dan Page

Stack Smashing: Attack (5)

I ... but we need to branch to useful code; random behaviour or

crashing is undesirable.

I We control the content of buffer, what if we fill it with a program and

branch there?

I Shellcode is the term associated with machine instructions that

execute the equivalent of exec( "/bin/sh" );

I By causing the target program to run a shell, the attacker is able to drop

into and use that shell.

I If the target program is run in super-user mode, the shell is also a

super-user shell i.e. the attacker becomes root.

I Building compact shellcode that fits into a small array but contains no

NULL bytes is a challenge but not too hard.

Dan Page

Stack Smashing: Defence (1)

I Applying some form of code audit is often the first line of defence:

I This approach is expensive in terms of physical effort.

I It is also error prone due to human nature.

I However, it can be effective; Open BSD has a dedicated team that

carries out code audits:

I Around twelve full time code auditors look for bugs and vulnerabilities.

I Scan millions of lines of code on a file-per-file basis.

I Thousands of problems fixed in first year, increasingly less from then on.

I Ultimately, educating programmers to write better code is vital:

I ... many programmers want to get the job done as quick as possible.

I ... many programmers focus on performance rather than security.

I ... many programmers are unaware of the dangers or solutions.

Dan Page

Stack Smashing: Defence (2)

I As a first line of defence against attacks launched over a network, we

might utilise packet-filtering:

I Similar approach to that used within virus checkers.

I Scan for packets that have “bad” content such as shell-code.

I Throw away or block connections that send such packets.

I However, there are some obvious problems:

I Not all attacks are launched over a network.

I The scan is fooled by polymorphic or encrypted shell-code.

I Need a very low false positive rate or network traffic is disrupted.

Dan Page

Stack Smashing: Defence (4)

I Overflowing the stack to re-direct the program counter assumes the

stack contains data and instruction information.

I So one way to prevent data overflow influencing program flow is to

split the stack in two:

I One stack for control flow, e.g. return addresses ...

I One stack for data, e.g. local variables, saved registers ...

I This can be achieved in:

I Software using GCC and some assistance from the kernel.

I Hardware by altering the actual processor design.

I Again a good idea but backward compatibility issues mean a slim

chance of actually happening.

Dan Page

Stack Smashing: Defence (5)

I More complex defence methods take one of two main approaches:

I Compile-time attack prevention using secure language and compiler

design.

I Run-time attack detection of an attack that triggers some alarm and

hence prevents the attack succeeding.

I These approaches are also deployed using one of two methods:

I Application of solution to all software elements i.e. centralised

deployment.

I Application of solution to individual elements i.e. decentralised

deployment.

I As with side-channel attacks, there is no silver bullet:

I A blending of different methods is advisable.

Dan Page

Stack Smashing: Defence (7)

I StackGuard is a system proposed by Cowan et. al. in 1998/1999.

I Basic idea is to place a checksum (or “canary”) on the stack to signal

overflow.

I Buffer overflow also overwrites canary which is checked by function exit.

I Can also be applied to heap by placing canary between chunks.

I Improved by so called “terminator canary” which includes NULL bytes etc.

I Good idea but there are some problems:

I The attacker might be able to step over the canary somehow.

I The attacker might corrupt the source of canary checksums.

Dan Page

Stack Smashing: Defence (8)

I PointGuard is a system that improves on StackGuard; again proposed

by Cowan et. al. in 2002/2003.

I Basic idea is to “encrypt” all pointers while they are stored in memory.

I Tampering with memory resident pointers corrupts encryption.

I Only valid encryptions decrypt to the correct pointer.

I Tampered pointers decrypt to fairly random addresses.

I Dereferencing a random address means high chance of crash.

I Low cost in terms of performance:

I Encrypt and decrypt are simple XOR.

I Can place instructions in memory access delay slots (?).

Dan Page

Defencive Programming (2)

1. Don’t ignore compiler warnings and/or error messages; specify the

maximum level for both.

2. Give the compiler as much help as you can, for example use const

where appropriate.

3. Test every value possible and act accordingly; essentially means

checking pre and post conditions:

I ... NULL pointer values.

I ... return values from functions that indicate error.

I ... the errno value set by some library functions.

4. Don’t assume shortcuts are acceptable, for example using casts often

means bad design.

5. Know and use appropriate library functions:

I ... gets and scanf can be bad because they don’t bound input.

I ... strncpy is a bounded version of strcpy.

6. Never assume users will do what you want them to!

Dan Page