Download Understanding Buffer Overruns in C: Causes, Consequences, and Solutions - Prof. Aaron Bloo and more Study notes Programming Languages in PDF only on Docsity!
Language Security (1) Language Security (1)
Or: bringing a knife to a gun fight
One-Slide Summary
- (^) A language’s design principles and features have a strong influence on the security of programs written in that language.
- (^) C’s legacy of null-terminated , stack- allocated and non-sized buffers leads directly to the most common sort of security vulnerability: the buffer overrun.
- (^) What can be done?
Lecture Outline
- (^) Beyond interpreters
- (^) Looking at other issues in programming language design and tools
- (^) C
- (^) Arrays
- (^) Exploiting buffer overruns
- (^) Detecting buffer overruns
Duck-billed Platitudes
- (^) Language design has profound influence on
- (^) Safety
- (^) Efficiency
- (^) Security
Arrays in C
char buffer[100]; Declares and allocates an array of 100 chars 100*sizeof(char) (^0 1 )
C Array Operations
char buf1[100], buf2[100];
Write:
buf1[0] = ‘a’;
Read:
return buf2[0];
Indexing Out of Bounds
The following are all legal C (no parse errors, no type errors, etc.) and may generate no run-time errors char buffer[100]; buffer[-1] = ‘a’; buffer[100] = ‘a’; buffer[100000] = ‘a’;
Why Ask Why?
• Why does C allow out of bounds
array references?
– Proving at compile-time that all array
references are in bounds is very
difficult ( why? )
– Checking at run-time that all array
references are in bounds is expensive
( why? who does this? )
C vs. Java
- (^) Typical work for a C array reference
- (^) Offset calculation
- (^) Memory operation (load or store)
- (^) Typical work for a Java array reference
- (^) Offset calculation
- (^) Memory operation (load or store)
- (^) Array bounds check
- (^) Type compatibility check (for stores) ( why? )
Buffer Overruns
- (^) A buffer overrun writes past the end of an array
- (^) Buffer usually refers to a C array of char
- (^) So who’s afraid of a buffer overrun?
- (^) Cause a core dump
- (^) Can damage data structures
- (^) What else?
An Overrun Vulnerability
void foo(char in[]) {
char buffer[ 100 ];
int i = 0;
for(i = 0; in[i] != ‘\0’; i++)
buffer[i] = in[i];
buffer[i] = ‘\0’;
An Interesting Idea
char in[104] = { 0,…,0, magic 4 chars } foo(in); (*) 100 sizeof(char) 0 1 2 99 return address foo entry () 100 *sizeof(char) 0 1 2 99 return address foo exit magic 4 chars
The Rest of the Story
- (^) Say that foo is part of a network server and the in originates in a received message - (^) Some remote user can make foo jump anywhere!
- (^) But where is a “useful” place to jump?
- (^) Idea: Jump to some code that gives you control of the host system (e.g. code that spawns a shell)
- (^) But where to put such code?
- (^) Idea: Put the code in the same buffer and jump there!
Useful Jumps
- (^) Where to jump?
- (^) We want to take control of the program
- (^) How about to a system call?