50
Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion Return-oriented programming Sebastian Neuser Hackspace Siegen May 8, 2014 Return-oriented programming Sebastian Neuser

Return oriented programming

  • Upload
    hybr1s

  • View
    552

  • Download
    0

Embed Size (px)

DESCRIPTION

**Return-oriented programming** bezeichnet eine gewiefte IT-Angriffstechnik, die im Prinzip eine Verallgemeinerung von *return-to-libc*-Attacken ist, welche wiederum zu den *stack buffer overflow exploits* gehören. Wem das alles nichts sagt - keine Angst: Im Vortrag werden zunächst die Grundlagen von Puffer-Überläufen und deren Angriffspotential erläutert und einige historische Beispiele aufgezeigt, bevor schrittweise die Brücke zu **ROP** geschlagen wird. Zum Abschluss werden kurz einige Abwehrmaßnahmen vorgestellt und im Hinblick auf Umsetzbarkeit und Wirkungsgrad bewertet. So die Demo-Götter es wollen, wird live u.A. ein Beispiel-Programm mithilfe von **ROP**-Tools gecrackt.

Citation preview

Page 1: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

Return-oriented programming

Sebastian Neuser

Hackspace Siegen

May 8, 2014

Return-oriented programming Sebastian Neuser

Page 2: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

1 IntroductionWhat is return-oriented programming?Before we begin...ExamplesHistory

2 Return-oriented programming in a nutshellx86 crash courseStack buffer overflowGadgets

Return-oriented programming Sebastian Neuser

Page 3: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

3 DemonstrationROPgadget – a ROP compilerStupid vulnerable programShowtime!

4 CountermeasuresASLR and PIEStack canaries and shadow stacksCFI and ROPdefender

5 Conclusion

Return-oriented programming Sebastian Neuser

Page 4: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

1 IntroductionWhat is return-oriented programming?Before we begin...ExamplesHistory

2 Return-oriented programming in a nutshell

3 Demonstration

4 Countermeasures

5 Conclusion

Return-oriented programming Sebastian Neuser

Page 5: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

What is return-oriented programming?

Buffer overflow vulnerabilities

simple example:

• fixed size character buffer

• program reads a string from the keyboard and copies it to thebuffer without bounds checking

• number of input characters > buffer size ; buffer overflow

• variables on the stack are overwritten – possibly including thecurrent function’s return address

• best case scenario: SIGSEGV

Return-oriented programming Sebastian Neuser

Page 6: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

What is return-oriented programming?

Return-oriented programming

• generalization of return-to-libc exploitation

• attacker uses buffer overflow-vulnerability or something similarto inject return addresses into the stack

• return-to-libc-exploits chain together calls to libraryfunctions (libc in most cases)

• return-oriented exploits jump a few instructions before afunction’s ret to perform small operations

By carefully chaining together such jumps, an attacker can performarbitrary computations!

Return-oriented programming Sebastian Neuser

Page 7: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

What is return-oriented programming?

Why care?

• 45% of all recorded security vulnerabilities in Ubuntu:; buffer overflow vulnerabilities

• buffer overflow exploits have been implemented in numerousmalicious programs across different platforms

• Return-oriented programming:• probably the most advanced buffer overflow exploitation

technique so far• developed and refined over decades

Return-oriented programming Sebastian Neuser

Page 8: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

Before we begin...

Terms of service

• Although I don’t intend to, unfortunately I tend to• become overzealous,• talk too fast and• speak with a slur.

; Please insult me, if I do!

• By sitting here and listening to the talk, you agree that• you will not use the knowledge provided here to harm anyone,• I am not responsible for anything you break while messing

around with the techniques I present,• vim is the name of the one true editor,• proprietary software is inherently evil.

• Feel free to ask questions at any time.

Return-oriented programming Sebastian Neuser

Page 9: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

Before we begin...

Stack diagrams

Stack diagrams are depicted from the stack’s top to bottom:

pointers addresses values

