How to Set Up Your C or C++ Project for Fuzzing
Download an Example Project
Now that the installation is complete, we can move on to fuzzing our first C++ project. First you have to start the CI Daemon. Open a new terminal and start it with $ ci-daemon. For this tutorial, we are going to test CppCMS. CppCMS is a High Performance C++ Web Framework that can be found at https://github.com/artyom-beilis/cppcms.
Download the vulnerable version 1.2.0 either through the browser or via git as follows:
$ git clone https://github.com/artyom-beilis/cppcms.git
$ cd cppcms
$ git checkout v1.2.0
To enable fuzzing a C++ project with CI Fuzz, open the project in VS Code (File > Open Folder).
If you have our extension installed, you can start it with clicking on our logo in the left sidebar. This will lead you from VS Code’s file browser sidebar to our CI Fuzz sidebar:
From here, you can create the Fuzzing Project with a click on the plus button next to “Create Fuzzing Project”.
CI Fuzz will automatically detect most current build systems for C++ including CMake, Autotools, Scons, Bazel, Ninja and of course Unix Makefiles. If it recognizes a build system it will ask to automatically create a script to build the project with sensible defaults.
But even if the build system is not detected you can just enter the steps needed to build the project manually. Click continue.
Here you need to provide the name of a docker image, which will allow CI Fuzz to create containers in which the fuzzing project and fuzz tests will be built. This image must contain all the dependencies needed to build your project.
In case of cppcms, you can create a simple image yourself. Create a file called "Dockerfile" with the following contents:
RUN apt update && apt install -y g++ cmake
RUN apt install -y libpcre3-dev zlib1g-dev libgcrypt-dev libicu-dev python
Note: When selecting the base image (the FROM instruction in your Dockerfile), it is better to avoid images that contain newer versions of system libraries than your host system. This could later cause issues with dependencies when debugging your code.
Then execute the following command within the directory where the Dockerfile resides, to build the Docker image and call it cppcms:
$ docker build . -t cppcms
Lastly, type cppcms in the Docker Build Image field and click Submit.
Alternatively, local mode creates distroless docker containers which will use dependencies installed on your system.
Additional Docker volume mounts in the Advanced Settings section will let you mount files and directories that reside on your local filesystem inside the docker container that will be used for building and fuzzing your project. WARNING: this only works when you are fuzzing on your own computer. It will not work if you load your fuzzing project in the CI Fuzz Web Interface for Continuous Fuzzing.
Once the project has been created, it is time to initialize it. In this step, we are simply building the project, without any modification. This allows us to identify which parts of the code end up in which libraries and helps us to automate the internal configuration of the fuzz tests.
To run the initialization, click on the Submit button below the docker configuration options.
Depending on the size of your project, this might take a while, since we are building the whole project by default. You can of course disable compilation of parts of the code that are not relevant for the fuzz tests, like already existing unit tests. For CMake, this can be done by adding -DBUILD_TESTING=OFF to the cmake call. CI Fuzz makes use of the build system caching capabilities. That means, future re-initializations of the same project are done faster.