In previous blogs, I’ve talked about using code coverage as one metric for assessing the effectiveness of fuzzing. While protocol specifications and application definitions can be used for fuzzing, the interdependencies of fields and messages within protocols, including state, are not always obvious. For example, when looking at the telnetd source, it’s pretty obvious that you need to send 4 or 5 primary telnet options before the server will enter the main loop. Or the fact that no matter what you do with the XDISPLAYLOC telnet option, you are wasting time since the server simply passes this to setenv.
What we really need is an interactive way to look at code coverage to help us guide the development of a fuzzer. The goal here is not as much to get a concrete measurement about the coverage, but to help us better understand how the control flow works and how the protocol fields affect the control flow. It also helps us understand how some fields/messages up front affect the subsequent messages because of the dependencies in state, structure and semantics.
Various reverse engineering tools exist for compiled binaries including, IDA pro and Pai Mei. But when you have the source, why not use it? Lcov is another open source tool that generates coverage information from multiple runs of the target and it’s primary purpose is to provide top-line summaries of directories and files. However, it’s not interactive.
Rcov is a WEBrick application that uses the compile/runtime output generated by gcov, uses the browser for navigation (tested with Firefox and Safari), cross links the source using ctags and decorates the output using the runtime coverage data generated by the program under execution. You can think of this as a cross between Doxygen and lcov.
Once rcov is fired up with the root directory of the target’s source, it will first read the various gcda files generated by the compiler. It will then listen on localhost:8080 and you can point your browser to this URL. Run your fuzzer against the target and each time the target exits, the gcov compiled target will dump a bunch of gcno files. Refresh your browser window and you should see the source files updated with coverage information.
More information in the README.txt included in the distribution. And yeah, the ‘r’ in rcov is for ruby.