<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.0">Jekyll</generator><link href="/feed.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2021-02-14T14:32:58+00:00</updated><id>/feed.xml</id><title type="html">wwkenwong</title><subtitle>A random security enthusiast</subtitle><entry><title type="html">My first take on real world vulnerability research (Part 1)</title><link href="/fuzzing/2021/02/14/fuzzing-1.html" rel="alternate" type="text/html" title="My first take on real world vulnerability research (Part 1)" /><published>2021-02-14T04:00:00+00:00</published><updated>2021-02-14T04:00:00+00:00</updated><id>/fuzzing/2021/02/14/fuzzing-1</id><content type="html" xml:base="/fuzzing/2021/02/14/fuzzing-1.html">&lt;h2 id=&quot;preface&quot;&gt;Preface&lt;/h2&gt;

&lt;p&gt;I was looking for new challenges that could excite me (and fill my CV) in early 2019. One day, I saw this picture on a slide from &lt;a href=&quot;https://twitter.com/guhe120&quot;&gt;Yuki Chen&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/fuzz-1/yukichen.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;“Oh, CV is inside CVE, so CVEs can make my CV complete!”&lt;/p&gt;

&lt;p&gt;Since my goal was to obtain a CVE within a short period of time, I decided to go with fuzzing. That is how I start my journey to look for CVEs. Luckily, we were assigned 2 CVEs after reporting 5 issues to Apple WebKit, namely CVE-2019-8678 and CVE-2019-8685. In this series of blog posts, I will walk through some basic ideas of fuzzing. We will also get started on fuzzing, debugging and developing exploits. We have also shared our experience in &lt;a href=&quot;https://hitcon.org/2020/agenda/1f069ce7-8dad-4aa9-a9f3-20a321a36e34/&quot;&gt;HITCON 2020&lt;/a&gt;. In the first part, we will look into fuzzing and enumerating targets.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclaimer: The content of this blogpost is written in late 2019 and some of them are not up-to-date. It only serves as a reference for beginners. You will not need this if you have sufficient knowledge on fuzzing, anyway.&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;what-the-fuzz&quot;&gt;What the fuzz?&lt;/h2&gt;

&lt;p&gt;Fuzzing is an automatic testing strategy used to look for security vulnerabilities. In short, this is a methodology to analyse software behaviour by sending it random data.&lt;/p&gt;

&lt;p&gt;In general, a vulnerability can only be accounted for CVE 30-60 days after patching, and fuzzing is the least time-consuming method to discover vulnerabilities. I recommend this &lt;a href=&quot;https://labs.f-secure.com/blog/what-the-fuzz/&quot;&gt;article&lt;/a&gt; for some terminology for fuzzing. I will just cover four of the important terms here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instrumentation&lt;/strong&gt; is a code snippet that is inserted into the program to gather execution feedback. Usually, it is used for collecting code coverage and detect memory corruption. There are two types of instrumentation methods, static and dynamic instrumentation. For static instrumentation, it is performed at compile-time, which imposes less runtime overhead compared to dynamic instrumentation. On the other hand, one of the benefits of dynamic instrumentation is that they are easily applied to binaries during runtime. &lt;em&gt;DynamoRIO&lt;/em&gt; and &lt;em&gt;Pin&lt;/em&gt; are two examples of instrumentation tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Seed (or corpus)&lt;/strong&gt; is the initial input files to the fuzzer to carry out mutation. The reason for using seed instead of random data is that completely random input may not be able to pass the sanity check for a lot of parser or fuzzing target. Seeds are used to make the results of fuzzing more meaningful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mutation&lt;/strong&gt; transforms an input into new input. There are some well-known and simple mutation strategies, for example, bit flipping and embed tokens from user-defined dictionaries. Both of them were implemented in &lt;a href=&quot;https://lcamtuf.blogspot.com/2014/08/binary-fuzzing-strategies-what-works.html&quot;&gt;AFL&lt;/a&gt;. There are also some advanced strategies like tree-based mutations used in &lt;a href=&quot;https://arxiv.org/pdf/1812.01197.pdf&quot;&gt;Superion&lt;/a&gt; or &lt;a href=&quot;https://dl.acm.org/doi/pdf/10.1145/3022671.2984038&quot;&gt;EMI&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code coverage&lt;/strong&gt; is a measurement of the proportion of the code being executed. There are various level of coverages like instruction coverage, branch coverage, line coverage. In C/C++ projects, we can use &lt;em&gt;gcov&lt;/em&gt; to collect coverage by compiling our program with special flags, and we can use &lt;em&gt;lcov&lt;/em&gt; to visualize the coverage collected.&lt;/p&gt;

