Minemu: Protecting buggy binaries from memory corruption attacks - - PowerPoint PPT Presentation

minemu protecting buggy binaries from memory corruption
SMART_READER_LITE
LIVE PREVIEW

Minemu: Protecting buggy binaries from memory corruption attacks - - PowerPoint PPT Presentation

Minemu: Protecting buggy binaries from memory corruption attacks Erik Bosman <erik@minemu.org> Programming Languages type-safe vs. not type-safe Programming Languages type-safe vs. not type-safe Java Python Ruby Javascript


slide-1
SLIDE 1

Minemu: Protecting buggy binaries from memory corruption attacks

Erik Bosman <erik@minemu.org>

slide-2
SLIDE 2
slide-3
SLIDE 3
slide-4
SLIDE 4
slide-5
SLIDE 5

type-safe not type-safe vs. Programming Languages

slide-6
SLIDE 6

type-safe Java Python Ruby Javascript not type-safe vs. Programming Languages

slide-7
SLIDE 7

type-safe Java Python Ruby Javascript not type-safe C C++ vs. Programming Languages

slide-8
SLIDE 8

type-safe Java Python Ruby Javascript not type-safe C C++ vs.

MEMORY CORRUPTIONS!

Programming Languages

slide-9
SLIDE 9

type-safe Java Python Ruby Javascript not type-safe C C++ vs.

MEMORY CORRUPTIONS!

M E M O R Y C O R R U P T I O N S !

Programming Languages

slide-10
SLIDE 10

type-safe Java Python Ruby Javascript not type-safe C C++ vs.

MEMORY CORRUPTIONS!

M E M O R Y C O R R U P T I O N S ! b u t n

  • t

y

  • u

r f a u l t

Programming Languages

slide-11
SLIDE 11

The Stack

[code] run(char *name) { char buf[16]; print("hello "); print("world\n") }

slide-12
SLIDE 12

The Stack

baseretnarg1...

[code] [stack] run(char *name) { char buf[16]; print("hello "); print("world\n") }

slide-13
SLIDE 13

The Stack

baseretnarg1... baseretnarg1... buf

[code] [stack] run(char *name) { char buf[16]; print("hello "); print("world\n") }

slide-14
SLIDE 14

The Stack

baseretnarg1... baseretnarg1... buf

[address] [code] [stack] 8048751: run(char *name) { char buf[16]; 8048770: print("hello "); 8048798: print("world\n") }

slide-15
SLIDE 15

The Stack

baseretnarg1... baseretnarg1... buf

[address] [code] [stack] 8048751: run(char *name) { char buf[16]; 8048770: print("hello "); 8048798: print("world\n") }

baseretnarg1... retnarg1buf

slide-16
SLIDE 16

The Stack

baseretnarg1... baseretnarg1... buf

[address] [code] [stack] 8048751: run(char *name) { char buf[16]; 8048770: print("hello "); 8048798: print("world\n") }

baseretnarg1... retnarg1buf baseretnarg1... retnarg1buf

slide-17
SLIDE 17

GET / HTTP/1.100baseretnarg1arg2

Traditional Stack Smashing buf[16]

slide-18
SLIDE 18

GET / HTTP/1.100baseretnarg1arg2 SHELLCODE!@#$%^&*()_&buf

Traditional Stack Smashing buf[16]

slide-19
SLIDE 19

GET / HTTP/1.100baseretnarg1arg2 SHELLCODE!@#$%^&*()_????

Address Space Layout Randomisation (ASLR) buf[16]

slide-20
SLIDE 20

GET / HTTP/1.100 baseretnarg1

buf[16] Stack Canaries

slide-21
SLIDE 21

GET / HTTP/1.100 baseretnarg1 SHELLCODE!@#$%^&*()_!@#%&buf

buf[16] Stack Canaries

slide-22
SLIDE 22

GET / HTTP/1.100baseretnarg1arg2 SHELLCODE!@#$%^&*()_&buf

Non-executable data (DEP / NX) buf[16]

slide-23
SLIDE 23

GET / HTTP/1.100baseretnarg1arg2 sh;STACKSMASHERAAAAAAAAAAAAAAAAA

Fortify Source char buf[16]; memcpy(buf, r->buf, r->len);

slide-24
SLIDE 24

GET / HTTP/1.100baseretnarg1arg2 sh;STACKSMASHERAAAAAAAAAAAAAAAAA

Fortify Source char buf[16]; memcpy(buf, r->buf, r->len); char buf[16]; memcpy_chk(buf, r->buf, r->len, 16);