stack top 0xbf8c73c0:

0xbf8c73c4:

0xbf8c73c8:

0x1337c0de

0xdeadc0de

0xdeadbeef

Return-oriented programming Sebastian Neuser

Page 10: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

Before we begin...

Platform

Examples and demo compiled and tested with

• gcc version 4.7.2

• gdb version 7.4.1

• 32 bit Debian GNU/Linux 7.1; instruction set architecture: IA-32

• Intel Core 2 Duo P7450

Return-oriented programming Sebastian Neuser

Page 11: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

Examples

Computer worms

• The Morris worm aka. ”Great Worm”• utilized a buffer overflow-vulnerability in the fingerd program

on Unix systems• rendered infected systems unusable within 90 minutes

• The Slammer worm• used buffer overflow-vulnerabilities in Microsoft’s ”SQL Server

2000” and ”Desktop Engine 2000”• infected roughly 75000 servers in approximately 30 minutes• caused network overloads on a great scale

• The Sasser worm• exploited a vulnerability in Microsoft’s LSASS• caused systems to shut down

Return-oriented programming Sebastian Neuser

Page 12: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

History

Timeline of buffer overflow exploits

1988 Morris worm

1996 Aleph One: ”Smashing The Stack For Fun And Profit”

1997 Solar Designer: return-to-libc basics

1998 Solar Designer: security patch for the Linux kernel

2000 PaX: Implementation of W⊕X2001 Nergal: function chaining with return-to-libc

2007 Hovav Shacham: ”Return-into-libc without function calls”; return-oriented programming

since more and more proof, that return-oriented programming is areal threat

Return-oriented programming Sebastian Neuser

Page 13: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

1 Introduction

2 Return-oriented programming in a nutshellx86 crash courseStack buffer overflowGadgets

3 Demonstration

4 Countermeasures

5 Conclusion

Return-oriented programming Sebastian Neuser

Page 14: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

x86 crash course

Register set

%eax holds the return value of a function call.

%ebx holds a pointer to some data.

%ecx is used for counters in string- and loop instructions.

%edx holds a I/O pointers.

%esi is the source pointer in some instructions.

%edi is the destination pointer in some instructions.

%ebp is the stack frame- or base pointer.

%esp is the stack pointer.

%eip is the instruction pointer.

%eflags is the status and control register.

Return-oriented programming Sebastian Neuser

Page 15: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

x86 crash course

Instruction set

mov %esp, %ebp Copies the stack pointer %esp to the basepointer %ebp.

push %ebp Updates the stack pointer %esp and writesthe value of %ebp to the new top of the stack.

pop %ebp Reads the value at the top of the stack – thememory location that %esp points to, writesit into %ebp and discards the value from thestack by adjusting %esp.

call func Pushes the return address, which is the ad-dress of the next instruction (%eip+5) ontothe stack and jumps to the instruction la-beled by ”func:”.

ret Pops the return address from the top of thestack and writes it into %eip.

Return-oriented programming Sebastian Neuser

Page 16: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

x86 crash course

The stack

• data section in a process’ address space

• contains local variables and buffers

• arguments to function calls and return addresses are alsoimplemented using the stack

• x86 -family of CPUs:• stack grows from higher to lower memory addresses• memory is addressed byte-wise

; push decrements %esp by 4, pop increments %esp by 4

Return-oriented programming Sebastian Neuser

Page 17: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

x86 crash course

Function calls – cdecl

• parameters are pushed to the stack in reverse order

• call pushes the address of the next instruction onto the stack

• function prologue (enter):• save the base pointer %ebp• copy %esp to %ebp for base pointer addressing• decrement %esp to allocate stack memory for local variables

• function epilogue (leave):• discard local variables by copying %ebp to %esp• restore %ebp by popping it from the stack

• ret pops the return address off the stack and jumps to it

Return-oriented programming Sebastian Neuser

Page 18: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

x86 crash course

Function calls – stack diagram

%esp

%ebp

