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

Similar documents
Lecture 08 Control-flow Hijacking Defenses

CS 161 Computer Security

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

CS 161 Computer Security

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

Lecture 10 Code Reuse

Architecture-level Security Vulnerabilities

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

CSE 509: Computer Security

CMPSC 497 Buffer Overflow Vulnerabilities

Q: Exploit Hardening Made Easy

String Oriented Programming Exploring Format String Attacks. Mathias Payer

(Early) Memory Corruption Attacks

Basic Buffer Overflows

Advanced Buffer Overflow

Architecture-level Security Vulnerabilities. Julian Stecklina

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

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

Assembly Language: Function Calls" Goals of this Lecture"

CSE 127: Computer Security Control Flow Hijacking. Kirill Levchenko

Betriebssysteme und Sicherheit Sicherheit. Buffer Overflows

CSC 2400: Computing Systems. X86 Assembly: Function Calls

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

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

Advanced Buffer Overflow

Buffer Overflows Defending against arbitrary code insertion and execution

From Over ow to Shell

Lecture 04 Control Flow II. Stephen Checkoway University of Illinois at Chicago CS 487 Fall 2017 Based on Michael Bailey s ECE 422

Lecture 07 Heap control data. Stephen Checkoway University of Illinois at Chicago

U23 - Binary Exploitation

Assembly Language: Function Calls

Software Security: Buffer Overflow Attacks (continued)

Università Ca Foscari Venezia

Software Security II: Memory Errors - Attacks & Defenses

BUFFER OVERFLOW DEFENSES & COUNTERMEASURES

Biography. Background

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

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

Assembly Language: Function Calls" Goals of this Lecture"

ROP It Like It s Hot!

CSc 466/566. Computer Security. 20 : Operating Systems Application Security

CS 161 Computer Security

18-600: Recitation #4 Exploits

Is stack overflow still a problem?

Exploiting Stack Buffer Overflows Learning how blackhats smash the stack for fun and profit so we can prevent it

Lecture 9: Buffer Overflow* CS 392/6813: Computer Security Fall Nitesh Saxena

Return-orientated Programming

Software Security: Buffer Overflow Defenses

Software Security: Buffer Overflow Attacks

Format string vulnerabilities

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

Writing your first windows exploit in less than one hour

Outline. Memory Exploit

Midterm 1 Review. Memory Safety & Web Attacks

Buffer Overflow and Protection Technology. Department of Computer Science,

Hacking Blind. Andrea Bittau, Adam Belay, Ali Mashtizadeh, David Mazières, Dan Boneh. Stanford University

On Compilers, Memory Errors and Control-Flow Integrity

Writing Exploits. Nethemba s.r.o.

6.858 Lecture 3. char *p = malloc(256); char *q = p + 256; char ch = *q; //Does this raise an exception? //Hint: How big is the baggy bound for p?

Robust Shell Code Return Oriented Programming and HeapSpray. Zhiqiang Lin

Reserve Engineering & Buffer Overflow Attacks. Tom Chothia Computer Security, Lecture 17

AS08-C++ and Assembly Calling and Returning. CS220 Logic Design AS08-C++ and Assembly. AS08-C++ and Assembly Calling Conventions

Memory Safety (cont d) Software Security

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

X86 Stack Calling Function POV

The first Secure Programming Laboratory will be today! 3pm-6pm in Forrest Hill labs 1.B31, 1.B32.

CNIT 127: Exploit Development. Ch 3: Shellcode. Updated

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

The Geometry of Innocent Flesh on the Bone

Return oriented programming

idkwim in SecurityFirst 0x16 years old Linux system security researcher idkwim.tistory.com idkwim.linknow.

CS 33 (Week 4) Section 1G, Spring 2015 Professor Eggert (TA: Eric Kim) v1.0

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

Secure Programming Lecture 6: Memory Corruption IV (Countermeasures)

Abstraction Recovery for Scalable Static Binary Analysis

Buffer Overflow Attacks

Lecture 05 Integer overflow. Stephen Checkoway University of Illinois at Chicago

CSE 127 Computer Security

New York University CSCI-UA : Advanced Computer Systems: Spring 2016 Midterm Exam

Software Vulnerabilities. Jeff Foster University of Maryland, College Park

Security and Privacy in Computer Systems. Lecture 5: Application Program Security

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

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

Buffer overflow risks have been known for over 30 years. Is it still a problem? Try searching at to see.

SYSTEM CALL IMPLEMENTATION. CS124 Operating Systems Fall , Lecture 14

Secure Programming Lecture 5: Memory Corruption III (Countermeasures)

CMPSC 497: Midterm Review

Exploits and gdb. Tutorial 5

Systems I. Machine-Level Programming V: Procedures

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

CSE 127 Computer Security

Lecture 6: Buffer Overflow. CS 436/636/736 Spring Nitesh Saxena

University of Washington