slide-25
SLIDE 25

*** buffer overflow detected ***: /my/fortified/binary terminated ======= Backtrace: ========= /lib/i386-linux-gnu/i686/cmov/libc.so.6(__fortify_fail+0x50)[0xb774a4d0] /lib/i386-linux-gnu/i686/cmov/libc.so.6(+0xe040a)[0xb774940a] /my/fortified/binary[0x8048458] /lib/i386-linux-gnu/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0xb767fe46] /my/fortified/binary[0x8048371] ======= Memory map: ======== 08048000-08049000 r-xp 00000000 fe:00 282465 /my/fortified/binary 08049000-0804a000 rw-p 00000000 fe:00 282465 /my/fortified/binary 08600000-08621000 rw-p 00000000 00:00 0 [heap] b764b000-b7667000 r-xp 00000000 fe:00 131602 /lib/i386-linux-gnu/libgcc_s.so.1 b7667000-b7668000 rw-p 0001b000 fe:00 131602 /lib/i386-linux-gnu/libgcc_s.so.1 b7668000-b7669000 rw-p 00000000 00:00 0 ... Aborted

slide-26
SLIDE 26
slide-27
SLIDE 27

GET / HTTP/1.100baseretnarg1arg2 sh;STACKSMASHER.....ROP1ROP2var1

Return Oriented Programming (ROP) buf[16] pointer to useful code

slide-28
SLIDE 28

Some exploits still work with all these defense measures. Example: nginx buffer underrun (CVE-2009-2629)

slide-29
SLIDE 29

/%3F/../abcd0000BADP0000BAD_CTX0

CVE-2009-2629 r->uri_start

slide-30
SLIDE 30

/%3F/../abcd0000BADP0000BAD_CTX0 /

r->uri.data r->ctx[33]

u

CVE-2009-2629 r->uri_start

slide-31
SLIDE 31

/%3F/../abcd0000BADP0000BAD_CTX0 /?..

r->uri.data r->ctx[33]

u

CVE-2009-2629

slide-32
SLIDE 32

/%3F/../abcd0000BADP0000BAD_CTX0 xyz/....0000CTXP0000 /?..

r->uri.data r->ctx[33]

u

CVE-2009-2629

slide-33
SLIDE 33

/%3F/../abcd0000BADP0000BAD_CTX0 xyz/....0000BADP0000 BAD_CTX0

r->uri.data r->ctx[33] CVE-2009-2629

slide-34
SLIDE 34

{ ngx_buf_t *buf; ngx_chain_t *in; ngx_chain_t *free; ngx_chain_t *busy; sendfile; need_in_memory; need_in_temp; ngx_pool_t *pool; ngx_int_t allocated; ngx_bufs_t bufs; ngx_buf_tag_t tag; ngx_output_chain_filter_pt output_filter; *filter_ctx; } ngx_output_chain_ctx_t; typedef struct unsigned unsigned unsigned void

slide-35
SLIDE 35

{ ngx_buf_t *buf; ngx_chain_t *in; ngx_chain_t *free; ngx_chain_t *busy; sendfile; need_in_memory; need_in_temp; ngx_pool_t *pool; ngx_int_t allocated; ngx_bufs_t bufs; ngx_buf_tag_t tag; ngx_output_chain_filter_pt output_filter; *filter_ctx; } ngx_output_chain_ctx_t; typedef struct unsigned unsigned unsigned void

function pointer

slide-36
SLIDE 36
slide-37
SLIDE 37

805ba93: mov ,%ebx ; copy filename movl $0x3,0x10(%ecx) mov %ecx,(%esp) call (%ecx) *0x2c(%ecx)

slide-38
SLIDE 38

805ba93: mov ,%ebx ; copy filename movl $0x3,0x10(%ecx) mov %ecx,(%esp) call 8052267: mov ,0x4(%esp) ; push argv mov ,(%esp) ; push filename call (%ecx) *0x2c(%ecx) %eax %ebx *0x14(%ebx)

slide-39
SLIDE 39

805ba93: mov ,%ebx ; copy filename movl $0x3,0x10(%ecx) mov %ecx,(%esp) call 8052267: mov ,0x4(%esp) ; push argv mov ,(%esp) ; push filename call 804b274: <execve@plt> ; get shell (%ecx) *0x2c(%ecx) %eax %ebx *0x14(%ebx)

slide-40
SLIDE 40
  • defeats address randomisation (through info leak)