0xbf8c73d0:

0xbf8c73d4:

local var 0

saved %ebp

Return-oriented programming Sebastian Neuser

Page 19: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

x86 crash course

Function calls – stack diagram

%esp

%ebp

0xbf8c73cc:

0xbf8c73d0:

0xbf8c73d4:

parameter 2

local var 0

saved %ebp

Return-oriented programming Sebastian Neuser

Page 20: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

x86 crash course

Function calls – stack diagram

%esp

%ebp

0xbf8c73c8:

0xbf8c73cc:

0xbf8c73d0:

0xbf8c73d4:

parameter 1

parameter 2

local var 0

saved %ebp

Return-oriented programming Sebastian Neuser

Page 21: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

x86 crash course

Function calls – stack diagram

%esp

%ebp

0xbf8c73c4:

0xbf8c73c8:

0xbf8c73cc:

0xbf8c73d0:

0xbf8c73d4:

parameter 0

parameter 1

parameter 2

local var 0

saved %ebp

Return-oriented programming Sebastian Neuser

Page 22: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

x86 crash course

Function calls – stack diagram

%esp

%ebp

0xbf8c73c0:

0xbf8c73c4:

0xbf8c73c8:

0xbf8c73cc:

0xbf8c73d0:

0xbf8c73d4:

return addr

parameter 0

parameter 1

parameter 2

local var 0

saved %ebp

Return-oriented programming Sebastian Neuser

Page 23: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

x86 crash course

Function calls – stack diagram

%esp

%ebp

0xbf8c73bc:

0xbf8c73c0:

0xbf8c73c4:

0xbf8c73c8:

0xbf8c73cc:

0xbf8c73d0:

0xbf8c73d4:

saved %ebp

return addr

parameter 0

parameter 1

parameter 2

local var 0

saved %ebp

Return-oriented programming Sebastian Neuser

Page 24: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

x86 crash course

Function calls – stack diagram

%esp,%ebp 0xbf8c73bc:

0xbf8c73c0:

0xbf8c73c4:

0xbf8c73c8:

0xbf8c73cc:

0xbf8c73d0:

0xbf8c73d4:

saved %ebp

return addr

parameter 0

parameter 1

parameter 2

local var 0

saved %ebp

Return-oriented programming Sebastian Neuser

Page 25: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

x86 crash course

Function calls – stack diagram

%esp

%ebp

0xbf8c73b4:

0xbf8c73b8:

0xbf8c73bc:

0xbf8c73c0:

0xbf8c73c4:

0xbf8c73c8:

0xbf8c73cc:

0xbf8c73d0:

0xbf8c73d4:

local var 1

local var 0

saved %ebp

return addr

parameter 0

parameter 1

parameter 2

local var 0

saved %ebp

Return-oriented programming Sebastian Neuser

Page 26: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

Stack buffer overflow

Before...

%esp

%ebp

0xbffff8b4:

0xbffff8b8:

0xbffff8bc:...

0xbffff93c:

0xbffff940:

0xbffff944:

buffer[0]

buffer[1]

. . .

local var 1

local var 0

saved %ebp

return addr

Return-oriented programming Sebastian Neuser

Page 27: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

Stack buffer overflow

Meanwhile...

%esp

%ebp

0xbffff8b4:

0xbffff8b8:

0xbffff8bc:...

0xbffff93c:

0xbffff940:

0xbffff944:

buffer[0]

buffer[1]

. . .

local var 1

local var 0

saved %ebp

return addr

Return-oriented programming Sebastian Neuser

Page 28: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

Stack buffer overflow

Meanwhile...

%esp

%ebp

0xbffff8b4:

0xbffff8b8:

0xbffff8bc:...

0xbffff93c:

0xbffff940:

0xbffff944:

buffer[0]

buffer[1]

. . .

local var 1

local var 0

saved %ebp

return addr

Return-oriented programming Sebastian Neuser

Page 29: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

Stack buffer overflow

