200 likes | 215 Views
Detecting Memory Access Errors via Illegal Write Monitoring. Ongoing Research by Emre Can Sezer. ASLANLAR '05. Outline. Quick wrap-up of last semester’s presentation Basic design Problems and Solutions Pointers Structure types Discussion Performance considerations Applications.
E N D
Detecting Memory Access ErrorsviaIllegal Write Monitoring Ongoing Research by Emre Can Sezer
ASLANLAR '05 Emre Can Sezer
Outline • Quick wrap-up of last semester’s presentation • Basic design • Problems and Solutions • Pointers • Structure types • Discussion • Performance considerations • Applications Emre Can Sezer
Wrap-up of last semester’s talk • C is not type safe, and continue to have vulnerabilities • Worm outbreaks • NIDS’s can only detect random scanning worms • NIDS’s accept a certain number of casualties • Data attacks evade most HIDS’s • We need a good host-based framework to detect a broad range of memory corruption attacks Emre Can Sezer
Overflow Main Observation with an Illustrative Example • Line 11 can overflow buffer. • Line 11 should only be writing to buffer. Activation Record of func() on stack 1 void func () { 2 int isAdmin; 3 char buffer[255]; 4 isAdmin = 0; 5 if ( check_pssw(buffer) ) { 6 isAdmin = 1; 7 } else { 8 isAdmin = 0; 9 } 10 … 11 scanf (“%s”, buffer); 12 … 13 if (isAdmin) {…} else {…} 14 … 15 return; 16 } Ret. address isAdmin Buffer[255] Emre Can Sezer
Basic Design • Observation: A memory location is only modified by a small number of instructions. • Idea: • Select a list of memory locations to monitor • For every location determine the list of instructions that can modify it, called the memory location’s write set (WS). • At runtime perform checks to ensure monitored memory locations are only modified by instructions in their WS. • Implementation has two parts: • Static analysis • Dynamic monitoring Emre Can Sezer
Static Analysis • Use source code analysis • For every variable, determine the variable’s WS. • Assignment instructions where the variable is on the LHS. • Library function calls in which the variable is used as an argument that the function can modify (i.e. memcpy()) • Current implementation uses Code Surfer • A script automatically extracts all the information required Emre Can Sezer
Dynamic Monitoring • Terminology • Monitoring agent is called “agent” for short • The list of memory locations that are being monitored is M. • Illegal write checking • Capturing of memory writes and set membership checks • State maintenance • Capturing function calls and returns • Capturing malloc family of function calls • “Points to” tracking for pointers* • We have written a skin for Valgrind, an open source x86 emulator, for dynamic monitoring Emre Can Sezer
System Overview Emre Can Sezer
? Problems and Solutions • Static Analysis and Dynamic Monitoring don’t talk the same language If code is compiled with debug flags, a PC can be translated into a file name and line number. Emre Can Sezer
Finding variables on memory • Global variables • Reside in the data segment • Have fixed addresses • Local variables • Their addresses depend on the function call stack • They are defined as offsets from the beginning of the function’s activation record • Function calls must be monitored at runtime Emre Can Sezer
Problem: Good old pointers • Line 4 is writing to a heap location • How do we monitor and associate with line 4? • Solution: • For a pointer p, keep two separate WS’s • One for the pointer variable itself WS(p) • Another for the memory region it points to WS(ref(p)) • At runtime determine ref(p) and add WS(ref(p)) to ref(p)’s WS. 1 void main () { 2 int * array; 3 array = (int *) malloc (10*sizeof(int)); 4 array[5] = 42; 5 } Emre Can Sezer
Problem: Good old pointers • Side benefits • Inter-procedural static analysis is not required. • Pointer aliasing and arithmetic can be handled. Emre Can Sezer
Problem: Good old pointers • If a function has pointer type formal arguments, we check where they point to at function call time • In this example, line 2 is added to a’s WS. • 1 int square (int * num) { • 2 *num = (*num) * (*num); • 3 } • 4 void main () { • 5 int a; • 6 scanf (“%d”, &a); • 7 square (&a); • 8 printf (“%d\n”, a); • 9 } Emre Can Sezer
Problem: Chained Dereferences • Our current approach cannot handle this situation • Relation between line 4 and var z is lost • Solution: • Use source code rewriting • Replace all complex dereferences with simple dereferences by introducing temporary variables 1 int z; 2 int * y = &z; 3 int ** x = &y; 4 **x = 5; 1 int z; 2 int * y = &z; 3 int ** x = &y; 4a int * temp1 = *x; 4b *temp1 = 5; Emre Can Sezer
Problem: Structures • Not handled in our current implementation • Solution: • Treat every field of a structure as a separate variable with its own WS • Instructions operating on a structure variable is added to each field’s WS seperately struct { int num; char str[4]; } entry; 1 int main () { 2 struct entry var; 3 strcpy(var.str, "Hello"); 4 return 0; 5 } • struct { • int num; • char str[4]; • } entry; • int main() { • 2 struct entry base; • 3 struct entry * var = &base; • 4 strcpy(var->str, "Hello"); • 5 } Emre Can Sezer
Discussion: Capabilities • Detects memory corruption errors at the time of write • Can provide information about: • Instruction causing the error • Variable that was illegitimately written to • Current user stack • The error type (buffer overflow, double free etc.) Emre Can Sezer
Discussion: Performance • No real performance results yet • Expecting to see 20x slow down • We keep data structures for each variable, so memory requirement may be high • Implications? • How much CPU/RAM does a web server use? • How bad is bad? 1% increase 1000% increase? • How does application runtime overhead influence service? Emre Can Sezer
Discussion: Applications • Attack identification • Use light-weight IPS • Replay attack on instrumented version to identify attack • Debugging tool • Testing and debugging usually don’t have lower performance demands Emre Can Sezer
Memory Level Monitoring for Detecting Illegal Writes Ongoing Research by Emre Can Sezer