10.08.2015 Views

Fuzz By Number

Fuzz By Number - CanSecWest

Fuzz By Number - CanSecWest

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>Fuzz</strong> <strong>By</strong> <strong>Number</strong>More Data About <strong>Fuzz</strong>ing Than You Ever Wanted To KnowCharlie MillerIndependent Security Evaluatorscmiller@securityevaluators.comMarch 28, 2008


Who Am I?Former NSA security guyBreak stuff: iPhone, SecondLifeGive talksWrite books“Open Source <strong>Fuzz</strong>ing Tools” (co-author)“<strong>Fuzz</strong>ing for Software Testing and Quality Assurance”Due out in June


Agenda<strong>Fuzz</strong>ing, why we careHow do you test fuzzers?My testingResultsWhy some bugs are harder to find than othersAnalysis and fun facts


<strong>Fuzz</strong>ingSend invalid/semi-valid data into a systemIf data is too valid, might not cause problemsIf data is too invalid, might be quickly rejectedMonitor system for faultsNot the best tool, but finds lots of bugsBetter at finding some classes of bugs than othersi.e. buffer overflows versus race conditions


Generating Test CasesMutation-based approachTake valid data and add anomaliesOnly as good as the quality of valid dataEasy: requires no knowledge of protocolGeneration-based approachGenerate test cases from protocol specificationHard: need to represent all possibilities of inputs


I Heard <strong>Fuzz</strong>ing Is Useful...Which fuzzer do I use?


<strong>Fuzz</strong>ing LifecycleIdentifying interfacesInput generation


How To Test <strong>Fuzz</strong>ers?Retrospective testingSimulated vulnerability discoveryCode coverage analysis


Retrospective TestingTime period is selected, say 6 monthsAll security bugs in the products under study thatemerged during the testing period are identified6 month old fuzzers are run against 6 month oldproductsWe see if the “new” bugs are found


Retrospective Testing (Cont.)PositivesMeasures how well fuzzers find real bugs in realprogramsNegativesIn good products, not many bugs come out in 6monthsSmall sample size - hard to draw conclusionsOld versions of fuzzers are being tested


Simulated VulnerabilityDiscoveryExperienced security researcher adds bugs to aproductBugs should be representative of the types of bugsfound in this product in the pastEach bug is verified to be reachable from an externalinterfaceAnother researcher uses fuzzers to try to find these“fake” bugs


Fake BugsPositivesLarge sample size - add as many bugs as you wantThe fuzzers still has to actually find the bugsNegativesBugs aren’t “real” - depend on the prejudices of theperson adding them


Code Coverage AnalysisInstrument the target application to measure theamount of code each fuzzer executesAbsolute numbers are meaningless, but relativenumbers can be usedLines not executed by a fuzzer indicate the fuzzer willnot find bugs in those lines (if they exist)Measure “opportunity” of finding bugs


Code CoveragePositivesEasy to obtainNegativesDoesn’t actually measure “bug finding” abilityMeasures what isn’t testedCovered does not necessarily mean fuzzedThink non-security regression tests


Our TestingThree network protocolsTwo servers, one clientA handful of fuzzersSimulated vulnerability discovery and code coverageused


CaveatsIn real life, choice of fuzzer will depend heavily on yourparticular projectFunding can be an issue - commercial fuzzers areexpensive!<strong>Fuzz</strong>ing an obscure or proprietary protocol may limityour choicesThis testing was only 3 protocols and relied heavily onthe placement of the fake bugs - buyer beware


Introducing The <strong>Fuzz</strong>ersGeneral Purpose <strong>Fuzz</strong>er (GPF)The Art of <strong>Fuzz</strong>ing (Taof)Proxy<strong>Fuzz</strong>Mu-4000CodenomiconbeSTORMApplication specific fuzzers: FTPfuzz, PROTOS


GPFOpen sourceMutation based (requires packet capture)Parses packet capture and adds anomaliesCan do this automatically or with a custom written “tokAid”Custom tokAids can take many hours to writeSuperGPF: a mode which modifies packet capture, addsanomalies, and launches many GPF instancesOnly works for text based protocols


TaofOpen source, mutation basedGUI basedUser dissects the captured packets and identifieslength fields, etc.Effort comparable to writing a GPF tokAidTypes of anomalies added are configurableCurrently cannot handle length fields within length fieldsLimits effectiveness in many binary protocols


Proxy<strong>Fuzz</strong>Open source, mutation basedSits in the middle of traffic and randomly injectsanomalies into live trafficCan set up and run in a matter of secondsCompletely protocol unaware


Mu-4000Commercial fuzzer from Mu SecurityGeneration basedUnderstands 55+ protocolsEasy to useCan only fuzz protocols it knowsCan only fuzz serversSophisticated target monitoring