slide-41
SLIDE 41
  • defeats address randomisation (through info leak)
  • defeats non-executable data protection
slide-42
SLIDE 42
  • defeats address randomisation (through info leak)
  • defeats non-executable data protection
  • no standard copy function (no fortify src protections)
slide-43
SLIDE 43
  • defeats address randomisation (through info leak)
  • defeats non-executable data protection
  • no standard copy function (no fortify src protections)
  • not return oriented, so stack smash protection

does not matter

slide-44
SLIDE 44

But the situation is even worse

slide-45
SLIDE 45

But the situation is even worse

  • needs to be enabled at compile time, and

there is a lot of old code out there

slide-46
SLIDE 46

But the situation is even worse

  • needs to be enabled at compile time, and

there is a lot of old code out there

  • many packages do not apply these defence

mechanisms even today

slide-47
SLIDE 47

But the situation is even worse

  • needs to be enabled at compile time, and

there is a lot of old code out there

  • many packages do not apply these defence

mechanisms even today

  • implementation flaws
slide-48
SLIDE 48

Can we do more?

slide-49
SLIDE 49

Can we do more? >> Non-executable data prevents untrusted data from being run as code

slide-50
SLIDE 50

Can we do more? >> Non-executable data prevents untrusted data from being run as code << Return oriented programming replaces untrusted code with pointers to original code.

slide-51
SLIDE 51

Can we do more? >> Non-executable data prevents untrusted data from being run as code << Return oriented programming replaces untrusted code with pointers to original code. >> Can we prevent untrusted pointers from being used as jump addresses?

slide-52
SLIDE 52

Taint analysis

0805be60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 0805be70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 0805be80 00 00 00 00 02 00 00 00 d8 4b 06 08 a0 2e 05 08 |.........K......| 0805be90 | | 0805bea0 | | 0805beb0 | | 0805bec0 | | 0805bed0 00 00 00 00 |.... | 0805bee0 ff fa 26 08 ff f0 00 00 00 00 00 00 00 00 00 00 |..&.............| 0805bef0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 0805bf00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 94 be 05 08 78 a0 04 08 ef be ad de a4 be 05 08 ....x........... ac be 05 08 2f 62 69 6e 2f 73 68 00 a4 be 05 08 ..../bin/sh..... 00 00 00 00 53 41 4d 45 54 48 49 4e 47 57 45 44 ....SAMETHINGWED 4f 45 56 45 52 59 4e 49 47 48 54 50 49 4e 4b 59 OEVERYNIGHTPINKY 4e 41 52 46 90 be 05 08 ef 1f 05 08 NARF........

slide-53
SLIDE 53

Taint tracking (1/2):

  • remember whether data is trusted or not
  • untrusted data is 'tainted'
  • when data is copied, its taint is copied along
  • taint is ORed for arithmetic operations
slide-54
SLIDE 54

Taint tracking (2/2): When the code jumps to an address in memory, the source of this address is checked for taint. eg.:

  • RET
  • CALL
  • JMP

*%eax *0x1c(%ebx)

slide-55
SLIDE 55
slide-56
SLIDE 56

T aint tracking

photo: sammydavisdog@flickr

useful, but slow as hell

slide-57
SLIDE 57

Is this slowness fundamental?

fast emulator memory layout use SSE registers to hold taint

minemu

slide-58
SLIDE 58

Is this slowness fundamental?

fast emulator memory layout use SSE registers to hold taint

minemu

slide-59
SLIDE 59

Emulator

compile jit code

slide-60
SLIDE 60

Emulator

run jit code compile jit code

slide-61
SLIDE 61

Emulator

run jit code find jump address compile jit code indirect jump

slide-62
SLIDE 62

Emulator

run jit code find jump address compile jit code indirect jump lookup miss

slide-63
SLIDE 63

Dynamic instrumentation

eax = eax + ebx t_eax = t_eax | t_ecx eax = eax + ecx

jit code

  • riginal code
slide-64
SLIDE 64

Is this slowness fundamental?

fast emulator memory layout use SSE registers to hold taint

minemu

slide-65
SLIDE 65

Linux User

stack executable heap/libs

slide-66
SLIDE 66

linux kernel USER Memory layout (linux)

slide-67
SLIDE 67

linux kernel USER TAINT

minemu

Memory layout (minemu)

slide-68
SLIDE 68

linux kernel USER TAINT

minemu

Memory layout (minemu)

slide-69
SLIDE 69

linux kernel USER TAINT

minemu

Memory layout (minemu)

write to x

slide-70
SLIDE 70

