Introduction

Return Address Protection

RAP: RIP ROPPaX Team

H2HC 2015.10.24

RAP: RIP ROP

Indirect Control Transfer Protection

Introduction

Return Address Protection

Introduction
PaX/grsecurity
Return Address Protection
Indirect Control Transfer Protection

RAP: RIP ROP

Indirect Control Transfer Protection

Introduction

Return Address Protection

Indirect Control Transfer Protection

PaX/grsecurity

Overview

I Host Intrusion Prevention System
I 15 years: 2000-2015, linux 2.2-4.2
I Focus: exploitation of memory corruption bugs
I Threat model: arbitrary read-write memory access
I Bugs vs. Exploits vs. Exploit techniques
I Privilege abuse vs. Privilege escalation
I Performance vs. Usability

RAP: RIP ROP

Return Address Protection

Introduction

Indirect Control Transfer Protection

PaX/grsecurity

Memory Corruption Bugs
I Unintended control over address/content of memory access
I“Precursor” bugs included (memory disclosure, unintendedreads, etc)

I Two generic goals:
II

Find them in the source
Catch them before they trigger

I Too many kinds to cover them with universal approaches
I see http://cwe.mitre.org/

RAP: RIP ROP

Return Address Protection

Introduction

Indirect Control Transfer Protection

PaX/grsecurity

Threat ModelI Union of the powers (unintended sideeffects) of all possible

memory corruption bugs
I Arbitrary read-write memory access
I Bug can be triggered:

1. for arbitrary addresses
2. with arbitrary content
3. arbitrary operation
4. arbitrary number of times
5. at arbitrary times
I Privilege abuse: exercise existing powers for unintendedpurposes
I Privilege escalation: gain new powers (to subsequently abusethem)
RAP: RIP ROP

Introduction

Return Address Protection

Indirect Control Transfer Protection

PaX/grsecurity

Exploit Techniques & Defenses
Execute new (injected) code(shellcode)
Execute existing code
out-of-(intended)-order(return-to-libc, ROP/JOP)
Execute existing codein-(intended)-order (data-onlyattacks)
I Increasing order of difficulty
I Decreasing amount of control

RAP: RIP ROP

Non-executable pages, runtime
code generation control, ASLR
Control flow integrity, RAP,ASLROpen question (RANDSTRUCT,KERNSEAL, etc)

Introduction

Indirect Control Transfer Protection

Return Address Protection

PaX/grsecurity

Exploit Techniques vs. Memory Corruption Bugs
Abuse/Escalation

Shellcode"

Code Reuse""

Data-only""