&lt;h2 id=&quot;first-attempt-failure&quot;&gt;First attempt (Failure)&lt;/h2&gt;

&lt;p&gt;There are some state-of-the-art fuzzers in the public domain like &lt;em&gt;AFL&lt;/em&gt;, &lt;em&gt;Honggfuzz&lt;/em&gt;, &lt;em&gt;peach&lt;/em&gt;, &lt;em&gt;libfuzzer&lt;/em&gt;. With so much choice, &lt;em&gt;libfuzzer&lt;/em&gt; and &lt;em&gt;AFL&lt;/em&gt; have caught my attention. However, I picked &lt;em&gt;AFL&lt;/em&gt; (American Fuzzy Lop) as my first attempt. It is a well-known fuzzing tool and contains many features that I need. This includes instrumentation, mutation, code coverage measurement and forkserver. Most importantly, we don’t need to spend time to audit the code and write harness for fuzzing, just like the case for &lt;em&gt;libfuzzer&lt;/em&gt;. If you want to have an introduction to libfuzzer, I highly recommend &lt;a href=&quot;https://www.youtube.com/watch?v=xzG0pLM4Q64&quot;&gt;this talk&lt;/a&gt; from &lt;a href=&quot;https://twitter.com/NedWilliamson&quot;&gt;@nedwill&lt;/a&gt; and his fuzzer for Chrome IPC. Anyway, let’s get back to &lt;em&gt;AFL&lt;/em&gt;, it is available &lt;a href=&quot;http://lcamtuf.coredump.cx/afl/releases/&quot;&gt;here&lt;/a&gt;. You can also refer to &lt;a href=&quot;http://lcamtuf.coredump.cx/afl/QuickStartGuide.txt&quot;&gt;the documentation&lt;/a&gt; for deployment.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: I will recommend starting with &lt;a href=&quot;https://github.com/AFLplusplus/AFLplusplus&quot;&gt;afl++&lt;/a&gt; since it is actively maintained by the community nowadays…&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;setting-up&quot;&gt;Setting up&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt-get &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;clang autoconf make cmake
&lt;span class=&quot;c&quot;&gt;# Build AFL...&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# cd to where you extracted AFL&lt;/span&gt;
make 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;/assets/fuzz-1/afl_0.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;After AFL is built, add the below line to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.profile&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PATH&lt;/span&gt;:&amp;lt;where you build your AFL&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To build your fuzzing target, configure the &lt;em&gt;cc compiler&lt;/em&gt; to the AFL’s version:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;afl-gcc 
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CXX&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;afl-g++ 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Continue the remaining steps from the documentation to build the application.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: In AFL, there is a LLVM mode. You can find the code and instructions for building it inside the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;llvm_mode&lt;/code&gt; folder of AFL source code. Its report has a 10% increase in performance when compare with default mode, though I didn’t use it this time.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/fuzz-1/afl_1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Different software may have slightly different settings, just &lt;em&gt;RTFM&lt;/em&gt; before everything is ready. Here are some examples I came across as reference:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# For libjpeg-turbo&lt;/span&gt;
cmake &lt;span class=&quot;nt&quot;&gt;-G&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Unix Makefiles&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-DCMAKE_C_COMPILER&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;afl-gcc &lt;span class=&quot;nt&quot;&gt;-DCMAKE_C_FLAGS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-m32&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# For ImageMagick&lt;/span&gt;
cmake &lt;span class=&quot;nt&quot;&gt;-DCMAKE_CXX_COMPILER&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;afl-clang++ &lt;span class=&quot;nt&quot;&gt;-DCMAKE_CC_COMPILER&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;afl-clang

