Coder Social home page Coder Social logo

thumper's Introduction

README

Thumper is a project that provides further accessibility for fuzzing targets with AFL. This is currently in a development stage. The original code is based on Kelinci written by Rody Kersten, but Thumper is larger than just providing Java fuzzing with AFL, and is currently being developed to provide fuzzing on Hypervisors where gathering code coverage and test data is currently difficult. Additionally, Thumper will likely modify AFL to provide a faster low level socket interface, instead of using a shim binary as it does today.

Java Fuzzing

Thumper provides Java fuzzing through the combination of the fuzzerside and instrumentation directories. This is mostly provided through the capabilities provided by Kelinci, but has provided optimizations to the fuzzing model tha tprovides up to a 100x speedup in some cases. However, this is still under development and has its quirks.

Known Issues Regressions from Kelinci

On this particular repository, I modified the code to run much faster, but has a couple limitations.

First, there seems to be issues with executions dropping down to 50/second. To avoid this, I recommend wrapping the script to run the Java component with the following command: while true; do timeout -k 1 10 java -cp YOUR_CLASSPATH edu.cmu.sv.kelinci.Kelinci -v 0 YOUR_CLASS @@; done

Also, there is no longer the ability to run remote. If you want to run remote, you'll have to modify the Java/C components to allow the option again.

Installation

The application has two components. First, there is a C application that acts as the target application for AFL. It behaves the same as an application built with afl-gcc / afl-g++; AFL cannot tell the difference. This C application is found in the subdirectory 'fuzzerside'. It sends the input files generated by AFL to the JAVA side over a TCP connection. It then receives the results and forwards them to AFL in its expected format. To build, run make in the 'fuzzerside' subdirectory.

The second component is on the JAVA side. It is found in the 'instrumentor' subdirectory. This component instruments a target application with AFL style administration, plus a component to communicate with the C side. When later executing the instrumented program, this sets up a TCP server and runs the target application in a separate thread for each incoming request. It sends back an exit code (success, timeout, crash or queue full), plus the gathered path information. Any exception escaping main is considered a crash. To build, run gradle build in the 'instrumentor' subdirectory.

Usage

This describes how to run Kelinci on a target application. It assumes AFL and both Kelinci components have been built.

1. Optional: build a driver AFL/Kelinci expects a program that takes a parameter specifying a file location. It randomly mutates files to fuzz this program. If this is not how your target application works, a driver will need to be built that parses an input file and simulates the normal interaction based on that. When building a driver, remember that the input files will be randomly mutated. The less structure and cohesion the program expects in the file, the more effective fuzzing will be. Even if the program does accept an input file, it could make sense to build a driver that accepts a different format in order to maximize the ratio of valid version invalid input files.

One more thing to take into account when building a driver is that the target program will be running in a VM where the main method will be invoked again and again. All runs must be independent and deterministic. If the program for instance stores information from an input in a database or a static memory location, be sure to reset it such that it cannot affect future runs.

2. Instrument We'll assume that the target application and driver were built and the output directory is 'bin'. Our next step is to instrument the classes for use with Kelinci. The tool provides the edu.cmu.sv.kelinci.instrumentor.Instrumentor class for this. It takes an input directory after the -i flag (here 'bin') and an output directory after the -o flag (here 'bin-instrumented'). We'll need to make sure that the kelinci JAR is on the classpath, as well as all the dependencies of the target application. Assuming the JARs that the target application depends on are in /path/to/libs/, the command to instrument looks like this:

java -cp /path/to/kelinci/instrumentor/build/libs/kelinci.jar:/path/to/libs/* edu.cmu.sv.kelinci.instrumentor.Instrumentor -i bin -o bin-instrumented

Note that there may be trouble if the project depends on different versions of libraries that the Kelinci Instrumentor also depends on. Currently, these are args4j version 2.32, ASM 5.2 and Apache Commons IO 2.4. In most cases, one can make this work by putting the 'classes' directory of the Kelinci build on the class path instead of the Fat JAR, then add a version of the library JARs to the classpath that both Kelinci and the target work with.

3. Create example input We want to test that the instrumented Java application works now. To do this, create a directory for example input file(s): mkdir in_dir

AFL will later use this directory to grab the input file(s) that it will mutate. It is therefor very important to have representative input files in there. Copy representative file(s) in there, or create them.

4. Optional: test the Java application See if the instrumented Java application works with the provided / created input files: java -cp bin-instrumented:/path/to/libs/* <driver-classname> in_dir/<filename>

5. Start the Kelinci server We can now start the Kelinci server. We will simply edit the last command we executed, which ran the Java application. Kelinci expects the main class of the target application as the first parameter, so we can now just add the Kelinci main class before that one. We'll also need to replace the concrete file name by @@, which will be replaced by Kelinci with the actual path of the input file it wrote. Other parameters are ok and will be fixed across runs.

java -cp bin-instrumented:/path/to/libs/* edu.cmu.sv.kelinci.Kelinci <driver-classname> @@

Optionally, we can specify a port number (the default is 7007): java -cp bin-instrumented:/path/to/libs/* edu.cmu.sv.kelinci.Kelinci -port 6666 <driver-classname> @@

6. Optional: test the interface Before we start the fuzzer, let's make sure that the connection to the Java side is working as expected. The interface.c program has a mode for running outside of AFL as well, so we can test it as follows: /path/to/kelinci/fuzzerside/interface in_dir/<filename>

If we created a list of servers in step 6, we can add it as follows: /path/to/kelinci/fuzzerside/interface -s servers.txt in_dir/<filename>

Optionally, we can specify a server with the -s flag (e.g. -s 192.168.1.1 or "sv.cmu.edu", default is "localhost") and a port number with the -p flag (default is 7007).

7. Start fuzzing! If everything works as expected, we can now start AFL! Like the Kelinci server side, AFL expects a binary that takes an input file as a parameter, specified by @@. In our case, this is always the interface binary. It also expects a directory with input files from which to start fuzzing, plus an output directory.

/path/to/afl/afl-fuzz -i in_dir -o out_dir /path/to/kelinci/fuzzerside/interface [-s servers.txt] @@

If everything works, the AFL interface will start up after a short while and you'll notice new paths being discovered. For additional monitoring, have a look at the output directory. The input files in the 'queue' subdirectory all trigger different program behaviors. There are also 'crashes' and 'hangs' subdirectories that contain inputs that resulted in a crash or a time-out. Please see the AFL website for more details: http://lcamtuf.coredump.cx/afl/

Note on parallelization

The Java side is naturally parallelizable. Simply start an instance for every core you want to execute your Java runs on. This can be on the same machine (but different ports!) or on multiple machines.

For details on how to run AFL in parallel, please see the parallel_fuzzing.txt document that comes with it. You'll want to have as many afl-fuzz processes running as there are Java side Kelinci components, where each afl-fuzz process connects to a different Kelinci server. The Kelinci server to connect to can be specified using the -s <server> and -p <port> flags for interface.c.

Credit to Kelinci Developer

Rody Kersten ([email protected])

Thumper Developer / Maintainer

Sam Smith ([email protected])

thumper's People

Contributors

jtpereyda avatar jwilk avatar rodykersten avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.