Meanwhile...

%esp

%ebp

0xbffff8b4:

0xbffff8b8:

0xbffff8bc:...

0xbffff93c:

0xbffff940:

0xbffff944:

buffer[0]

buffer[1]

. . .

local var 1

local var 0

saved %ebp

return addr

Return-oriented programming Sebastian Neuser

Page 30: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

Stack buffer overflow

Meanwhile...

%esp

%ebp

0xbffff8b4:

0xbffff8b8:

0xbffff8bc:...

0xbffff93c:

0xbffff940:

0xbffff944:

buffer[0]

buffer[1]

. . .

local var 1

local var 0

saved %ebp

return addr

Return-oriented programming Sebastian Neuser

Page 31: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

Stack buffer overflow

Boom!

%esp

%ebp

0xbffff8b4:

0xbffff8b8:

0xbffff8bc:...

0xbffff93c:

0xbffff940:

0xbffff944:

buffer[0]

buffer[1]

. . .

local var 1

local var 0

saved %ebp

return addr

Return-oriented programming Sebastian Neuser

Page 32: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

Gadgets

What is a gadget?

• attacker searches for short instruction sequences that performsmall tasks and end with ret

; for example poping some values into registers

• gadget: combination of one or more addresses of shortinstruction sequences and the values that they should pop offthe stack

• payload : chain of gadgets

Return-oriented programming Sebastian Neuser

Page 33: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

Gadgets

A very simple gadget

ret addr

. . .

{prev gadg}

0x0000002a

{next gadg}. . .

pop %eax

ret

Return-oriented programming Sebastian Neuser

Page 34: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

1 Introduction

2 Return-oriented programming in a nutshell

3 DemonstrationROPgadget – a ROP compilerStupid vulnerable programShowtime!

4 Countermeasures

5 Conclusion

Return-oriented programming Sebastian Neuser

Page 35: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

ROPgadget – a ROP compiler

ROPgadget

• finds and lists gadgets that are available in a specified binary

• constructs shellcode, a payload that opens a network socketor user-specified opcodes

• prints out python commands that can be embedded in apayload generation script

• searches and prints out addresses of instructions/opcodes andstrings in a binary

Return-oriented programming Sebastian Neuser

Page 36: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

Stupid vulnerable program

log.h

1 //// io.c ////

2

3 // Appends the buffer to the log-file specified by the path

4 void append_log(char* buffer, char* path);

5

6 // Reads an input string to the buffer until EOF is read

7 void read_string_till_eof(char* buffer);

8

9

10

11 //// util.c ////

12

13 // Checks the program arguments

14 void check_args(int count, char* vector[]);

15

16 // Returns a string that describes the current timestamp

17 char* get_time_string(void);

Return-oriented programming Sebastian Neuser

Page 37: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

Stupid vulnerable program

log.c

1 #include <string.h>

2 #include "log.h"

3

4 int main(int argc, char* argv[])

5 {

6 check_args(argc, argv);

7

8 char buffer[512];

9 char logfile_path[32];

10

11 strcpy(logfile_path, argv[1]);

12 if (!strcasestr(logfile_path, ".log"))

13 strcat(logfile_path, ".log");

14

15 read_string_till_eof(buffer);

16 append_log(buffer, logfile_path);

17 return 0;

18 }

Return-oriented programming Sebastian Neuser

Page 38: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

Stupid vulnerable program

io.c

1 #include <stdio.h>

2 #include "log.h"

3

4 void append_log(char* buffer, char* path)

5 {

6 FILE* fp = fopen(path, "a");

7 fprintf(fp, "%s: %s\n", get_time_string(), buffer);

8 fclose(fp);

9 }

10

11 void read_string_till_eof(char* buffer)

12 {

13 int c;

14 while ((c=getchar()) && c != EOF) {

15 *buffer++ = c;

16 }

17 printf("\n");

18 }

Return-oriented programming Sebastian Neuser

Page 39: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

Stupid vulnerable program

