Advanced Systems Security: Control-Flow Integrity

Similar documents
CMPSC 497 Execution Integrity

Project 1 Buffer Overflow

Module: Return-oriented Programming. Professor Trent Jaeger. CSE543 - Introduction to Computer and Network Security

Module: Return-oriented Programming. Professor Trent Jaeger. CSE543 - Introduction to Computer and Network Security

Module: Advanced Program Vulnerabilities and Defenses. Professor Trent Jaeger. CSE543 - Introduction to Computer and Network Security

CMPSC 497 Buffer Overflow Vulnerabilities

Advanced Systems Security: Program Diversity

This time. Defenses and other memory safety vulnerabilities. Everything you ve always wanted to know about gdb but were too afraid to ask

Return-orientated Programming

Q: Exploit Hardening Made Easy

CSE 509: Computer Security

Software Security: Buffer Overflow Defenses

Software Security: Buffer Overflow Attacks

String Oriented Programming Exploring Format String Attacks. Mathias Payer

Control-Flow Bending: On the Effectiveness of Control-Flow Integrity

CMPSC 497: Midterm Review

CSE 127 Computer Security

CS 161 Computer Security

Lecture 10 Return-oriented programming. Stephen Checkoway University of Illinois at Chicago Based on slides by Bailey, Brumley, and Miller

Advanced Systems Security: Ordinary Operating Systems

Static Analysis. Systems and Internet Infrastructure Security

Basic Buffer Overflows

Advanced Buffer Overflow

EECE.3170: Microprocessor Systems Design I Summer 2017 Homework 4 Solution

2 Sadeghi, Davi TU Darmstadt 2012 Secure, Trusted, and Trustworthy Computing Chapter 6: Runtime Attacks

Midterm 1 Review. Memory Safety & Web Attacks

18-600: Recitation #4 Exploits

CNIT 127: Exploit Development. Ch 1: Before you begin. Updated

BUFFER OVERFLOW DEFENSES & COUNTERMEASURES

CSE 127: Computer Security Control Flow Hijacking. Kirill Levchenko

CSE 127 Computer Security

CSE 127 Computer Security

Software Security II: Memory Errors - Attacks & Defenses

Module: Program Vulnerabilities. Professor Trent Jaeger. CSE543 - Introduction to Computer and Network Security

Advanced Buffer Overflow

This exam contains 7 pages (including this cover page) and 4 questions. Once we tell you to start, please check that no pages are missing.

Software Security: Buffer Overflow Attacks (continued)

Stephen Checkoway, Lucas Davi, Alexandra Dmitrienko, Ahmad-Reza Sadeghi, Hovav Shacham, Marcel Winandy. ACM CCS 2010, Chicago, USA

Assembly Language: Function Calls. Goals of this Lecture. Function Call Problems

Assembly Language: Function Calls" Goals of this Lecture"

Function Calls COS 217. Reading: Chapter 4 of Programming From the Ground Up (available online from the course Web site)

CSE 127 Computer Security

Stack Vulnerabilities. CS4379/5375 System Security Assurance Dr. Jaime C. Acosta

Linux Memory Layout. Lecture 6B Machine-Level Programming V: Miscellaneous Topics. Linux Memory Allocation. Text & Stack Example. Topics.

Selected background on ARM registers, stack layout, and calling convention

Module: Program Vulnerabilities. Professor Trent Jaeger. CSE543 - Introduction to Computer and Network Security

Advanced Security for Systems Engineering VO 05: Advanced Attacks on Applications 2

On Compilers, Memory Errors and Control-Flow Integrity

CSC 2400: Computing Systems. X86 Assembly: Function Calls"

Exploits and gdb. Tutorial 5

Is stack overflow still a problem?

Robust Shell Code Return Oriented Programming and HeapSpray. Zhiqiang Lin

18-600: Recitation #4 Exploits (Attack Lab)

Countermeasures in Modern Operating Systems. Yves Younan, Vulnerability Research Team (VRT)

CSC 591 Systems Attacks and Defenses Return-into-libc & ROP

Function Call Convention

CS 161 Computer Security

Software Vulnerabilities. Jeff Foster University of Maryland, College Park

