0% found this document useful (0 votes)
18 views104 pages

Cmiller Toorcon2007 Code Coverage With Fuzzing

The document discusses fuzzing as a method for vulnerability analysis and testing, detailing various approaches such as mutation-based, generation-based, and evolutionary fuzzing. It highlights the importance of code coverage in identifying which parts of the code have been executed during testing and presents examples of fuzzing applied to different file formats. Additionally, it addresses the challenges and limitations of fuzzing and code coverage, along with practical examples from real-world applications like the iPhone and WebKit.

Uploaded by

Myungjun Sung
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views104 pages

Cmiller Toorcon2007 Code Coverage With Fuzzing

The document discusses fuzzing as a method for vulnerability analysis and testing, detailing various approaches such as mutation-based, generation-based, and evolutionary fuzzing. It highlights the importance of code coverage in identifying which parts of the code have been executed during testing and presents examples of fuzzing applied to different file formats. Additionally, it addresses the challenges and limitations of fuzzing and code coverage, along with practical examples from real-world applications like the iPhone and WebKit.

Uploaded by

Myungjun Sung
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 104

Fuzzing with Code Coverage

By Example

Charlie Miller
Independent Security Evaluators
October 20, 2007

[email protected]

© 2005, Independent Security Evaluators


www.securityevaluators.com
Agenda

▪ Fuzzing 101
▪ Common Fuzzing Problems
▪ Code Coverage
▪ Examples
▪ Improving Code Coverage

© 2005, Independent Security Evaluators


www.securityevaluators.com
Fuzzing

▪ A form of vulnerability analysis and testing


▪ Many slightly anomalous test cases are
input into the target application
▪ Application is monitored for any sign of
error

© 2005, Independent Security Evaluators


www.securityevaluators.com
Example

▪ Standard HTTP GET request


§ GET /index.html HTTP/1.1
▪ Anomalous requests
§ AAAAAA...AAAA /index.html HTTP/1.1
§ GET ///////index.html HTTP/1.1
§ GET %n%n%n%n%n%n.html HTTP/1.1
§ GET /AAAAAAAAAAAAA.html HTTP/1.1
§ GET /index.html HTTTTTTTTTTTTTP/1.1
§ GET /index.html HTTP/1.1.1.1.1.1.1.1
§ etc...
© 2005, Independent Security Evaluators
www.securityevaluators.com
Different Ways To Fuzz

▪ Mutation Based - “Dumb Fuzzing”


▪ Generation Based - “Smart Fuzzing”
▪ Evolutionary

© 2005, Independent Security Evaluators


www.securityevaluators.com
Mutation Based Fuzzing
▪ Little or no knowledge of the structure of the inputs is
assumed
▪ Anomalies are added to existing valid inputs
▪ Anomalies may be completely random or follow some
heuristics
▪ Requires little to no set up time
▪ Dependent on the inputs being modified
▪ May fail for protocols with checksums, those which
depend on challenge response, etc.
▪ Examples:
§ Taof, GPF, ProxyFuzz, etc.

© 2005, Independent Security Evaluators


www.securityevaluators.com
Generation Based Fuzzing
▪ Test cases are generated from some
description of the format: RFC, documentation,
etc.
▪ Anomalies are added to each possible spot in
the inputs
▪ Knowledge of protocol should give better
results than random fuzzing
▪ Can take significant time to set up
▪ Examples
§ SPIKE, Sulley, Mu-4000, Codenomicon

© 2005, Independent Security Evaluators


www.securityevaluators.com
Evolutionary Fuzzing

▪ Attempts to generate inputs based on the


response of the program
▪ Autodafe
§ Prioritizes test cases based on which inputs
have reached dangerous API functions
▪ EFS
§ Generates test cases based on code
coverage metrics (more later)
▪ This technique is still in the alpha stage :)
© 2005, Independent Security Evaluators
www.securityevaluators.com
The Problems With Fuzzing

▪ Mutation based fuzzers can generate an


infinite number of test cases... When has
the fuzzer run long enough?
▪ Generation based fuzzers generate a finite
number of test cases. What happens when
they’re all run and no bugs are found?
▪ How do you monitor the target application
such that you know when something “bad”
has happened?
© 2005, Independent Security Evaluators
www.securityevaluators.com
The Problems With Fuzzing

▪ What happens when you find too many bugs?


Or every anomalous test case triggers the same
(boring) bug?
▪ How do you figure out which test case caused
the fault?
▪ Given a crash, how do you find the actual
vulnerability
▪ After fuzzing, how do you know what changes to
make to improve your fuzzer?
▪ When do you give up on fuzzing an application?
© 2005, Independent Security Evaluators
www.securityevaluators.com
Example 1: PDF

▪ Have a PDF file with 248,000 bytes


