First of all, Happy new hacking year everyone 😉
Just a quick reminder before we start, if you are interested about WebAssembly security and fuzzing WebAssembly Browsers/VMs, I decided to convert my 4-day live training into recorded courses (check here).
As you can see on caniuse.com, in January 2020, around 88% of all internet users can run WebAssembly modules on their browsers.
Notably, some security issues related to WebAssembly APIs has been found in V8, WebKit and Firefox by Natalie Silvanovich (@natashenka) but also in the closed-source Xiaomi Mi6 Browser by @fluoroacetate with CVE-2019-6743.
If you want to discover more about existing WebAssembly browser CVEs, take a look at those links:
Personally, I prefer the grammar syntax of Dharma but if you are a Domato adept, converting the following grammar to Domato shouldn’t be difficult 😉
The most time consuming part is to read all the specification and/or APIs descriptions in order to create valid wasm objects and methods calls. I will not detailed Dharma grammar syntax in this blogpost but you can find a complete grammar cheatsheet on the official github repository of Dharma. Once your grammar seems acceptable, you can generate multiple files using this command:
dharma -grammars dharma/wasm.dg -count 100 -format js -seed 1337 -storage output_folder
I just published a simple WebAssembly grammar in this github repository if you need something to start 😉 I also invited you to read the following blogposts to discover how other researchers are using Dharma or Domato 😉
In this blogpost, I will only target Chrome/V8 because it’s the best way for you (readers) to reproduce blogpost’s steps at home without spending hours in compilation/debugging. Just a quick reminder, AddressSanitizer (ASan) is a memory error detector based on compiler instrumentation (LLVM) and used to detect multiple kind vulnerabilities (UaF, HBoF, etc.).
Here is the main reasons why I choose fuzzing V8 engine/Chrome as a first choice:
gsutil cp $(gsutil ls "gs://chromium-browser-asan/linux-release/asan-linux-release-*.zip" | tail -1) .
Last but not least, we need to provide our JS files to d8. An easy way to start can be to create a simple bash script (like this one) that will loop and:
Honggfuzz is really easy-to-use and awesome fuzzer developed and maintained by Robert Swiecki from Google. During honggfuzz “dry-run”, all given files will be executed in different threads, monitored for crashes and stored if relevants. That also mean that only using the following command-line, you let honggfuzz handle everything and can go to sleep 😉
honggfuzz -t 5 -n 4 -i input_wasm_js/ -- ./d8 ___FILE___
Note: I noticed during my research that someone also integrate dharma directly into honggfuzz. I let you the check here, but personally I was not able to make it work :s
Congratz, you are now able to fuzz V8 WebAssembly APIs using generation-based fuzzers.
Grammar and script shown in this blogpost are available in this github repository.
Final reminder, If you want to learn/discover more about WebAssembly security (both reversing and fuzzing), I converted my 4-day live training into recorded courses. More details here.