Secure Programming Lecture 6: Memory Corruption IV ... · É a safe compiler to automatically...

Preview:

Citation preview

Secure Programming Lecture 6: MemoryCorruption IV (Countermeasures)

David Aspinall, Informatics @ Edinburgh

30th January 2014

Outline

Announcement

Recap

Containment and curtailment

Stack tamper detection

Memory mode protection

Diversification

Secure programming

Summary

Outline

Announcement

Recap

Containment and curtailment

Stack tamper detection

Memory mode protection

Diversification

Secure programming

Summary

Lab session tomorrow

The first Secure Programming Laboratory will betomorrow!

Friday 31st January, 2pm-5.30pm in AT 5.04.

Please arrive on time, the lab will start with a demointroduction.

Recommended:

É find someone to work with (pairs rather than largergroups).

É preparation: study the lectures on overflowscarefully, try out some examples.

Outline

Announcement

Recap

Containment and curtailment

Stack tamper detection

Memory mode protection

Diversification

Secure programming

Summary

Memory corruption attacks

We’ve seen memory corruption attacks on the heap, onthe stack and elsewhere.

Overflow vulnerabilities in code are caused by, forexample:

É unchecked buffer boundariesÉ out-by-one errorsÉ integer overflowÉ type confusion errors

Memory corruption countermeasures

Two basic programming-related countermeasures:

1. Treat the symptoms:É special technologies in execution or compilationÉ limit the damage that can be done by attacksÉ containment and curtailment

2. Treat the causeÉ ensure that code does not contain vulnerabilitiesÉ secure programming through code review,

analysis tools

Question. Why might choice 2 be impossible?

Outline

Announcement

Recap

Containment and curtailment

Stack tamper detection

Memory mode protection

Diversification

Secure programming

Summary

Generic defences

Defensive technologies are not a real substitute forproper fixes, but:

É give defence in depth security that can protect incase of accidently running malware or regressionsto vulnerable code;

É sometimes code replacement is simply prohibitivelyexpensive or impossible (e.g. non-upgradeablefirmware)

Defences against overflows

Several generic protection mechanisms have beeninvented to prevent overflow attacks and new ones areevolving.

These reduce the attackers chance of reliably exploitinga bug on the host system.

We will look at:

É Tamper detectionÉ Memory protection in OS and hardwareÉ Diversification methods

Outline

Announcement

Recap

Containment and curtailment

Stack tamper detection

Memory mode protection

Diversification

Secure programming

Summary

Canaries on the stack

Each stack frame includes vulnerable location pointerswhich may be corrupted in a stack overflow attack.

Idea:

É wrap frame with protective layer, a “canary”É canary sits below return addressÉ attacker overflows stack buffer to hit return address

É necessarily overwrites canary

É generated code adds and checks canaries

Early proposal: StackGuard compiler.

Stack without canaries

Stack with canary

Question. How might this mechanism be defeated?

GCC’s Stack Smashing Protector

Consider this C program:

#include <stdio.h>#include <string.h>

int fun1(char *arg) {char buffer[1024];strcpy(buffer,arg);

}

void main(int argc, char *argv[]) {fun1(argv[1]);

}

fun1: ; code without SSPpushl %ebpmovl %esp, %ebpsubl $1048, %espmovl 8(%ebp), %eaxmovl %eax, 4(%esp)leal -1032(%ebp), %eaxmovl %eax, (%esp)call strcpyleaveret

main:pushl %ebpmovl %esp, %ebpandl $-16, %espsubl $16, %espmovl 12(%ebp), %eaxaddl $4, %eaxmovl (%eax), %eaxmovl %eax, (%esp)call fun1leaveret

fun1: ;; code with SSP (main function stays the same);; Note: GS register points to per-CPU thread;; memory storagepushl %ebpmovl %esp, %ebpsubl $1064, %espmovl 8(%ebp), %eaxmovl %eax, -1052(%ebp)movl %gs:20, %eax ; set EAX=canary valuemovl %eax, -12(%ebp) ; store near return addressxorl %eax, %eaxmovl -1052(%ebp), %eaxmovl %eax, 4(%esp)leal -1036(%ebp), %eaxmovl %eax, (%esp)call strcpymovl -12(%ebp), %edx ; EDX=canary from stackxorl %gs:20, %edx ; has it changed?je .L3 ;call __stack_chk_fail ; if it has, we’ll abort