&lt;span class=&quot;c&quot;&gt;# From Vim&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;CC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;afl-gcc ./configure &lt;span class=&quot;se&quot;&gt;\ &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;--with-features&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;huge &lt;span class=&quot;se&quot;&gt;\ &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;--enable-gui&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;none
make
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;From looking around in &lt;a href=&quot;https://lcamtuf.blogspot.com/2014/11/pulling-jpegs-out-of-thin-air.html&quot;&gt;the post&lt;/a&gt; of &lt;em&gt;AFL&lt;/em&gt; developer and &lt;a href=&quot;https://research.checkpoint.com/2018/50-adobe-cves-in-50-days/&quot;&gt;this post&lt;/a&gt; from &lt;em&gt;Checkpoint&lt;/em&gt;, I chose to fuzz the JPEG file format as my initial target and targeted on &lt;em&gt;libjpeg-turbo&lt;/em&gt;. I need to gather some initial corpus from the below GitHub repositories:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/MozillaSecurity/fuzzdata&quot;&gt;https://github.com/MozillaSecurity/fuzzdata&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/google/fuzzer-test-suite&quot;&gt;https://github.com/google/fuzzer-test-suite&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/libjpeg-turbo/libjpeg-turbo/tree/master/testimages&quot;&gt;https://github.com/libjpeg-turbo/libjpeg-turbo/tree/master/testimages&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/fuzzdb-project/fuzzdb/tree/master/attack/file-upload/malicious-images&quot;&gt;https://github.com/fuzzdb-project/fuzzdb/tree/master/attack/file-upload/malicious-images&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I also collected crash samples and regression tests from various image processing libraries and Exploit-DB. We are able to get some nice samples with correct keywords. For instance:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/fuzz-1/cve_0.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/fuzz-1/cve_1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/fuzz-1/cve_2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/fuzz-1/cve_3.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;At the same time, you can get a sense of the following questions:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;which part of your target had lots of bugs,&lt;/li&gt;
  &lt;li&gt;whether the developers will reward CVE to bugs reported, and&lt;/li&gt;
  &lt;li&gt;how long does it take for the developers to fix the bugs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/fuzz-1/cve_4.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;For now, we had built our target and collected some initial input for the fuzzer. Next, we run this command with the root account (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo -s&lt;/code&gt;):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;echo core &amp;gt;/proc/sys/kernel/core_pattern
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;After that, run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;afl-cmin&lt;/code&gt; to minimize the corpus. Before fuzzing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libjpeg-turbo&lt;/code&gt;, I fuzzed &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ImageMagick&lt;/code&gt; for a few days to collect more initial corpus. Below is the command to run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;afl-cmin&lt;/code&gt; for cjpeg of ImageMagick:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;afl-cmin -i input/ -o output/ -t 300000 -m 200 ./cjpeg -outfile /dev/null @@
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@@&lt;/code&gt; in the command is the input field of the original program, and afl will take in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@@&lt;/code&gt; as the argument during fuzzing. Also, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-t&lt;/code&gt; is for setting the timeout and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-m&lt;/code&gt; is for setting the memory limit.&lt;/p&gt;

&lt;p&gt;After running this command, the minimized output will be saved in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;./output/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/fuzz-1/afl_2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;why-cmin&quot;&gt;Why cmin?&lt;/h4&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;afl-cmin&lt;/code&gt; generates a subset of files that yield the same edge coverage. &lt;em&gt;AFL&lt;/em&gt; also has a test case minimization function, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;afl-tmin&lt;/code&gt;. It will attempt to minimize the size of the corpus. Next, we install &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;screen&lt;/code&gt;, and we can attach it to the fuzzing processes later (assume using ubuntu).&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo apt install screen
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In my case, I chose to fuzz with 4 cores of my machine and ran the following:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# initialize the master&lt;/span&gt;
screen afl-fuzz &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; input/ &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; output/ &lt;span class=&quot;nt&quot;&gt;-M&lt;/span&gt; master &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; 300000 &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt; 200 ./cjpeg &lt;span class=&quot;nt&quot;&gt;-outfile&lt;/span&gt; /dev/null @@

