Fuzzing on Real Target
In this post, I will begin to use fuzzilli and try on the present supported targets. Section 4 I took note of some information about some background knowledge of swift.
Fuzzing Preparation
My ubuntu environment is showed as below
Install Clang
The require version >=4.0, I installed clang-10. This part I installed before. But I did meet some problem after I installed swift.
The path of clang point to the path of the swift installed folder, which forced me to reinstall Clang again, and add clang into update-alternative --config
. Using sudo ln
may solve this issue but I did not try.
1 | sudo apt-get install clang-10 #or just simply install clang |
The llvm-dev
is also needed:
1 | sudo apt install llvm-dev |
If want to swap to different clang version:
1 | sudo update-alternatives --config clang |
For remove the link (and its slave):
1 | sudo update-alternatives --display clang #or clang++ or others |
Do not install like this (easier to make error)
1 | sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-10 10000 |
I guess clang may not need to install since swift it has it. But I am not sure so I note down this part of installing clang here.
Install Swift
Ensure that the package index and installed packages are up to date
1 | sudo apt update && sudo apt upgrade |
Install the dependency of swift (I did not execute this, but for new docker container or new installed system, this could be needed)
1 | sudo apt install binutils git gnupg2 libc6-dev libcurl4 libedit2 libgcc-9-dev libpython2.7 libsqlite3-0 libstdc++-9-dev libxml2 libz3-dev pkg-config tzdata zlib1g-dev |
Download toolchains from the swift download page. For example, I choose swift-5.4.2-RELEASE-ubuntu18.04.tar.gz
to download. Then, extract the file into a folder (home/user_name/):
1 | tar -xvzf swift-5.4.2-RELEASE-ubuntu18.04.tar.gz -C ~ |
Add the path into ~/.bashrc
and source it (restart the environment)
1 | echo "PATH=~/swift-5.4.2-RELEASE-ubuntu18.04/usr/bin:$PATH" >> ~/.bashrc |
To verify the swift, can enter:
1 | swift --version |
if the output is as below, that means swift has been instlled.
Test Swift
To test the swift in commandline, enter swift
, and terminal will launch an shell called REPL or Read Eval Print Loop. Here I met some error when enter REPL:
After remove libc6-dbg
, the error message just gone.
1 | sudo apt remove libc6-dbg |
Type in the following code to see whether swift works or not.
1 | let name = "LinuxConfig" |
After testing, can use ctrl + d
or :quit
or :q
to exit.
Build Fuzzilli
1 | git clone https://github.com/googleprojectzero/fuzzilli.git |
If build sucessfully, we can begin to fuzz the JavaScript Engine.
Begin Fuzzing
After establish the environment of swift and clang, fuzzilli can be tried on the following JSE (JavaScript Engine).
Fuzzing on JavaScriptCore
JavaScriptCore is the JSE implemented in Safari. Firstly, download the source code, and patch it by using fuzzilli's patch.
1 | git clone https://github.com/WebKit/webkit |
After this, we can begin to run fuzzilli
1 | sysctl -w 'kernel.core_pattern=|/bin/false' #Run this if this is first time to use fuzzilli to fuzz |
In the commandline, the error may be generate:
1 | error: root manifest not found |
Thus, shoule execute this command at first:
1 | swift package init --type executable |
However, sometimes it does not work, so the problem of show "root manifest not found" error is because the project lack of package.swift
. Thus, I found the solution finally, that is clone the whole project in fuzzilli instead of any else where! So all the source code of sepcific JSE (Here is JavaScriptCore) should under /Path/to/fuzzilli/Targets/xxx
, this ensure that they have package.swift
exists in the root folder of fuzzilli
.
Thus, I git clone
the webkit under ~/coding_env/fuzzilli/Targets/JavaScriptCore
, and execute the following command under ~/coding_env/fuzzilli/Targets/JavaScriptCore/webkit
:
1 | swift run -c release -Xlinker='-lrt' FuzzilliCli --profile=jsc FuzzBuild/Debug/bin/jsc #under fuzzilli's folder, in .../fuzzilli/Targets/JavaScriptCore/webkit |
Fuzzing begin! This will take some time to initialize.
Begin to fuzz, let's look at the console.
After fuzzing, we can conduct crash analysis by using gdb
.
Fuzzing on QJS
QuickJS is a embeddable JS engine. Using the follow command to build this. Or enter this link to download the code from the version in Targets/QJS/REVISION
.
1 | cd fuzzilli/Targets/QJS #Make sure under the fuzzilli directory |
I encountered some issues here, so I think this should be build on MacOS (which set default to use clang to compiler):
Build on Ubuntu failed, I am still figuring why and how to fix this. It seems not supported to use clang to build QuickJS on Ubuntu (set default to use gcc, but gcc not support -fsanitize-coverage=trace-pc-guard
, and only clang supports this.
On ubuntu, if make by using make qjs
(follow the instruction on here), the error is different.
It seems very near to the success, but I stuck on here.
Fuzzing on V8
V8 is the open source JSE used in chrome. First, we need to fetch the source code. so install depot_tools at first.
1 | git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git |
Add depot_tools to the front of your PATH (you will probably want to put this in your ~/.bashrc
or ~/.zshrc
). Assuming you cloned depot_tools to /path/to/depot_tools
:
1 | export PATH=/path/to/depot_tools:$PATH |
Update depot_tools
by executing the following into your terminal/shell.
1 | gclient |
Now, get the V8 source code, including all branches and dependencies:
1 | cd fuzzilli/Targets/V8 #Make sure under the fuzzilli directory |
If want to update the code, could use the following command:
1 | git pull |
Done! Let's go to the directory of v8 and copy a fuzzbuild.sh
script in the v8 root directory. Then try to execute fuzzbuild.sh
in the v8 root directory.
We successfully built it! Let's type in this command to begin fuzzing
1 | cd .. |
Now it works well!
Note: sanitizer coverage for v8 is currently not supported on macOS as it is missing from v8's custom clang toolchain.
Fuzzing on Duktape
Duktape is a embeddable Javascript engine. First, fetch the code from github:
1 | cd fuzzilli/Targets/duktape #Make sure under the fuzzilli directory |
The executable will be named duk-fuzzilli
, in the duktape directory. However, I stuck after I type in make duk-fuzzilli
Fuzzing on Spidermonkey
Spidermonkey is a opensource JSE implemented in firefox. First, clone the repo and run the script in Fuzzilli.
1 | cd fuzzilli/Targets/Spidermonkey #Make sure under the fuzzilli directory |
After copy the fuzzbuild.sh
in Targets/Spidermonkey
to the directory of gecko-dev/js/src
, run it
1 | cd Targets/Spidermonkey/gecko-dev |
fuzzbuild_OPT.OBJ/dist/bin/js
will be the JavaScript shell for the fuzzer
1 | mkdir out #In gecko-dev/js/src |
Happy hacking!
Fuzzing on Jerryscript
Jerryscript is a lightweight JavaScript engine for the Internet of Things. To fetch the code:
1 | cd fuzzilli/Targets/Jerryscript #Make sure under the fuzzilli directory |
Then apply the patch and run the script (fuzzbuild.sh
). Note that rustc
may need in this part.
1 | cd jerryscript #Ensure under fuzzilli/Targets/Jerryscript/jerryscript |
./build/bin/jerry
will be the JavaScript shell for the fuzzer.
1 | mkdir out #In Targets/Jerryscript/jerryscript |
Hah! Let's begin fuzzing!
Swift Basic Knowledge (Optional)
Swift use SPM (Swift Package Manager) to establish a new package project. Make a new folder called swift_test
and use this command to initialize.
1 | swift package init --type executable --name helloworld #swift build --init |
So the executable swift package called helloworld
will be generated in this folder.
We can execute this by build and run.
So this create a fundemental Command line tool
.
Fuzzilli in Docker (Optional)
The part can be referred to this document, available docker image can be found here.
Install Rust (Optional)
1 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh #Choose 1 after this |
Ouput message is showed as below:
All the tool included rustc
, cargo
and rustup
will be located in ~/.cargo/bin
. It can be added into PATH
environment variable. try rustc --version
to check rust has been installed or not. If want to uninstall, try rustup self uninstall
.