.L3:leaveret

the stack protection spots an overflow with 1026characters:

$ gcc -m32 overflow.c -o overflow.out$ ./overflow.out xxxx$ ./overflow.out ‘perl -e ’print "x"x1025’‘*** stack smashing detected ***: ./overflow.out terminatedAborted (core dumped)

Canary arms race

The arms race in general: attackers respond to newprotection mechanisms by looking for vulnerabilities inthose mechanisms. . .

For example:

É Attack code/probing discovers a constant canaryÉ e.g., canary is 0x0af237ab6, so write that near

return address

É Canary defence uses pseudorandom sequenceÉ attacker learns sequence or discovers seed

É Canary defences uses cryptographic PRNGÉ attacker finds where value is storedÉ finds another exploit to copy it

Effectiveness

É Doesn’t protect against local variable overwritingÉ related protection mechanisms reorder local

variables

É Other attacks work by overwriting parametersÉ aim to change where subsequent writes occurÉ overwrite return address, but don’t return

É Hardened heap implementations have also beendevelopedÉ glibc and Windows since XP SP2 have heap canaries

É Self-managed memory mechanisms not addressedÉ e.g., HLL runtimes, application specific heaps

É Return-oriented programming (ROP)É state-of-the-art: use existing executable codeÉ evades canaries, also defeats NX (see below)

Outline

Announcement

Recap

Containment and curtailment

Stack tamper detection

Memory mode protection

Diversification

Secure programming

Summary

Operating system separation (review)

Isolation different processes have different resources(address spaces, file systems, . . . )

Sharing resources are shared between processes,partial isolation. Sharing may be:

É all or nothingÉ mediated with access controlsÉ mediated with usage controls (capabilities)

Concern: granularity of protection.

OSes have provided separation mechanisms since theearly days of multi-user systems. For memory, directsupport was added to the CPU and memory systemhardware.

Hardware memory protection mechanisms

Original mechanisms introduced to provide separation(mainly for safety) between different programs onmulti-user systems:

É Fences: separate memory accesses between OSand user code (one boundary, one way protection).

É Base and bounds registers: enforce separationbetween several programs allowing access controlon memory ranges.

É Tagged architecture: more fine-grained, tags oneach memory location set access rights to storedword (R, RW, X). Supervisor mode instructionsrequired to set tag. Not currently supported inmodern architectures.

OS memory segmentation

Segmentation splits a program into many variablesized pieces, each with a name.

É mainÉ dataÉ moduleÉ libraryÉ . . .

É Programs access memory using names and offsets.É Segmentation table maintained by OS, use

segment registers for indexing.

OS memory segmentation

Pros:

É memory locations abstract from physical memoryÉ OS can move things aroundÉ segments can be shared between programsÉ different segments may have different access

rightsÉ user programs cannot access locations outwith

their segments

Cons:

É seg names mapped to the numbers for efficiencyÉ segfaults: must dynamically check boundsÉ fragmentation of memory

OS paging

Paging splits a program into fixed-sized pieces. Theseget mapped onto memory which is split intoequal sized page frames.

Pros:

É fixed sizes easier to manage, avoid fragmentationÉ transparent to programming model

Cons:

É vs segmentation, lose logical control over regionsÉ access control granularity increasedÉ potential for wasted space

Combined paging and segmentation

É Access via segment table + page translationÉ Combines advantages of each.É Designed for efficient memory allocation/relocationÉ Memory protection useful secondary benefit

Modern solution since Multics. Relies on only twoprotection levels supported in the hardware.

Exercise. Why might more protection levels be better?What is the reason only two levels are currentlysupported?

However, complex/portable OSes prefer to use softwareand work over a flat memory model. The x86 and Linuxwork over a flat model.

Non-executable memory pages

CPU have often included R, RW, X protection formemory pages.

É x86 series CPUs added page-level XD/NX in 2001-4

By enforcing non-executable regions, if the programkeeps code and data separate, shellcode can beprevented from running when it’s injected into dataregions on the heap or stack.

É Compared with C, more tricky for certainlanguages/compilers/interpreters, which maymanipulate executable code during runtime.

