MoonShine selects compact and diverse seeds for OS fuzzers from system call traces of real world programs. Please see our USENIX'18 paper MoonShine: Optimizing OS Fuzzer Seed Selection with Trace Distillation for more details. Currently, MoonShine can only generate seeds for Syzkaller on Linux.
The following setup instructions have been tested on Ubuntu 16.04. Let us know if there are issues on other versions or distributions.
MoonShine is mostly written in Go so the first step is to setup Go. You can either follow the below instructions or follow the Official Go Installation Guide .
$ wget https://dl.google.com/go/go1.10.3.linux-amd64.tar.gz
$ sudo tar -C /usr/local -xzf go1.10.3.linux-amd64.tar.gz
$ export PATH=$PATH:/usr/local/go/bin
$ go version
go version go1.10.3 linux/amd64
After installing Go, setup your Go workspace. Your Go workspace is where all Go project binary and source code is stored. By default, Go expects the workspace to be under $HOME/go
so either create the directory $HOME/go
or install to a custom location and set $GOPATH
(Note: If you have already setup Syzkaller then this step can be skipped since Syzkaller is a Go project)
MoonShine uses ragel (variation of lex) to scan/parse traces.
sudo apt-get update
sudo apt-get install ragel
MoonShine uses goyacc (variation of yacc) to scan/parse traces.
go get golang.org/x/tools/cmd/goyacc
goyacc gets installed in $HOME/go/bin
(or $GOPATH/bin
if workspace is not in the home directory). Make sure this directory is on your $PATH.
$ export PATH=$PATH:$HOME/go/bin
go get -u -d github.com/shankarapailoor/moonshine/...
cd $GOPATH/src/github.com/shankarapailoor/moonshine
make
Once MoonShine has been successfully built, we can generate seeds for Syzkaller as follows:
$ ./bin/moonshine -dir [tracedir] -distill [distillConfig.json]
The arguments are explained below:
-dir
is a directory for traces to be parsed. We have provided a tarball of sample traces on Google Drive to get started. To run the example below, download the tarball, move it to thegetting-started/
directory, and unpack.-distill
is a config file that specifies the distillation strategy (e.g. implicit, explicit only). If the traces don't have call coverage information or you simply don't want to distill, then this parameter should be ommitted and MoonShine will generate traces "as is". We have provided an example config undergetting-started/distill.json
$ ./bin/moonshine -dir getting-started/sampletraces/ -distill getting-started/distill.json
Total number of Files: 346
Parsing File 1/346: ltp_accept4_01
Parsing File 2/346: ltp_accept_01
...
Total Distilled Progs: 391
Average Program Length: 10
Total contributing calls: 639 out of 43480 in 388 implicitly-distilled programs. Total calls: 3250
MoonShine produces a corpus.db
file that contains the serialized Syzkaller programs. Move corpus.db
to your Syzkaller workdir and begin fuzzing!
MoonShine also writes the deserialized syzkaller programs from the traces under deserialized
so that you can manually inspect the conversion. If moonshine was run without distillation, then the programs in the deserialized directory obey the naming convention [trace_name]+[id]
. If the original trace consists of 1 task, id
should always be 1, but if there are multiple tasks then each task is assigned a unique id and converted to a separate program.
$ ls deserialized/
ltp_accept_011
ltp_accept4_011
...
MoonShine has been tested with Syzkaller commit f48c20b8f9b2a6c26629f11cc15e1c9c316572c8
. Instructions to setup Syzkaller and to build Linux disk images for fuzzing can be found here. Although the instructions say they are for Ubuntu 14.04 it also works for Ubuntu 16.04+.
Currently, MoonShine can only parse traces gathered with strace. We also suggest that you use strace versions >= 4.16 as those are the only versions we have tried so far. You can download specific releases at the Official Strace Release page. Build instructions can be found here.
MoonShine needs to know the coverage achieved by each call in a trace in order to distill traces. We have created a patch strace_kcov.patch for strace that captures per-call coverage using kcov. This patch should be applied to commit a8d2417e97e71ae01095bee1a1e563b07f2d6b41
. Follow the below instructions to both build strace and apply the patch.
$ cd ~
$ git clone https://github.com/strace/strace strace
$ git checkout a8d2417e97e71ae01095bee1a1e563b07f2d6b41
$ git apply $GOPATH/src/github.com/shankarapailoor/moonshine/strace_kcov.patch
$ ./bootstrap
...
$ ./configure
....
$ make
- -s [val] indicates the maximum amount of data that should be written for each call. We typically set val to 65500.
- -v means the arguments should be unabbreviated
- -xx writes strings in hex
- -f captures traces from children processes (follows forks)
- -k captures per-call coverage (Only supported on patched strace. Requires kernel compiled with CONFIG_KCOV=y)
$ strace -o tracefile -s 65500 -v -xx -f -k /path/to/executable arg1 arg2 .. argN
We are actively working with Syzkaller maintainers to add MoonShine as a collection of Syzkaller tools. Our current plan is to break MoonShine into two tools. The first converts strace-output to Syzkaller programs, and the second distills the generated programs. We have a pull request for the first tool here where you can see the current status. After this has been integrated, we will create a PR for the second. We also have an active email thread on Syzkaller google group here where you can follow ongoing discussions.
MoonShine's code is concentrated in 5 directories:
strace_types
- contains data structures corresponding to high level types present in the strace traces such as call, structs, int, flag, etc.. In essence, this these types are composed to provide in-memory representation of the Tracescanner
- scans and parses strace programs into their in-memory representationparser
- converts the in-memory trace representation into a Syzkaller programdistiller
- distills the Syzkaller using the coverage gathered from traces.implicit-dependencies
- contains a json of the implicit dependencies found by our Smatch static analysis checkers.
- Memory Corruption in inotify_handle_event() (CVE-2017-7533)
- Memory Corruption in __jfs_setxattr() (CVE-2018-12233)
- Denial of Serivce in socket_setattr() (CVE-2018-12232)
- Double free in inet_child_forget()
- Use after free in move_expired_inodes()
- Integer overflow in pipe_set_size()
- Integer overflow in posix_cpu_timer_set()
- Deadlock in Reiserfs
@inproceedings {Pailoor18,
author = {Shankara Pailoor and Andrew Aday and Suman Jana},
title = {MoonShine: Optimizing {OS} Fuzzer Seed Selection with Trace Distillation},
booktitle = {27th {USENIX} Security Symposium ({USENIX} Security 18)},
year = {2018},
address = {Baltimore, MD},
url = {https://www.usenix.org/conference/usenixsecurity18/presentation/pailoor},
publisher = {{USENIX} Association},
}
- Shankara Pailoor - sp3485@columbia.edu
- Suman Jana - suman@cs.columbia.edu
- Andrew Aday - andrew.aday@columbia.edu