linux kernel USER TAINT

minemu

Memory layout (minemu)

write to x x+const

slide-71
SLIDE 71

linux kernel USER TAINT

minemu

Memory layout (minemu)

taint data to user memory user data to taint memory

slide-72
SLIDE 72

linux kernel USER TAINT

minemu

Memory layout (minemu)

taint data to user memory user data to taint memory

slide-73
SLIDE 73

mov EAX, (EDX)

Addressing shadow memory

slide-74
SLIDE 74

mov EAX, (EDX) address: EDX

Addressing shadow memory

slide-75
SLIDE 75

mov EAX, (EDX) address: EDX taint: EDX+ const

Addressing shadow memory

slide-76
SLIDE 76

mov EAX, (EDX+EBX*4)

Addressing shadow memory

slide-77
SLIDE 77

mov EAX, (EDX+EBX*4) address: EDX+EBX*4

Addressing shadow memory

slide-78
SLIDE 78

mov EAX, (EDX+EBX*4) address: EDX+EBX*4 taint: EDX+EBX*4+ const

Addressing shadow memory

slide-79
SLIDE 79

push ESI

Addressing shadow memory

slide-80
SLIDE 80

push ESI address: ESP

Addressing shadow memory

slide-81
SLIDE 81

push ESI address: ESP taint: ESP+ const

Addressing shadow memory

slide-82
SLIDE 82

Is this slowness fundamental?

fast emulator memory layout use SSE registers to hold taint

minemu

slide-83
SLIDE 83

T aint propagation in SSE registers

T(eax) T(ecx) T(edx) T(ebx) T(eax) T(ecx) T(edx) T(ebx) xmm6 T(esp) T(ebp) T(esi) T(edi) T(esp) T(ebp) T(esi) T(edi) xmm7 xmm5 scratch register scratch register 128-bit

slide-84
SLIDE 84

T aint propagation in SSE registers

T(eax) T(ecx) T(edx) T(ebx) T(eax) T(ecx) T(edx) T(ebx) xmm6 T(esp) T(ebp) T(esi) T(edi) T(esp) T(ebp) T(esi) T(edi) xmm7 xmm5 scratch register scratch register 128-bit

add EDX, x

slide-85
SLIDE 85

T aint propagation in SSE registers

T(eax) T(ecx) T(edx) T(ebx) T(eax) T(ecx) T(edx) T(ebx) xmm6 T(esp) T(ebp) T(esi) T(edi) T(esp) T(ebp) T(esi) T(edi) xmm7 xmm5 scratch register scratch register

add EDX, x

slide-86
SLIDE 86

T aint propagation in SSE registers

T(eax) T(ecx) T(edx) T(ebx) T(eax) T(ecx) T(edx) T(ebx) xmm6 T(esp) T(ebp) T(esi) T(edi) T(esp) T(ebp) T(esi) T(edi) xmm7 xmm5 T(x) T(x)

add EDX, x vector insert

slide-87
SLIDE 87

T aint propagation in SSE registers

T(eax) T(ecx) T(edx) T(ebx) T(eax) T(ecx) T(edx) T(ebx) xmm6 T(esp) T(ebp) T(esi) T(edi) T(esp) T(ebp) T(esi) T(edi) xmm7 xmm5 T(x) T(x)

add EDX, x

  • r
slide-88
SLIDE 88

Effectiveness

Application Type of vulnerability Security advisory Snort 2.4.0 Stack overflow CVE-2005-3252 Cyrus imapd 2.3.2 Stack overflow CVE-2006-2502 Samba 3.0.22 Heap overflow CVE-2007-2446 Memcached 1.1.12 Heap overflow CVE-2009-2415 Nginx 0.6.32 Buffer underrun CVE-2009-2629 Proftpd 1.3.3a Stack overflow CVE-2010-4221 Samba 3.2.5 Heap overflow CVE-2010-2063 Telnetd 1.6 Heap overflow CVE-2011-4862 Ncompress 4.2.4 Stack overflow CVE-2001-1413 Iwconfig V.26 Stack overflow CVE-2003-0947 Aspell 0.50.5 Stack overflow CVE-2004-0548 Htget 0.93 Stack overflow CVE-2004-0852 Socat 1.4 Format string CVE-2004-1484 Aeon 0.2a Stack overflow CVE-2005-1019 Exim 4.41 Stack overflow EDB-ID#796 Htget 0.93 Stack overflow Tipxd 1.1.1 Format string OSVDB-ID#12346

slide-89
SLIDE 89