Software Vulnerabilities August 31, 2011 / CS261 Computer Security

Program Security and Vulnerabilities Class 2

CS 645: Lecture 3 Software Vulnerabilities. Rachel Greenstadt July 3, 2013

Buffer Overflows. Buffer Overflow. Many of the following slides are based on those from

Question 4.2 2: (Solution, p 5) Suppose that the HYMN CPU begins with the following in memory. addr data (translation) LOAD 11110

Machine-level Programming (3)

CPEG421/621 Tutorial

Transcription:

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

Last time No good reason for stack/heap/static data to be executable No good reason for code to be writable - An exception to this would be a JIT Data Execution Prevention (DEP) or W ^ X gives us exactly that - A page of memory can be writable - A page of memory can be executable - No page can ever be both - (Pages can be neither writable nor executable, of course)

Think like an attacker shellcode (aka payload) padding &buf computation + control We (as attackers) are now prevented from executing any injected code We still want to perform our computation We talked about how to bypass stack canaries last time, so let s ignore them for now and focus on bypassing DEP If we can t execute injected code, what code should we execute?

Existing code in binaries Program code itself Dynamic libraries - Google Chrome 61.0.3163.91 links to 99 dynamic libraries! - libc is linked into (almost) every program libc contains useful functions - system Run a shell command - mprotect Change the memory protection on a region of code

Return to libc (2libc) Rather than urning to our shellcode, let s urn to a standard library function like system We need to set the stack up precisely how system expects int system(const char *command);

Simple example Consider void foo(char *evil) { char buf[32]; evil saved eip saved ebp strcpy(buf, evil); } buf Let s overwrite the saved eip with the address of system evil &buf

Simple example Consider void foo(char *evil) { evil &system char buf[32]; strcpy(buf, evil); } buf Let s overwrite the saved eip with the address of system evil &buf

Simple example Consider void foo(char *evil) { evil &system char buf[32]; strcpy(buf, evil); } buf Let s overwrite the saved eip with the address of system system takes one argument, a pointer to the command string; where does it go? evil &buf

Back to basics Imagine we called system directly via system(command); Look at the stack layout before the first instruction in system command saved eip As usual, the first argument is at esp + 4

Simple example Consider void foo(char *evil) { evil &system char buf[32]; strcpy(buf, evil); } buf Let s overwrite the saved eip with the address of system system takes one argument, a pointer to the command string; where does it go? esp + 4 after the evil &buf

Simple example pops the address of system off the stack and into eip leaving the stack pointer pointing at the first evil evil &system 4 bytes above that should be our pointer to the command string buf evil &buf

Simple example pops the address of system off the stack and into eip leaving the stack pointer pointing at the first evil &cmd string??? &system 4 bytes above that should be our pointer to the command string Where should we put the command string "sh" itself? - In buf? - Above the pointer to the command string? buf evil &buf

Simple example pops the address of system off the stack and into eip leaving the stack pointer pointing at the first evil "sh" &cmd string??? &system 4 bytes above that should be our pointer to the command string Where should we put the command string "sh" itself? - In buf? - Above the pointer to the command string? buf evil &buf

Simple example When system urns, it'll urn to the address on the stack at esp (the???) "sh" &cmd string??? &system This will likely crash unless we pick a good value to put there buf evil &buf

Simple example When system urns, it'll urn to the address on the stack at esp (the???) "sh" &cmd string &exit &system This will likely crash unless we pick a good value to put there The address of exit is a good choice Now when system urns, the program will exit buf evil &buf

Injecting code We cannot run injected code directly, but we can first make it executable by calling mprotect int mprotect(void *addr, size_t len, int prot); code RWX code_len &code &code &mprotect This can be tricky since there are likely to be zero bytes - Use memcpy instead of strcpy - Use urn-oriented programming (next class)

Injecting code Return to mprotect code RWX code_len &code &code &mprotect

Injecting code Return to mprotect - Increments esp by 4 - Runs mprotect making the injected code executable - Modifies the stack below esp code RWX code_len &code &code

Injecting code Return to mprotect - Increments esp by 4 - Runs mprotect making the injected code executable - Modifies the stack below esp Return from mprotect to code code RWX code_len &code &code

Injecting code Return to mprotect - Increments esp by 4 - Runs mprotect making the injected code executable - Modifies the stack below esp Return from mprotect to code - Increments esp by 4 - Runs code eip! code RWX code_len &code &code

Chaining functions We can chain two functions together if - the first has one argument and the second any number of arguments g argn... g arg2 g arg1 f arg1 &g &f

Chaining functions We can chain two functions together if - the first has one argument and the second any number of arguments; or - the first has any number of arguments and the second has none f argn... f arg2 f arg1 &g &f