&lt;span class=&quot;c&quot;&gt;# initialize other slave &lt;/span&gt;
screen afl-fuzz &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; input/ &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; output/ &lt;span class=&quot;nt&quot;&gt;-S&lt;/span&gt; slave1 &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; 300000 &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt; 200 ./cjpeg &lt;span class=&quot;nt&quot;&gt;-outfile&lt;/span&gt; /dev/null @@
screen afl-fuzz &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; input/ &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; output/ &lt;span class=&quot;nt&quot;&gt;-S&lt;/span&gt; slave2 &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; 300000 &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt; 200 ./cjpeg &lt;span class=&quot;nt&quot;&gt;-outfile&lt;/span&gt; /dev/null @@
screen afl-fuzz &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; input/ &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; output/ &lt;span class=&quot;nt&quot;&gt;-S&lt;/span&gt; slave3 &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; 300000 &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt; 200 ./cjpeg &lt;span class=&quot;nt&quot;&gt;-outfile&lt;/span&gt; /dev/null @@
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;afl-whatsup&lt;/code&gt; is a handy extension for monitoring the status of the fuzzers. We can use the command below:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;afl-whatsup output/ &lt;span class=&quot;c&quot;&gt;# output is the folder you set in the -o flag when you start running your fuzzer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;/assets/fuzz-1/afl_3.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;screen &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# for listing process id &lt;/span&gt;
screen &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; &amp;lt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# for attachment&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;/assets/fuzz-1/afl_4.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Sadly, no crashes were generated after a week of fuzzing. I recalled this blog post from &lt;a href=&quot;https://payatu.com/blog/Nikhil-Joshi/cloudfuzz-machine-learning-powered-content-specific-input-generation-fuzzing&quot;&gt;payatu&lt;/a&gt; and decided to further mutate the generated corpus. I remembered that &lt;a href=&quot;https://gitlab.com/akihe/radamsa&quot;&gt;radamsa&lt;/a&gt; can digest files and output mutated files based on the input. Therefore, I used the generated corpus from previous fuzzing to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;radamsa&lt;/code&gt; and generate more corpus.&lt;/p&gt;

&lt;p&gt;I tried to re-import the output from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;radamsa&lt;/code&gt;. Despite gaining coverage, I couldn’t find any crashes. As everyone and academia were using (and modifying) &lt;em&gt;AFL&lt;/em&gt; on these famous open source libraries, it would be impossible to generate meaningful crashes without my own AFL modifications. &lt;a href=&quot;https://web.cs.ucdavis.edu/~hchen/paper/chen2018angora.pdf&quot;&gt;Angora&lt;/a&gt; and &lt;a href=&quot;https://www.usenix.org/system/files/conference/usenixsecurity18/sec18-yun.pdf&quot;&gt;QSYM&lt;/a&gt; are two excellent academic papers I came across during my self-evaluation. &lt;del&gt;Well, don’t try to mess with things that targeted by academia.&lt;/del&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/fuzz-1/afl_5.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;second-attempt-failure&quot;&gt;Second attempt (Failure)&lt;/h2&gt;