▪ There is one byte that, if changed to particular
values, causes a crash
§ This byte is 94% of the way through the file
▪ Any single random mutation to the file has a
probability of .00000392 of finding the crash
▪ On average, need 127,512 test cases to find it
▪ At 2 seconds a test case, thats just under 3
days...
▪ It could take a week or more...
© 2005, Independent Security Evaluators
www.securityevaluators.com
Example 2: 3g2

▪ Video file format


▪ Changing a byte in the file to 0xff crashes
QuickTime Player 42% of the time
▪ All these crashes seem to be from the
same bug
▪ There may be other bugs “hidden” by this
bug

© 2005, Independent Security Evaluators


www.securityevaluators.com
Code Coverage

▪ Some of the answers to these questions


lie in code coverage
▪ Code coverage is a metric which can be
used to determine how much code has
been executed.
▪ Works for source code or binaries,
although almost all the literature assumes
you have source

© 2005, Independent Security Evaluators


www.securityevaluators.com
Line Coverage

▪ Measures how many lines of code (source


code lines or assembly instructions) have
been executed.

© 2005, Independent Security Evaluators


www.securityevaluators.com
Branch Coverage

▪ Measures how many branches in code


have been taken (conditional jmps)
if( x > 2 )
x = 2;

▪ The above code can achieve full line


coverage in one test case (ex. x=3)
▪ Requires 2 test cases for total branch
coverage (ex. x=1, x=2).

© 2005, Independent Security Evaluators


www.securityevaluators.com
Path Coverage

▪ Measures the number of paths executed


if( a > 2 )
a = 2;
if( b > 2 )
b = 2;

▪ Requires
§ 1 test case for line coverage
§ 2 test cases for branch coverage
§ 4 test cases for path coverage
• i.e. (a,b) = {(0,0), (3,0), (0,3), (3,3)}
© 2005, Independent Security Evaluators
www.securityevaluators.com
Path Coverage Issues

▪ In general, a program with n “reachable” branches will


require 2n test cases for branch coverage and 2^n test
cases for path coverage
§ Umm....there’s a lot of paths in a program!
▪ If you consider loops, there are an infinite number of paths
▪ Some paths are infeasible
if(x>2)
x=2;
if(x<0)
x=0;
§ You can’t satisfy both of these conditionals, i.e. there is
only three paths through this code, not four

© 2005, Independent Security Evaluators


www.securityevaluators.com
Getting Code Coverage Data

▪ If you’ve got source


§ Instrument the code while compiling
• gcov
• Insure++
• Bullseye

© 2005, Independent Security Evaluators


www.securityevaluators.com
Getting Code Coverage Data

▪ If you live in the real world


§ Use Debugging info
• Pai Mei
§ Virtualization
• Valgrind
• Bochs
• Xen?
§ Dynamic code instrumentation
• DynamoRIO
• Aprobe
© 2005, Independent Security Evaluators
www.securityevaluators.com
Problems with Code Coverage

▪ Code can be covered without revealing bugs


mySafeCpy(char *dst, char* src){
if(dst && src)
strcpy(dst, src);
}

▪ Error checking code mostly missed (and we don’t


particularly care about it)
ptr = malloc(sizeof(blah));
if(!ptr)
ran_out_of_memory();

▪ Only “attack surface” reachable


§ i.e. the code processing user controlled data
§ No easy way to measure the attack surface
© 2005, Independent Security Evaluators
www.securityevaluators.com
Now the Examples

▪ Note: we start with some source code


examples but move on to binary only

© 2005, Independent Security Evaluators


www.securityevaluators.com
In June 2007...

▪ A group of cunning, good looking


researchers hacked the iPhone
▪ How’d we find the bug?

▪ Fuzzing + Code Coverage!


© 2005, Independent Security Evaluators
www.securityevaluators.com
WebKit

▪ Most Apple Internet applications share the


same code, WebKit
▪ WebKit is an open source library
▪ Source code is available via svn:
§ svn checkout http://svn.webkit.org/repository/
webkit/trunk WebKit

© 2005, Independent Security Evaluators


www.securityevaluators.com
Thanks

▪ From the development site:

▪ So we know what they use for unit testing


▪ Let’s use code coverage to see which
portions of code might not be as well
tested
© 2005, Independent Security Evaluators
www.securityevaluators.com
lcov

▪ One problem with gcov is the data is


stored in many different files
▪ lcov is an open source software package
which collects data from a whole project
and displays it in a nice html report
▪ It can be a minor pain in the ass to get to
work...

© 2005, Independent Security Evaluators


www.securityevaluators.com
Build and Run WebKit

▪ Build it:
WebKit/WebKitTools/Scripts/build-webkit -coverage

▪ Run the test suite:


WebKitTools/Scripts/run-javascriptcore-tests -coverage