Module: Program Vulnerabilities. Professor Trent Jaeger. CSE543 - Introduction to Computer and Network Security

CSC 2400: Computing Systems. X86 Assembly: Function Calls

CPEG421/621 Tutorial

Secure Programming Lecture 3: Memory Corruption I (Stack Overflows)

Betriebssysteme und Sicherheit Sicherheit. Buffer Overflows

Memory Corruption: Why Protection is Hard. Mathias Payer, Purdue University

CMPSC 497: Static Analysis

On The Effectiveness of Address-Space Randomization. H. Shacham, M. Page, B. Pfaff, E.-J. Goh, N. Modadugu, and D. Boneh Stanford University CCS 2004

Assembly Language: Function Calls

Stitching the Gadgets: On the Ineffectiveness of Coarse-Grained Control-Flow Integrity Protection. Accepted at USENIX Security 2014

Beyond Stack Smashing: Recent Advances in Exploiting. Jonathan Pincus(MSR) and Brandon Baker (MS)

Runtime attacks are major threats to today's applications Control-flow of an application is compromised at runtime Typically, runtime attacks include

Lecture 08 Control-flow Hijacking Defenses

CMPSC 497 Other Memory Vulnerabilities

CSC 405 Computer Security Stack Canaries & ASLR

Assembly Language: Function Calls" Goals of this Lecture"

Practical Malware Analysis

The Geometry of Innocent Flesh on the Bone

Return Oriented Programming

Architecture-level Security Vulnerabilities

CS 161 Computer Security. Week of January 22, 2018: GDB and x86 assembly

Buffer-Overflow Attacks on the Stack

P-TAXI: Enforcing Memory Safety with Programmable Tagged Architecture. Witchakorn Kamolpornwijit

Buffer Overflow Attack (AskCypert CLaaS)

Buffer-Overflow Attacks on the Stack

I Control Your Code Attack Vectors through the Eyes of Software-based Fault Isolation. Mathias Payer

Inject malicious code Call any library functions Modify the original code

Security Workshop HTS. LSE Team. February 3rd, 2016 EPITA / 40

Outline. Memory Exploit

Outline. Format string attack layout. Null pointer dereference

Return oriented programming

Department of Electrical Engineering and Computer Science MASSACHUSETTS INSTITUTE OF TECHNOLOGY Fall Quiz I

Program Exploitation Intro

Department of Electrical Engineering and Computer Science MASSACHUSETTS INSTITUTE OF TECHNOLOGY Fall Quiz I Solutions

CNIT 127: Exploit Development. Ch 2: Stack Overflows in Linux

Native Language Exploitation

Advanced Systems Security: Ordinary Operating Systems

How Software Executes

Lecture 09 Code reuse attacks. Stephen Checkoway University of Illinois at Chicago CS 487 Fall 2017

Introduction to Reverse Engineering. Alan Padilla, Ricardo Alanis, Stephen Ballenger, Luke Castro, Jake Rawlins

CS61, Fall 2012 Midterm Review Section

Vulnerability Analysis I:

Transcription:

Systems and Internet Infrastructure Security Network and Security Research Center Department of Computer Science and Engineering Pennsylvania State University, University Park PA Advanced Systems Security: Control-Flow Integrity Trent Jaeger Systems and Internet Infrastructure Security (SIIS) Lab Computer Science and Engineering Department Pennsylvania State University Page 1

Quiz Questions 1 Why randomize code layout with ASLR (one reason)? 2 Why randomize data layout with ASLR given DEP (one reason)? 3 What are indirect memory disclosures? Page 2

Vulnerability How do you define computer vulnerability? Page 3

Buffer Overflow First and most common way to take control of a process Attack code Call the victim with inputs necessary to overflow buffer Overwrites the urn address on the stack Exploit Jump to attacker chosen code Run that code Page 4