&lt;p&gt;Since I am interested in playing browser CTF challenges, why don’t I give a shot to fuzz JavaScript Engines? I recalled the &lt;a href=&quot;http://blog.ret2.io/2018/06/05/pwn2own-2018-exploit-development/&quot;&gt;blogpost series on &lt;em&gt;Pwn2Own&lt;/em&gt;&lt;/a&gt; from &lt;em&gt;ret2system&lt;/em&gt;. They had demonstrated using &lt;a href=&quot;https://github.com/MozillaSecurity/dharma&quot;&gt;dharma&lt;/a&gt; on their &lt;a href=&quot;https://blog.ret2.io/2018/06/13/pwn2own-2018-vulnerability-discovery/&quot;&gt;first blogpost&lt;/a&gt; for the bugs they submitted to &lt;em&gt;Pwn2Own&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Therefore, I started to modify and extend &lt;a href=&quot;https://github.com/googleprojectzero/domato&quot;&gt;Domato&lt;/a&gt;’s grammar to generate pure JavaScript. For those of you who don’t know Domato, it is a context-free grammar code generator originally targeted for DOM fuzzing, developed by &lt;a href=&quot;https://twitter.com/ifsecure&quot;&gt;Ivan Fratric&lt;/a&gt; from Google Project Zero. It supports simple and robust PL features with regular expressions. It also supports JScript, VBScript fuzzing in a later stage. Some security researchers re-engineering it to support more templates like PHP and PDF. You may refer to &lt;a href=&quot;https://googleprojectzero.blogspot.com/2017/09/the-great-dom-fuzz-off-of-2017.html&quot;&gt;Ivan Fratric’s post&lt;/a&gt; for details.&lt;/p&gt;

&lt;p&gt;An advantage of using Domato is the grammar is easy to understand and rewrite. Below is some example copied from its Github repo. And it also supports running Python in the grammar. For details on how Domato works, you may refer to this excellent analysis &lt;a href=&quot;https://sigpwn.io/blog/2018/4/14/domato-fuzzers-generation-engine-internals&quot;&gt;blog post&lt;/a&gt; for Domato’s internal.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;!varformat fuzzvar%05d
!lineguard try { &amp;lt;line&amp;gt; } catch(e) {}

!begin lines
&amp;lt;new element&amp;gt; = document.getElementById(&quot;&amp;lt;string min=97 max=122&amp;gt;&quot;);
&amp;lt;element&amp;gt;.doSomething();
!end lines
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here, I have taken an approach similar to &lt;a href=&quot;https://en.wikipedia.org/wiki/Differential_testing&quot;&gt;differential testing&lt;/a&gt;. We try to execute the same corpus with two different builds of v8 and look for the difference in behaviour. No good crashes were generated despite tons of v8 OOM features and panics. However, I found a hang in the v8 engine that only appears in the later builds using this approach. Even though it is useless, at least we got something this time.&lt;/p&gt;

&lt;p&gt;Although I failed to get some bugs with Domato, there are &lt;a href=&quot;https://blog.redteam.pl/2019/12/chrome-portal-element-fuzzing.html&quot;&gt;some successful attempts&lt;/a&gt;. I am just too weak…&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/fuzz-1/miner.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;third-attempt-succeed-maybe&quot;&gt;Third attempt (Succeed, maybe?)&lt;/h2&gt;

&lt;p&gt;I was desperate until I saw Saelo’s open-source tool &lt;a href=&quot;https://github.com/googleprojectzero/fuzzilli&quot;&gt;Fuzzilli&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/fuzz-1/twitter.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Fuzzilli is a JS fuzzer targeted at JIT engine bugs. JIT engine is an important part of the Javascript engine, which improves the performance of Javascript execution for frequently executed functions.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/fuzz-1/jit-compiler.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Traditional fuzzer, like Domato or dharma, wrap the statements inside a try-catch block to prevent exceptions. However, this may prevent the JIT &lt;em&gt;Bounds Check Elimination (BCE)&lt;/em&gt; optimization. The slides below from &lt;em&gt;Saelo&lt;/em&gt; for &lt;em&gt;OffensiveCon&lt;/em&gt; illustrated this idea.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/fuzz-1/fuzzilli_0.jpg&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/assets/fuzz-1/fuzzilli_1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;To resolve this, &lt;em&gt;Saelo&lt;/em&gt; proposed an intermediate language - &lt;em&gt;FuzzIL&lt;/em&gt; for generating JS code. He implemented the code mutation based on this IL. After that, we can pass these IL to different lifting and generate different corpus, as shown in the below slides:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/fuzz-1/fuzzilli_2.jpg&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/assets/fuzz-1/fuzzilli_3.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Fuzzilli&lt;/em&gt; comes with several mutators in the initial release, which can be found under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;./fuzzilli/Sources/Fuzzilli/Mutators/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/fuzz-1/fuzzilli_4.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now, let’s get back to our goal. This newly released fuzzer reminded me of &lt;a href=&quot;https://googleprojectzero.blogspot.com/2018/10/365-days-later-finding-and-exploiting.html&quot;&gt;this post&lt;/a&gt; of Project Zero instantly. Bugs still appear after a year of release of Domato, which means that we may be able to find some bugs. We must first decide on our target as everyone out there are finding bugs at the same time. I ultimately chose WebKit among popular JS engines to fuzz.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/fuzz-1/chakracore.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;My setup steps for fuzzilli (for the initial release):&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# first setup the LLVM &lt;/span&gt;
wget &lt;span class=&quot;nt&quot;&gt;-O&lt;/span&gt; - https://apt.llvm.org/llvm-snapshot.gpg.key | &lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt-key add -
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt-add-repository &lt;span class=&quot;s2&quot;&gt;&quot;deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-6.0 main&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt-get update
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt-get &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-y&lt;/span&gt; clang-6.0

