NTFUZZ is a type-aware kernel fuzzing framework for Windows. For the details of NTFUZZ, please see our paper "NTFUZZ: Enabling Type-Aware Kernel Fuzzing on Windows with Static Binary Analysis", published in IEEE Symposium on Security and Privacy 2021.
You can clone the repository and initialize it as follow.
$ git clone https://github.com/SoftSec-KAIST/NTFuzz
$ cd NTFuzz
NTFuzz$ git submodule update --init
The repository contains three components.
DLLAnalysis statically analyzes Windows system binaries and infers the types of system calls.
Hooker is a hooking driver which is installed in kernel. It intercepts system calls generated by a seed application, and performs type-aware fuzzing on their arguments.
Launcher is responsible for launching a seed application used for hooking-based fuzzing.
First, we use DLLAnalysis module to statically analyze Windows system binaries and infer system call types. In addition, DLLAnalysis module also generates system call wrapper code needed by Hooker module.
We used Windows Subsystem for Linux (WSL) to run the static analyzer, but you can run the analyzer on a pure Linux, too. Other platforms are also supported if you slightly modify the commands and scripts below.
- Install .NET 5.0 SDK and .NET 3.1 Runtime.
Installation process depends on the Linux distributions and versions, so please refer to this link. For instance, if you are using Ubuntu 18.04, you would have run the following commands.
$ wget https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
$ sudo dpkg -i packages-microsoft-prod.deb
$ rm packages-microsoft-prod.deb
$ sudo apt-get update
$ sudo apt-get install -y apt-transport-https
$ sudo apt-get update
$ sudo apt-get install -y dotnet-sdk-5.0 dotnet-runtime-3.1
- Build the static analyzer.
NTFuzz$ cd DLLAnalysis
NTFuzz/DLLAnalysis$ make
- Run the analysis on DLL files.
For fuzzing on Windows 17134.1 build (released in April 2018), run the following
script. It statically analyze Windows DLL files under binaries/17134.1
directory, and generates outputs at output/
directory.
NTFuzz/DLLAnalysis$ ./scripts/run_on_18_Apr.sh
Similarly, you can use the following command to analyze the system binaries of Windows 18362.592 build (released in January 2020).
NTFuzz/DLLAnalysis$ ./scripts/run_on_20_Jan.sh
To run the analyzer on other builds of Windows 10, you can put the relevant DLL
files under ./binaries/<build number>
directory and create your own script
similar to run_on_18_Apr.sh
or run_on_20_Jan.sh
.
For now, we release B2R2 front-end for static analysis in binary form. This is because the B2R2 version we used in NTFUZZ is not yet released in the upstream repository.
- Install Visual Studio, Windows SDK and Windows Driver Kit.
In particular, we used Visual Studio 2019, Windows SDK 10.0.18362.1, and Windows Driver Kit 10.0.18362.1.
- Copy system call wrapper code generated by the DLL analyzer.
For instance, if you are targeting Windows 17134.1 build, you can copy the files generated from the previous step as follow.
NTFuzz$ cp DLLAnalysis/output/VersionConst_18_Apr.h Hooker/Driver/inc/VersionConst.h
NTFuzz$ cp DLLAnalysis/output/GeneralHooker_18_Apr.cpp Hooker/Driver/src/GeneralHooker.cpp
- Build the hooking driver and its controller.
Open Hooker.sln with Visual Studio and build the solution. You may have to manually set the target platform into 'x86' before the build. The solution will output a hooking driver (Hooker.sys) and a program to interact with that driver (Controller.exe).
- Pack up the hooker directory.
Now, pack up the hooker directory by copying the system call type specification file. This hooker directory will be used in the next step. Please make sure to use the exact file names specified below.
NTFuzz$ cp DLLAnalysis/output/Types_18_Apr.json ./Hooker/Debug/Types.json
NTFuzz$ ls Hooker/Debug
Controller.exe Hooker.sys Types.json ...
- Prepare a Windows VM image.
We used a VM image to run hooking-based fuzzing, and do NOT recommend to run the fuzzing on your real machine.
Be careful to prepare the exact same Windows build that you statically analyzed in the first step. If the build versions do not match, the hooking driver will raise a kernel panic (blue screen of death) before the fuzzing actually starts.
- Install python packages and seed applications.
First, install python-2.7, and install PyWin32 and PyUserInput packages.
Next, setup seed applications to use for hooking-based fuzzing. If you are not sure what a seed application means, please refer to our paper. We will use Launcher module to run the seed applications. This module contains scripts to run the 8 seed application that we used in the experiment. You can add your own seed application and its running script, too.
Launcher module assumes that seed applications are properly prepared. For
instance, the script for SumatraPDF assumes that
the target executable is stored in C:\Apps\SumatraPDF.exe
, and a sample PDF
file is stored in C:\Files\paper.pdf
. Please check the script and satisfy the
requirement for the seed application that you wish to run.
- Copy hooker and launcher directories.
First, copy the Hooker build directory (Debug
) created in the previous step
and put it as C:\Hooker
in the VM.
Also, copy the Launcher directory and put it as C:\Launcher
in
the VM.
- Setup the hooker and start fuzzing.
First, launch a command prompt with an administrator privilege, and run the following commands. These commands register our hooking driver to the kernel.
> bcdedit /set testsigning on
> sc create Hooker type=kernel binpath=C:\Hooker\Hooker.sys
Next, initialize the hooker and start fuzzing. This does not have to be run with an administrator privilege.
> python C:\Launcher\hooker32.py
> python C:\Launcher\run32.py <heartbeat path> <target app> <mutate ratio> <PRNG seed>
- "heartbeat path":
run32.py
will periodically create an empty file at this path. This can be used as a signal to indicate that the fuzzing process is properly running. You can simply provide a dummy (but valid) path if this feature is not needed. - "target app": The ID of seed application to run. Currently we support
awatch
,chess
,dxdiag
,ppt
,sniffer
,sumatra
,unity
, andwordpad
. See Launcher/apps directory for more details. - "mutate ratio": The mutation ratio for fuzzing. Note that our parameter unit considers 1000000 as 100%. Thus, you should provide 10000 to specify 1% mutation ratio, for example. If you provide 1 as a mutation ratio, it will be interpreted as a variable mutation ratio we used in the experiment (Section VII.C of the paper).
- "PRNG seed": A pseudo random number generator seed to use in the fuzzing loop. You may want to provide different seeds if you run multiple instances of VM.
One may be interested in automating the whole fuzzing process, to scale up fuzzing. This includes launching VMs, detecting kernel crashes, rebooting the VMs, and so on. If you are interested, please take a look at this repository, although we do not provide detailed documentation as of now.
You can cite our paper with the following bibtex entry.
@INPROCEEDINGS{choi:oakland:2021,
author = {Jaeseung Choi and Kangsu Kim and Daejin Lee and Sang Kil Cha},
title = {{NTFUZZ}: Enabling Type-Aware Kernel Fuzzing on Windows with Static Binary Analysis},
booktitle = {Proceedings of the {IEEE} Symposium on Security and Privacy},
pages = {1973--1989},
year = 2021
}