Determine what to attack Local variable that is a char buffer Called buf... printf("before picture of stack\n"); for ( i=((unsigned) buf-8); i<((unsigned) ((char *)&ct)+8); i++ ) printf("%p: 0x%x\n", (void *)i, *(unsigned char *) i); /* run overflow */ for ( i=1; i<tmp; i++ ){ printf("i = %d; tmp= %d; ct = %d; &tmp = %p\n", i, tmp, ct, (void *)&tmp); strcpy(p, inputs[i]); /* print stack after the fact */ printf("after iteration %d\n", i); for ( j=((unsigned) buf-8); j<((unsigned) ((char *)&ct)+8); j++ ) printf("%p: 0x%x\n", (void *)j, *(unsigned char *) j); p += strlen(inputs[i]); if ( i+1!= tmp ) *p++ = ' '; } printf("buf = %s\n", buf); printf("victim: %p\n", (void *)&victim); urn 0; } BEFORE picture of stack 0xbfa3b854: 0x3 0xbfa3b855: 0x0 0xbfa3b856: 0x0 0xbfa3b857: 0x0 0xbfa3b858: 0x3 0xbfa3b859: 0x0 0xbfa3b85a: 0x0 0xbfa3b85b: 0x0 0xbfa3b85c: 0x0 0xbfa3b85d: 0x0 0xbfa3b85e: 0x0 0xbfa3b85f: 0x0 0xbfa3b860: 0x0 0xbfa3b861: 0x0 0xbfa3b862: 0x0 0xbfa3b863: 0x0 0xbfa3b864: 0x0 0xbfa3b865: 0x0 0xbfa3b866: 0x0 0xbfa3b867: 0x0 0xbfa3b868: 0xa8 0xbfa3b869: 0xb8 0xbfa3b86a: 0xa3 0xbfa3b86b: 0xbf 0xbfa3b86c: 0x71 0xbfa3b86d: 0x84 0xbfa3b86e: 0x4 0xbfa3b86f: 0x8 0xbfa3b870: 0x3 0xbfa3b871: 0x0 0xbfa3b872: 0x0 ct 0xbfa3b873: 0x0 buf ebp rtn addr Page 5

Configure Attack Configure following Distance to urn address from buffer Where to write? Location of start of attacker s code Where to take control? What to write on stack How to invoke code (jump-to existing function)? How to launch the attack How to send the malicious buffer to the victim? Page 6

Return Address x86 Architecture Build 32-bit code for Linux environment Remember integers are represented in little endian format Take address 0x8048471 See trace at right BEFORE picture of stack 0xbfa3b854: 0x3 0xbfa3b855: 0x0 0xbfa3b856: 0x0 0xbfa3b857: 0x0 0xbfa3b858: 0x3 0xbfa3b859: 0x0 0xbfa3b85a: 0x0 0xbfa3b85b: 0x0 0xbfa3b85c: 0x0 0xbfa3b85d: 0x0 0xbfa3b85e: 0x0 0xbfa3b85f: 0x0 0xbfa3b860: 0x0 0xbfa3b861: 0x0 0xbfa3b862: 0x0 0xbfa3b863: 0x0 0xbfa3b864: 0x0 0xbfa3b865: 0x0 0xbfa3b866: 0x0 0xbfa3b867: 0x0 0xbfa3b868: 0xa8 0xbfa3b869: 0xb8 0xbfa3b86a: 0xa3 0xbfa3b86b: 0xbf 0xbfa3b86c: 0x71 0xbfa3b86d: 0x84 0xbfa3b86e: 0x4 0xbfa3b86f: 0x8 0xbfa3b870: 0x3 0xbfa3b871: 0x0 0xbfa3b872: 0x0 ct 0xbfa3b873: 0x0 buf ebp rtn addr Page 7

Anatomy of Control Flow Attacks Two steps First, the attacker changes the control flow of the program In buffer overflow, overwrite the urn address on the stack What are the ways that this can be done? Second, the attacker uses this change to run code of their choice In buffer overflow, inject code on stack What are the ways that this can be done? Page 10

Return-oriented Programming General approach to control flow attacks Demonstrates how general the two steps of a control flow attack can be First, change program control flow In any way Then, run any code of attackers choosing - code in the existing program From starting address (gadget) to Page 11

ROP Use ESP as program counter E.g., Store 5 at address 0x8048000 without introducing new code Code pop %eax pop %ebx movl %eax, (%ebx) Registers %eax = %ebx = Stack G1 5 jmp G2 0x8048000 jump G3... Memory 0x8048000 = Return Address buf Page

