Logo Umeet2001

ESPAÑOL
Presentación

Programa

Desarrollo

ENGLISH

Presentation

Programa

Desarrollo


fernandoHello,
fernandowe are very pleased to have here today Mr. David Larochelle. He is a
fernandograudate student in Computer Science at the University of Virginia working
fernandowith Dave Evans on annotation-assisted static checking.
fernandoThey work on a tool that all of you, for sure, know: LCLint (Soon to be
viXardDavid Larochelle
fernandoLet me thank all of you for comming here, and specially, David Larochelle
fernandofor preparing this tallk.
fernandoHe has prepared some slides for the talk, you can access them via our web
fernandopage
fernandohttp://umeet.uninet.edu/umeet2001/talk/10-12-2001/umeet/umeet.htm
fernandohttp://www.cs.virginia.edu/~drl7x/umeet/umeet.htm
fernandoThe title is: ' Statically detectting likely buffer overflow
fernandovulnerabilities.' It is based on a paper that was presented at USENIX, this
fernandosummer.
fernandoMr. Larochelle. ...
drl7xThank you
fernandoyou can make questions in #qc
drl7xHello.  This talk is based largely on a paper in this years usenix security
drl7xif you want more detail you can find the paper at lclint.cs.virginia.edu
drl7x13 years ago, many computers on the Internet became saturated to the point of being unusable.
drl7x The culprit was the now infamous Morris Internet worm.
drl7xExploiting a buffer overflow in fingerd was one of the primary methods the worm used to compromise systems.
drl7xAt this time the dangers of buffer overflows were not well understood, so it's understandable that a common security critical Internet demon was vulnerable.
drl7xBut buffer overflows are a simple program flaw and the consequences of buffer overflows were soon well understood within the security community.
drl7xToday buffer overflows remain a problem.
drl7xBuffer overflows in IIS are still being explioted by the code red worm.
drl7xBuffer overflows have remained the single largest cause of vulnerabilities in CERT advisories.   Earlier this year the WSJ described a buffer overflow in bind as a threat to the Internet.
drl7x
drl7xIf you have access to the slides you can see that the Wall Street Journal web page recently provided a more compleeling testment to
drl7xthe dangers of buffer overflows.
drl7x(The site was defaced earlier this year.
drl7xslide 2
drl7xWhy aren't we better off than we were 13 years ago?
drl7xPart of the problem is certainly lack of education.  There are definitely a lot of programmers that are not aware of the dangers posed by buffer overflows and how to prevent them.
drl7xThe security community understands buffer overflows but this knowledge has not been codified in a way that typical programmers can benefit from it.
drl7xThis is important because The C language is hard to program in securely.
drl7xThere's no bounds checking which is what permits buffer overflow attacks in the first place.
drl7xBut the standard library exacerbates the situation. There are functions such as strcpy that are easy to use incorrectly and even function such as gets which are always unsafe.
drl7xEven the so-called safe functions such as strncpy and strncat have confusing and inconsistent APIs.
drl7xFor these reasons, even security aware programmers make mistakes.
drl7xTo illustrate, this latter we'll show an example of a subtle error in code that was published by a major security web site.
drl7xBecause programmers will always make mistakes, we need to use automated tools.
drl7xslide 3
drl7xTwo possible approaches automated tools can take are run-time and compiler time.
drl7xRun time solutions work by creating executables with additional checking to detect buffer overflows.
drl7xFor example, StackGuard is a compiler which produces special binaries to detect stack smashing attacks.
drl7xThere are 2 problems with the run-time approach.  First because of the additional checking there will be some type of performance penalty.
drl7xMore significantly, there's usually no sensible way to recover when a buffer overflow is detected so the buffer overflows become a denial of service attack.
drl7xAn alternative is a compile time approach.  Which is the approach we take.
drl7xHere, problems are detected by examining the source code without running it, usually at compile time or as part of the compilation process.
drl7x The problems are then fixed in the source code so there is no run-time performance penalty.
drl7xStatic analysis is able to check properties of all possible program executions.
drl7xThis is extremely useful for detecting security problems because security problems often occur in obscure cases which are not likely to come up in testing or normal use.
drl7xAlso this approach can be used to compliment the run-time approach.
drl7xnext slide
drl7xWe wanted to create a tool that typical programmers would be willing and able to use as part of the development process.
drl7xIn order to do this we needed it to be fast, -- about as fast as a compiler. And we also wanted it to be easy to use.
drl7xAdditionally we wanted the tool to be useful for analyzing legacy code.
drl7xEither for auditing existing code or for someone making changes who did not want to introduce new vulnerabilities.  To do this our tool needed to handle code in typical C programs.
drl7xFinally we want to encourage a proactive approach to security.
drl7x Rather than just directing programmers to fix confirmed bugs, we want programmers to avoid potentially dangerous constructs and only use them if they have clear well documented assumptions.
drl7x<next slide >
drl7xOur approach is to document assumptions about buffers using semantic comments or annotations.
drl7x These are special comments which are treated as comments by the compiler but are recognized to contain semantic information by our tool.  We provide an annotated version of the standard library internally and allow users to annotate their code.
drl7xOur checking works by finding inconsistencies between the code and annotations.
drl7xIn order to have a tool that's useful in real world situations, we make a number of compromises.  We make simplifying assumptions to improve efficiency. And we use heuristics to analyze common loop idioms.
drl7xAs a result we accept some false positives and false negatives.
drl7xIt's worth mentioning that like many interesting program properties detecting buffer overflows is an undecidable problem.
drl7x So all tools must accept either false positives or false negatives or restrict the kinds of programs they work on.
drl7x<slide 7>
drl7xWe implemented our tool by extending LCLint, an open source static checking tool.
drl7x By using annotations LCLint is able to detect a variety of problems such as memory leaks and null pointer errors which can not be detected by a standard lint.
drl7xWe integrated our checking into LCLint.  Which allowed us to leverage the existing checking and annotations within LCLint.
drl7xWe extended LCLint by adding new annotations and checking regarding buffer sizes.
drl7xI should mention that we've since decided to rename the tool to splint.  This renaming isn't official yet but will be soon
drl7x<slide 8>
drl7xTwo annotations we added are maxSet which denotes the highest index of an array that can be safely written to and maxRead which denotes the highest index of an array that can be safely read from.
drl7xThe requires and ensures denote whether it is a  function precondition or postcondition.
drl7xFor example, the declaration of buffer as a static array would cause LCLint to generate a constraint equivalent to ensures maxSet(buffer) == 99.
drl7x<next slide>
drl7xHere';s the example I mentioned earlier.
drl7xThis works best if you go to slide 9.
drl7x It comes from a guide to secure programming from the SecurityFocus web site.
drl7xIn the guide they suggest that programmers use strncat instead strcat and provide this as an example of how to use strncat.
drl7xAt first glance the problems with this example are not obvious.  Here's an annotated declaration of strncat.
drl7xTHe code was basicly
drl7xchar buffer[256]
drl7xstrncat (buffer, str, sizeof(str) -1 )
drl7xwhere str is a function parameter.
drl7xThere are two problems here
drl7xfirst the buffer is uninitialized
drl7xadditionally the user has confused the requirement of strncat.
drl7xnext slide
drl7xIf you can see this slide it gives an example of the warning reported by lclint
drl7x,slide 11.
drl7xOur checking takes place entirely within functions.  But we are able to check interprocedural properties by using annotations to check functions calls and the state of function at entry and exit points.
drl7xWe generate constraints at the expression level using C semantics and annotations in the case of function calls.
drl7xWe propagate and resolve constraints using axiomatic semantics.  We use a set of simplifying rules to help resolve constraints.
drl7x In the previous slides LCLint used simple algebra to combine to terms.
drl7x We also have LCLint specific rules.  For example,
drl7xthe rule  maxRead(str + i) = maxRead(str) - i
drl7xthis helps us to handle code in which a pointer has been incremented.
drl7xFinally we produce error messages for any constraints that can not be resolved.
drl7x<slide> 12 loop heuristics
drl7xTraditionally loops have been analyzed using invariants.
drl7x But loop invariants are extremely difficult to generate automatically and programmers have been reluctant to add them by hand.
drl7xWe wanted to avoid loop invariants.
drl7xBut we still needed to analyze loops reasonably well.
drl7xWe found that many loops have common forms.  By recognizing common loop idioms we were able to develop a series of heuristics that work for many loops in real programs.
drl7xFor example, in the loop:
drl7xfor (init; *buf; buff++)
drl7x we assume that the loop runs for maxRead(buf) iterations and we model the first and last iterations of the loop.
drl7xSo the last iteration will be checked assuming buf_last = buf_orig + maxRead (buf) ).
drl7x  
drl7xObviously this approach will not always be correct but we've found that this approach works for many loops in real programs.
drl7x<next slide 13>
drl7xTo test our tool we used it to analysis two security critical open source programs.
drl7x We analyzed wu-ftpd and a subsection of BIND.
drl7xIn both cases we successfully  detected known bugs.
drl7xAdditionally we were able to detect unknown buffer overflows exploitable by users with write access to
configuration files.
drl7xOur tool ran fast enough, that we believe it's reasonable for users to add it to the makefile as part of the built process.
drl7x(It took about 7 seconds to analyze wu-ftpd 2.50)
drl7xand 33 secnonds to analyze Bind
drl7xwu-ftpd is 20000 lines
drl7xbind is 40,000 lines
drl7xThe table in slide 14 has a nice summary of the results
drl7xRecently we reanalzed wu-ftpd
drl7xWith no annotations we the tool porduced 166 warning for out-of bounds writes.
drl7xAfter iteratively adding annotations and rerunning the tool
drl7xlclint produced 101 warnings for buffer overflows
drl7x25 or these were real problems while 76 were spurios messages.
drl7xSlide 15
drl7xTHis is an example of a bug in wu-ftpd that we detected.
drl7xint access_ok( int msgcode) {
drl7x    char class[1024], msgfile[200];
drl7x    int limit;
drl7x  limit = acl_getlimit(class, msgfile);
drl7x Here the function getaclentry sets entry->arg[3] to point to a string of potentially arbitrary length read from a configuration file.
drl7xThe str copy this into  msgpathbuf
drl7xstrcpy(msgpathbuf, entry->arg[3];
drl7xWhen we run lclint to reports:
drl7xa potential buffer overflow here
drl7xBy adding annotations and changes to strncoy to determine that the function
drl7xLCLint is able to determine that the function is safe.
drl7xHow ever we had to make a number of changes to the function and rerun lclint before we could be sure of saftey
drl7xslide 16
drl7xRelated work
drl7xTraditionally, lexical analysis has been used to find vulnerabilities.
drl7x Using a tool such as grep an auditor would scan a program for potentially unsafe library functions. Recently tools such as ITS4 combine this approach with a data base of potentially unsafe functions.
drl7xLexical analysis is limited to detecting vulnerabilities  involving library functions.  And tends to produce a large number of false positives.
drl7xWagner has developed a system to detect vulnerabilities by modeling c strings as an abstract data type which is accessed through library functions.
drl7x  Flow insensitive analysis is used to resolve constraints.
drl7xThis approach does not require annotations and scales very well.
drl7xBut flow insensitive analysis is imprecise causing large numbers of false positives.
drl7x  Also this approach can not detect buffer overflows that occur as a result of a direct access to a  buffer.
drl7xRecently Dor has attempted to detect buffer overflows by performing a source to source transformation.  
drl7x This is creates a safe program which contains additional variables and assert statements.
drl7x Buffer overflows in the original program are detected by finding cases where assert statements in the safe program which may fail.
drl7xslide 17
drl7xWe recognize that there are certain impediments to the wide spread use of our tool.
drl7xPeople are lazy and
drl7xprogrammer are lazier than most people.
drl7xAdding annotations may be too much work except for security weenies.
drl7xWe're currently working on techniques to automate the process.
drl7x<slide 18 conclusions>
drl7xWhat will things be like 13 years from now?
drl7xWill buffer overflows still be commonly exploited.
drl7xWithin the security community, buffer overflows have long been a well understood problem.
drl7xHowever, buffer overflows have remained far too common.
drl7xIf we want 2013 to be better than 2001, we, the security committee, must work to codify our knowledge into tools  that real programmers can use as part of the development process so that our expertise reaches real developers.
drl7xThe creation of static checking tools is a promising way of doing this.
drl7xUpdate:
drl7xThere are a couple of new additions to LCLint which are not included in the slides.
drl7xWe now offer ITS4 like functionality in which
drl7xevery instance of a potentially valnerable function such as gets
drl7xis reported.
drl7xHowever our approach uses a full parse tree so if gets is used as a variable or in a string literal no warning is reproted.
drl7xTHanks you for listening to this talk.
mjcomaclap clap clap clap clap clap clap clap clap clap
mjcomaclap clap clap clap clap clap clap clap clap clap
mjcomaclap clap clap clap clap clap clap clap clap clap
mjcomaclap clap clap clap clap clap clap clap clap clap
Chesssplash splash splash splash splash splash splash
Chesssplash splash splash splash splash splash splash
fernandplas plas plas plas plas plas plas plñas plas
Chesssplash splash splash splash splash splash splash
fernandplas plas plas plas plas plas plas plñas plas
fernandplas plas plas plas plas plas plas plñas plas
Chesssplash splash splash splash splash splash splash
peter11plasplas plas plas plas plas plas plas plas plas
peter11plasplas plas plas plas plas plas plas plas plas
peter11plasplas plas plas plas plas plas plas plas plas
sarnold_thank you drl7x; so, your static tool (lclint, correct?) requires marking up the source code in order to disable warnings on 'known good' pieces of code?
drl7xOkay sarnold
drl7xYou had the first question
drl7xIt does a combination of things.  
drl7xYou use annotations to mark up source code so that lclint has more information
drl7xfor example so it knows a function is only called with a buffer of size 100
drl7xHopefully this additional information will be verified by lclint
drl7xIn the worst case you can explictedly mark code safe
sarnold_is there an easy way to tie together the LCLint "100 element array" with the declaration/malloc of the buffer to 100 elements?
drl7xYes.  We have an internal annotated version of the standard library.
drl7xmalloc has the annotation:
drl7xthis tells us that str = malloc(100); implies that str[99] or lowwer is okay
sarnold_hmm, I think I missed the annotation..
sarnold_(did it start with '/' ? :)
drl7xSorry the annotation is * void malloc (size_t size) /*@ensures maxSet(result) == (size - 1) @*/
drl7xYes the anotations are ine /*@ .. @*/
drl7xOther questions
sarnold_yes, one sec :)
fernandwhat do you think of cyclone and other similar approaches?
Amanda15,15·14,14·06,00 Buenas tardes a todos 14,14·15,15·
drl7xI think cyclone is an interesting project.
sarnold_drl7x, how does LCLint handle functions that take variable-sized arrays as their arguments?
drl7xcyclone for these who don't know is an attempt to make a type safe version of C
drl7xThis is a thing and in would be good if people used safer languages.  
drl7xHowever, many safe languages already exist: java, ada, etc.
drl7xStill people insist on probleming C.  
drl7xWhatever benefits a new language has geting people in switch languages is difficult.
drl7xPerhaps cyclone is close enough in C that people will be willing to switch.  But history indicate that this isn't likely to happen.
drl7xnext question
sarnold_drl7x, how does LCLint handle functions that take variable-sized arrays as their arguments?
BryamHola a todos....
drl7xWe use the required annotation for example:
drl7xfoo (char *s, int n ) /@requires maxSet(s) >= n @*/
drl7xthis says that this function is only safe if the buffer pointed to by s is larger than n
sarnold_ok, and that ties together with the size declarations at static compile time, or the dynamic /*@ensures maxSet(result) == (size - 1) @*/ from malloc() ?
drl7xWell when we check the body of foo we assume that the annotations is true....
sarnold_and, as a final pestering question (that I can think of right now :), how would that last example be modified, say, for free(), which is going to back up four bytes or something similar, using *(variable - 4) to get to housekeeping information?
drl7x  THIS IS for the previos question: Every time the foo is called we report an error this we can't verify the precondition for the actuall paramenter.
drl7xLet me think about your next question...
drl7xAre you asking using free then accessing the memory?
sarnold_no, no
sarnold_asking how LCLint can verify that free(3) isn't going 'out of bounds' when it takes ptr-4 to get to its own data ..
sarnold_maxSet(ptr) >= n-4 ?
drl7xYou mean free( *(ptr -3) ) or free (ptr - 3)
sarnold_heh, sometimes IRC isn't perfect :)
sarnold_free(3) as in the libc implementation of malloc...
sarnold_I'm curious if LCLint can protect from buffer 'underruns'; the malloc implementation often uses the four bytes previous to the ptr to store house-keeping information..
sarnold_since there is no count on the size of the data blob to be free()ed, except in implementation-specific data structures, does LCLint punt and say, "Hmm, call to free(), looks fine" :), or does it try to do more analysis to see if the free() call is legitimate?
sarnold_(and yes, it is legit to say, "go read the USENIX paper" :)
drl7xI'm not exactly sure free is implemented internally.  We dodn't check the internal workings of standard libraries have some memor
drl7xinstead me just an annotated declaration...
drl7xWe do have the option to detect buffer underflows.  We have a minSet and minRead options.  I found that underflows we're common enough to
drl7xjustify checking for them in many cases though.
drl7xYes.  Or download the beta version.  Some of the code examples didn't translate well to IRC.  
sarnold_heh, yeah, that is true
sarnold_the number of vulnerabilities i've seen that exploited free() are much more rare than overflow auto variables.. :)
sarnold_drl7x, well, I think I am finally out of questions :) thanks again
drl7xLCLint does try to detect memory leaks with free.
drl7xsarnold thanks for your questions.

Generated by irclog2html.pl by Jeff Waugh - find it at freshmeat.net!


Mas información: umeet@uninet.edu