memory corruption - thinkst › resources › slides › bh-2010-haroon-meer... · 2019-03-18 ·...

92
Memory Corruption The (almost) Complete History... haroon meer - 2010 @haroonmeer | [email protected]

Upload: others

Post on 05-Jul-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

Memory CorruptionThe (almost) Complete History...

haroon meer - 2010@haroonmeer | [email protected]

Who ?haroon meer

thinkst ?

some papers, some books, some talks

academic wannabe

Why?

Why?

Why?

Why?

Why?

twitter made me do it!

Why?

de-mystify some of the otherwise mystical

convince you that Solar Designer was skynet

Why?(Some silly Stats)

Stack : 140 Heap : 74

!"

#"

$!"

$#"

%!"

%#"

&!"

&#"

'!"

$(((" %!!!" %!!$" %!!%" %!!&" %!!'" %!!#" %!!)" %!!*" %!!+" %!!("

!"

#"

$!"

$#"

%!"

%#"

&!"

$'''" %!!!" %!!$" %!!%" %!!&" %!!(" %!!#" %!!)" %!!*" %!!+" %!!'"

Why?(Some silly Stats)

Stack : 140 Heap : 74

!"

#"

$!"

$#"

%!"

%#"

&!"

&#"

'!"

$(((" %!!!" %!!$" %!!%" %!!&" %!!'" %!!#" %!!)" %!!*" %!!+" %!!("

!"

#"

$!"

$#"

%!"

%#"

&!"

$'''" %!!!" %!!$" %!!%" %!!&" %!!(" %!!#" %!!)" %!!*" %!!+" %!!'"

Caveats - Limits

Caveats - Limits

Caveats - Myopia

Caveats - Myopia

332880 : 1

Caveats -Compression Ratio

Disclosure, Bugs and Counts

VS.

Disclosed Bugs

Our Approach

Clearly naive initially

the paper(read it)

So at the end of this..You wont be able to suddenly use free() to obtain a 4-byte write anything anywhere primitive.

You will understand what that means.

You will be able to see:

When that was first used;

What prevents it’s use/abuse today;

Where did it start?

Memory Basics

Memory Basics

0x00000000

Memory Basics

UserPageTable{4 gig

Kernel

0x00000000

Memory Basics

UserPageTable{4 gig

Kernel

0x00000000

User

Kernel

{3 gig

0x00000000

User

Kernel

0x00000000

User

Kernel

Multiple Processes

0x00000000

User

Kernel

{3 gig

0x00000000

User

Kernel

0x00000000

User

Kernel

Multiple Processes

Kernel

0x00000000

User

PageTable{4 gig

Kernel

Segments

0x00000000

User{4 gig

Kernel

Segments

0x00000000

User{4 gig

Kernel

0x00000000

Segments

0x00000000

User{4 gig

Kernel

0x00000000

Text

Segments

0x00000000

User{4 gig

Kernel

0x00000000

Text

Data

Segments

0x00000000

User{4 gig

Kernel

0x00000000

Text

Data

...

Segments

0x00000000

User{4 gig

Kernel

0x00000000

Text

Data

...

HeapGrowsUpwards

Segments

0x00000000

User{4 gig

Kernel

0x00000000

Text

Data

...

HeapGrowsUpwards

mmap(Shared Memory)

Segments

0x00000000

User{4 gig

Kernel

0x00000000

Text

Data

...

HeapGrowsUpwards

mmap(Shared Memory)

StackGrows

Downwards

Segments

So what is code?

So what is code?

So what is code?

So what is code?

Is this code?

Is this code?

Is this code?

Is this code?

Is this code?

0x00000000

User{4 gig

Kernel

0x00000000

Text

Data

...

HeapGrowsUpwards

mmap(Shared Memory)

StackGrows

Downwards

int function_1(int a, int b){

int j;// do stuffreturn j;

}

int main(int argc, char **argv, char **envp){

int i;i = function_1(1,2);printf(“answer is %d”, i)return i;

}

GrowsUpwards

GrowsDownwards

0x00

0000

00

Stackmmap(Shared Memory)HeapText Data ...

Stack Basics

int function_1(int a, int b){

int j;// do stuffreturn j;

}

int main(int argc, char **argv, char **envp){

int i;i = function_1(1,2);printf(“answer is %d”, i)return i;

}

GrowsUpwards

GrowsDownwards

0x00

0000

00

Stackmmap(Shared Memory)HeapText Data ...

Stack Basics

int function_1(int a, int b){

int j;// do stuffreturn j;

}

int main(int argc, char **argv, char **envp){

int i;i = function_1(1,2);printf(“answer is %d”, i)return i;

}

GrowsDownwards

0x00

0000

00

int argc char **envpchar **argv

Stack Basics

int function_1(int a, int b){

int j;// do stuffreturn j;

}

int main(int argc, char **argv, char **envp){

int i;i = function_1(1,2);printf(“answer is %d”, i)return i;

}

GrowsDownwards

0x00

0000

00

SavedEIP

SavedEBP int argc char **envpchar **argv

Stack Basics

int function_1(int a, int b){

int j;// do stuffreturn j;

}

int main(int argc, char **argv, char **envp){

int i;i = function_1(1,2);printf(“answer is %d”, i)return i;

}

GrowsDownwards

0x00

0000

00

SavedEIP

SavedEBP int argc char **envpchar **argv

Stack Basics

int function_1(int a, int b){

int j;// do stuffreturn j;

}

int main(int argc, char **argv, char **envp){

int i;i = function_1(1,2);printf(“answer is %d”, i)return i;

}

GrowsDownwards

0x00

0000

00

int i SavedEIP

SavedEBP int argc char **envpchar **argv

Stack Basics

int function_1(int a, int b){

int j;// do stuffreturn j;

}

int main(int argc, char **argv, char **envp){

int i;i = function_1(1,2);printf(“answer is %d”, i)return i;

}

GrowsDownwards

0x00

0000

00

int i SavedEIP

SavedEBP int argc char **envpchar **argv

Stack Basics

int function_1(int a, int b){

int j;// do stuffreturn j;

}

int main(int argc, char **argv, char **envp){

int i;i = function_1(1,2);printf(“answer is %d”, i)return i;

}

GrowsDownwards

0x00

0000

00

int i SavedEIP

function_1argument_2

(b)

function_1argument_1

(a)SavedEBP int argc char **envpchar **argv

Stack Basics

int function_1(int a, int b){

int j;// do stuffreturn j;

}

int main(int argc, char **argv, char **envp){

int i;i = function_1(1,2);printf(“answer is %d”, i)return i;

}

GrowsDownwards

0x00

0000

00

int i SavedEIP

function_1argument_2

(b)

function_1argument_1

(a)SavedEBP int argc char **envpchar **argv

Stack Basics

int function_1(int a, int b){

int j;// do stuffreturn j;

}

int main(int argc, char **argv, char **envp){

int i;i = function_1(1,2);printf(“answer is %d”, i)return i;

}

GrowsDownwards

0x00

0000

00

int i SavedEIP

function_1argument_2

(b)

function_1argument_1

(a)

SavedEBP

SavedEIP

SavedEBP int argc char **envpchar **argv

Stack Basics

int function_1(int a, int b){

int j;// do stuffreturn j;

}

int main(int argc, char **argv, char **envp){

int i;i = function_1(1,2);printf(“answer is %d”, i)return i;

}

GrowsDownwards

0x00

0000

00

int i SavedEIP

function_1argument_2

(b)

function_1argument_1

(a)

SavedEBP

SavedEIP

SavedEBP int argc char **envpchar **argv

Stack Basics

int function_1(int a, int b){

int j;// do stuffreturn j;

}

int main(int argc, char **argv, char **envp){

int i;i = function_1(1,2);printf(“answer is %d”, i)return i;

}

GrowsDownwards

0x00

0000

00

int i SavedEIP

function_1argument_2

(b)

function_1argument_1

(a)

SavedEBPint j Saved

EIPSavedEBP int argc char **envpchar **argv

Stack Basics

int function_1(int a, int b){

int j;// do stuffreturn j;

}

int main(int argc, char **argv, char **envp){

int i;i = function_1(1,2);printf(“answer is %d”, i)return i;

}

Stack Basics

GrowsDownwards

0x00

0000

00

int i SavedEIP

function_1argument_2

(b)

function_1argument_1

(a)

SavedEBP

SavedEIP

SavedEBP int argc char **envpchar **argv

int function_1(int a, int b){

int j;// do stuffreturn j;

}

int main(int argc, char **argv, char **envp){

int i;i = function_1(1,2);printf(“answer is %d”, i)return i;

}

Stack Basics

GrowsDownwards

0x00

0000

00

int i SavedEIP

function_1argument_2

(b)

function_1argument_1

(a)SavedEBP int argc char **envpchar **argv

Classic Overflow

Stack GrowsDownwards

SavedEIP

function_1argument_1

(a)SavedEBPint j Saved

EIPSavedEBP int argc char **envpchar **argvbuff

Overflow Direction

Where to go

non-terminated stringsstrcpy(buf1, buf2);

non-terminated stringsstrcpy(buf1, buf2);

non-terminated stringsstrcpy(buf1, buf2); char buf1[4];

strncpy(buf1, buf2, 4);

non-terminated stringsstrcpy(buf1, buf2); char buf1[4];

strncpy(buf1, buf2, 4);

non-terminated stringsstrcpy(buf1, buf2); char buf1[4];

strncpy(buf1, buf2, 4);

T E S T I N G \0

char buf1[4] char buf2[] = “TESTING”

non-terminated stringsstrcpy(buf1, buf2); char buf1[4];

strncpy(buf1, buf2, 4);

T E S T I N G \0

char buf1[4] char buf2[] = “TESTING”

T E S T

non-terminated stringsstrcpy(buf1, buf2); char buf1[4];

strncpy(buf1, buf2, 4);

T E S T I N G \0

char buf1[4] char buf2[] = “TESTING”

T E S T

printf(“buf1 is [%s]\n”,buf1);

non-terminated stringsstrcpy(buf1, buf2); char buf1[4];

strncpy(buf1, buf2, 4);

T E S T I N G \0

char buf1[4] char buf2[] = “TESTING”

T E S T

printf(“buf1 is [%s]\n”,buf1);

$ buf1 is [TESTTESTING]

heap-unlink()

bk fd bk fd bk fd7 8 9

heap-unlink()

bk fd bk fd bk fd7 8 9

[x] [8] [7] [9] [8] [x]7 8 9

back

forward

back

forward

heap-unlink()

[x] [8] [7] [9] [8] [x]7 8 9

back

forward

back

forward

heap-unlink()

[x] [8] [7] [9] [8] [x]7 8 9

back

forward

back

forward

[x] [8] [7] [9] [8] [x]7 8 9

back

forward

back

forward

heap-unlink()

[x] [9] [7] [9] [8] [x]7 8 9

back

forward

back

heap-unlink()

[x] [9] [7] [9] [7] [x]7 8 9

forward

back

heap-unlink()

[x] [9] [7] [9] [7] [x]7 8 9

forward

back

WHERE WHAT

slapper

* Peter Szor - analysis of the slapper worm

gs vs params

Stack Growth

SavedEBPint j Saved

EIPbuff

Overflow Direction

Pointers Arguments

int func(char *a, char *b){ char buf[12]; strcpy(buf, a); strcpy(b, buf); return 1;}

gs vs params

Stack Growth

SavedEBPint j Saved

EIPbuff

Overflow Direction

Pointers Arguments

int func(char *a, char *b){ char buf[12]; strcpy(buf, a); strcpy(b, buf); return 1;}

Stack Growth

SavedEBPint j Saved

EIPbuff

Overflow Direction

PointersArguments

(shadow copy) Arguments

so..

Everything executable --> DEP

DEP vs ret-2-libc (ROP)

so..

ASLR to beat ret-2-libc / ROP

Single leaked / static address beats ASLR

Partial Overwrites

App specific..

so..

ASLR to beat ret-2-libc / ROP

Single leaked / static address beats ASLR

Partial Overwrites

App specific..

Stack Growth

int xint j function pointer bbuff

LSB's MSB's

function pointer a

Overflow Direction

So..

DEP without ASLR

ASLR without DEP

without

Conclusions?What the ASLR/DEP taketh..

The rich client side applications giveth back.

Info. leakage attacks are an area of much research

http://ilm.thinkst.com/folklore/

Thanks!• Marco Slaviero

• Brad Spengler (spender)

• PaX Team

• Halvar Flake

• icesurfer

• Nate Lawson

• Chris Wysopal

• Saumil Shah

• Matt Miller

• Ollie Whitehouse

• Dennis Groves

• Ivan Arce

• Mario Vilas

• Tyler Shields

• Dion Blazakis

• georgie

• Ben Nagy

• the Grugq.

• Bradley Cowie

• Barry Irwin