&lt;span class=&quot;c&quot;&gt;# next setup swift for building fuzzilli (for old version of swift)&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# https://tecadmin.net/install-swift-ubuntu-1604-xenial/&lt;/span&gt;
wget https://swift.org/builds/swift-4.0.3-release/ubuntu1604/swift-4.0.3-RELEASE/swift-4.0.3-RELEASE-ubuntu16.04.tar.gz
&lt;span class=&quot;nb&quot;&gt;sudo tar &lt;/span&gt;xzf swift-4.0.3-RELEASE-ubuntu16.04.tar.gz
&lt;span class=&quot;nb&quot;&gt;mv &lt;/span&gt;swift-4.0.3-RELEASE-ubuntu16.04 /usr/share/swift

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;export PATH=/usr/share/swift/usr/bin:&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PATH&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.bashrc
&lt;span class=&quot;nb&quot;&gt;source&lt;/span&gt; ~/.bashrc

&lt;span class=&quot;c&quot;&gt;# next symlink clang &lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#https://stackoverflow.com/questions/1951742/how-to-symlink-a-file-in-linux&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;sudo ln&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; /usr/bin/clang-5.0 /usr/bin/clang
&lt;span class=&quot;nb&quot;&gt;sudo ln&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; /usr/bin/clang++-5.0 /usr/bin/clang++

&lt;span class=&quot;c&quot;&gt;# next, install all the dependencies&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# you may need to comment out some of the dependencies on WebKit's bash&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;webkit/Tools/gtk/install-dependencies

&lt;span class=&quot;c&quot;&gt;# next patch the code, copy fuzzbuild.sh to the webkit directory and build the jsc &lt;/span&gt;
patch &amp;lt; webkit.patch
./fuzzbuild.sh

&lt;span class=&quot;c&quot;&gt;# next cd to fuzzilli's directory &lt;/span&gt;
swift build &lt;span class=&quot;nt&quot;&gt;-Xlinker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'-lrt'&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# enable this &lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo &lt;/span&gt;core &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;/proc/sys/kernel/core_pattern