util.c

1 #include <stdio.h>

2 #include <stdlib.h>

3 #include <string.h>

4 #include <time.h>

5

6 void check_args(int count, char* vector[])

7 {

8 if (count != 2) {

9 printf("Usage: log <log file>\n");

10 exit(0);

11 }

12 }

13

14 char* get_time_string(void)

15 {

16 time_t timestamp = time(NULL);

17 char* time_string = ctime(&timestamp);

18 time_string[strlen(time_string)-1] = ’\0’;

19 return time_string;

20 }

Return-oriented programming Sebastian Neuser

Page 40: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

Showtime!

The fun part...

”For a moment, nothing happened.Then, after a second or so, nothing continued to happen.”

- Douglas Adams, The Hitchhiker’s Guide to the Galaxy

Return-oriented programming Sebastian Neuser

Page 41: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

1 Introduction

2 Return-oriented programming in a nutshell

3 Demonstration

4 CountermeasuresASLR and PIEStack canaries and shadow stacksCFI and ROPdefender

5 Conclusion

Return-oriented programming Sebastian Neuser

Page 42: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

ASLR and PIE

ASLR and PIE

• Address Space Layout Randomization

• Position Independent Executable

• take effect at load and link time during program startup

• in the PaX implementation, the addresses of the followingsegments are randomized:

• .text-segment of the binary (; executable code)• dynamically linked libraries• the stack• the heap

• libraries in themselves are not randomized; randomization can be overcome by brute-force attacksand/or through information leakage

Return-oriented programming Sebastian Neuser

Page 43: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

Stack canaries and shadow stacks

Stack canaries – Explanation

• canary word: word between local variables of a function andthe return address

• during function prologue: canary word is placed on the stackand backed up in a different location

• during function epilogue: canary word is verified throughcomparison with the stored value

• word has changed (; the canary is dead §); program is terminated with a warning message

• Example: StackGuard

Return-oriented programming Sebastian Neuser

Page 44: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

Stack canaries and shadow stacks

Stack canaries – Diagram

%esp

%ebp

0xbf9358bc:...

0xbf935924:

0xbf935928:

0xbf93592c:

buffer

. . .

canary

saved %ebp

return addr

Return-oriented programming Sebastian Neuser

Page 45: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

Stack canaries and shadow stacks

Shadow stacks

• TRUSS : maintains shadow stack, which stores returnaddresses

• function prologue: modified to push the correct return addressonto the shadow stack

• epilogue: compares return addresses

• mismatch ; program termination and error signal

Return-oriented programming Sebastian Neuser

Page 46: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

CFI and ROPdefender

Control Flow Integrity

• control flow graph maps all function calls

• function prologues and epilogues are modified at runtime

• targets of call and ret instructions are correlated with theanticipated control flow in the graph

• opcodes do not match ; program is aborted

• significant computational overhead with a factor typically inthe range of [1.5, 3.5]

Return-oriented programming Sebastian Neuser

Page 47: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

CFI and ROPdefender

ROPdefender

• ROPdefender also maintains a shadow stack

• capable of detecting unintended instruction sequences

• return address of every call instruction is pushed onto theshadow stack

• every ret instruction: comparison of the destination addressto the top of the shadow stack

• program is aborted if the addresses do not match

• computational overhead similar to CFI

Return-oriented programming Sebastian Neuser

Page 48: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

1 Introduction

2 Return-oriented programming in a nutshell

3 Demonstration

4 Countermeasures

5 Conclusion

Return-oriented programming Sebastian Neuser

Page 49: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

Summary

• long evolution from direct code injection to ROP

• applicable to many popular architectures

• quite complex technique

• relatively recent ; few effective countermeasures

• frameworks for automation of payload generation

• ; serious threat!

• But: It’s fun! ©

Return-oriented programming Sebastian Neuser

Page 50: Return oriented programming

Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion

Thanks for your attention.

Questions?

Return-oriented programming Sebastian Neuser