CodenomiconCommercial, generation based fuzzerUnderstands 130+ protocolsCan only fuzz these protocols<strong>Fuzz</strong> client, server, and file parsing applicationsLimited or no monitoring capabilities


eSTORMCommercial, generation based fuzzerUnderstands 50+ protocolsCan be used to fuzz arbitrary protocolsConfigured through GUISophisticated monitoring capabilities


Application Specific <strong>Fuzz</strong>ersFTP<strong>Fuzz</strong>GUI driven, open source, generation basedOnly fuzzes FTP serversPROTOS SNMP test suiteGeneration basedJava command line application fires off SNMPpacketsFound all those ASN.1 bugs a few years ago


What’s Missing?What about SPIKE, Sulley, Peach, etc...These are fuzzing frameworks, not fuzzersTheir effectiveness is based solely on the quality of theprotocol description they are givenWe wouldn’t be testing the frameworks, but thespecification filesWe’d have to write the protocol descriptions - I’m toolazy to do that!


TargetsFTP Server - ProFTPDUses common ASCII based protocolSNMP Server - Net-SNMPUses binary based protocolDNS client - dig from BINDUses binary based protocol


The Bugs17 bugs added to each application - Thanks JakeHonoroff!Half were buffer overflowsA fourth were format stringsA fourth were others types of issues: commandinjection, double free, wild writes, etc.Not detectable with normal client (not THAT obvious)Prefaced with logging codeNot necessarily “exploitable” - but probably


Example: FTP Bug #0MODRET xfer_type(cmd_rec *cmd) {...if (strstr(get_full_cmd(cmd), "%")!=NULL){BUGREPORT(0);}char tempbuf[32];snprintf(tempbuf, 32, "%s not understood", get_full_cmd(cmd));pr_response_add_err(R_500, tempbuf);This is a format string bug becausepr_response_add_err() expects a format string for thesecond argument


Results!


FTPBug 0 1 3 4 5 9 11 12 13 14 15 16RandomGPF Partial X X XGPF Full X X X X XSuper GPF X X X X X XTaof PartialTaof Full X X XProxy<strong>Fuzz</strong> PartialProxy<strong>Fuzz</strong> Full X X XMu-4000 X X X X XFTPfuzz X X X XCodenomicon X X X X X X


FTP - Summary% bugs found % code coverageRandomGFP PartialGPF FullSuperGPFTaof PartialTaof FullPF PartialPF FullMu-4000CodenomiconFTP<strong>Fuzz</strong>0 10 20 30 40 50


SNMPBug 0 1 2 3 4 5 6 9 10 11 12 13 14 15 16RandomGPF Generic X X X X X X XGPF SNMP X X X X X X X X XProxy<strong>Fuzz</strong> X X X X X XMu-4000 X X X X X X X X X X X XPROTOS X X X X X X XCodenomicon X X X X X X X X X X X XbeSTORM X X X X X X


SNMP Summary% bugs found % code coverageRandomGPF GenericGFP SNMPProxy<strong>Fuzz</strong>Mu-4000PROTOSCodenomiconbeSTORM0 20 40 60 80


DNSBug 0 1 2 3 4 5 7 8 11 12 13 14 15GPF RandomGPF Generic X X X XProxy<strong>Fuzz</strong> X X X X X X X X XCodenomicon X X X X X X X X X XbeSTORMX


DNS Summary% Bugs found % Code coverageRandomGPF GenericProxy<strong>Fuzz</strong>CodenomiconbeSTORM0 15 30 45 60


A Closer Look


FTP OdditiesBugs 9, 12, and 13 were found by GPF but no otherfuzzersBugs 14 and 16 were found by Taof and Proxy<strong>Fuzz</strong> butno other fuzzersBugs 4, 5, and 15 were found by the generationalbased fuzzers, but not the mutation based ones