ROP Use ESP as program counter E.g., Store 5 at address 0x8048000 without introducing new code Code G!: pop %eax G2: pop %ebx G3: movl %eax, (%ebx) Registers %eax = %ebx = Stack G1 5 jmp G2 0x8048000 jump G3... Memory 0x8048000 = Return Address buf Page

ROP Use ESP as program counter E.g., Store 5 at address 0x8048000 without introducing new code Code G!: pop %eax G2: pop %ebx G3: movl %eax, (%ebx) Registers %eax = %ebx = Stack G1 5 jmp G2 0x8048000 jump G3... Memory 0x8048000 = Return Address buf Page

ROP Use ESP as program counter E.g., Store 5 at address 0x8048000 without introducing new code Code G!: pop %eax G2: pop %ebx G3: movl %eax, (%ebx) Registers %eax = 5 %ebx = Stack G1 5 jmp G2 0x8048000 jump G3... Memory 0x8048000 = Return Address buf Page

ROP Use ESP as program counter E.g., Store 5 at address 0x8048000 without introducing new code Code G!: pop %eax G2: pop %ebx G3: movl %eax, (%ebx) Registers %eax = 5 %ebx = Stack G1 5 jmp G2 0x8048000 jump G3... Memory 0x8048000 = Return Address buf Page

ROP Use ESP as program counter E.g., Store 5 at address 0x8048000 without introducing new code Code G!: pop %eax G2: pop %ebx G3: movl %eax, (%ebx) Registers %eax = 5 %ebx = 0x8048000 Stack G1 5 jmp G2 0x8048000 jump G3... Memory 0x8048000 = Return Address buf Page

ROP Use ESP as program counter E.g., Store 5 at address 0x8048000 without introducing new code Code G!: pop %eax G2: pop %ebx G3: movl %eax, (%ebx) Registers %eax = 5 %ebx = 0x8048000 Stack G1 5 jmp G2 0x8048000 jump G3... Memory 0x8048000 = Return Address buf Page

ROP Use ESP as program counter E.g., Store 5 at address 0x8048000 without introducing new code Code G!: pop %eax G2: pop %ebx G3: movl %eax, (%ebx) Registers %eax = 5 %ebx = 0x8048000 Stack G1 5 jmp G2 0x8048000 jump G3... Memory 0x8048000 = 5 Return Address buf Page

Prevent ROP Attacks How would you prevent a program from executing gadgets rather than the expected code? Page 20

Prevent ROP Attacks How would you prevent a program from executing gadgets rather than the expected code? Control-flow integrity Force the program to execute according to an expected CFG Page 21

Control-Flow Integrity Our Mechanism F A F B nop IMM 1 if(*fp!= nop IMM 1 ) halt call fp nop IMM 2 if(**esp!= nop IMM 2 ) halt urn CFG excerpt NB: Need to ensure bit patterns for nops appear nowhere else in code memory A call A call+1 B 1 B Page 22

Control-Flow Integrity More Complex CFGs Maybe statically all we know is that F A can call any int int function F A CFG excerpt A call B 1 C 1 F B succ(a call ) = {B 1, C 1 } if(*fp!= nop IMM 1 ) halt call fp nop IMM 1 F C nop IMM 1 Construction: All targets of a computed jump must have the same destination id (IMM) in their nop instruction 9 Page 23

Control-Flow Integrity Imprecise Return Information F A call F B nop IMM 2 Q: What if F B can urn to many functions? A: Imprecise CFG F B CFG excerpt A call+1 B D call+1 succ(b ) = {A call+1, D call+1 } F D call F B nop IMM 2 if(**esp!= nop IMM 2 ) halt urn CFG Integrity: Changes to the PC are only to valid successor PCs, per succ(). 10 Page 24

Destination Equivalence Eliminate impossible urn targets Two destinations are said to be equivalent if connect to a common source in the CFG. func_i: call R1: %eax call func_i R2: func_j: call func_j R3: Figure 4. Destination equivalence effect on instructions (a dashed line represents an indirect call while a solid line stands for a direct call) Page 25

Destination Equivalence Eliminate impossible urn targets Can R2 be a urn target of function_j? func_i: call R1: %eax call func_i R2: func_j: call func_j R3: Figure 4. Destination equivalence effect on instructions (a dashed line represents an indirect call while a solid line stands for a direct call) Page 26