Chaining functions We can chain two functions together if - the first has one argument and the second any number of arguments; or - the first has any number of arguments and the second has none We can start with any number of zero argument functions for either case f argn... f arg2 f arg1 &g &f &funm... &fun2 &fun1 g argn... g arg2 g arg1 f arg1 &g &f &funm... &fun2 &fun1

Cleaning up between z What if we want to chain the four function calls fun1(t), fun2(u,v), fun3(w,x,y), fun4(z)? Identify pieces of code that clean up the stack and urn to those between function calls Examples: - ; - popl %ebx; ; - addl $16, %esp; &fun4 y x w &fun3 v u &fun2 t &fun1 addl $16, %esp popl %ebx

Running 1. Return to fun1 z &fun4 y x w &fun3 v u &fun2 t &fun1 addl $16, %esp popl %ebx

Running 1. Return to fun1 which runs, modifies stack z &fun4 y x w &fun3 v u &fun2 t addl $16, %esp popl %ebx

Running z 1. Return to fun1 which runs, modifies stack &fun4 2. Return to pop; y x w &fun3 v u &fun2 t addl $16, %esp popl %ebx eip

Running z 1. Return to fun1 which runs, modifies stack &fun4 2. Return to pop; y x w &fun3 v u &fun2 t addl $16, %esp popl %ebx eip

Running z 1. Return to fun1 which runs, modifies stack &fun4 2. Return to pop; 3. Return to fun2 y x w &fun3 v u &fun2 t addl $16, %esp popl %ebx

Running z 1. Return to fun1 which runs, modifies stack &fun4 2. Return to pop; 3. Return to fun2 which runs, modifies stack y x w &fun3 v u addl $16, %esp popl %ebx

Running z 1. Return to fun1 which runs, modifies stack &fun4 2. Return to pop; 3. Return to fun2 which runs, modifies stack 4. Return to pop; pop; y x w &fun3 v u addl $16, %esp popl %ebx eip

Running z 1. Return to fun1 which runs, modifies stack &fun4 2. Return to pop; 3. Return to fun2 which runs, modifies stack 4. Return to pop; pop; y x w &fun3 v u addl $16, %esp popl %ebx eip

Running z 1. Return to fun1 which runs, modifies stack &fun4 2. Return to pop; 3. Return to fun2 which runs, modifies stack 4. Return to pop; pop; y x w &fun3 v u addl $16, %esp popl %ebx eip

Running z 1. Return to fun1 which runs, modifies stack &fun4 2. Return to pop; 3. Return to fun2 which runs, modifies stack 4. Return to pop; pop; 5. Return to fun3 y x w &fun3 v u addl $16, %esp popl %ebx

Running z 1. Return to fun1 which runs, modifies stack &fun4 2. Return to pop; 3. Return to fun2 which runs, modifies stack 4. Return to pop; pop; y x w addl $16, %esp 5. Return to fun3 which runs, modifies stack popl %ebx

Running z 1. Return to fun1 which runs, modifies stack &fun4 2. Return to pop; 3. Return to fun2 which runs, modifies stack 4. Return to pop; pop; y x w eip addl $16, %esp 5. Return to fun3 which runs, modifies stack 6. Return to add; popl %ebx

Running 1. Return to fun1 which runs, modifies stack z &fun4 2. Return to pop; 3. Return to fun2 which runs, modifies stack 4. Return to pop; pop; 5. Return to fun3 which runs, modifies stack 6. Return to add; y x w addl $16, %esp popl %ebx eip

Running 1. Return to fun1 which runs, modifies stack z &fun4 2. Return to pop; 3. Return to fun2 which runs, modifies stack 4. Return to pop; pop; 5. Return to fun3 which runs, modifies stack 6. Return to add; 7. Return to fun4 y x w addl $16, %esp popl %ebx

Running z 1. Return to fun1 which runs, modifies stack 2. Return to pop; 3. Return to fun2 which runs, modifies stack 4. Return to pop; pop; addl $16, %esp 5. Return to fun3 which runs, modifies stack 6. Return to add; 7. Return to fun4 which runs, modifies stack popl %ebx

Running z 1. Return to fun1 which runs, modifies stack 2. Return to pop; 3. Return to fun2 which runs, modifies stack 4. Return to pop; pop; addl $16, %esp 5. Return to fun3 which runs, modifies stack 6. Return to add; 7. Return to fun4 which runs, modifies stack 8. Et cetera popl %ebx

Cleanup code Two key pieces - Stack modification (pop or add esp). Modifies the stack pointer to move over the arguments to the function - Return at the end. Returns to the next function whose address is on the stack Together, this lets us chain a more or less arbitrary number of function calls with constant parameters - Depends on how much stack space we have (but we can change the stack pointer via a sequence like xchgl %eax, %esp; ) - Depends on what cleanup code we can find in the program/libraries (turns out there's a whole lot there)

Next time There's no need to limit ourselves to urning to functions and cleanup code We can encode arbitrary computation (including conditionals and loops) by urning to sequences of code ending in