Académique Documents
Professionnel Documents
Culture Documents
Reference. Based on a presentation provided by Microsoft in relation to the Security Development Lifecycle Developer Starter Kit
http://www.microsoft.com/en-us/download/details.aspx?id=4645 1/37
Agenda
Overview of buffer overflows
Stack-based
Structured Exception Handlers (SEH)
Heap-based
Buffer overflow myths
Reducing the risk of buffer overflow attacks in code with the
Microsoft SDL
Common Weakness Enumeration (CWE) Overview
Examples
Conclusions
2/37
Buffer Overflows Overview
Buffer Overflow: Occurs when data is written into a
fixed-length buffer and the size of that data exceeds the
capacity of the receiving buffer
4
Review of Application
Stack Frames (detailed)
int function_B(int a, int b)
{ push EBP
int x, y;
mov EBP, ESP // local variable ... ...
0xBFFFF000
x sub
= a *ESP,
a; 48h
0xBFFFF000
(small addresses)
(small addresses)
y ...
= b * b; int y
int x
fu nction B()s
stack frame
}
return (x + y); saved EBP stack frame
function B()s function A()s stack frame
saved EIP (ret addr in A)
int function_A(int p, int q) 0x01 (Bs arg 1 = int a)
int function_A(int p, int q)
{
push EBP
0x01 (Bs arg 2 = int b)
int c
local parameters
mov
c; EBP, ESP // local variables
function A()s
int saved EBP
stack frame
function A()s stack frame
sub ESP, 44h
c ...
= p * q * function_B(p, p);
saved EIP (ret addr in main)
0x01 (As arg 1 = int p)
saved frame pointer
memory addresses
push 1
return c; int res
}
push 1 calling parameters
fu nction main()s
call function_B
saved EBP
stack frame
main()s
saved EIP (retstack
addr)frame
0xBFFFFF00 int argc
int main(int argc, char **argv, char **env) (big ad dresses)
0xBFFFFF00 char **argv
{ push 2 (big ad dresses) char **env
int res;
push 1
call function_A ...
res = function_A(1, 2); ...
...
return res;
} Stack base
Stack base
5
Reference. M. Down et al., The Art of Software Security Assessment, Addison Wesley, 2012, pg. 175
Stack-Based Buffer Overflows
Primary Risk: Ability to overwrite control structures
6
Stack-Based Buffer Overflows (details)
Primary Risk: Ability to overwrite control structures
unsafe_function()s
strcpy(buffer, msg);
stack frame
int var
saved EBP
return var; saved EIP (ret addr in main)
} arg 1 = char *msg
int res
function main()s
int main(int argc, char **argv, char **env) saved EBP
stack frame
saved EIP (ret addr)
{
int argc
int res; 0xBFFFFF00 char **argv
(big ad dresses) char **env
/* Buffer overflow for strlen(argv[1]) >= 8
res = unsafe_function(argv[1]);
...
return res;
}
Stack base
7
Off-by-One Stack-Based Buffer Overflows
Primary Risk: Ability to overwrite local variables or saved EBP
unsafe_function()s
unsafe_function()s
function main()s
strcpy(buffer, msg); saved EBP
stack
stack
stack
} saved EIP (ret addr)
frame
frame
saved EBP
saved (0x0018FF2C)
int(0x0018FF00)
EBP
frame
argc
saved EIP (ret addr in main)
char **argv
int main(int argc, char **argv, char **env) 0x0018FF2C
0x0018FF00 arg char
1 = char *msg
**env
(corrupted
(original EBP
EBPininmain)
main)
{ int res
function
function main()s
saved EBP
stack
stack frame
int res; saved EIP (ret addr)
frame
int argc
main()s
/* Buffer overflow for strlen(argv[1]) >= 8 char **argv
res = unsafe_function(argv[1]); char **env
return res;
} ...
Stack base
8
Review of Application Heaps
void SampleFunction(void)
{
/* Allocate space on heap */
char * ptr = (char *)malloc(32); Pseudo-code For Chunk Freeing:
/* Operations */ NextChunk = Current->FP
PreviousChunk = Current->BP
/* Free allocated heap space */
free(ptr);
} NextChunk->BP = PreviousChunk
PreviousChunk->FP = NextChunk
9
Heap-Based Buffer Overflows
Primary Risk: Ability to write arbitrary 4 byte DWORD anywhere in memory
(return address, pointers, etc.)
/* UNSAFE Function */
Pseudo-code For Chunk Freeing:
void UnsafeFunction(char * str) AAAA
NextChunk = Current->FP
{ PreviousChunk = Current->BP
AAAA
/* Allocate 32 bytes heap space */
char * Buffer = (char *)malloc(32); NextChunk->BP
AAAA = PreviousChunk
AAAA
PreviousChunk->FP = NextChunk
/* Copy str into Buffer */
strcpy(Buffer,str);
}
FP BP AA(32Data
times)AA FP
AAAA BP
AAAA Data FP BP Data
11
Reference. M. Down et al., The Art of Software Security Assessment, Addison Wesley, 2012, pg. 179-180
Structured Exception Handling (SEH)
...
0xBFFFF000
(small addresses)
Buffer overflowed
Exceptio
Exception
Attacker Controlled
Stack Frame
Code
n Han dler #3
Pointer to _EXCEPTION_REGISTRATION
SHE Handler #3
Attacker Controlled
Stack Frame
Handler #2
Exception
Code
Pointer to _EXCEPTION_REGISTRATION
SHE Handler #2
Exception Handler #1
Stack Frame
0xBFFFFF00 Pointer to _EXCEPTION_REGISTRATION (-1)
(big addresses)
ad dresses) SHE Handler #1
...
Stack base
12
Reference. M. Down et al., The Art of Software Security Assessment, Addison Wesley, 2012, pg. 179-180
Reducing Exposure to Buffer Overflows with the
Microsoft SDL
Use safer
libraries and /GS, NX and
classes (StrSafe, Heap Checking
Safe CRT, STL)
Reducing
Reduce Attack
Surface and
Risk From Fuzz Testing
Least Privilege Buffer
Overflows
See Presentation:
Banned APIs
15
SDL:
Use Run-Time Protection
See Presentation:
Compiler Protection
16
SDL:
Use Code Analysis Tools
See Presentations:
Code Analysis
Source Code Annotation Language
17
SDL:
Use Fuzz Testing
See Presentations:
Secure Verification Principles
Fuzz Testing
18
Platform Protection
From Buffer Overflows
Modern day operating systems and processors
have built-in buffer overflow protection
Address Space Layout Randomization (ASLR)
Data Execution Protection (DEP)
However none of these are silver bullets
Denial of Service (DoS) attacks usually not prevented
More subtle attacks could still be performed
Developers still need to follow security best practices
Developers should always apply the Microsoft SDL
19
CWE Buffer-Overflow Related
CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer
CWE-120: Buffer Copy without Checking Size of Input ('Classic Buffer Overflow')
Rank 3 in the Top 25
CWE-121: Stack-based Buffer Overflow
CWE-122: Heap-based Buffer Overflow
CWE-124: Buffer Underwrite ('Buffer Underflow')
CWE-125: Out-of-bounds Read
CWE-131: Incorrect Calculation of Buffer Size (!)
Rank 20 in the Top 25
CWE-170: Improper Null Termination
CWE-190: Integer Overflow (!)
Rank 24 in the Top 25
CWE-193: Off-by-one Error
CWE-805: Buffer Access with Incorrect Length Value
20
Reference. CWE = Common Weakness Enumeration (http://cwe.mitre.org)
Example: local variable overwrite
Local variable int authenticate(char *username, char *password)
{
authenticate int authenticated;
char buffer[1024];
could be
overwritten authenticated = verify_password(username, password);
return authenticated;
}
21
Reference. M. Down et al., The Art of Software Security Assessment, Addison Wesley, 2012, pg. 176
Example: off-by-one error (1)
Error: wrong array indexing
22
Reference. M. Down et al., The Art of Software Security Assessment, Addison Wesley, 2012, pg. 180-181
Example: off-by-one error (2)
Error: wrong string terminator handling
if (strlen(user) >=
> sizeof(buf))
die("error: user string too long\n");
strcpy(buf, user);
}
23
Reference. M. Down et al., The Art of Software Security Assessment, Addison Wesley, 2012, pg. 180-181
Example: off-by-one error (3)
Error: wrong string terminator handling
24
Reference. CWE 193 (http://cwe.mitre.org/data/definitions/193.html)
Example: incorrect length value (1)
Error: wrong size limit considered
...
char source[21] = "the character string";
char dest[12];
strncpy(dest, source, sizeof(dest)-1);
sizeof(source)-1);
...
dest[sizeof(dest)-1)] = \0;
...
25
Reference. CWE 805 (http://cwe.mitre.org/data/definitions/805.html)
Example: incorrect length value (2)
returnChunkSize() int returnChunkSize(void *chunk) {
returns -1 on error /* if chunk info is valid, return the size of usable memory,
* else, return -1 to indicate an error
the return value is not */
...
checked before the }
memcpy operation
int main() {
memcpy() assumes ...
that the value is memcpy(destBuf, srcBuf,
unsigned (returnChunkSize(destBuf)-1));
when -1 is returned, ...
it will be interpreted }
as MAXINT-1 (e.g.
0xFFFFFFFE) #include <string.h>
void *memcpy(void *dest, const void *src, size_t n);
26
Reference. CWE 805 (http://cwe.mitre.org/data/definitions/805.html)
Example: incorrect length value (3)
if count is user bool CopyStructs(InputFile * pInFile,
(attacker) controlled unsigned long count)
is not checked !!! {
unsigned long i;
could be given to
generate a overflow in m_pStruct = new Structs[count];
the multiplication
operation for (i = 0; i < count; i++) {
allocates smaller space if (!ReadFromFile(pInFile, &(m_pStruct[i])))
than accessed break;
}
}
27
Reference. M. Howard et al., 24 Deadly Sins of Software Security, 2010, p. 97
Example: incorrect calc. of buffer size (1)
malloc(3) allocates just int *id_sequence;
id_sequence[0] = 13579;
id_sequence[1] = 24680;
id_sequence[2] = 97531;
28
Reference. CWE 131 (http://cwe.mitre.org/data/definitions/131.html)
Example: incorrect calc. of buffer size (2)
numHeaders defined as a DataPacket *packet;
DataPacket *packet;
signed int int numHeaders;
int numHeaders;
when assigned a huge PacketHeader *headers;
PacketHeader *headers;
unsigned number, it results in
a negative number sock=AcceptSocketConnection();
sock=AcceptSocketConnection();
ReadPacket(packet, sock);
when compared, condition is ReadPacket(packet, sock);
fulfilled numHeaders = packet->headers;
numHeaders = packet->headers;
when used in malloc, it is if (numHeaders > 100) {
converted back to an unsigned if (numHeaders > 100 || numHeaders < 0) {
ExitError("too many headers!");
integer => a huge number } ExitError("too many headers!");
Example }
29
Reference. CWE 131 (http://cwe.mitre.org/data/definitions/131.html)
Example: incorrect calc. of buffer size (3)
when input user const long MAX_LEN = 0x7FFF;
controlled char dst[MAX_LEN];
Problem 1: truncation
short len = strlen(input);
strlen() returns size_t
len is short if (len < MAX_LEN)
Problem 2: type strncpy(dst, input, len);
casting
len converted to an
(signed) int
size_t strlen(const char *s);
30
Reference. M. Howard et al., 24 Deadly Sins of Software Security, 2010, p. 121
Example: out-of-bound access (1)
the buffer index is not validated
allows access outside the intended area
31
Reference. CWE 125 (http://cwe.mitre.org/data/definitions/125.html)
Example: out-of-bound access (2)
the buffer index is only checked against the upper limits, but
not against the lower one (i.e. zero)
int getValueFromArray(int *array, int len, int index)
{
int value;
return value;
}
32
Reference. CWE 125 (http://cwe.mitre.org/data/definitions/125.html)
Example: Improper Null Termination (1)
inputbuf could be not NULL terminated
strcpy could copy more than MAXLEN
#define MAXLEN 1024
...
char *pathbuf[MAXLEN];
...
read(cfgfile, inputbuf, MAXLEN); //may not null terminate
strcpy(pathbuf, input_buf); //requires null terminated input
...
33
Reference. CWE 170 (http://cwe.mitre.org/data/definitions/170.html)
Example: Improper Null Termination (2)
buf could be not NULL terminated
length could be greater than MAXPATH
char buf[MAXPATH];
char dst[MAXPATH];
...
readlink(path, buf, MAXPATH);
int length = strlen(buf);
...
strncpy(dst, buf, length);
34
Reference. CWE 170 (http://cwe.mitre.org/data/definitions/170.html)
Real-Life Examples
First well-known Internet worm: Morris finger worm (1988)
Common Vulnerabilities and Exposures (https://cve.mitre.org/find/index.html)
Searching string buffer overflow About 639 results (actually few thousands)
Vulnerability Notes Database (https://www.kb.cert.org/vuls/)
Searching string buffer overflow About 240 results
Examples
CVE-2015-0235 - GHOST: glibc gethostbyname buffer overflow
CVE-2014-0001 - Buffer overflow in client/mysql.cc in Oracle MySQL and MariaDB before 5.5.35
CVE-2014-0182 - Heap-based buffer overflow in the virtio_load function in hw/virtio/virtio.c in QEMU before 1.7.2
CVE-2014-0498 - Stack-based buffer overflow in Adobe Flash Player before 11.7.700.269
CVE-2014-0513 - Stack-based buffer overflow in Adobe Illustrator CS6 before 16.0.5
CVE-2014-8271 - Tianocore UEFI implementation reclaim function vulnerable to buffer overflow
CVE-2013-0002 - Buffer overflow in the Windows Forms (aka WinForms) component in Microsoft .NET Framework
CVE-2005-3267 - Integer overflow in Skype client leads to a resultant heap-based buffer overflow
35
Conclusions
Buffer Overflow
classical, well known, still present (oldie but goldie)
due to
the usage of unsafe function and non-validated user input
logic (calculation) errors
Recommendations for Code Developers
Do not use unsafe (string) functions
Use the right compiler/linker options
Check allocation size calculations
Do make size checking
Take care of automatic type casting and possible integer overflows
use size_t (when possible) for allocation size variables
take care at casts from signed to unsigned
.
Recommendations for Code Reviewers
Check for user input and trace it through the application
Check for unsafe functions
Check for allocation size calculations