Outline

Announcement

Recap

Containment and curtailment

Stack tamper detection

Memory mode protection

Diversification

Secure programming

Summary

Address Space Layout Randomization (ASLR)

Concept: use diversification to make many versions ofsame program; thwarts general attacks that makeassumptions about fixed structure.

ASLR: make it harder to find data or code locations, byrandomising layout during load time. Breakshard-coded static locations.

Implemented in Linux by the PaX Team.

Effectiveness: good, but doesn’t remove mainvulnerability and vulnerabilities in ASLR implementationbecome target of attack. Early implementationsrandomised by small amounts (e.g. 256 addresses), soattacker could use brute force to find the vulnerablelocations. Such attacks may attract attention (sincefailures cause crashes).

Outline

Announcement

Recap

Containment and curtailment

Stack tamper detection

Memory mode protection

Diversification

Secure programming

Summary

Defensive programming: bounds checking

Defensive programming to avoid overflow requiresbounds checking.

É Check data lengths before writingÉ Check array subscripts are within limitsÉ Check boundary conditions to avoid OBOÉ Constrain size of inputsÉ Beware of dangerous API calls to risky code

Responsibility for bounds checking

Like many security checks, this is a sharedresponsibility. It requires checking at each point, bythe:

É programmerÉ programming language, compilerÉ OSÉ hardware

Exercise. For each role, give an example of what theydo to check bounds.

Bounds checks by programmer

int a[20], i;for (i=0, i<20; i++) {

a[i] = 0;...

}

É How can this go wrong?

Bounds checks by programmer

int a[20], i;for (i=0, i<20; i++) {

if (i<0) signal error;if (i >= 20) signal error;a[i] = 0;...

}

É Checking every time seems inefficientÉ Are both checks required?É Tempting to skip. . .

Bounds checks by programmer

int a[20], i, max;...

for (i=0, i<max; i++) {if (i<0) signal error;if (i >= 20) signal error;a[i] = 0;...

}

É If bound is computed, both checks essentialÉ Code reviews, programmer reasoning are brittle

Safety from programming languages

Programming languages may provide memory safetyand type safety, automatically for all programs:

Memory safety disallow reading/writing with arbitrarymemory addressing.Prevents overflow attacks from corruptingmemory.

Type safety prevent storing arbitrary data into datavalues.Makes it harder for attacker to inject data thatwill be executed as binary code.

Safety from compilers and tools

To try to ensure safety with an unsafe language, wemay use:

É a safe compiler to automatically generatechecking code that checks bounds or typesdynamically, during execution.

É a verifying compiler that checks statically atcompile time that the code it produces is safe.

É security testing tools that generate inputs toprograms to try to find security bugs.

É program analysis tools that ensure that inputsource code is free from certain vulnerabilities.

We’ll look at these technologies in more detail later inthe course.

Safety from OS, libraries

É See lists of unsafe functions and explanations:É Microsoft’s recommendationsÉ CERT Secure C Coding

É Use a code security scanning toolÉ Have lists of dangerous API calls built inÉ Simple to find these in code, need deeper analysis

to identify certain vulnerabilitiesÉ Examples: RATS, cppcheck, SPLint, Clang.

É Switch to using safe(r) library functionsÉ The Safe C Library introduced in VS 2005.É Bounds checking functions part of the latest C11

standard (appendix K, also ISO/IEC TR 24731-1)É But has been contentious, not clear how

widely/quickly will be adopted.

Outline

Announcement

Recap

Containment and curtailment

Stack tamper detection

Memory mode protection

Diversification

Secure programming

Summary

Review questionsOverflow protection mechanisms

É Describe how StackGuard’s “canaries” work to stopbuffer overflows. What kind of attacks are they noteffective against?

É Describe how hardware-assisted memoryprotection can prevent the worst kinds of overflowattacks. In what cases may it be difficult to use?

É Explain the strategy of program diversification andhow it is achieved in ASLR.

Avoiding overflow vulnerabilities

É Explain where bounds checking should beperformed, especially to ensure “defence-in-depth”.

É List some checks which a programmer or staticanalysis tool should do to prevent overflowvulnerabilities in released code.

Coming next

Lab session tomorrow!

Next week: looking at injections.

References and credits

TBD

Recommended