It comes with great convenience if we already have a reproduceable syz testcase (i.e., testcase in syzkaller's format) since it allows us to perform fuzzing and produce corresponding c PoC with source code instrumetation. Otherwise, we have to do it manually. Also, the automation we provide also comes with a price, the lack of flexibility and a lot of corner cases we did not handle well. To cope with it, we hereby offer a detailed tutorial explaning the logic of the tool and how we can interact with the tool.
If we have syz PoC, we could simply use syz-prog2c
to generate c PoC with annotation as follows:
${GOPATH}/src/github.com/google/syzkaller/bin/syz-prog2c -prog path/to/syz -s2e
Add options "-sandbox namespace -tmpdir" if it requires user namespace.
Add option "-threaded" if it requires multi-threading.
Alternatively, we can manually annotate the PoC.
// add header file:
#include <s2e.h>
// Insert the following right before the first syscall we would like to track.
// Indicating the start of the process
s2e_invoke_plugin("ProgramMonitor", "s", 1);
// Insert the following right after the last syscall we would like to track.
// INdicating the end of the process
s2e_invoke_plugin("ProgramMonitor", "e", 1);
// For any syscalls' argument you find interesting
s2e_make_symbolic((void*)0x20000300, 32, "ptr_0x20000300");
Build the poc:
gcc poc.c -o poc -I${S2EDIR}/source/s2e/guest/common/include/s2e -lpthread
// s2e new_project -h for details
s2e new_project -n p0 -i image -f path/to/poc
Now we have a project named p0 at ${S2EDIR}/projects/p0.
cd aeg-analysis
python main.py pahole -i path/to/vmlinux --known
We use the tool pahole to extract debug info from vmlinux and look for candidates that have either reference counter or pointer. To reduce false positives, we add an option '--known' to only check types that defined in aeg-analysis/template/known.json
.
The results are store in aeg-analysis/candidates.lua
, you can add your own target objects to it.
The purpose of the this step is to identify the vulnerable object causing OOB. Then, in next run we could track every read/write to this particular object.
cd aeg-analysis
// Patch the s2e-config.lug config file
python main.py genconf -p p0 -i path/to/vmlinux -e -m 1
cd ${S2EDIR}/projects/p0
./launch-s2e.sh
Upon success, you could see a message like this one:
[Busy Object] {"Callsite": [18446744071595249223, 18446744071595260884], "Size": 32768, "Allocator": "page", "Symbolic": true}
By default, we only track process 0, but we can add extra processes to track by adding the option '--pids pid_num'.
As mentioned earlier, this step is to identify all the OOB access.
cd aeg-analysis
// Patch the s2e-config.lug config file
python main.py genconf -p p0 -i path/to/vmlinux -e -m 2
cd ${S2EDIR}/projects/p0
./launch-s2e.sh
The first step extracts the info of the vulnerable object from the output file ${S2EDIR}/projects/p0/s2e-last/debug.txt
and saves it to ${S2EDIR}/projects/p0/vuln.json
.
Upon success of the second cmd, we could see messages like:
[KASAN] {"ip": [18446744071595236015, 18446744071595255266], "addr": 18446612133206425644, "len": 4, "reliable": false, "write": true}
cd aeg-analysis
// Patch the s2e-config.lug config file
python main.py genconf -p p0 -i path/to/vmlinux -e -m 3
cd ${S2EDIR}/projects/p0
./launch-s2e.sh
The first step extracts the info from the output file ${S2EDIR}/projects/p0/s2e-last/debug.txt
and saves it to ${S2EDIR}/projects/p0/reports.json
. Among those vulnerability points, sometimes we do not need to analyze all of them, for instance, an OOB access triggered by memcpy
is usually powerful enough for an exploit. Thus, the first step also picks which vulnerability points we want to analyze. You can change it by modifying pluginsConfig.KernelInstructionTracer.spots
in s2e-config.lua
.
Upon success of the second cmd, we could see messages similar to:
{"solution": {"ptr_0x20000000": [2, 0, 0, 0],
... ...
"target": "packet_sock_sk_destruct", "size": 32768,
"pointer": "0xdeadbeefdeadbeef"}
We could use the following cmd to extract the info:
python main.py parselog -p p0 --solution
It produces some 'ans_*.json' files containing the concrete inputs of syscalls' arguments (recall we make some arguments symbolic at step 1) and the heap status useful for feng shui strategy. Not that race condition is not well supported and thus the heap status may not be correct.
${GOPATH}/src/github.com/google/syzkaller/bin/syz-prog2c -prog path/to/syz -exp -json ans_*.json
For now, we only provide a few exploit strategies and thus most exploit genereation will fail. Also, race condition is not supported for this step.