This project is a fast greybox fuzzer forked from Neutrino, built for the ARMv7 architecture and designed to increase the security of the software developed for IoT applications.
We extended the existing x86 translation component to support the ARM architecture. We also improve its resource utilisation and overall performance by fixing some bottlenecks, bugs and memory leaks. In the end, we compare its result on a benchmark of libraries with AFL to validate our solution.
CMake >= 3.7
Clang >= 6.0 (for ASAN usage)
git clone https://github.com/systems-cs-pub-ro/neutrino.git
mkdir neutrino-build
cd neutrino-build
cmake ../neutrino
make
make install
Neutrino requires a configure file neutrino/deploy/neutrino.json. This is an example of the config file:
{
{
"inputs":{
"fileinput":{
"dirs":[
"/home/alex/neutrino/deploy/inputs"
],
"exceptions":[
]
}
},
"outputs":{
"fileoutput":{
"dir":"/home/alex/neutrino/deploy/outputs"
}
},
"loggers":{
"consolelogger":"/home/alex/neutrino/deploy/logs"
},
"evaluator":{
"plugin":"traceevaluator"
},
"mutator":{
"plugin":"mutator"
}
}
cd neutrino/src/payload
g++ -g -c Payload2.cpp
g++ -shared -g Payload2.o -o fuzzer.so
cp fuzzer.so ../../deploy/payload/fuzzer.so
cd neutrino/deploy
./neutrino
ASAN_OPTIONS=abort_on_error=1 LD_PRELOAD=/usr/local/clang_6.0.0/lib/clang/6.0.0/lib/linux/libclang_rt.asan-armhf.so ./neutrino
alex@rpi1:~/neutrino/deploy $ ./neutrino
libname ./payload/fuzzer.so
[00:00:00.022] NEW queued: 1, traced: 1, corpus: 1, coverage: 88, unique crashes: 0, memory: 270.38MB, paths: 1 test: 8c5dea64...
[00:00:00.023] NEW queued: 0, traced: 2, corpus: 2, coverage: 88, unique crashes: 0, memory: 270.38MB, paths: 2 test: 3f786850...
[00:00:01.780] NEW queued: 4095, traced: 151, corpus: 3, coverage: 88, unique crashes: 0, memory: 293.79MB, paths: 3 test: 061fb208...
[00:00:01.782] NEW queued: 4091, traced: 155, corpus: 4, coverage: 88, unique crashes: 0, memory: 293.79MB, paths: 4 test: 69c3f6f4...
[00:00:05.466] NEW queued: 1, traced: 4867, corpus: 5, coverage: 90, unique crashes: 0, memory: 294.07MB, paths: 5 test: 629c9462...
^CCtrl-C pressed... Shutting down...
[00:00:14.370] DONE queued: 563, traced: 18205, corpus: 5, coverage: 90, unique crashes: 0, memory: 297.21MB, paths: 5
Executed: 18186
Evaluated: 5
Crashed: 0
We chose a test suite that can give us some meaningful results that can be compared with other fuzzers, google-fuzzer-test-suite, despite the fact that its targets are not exactly IoT binaries. This is a benchmark for fuzzers, created by Google, containing 24 libraries that have real-life use and interesting bugs/scenarios for a fuzzer to test. The infrastructure consists of several building scripts that generate a binary for AFL to fuzz, following the steps below:
- download the exact version of the library source code that has the known exploits
- build the library and generate the static version of it for AFL to use
- compile the target with the static library in order to obtain an AFL binary
The benchmark comes with corpus seeds for some of the libraries and with details about the inputs that generate crashes most of them are using ASAN to trigger the crashes) in the library so you can test your own custom fuzzer against them.
Since ASAN is not officially supported on ARM we had problems with some of the libraries which on execution produced false positive warnings for every input given. Others had no support for ARM, some of them had no actual exploits and were being used just as a coverage benchmark we end up with a limited set of 12 libraries.
These are the following: c-ares-CVE-2016-5180, json-2017-02-12, libpng-1.2.56, openssl-1.1.0c, re2-2014-12-09, sqlite-2016-11-14, vorbis-2017-12-11, woff2-2016-05-06, harfbuzz-1.3.2, guetzli-2017-3-30, freetype2-2017, libjpeg-turbo-07-2017. We ran Neutrino on these targets and recorded results based on following parameters: executions per second, coverage, time to crash and translation overhead.
In the following tables, the results we obtained can be observed.