Program SecurityCOMS W4115Prof. Stephen A. EdwardsFall 2005Columbia UniversityDepartment of Computer ScienceOriginal by Prof. Angelos KeromytisWhy Security?Many, many more computers and users than ten yearsago.Internet changes the whole game: easy to be attackedfrom the other side of the planet.Military-style security of permission levels, groups, etc.worked for closed mainframes, imperfect for networkedcomputers.Trojan HorsesLeave a program running that looks like the login prompt:ExploitsAt least 40/week on BUGTRAQ mailing listphrack.com is a how-to guideConstruct-your-own exploit wizards? Point-and-click tobreach security?Code VulnerabilitiesProtocols and algorithms often good; implementationsrarely areSource is bad code with subtle bugs:Buffer overflowsRace conditionsSQL injectionWhat’s Wrong With This Code?int main(int argc, char**argv) {char fname[]= "/tmp/testfile";char buffer[16];u_long distance;distance= (u_long)fname - (u_long)buffer;printf("fname = %p\nbuffer = %p\ndistance = 0x%x bytes\n",fname, buffer, distance);printf("fname = %s\n",fname);strcpy(buffer, argv[1]);printf(fname = %s\n",fname);return 0;}Stack Smashing ScenarioPC foo()’sbuf[16] activationrecordPC strcpy()’sactivationrecordvoid foo(char*mystring) {char buf[16];strcpy( buf, mystring );}Heap SmashingSimilar trick works when buffer is on heap and somethingon the heap is treated as a function pointer.e.g., a C++ virtual table pointerclass C {virtual void foo();}void foo(char*mybuffer) {C c = new C();char*buf = new char[10];strcpy(buf, mybuffer);c->foo();}SQL code injectionSQL queries typically built as a string and passed to thedatabaseString query ="select*from mysql.user where username=’" +uid + "’ and password=password(’" + pwd + "’);";mydb.submit(query);But what if the uid the user supplied is malicious? Couldget the queryselect*from mysql.user where username=’’ or 1=1; /*’ and password=password(’whatever’);Nice way to get, say, all the credit card numbers from ane-commerce site.Race ConditionsThe Unix filesystem is a shared resource. Things canchange from when you check something to when you useit. Example from the “passwd” program:Pick a “random” filenameIf the file already exists in /tmp, try againOpen the fileCopy the contents of /etc/passwd to the /tmp fileRemove existing entry; add the new oneCopy the /tmp file to /etc/passwdSolutions?Things to ask about any solution:How much does it slow things down?How effective is it against existing and future attacks?How much of a pain is it to use?Solutions: Code SigningSomebody you trust “signs” the code cryptographicallyYou check signature before you install and run itWorks so-so: is it practical to check everything?What if it doesn’t come from Microsoft?Do you really trust Bill Gates?Widely-used: an obvious first line of defenseSandboxing: Unix’s chroot()In Unix, everything interesting is part of the filesystem.So limit what a process can do by changing whatfilesystem it sees.chroot("/usr/ftp");/*... public FTP server ...*/FreeBSD’s jail() system call even strongerSandboxing: System CallMonitoringMonitor pattern of system calls in the OS kernelIf a process deviates from what it’s allowed to do,terminate itWorks OK for daemons, but what to do for arbitrarydownloaded code?Who writes these policies?Java’s Security Manager does something like thisSolutions: Static AnalysisRun a complex compiler-like program on source code thatidentifies all vulnerabilitiesReally tricky to do quickly and accuratelyFundamentally undecidable; interesting work is on safeabstractionsAn open field of researchSolutions: Dynamic AnalysisAugment buffers with size informationAdd checks before all reads and writesInvasive; difficult to get rightAnother approach: Perl’s “taint” model: Track whichinformation has come from a potentially malicious userand don’t allow it to be used in certain ways.Solutions: Software Fault IsolationAugmenting binaryInsert checking code around each load, store, or jump thatchecks it before it is doneCan be done at compile, link, or run timeSlows things down, bloats codeReally a mess for CISC architectures, which alwaysaccess memoryCompiler Tricks: StackGuardIdea: Put a canary on the stack and check if it is still alivebefore returning.PC foo()’sbuf[16] activationrecordcanaryPC strcpy()’sactivationrecordvoid foo(char*mystring) {char buf[16];strcpy( buf, mystring );}Nice defense againststack-smashing, but doesn’t doanything for heap smashing, SQLinjection, etc.Solutions: Better APIsC’s string manipulation routines are some of the worstoffenders.char*strcpy(char*dest,const char*src);char*strncpy(char*dest,const char*src,size_t n);Solutions: Better APIsNAMEtmpnam — create a name for a temporary fileSYNOPSISchar*tmpnam(char*s);DESCRIPTIONThe tmpnam() function returns a pointer to a string that isa valid filename, and such that a file with this name did notexist at some point in time, so that na¨ıve programmersmay think it a suitable name for a temporary file.BUGSNever use this function. Use mkstemp(3) instead.Solutions: Better LanguagesWe’re language people, so we should be able to solveeverything.Java, ML, Erlang, etc. aren’t subject to buffer overflowattacks (we hope)Cyclone is a “safe subset” of C (we hope)CCured: Static analysis of C plus runtime checks for whatcannot be determined
View Full Document