CVE-xxxx-xxxxCVE-xxxx-xxxx
CVE-xxxx-xxxx
0-day #1
0-day #2...
I PaX: started as a defense mechanism for the first column"""

I Lately: groups of rows (bug classes via gcc plugins)
I Today: second column

RAP: RIP ROP

Return Address Protection

Introduction

Indirect Control Transfer Protection

PaX/grsecurity

Code Reuse Attacks and Defenses
I Code pointer modification (unintended CFG edge)
II

Return addresses
Language level function pointers
Virtual method table
Signal handlers and signal return contexts
I Exception handling, setjmp/longjmp, landing padsII

I Defenses (PaX future doc from 2003)
I

Immutable (read-only) code pointers
II

Code pointer target verification
II

RAP: RIP ROP.rodata, RELRO, CONSTIFY, CPI/CPS

CFI, RAP

Limited performance budget as usualIntroduction

Return Address Protection

Introduction
Return Address Protection
History
RAP
Indirect Control Transfer Protection

RAP: RIP ROP

Indirect Control Transfer Protection

Return Address Protection

Introduction

Indirect Control Transfer Protection

History

StackGuard 1997
I Developed in 1997, published in January 1998 at the USENIX

Security Symposium
I Crispin Cowan and others
I No formal threat model, mixes up bug category (bufferoverflow) with exploit techniques (code injection)
I Probabilistic defense
I Canary between saved return address and the rest of the stackframeII

RAP: RIP ROP

Canary: terminator, random
No protection for other state (frame pointer, local variables,arguments)

Return Address Protection

Introduction

Indirect Control Transfer Protection

HistoryStackGuard 1999 (XOR canary)
I Attack by Mariusz Woloszyn (emsi) in PHRACK 56 in May2000
I

Abuses unprotected local pointer variable

I Response: encrypt/decrypt return address by a random keyIICredited to Aaron Grier
Mentioned in US7752459 (PointGuard patent)

I Released in StackGuard 1.21 in November 1999, abandoned

later without explanation

RAP: RIP ROP

Return Address Protection

Introduction

Indirect Control Transfer Protection

History

Stack Shield 1999

I Released in August 1999 by Vendicator
I No formal threat model
I Shadow stack and range checking for return addresses
I

Deterministic defense

I No attack detection originally, added in v0.5
I Limited function pointer protection (range checking) in v0.6

RAP: RIP ROP

Return Address Protection

Introduction

Indirect Control Transfer Protection

History

Propolice/Stack Smashing Protector (SSP) 2000
I Developed by Hiroaki Etoh (IBM Japan) and announced on

the gcc and bugtraq lists in August 2000
I

Patented (lapsed):US6941473

I No formal threat model
I Probabilistic defense
I Protects the frame pointer, some local variables, arguments
I Served as basis for Microsoft’s /GS and Red Hat’s

reimplementation for gcc 4.1 (February 2006)
I -fstack-protector vs. -fstack-protector-all vs.

-fstack-protector-strong (gcc 4.8)

RAP: RIP ROP

Return Address Protection

Introduction

Indirect Control Transfer ProtectionRAPOverview
I Threat model: arbitrary read-write accessI

Except the ’at arbitrary times’ part

I Conceptually based on the XOR canary approach

Probabilistic defense
Performance tweaks without sacrificing security
I Main pass is in GIMPLE, not RTL
II

I Mostly architecture independent
I

Single callee saved reserved register (RAP cookie), (r12 onamd64)
I

RAP: RIP ROP

Hard to leak (uninstrumented asm code)Introduction

Return Address Protection

RAP

RAP Example
push %rbx
mov 8(%rsp),%rbx
xor %r12,%rbx...
xor %r12,%rbx
cmp %rbx,8(%rsp)
jnz .error
pop %rbx
retn.error:
ud2

RAP: RIP ROP

Indirect Control Transfer Protection

Return Address Protection

Introduction

Indirect Control Transfer Protection

RAP

RAP (kernel)
I RAP cookie changes:

Per task
Per system call
I Per iteration in selected infinite loops
III
I

Long running event handlers (idle loop, kthreadd, etc)
Could be automated perhaps

I Unreadable kernel stacks

Prevents cross-task infoleaks and corruption
Needs per-cpu pgd (already developed for
KERNEXEC/UDEREF)
I Implementation problem: waitqueue structsIII

RAP: RIP ROP

Move them off the kernel stackReturn Address Protection

Introduction

Indirect Control Transfer Protection

RAP

RAP (userland)

I XOR canary method is vulnerable to arbitrary reads
I

ASLR helps a bit: two leaks are neededII

encrypted return addressplaintext code address (not necessarily the return address)

I Combine with return place (code pointer target) verification

RAP: RIP ROP

Return Address Protection

Introduction

Indirect Control Transfer Protection

RAP

Performance Optimizations
I Reduce coverage without sacrificing security
IUnlike ssp and ssp-strong

I Compute ’can corrupt memory’ property for each function andbasic block
IPropagate it up the call hierarchy
III

Omit instrumentation if the function cannot corrupt memory
About 9% of kernel functions untouched, 15% in chromium

Basic block coverage narrowing
I

Up to 40% of kernel functions, 8% in chromium

I XOR elimination

If the RAP cookie does not spill to memory (basic blocknarrowing can help)
I About 6% of kernel functions
IRAP: RIP ROP

Introduction

Return Address Protection

Indirect Control Transfer Protection

Introduction
Return Address Protection
Indirect Control Transfer Protection
HistoryType-Based Self-Assembling Indirect Control Flow Graph

RAP: RIP ROP

Return Address Protection

Introduction

Indirect Control Transfer Protection

History

Overview
I Deterministic defense
I PaX future doc 2003
I CFI at CCS 2005
I Many more variants since (IFCC, VTV)I Coarse-grained vs. fine-grained
I Fine grained approaches based on the Indirect Control FlowGraphII

Hard to construct (undecidable in the general case)Approximations
I

RAP: RIP ROP

RAP: Type-Based Self-Assembling Indirect Control FlowGraph

Return Address Protection

Introduction

History

Fine-Grained Control Flow Integrity
I Constructing the ICFG is hardII

Vertices are easy
Edges not so much
III

Missing edges result in false positives
Extra edges result in reduced security

Access to entire code
II

Dynamically loaded or generated code
LTO, load time/runtime construction

I Vertex categorization

Equivalence sets based on the ICFG
Argument count
I Type based
II

RAP: RIP ROP

Indirect Control Transfer Protection

Return Address Protection

Introduction

Indirect Control Transfer Protection

Type-Based Self-Assembling Indirect Control Flow GraphOverview
I Idea: construct the ICFG vertex categorization and have theICFG approximation emerge automatically
Overapproximate the ICFG as much as the language rules allow
Based on function and function pointer types
I False edges possible if unintended functions have the same typeIIII

Indirect call elimination (devirtualization, etc)
Type diversification

I Extract type information for each function and function

pointer
I Compute hash based on parts of the type
ILanguage construct dependent

I Verify matching hash value between function and function

pointer dereference (indirect call, function return, etc)
RAP: RIP ROP

Return Address Protection

Introduction

Indirect Control Transfer Protection

Type-Based Self-Assembling Indirect Control Flow Graph

Type Hash
I C functions and function pointers
I C++ functions and function pointers

Non-class functions
Static class member functions
I Non-virtual class member functions
I Virtual class member functions
II

I

Ancestor method that every other method overrides

I Type parts

Return type
Function name
I Function parameters
III

RAP: RIP ROP’this’ parameter for non-static class member functions

Indirect Control Transfer Protection

Return Address Protection

Introduction

Type-Based Self-Assembling Indirect Control Flow Graph

Type Hash Parts
Usable parts in type hash

ReturnName’this’Parameters

non-class or static member function/ptr

YNN/AYnon-virtual method/ptr

YNNYvirtual method/ptr

NN

NYancestor method/virtual method callYYYY

I C++ virtual method return types can be covariant
I C++ method pointers can target both virtual and non-virtualmethods
I Ancestor method type can supplant all overriding method

types in virtual calls
I Compiler internal representation or source language text

RAP: RIP ROP

Return Address Protection

Introduction

Indirect Control Transfer Protection

Type-Based Self-Assembling Indirect Control Flow Graph

Type Hash Details
I Any hash function will doI
I

Initial state allows for easy binary diversification/watermarking
Reduce output to desired size (e.g., 32 bits)

I Hash value range assignment:

Positive numbers for functions and function pointers
Negative numbers for function returns and return places
I Reserved value for functions whose address is not taken
I Reserved values for exception handling(setjmp/longjmp/landing pads)
II

I Store as 64 bits (full sign extended 32 bit value)
I Verify as sign extended 32 bit value

RAP: RIP ROP

Introduction

Return Address Protection

Type-Based Self-Assembling Indirect Control Flow Graph

Indirect function call examples
cmpq $0x11223344,-8(%rax)
jne .error
call *%rax...
cmpq $0x55667788,-16(%rax)
jne .error
call *%rax...
dq 0x55667788,0x11223344
func:

RAP: RIP ROP

Indirect Control Transfer Protection

Introduction

Return Address Protection

Type-Based Self-Assembling Indirect Control Flow Graph

Function return example
call ...
jmp 1fdq 0xffffffffaabbccdd
1:...
mov %(rsp),%rcx
cmpq $0xaabbccdd,2(%rcx)
jne .error
retn

RAP: RIP ROP

Indirect Control Transfer Protection

Return Address Protection

Introduction

Indirect Control Transfer Protection

Type-Based Self-Assembling Indirect Control Flow Graph

Compatibility
I Observation: everyone gets function pointer casts wrong :)Igcc(!), glibc, linux, chromium, etc

I Basic rule: function type must match function pointer typeused in the indirect callI

In-between casts to other function pointer types are allowedI

But almost everyone fails to convert back for the actual
indirect call

I Fixing these problems can uncover real bugsITwo birds with one stone: might as well do type diversification
while at it

I Call to arms to fix all of them :)I
RAP: RIP ROP

RAP related fixes

Introduction

Return Address Protection

Type-Based Self-Assembling Indirect Control Flow Graph

Compatibility examples
int (*fptr)(void *, int);
int func1(void *p, int i);
int func2(void *p);char func3(void *p, int i);
int func4(struct1 *p, int i);
fptr = &func1; //correct
fptr = &func2; //wrong
fptr = &func3; //wrong
fptr = &func4; //wrongRAP: RIP ROP

Indirect Control Transfer Protection

Return Address Protection

Introduction

Indirect Control Transfer Protection

Type-Based Self-Assembling Indirect Control Flow Graph

Performance
I Linux: both return address and function pointer protection
II

Less than 5% on ’du -s’Over 25% for ssp-all

I xalancbmk: used in SPECCPU but this was the latest

xalan-c/xerces-c available in gentoo
All dependencies with return address protection only (cf.
compatibility note before)
I Less than 4% on the SPEC reference test fileI

I chromium:

All dependencies with return address protection only (cf.
compatibility note before)
I Less than 8% on dromaeo javascript tests (big variations, someeven better than baseline)I

RAP: RIP ROP

Indirect Control Transfer Protection

Return Address Protection

Introduction

Type-Based Self-Assembling Indirect Control Flow Graph

Chromium 47.0.2526.16 Statistics

uniquenon-virtual

virtualuniquenon-virtual

virtualfunctions

235196159427indirect calls

10811

101552hashes

70498

44265

hashes

6467

29567

ratio (func/hash)

3.4

3.6

ratio (call/hash)

1.7

3.4

RAP: RIP ROP

Introduction

Return Address Protection

Indirect Control Transfer Protection

Type-Based Self-Assembling Indirect Control Flow Graph

Chromium 47.0.2526.16 Top Ancestors
4050 base::internal::BindStateBase<Diversifier>::~BindStateBase() [with Diversifier = void()]1976 virtual base::Pickle::~Pickle()
867 virtual blink::ScriptWrappable::~ScriptWrappable()
829 virtual ExtensionFunction::~ExtensionFunction()
707 virtual const blink::WrapperTypeInfo* blink::ScriptWrappable::wrapperTypeInfo() const
662 virtual google::protobuf::MessageLite::~MessageLite()
660 virtual int google::protobuf::MessageLite::GetCachedSize() const
660 virtual google::protobuf::MessageLite* google::protobuf::MessageLite::New() const
660 virtual void
google::protobuf::MessageLite::SerializeWithCachedSizes(google::protobuf::io::CodedOutputStream*)const
660 virtual bool
google::protobuf::MessageLite::MergePartialFromCodedStream(google::protobuf::io::CodedInputStream*)
660 virtual int google::protobuf::MessageLite::ByteSize() const
660 virtual void google::protobuf::MessageLite::Clear()
660 virtual bool google::protobuf::MessageLite::IsInitialized() const
637 virtual std::string google::protobuf::MessageLite::GetTypeName() const
637 virtual void google::protobuf::MessageLite::CheckTypeAndMergeFrom(const
google::protobuf::MessageLite&)
501 virtual ui::LayerDelegate::~LayerDelegate()

RAP: RIP ROP

Return Address Protection

Introduction

Indirect Control Transfer Protection

Type-Based Self-Assembling Indirect Control Flow Graph

Indirect Function Call Conversion (Devirtualization)

I Observation: some hash values get assigned to a single virtual

method in a program
IAll virtual method calls with the same hash can only resolve tothis one method
IDevirtualization opportunity missed by normal approaches

I Works for non-virtual methods and pointers too

RAP: RIP ROP

Return Address Protection

Introduction

Indirect Control Transfer Protection

Type-Based Self-Assembling Indirect Control Flow Graph

Summary
I RAP provides comprehensive indirect control flow protection
I Function returns
II

Return address encryption (XOR canary): probabilistic, precise
Return place type checking: deterministic, approximation

I Indirect calls
I

Call target type checking: deterministic, approximation

I Very low performance impact
I Scales to real world software

RAP: RIP ROPhttp://pax.grsecurity.nethttp://grsecurity.net
irc.oftc.net #pax #grsecurity