Control-Flow Integrity No Zig-Zag Imprecision Solution I: Allow the imprecision CFG excerpt A call B 1 Solution II: Duplicate code to remove zig-zags CFG excerpt A call B 1 C 1 C 1A E call E call C 1E Page 27

Restricted Pointer Indexing One table for call and urn for each function Call Site i call *%eax Ri:...... eax Target Table j Ri Target Table i func_j [esp] Callee j func_j: Why can t function_j urn to R2 with this approach? Page 28

Control-Flow Graph CFI enforces an expected CFG Each call-site transfers to expected instruction Each urn transfers back to expected call-site Direct calls Call instructions targeted for specific instruction no problem Indirect calls Function pointers what are the possible targets? Returns Determine urn target dynamically can be overwritten Can we compute an accurate CFG? Page 29

Enforce CFG Challenge in computing an enforceable CFG Targets computed dynamically, so how can we predict in advance and without generating any false positives Coarse-grained CFG Any function is a legal indirect call target (ICT) Any call-site is a legal urn target Signature-based Function with same signature as call-site is a valid ICT Taint-based Track function symbols that can reach a ICT Page 30

Taint-based CFG If function pointers are used in a restricted way, we can predict the indirect call targets using taint analysis Assumption 1: The only allowed operations on a function pointer variable are assignment and dereferencing (for call) Assumption 2: There exist no data pointer to a function pointer int (*fp)() void *ptr struct X int field0 int (*fp1)() int (*fp2)() int foo(void) {... urn x; } int (*ar[])() [0] [1] [2] int bar(void) {... urn y; } FreeBSD and MINIX largely follow these assumptions Page 31

Shadow Stack Method for maintaining urn targets for each function call reliably On call Push urn address on the regular stack Also, push the urn address on the shadow stack On urn Validate the urn address on the regular stack with the urn address on the shadow stack Why might this work? Normal program code cannot modify the shadow stack memory directly Page 32

Other Problems with CFI CFI enforcement can be expensive Idea: only check CFI lazily kbouncer inspects the last 16 indirect branches taken each time the program invokes a system call Why 16? Uses Intel s Last Branch Record (LBR), which can store 16 records ROPecker also checks forward for future gadget sequences (short sequences ending in indirection) These hacks do not work See papers in USENIX Security 2014 for attacks against Bottom line no shortcuts Page 33

Control-Flow Bending Do we need a shadow stack? After applying coarse-grained CFG AIR Gadget red. Targets Gadgets No CFI 0% 0% 1850580 128929 CFI 99.06% 98.86% 19611 1462 Table 1: Basic metrics for the minimal vulnerable program under no CFI and our coarse-grained CFI policy. Still lots of choices and gadgets Page 34

Control-Flow Bending Do we need a shadow stack? After applying precise CFG Problem: Dispatcher functions A function that can overwrite its urn address when given adversary controlled input argument values Even with buffer overflow protection (stackguard) E.g., consider memcpy How would you use a dispatcher function to control execution while evading CFI? Page 35

Control-Flow Bending Do we need a shadow stack? After applying precise CFG Problem: Dispatcher functions A function that can overwrite its urn address when given adversary controlled input argument values Even with buffer overflow protection (stackguard) E.g., consider memcpy How would you block a dispatcher function from launching an ROP? Page 36

Control-Flow Bending If we have a fine-grained CFG and a shadow stack are we safe from control-flow bending? Page 37

Control-Flow Bending If we have a fine-grained CFG and a shadow stack are we safe from control-flow bending? Unfortunately, no. Turing-complete functions A function that has a memory read and memory write A conditional jumps and loops Examples of these functions printf fputs Page 38

Take Away Memory errors are the classic vulnerabilities in C programs (buffer overflow) Despite years of exploration into defenses, a Turingcomplete approach to exploitation remains given an appropriate memory error (urn-oriented programming) Control-flow integrity has been suggested as the way to block ROP attacks Not as easy as it sounds CFI enforcement requires a fine-grained CFG and shadow stack (or equivalent) Yet, still some ROP attacks are possible (bending) Page 39