FTP Bug 9MODRET core_size(cmd_rec *cmd) {…if (!path || !dir_check(cmd->tmp_pool, cmd->argv[0], cmd->group, path,NULL) || pr_fsio_stat(path, &sbuf) == -1) {char tempbuf[64];if(strstr(cmd->arg, "%")){BUGREPORT(9);}strncpy(tempbuf, cmd->arg, 62);strncat(tempbuf, ": ", 64);strncat(tempbuf, strerror(errno), 64-strlen(tempbuf));pr_response_add_err(R_550, tempbuf);Generation based fuzzers didn’t run SIZE verb - not inRFCLikewise, other 2 bugs are in EPSV


FTP Bug 16MODRET core_eprt(cmd_rec *cmd) {char delim = '\0', *argstr = pstrdup(cmd->tmp_pool, cmd->argv[1]);…/* Format is protoip addressport (ASCII in network order),* where is an arbitrary delimiter character.*/delim = *argstr++;…while (isdigit((unsigned char) *argstr))argstr++;…if (*argstr == delim)argstr++;…if ((tmp = strchr(argstr, delim)) == NULL) {char tempbuf[64];if(strstr(cmd->argv[1], "%")!=NULL){BUGREPORT(16);}snprintf(tempbuf, 64, "badly formatted EPRT argument: '%s'", cmd->argv[1]);pr_response_add_err(R_501, tempbuf);return ERROR(cmd);}


FTP Bug 16 (Cont.)Need to not have enough delimitersThe data after the second one needs to have a formatstring specifierGeneration based fuzzers did not issue EPRTGPF was not random enough


FTP Bug 4char *dir_canonical_path(pool *p, const char *path) {char buf[PR_TUNABLE_PATH_MAX + 1] = {'\0'};char work[256 + 1] = {'\0'};if (*path == '~') {if(strlen(path) > 256 + 1){BUGREPORT(4);}if (pr_fs_interpolate(path, work, strlen(path)) != 1) {if (pr_fs_dircat(work, sizeof(work), pr_fs_getcwd(), path) < 0)return NULL;}Need a long path path that starts with a ‘~’.


FTP Bug 4 (Cont.)Generation based fuzzers got this oneMutation based did not - never began a path with a ‘~’


SNMP Bug #4int snmp_pdu_parse(netsnmp_pdu *pdu, u_char * data, size_t * length){…data = asn_parse_sequence(data, length, &type, (ASN_SEQUENCE | ASN_CONSTRUCTOR),"varbinds");if (data == NULL)return -1;...while ((int) *length > 0) {…switch ((short) vp->type) {…case ASN_OCTET_STR:case ASN_IPADDRESS:case ASN_OPAQUE:case ASN_NSAP:if (vp->val_len < sizeof(vp->buf)) {vp->val.string = (u_char *) vp->buf;} else {vp->val.string = (u_char *) malloc(200);if (vp->val_len > 200){BUGREPORT(4);}}…asn_parse_string(var_val, &len, &vp->type, vp->val.string,&vp->val_len);break;


SNMP Bug #4 (Cont.)Bug is reached with a particular type of packet and alarge length and corresponding long stringGPF executes the function but doesn’t even make it tothe switch statement (i.e. its too random)Proxy<strong>Fuzz</strong> and Mu-4000 sent the right kind of packet,but not with a long enough string


GeneralConclusions


The More <strong>Fuzz</strong>ers The Better# bugs found: all fuzzers # bugs found: best fuzzerFTPSNMPDNS0 3 6 9 12 15


Generation Based ApproachMost Effective# bugs found: mutation based # bugs found: generation basedFTPSNMPDNS0 2 4 6 8 10 12


Initial Test Cases Important# FTP bugs found - partial capture # FTP bugs found - full captureGPFTaofProxy<strong>Fuzz</strong>0 1 2 3 4 5


Protocol Knowledge Is Good% SNMP bugs foundProxy<strong>Fuzz</strong>GPF GenericGPF w/tokAidMu/Code.0 10 20 30 40 50 60 70 80


Does Code CoveragePredict Bug Finding?


More Code Coverage...


More Code Coverage...


Statistics Says “Yes”Dep Var: BUGS N: 11 Multiple R: 0.716 Squared multiple R: 0.512Adjusted squared multiple R: 0.458 Standard error of estimate: 9.468Effect Coefficient Std Error Std Coef Tolerance t P(2 Tail)CONSTANT -5.552 8.080 0.000 . -0.687 0.509CC 0.921 0.300 0.716 1.000 3.074 0.013Analysis of VarianceSource Sum-of-Squares df Mean-Square F-ratio PRegression 847.043 1 847.043 9.449 0.013Residual 806.813 9 89.646A 1% increase in code coverage increases thepercentage of bugs found by .92%


How Long To Run <strong>Fuzz</strong>ers?Time to discovery in minutes, Proxy<strong>Fuzz</strong> versus DNS40030020010001 2 3 4 5 6 7 8 9


A Real BugAll this fuzzing with different fuzzers against a realprogram might have actually found a real bugIt is possible that some were found but were lost in the“noise”One Net-SNMP bug was found (DOS)Only found by CodenomiconReported and fixed


ConclusionsVerified a lot of what intuition tells usIncorporate as much protocol specific knowledge aspossibleCommercial fuzzers are good (if you can afford them)Multiple fuzzers are better than oneRun fuzzers for a very long time (longer than you’dthink)Code coverage in fuzzers is useful as a measurement


Special Thanks To:Commercial fuzzer vendors who let me use theirproduct - very cool!Open source fuzzer developers who helped me find/fixbugs in their fuzzers


Questions?Buggy programs will be made availableContact me at: cmiller@securityevaluators.com

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!