▪ Add a bunch of stupid links for lcov...sigh :(


▪ Collect coverage data
lcov --directory WebKitBuild/JavaScriptCore.build/Release/
JavaScriptCore.build/Objects-normal/i386 -c -o testsuite.info

▪ Generate HTML report


genhtml -o WebKit-html -f testsuite.info

© 2005, Independent Security Evaluators


www.securityevaluators.com
Results

© 2005, Independent Security Evaluators


www.securityevaluators.com
Results

▪ 59.3% of 13622 lines in JavaScriptCore


were covered
§ The main engine (53% of the overall code)
had 79.3% of its lines covered
§ Perl Compatible Regular Expression (PCRE)
library (17% of the overall code) had 54.7% of
its lines covered
▪ We decided to investigate PCRE further

© 2005, Independent Security Evaluators


www.securityevaluators.com
...The Rest of the Story

▪ Wrote a PCRE fuzzer (20 lines of perl)


▪ Ran it on a standalone PCRE parser
(pcredemo from the PCRE library)
▪ We started getting errors like:
PCRE compilation failed at offset 6: internal error: code overflow.

▪ This was good

© 2005, Independent Security Evaluators


www.securityevaluators.com
A Short Digression on iPhone Hacking:
- or - How To Write an Exploit by Fuzzing

▪ Using our evil regular expression, we


could crash mobileSafari (which uses
Webkit)
▪ We didn’t have a debugger for the iPhone.
▪ We couldn’t compile code for the iPhone
▪ We did have crash reports which gave
register values
▪ We did have core dumps (after some
iPhone modifications)
© 2005, Independent Security Evaluators
www.securityevaluators.com
All Exploits Need...

▪ To get control (in this case pc = r15)


▪ To find your shellcode

▪ Q: How can you do this without a debugger?


▪ A: The same way you find bugs while
watching TV: fuzzing

© 2005, Independent Security Evaluators


www.securityevaluators.com
Fuzz to Exploit

▪ We generated hundreds of regular


expressions containing different number of
“evil” strings: “[[**]]”
▪ Sorted through the crash reports
▪ Eventually found a good one

© 2005, Independent Security Evaluators


www.securityevaluators.com
A “Good” Crash
Thread 2 crashed with ARM Thread State:
r0: 0x00065000 r1: 0x0084f800 r2: 0x00000017 r3: 0x15621561
r4: 0x00000018 r5: 0x0084ee00 r6: 0x00065000 r7: 0x005523ac
r8: 0x0000afaf r9: 0x00817a00 r10: 0x00ff8000 r11: 0x00000005
ip: 0x15641563 sp: 0x00552358 lr: 0x30003d70 pc: 0x3008cbc4
cpsr: 0x20000010 instr: 0xe583c004

__text:3008CBC4 STR R12, [R3,#4]


__text:3008CBC8 BXEQ LR
__text:3008CBCC
__text:3008CBCC loc_3008CBCC ; CODE XREF: __text:3008CBA0j
__text:3008CBCC STR R3, [R12]

▪ Unlinking of a linked list


▪ r3 and r12=ip are controllable
▪ Old school heap overflow (gotta love Apple)
▪ Gives us a “write anywhere” primitive
▪ Hows it work? Who the hell knows!
▪ HD Moore, who is an exploit writing genius, would be sad :(
© 2005, Independent Security Evaluators
www.securityevaluators.com
More Fuzzing For Exploitation

▪ We decided to overwrite a return address


on the stack.
▪ How do you find it? Fuzz!
§ True fuzzing folks will call this brute forcing
and not fuzzing, but either way its easy...
Exception Type: EXC_BAD_INSTRUCTION
...
Thread 2 crashed with ARM Thread State:
r0: 0x00065038 r1: 0x00000000 r2: 0x00000a00 r3: 0x00000001
r4: 0x00065000 r5: 0x380135a4 r6: 0x00000000 r7: 0x005523e4
r8: 0x00000000 r9: 0x00815a00 r10: 0x0084b800 r11: 0x00000000
ip: 0x380075fc sp: 0x005523d0 lr: 0x30003e18 pc: 0x0055ff3c
cpsr: 0x20000010 instr: 0xffffffff

© 2005, Independent Security Evaluators


www.securityevaluators.com
PNG - with source

▪ libpng-1.2.16
▪ Used in Firefox, Safari, and Thunderbird
(and others)
▪ http://www.libpng.org/pub/png/libpng.html

© 2005, Independent Security Evaluators


www.securityevaluators.com
Build the Source

▪ ./configure CFLAGS="-g -fprofile-arcs -ftest-coverage"


▪ make (errors out)
▪ gcc -g -fprofile-arcs -ftest-coverage -I. -L/usr/X11R6/
lib/ -I/usr/X11R6/include contrib/gregbook/rpng-
x.c .libs/libpng12_la-png.o .libs/libpng12_la-
pngset.o .libs/libpng12_la-pngget.o .libs/libpng12_la-
pngrutil.o .libs/libpng12_la-pngtrans.o .libs/
libpng12_la-pngwutil.o .libs/libpng12_la-
pngread.o .libs/libpng12_la-pngrio.o .libs/libpng12_la-
pngwio.o .libs/libpng12_la-pngwrite.o .libs/libpng12_la-
pngrtran.o .libs/libpng12_la-pngwtran.o .libs/
libpng12_la-pngmem.o .libs/libpng12_la-pngerror.o .libs/
libpng12_la-pngpread.o .libs/libpng12_la-pnggccrd.o
contrib/gregbook/readpng.c -o contrib/gregbook/rpng-x
-lX11 -lz -lgcov
▪ result: contrib/gregbook/rpng-x

© 2005, Independent Security Evaluators


www.securityevaluators.com
How ‘bout a Little Dumb Fuzzing Action?

▪ Grab a PNG off the Internet


§ The first one I find is from Wikipedia:
PNG_transparency_demonstration_1.png
▪ Zero out any code coverage data
§ lcov --directory . -z

© 2005, Independent Security Evaluators


www.securityevaluators.com
Generate Some Files

▪ Use fuzz.c, the “super” fuzzer


§ Changes 1-17 bytes in each file
§ New value is random
§ Does this 8192 times
▪ The ultimate in dumb fuzzer technology

./fuzz > fuzz.out

© 2005, Independent Security Evaluators


www.securityevaluators.com
Use the Files

▪ Use script.sh
§ Executes the program 10 at a time
§ Sleeps 5 seconds
§ Kills any processes
§ Repeats
§ Monitors CrashReporter log for crashes

© 2005, Independent Security Evaluators


www.securityevaluators.com
Get Code Coverage

▪ We covered 10.7% of the lines


cp *.c .libs/
lcov --directory . -c -o fuzz.info
genhtml -f -o fuzz_html_files fuzz.info
...

▪ This compares to
§ 0.4% for getting the usage statement
§ 745 of 7399 (10.1%) for opening the good file
• 43 more lines covered by fuzzing...

© 2005, Independent Security Evaluators


www.securityevaluators.com
What’s up?

▪ That code coverage kinda sucked...


▪ Did we choose a bad initial file
▪ Let’s try some other files...
§ Choose 4 other PNG’s from the Internet
§ Fuzz them the same way
§ Collect data from each separately

© 2005, Independent Security Evaluators


www.securityevaluators.com
Results
Good file Fuzzed

15.00

11.25

7.50

3.75

0
File 1 File 2 File 3 File 4 File 5

© 2005, Independent Security Evaluators


www.securityevaluators.com
So...

▪ Initial file can make a big difference


§ 50% more code coverage from file 2 than in
file 5
▪ What if we ran them all?

© 2005, Independent Security Evaluators


www.securityevaluators.com
The Sum is Greater Than the Parts

Good file Fuzzed

20

15

10

0
File 1 File 2 File 3 File 4 File 5 All

© 2005, Independent Security Evaluators


www.securityevaluators.com
WTF is Going On?

▪ Each PNG contains certain elements that


requires some code to process
▪ Some PNG’s contain the same elements,
some contain different ones
▪ By fuzzing with a variety of different
PNG’s, you increase the chance of having
different elements which need processing
▪ Charlie’s Heuristic: Keep adding files until
the cumulative effect doesn’t increase
© 2005, Independent Security Evaluators
www.securityevaluators.com
Enter Generation-Based Fuzzers

▪ Since Generation-based fuzzers build test


cases not from valid data, but from the
specification, they should contain all
possible chunks
▪ This should make for a more thorough test

© 2005, Independent Security Evaluators


www.securityevaluators.com
SPIKE
//png.spk
// Charlie Miller

// Header - fixed.
s_binary("89504E470D0A1A0A");

// IHDRChunk
s_binary_block_size_word_bigendian("IHDR"); //size of data field
s_block_start("IHDRcrc");
s_string("IHDR"); // type
s_block_start("IHDR");
// The following becomes s_int_variable for variable stuff
// 1=BINARYBIGENDIAN, 3=ONEBYE
s_push_int(0x1a, 1); // Width
s_push_int(0x14, 1); // Height
s_push_int(0x8, 3); // Bit Depth - should be 1,2,4,8,16, based
on colortype
s_push_int(0x3, 3); // ColorType - should be 0,2,3,4,6
s_binary("00 00"); // Compression || Filter - shall be 00 00
s_push_int(0x0, 3); // Interlace - should be 0,1
s_block_end("IHDR");
s_binary_block_crc_word_littleendian("IHDRcrc"); // crc of type and data
s_block_end("IHDRcrc");
...

© 2005, Independent Security Evaluators


www.securityevaluators.com
Generation Gap

30.0

22.5

15.0

7.5

0
File 1 File 2 File 3 File 4 File 5 All Gen

© 2005, Independent Security Evaluators


www.securityevaluators.com
Halting Problem (Again)

▪ During all this testing


§ Used mutation and generation based fuzzers
§ Generated over 200,000 test cases
§ Not one crash
▪ This is a common occurrence for difficult
or well audited target applications
▪ Raises the question: Now what?
▪ Answer later...
§ (Hint: has to do with code coverage)
© 2005, Independent Security Evaluators
www.securityevaluators.com
Code Coverage is...

▪ We’ve seen that code coverage is


§ A metric to find results about fuzzing
§ Helpful in figuring out general approaches to
fuzzing
§ Useful to find what code to focus fuzzing upon
▪ More importantly:
§ A way to improve fuzzing and find more bugs!
§ Helpful in figuring out when fuzzing is
“finished”

© 2005, Independent Security Evaluators


www.securityevaluators.com
Look

▪ Suppose we didn’t know anything about


PNG’s
▪ Could we have figured out what was
missing when we were fuzzing PNG with
the mutation based approach?
▪ Lets look through some of the lcov report

© 2005, Independent Security Evaluators


www.securityevaluators.com
Yup

© 2005, Independent Security Evaluators


www.securityevaluators.com
Code Coverage Improves Fuzzing

▪ Finding spots in the code which are not


covered can help with the generation of
new test cases
▪ Beware: covered code doesn’t necessarily
mean its “fuzzed”
▪ Code which has not been executed
definitely still needs to be fuzzed!

© 2005, Independent Security Evaluators


www.securityevaluators.com
Digression into Binary Code Coverage

▪ So far, we’ve seen how code coverage


can give useful information to help fuzzing
▪ We’ve seen how to use gcov and lcov to
do this
▪ The exact same data can be obtained on
Windows binaries using Pai Mei
▪ Pai Mei exists for Mac OS X and is being
ported to Linux

© 2005, Independent Security Evaluators


www.securityevaluators.com
Pai Mei

▪ A reverse engineering framework


▪ Integrates
§ PyDbg debugger
§ IDA Pro databases (via PIDA)
§ pGraph graphing
§ mySQL database
▪ Gives the ability to perform
reverse engineering tasks quickly
and repeatably
▪ http://paimei.openrce.org/
© 2005, Independent Security Evaluators
www.securityevaluators.com
Pstalker

▪ A Pai Mei Module


▪ Uses IDA Pro to get structure of binary
▪ Sets breakpoints at each basic block (or
function)
▪ Records and removes breakpoints that are
hit
▪ Allows for filtering of breakpoints
▪ Gathers code coverage for binaries
© 2005, Independent Security Evaluators
www.securityevaluators.com
Screenshot

© 2005, Independent Security Evaluators


www.securityevaluators.com
One Hitch

▪ Can’t keep launching the process


▪ Have to have a way for it to keep loading
the fuzzed images
▪ Just use a meta-refresh tag and point the
browser at it

© 2005, Independent Security Evaluators


www.securityevaluators.com
The Fuzzing Website
#!/usr/bin/perl

$file = $ENV{'QUERY_STRING'};
$nextfile = $file + 1;
$server = $ENV{'SERVER_NAME'};
$script = $ENV{'SCRIPT_NAME'};
$url = "http://".$server.$script."?".$nextfile;
$pic = sprintf("bad-%d.gif", $nextfile);
$picurl = "http://".$server."/gif/".$pic;

print "Content-type: text/html

<head>
Fuzz!
";
print " <meta http-equiv=\"refresh\" content=\"2;$url\">";
print " </head><body>";
print"</body>\n";
print "<Script Language=\"JavaScript\">";
print "window.open('$picurl');";
print "</Script>";

© 2005, Independent Security Evaluators


www.securityevaluators.com
Missed PNG Basic Blocks

© 2005, Independent Security Evaluators


www.securityevaluators.com
Using Pai Mei to Find the Code

▪ Do some general browsing in Safari under


Pai Mei
§ Avoid pages with PNG’s if possible
§ Stop when no more breakpoints are hit
▪ Record this code coverage in a tag
▪ Filter out on that tag and browse a bunch
of different PNG’s
▪ This will record those basic blocks used
only in PNG processing (mostly)
© 2005, Independent Security Evaluators
www.securityevaluators.com
This Results In:

▪ Total basic blocks: 123,325


▪ Hit during “general browsing”: 12,776
▪ Hit during PNG only surfing with filter on:
1094 (0.9% of total basic blocks)
§ This includes 87 functions (out of 7069)
§ 61 of these basic blocks are in the “main”
PNG processing function
§ Most of the others are in “chunk” specific
functions
© 2005, Independent Security Evaluators
www.securityevaluators.com
Where’s the Code?

© 2005, Independent Security Evaluators


www.securityevaluators.com
Pai Mei Limitations

▪ Pai Mei is only as good as what IDA give it


§ If IDA misidentifies data as code, bad things
happen!
▪ Some anti-debugging measures screw it up
▪ Have to know the DLL you’re interested in
§ Or load them all
▪ For large binaries, it can be slow to set all
the breakpoints
§ For this library, it takes a few minutes
© 2005, Independent Security Evaluators
www.securityevaluators.com
Increasing Code Coverage

▪ Lack of code coverage is a bad thing


§ Can’t find bugs in code you’re not executing
▪ How do you increase code coverage?
▪ Basically three ways
§ Manually
§ Dynamically using run time information
§ Automatically from static information

© 2005, Independent Security Evaluators


www.securityevaluators.com
Manually

▪ You can imagine


looking at the PNG
code and figuring
out how to get more
code coverage.

© 2005, Independent Security Evaluators


www.securityevaluators.com
Another Example

▪ Freeciv 2.0.9, a free multiplayer game similar


to Civilization

▪ Don’t ever play this on a computer you care


about
© 2005, Independent Security Evaluators
www.securityevaluators.com
Steps to Code Coverage

▪ Get the Windows binary - no cheating


▪ Disassemble it
▪ Dump the PIDA file
▪ Launch civserver.exe
▪ Attach with Pai Mei’s Pstalker
▪ Capture a netcat connection to it
▪ Filter this out (551 of 36,183 BB’s - 2%)
▪ Trace the fuzzing!
© 2005, Independent Security Evaluators
www.securityevaluators.com
GPF

▪ Great, general purpose mutation-based


fuzzer
▪ Works on packet captures
▪ Replays packets while injecting faults
▪ User can manually tell GPF about the
structure of the data in the packets
§ Aids in the anomaly injection
▪ Many modes of operation

© 2005, Independent Security Evaluators


www.securityevaluators.com
Fuzz FreeCiv

▪ Start up the game, play a bit


▪ Capture the packets to a file
▪ Convert the PCAP file to a GPF file
./GPF -C freeciv_reg_game.pcap freeciv_reg_game.gpf

▪ Fire up GPF (main mode)


§ Main mode replaces some packets with
random data
./GPF -G l ../freeciv_reg_game.gpf client <IP ADDRESS> 5555 ? TCP
kj3874jff 1000 0 + 0 + 00 01 09 43 close 0 1 auto none

© 2005, Independent Security Evaluators


www.securityevaluators.com
FreeCiv Sucks

▪ Not designed to be fuzzed :)


▪ Need to add a sleep to GPF so FreeCiv
can keep up
▪ Fuzz overnight...
▪ I recorded 96 functions during fuzzing
§ 614 / 36183 basic blocks
▪ Import data back to IDA
▪ Look for places to increase code coverage
© 2005, Independent Security Evaluators
www.securityevaluators.com
I See One!

▪ A big switch statement I only hit once

▪ Tracing back reveals this switch is


controlled by the third byte of the packet

© 2005, Independent Security Evaluators


www.securityevaluators.com
Back to GPF

▪ Up until now we’ve basically been sending


random data
▪ Using Pai Mei, we observe that the third byte
is important
▪ We modify GPF to make sure it changes the
third byte
▪ We’ve added a little structure to our random
data
./bin/GPF -G l freeciv_reg_game.gpf client <IP ADDRESS> 5555 ?
TCP kj3874jff 1000 0 + 2 2 00 01 255 41 finish 0 1 auto none

© 2005, Independent Security Evaluators


www.securityevaluators.com
Better Code Coverage

▪ 2383 basic blocks covered (after filtering)


§ Compare this to 614 with the first fuzz run
§ 4x improvement

▪ All cases taken in switch (as expected)


▪ However, still no bugs...
© 2005, Independent Security Evaluators
www.securityevaluators.com
Manual Method Explained

▪ Send mostly random data


▪ Examine code coverage to see what
structure in the data is important
▪ Send data which has some elements set
but some mostly random parts
▪ Rinse and Repeat

© 2005, Independent Security Evaluators


www.securityevaluators.com
Fuzzing Beyond the 3rd Byte

▪ This command replaces the bytes 3 through 10 of


each packet, one at a time, with all possible values
from 0 to 255
./GPF -G l ../freeciv_reg_game.gpf client <IP ADDRESS> 5555 ?
TCP kj3874jff 1000 0 + 2 10 00 01 255 41 finish 0 1 auto none

▪ This will ensure that all the cases in the switch


statement are hit and each case will have some
random data
▪ After a bit, CPU is pegged: Memory consumption
bug!

© 2005, Independent Security Evaluators


www.securityevaluators.com
Dig Deeper

▪ Following the methodology, fix the 3rd byte


to, say 0x47
▪ Send in random data to that part of the
program
▪ See what you missed
▪ Try to do better

© 2005, Independent Security Evaluators


www.securityevaluators.com
Missed Some Spots

© 2005, Independent Security Evaluators


www.securityevaluators.com
Heap Overflow

▪ Can get a heap overflow if you send the


following packet:
27 2e | 2f | 0c | 00 00 13 94 | 41 41 41 41 41...
Length of Packet Length of memcpy Data

© 2005, Independent Security Evaluators


www.securityevaluators.com
Bugs In FreeCiv Aren’t a Huge Deal

▪ Fun for hacking your friends


▪ Also MetaServer is nice

© 2005, Independent Security Evaluators


www.securityevaluators.com
Dynamically Generating Better Test Cases

▪ Manually improving code coverage is, uh,


“time intensive”
▪ Need to automate the process
▪ Autodafe kinda does this
▪ But I prefer another of Jared Demott’s
tools....

© 2005, Independent Security Evaluators


www.securityevaluators.com
EFS

▪ Uses Pai Mei Pstalker to record code


coverage
▪ Uses Genetic Algorithms to generate new
test cases based on code coverage
feedback

© 2005, Independent Security Evaluators


www.securityevaluators.com
Genetic Algorithms

▪ Technique to find approximate solution to


optimization problems
▪ Inspired by evolutionary biology
§ Define fitness of an organism (test case)
§ Must define how to recombine two organisms
§ Must define how to mutate a single organism
▪ Lots more complexity but that is the basics

© 2005, Independent Security Evaluators


www.securityevaluators.com
GA example

▪ f(x) = -x * (x – 10000)
▪ Use “single point crossover” of binary
representation of numbers for
recombination
677 : 00000000000000000000001010100101
9931 : 00000000000000000010011011001011
----------------------------------------------------------------------
651 : 00000000000000000000001010001011

▪ Flip a bit 10% of the time for mutation


▪ Fitness is the value in the function
© 2005, Independent Security Evaluators
www.securityevaluators.com
In Practice

▪ Running it for a few generations gives


134 651 485 7653 1354 7654 134 7302
(1322044) (6086199) (4614775) (17961591) (11706684) (17956284) (1322044) (19700796)
1354 7652 134 7653 7302 390 1350 134
(11706684) (17966896) (1322044) (17961591) (19700796) (3747900) (11677500) (1322044)
390 7302 134 134 134 1350 134
(3747900) (19700796) (1322044) (1322044) 70 (695100) (1322044) (11677500) (1322044)
134 134 268 134 1350 134 134 2182
(1322044) (1322044) (2608176) (1322044) (11677500) (1322044) (1322044) (17058876)
134 134 134 2182 1618 134 134 2316
(1322044) (1322044) (1322044) (17058876) (13562076) (1322044) (1322044) (17796144)
134 1618 1612 132 2316 134 2322 1158
(1322044) (13562076) (13521456) (1302576) (17796144) (1322044) (17828316) (10239036)

▪ The optimum value is 5000

© 2005, Independent Security Evaluators


www.securityevaluators.com
GA Approaches the Solution
▪ Generation vs most fit individual
▪ Approaches the solution

© 2005, Independent Security Evaluators


www.securityevaluators.com
EFS and GA’s

▪ Fitness function: How many functions


were covered by the test case (in reality a
more elaborate measure is used)
▪ For breeding, tends to choose the most fit
individuals
▪ Recombination: single point crossover that
respects “protocol tokens”
▪ Mutation: portions of data replaced with
fuzzing heuristics
© 2005, Independent Security Evaluators
www.securityevaluators.com
Obligatory Screenshot

© 2005, Independent Security Evaluators


www.securityevaluators.com
Running EFS

▪ Still needs a PIDA file


▪ Connect to database
▪ Add PIDA file to module list
▪ Enter pathname to application in Load/Attach
window
▪ Choose Connections->Fuzzer Connect
§ Hit “Listen”
▪ On Client
./GPF -E <IP ADDRESS> root <PASSWORD> 0 0 <IP ADDRESS> 31338 funcs client <IP ADDRESS>
5555 ? TCP 800000 20 low AUTO 4 25 Fixed 10 Fixed 10 Fixed 35 3 5 9 none none no

© 2005, Independent Security Evaluators


www.securityevaluators.com
What You See

Successfully played generation 0. Saving to mysqldb.


Processing Generation 0 ...
Done processing. Time to play and process: 100 total
evaluations in
1001 seconds.
10.01 sec/eval
That's 16.683 mins or 0.278 hrs.

Successfully played generation 1. Saving to mysqldb.


Processing Generation 1 ...
Done processing. Time to play and process: 200 total
evaluations in
1887 seconds.
9.44 sec/eval
That's 31.450 mins or 0.524 hrs.

© 2005, Independent Security Evaluators


www.securityevaluators.com
Does It Work?

▪ The light blue line indicates the most fit pool of testcases
▪ Code coverage is (slowly) improving

© 2005, Independent Security Evaluators


www.securityevaluators.com
Caveats

▪ Still experimental
▪ GA’s can get stuck in “local maxima”
▪ GA’s have so many parameters
(population size, initial population,
mutation percentage, etc), hard to
optimize

© 2005, Independent Security Evaluators


www.securityevaluators.com
Statically Generating Code Coverage

▪ GA’s attempt to provide an approximating


solution to a difficult problem
▪ We have the binary, we have the control
flow graph, we have the disassembly...
▪ What if we “solve” the problem exactly?

© 2005, Independent Security Evaluators


www.securityevaluators.com
Existing Work

▪ Microsoft Research has a tool that generates


code coverage maximizing test cases from
binaries
§ ftp://ftp.research.microsoft.com/pub/tr/
TR-2007-58.pdf
▪ Catchcov (built on Valgrind) does something
similar to try to find integer overflows
▪ Greg Hoglund has something which tries to do
this
▪ Nothing freely available
© 2005, Independent Security Evaluators
www.securityevaluators.com
General Idea

▪ Identify where user supplied data enters


the program
▪ Data needs to be traced (symbolically) and
branch point’s dependence on initial data
recorded
▪ These equations need to be solved, i.e.
inputs need to be generated which can go
down either branch at each branch point.

© 2005, Independent Security Evaluators


www.securityevaluators.com
Example

▪ Input comes in through argv[1]


▪ test() takes an this value as an int
▪ 3 possible paths through the program
int test(int x){
if(x < 10){
if(x > 0){
return 1;
}
}
return 0;
}

int main(int argc, char *argv[]){


int x = atoi(argv[1]);
return test(x);
}
© 2005, Independent Security Evaluators
www.securityevaluators.com
Tracing the Data

▪ Use Valgrind or PyEmu?


▪ In this trivial example, we’ll just do it by
hand.
▪ The constraints would look something like
x >= 10
0 < x < 10
x <= 0

▪ In real life, there would be thousands of


such constraints
© 2005, Independent Security Evaluators
www.securityevaluators.com
Solve the Constraints

▪ Can use a Boolean satisfiability solver (SAT)


▪ One such solver is STP
§ Constraints expressed as bit vector variables
§ Bitwise operators like AND, OR, XOR
§ Arithmetic functions like +, =, *
§ Predicates like =, <, >

© 2005, Independent Security Evaluators


www.securityevaluators.com
In the STP Language

x : BITVECTOR(32);
QUERY(BVLT(x,0hex0000000a));

x : BITVECTOR(32);
ASSERT(BVLT(x,0hex0000000a));
QUERY(BVGT(x,0hex00000000));

x : BITVECTOR(32);
ASSERT(BVLT(x,0hex0000000a));
QUERY(BVLE(x,0hex00000000));

© 2005, Independent Security Evaluators


www.securityevaluators.com
Solving These Gives

▪ This gives the test cases x={12, 0, 4}


▪ These give maximal code coverage
$ ./stp -p q1
Invalid.
ASSERT( x = 0hex0000000C );
$ ./stp -p q2
Invalid.
ASSERT( x = 0hex00000000 );
$ ./stp -p q3
Invalid.
ASSERT( x = 0hex00000004 );

© 2005, Independent Security Evaluators


www.securityevaluators.com
Using This Technique

▪ Very sophisticated constraints, such as


those that found the Freeciv bug, could be
solved (sometimes)
▪ Optimum test cases can be generated
without executing the application
▪ Combining dynamic and static approaches
can optimize fuzzing

© 2005, Independent Security Evaluators


www.securityevaluators.com
Conclusion

▪ Fuzzing is easy, until you really try it


▪ Code coverage is a tool that can be used
to try to measure and improve fuzzing
▪ You won’t find any bugs in code you
haven’t tested
▪ Increasing code coverage can be difficult
and time consuming but new tools are
coming to make this easier

© 2005, Independent Security Evaluators


www.securityevaluators.com
References

▪ http://en.wikipedia.org/wiki/Fuzz_testing
▪ Make My Day: Just Run A Web Scanner, Toshinari Kureha, BH-EU-07
▪ How Smart is Intelligent Fuzzing - or - How Stupid is Dumb Fuzzing, Charlie
MIller, DEFCON 2007
▪ Robustness Testing Code Coverage Analysis, Teno Rontti, Masters Thesis
▪ How to Misuse Code Coverage, Brian Marick, http://www.testing.com/
writings/coverage.pdf
▪ ProxyFuzz: http://theartoffuzzing.com/joomla/index.php?
option=com_content&task=view&id=21&Itemid=40
▪ STP: http://theory.stanford.edu/~vganesh/stp.html
▪ SPIKE: http://www.immunitysec.com/downloads/SPIKE2.9.tgz
▪ lcov: http://ltp.sourceforge.net/coverage/lcov.php
▪ GPF and EFS: http://www.vdalabs.com/tools/efs_gpf.html

© 2005, Independent Security Evaluators


www.securityevaluators.com
Questions?

▪ Please contact me at:


[email protected]

© 2005, Independent Security Evaluators


www.securityevaluators.com

You might also like