&lt;span class=&quot;c&quot;&gt;# example command to run fuzzilli with 1 master+3 slave&lt;/span&gt;
screen ./FuzzilliCli &lt;span class=&quot;nt&quot;&gt;--profile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;jsc &lt;span class=&quot;nt&quot;&gt;--storagePath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/home/fuzz/fuzzing1_master8888 &lt;span class=&quot;nt&quot;&gt;--exportCorpus&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--networkMaster&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;127.0.0.1:8888 /home/fuzz/webkit-master/FuzzBuild/Debug/bin/jsc
screen ./FuzzilliCli &lt;span class=&quot;nt&quot;&gt;--profile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;jsc &lt;span class=&quot;nt&quot;&gt;--storagePath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/home/fuzz/fuzzing1_slave8888-1 &lt;span class=&quot;nt&quot;&gt;--exportCorpus&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--networkWorker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;127.0.0.1:8888 /home/fuzz/webkit-master/FuzzBuild/Debug/bin/jsc
screen ./FuzzilliCli &lt;span class=&quot;nt&quot;&gt;--profile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;jsc &lt;span class=&quot;nt&quot;&gt;--storagePath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/home/fuzz/fuzzing1_slave8888-2 &lt;span class=&quot;nt&quot;&gt;--exportCorpus&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--networkWorker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;127.0.0.1:8888 /home/fuzz/webkit-master/FuzzBuild/Debug/bin/jsc
screen ./FuzzilliCli &lt;span class=&quot;nt&quot;&gt;--profile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;jsc &lt;span class=&quot;nt&quot;&gt;--storagePath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/home/fuzz/fuzzing1_slave8888-3 &lt;span class=&quot;nt&quot;&gt;--exportCorpus&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--networkWorker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;127.0.0.1:8888 /home/fuzz/webkit-master/FuzzBuild/Debug/bin/jsc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;After fuzzing for a few days, although no crashes were generated, I found that the code coverage converged to 27% with very high sample validity. Below is a plot I prepared for the HITCON presentation, the orange line validated my observation on validity issue.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/fuzz-1/validity.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Since it’s meaningless to run fuzzers with high validity without crashing, I started to modify its mutation strategy and parameters to reduce the correctness of the fuzzer. It turns out this small trick works and coverage has increased slightly with decreasing validity and crashes finally happened.&lt;/p&gt;

&lt;p&gt;Part of my patch (with modified parameters and code):&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/fuzz-1/patch_0.jpg&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/assets/fuzz-1/patch_1.jpg&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/assets/fuzz-1/patch_2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;To scale up the fuzzing, I rented a 12-core machine from &lt;em&gt;GCP&lt;/em&gt; and fuzzed for 1.5 months, with 4 cores running the original release as a control setup, and 8 running the modified version (with 1 master + 3 slaves in each setup). It appears that all the security crashes were from the modified version. I am not certain about the reason, it can be luck, possibly P0 or Apple has fuzzed these targets thoroughly with default configuration before open-sourcing it to the public. Since our setup keeps on report crashes after these minor modifications, we spent most of our time on crash triaging them and didn’t further modifing fuzzilli.&lt;/p&gt;

&lt;p&gt;As a reference, our JSC fuzzing campaign lasted for around 2 months in 2019, we spent around $1000 GCP credit, which is also similar to the cost reported by &lt;a href=&quot;https://twitter.com/ifsecure&quot;&gt;@ifsecure&lt;/a&gt; in &lt;a href=&quot;https://googleprojectzero.blogspot.com/2018/10/365-days-later-finding-and-exploiting.html&quot;&gt;his blogpost&lt;/a&gt;. In return, we harvested 2 CVEs.&lt;/p&gt;

&lt;p&gt;To gain the whole picture of how the fuzzer works, I suggest going through &lt;a href=&quot;https://saelo.github.io/papers/thesis.pdf&quot;&gt;Saelo’s master thesis&lt;/a&gt;. Thanks Saelo and I learned a lot from his thesis.&lt;/p&gt;

&lt;h2 id=&quot;epilogue&quot;&gt;Epilogue&lt;/h2&gt;

&lt;p&gt;In my next blog post (which I hope to finish as soon as possible), I will analyse on CVE-2019-8678, which I guess this might be one of the variants of &lt;a href=&quot;http://rce.party/wtf.js&quot;&gt;wtf.js&lt;/a&gt; posted by &lt;em&gt;qwertyoruiopz&lt;/em&gt;. Thanks for reading until here.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By the way, as my teammate &lt;a href=&quot;https://twitter.com/mystiz613&quot;&gt;@mystiz&lt;/a&gt; said, part two of the blog post may not appear any time soon. This episode is already delayed by an year already.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/fuzz-1/delay.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;reference&quot;&gt;Reference&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;https://blog.f-secure.com/super-awesome-fuzzing-part-one/&lt;/li&gt;
  &lt;li&gt;https://arxiv.org/pdf/1812.00140.pdf&lt;/li&gt;
&lt;/ol&gt;</content><author><name></name></author><category term="Fuzzing" /><summary type="html">Preface</summary></entry></feed>