Performance

HTTP HTTPS

slide-90
SLIDE 90

Performance

1 2 3 gzip OpenSSH (scp+sshd) PostgreSQL (pgbench) MediaWiki (HTTPS) 1 2 3 4 5 400.perlbench 401.bzip2 403.gcc 429.mcf 445.gobmk 456.hmmer 458.sjeng 462.libquantum 464.h264ref 471.omnetpp 473.astar 483.xalancbmk

  • verall

SPECINT 2006

2.4x overall

slide-91
SLIDE 91

Limitations

slide-92
SLIDE 92

Limitations Doesn't prevent memory corruption, only acts when the untrusted data is used for arbitrary code execution.

slide-93
SLIDE 93

Limitations Tainted pointer dereferences

  • >some_field = useful_untainted_value;

tainted_pointer

slide-94
SLIDE 94

Limitations Tainted pointer dereferences

  • >some_field = useful_untainted_value;

propagation can lead to false positives: dispatch_table[ ](); tainted_pointer checked_input

slide-95
SLIDE 95

Limitations Taint whitewashing

  • ut = latin1_to_ascii[ ];

in

slide-96
SLIDE 96

Limitations Format string attacks: printf( ); printf( ); // Does not :-( "%65534s %123$hn" // Propagates taint in glibc "FillerFiller...%123$hn"

slide-97
SLIDE 97

Limitations Does not protect against non-control-flow exploits

slide-98
SLIDE 98

Limitations Does not protect against non-control-flow exploits

try_system( *username, *cmd) { user_rights = get_credentials(username); buf[16] ; strcpy(buf, username); (user_rights & ) system(cmd); log_error( , buf); } void char char int char 16 ALLOW_SYSTEM "user attempted login" %s if else

slide-99
SLIDE 99

Limitations Does not protect against non-control-flow exploits

try_system( *username, *cmd) { user_rights = get_credentials(username); buf[16] ; strcpy(buf, username); (user_rights & ) system(cmd); log_error( , buf); } void char char int char 16 ALLOW_SYSTEM "user attempted login" %s if else

slide-100
SLIDE 100

Limitations Does not protect against non-control-flow exploits

try_system( *username, *cmd) { user_rights = get_credentials(username); buf[16] ; strcpy(buf, username); (user_rights & ) system(cmd); log_error( , buf); } void char char int char 16 ALLOW_SYSTEM "user attempted login" %s if else

slide-101
SLIDE 101

Limitations Does not protect against non-control-flow exploits

try_system( *username, *cmd) { user_rights = get_credentials(username); buf[16] ; strcpy(buf, username); (user_rights & ) system(cmd); log_error( , buf); } void char char int char 16 ALLOW_SYSTEM "user attempted login" %s if else

slide-102
SLIDE 102

Limitations Does not protect against non-control-flow exploits

try_system( *username, *cmd) { user_rights = get_credentials(username); buf[16] ; strcpy(buf, username); (user_rights & ) system(cmd); log_error( , buf); } void char char int char 16 ALLOW_SYSTEM "user attempted login" %s if else

slide-103
SLIDE 103

in some cases we can add validation hooks. can be hooked to check for taint

  • utside of literals in SQL queries.

mysql_query()

slide-104
SLIDE 104

in some cases we can add validation hooks. can be hooked to check for taint

  • utside of literals in SQL queries.

in glibc can be hooked to check format strings for taint. mysql_query() _IO_vfprintf()

slide-105
SLIDE 105

Demo

demo@demo:~# ./minemu bash

slide-106
SLIDE 106

Minemu

git clone https://minemu.org/code/minemu.git

slide-107
SLIDE 107

Minemu

git clone https://minemu.org/code/minemu.git

any questions?

slide-108
SLIDE 108

https://minemu.org/vms/ 5f1ee00029e2c68699a7670de7aef02e minemu-demo.ova c4ee74155a858676bfb54e1fcfb6db0e minemu-demo.qcow2 5b8b910c38901f43d406a21fe9767822 minemu-demo.vdi.gz 7ba81ae9d35bfa05a70068a804a331ac minemu-demo.vmdk.gz c37acdc455ebac700139f60da621bc38 minemu-demo.xml minemu needs CPU with SSE 4.1

slide-109
SLIDE 109
slide-110
SLIDE 110

TAINT USER Memory layout (64 bit)

TAINT USER TAINT USER TAINT USER

slide-111
SLIDE 111

TAINT USER

Memory layout (64 bit) alternative

data/code/stack segment gs segment