├── Diagram.png ├── Exercise 1 ├── Images │ ├── Image1.png │ ├── Image2.png │ ├── Image3.png │ ├── Image3_1.png │ ├── Image3_2.png │ ├── Image4.png │ └── Image5.png ├── Readme.md └── Solutions │ └── CVE-2019-13288_example ├── Exercise 10 ├── Images │ ├── 1.png │ └── 2.png └── Readme.md ├── Exercise 2 ├── Images │ ├── Image1.png │ ├── Image2.png │ ├── Image3.png │ ├── Image4.png │ ├── Image5.png │ ├── Image6.png │ └── Image7.png ├── Readme.md └── Solutions │ ├── CVE-2009-3895__Example │ └── CVE-2012-2836__Example ├── Exercise 3 ├── Images │ ├── Image1.png │ ├── Image2.png │ ├── Image3.png │ └── Image4.png └── Readme.md ├── Exercise 4 ├── Images │ ├── Image1.png │ ├── Image2.png │ ├── Image2_2.png │ └── Image3.png └── Readme.md ├── Exercise 5 ├── Images │ ├── Image1.png │ ├── Image2.png │ └── Image3.png ├── Readme.md └── SampleInput.xml ├── Exercise 6 ├── Images │ ├── Image0.png │ ├── Image1.png │ ├── Image2.png │ └── Image3.png ├── Readme.md ├── SampleInput.xcf └── persistent.patch ├── Exercise 7 ├── Images │ ├── image0.png │ ├── image1.png │ ├── image2.png │ └── image3.png ├── InputCorpus │ ├── short2.wmv │ └── veryshort.wmv ├── Partial_instrumentation ├── Readme.md ├── asf_dictionary.dict ├── fuzzing_harness.patch └── speedup.patch ├── Exercise 8 ├── Images │ ├── 0.png │ ├── 10.png │ ├── 11.png │ ├── 4.png │ ├── 5.png │ ├── 6.png │ ├── 7.png │ ├── 8.png │ └── 9.png └── Readme.md ├── Exercise 9 ├── Images │ ├── Image0.png │ ├── Image1.png │ ├── Image2.png │ ├── Image3.png │ ├── Image4.png │ └── Image5.png ├── Readme.md └── Resources │ ├── 7z1505.exe │ ├── example.img │ └── vs_community.exe ├── LICENSE ├── Readme.md └── Resources └── SecurityLab.webp /Diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Diagram.png -------------------------------------------------------------------------------- /Exercise 1/Images/Image1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 1/Images/Image1.png -------------------------------------------------------------------------------- /Exercise 1/Images/Image2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 1/Images/Image2.png -------------------------------------------------------------------------------- /Exercise 1/Images/Image3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 1/Images/Image3.png -------------------------------------------------------------------------------- /Exercise 1/Images/Image3_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 1/Images/Image3_1.png -------------------------------------------------------------------------------- /Exercise 1/Images/Image3_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 1/Images/Image3_2.png -------------------------------------------------------------------------------- /Exercise 1/Images/Image4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 1/Images/Image4.png -------------------------------------------------------------------------------- /Exercise 1/Images/Image5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 1/Images/Image5.png -------------------------------------------------------------------------------- /Exercise 1/Readme.md: -------------------------------------------------------------------------------- 1 | # Exercise 1 - Xpdf 2 | 3 | For this exercize we will fuzz **Xpdf** PDF viewer. The goal is to find a crash/PoC for [**CVE-2019-13288**](https://www.cvedetails.com/cve/CVE-2019-13288/) in XPDF 3.02. 4 | 5 | <details> 6 | <summary>For more information about CVE-2019-13288 vulnerability, click me!</summary> 7 | -------------------------------------------------------------------------------------------------------- 8 | 9 | **CVE-2019-13288** is a vulnerability that may cause an infinite recursion via a crafted file. 10 | 11 | Since each called function in a program allocates a stack frame on the stack, if a a function is recursively called so many times it can lead to stack memory exhaustion and program crash. 12 | 13 | As a result, a remote attacker can leverage this for a DoS attack. 14 | 15 | You can find more information about Uncontrolled Recursion vulnerabilities at the following link: https://cwe.mitre.org/data/definitions/674.html 16 | 17 | </details> 18 | 19 | ## What you will learn 20 | After completing this exercise, you will know the basis of fuzzing with AFL, such as: 21 | - Compiling a target application with instrumentation 22 | - Running a fuzzer (afl-fuzz) 23 | - Triaging crashes with a debugger (GDB) 24 | 25 | ## Read Before Start 26 | - I suggest you to try to **solve the exercise by yourself** without checking the solution. Try as hard as you can, and only if you get stuck, check out the example solution below. 27 | - AFL uses a non-deterministic testing algorithm, so two fuzzing sessions are never the same. That's why I highly recommend **to set a fixed seed (-s 123)**. This way your fuzzing results will be similar to those shown here and that will allow you to follow the exercises more easily. 28 | - If you find a new vulnerability, **please submit a security report** to the project. If you need help or have any doubt about the process, the [GitHub Security Lab](mailto:securitylab.github.com) can help you with it :) 29 | 30 | ## Contact 31 | Are you stuck and looking for help? Do you have suggestions for making this course better or just positive feedback so that we create more fuzzing content? 32 | Do you want to share your fuzzing experience with the community? 33 | Join the GitHub Security Lab Slack and head to the `#fuzzing` channel. [Request an invite to the GitHub Security Lab Slack](mailto:securitylab-social@github.com?subject=Request%20an%20invite%20to%20the%20GitHub%20Security%20Lab%20Slack) 34 | 35 | ## Environment 36 | 37 | All the exercises have been tested on **Ubuntu 20.04.2 LTS**. I highly recommend you to use **the same OS version** to avoid different fuzzing results and to run AFL++ **on bare-metal** hardware, and not virtualized machines, for best performance. 38 | 39 | Otherwise, you can find an Ubuntu 20.04.2 LTS VMware image [here](https://drive.google.com/file/d/1_m1x-SHcm7Muov2mlmbbt8nkrMYp0Q3K/view?usp=sharing). You can also use VirtualBox instead of VMware. 40 | 41 | The username / password for this VM are `fuzz` / `fuzz`. 42 | 43 | ## Download and build your target 44 | 45 | Let's first get our fuzzing target. Create a new directory for the project you want to fuzz: 46 | ``` 47 | cd $HOME 48 | mkdir fuzzing_xpdf && cd fuzzing_xpdf/ 49 | ``` 50 | To get your environment fully ready, you may need to install some additional tools (namely make and gcc) 51 | ``` 52 | sudo apt install build-essential 53 | ``` 54 | 55 | Download Xpdf 3.02: 56 | ``` 57 | wget https://dl.xpdfreader.com/old/xpdf-3.02.tar.gz 58 | tar -xvzf xpdf-3.02.tar.gz 59 | ``` 60 | 61 | Build Xpdf: 62 | ``` 63 | cd xpdf-3.02 64 | sudo apt update && sudo apt install -y build-essential gcc 65 | ./configure --prefix="$HOME/fuzzing_xpdf/install/" 66 | make 67 | make install 68 | ``` 69 | 70 | Time to test the build. First of all, You'll need to download a few PDF examples: 71 | ``` 72 | cd $HOME/fuzzing_xpdf 73 | mkdir pdf_examples && cd pdf_examples 74 | wget https://github.com/mozilla/pdf.js-sample-files/raw/master/helloworld.pdf 75 | wget http://www.africau.edu/images/default/sample.pdf 76 | wget https://www.melbpc.org.au/wp-content/uploads/2017/10/small-example-pdf-file.pdf 77 | ``` 78 | 79 | Now, we can test the pdfinfo binary with: 80 | ``` 81 | $HOME/fuzzing_xpdf/install/bin/pdfinfo -box -meta $HOME/fuzzing_xpdf/pdf_examples/helloworld.pdf 82 | ``` 83 | 84 | You should see something like this: 85 | 86 |  87 | 88 | ## Install AFL++ 89 | For this course, we're going to use the latest version of [AFL++ fuzzer](https://github.com/AFLplusplus/AFLplusplus). 90 | 91 | You can install everything in two ways: 92 | 93 | <details> 94 | <summary>Local installation (recommended option)</summary> 95 | 96 | Install the dependencies 97 | 98 | ``` 99 | sudo apt-get update 100 | sudo apt-get install -y build-essential python3-dev automake git flex bison libglib2.0-dev libpixman-1-dev python3-setuptools 101 | sudo apt-get install -y lld-11 llvm-11 llvm-11-dev clang-11 || sudo apt-get install -y lld llvm llvm-dev clang 102 | sudo apt-get install -y gcc-$(gcc --version|head -n1|sed 's/.* //'|sed 's/\..*//')-plugin-dev libstdc++-$(gcc --version|head -n1|sed 's/.* //'|sed 's/\..*//')-dev 103 | ``` 104 | 105 | Checkout and build AFL++ 106 | ``` 107 | cd $HOME 108 | git clone https://github.com/AFLplusplus/AFLplusplus && cd AFLplusplus 109 | export LLVM_CONFIG="llvm-config-11" 110 | make distrib 111 | sudo make install 112 | ``` 113 | </details> 114 | 115 | <details> 116 | <summary>Docker image</summary> 117 | 118 | Install docker 119 | ``` 120 | sudo apt install docker 121 | ``` 122 | 123 | Pull the image 124 | ``` 125 | docker pull aflplusplus/aflplusplus 126 | ``` 127 | 128 | Launch the AFLPlusPlus docker container: 129 | ``` 130 | docker run -ti -v $HOME:/home aflplusplus/aflplusplus 131 | ``` 132 | and then type 133 | ``` 134 | export $HOME="/home" 135 | ``` 136 | </details> 137 | 138 | Now if all went well, you should be able to run afl-fuzz. Just type 139 | 140 | ```afl-fuzz``` 141 | 142 | and you should see something like this: 143 | 144 |  145 | 146 | ### Meet AFL++ 147 | 148 | AFL is a **coverage-guided fuzzer**, which means that it gathers coverage information for each mutated input in order to discover new execution paths and potential bugs. When source code is available AFL can use instrumentation, inserting function calls at the beginning of each basic block (functions, loops, etc.) 149 | 150 | To enable instrumentation for our target application, we need to compile the code with AFL's compilers. 151 | 152 | First of all, we're going to clean all previously compiled object files and executables: 153 | ``` 154 | rm -r $HOME/fuzzing_xpdf/install 155 | cd $HOME/fuzzing_xpdf/xpdf-3.02/ 156 | make clean 157 | ``` 158 | 159 | And now we're going to build xpdf using the **afl-clang-fast** compiler: 160 | ``` 161 | export LLVM_CONFIG="llvm-config-11" 162 | CC=$HOME/AFLplusplus/afl-clang-fast CXX=$HOME/AFLplusplus/afl-clang-fast++ ./configure --prefix="$HOME/fuzzing_xpdf/install/" 163 | make 164 | make install 165 | ``` 166 | 167 | Now, you can run the fuzzer with the following command: 168 | ``` 169 | afl-fuzz -i $HOME/fuzzing_xpdf/pdf_examples/ -o $HOME/fuzzing_xpdf/out/ -s 123 -- $HOME/fuzzing_xpdf/install/bin/pdftotext @@ $HOME/fuzzing_xpdf/output 170 | ``` 171 | 172 | A brief explanation of each option: 173 | - *-i* indicates the directory where we have to put the input cases (a.k.a file examples) 174 | - *-o* indicates the directory where AFL++ will store the mutated files 175 | - *-s* indicates the static random seed to use 176 | - *@@* is the placeholder target's command line that AFL will substitute with each input file name 177 | 178 | So, basically the fuzzer will run the command 179 | `$HOME/fuzzing_xpdf/install/bin/pdftotext <input-file-name> $HOME/fuzzing_xpdf/output` for each different input file. 180 | 181 | If you receive a message like *"Hmm, your system is configured to send core dump notifications to an external utility..."*, just do: 182 | ``` 183 | sudo su 184 | echo core >/proc/sys/kernel/core_pattern 185 | exit 186 | ``` 187 | 188 | After a few minutes you should see something like this: 189 | 190 |  191 | 192 | You can see the **"uniq. crashes"** value in red, showing the number of unique crashes found. You can find these crashes files in the `$HOME/fuzzing_xpdf/out/` directory. You can stop the fuzzer once the first crash is found, this is the one we'll work on. It can take up to one or two hours depending on your machine performance, before you get a crash. 193 | 194 | At this stage, you have learned: 195 | - How to compile a target using afl compiler with instrumentation 196 | - How to launch afl++ 197 | - How to detect unique crashes of your target 198 | 199 | So what's next? We don't have any information on this bug, just a crash of the program... It's time for debugging and triage! 200 | 201 | ## Do it yourself! 202 | In order to complete this exercise, you need to: 203 | 1) Reproduce the crash with the indicated file 204 | 2) Debug the crash to find the problem 205 | 3) Fix the issue 206 | 207 | **Estimated time = 120 mins** 208 | 209 | --- 210 | 211 | <details> 212 | <summary>SPOILER ALERT! : Solution inside</summary> 213 | 214 | ### Reproduce the crash 215 | 216 | Locate the file corresponding to the crash in the `$HOME/fuzzing_xpdf/out/` directory. The filename is something like `id:000000,sig:11,src:001504+000002,time:924544,op:splice,rep:16` 217 | 218 |  219 | 220 | Pass this file as input to pdftotext binary 221 | ``` 222 | $HOME/fuzzing_xpdf/install/bin/pdftotext '$HOME/fuzzing_xpdf/out/default/crashes/<your_filename>' $HOME/fuzzing_xpdf/output 223 | ``` 224 | It will cause a segmentation fault and results in a crash of the program. 225 | 226 |  227 | 228 | ### Triage 229 | 230 | Use gdb to figure out why the program crashes with this input. 231 | 232 | - **You can take a look at http://people.cs.pitt.edu/~mosse/gdb-note.html for a good brief primer on GDB** 233 | 234 | First of all, you need to rebuild Xpdf with debug info to get a symbolic stack trace: 235 | 236 | ``` 237 | rm -r $HOME/fuzzing_xpdf/install 238 | cd $HOME/fuzzing_xpdf/xpdf-3.02/ 239 | make clean 240 | CFLAGS="-g -O0" CXXFLAGS="-g -O0" ./configure --prefix="$HOME/fuzzing_xpdf/install/" 241 | make 242 | make install 243 | ``` 244 | 245 | Now, you can run GDB: 246 | 247 | ``` 248 | gdb --args $HOME/fuzzing_xpdf/install/bin/pdftotext $HOME/fuzzing_xpdf/out/default/crashes/<your_filename> $HOME/fuzzing_xpdf/output 249 | ``` 250 | And then, type inside GDB: 251 | ``` 252 | >> run 253 | ``` 254 | 255 | If all went well, you should see the following output: 256 | 257 |  258 | 259 | Then type ```bt``` to get the backtrace: 260 | 261 |  262 | 263 | Scroll the call stack and you will see many calls of the "Parser::getObj" method that seems to indicate an infinite recursion. If you go to https://www.cvedetails.com/cve/CVE-2019-13288/ you can see that the description matches with the backtrace we got from GDB. 264 | 265 | ### Fix the issue 266 | 267 | The last step of the exercise is to fix the bug! Rebuild your target after the fix and check that your use case is not causing a segmentation fault anymore. This last part is left as exercise for the student. 268 | 269 | Alternatively, you can download Xpdf 4.02 where the bug is already fixed, and check that the segmentation fault disappears. 270 | 271 | </details> 272 | -------------------------------------------------------------------------------- /Exercise 1/Solutions/CVE-2019-13288_example: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 1/Solutions/CVE-2019-13288_example -------------------------------------------------------------------------------- /Exercise 10/Images/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 10/Images/1.png -------------------------------------------------------------------------------- /Exercise 10/Images/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 10/Images/2.png -------------------------------------------------------------------------------- /Exercise 10/Readme.md: -------------------------------------------------------------------------------- 1 | # Exercise 10 (Final Challenge) - V8 engine 2 | 3 | For this exercise we will fuzz **V8** Google’s JavaScript and WebAssembly engine. The goal is to find a crash/PoC for [**CVE-2019-5847**](https://nvd.nist.gov/vuln/detail/CVE-2019-5847) in v8 7.5. 4 | 5 | <details> 6 | <summary>For more information about CVE-2019-5847 vulnerability, click me!</summary> 7 | -------------------------------------------------------------------------------------------------------- 8 | 9 | **CVE-2019-5847** is a vulnerability that may cause an infinite recursion via a crafted file. 10 | 11 | A heap-based memory corruption is a type of memory corruption that occurs in the heap data area, and it's usually related to explicit dynamic memory management (allocation/deallocation with malloc() and free() functions). 12 | 13 | As a result, a remote attacker can exploit this issue to execute arbitrary code within the context of an application using the affected library. 14 | 15 | You can find more information about Heap-based memory corruption vulnerabilities at the following link: https://cwe.mitre.org/data/definitions/122.html 16 | 17 | </details> 18 | 19 | ## What you will learn 20 | Once you complete this exercise you will know-how: 21 | - How to use Fuzzilli to fuzz Javascript engines 22 | 23 | ## Read Before Start 24 | - I suggest you try to **solve the exercise by yourself** without checking the solution. Try as hard as you can, and only if you get stuck, check out the example solution below. 25 | - If you find a new vulnerability, **please submit a security report** to the project. If you need help or have any doubt about the process, the [GitHub Security Lab](mailto:securitylab.github.com) can help you with it :) 26 | 27 | ## Contact 28 | Are you stuck and looking for help? Do you have suggestions for making this course better or just positive feedback so that we create more similar content? 29 | Do you want to share your fuzing experience with the community? 30 | Join the GitHub Security Lab Slack and head to the `#fuzzing` channel. [Request an invite to the GitHub Security Lab Slack](mailto:securitylab-social@github.com?subject=Request%20an%20invite%20to%20the%20GitHub%20Security%20Lab%20Slack) 31 | 32 | ## Environment 33 | 34 | All the exercises have been tested on **Ubuntu 18.04 LTS**. I highly recommend you to use **the same OS version** to be able to follow the guidelines. You can find an Ubuntu 18.04 LTS VMware image [here](https://drive.google.com/file/d/1925mpjbIL8ugc7WcOooIatYWnMKSX-g4/view?usp=sharing). You can also use VirtualBox instead of VMware. 35 | 36 | The username / password for this VM are `fuzz` / `fuzz`. 37 | 38 | ## Fuzzilli 39 | 40 | Fuzzilli is a (coverage-)guided fuzzer for dynamic language interpreters based on a custom intermediate language ("FuzzIL") which can be mutated and translated to JavaScript. It's written and maintained by Samuel Groß, saelo@google.com. 41 | 42 | You can find more information about Fuzzilli at [the official repository](https://github.com/googleprojectzero/fuzzilli/) 43 | 44 | ### Install dependencies 45 | 46 | To get your environment fully ready, you may need to install some additional tools (ex. Swift, Git) 47 | 48 | Let's start installing the following dependencies: 49 | ``` 50 | sudo apt --yes install clang libcurl3 libpython2.7 libpython2.7-dev libcurl4 git 51 | ``` 52 | 53 | Now, we can download Swift: 54 | ``` 55 | cd $HOME 56 | wget https://swift.org/builds/swift-4.2.1-release/ubuntu1804/swift-4.2.1-RELEASE/swift-4.2.1-RELEASE-ubuntu18.04.tar.gz 57 | tar xzvf swift-4.2.1-RELEASE-ubuntu18.04.tar.gz 58 | sudo mv swift-4.2.1-RELEASE-ubuntu18.04 /usr/share/swift 59 | ``` 60 | 61 | We also need to configure the PATH envvar: 62 | ``` 63 | echo "export PATH=/usr/share/swift/usr/bin:$PATH" >> ~/.bashrc 64 | source ~/.bashrc 65 | ``` 66 | 67 | ### Install Fuzzilli 68 | 69 | Time for download and build Fuzzilli: 70 | ``` 71 | cd $HOME 72 | wget https://github.com/googleprojectzero/fuzzilli/archive/refs/tags/v0.9.zip 73 | unzip v0.9.zip 74 | cd fuzzilli-0.9/ 75 | swift build -c release -Xlinker='-lrt' 76 | ``` 77 | 78 | ## Download and build V8 Engine 79 | 80 | ### Download and setup depot_tools 81 | 82 | V8 use a package of scripts called depot_tools to manage checkouts and code reviews. The depot_tools package includes gclient, gcl, git-cl, repo, and others. We can install it with: 83 | ``` 84 | cd $HOME 85 | mkdir depot_tools && cd depot_tools 86 | git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git 87 | echo "export PATH=`pwd`/depot_tools:$PATH" >> ~/.bashrc 88 | source ~/.bashrc 89 | ``` 90 | 91 | ### Get V8 source code: 92 | ``` 93 | cd $HOME 94 | mkdir Fuzzing_v8_75 && cd Fuzzing_v8_75 95 | fetch v8 96 | cd v8 97 | git checkout 1ca088652d3aad04caceb648bcffef100bc4abc0 98 | gclient sync 99 | ``` 100 | 101 | ### Build and test V8: 102 | 103 | First of all we need to install build dependencies: 104 | ``` 105 | ./build/install-build-deps.sh 106 | ``` 107 | 108 | Generate build files using gn: 109 | ``` 110 | gn gen out/Release "--args=is_debug=false" 111 | ``` 112 | 113 | After that, we can compile with the following command line (it may take some time): 114 | ``` 115 | ninja -C out/Release 116 | ``` 117 | 118 | Now, we can check the d8 binary with: 119 | ``` 120 | ./out/Release/d8 ./test/fuzzer/parser/hello-world 121 | ``` 122 | 123 | and you should see something like this: 124 | 125 |  126 | 127 | ## Fuzzing time 128 | 129 | Compile v8 with coverage instrumentation: 130 | ``` 131 | cd $HOME/Fuzzing_v8_75/v8 132 | cp ../../fuzzilli-0.9/Targets/V8/v8.patch ./ 133 | gn gen out/fuzzbuild --args='is_debug=false dcheck_always_on=true v8_static_library=true v8_enable_slow_dchecks=true v8_enable_v8_checks=true v8_enable_verify_heap=true v8_enable_verify_csa=true v8_enable_verify_predictable=true sanitizer_coverage_flags="trace-pc-guard" target_cpu="x64"' 134 | ninja -C ./out/fuzzbuild 135 | ``` 136 | 137 | Move to fuzzilli folder: 138 | ``` 139 | cd $HOME/fuzzilli-0.9 140 | ``` 141 | 142 | First of all, we need to disable the creation of core dump files: 143 | ``` 144 | sudo sysctl -w 'kernel.core_pattern=|/bin/false' 145 | ``` 146 | 147 | Now we can run fuzzilli with: 148 | ``` 149 | swift run -Xlinker='-lrt' -c release FuzzilliCli --profile=v8 '/home/fuzz/Fuzzing_v8_75/v8/out/fuzzbuild/d8' 150 | ``` 151 | 152 | For a complete list of options, type: 153 | ``` 154 | swift run -Xlinker='-lrt' FuzzilliCli --help 155 | ``` 156 | 157 | If all went well, you should see something like: 158 | 159 |  160 | 161 | ## Do it yourself! 162 | In order to solve this challenge, you need to: 163 | 164 | 1) Download and build the vulnerable version 165 | 2) Define a custom mutator to target the vulnerable code 166 | 3) Fuzz with Fuzzilli until you have a few unique crashes 167 | 4) Triage the crashes to find a PoC for the vulnerability 168 | 5) Send your PoC (see below) 169 | 170 | ## Challenge rules 171 | The rules are as follows: 172 | - Please, don't disclose your solution 173 | - In order to be the winner, you must provide a valid crash/PoC file 174 | - There will be 2 winners in total 175 | - I'll release a new hint every week 176 | - Send your solution by **28 February** to antoniomoralesmaldonado@gmail.com 177 | - The winners will receive a coupon to spend in the [GitHub Shop](https://thegithubshop.com/) 178 | 179 | ## Hints 180 | - 1º hint: 181 | 182 | ``` 183 | git checkout 7.5.288.22 184 | ``` 185 | 186 | ## This challenge ended on March 1, 2022. Thank you for your submissions!! :smiley: 187 | -------------------------------------------------------------------------------- /Exercise 2/Images/Image1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 2/Images/Image1.png -------------------------------------------------------------------------------- /Exercise 2/Images/Image2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 2/Images/Image2.png -------------------------------------------------------------------------------- /Exercise 2/Images/Image3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 2/Images/Image3.png -------------------------------------------------------------------------------- /Exercise 2/Images/Image4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 2/Images/Image4.png -------------------------------------------------------------------------------- /Exercise 2/Images/Image5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 2/Images/Image5.png -------------------------------------------------------------------------------- /Exercise 2/Images/Image6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 2/Images/Image6.png -------------------------------------------------------------------------------- /Exercise 2/Images/Image7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 2/Images/Image7.png -------------------------------------------------------------------------------- /Exercise 2/Readme.md: -------------------------------------------------------------------------------- 1 | # Exercise 2 - libexif 2 | 3 | This time we will fuzz **libexif** EXIF parsing library. The goal is to find a crash/PoC for [**CVE-2009-3895**](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-3895) and another crash for [**CVE-2012-2836**](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-2836) in libexif 0.6.14. 4 | 5 | <details> 6 | <summary>For more information about CVE-2009-3895 and CVE-2012-2836 vulnerabilities, click me!</summary> 7 | -------------------------------------------------------------------------------------------------------- 8 | 9 | **CVE-2009-3895** is a heap-based buffer overflow that can be triggered with an invalid EXIF image. 10 | 11 | A heap-based buffer overflow is a type of buffer overflow that occurs in the heap data area, and it's usually related to explicit dynamic memory management (allocation/deallocation with malloc() and free() functions). 12 | 13 | As a result, a remote attacker can exploit this issue to execute arbitrary code within the context of an application using the affected library. 14 | 15 | You can find more information about Heap-based buffer oveflow vulnerabilities at the following link: https://cwe.mitre.org/data/definitions/122.html 16 | 17 | ------------------------------------------------------------------------- 18 | 19 | **CVE-2012-2836** is an Out-of-bounds Read vulneratibily that can be triggered via an image with crafted EXIF tags. 20 | 21 | An Out-of-bounds Read is a vulnerability that occurs when the program reads data past the end, or before the beginning, of the intended buffer. 22 | 23 | As a result, it allows remote attackers to cause a denial of service or possibly obtain potentially sensitive information from process memory. 24 | 25 | You can find more information about Out-of-bounds Read vulnerabilities at the following link: https://cwe.mitre.org/data/definitions/125.html 26 | 27 | </details> 28 | 29 | 30 | ## What you will learn 31 | Once you complete this exercise you will know how: 32 | - To fuzz a library using an external application 33 | - To use **afl-clang-lto**, a collision free instrumentation that is faster and provides better results than *afl-clang-fast* 34 | - To use Eclipse IDE as an easy alternative to GDB console for triaging 35 | 36 | ## Read Before Start 37 | - I suggest you to try to **solve the exercise by yourself** without checking the solution. Try as hard as you can, and only if you get stuck, check out the example solution below. 38 | - AFL uses a non-deterministic testing algorithm, so two fuzzing sessions are never the same. That's why I highly recommend **to set a fixed seed (-s 123)**. This way your fuzzing results will be similar to those shown here and that will allow you to follow the exercises more easily. 39 | - If you find a new vulnerability, **please submit a security report** to the project. If you need help or have any doubt about the process, the [GitHub Security Lab](mailto:securitylab.github.com) can help you with it :) 40 | 41 | ## Contact 42 | Are you stuck and looking for help? Do you have suggestions for making this course better or just positive feedback so that we create more fuzzing content? 43 | Do you want to share your fuzzing experience with the community? 44 | Join the GitHub Security Lab Slack and head to the `#fuzzing` channel. [Request an invite to the GitHub Security Lab Slack](mailto:securitylab-social@github.com?subject=Request%20an%20invite%20to%20the%20GitHub%20Security%20Lab%20Slack) 45 | 46 | ## Environment 47 | 48 | All the exercises have been tested on **Ubuntu 20.04.2 LTS**. I highly recommend you to use **the same OS version** to avoid different fuzzing results and to run AFL++ **on bare-metal** hardware, and not virtualized machines, for best performance. 49 | 50 | Otherwise, you can find an Ubuntu 20.04.2 LTS VMware image [here](https://drive.google.com/file/d/1_m1x-SHcm7Muov2mlmbbt8nkrMYp0Q3K/view?usp=sharing). You can also use VirtualBox instead of VMware. 51 | 52 | The username / password for this VM are `fuzz` / `fuzz`. 53 | 54 | ## Do it yourself! 55 | In order to complete this exercise, you need to: 56 | 1) Find an interface application that makes use of the libexif library 57 | 2) Create a seed corpus of exif samples 58 | 3) Compile libexif and the chosen application to be fuzzed using afl-clang-lto 59 | 4) Fuzz libexif until you have a few unique crashes 60 | 5) Triage the crashes to find a PoC for each vulnerability 61 | 6) Fix the issues 62 | 63 | **Estimated time = 6 hours** 64 | 65 | --- 66 | 67 | <details> 68 | <summary>SPOILER ALERT! : Solution inside</summary> 69 | 70 | ### Download and build your target 71 | 72 | Let's first get our fuzzing target. Create a new directory for the project we want to fuzz: 73 | ``` 74 | cd $HOME 75 | mkdir fuzzing_libexif && cd fuzzing_libexif/ 76 | ``` 77 | 78 | Download and uncompress libexif-0.6.14: 79 | ``` 80 | wget https://github.com/libexif/libexif/archive/refs/tags/libexif-0_6_14-release.tar.gz 81 | tar -xzvf libexif-0_6_14-release.tar.gz 82 | ``` 83 | 84 | Build and install libexif: 85 | 86 | ``` 87 | cd libexif-libexif-0_6_14-release/ 88 | sudo apt-get install autopoint libtool gettext libpopt-dev 89 | autoreconf -fvi 90 | ./configure --enable-shared=no --prefix="$HOME/fuzzing_libexif/install/" 91 | make 92 | make install 93 | ``` 94 | 95 | ### Choosing an interface application 96 | 97 | Since libexif is a library, we'll need another application that makes use of this library and which will be fuzzed. For this task we're going to use **exif command-line**. Type the following for download and uncompressing exif command-line 0.6.15: 98 | ``` 99 | cd $HOME/fuzzing_libexif 100 | wget https://github.com/libexif/exif/archive/refs/tags/exif-0_6_15-release.tar.gz 101 | tar -xzvf exif-0_6_15-release.tar.gz 102 | ``` 103 | 104 | Now, we can build and install exif command-line utility: 105 | ``` 106 | cd exif-exif-0_6_15-release/ 107 | autoreconf -fvi 108 | ./configure --enable-shared=no --prefix="$HOME/fuzzing_libexif/install/" PKG_CONFIG_PATH=$HOME/fuzzing_libexif/install/lib/pkgconfig 109 | make 110 | make install 111 | ``` 112 | 113 | To test everything is working properly, just type: 114 | ``` 115 | $HOME/fuzzing_libexif/install/bin/exif 116 | ``` 117 | 118 | and you should see something like that 119 | 120 |  121 | 122 | ### Seed corpus creation 123 | 124 | Now we need to get some exif samples. We're gonna use the sample images from the following repo: https://github.com/ianare/exif-samples. You can download it with: 125 | ``` 126 | cd $HOME/fuzzing_libexif 127 | wget https://github.com/ianare/exif-samples/archive/refs/heads/master.zip 128 | unzip master.zip 129 | ``` 130 | 131 | As an example, we can do: 132 | ``` 133 | $HOME/fuzzing_libexif/install/bin/exif $HOME/fuzzing_libexif/exif-samples-master/jpg/Canon_40D_photoshop_import.jpg 134 | ``` 135 | 136 | And the output should look like 137 |  138 | 139 | ### Afl-clang-lto instrumentation 140 | 141 | Now we're going to build libexif using **afl-clang-lto** as the compiler. 142 | 143 | ``` 144 | rm -r $HOME/fuzzing_libexif/install 145 | cd $HOME/fuzzing_libexif/libexif-libexif-0_6_14-release/ 146 | make clean 147 | export LLVM_CONFIG="llvm-config-11" 148 | CC=afl-clang-lto ./configure --enable-shared=no --prefix="$HOME/fuzzing_libexif/install/" 149 | make 150 | make install 151 | ``` 152 | 153 | ``` 154 | cd $HOME/fuzzing_libexif/exif-exif-0_6_15-release 155 | make clean 156 | export LLVM_CONFIG="llvm-config-11" 157 | CC=afl-clang-lto ./configure --enable-shared=no --prefix="$HOME/fuzzing_libexif/install/" PKG_CONFIG_PATH=$HOME/fuzzing_libexif/install/lib/pkgconfig 158 | make 159 | make install 160 | ``` 161 | 162 | As you can see, I used **afl-clang-lto** instead of *afl-clang-fast*. In general, *afl-clang-lto* is the best option out there because it's a collision-free instrumentation and it's faster than *afl-clang-fast*. 163 | 164 | If you are not sure about when to use *afl-clang-lto* or *afl-clang-fast* you can check the following diagram extracted from [AFLplusplus : instrumenting that target](https://github.com/AFLplusplus/AFLplusplus#1-instrumenting-that-target) 165 | 166 | ``` 167 | +--------------------------------+ 168 | | clang/clang++ 11+ is available | --> use LTO mode (afl-clang-lto/afl-clang-lto++) 169 | +--------------------------------+ see [instrumentation/README.lto.md](instrumentation/README.lto.md) 170 | | 171 | | if not, or if the target fails with LTO afl-clang-lto/++ 172 | | 173 | v 174 | +---------------------------------+ 175 | | clang/clang++ 6.0+ is available | --> use LLVM mode (afl-clang-fast/afl-clang-fast++) 176 | +---------------------------------+ see [instrumentation/README.llvm.md](instrumentation/README.llvm.md) 177 | | 178 | | if not, or if the target fails with LLVM afl-clang-fast/++ 179 | | 180 | v 181 | +--------------------------------+ 182 | | gcc 5+ is available | -> use GCC_PLUGIN mode (afl-gcc-fast/afl-g++-fast) 183 | +--------------------------------+ see [instrumentation/README.gcc_plugin.md](instrumentation/README.gcc_plugin.md) and 184 | [instrumentation/README.instrument_list.md](instrumentation/README.instrument_list.md) 185 | | 186 | | if not, or if you do not have a gcc with plugin support 187 | | 188 | v 189 | use GCC mode (afl-gcc/afl-g++) (or afl-clang/afl-clang++ for clang) 190 | ``` 191 | 192 | ### Fuzzing time 193 | 194 | Now, you can run the fuzzer with the following command: 195 | ``` 196 | afl-fuzz -i $HOME/fuzzing_libexif/exif-samples-master/jpg/ -o $HOME/fuzzing_libexif/out/ -s 123 -- $HOME/fuzzing_libexif/install/bin/exif @@ 197 | ``` 198 | 199 | After a few minutes, you should have multiple crashes: 200 | 201 |  202 | 203 | ### Triage 204 | 205 | #### Eclipse setup 206 | 207 | In the exercise 1 we learned how to use GDB console for triaging crashes. In this second exercise, we'll see how to use Eclipse-CDT for debugging purposes. 208 | 209 | First of all, we can download it from: 210 | https://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/2021-03/R/eclipse-cpp-2021-03-R-linux-gtk-x86_64.tar.gz 211 | 212 | If JAVA-SDK is not installed on your system, you can install it on Ubuntu with the following command: 213 | ``` 214 | sudo apt install default-jdk 215 | ``` 216 | 217 | Then we can extract it with: 218 | ``` 219 | tar -xzvf eclipse-cpp-2021-03-R-linux-gtk-x86_64.tar.gz 220 | ``` 221 | 222 | Once we have started Eclipse-CDT, we need to import our source code into the Project Explorer. For that, we need to go to File -> Import -> and then we need to choose C/C++ -> "Existing code as makefile project". Then we need to select "Linux GCC" and browse for the Exif source code folder: 223 | 224 |  225 | 226 | If all went well, you should be able to see the "exif" folder into the Project explorer tab. 227 | 228 | 229 | Now we're going to configure the debug parameters. For that we need to go to `Run -> Debug Configurations`. Then we select our exif project and browse for the exif binary: 230 | 231 |  232 | 233 | Then we need to set the input arguments. For that, go to the `"Arguments"` tab and set the path of one of the AFL crashes. 234 | 235 |  236 | 237 | Finally, we only need to click on `"Debug"` for starting the debugging sesion and the program will stop at the beginning of the main function. 238 | 239 | Having got to this point, we only need to click on `Run -> Resume` and the execution will stop when a segmentation fault is detected. 240 | 241 |  242 | 243 | ### Fix the issues 244 | 245 | The last step of the exercise is to fix both bugs. Rebuild your target after the fixes and check that your PoCs don't crash the program anymore. This last part is left as exercise for the student. 246 | 247 | <details> 248 | <summary>Solution inside</summary> 249 | -------------------------------------------------------------------------------------------------- 250 | 251 | Official fixes: 252 | 253 | - https://github.com/libexif/libexif/commit/8ce72b7f81e61ef69b7ad5bdfeff1516c90fa361 254 | - https://github.com/libexif/libexif/commit/00986f6fa979fe810b46e376a462c581f9746e06 255 | 256 | </details> 257 | 258 | Alternatively, you can download a newer version of libexif, and check that both bugs have been fixed. 259 | 260 | </details> 261 | -------------------------------------------------------------------------------- /Exercise 2/Solutions/CVE-2009-3895__Example: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 2/Solutions/CVE-2009-3895__Example -------------------------------------------------------------------------------- /Exercise 2/Solutions/CVE-2012-2836__Example: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 2/Solutions/CVE-2012-2836__Example -------------------------------------------------------------------------------- /Exercise 3/Images/Image1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 3/Images/Image1.png -------------------------------------------------------------------------------- /Exercise 3/Images/Image2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 3/Images/Image2.png -------------------------------------------------------------------------------- /Exercise 3/Images/Image3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 3/Images/Image3.png -------------------------------------------------------------------------------- /Exercise 3/Images/Image4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 3/Images/Image4.png -------------------------------------------------------------------------------- /Exercise 3/Readme.md: -------------------------------------------------------------------------------- 1 | # Exercise 3 - TCPdump 2 | 3 | In this exercise we will fuzz **TCPdump** packet analyzer. The goal is to find a crash/PoC for [**CVE-2017-13028**](https://www.cvedetails.com/cve/CVE-2017-13028/) in TCPdump 4.9.2. 4 | 5 | <details> 6 | <summary>For more information about CVE-2017-13028 vulnerability, click me!</summary> 7 | -------------------------------------------------------------------------------------------------------- 8 | 9 | **CVE-2017-13028** is an Out-of-bounds Read vulneratibily that can be triggered via a BOOTP packet (Bootstrap Protocol). 10 | 11 | An Out-of-bounds Read is a vulnerability that occurs when the program reads data past the end, or before the beginning, of the intended buffer. 12 | 13 | As a result, it allows remote attackers to cause a denial of service or possibly obtain potentially sensitive information from process memory. 14 | 15 | You can find more information about Out-of-bounds Read vulnerabilities at the following link: https://cwe.mitre.org/data/definitions/125.html 16 | 17 | </details> 18 | 19 | ## What you will learn 20 | Once you complete this exercise you will know: 21 | - What is **ASan (Address Sanitizer)**, a runtime memory error detection tool 22 | - How to use ASAN to fuzz a target 23 | - How much easy is to triage the crashes using ASan 24 | 25 | ## Read Before Start 26 | - I suggest you to try to **solve the exercise by yourself** without checking the solution. Try as hard as you can, and only if you get stuck, check out the example solution below. 27 | - AFL uses a non-deterministic testing algorithm, so two fuzzing sessions are never the same. That's why I highly recommend **to set a fixed seed (-s 123)**. This way your fuzzing results will be similar to those shown here and that will allow you to follow the exercises more easily. 28 | - If you find a new vulnerability, **please submit a security report** to the project. If you need help or have any doubt about the process, the [GitHub Security Lab](mailto:securitylab.github.com) can help you with it :) 29 | 30 | ## Contact 31 | Are you stuck and looking for help? Do you have suggestions for making this course better or just positive feedback so that we create more fuzzing content? 32 | Do you want to share your fuzzing experience with the community? 33 | Join the GitHub Security Lab Slack and head to the `#fuzzing` channel. [Request an invite to the GitHub Security Lab Slack](mailto:securitylab-social@github.com?subject=Request%20an%20invite%20to%20the%20GitHub%20Security%20Lab%20Slack) 34 | 35 | ## Environment 36 | 37 | All the exercises have been tested on **Ubuntu 20.04.2 LTS**. I highly recommend you to use **the same OS version** to avoid different fuzzing results and to run AFL++ **on bare-metal** hardware, and not virtualized machines, for best performance. 38 | 39 | Otherwise, you can find an Ubuntu 20.04.2 LTS VMware image [here](https://drive.google.com/file/d/1_m1x-SHcm7Muov2mlmbbt8nkrMYp0Q3K/view?usp=sharing). You can also use VirtualBox instead of VMware. 40 | 41 | The username / password for this VM are `fuzz` / `fuzz`. 42 | 43 | ## Do it yourself! 44 | In order to complete this exercise, you need to: 45 | 1) Find an efficient way to fuzz TCPdump 46 | 2) Try to figure out how to enable ASan for fuzzing 47 | 3) Fuzz TCPdump until you have a few unique crashes 48 | 4) Triage the crashes to find a PoC for the vulnerability 49 | 5) Fix the issue 50 | 51 | **Estimated time = 4 hours** 52 | 53 | --------------------------------------------------------------------------------------------------------------------------------------------------- 54 | 55 | <details> 56 | <summary>SPOILER ALERT! : Solution inside</summary> 57 | 58 | ### Download and build your target 59 | 60 | Let's first get our fuzzing target. Create a new directory for the project you want to fuzz: 61 | ``` 62 | cd $HOME 63 | mkdir fuzzing_tcpdump && cd fuzzing_tcpdump/ 64 | ``` 65 | 66 | Download and uncompress tcpdump-4.9.2.tar.gz 67 | ``` 68 | wget https://github.com/the-tcpdump-group/tcpdump/archive/refs/tags/tcpdump-4.9.2.tar.gz 69 | tar -xzvf tcpdump-4.9.2.tar.gz 70 | ``` 71 | 72 | We also need to download libpcap, a cross-platform library that is needed by TCPdump. Download and uncompress libpcap-1.8.0.tar.gz: 73 | ``` 74 | wget https://github.com/the-tcpdump-group/libpcap/archive/refs/tags/libpcap-1.8.0.tar.gz 75 | tar -xzvf libpcap-1.8.0.tar.gz 76 | ``` 77 | 78 | We need to rename ``libpcap-libpcap-1.8.0`` to ``libpcap-1.8.0``. Otherwise, tcpdump doesn't find the ``libpcap.a`` local path: 79 | ``` 80 | mv libpcap-libpcap-1.8.0/ libpcap-1.8.0 81 | ``` 82 | 83 | Build and install libpcap: 84 | 85 | ``` 86 | cd $HOME/fuzzing_tcpdump/libpcap-1.8.0/ 87 | ./configure --enable-shared=no 88 | make 89 | ``` 90 | 91 | Now, we can build and install tcpdump: 92 | ``` 93 | cd $HOME/fuzzing_tcpdump/tcpdump-tcpdump-4.9.2/ 94 | ./configure --prefix="$HOME/fuzzing_tcpdump/install/" 95 | make 96 | make install 97 | ``` 98 | 99 | To test everything is working properly, just type: 100 | ``` 101 | $HOME/fuzzing_tcpdump/install/sbin/tcpdump -h 102 | ``` 103 | 104 | and you should see something like that 105 | 106 |  107 | 108 | **Before continuing to the following step, check that your version numbers matches the numbers above** 109 | 110 | ### Seed corpus creation 111 | 112 | You can find a lot of .pcacp examples in the "./tests" folder. You can run these .pcap files with the following command-line: 113 | ``` 114 | $HOME/fuzzing_tcpdump/install/sbin/tcpdump -vvvvXX -ee -nn -r [.pcap file] 115 | ``` 116 | 117 | For example: 118 | ``` 119 | $HOME/fuzzing_tcpdump/install/sbin/tcpdump -vvvvXX -ee -nn -r ./tests/geneve.pcap 120 | ``` 121 | 122 | And the output should look like 123 |  124 | 125 | ### AddressSanitizer 126 | 127 | **AddressSanitizer (ASan)** is a fast memory error detector for C and C++. It was originally developed by Google (Konstantin Serebryany, Derek Bruening, Alexander Potapenko, Dmitry Vyukov) and first released in May 2011. 128 | 129 | It consists of a compiler instrumentation module and a run-time library. The tool is capable of finding out-of-bounds accesses to heap, stack, and global objects, as well as use-after-free, double-free and memory leaks bugs. 130 | 131 | AddressSanitizer is open source and is integrated with the LLVM compiler tool chain starting from version 3.1. While it was originally developed as a project for LLVM, it has been ported to GCC and it is included into GCC versions >= 4.8 132 | 133 | You can find more information about AddressSanitizer at the following [link](https://clang.llvm.org/docs/AddressSanitizer.html). 134 | 135 | ### Build with ASan enabled 136 | 137 | Now we're going to build tcpdump (and libpcap) with ASAN enabled. 138 | 139 | First of all, we're going to clean all previously compiled object files and executables: 140 | ``` 141 | rm -r $HOME/fuzzing_tcpdump/install 142 | cd $HOME/fuzzing_tcpdump/libpcap-1.8.0/ 143 | make clean 144 | 145 | cd $HOME/fuzzing_tcpdump/tcpdump-tcpdump-4.9.2/ 146 | make clean 147 | ``` 148 | 149 | Now, we set `AFL_USE_ASAN=1` before calling ``configure`` and ``make``: 150 | 151 | ``` 152 | cd $HOME/fuzzing_tcpdump/libpcap-1.8.0/ 153 | export LLVM_CONFIG="llvm-config-11" 154 | CC=afl-clang-lto ./configure --enable-shared=no --prefix="$HOME/fuzzing_tcpdump/install/" 155 | AFL_USE_ASAN=1 make 156 | 157 | cd $HOME/fuzzing_tcpdump/tcpdump-tcpdump-4.9.2/ 158 | AFL_USE_ASAN=1 CC=afl-clang-lto ./configure --prefix="$HOME/fuzzing_tcpdump/install/" 159 | AFL_USE_ASAN=1 make 160 | AFL_USE_ASAN=1 make install 161 | ``` 162 | 163 | **Afl-clang-lto compilation can take a few minutes to complete** 164 | 165 | ### Fuzzing time 166 | 167 | Now, you can run the fuzzer with the following command: 168 | ``` 169 | afl-fuzz -m none -i $HOME/fuzzing_tcpdump/tcpdump-tcpdump-4.9.2/tests/ -o $HOME/fuzzing_tcpdump/out/ -s 123 -- $HOME/fuzzing_tcpdump/install/sbin/tcpdump -vvvvXX -ee -nn -r @@ 170 | ``` 171 | 172 | **Note: ASAN on 64-bit systems requests a lot of virtual memory. That's why I've set the flag "-m none" that disable memory limits in AFL** 173 | 174 | After a while, you should have multiple crashes: 175 | 176 |  177 | 178 | 179 | ### Triage 180 | 181 | To debug a program built with ASan is so much easier than in the previous exercises. All you need to do is to feed the program with the crash file: 182 | 183 | ``` 184 | $HOME/fuzzing_tcpdump/install/sbin/tcpdump -vvvvXX -ee -nn -r '/home/antonio/fuzzing_tcpdump/out/default/crashes/id:000000,sig:06,src:002318+001583,time:10357087,op:splice,rep:8' 185 | ``` 186 | 187 | and you will get a nice summary of the crash, including the execution trace: 188 | 189 |  190 | 191 | ### Fix the issue 192 | 193 | The last step of the exercise is to fix the bug! Rebuild your target after the fix and check that your PoC don't crash the program anymore. This last part is left as exercise for the student. 194 | 195 | <details> 196 | <summary>Solution inside</summary> 197 | -------------------------------------------------------------------------------------------------- 198 | 199 | Official fix: 200 | - https://github.com/the-tcpdump-group/tcpdump/commit/85078eeaf4bf8fcdc14a4e79b516f92b6ab520fc#diff-05f854a9033643de07f0d0059bc5b98f3b314eeb1e2499ea1057e925e6501ae8L381 201 | 202 | </details> 203 | 204 | Alternatively, you can download a newer version of TCPdump, and check that both bugs have been fixed. 205 | 206 | </details> 207 | -------------------------------------------------------------------------------- /Exercise 4/Images/Image1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 4/Images/Image1.png -------------------------------------------------------------------------------- /Exercise 4/Images/Image2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 4/Images/Image2.png -------------------------------------------------------------------------------- /Exercise 4/Images/Image2_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 4/Images/Image2_2.png -------------------------------------------------------------------------------- /Exercise 4/Images/Image3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 4/Images/Image3.png -------------------------------------------------------------------------------- /Exercise 4/Readme.md: -------------------------------------------------------------------------------- 1 | # Exercise 4 - LibTIFF 2 | 3 | This time we will fuzz **LibTIFF** image library. The goal is to find a crash/PoC for [**CVE-2016-9297**](https://www.cvedetails.com/cve/CVE-2016-9297/) in libtiff 4.0.4 and **to measure the code coverage data** of your crash/PoC. 4 | 5 | <details> 6 | <summary>For more information about CVE-2016-9297 vulnerability, click me!</summary> 7 | -------------------------------------------------------------------------------------------------------- 8 | 9 | **CVE-2016-9297** is an Out-of-bounds Read vulnerability that can be triggered via crafted TIFF_SETGET_C16ASCII or TIFF_SETGET_C32_ASCII tag values. 10 | 11 | An Out-of-bounds Read is a vulnerability that occurs when the program reads data past the end, or before the beginning, of the intended buffer. 12 | 13 | As a result, it allows remote attackers to cause a denial of service or possibly obtain potentially sensitive information from process memory. 14 | 15 | You can find more information about Out-of-bounds Read vulnerabilities at the following link: https://cwe.mitre.org/data/definitions/125.html 16 | 17 | </details> 18 | 19 | ## What you will learn 20 | Once you complete this exercise you will know: 21 | - How to measure code coverage using LCOV 22 | - How to use code coverage data to improve the effectiveness of fuzzing 23 | 24 | ## Read Before Start 25 | - I suggest you to try to **solve the exercise by yourself** without checking the solution. Try as hard as you can, and only if you get stuck, check out the example solution below. 26 | - AFL uses a non-deterministic testing algorithm, so two fuzzing sessions are never the same. That's why I highly recommend **to set a fixed seed (-s 123)**. This way your fuzzing results will be similar to those shown here and that will allow you to follow the exercises more easily. 27 | - If you find a new vulnerability, **please submit a security report** to the project. If you need help or have any doubt about the process, the [GitHub Security Lab](mailto:securitylab.github.com) can help you with it :) 28 | 29 | ## Contact 30 | Are you stuck and looking for help? Do you have suggestions for making this course better or just positive feedback so that we create more fuzzing content? 31 | Do you want to share your fuzzing experience with the community? 32 | Join the GitHub Security Lab Slack and head to the `#fuzzing` channel. [Request an invite to the GitHub Security Lab Slack](mailto:securitylab-social@github.com?subject=Request%20an%20invite%20to%20the%20GitHub%20Security%20Lab%20Slack) 33 | 34 | ## Environment 35 | 36 | All the exercises have been tested on **Ubuntu 20.04.2 LTS**. I highly recommend you to use **the same OS version** to avoid different fuzzing results and to run AFL++ **on bare-metal** hardware, and not virtualized machines, for best performance. 37 | 38 | Otherwise, you can find an Ubuntu 20.04.2 LTS VMware image [here](https://drive.google.com/file/d/1_m1x-SHcm7Muov2mlmbbt8nkrMYp0Q3K/view?usp=sharing). You can also use VirtualBox instead of VMware. 39 | 40 | The username / password for this VM are `fuzz` / `fuzz`. 41 | 42 | ## Do it yourself! 43 | In order to complete this exercise, you need to: 44 | 1) Fuzz LibTiff (with ASan enabled) until you have a few unique crashes 45 | 2) Triage the crashes to find a PoC for the vulnerability 46 | 3) Measure the code coverage of this PoC 47 | 4) Fix the issue 48 | 49 | **Estimated time = 3 hours** 50 | 51 | --------------------------------------------------------------------------------------------------------------------------------------------------- 52 | 53 | <details> 54 | <summary>SPOILER ALERT! : Solution inside</summary> 55 | 56 | ### Download and build your target 57 | 58 | Let's first get our fuzzing target. Create a new directory for the project you want to fuzz: 59 | ``` 60 | cd $HOME 61 | mkdir fuzzing_tiff && cd fuzzing_tiff/ 62 | ``` 63 | 64 | Download and uncompress libtiff 4.0.4: 65 | ``` 66 | wget https://download.osgeo.org/libtiff/tiff-4.0.4.tar.gz 67 | tar -xzvf tiff-4.0.4.tar.gz 68 | ``` 69 | 70 | 71 | Now, we can build and install libtiff: 72 | ``` 73 | cd tiff-4.0.4/ 74 | ./configure --prefix="$HOME/fuzzing_tiff/install/" --disable-shared 75 | make 76 | make install 77 | ``` 78 | 79 | As target binary we can just fuzz the ``tiffinfo`` binary located in the ``/bin`` folder. As seed input corpus, we're gonna use the sample images from the ``/test/images/`` folder. 80 | 81 | To test everything is working properly, just type: 82 | ``` 83 | $HOME/fuzzing_tiff/install/bin/tiffinfo -D -j -c -r -s -w $HOME/fuzzing_tiff/tiff-4.0.4/test/images/palette-1c-1b.tiff 84 | ``` 85 | 86 | and you should see something like that 87 |  88 | 89 | In the last command line you can see that I enabled all these flags: "-j -c -r -s -w". This is to improve the **code coverage** and increase the chances of finding the bug. 90 | 91 | But how can we measure the code coverage of a given input case? 92 | 93 | ### Code coverage 94 | 95 | Code coverage is a software metric that show the number of times each line of code is triggered. By using code coverage we will get to know which parts of the code have been reached by the fuzzer and visualizes the fuzzing process. 96 | 97 | First of all, we need to install lcov. We can do it with the following command: 98 | ``` 99 | sudo apt install lcov 100 | ``` 101 | 102 | Now we need to rebuild libTIFF with the ``--coverage`` flag (compiler and linker): 103 | ``` 104 | rm -r $HOME/fuzzing_tiff/install 105 | cd $HOME/fuzzing_tiff/tiff-4.0.4/ 106 | make clean 107 | 108 | CFLAGS="--coverage" LDFLAGS="--coverage" ./configure --prefix="$HOME/fuzzing_tiff/install/" --disable-shared 109 | make 110 | make install 111 | ``` 112 | Then we can collect code coverage data by typing the following: 113 | 114 | ``` 115 | cd $HOME/fuzzing_tiff/tiff-4.0.4/ 116 | lcov --zerocounters --directory ./ 117 | lcov --capture --initial --directory ./ --output-file app.info 118 | $HOME/fuzzing_tiff/install/bin/tiffinfo -D -j -c -r -s -w $HOME/fuzzing_tiff/tiff-4.0.4/test/images/palette-1c-1b.tiff 119 | lcov --no-checksum --directory ./ --capture --output-file app2.info 120 | ``` 121 | 122 | I will try to explain each of the commands: 123 | - ``lcov --zerocounters --directory ./`` : Reset previous counters 124 | - ``lcov --capture --initial --directory ./ --output-file app.info`` : Return the "baseline" coverage data file that contains zero coverage for every instrumented line 125 | - ``$HOME/fuzzing_tiff/install/bin/tiffinfo -D -j -c -r -s -w $HOME/fuzzing_tiff/tiff-4.0.4/test/images/palette-1c-1b.tiff`` : Run the application you want to analyze . You can run it multiple times with different inputs 126 | - ``lcov --no-checksum --directory ./ --capture --output-file app2.info``: Save the current coverage state into the app2.info file 127 | 128 | Finally, we have to generate the HTML output: 129 | ``` 130 | genhtml --highlight --legend -output-directory ./html-coverage/ ./app2.info 131 | ``` 132 | 133 | If all went well, the code coverage report was created in the ``html-coverage`` folder. Just open the ``./html-coverage/index.html`` file and you should see something like this: 134 | 135 |  136 | 137 | Now you can browse trough the different folders and files, and see the number of times each line was executed. 138 | 139 | ### Fuzzing time 140 | 141 | Now we're going to compile libtiff with ASAN enabled. 142 | 143 | First of all, we're going to clean all previously compiled object files and executables: 144 | ``` 145 | rm -r $HOME/fuzzing_tiff/install 146 | cd $HOME/fuzzing_tiff/tiff-4.0.4/ 147 | make clean 148 | ``` 149 | 150 | Now, we set AFL_USE_ASAN=1 before calling make: 151 | ``` 152 | export LLVM_CONFIG="llvm-config-11" 153 | CC=afl-clang-lto ./configure --prefix="$HOME/fuzzing_tiff/install/" --disable-shared 154 | AFL_USE_ASAN=1 make -j4 155 | AFL_USE_ASAN=1 make install 156 | ``` 157 | 158 | Now, you can run the fuzzer with the following command: 159 | ``` 160 | afl-fuzz -m none -i $HOME/fuzzing_tiff/tiff-4.0.4/test/images/ -o $HOME/fuzzing_tiff/out/ -s 123 -- $HOME/fuzzing_tiff/install/bin/tiffinfo -D -j -c -r -s -w @@ 161 | ``` 162 | 163 | After a few minutes you should see somethink like this: 164 |  165 | 166 | ### Triage 167 | 168 | The ASan trace may looks like: 169 | 170 |  171 | 172 | ### Code coverage measure 173 | 174 | Now, try to measure the code coverage of your PoC. In order to complete this part, **you need to obtain a coverage html report**, similar to the example above. 175 | 176 | ### Fix the issue 177 | 178 | The last step of the exercise is to fix the bug! Rebuild your target after the fix and check that your PoC don't crash the program anymore. This last part is left as exercise for the student. 179 | 180 | <details> 181 | <summary>Solution inside</summary> 182 | -------------------------------------------------------------------------------------------------- 183 | 184 | Official fix: 185 | - https://github.com/vadz/libtiff/commit/30c9234c7fd0dd5e8b1e83ad44370c875a0270ed 186 | 187 | </details> 188 | 189 | Alternatively, you can download a newer version of LibTIFF, and check that both bugs have been fixed. 190 | 191 | 192 | </details> 193 | -------------------------------------------------------------------------------- /Exercise 5/Images/Image1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 5/Images/Image1.png -------------------------------------------------------------------------------- /Exercise 5/Images/Image2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 5/Images/Image2.png -------------------------------------------------------------------------------- /Exercise 5/Images/Image3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 5/Images/Image3.png -------------------------------------------------------------------------------- /Exercise 5/Readme.md: -------------------------------------------------------------------------------- 1 | # Exercise 5 - LibXML2 2 | 3 | For this exercize we will fuzz **LibXML2** XML parsing library. The goal is to find a crash/PoC for [**CVE-2017-9048**](https://nvd.nist.gov/vuln/detail/CVE-2017-9048) in LibXML2 2.9.4. 4 | 5 | <details> 6 | <summary>For more information about CVE-2017-9048 vulnerability, click me!</summary> 7 | -------------------------------------------------------------------------------------------------------- 8 | 9 | **CVE-2017-9048** is an stack buffer overflow vulnerability affecting the DTD validation functionality of LibXML2. 10 | 11 | A stack buffer overflow is a type of buffer overflow where the buffer being overwritten is allocated on the stack. 12 | 13 | As a result, a remote attacker can exploit this issue to execute arbitrary code within the context of an application using the affected library. 14 | 15 | You can find more information about stack buffer oveflow vulnerabilities at the following link: https://cwe.mitre.org/data/definitions/121.html 16 | 17 | </details> 18 | 19 | ## What you will learn 20 | Once you complete this exercise you will know how: 21 | - To use custom dictionaries for helping the fuzzer to find new execution paths 22 | - To parallelize the fuzzing job accross multiple cores 23 | 24 | ## Read Before Start 25 | - I suggest you to try to **solve the exercise by yourself** without checking the solution. Try as hard as you can, and only if you get stuck, check out the example solution below. 26 | - AFL uses a non-deterministic testing algorithm, so two fuzzing sessions are never the same. That's why I highly recommend **to set a fixed seed (-s 123)**. This way your fuzzing results will be similar to those shown here and that will allow you to follow the exercises more easily. 27 | - If you find a new vulnerability, **please submit a security report** to the project. If you need help or have any doubt about the process, the [GitHub Security Lab](mailto:securitylab.github.com) can help you with it :) 28 | 29 | ## Contact 30 | Are you stuck and looking for help? Do you have suggestions for making this course better or just positive feedback so that we create more fuzzing content? 31 | Do you want to share your fuzzing experience with the community? 32 | Join the GitHub Security Lab Slack and head to the `#fuzzing` channel. [Request an invite to the GitHub Security Lab Slack](mailto:securitylab-social@github.com?subject=Request%20an%20invite%20to%20the%20GitHub%20Security%20Lab%20Slack) 33 | 34 | ## Environment 35 | 36 | All the exercises have been tested on **Ubuntu 20.04.2 LTS**. I highly recommend you to use **the same OS version** to avoid different fuzzing results and to run AFL++ **on bare-metal** hardware, and not virtualized machines, for best performance. 37 | 38 | Otherwise, you can find an Ubuntu 20.04.2 LTS VMware image [here](https://drive.google.com/file/d/1_m1x-SHcm7Muov2mlmbbt8nkrMYp0Q3K/view?usp=sharing). You can also use VirtualBox instead of VMware. 39 | 40 | The username / password for this VM are `fuzz` / `fuzz`. 41 | 42 | ## Dictionaries 43 | 44 | When we want to fuzz complex text-based file formats (such as XML), it’s useful to provide the fuzzer with a dictionary containing a list of basic syntax tokens. 45 | 46 | In the case of AFL, such a dictionary is simply a set of words or values which is used by AFL to apply changes to the current in-memory file. Specifically, AFL performs the following changes with the values provided in the dictionary: 47 | - Override: Replaces a specific position with n number of bytes, where n is the length of a dictionary entry. 48 | - Insert: Inserts the dictionary entry at the current file position, forcing all characters to move n positions down and increasing file size. 49 | 50 | You can find a good bunch of examples [here](https://github.com/AFLplusplus/AFLplusplus/tree/stable/dictionaries) 51 | 52 | ## Paralellization 53 | 54 | If you have a multi-core system is a good idea to parallelize your fuzzing job to make the most of your CPU resources. 55 | 56 | ### Independent instances 57 | 58 | This is the simplest parallelization strategy. In this mode, we run fully separate instances of afl-fuzz. 59 | 60 | It is important to remember that AFL uses a non-deterministic testing algorithm. So, if we run multiples AFL instances, We increase our chances of success. 61 | 62 | For this, you only need to run multiple instances of "afl-fuzz" on multiple terminal windows, setting a different "output folder" for each one of them. A simple approach is to run as many fuzzing jobs as cores are on your system. 63 | 64 | Note: If you're using the -s flag, you need to use a different seed for each instance 65 | 66 | ### Shared instances 67 | 68 | The use of shared instances is a better approach to parallel fuzzing. In this case, each fuzzer instance gathers any test cases found by other fuzzers. 69 | 70 | You will usually have only one master instance at a time: 71 | ``` 72 | ./afl-fuzz -i afl_in -o afl_out -M Master -- ./program @@ 73 | ``` 74 | 75 | and N-1 number of slaves: 76 | ``` 77 | ./afl-fuzz -i afl_in -o afl_out -S Slave1 -- ./program @@ 78 | ./afl-fuzz -i afl_in -o afl_out -S Slave2 -- ./program @@ 79 | ... 80 | ./afl-fuzz -i afl_in -o afl_out -S SlaveN -- ./program @@ 81 | ``` 82 | 83 | ## Do it yourself! 84 | In order to complete this exercise, you need to: 85 | 1) Find an interface application that makes use of the LibXML2 library 86 | 2) Copy the [SampleInput.xml](./SampleInput.xml) file to your AFL input folder 87 | 3) Create a custom dictionary for fuzzing XML 88 | 4) Fuzz LibXML2 until you have a few unique crashes. I recommend you to use as many AFL instances as posible (CPU cores) 89 | 5) Triage the crashes to find a PoC for the vulnerability 90 | 6) Fix the issues 91 | 92 | **Estimated time = 3 hours** 93 | 94 | 95 | <details> 96 | <summary>SPOILER ALERT! : Solution inside</summary> 97 | 98 | ### Download and build your target 99 | 100 | Let's first get our fuzzing target. Create a new directory for the project you want to fuzz: 101 | ``` 102 | cd $HOME 103 | mkdir Fuzzing_libxml2 && cd Fuzzing_libxml2 104 | ``` 105 | 106 | Download and uncompress libxml2-2.9.4.tar.gz 107 | ``` 108 | wget http://xmlsoft.org/download/libxml2-2.9.4.tar.gz 109 | tar xvf libxml2-2.9.4.tar.gz && cd libxml2-2.9.4/ 110 | ``` 111 | 112 | Build and install libxml2: 113 | ``` 114 | sudo apt-get install python-dev 115 | CC=afl-clang-lto CXX=afl-clang-lto++ CFLAGS="-fsanitize=address" CXXFLAGS="-fsanitize=address" LDFLAGS="-fsanitize=address" ./configure --prefix="$HOME/Fuzzing_libxml2/libxml2-2.9.4/install" --disable-shared --without-debug --without-ftp --without-http --without-legacy --without-python LIBS='-ldl' 116 | make -j$(nproc) 117 | make install 118 | ``` 119 | 120 | Now, we can test that all is working OK with: 121 | ``` 122 | ./xmllint --memory ./test/wml.xml 123 | ``` 124 | 125 | and you should see something like that 126 | 127 |  128 | 129 | ### Seed corpus creation 130 | 131 | First of all, we need to get some XML samples. We're gonna use the **SampleInput.xml** provided in this repository: 132 | ``` 133 | mkdir afl_in && cd afl_in 134 | wget https://raw.githubusercontent.com/antonio-morales/Fuzzing101/main/Exercise%205/SampleInput.xml 135 | cd .. 136 | ``` 137 | 138 | ### Custom dictionary 139 | 140 | Now, you need to create an XML dictionary. Alternatively, you can use the XML dictionary provided with AFL++: 141 | ``` 142 | mkdir dictionaries && cd dictionaries 143 | wget https://raw.githubusercontent.com/AFLplusplus/AFLplusplus/stable/dictionaries/xml.dict 144 | cd .. 145 | ``` 146 | ### Fuzzing time 147 | 148 | In order to catch the bug, is mandatory to enable the `--valid` parameter. I also set the dictionary path with the **-x flag** and enabled the deterministic mutations with the **-D flag** (only for the master fuzzer): 149 | 150 | For example, I ran the fuzzer with the following command 151 | ``` 152 | afl-fuzz -m none -i ./afl_in -o afl_out -s 123 -x ./dictionaries/xml.dict -D -M master -- ./xmllint --memory --noenc --nocdata --dtdattr --loaddtd --valid --xinclude @@ 153 | ``` 154 | 155 | You can run another slave instance with: 156 | ``` 157 | afl-fuzz -m none -i ./afl_in -o afl_out -s 234 -S slave1 -- ./xmllint --memory --noenc --nocdata --dtdattr --loaddtd --valid --xinclude @@ 158 | ``` 159 | 160 | **Are you interested in fuzzing command-line arguments?** Take a look to the following [blog post](https://securitylab.github.com/research/fuzzing-challenges-solutions-1/), to the "Fuzzing command-line arguments" section. 161 | 162 | After a while, you should have multiple crashes: 163 | 164 |  165 | 166 | ### Triage 167 | 168 | To debug a program built with ASan is so much easier than in the previous exercises. All you need to do is to feed the program with the crash file: 169 | 170 | ``` 171 | ./xmllint --memory --noenc --nocdata --dtdattr --loaddtd --valid --xinclude './afl_out/default/crashes/id:000000,sig:06,src:003963,time:12456489,op:havoc,rep:4' 172 | ``` 173 | 174 | and you will get a nice summary of the crash, including the execution trace: 175 | 176 |  177 | 178 | ### Fix the issue 179 | 180 | The last step of the exercise is to fix the bug! Rebuild your target after the fix and check that your PoC don't crash the program anymore. This last part is left as exercise for the student. 181 | 182 | <details> 183 | <summary>Solution inside</summary> 184 | -------------------------------------------------------------------------------------------------- 185 | 186 | Official fix: 187 | - https://github.com/GNOME/libxml2/commit/932cc9896ab41475d4aa429c27d9afd175959d74 188 | 189 | </details> 190 | 191 | Alternatively, you can download a newer version of LibXML, and check that the bug has been fixed. 192 | 193 | </details> 194 | 195 | -------------------------------------------------------------------------------- /Exercise 5/SampleInput.xml: -------------------------------------------------------------------------------- 1 | <!DOCTYPE a []> -------------------------------------------------------------------------------- /Exercise 6/Images/Image0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 6/Images/Image0.png -------------------------------------------------------------------------------- /Exercise 6/Images/Image1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 6/Images/Image1.png -------------------------------------------------------------------------------- /Exercise 6/Images/Image2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 6/Images/Image2.png -------------------------------------------------------------------------------- /Exercise 6/Images/Image3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 6/Images/Image3.png -------------------------------------------------------------------------------- /Exercise 6/Readme.md: -------------------------------------------------------------------------------- 1 | # Exercise 6 - GIMP 2 | 3 | For this exercise, we will fuzz **GIMP** image editor. The goal is to find a crash/PoC for [**CVE-2016-4994**](https://www.cvedetails.com/cve/CVE-2016-4994/) in GIMP 2.8.16. 4 | 5 | <details> 6 | <summary>For more information about CVE-2016-4994 vulnerability, click me!</summary> 7 | -------------------------------------------------------------------------------------------------------- 8 | 9 | **CVE-2016-4994** is an Use-After-Free vulnerability that can be triggered via a crafted XCF file. 10 | 11 | Use after free errors occur when a program continues to use a pointer after it has been freed. 12 | 13 | This can have any number of adverse consequences, ranging from the corruption of valid data to the execution of arbitrary code. 14 | 15 | You can find more information about Use-After-Free vulnerabilities at the following link: https://cwe.mitre.org/data/definitions/416.html 16 | 17 | </details> 18 | 19 | 20 | ## What you will learn 21 | Once you complete this exercise you will know: 22 | - How to use persistent mode to speed up fuzzing 23 | - How to fuzz interactive / GUI applications 24 | 25 | ## Read Before Start 26 | - I suggest you to try to **solve the exercise by yourself** without checking the solution. Try as hard as you can, and only if you get stuck, check out the example solution below. 27 | - AFL uses a non-deterministic testing algorithm, so two fuzzing sessions are never the same. That's why I highly recommend **to set a fixed seed (-s 123)**. This way your fuzzing results will be similar to those shown here and that will allow you to follow the exercises more easily. 28 | - If you find a new vulnerability, **please submit a security report** to the project. If you need help or have any doubt about the process, the [GitHub Security Lab](mailto:securitylab.github.com) can help you with it :) 29 | 30 | ## Contact 31 | Are you stuck and looking for help? Do you have suggestions for making this course better or just positive feedback so that we create more fuzzing content? 32 | Do you want to share your fuzzing experience with the community? 33 | Join the GitHub Security Lab Slack and head to the `#fuzzing` channel. [Request an invite to the GitHub Security Lab Slack](mailto:securitylab-social@github.com?subject=Request%20an%20invite%20to%20the%20GitHub%20Security%20Lab%20Slack) 34 | 35 | ## Environment 36 | 37 | All the exercises have been tested on **Ubuntu 20.04.2 LTS**. I highly recommend you to use **the same OS version** to avoid different fuzzing results and to run AFL++ **on bare-metal** hardware, and not virtualized machines, for best performance. 38 | 39 | Otherwise, you can find an Ubuntu 20.04.2 LTS VMware image [here](https://drive.google.com/file/d/1_m1x-SHcm7Muov2mlmbbt8nkrMYp0Q3K/view?usp=sharing). You can also use VirtualBox instead of VMware. 40 | 41 | The username / password for this VM are `fuzz` / `fuzz`. 42 | 43 | ## Persistent mode 44 | 45 | The AFL persistent mode is based on **in-process fuzzers**: fuzzers that make use of a single one process, injecting code into the target process and changing the input values in memory. 46 | 47 | afl-fuzz supports a working mode that combines the benefits of in-process fuzzing with the robustness of a more traditional multi-process tool: **the Persistent Mode**. 48 | 49 | In persistent mode, AFL++ fuzzes a target multiple times in a single forked process, instead of forking a new process for each fuzz execution. This mode can improve the fuzzing speed up to 20X times. 50 | 51 | The basic structure of the target would be as follows: 52 | ```C 53 | //Program initialization 54 | 55 | while (__AFL_LOOP(10000)) { 56 | 57 | /* Read input data. */ 58 | /* Call library code to be fuzzed. */ 59 | /* Reset state. */ 60 | } 61 | 62 | //End of fuzzing 63 | 64 | ``` 65 | 66 | You can find more information about AFL++ persistent mode at: https://github.com/AFLplusplus/AFLplusplus/blob/stable/instrumentation/README.persistent_mode.md 67 | 68 | ## Do it yourself! 69 | In order to complete this exercise, you need to: 70 | 1) Find an efficient way of modifying GIMP source code to enable AFL persistent mode 71 | 2) Create a seed corpus of XCF samples 72 | 3) Optional: Create a fuzzing dictionary for the XCF file format 73 | 4) Fuzz GIMP until you have a few unique crashes. I recommend you to use as many AFL instances as possible (CPU cores) 74 | 5) Triage the crashes to find a PoC for the vulnerability 75 | 6) Fix the issues 76 | 7) Bonus: Find some of the other minor bugs 77 | 78 | **Estimated time = 7 hours** 79 | 80 | --------------------------------------------------------------------------------------------------------------------------------------------------- 81 | 82 | <details> 83 | <summary>SPOILER ALERT! : Solution inside</summary> 84 | 85 | ### Download and build your target 86 | 87 | Let's first get our fuzzing target. Create a new directory for the project you want to fuzz: 88 | ``` 89 | cd $HOME 90 | mkdir Fuzzing_gimp && cd Fuzzing_gimp 91 | ``` 92 | 93 | Now, install the required dependencies: 94 | ``` 95 | sudo apt-get install build-essential libatk1.0-dev libfontconfig1-dev libcairo2-dev libgudev-1.0-0 libdbus-1-dev libdbus-glib-1-dev libexif-dev libxfixes-dev libgtk2.0-dev python2.7-dev libpango1.0-dev libglib2.0-dev zlib1g-dev intltool libbabl-dev 96 | ``` 97 | 98 | We also need **GEGL 0.2(Generic Graphics Library)**. Unfortunately, we cannot find the gegl-0.2.0 package in our Ubuntu distribution. So, we need to download and build this library from source code. Just type: 99 | ``` 100 | wget https://download.gimp.org/pub/gegl/0.2/gegl-0.2.0.tar.bz2 101 | tar xvf gegl-0.2.0.tar.bz2 && cd gegl-0.2.0 102 | ``` 103 | 104 | Now, we need to make two minor changes in the source code: 105 | ``` 106 | sed -i 's/CODEC_CAP_TRUNCATED/AV_CODEC_CAP_TRUNCATED/g' ./operations/external/ff-load.c 107 | sed -i 's/CODEC_FLAG_TRUNCATED/AV_CODEC_FLAG_TRUNCATED/g' ./operations/external/ff-load.c 108 | ``` 109 | 110 | Build and install Gegl-0.2: 111 | ``` 112 | ./configure --enable-debug --disable-glibtest --without-vala --without-cairo --without-pango --without-pangocairo --without-gdk-pixbuf --without-lensfun --without-libjpeg --without-libpng --without-librsvg --without-openexr --without-sdl --without-libopenraw --without-jasper --without-graphviz --without-lua --without-libavformat --without-libv4l --without-libspiro --without-exiv2 --without-umfpack 113 | make -j$(nproc) 114 | sudo make install 115 | ``` 116 | Don't worry if you see some error messages in the testing stage. 117 | 118 | Now, we download and uncompress GIMP 2.8.16: 119 | ``` 120 | cd .. 121 | wget https://mirror.klaus-uwe.me/gimp/pub/gimp/v2.8/gimp-2.8.16.tar.bz2 122 | tar xvf gimp-2.8.16.tar.bz2 && cd gimp-2.8.16/ 123 | ``` 124 | 125 | Time for building GIMP using **afl-clang-lto** as the compiler (it can take some time): 126 | ``` 127 | CC=afl-clang-lto CXX=afl-clang-lto++ PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$HOME/Fuzzing_gimp/gegl-0.2.0/ CFLAGS="-fsanitize=address" CXXFLAGS="-fsanitize=address" LDFLAGS="-fsanitize=address" ./configure --disable-gtktest --disable-glibtest --disable-alsatest --disable-nls --without-libtiff --without-libjpeg --without-bzip2 --without-gs --without-libpng --without-libmng --without-libexif --without-aa --without-libxpm --without-webkit --without-librsvg --without-print --without-poppler --without-cairo-pdf --without-gvfs --without-libcurl --without-wmf --without-libjasper --without-alsa --without-gudev --disable-python --enable-gimp-console --without-mac-twain --without-script-fu --without-gudev --without-dbus --disable-mp --without-linux-input --without-xvfb-run --with-gif-compression=none --without-xmc --with-shm=none --enable-debug --prefix="$HOME/Fuzzing_gimp/gimp-2.8.16/install" 128 | make -j$(nproc) 129 | make install 130 | ``` 131 | 132 | ### Persistent mode 133 | 134 | There are two very simple approaches: 135 | 136 | - The first one is to modify the ``app.c`` file and include the AFL_LOOP macro into the for loop: 137 | 138 |  139 | 140 | - The second one is to insert the AFL_LOOP macro inside the ``xcf_load_invoker`` function: 141 | 142 |  143 | 144 | While the first one allows us to target different input formats, the second is faster and we will have more chances to catch the bug. 145 | 146 | You can download the patch for the second one [here](./persistent.patch) 147 | 148 | ### Seed corpus creation 149 | 150 | I recommend you to create multiple GIMP projects and save them to obtain multiple .xcf samples 151 | 152 | Alternatively, you can just copy the [SampleInput.xcf](./SampleInput.xcf) file to your AFL input folder 153 | 154 | ### Fuzzing time 155 | 156 | Since the vulnerability affects GIMP core, we can save some startup time by removing plugins that we don't need: 157 | ``` 158 | rm ./install/lib/gimp/2.0/plug-ins/* 159 | ``` 160 | 161 | Now, you can run the fuzzer with the following command: 162 | ``` 163 | ASAN_OPTIONS=detect_leaks=0,abort_on_error=1,symbolize=0 afl-fuzz -i './afl_in' -o './afl_out' -D -t 100 -- ./install/bin/gimp-console-2.8 --verbose -d -f @@ 164 | ``` 165 | 166 | Some notes: 167 | - `gimp-console-2.8` is a console-only version of GIMP 168 | - I recommend enabling deterministic mutations (-D) 169 | - There is also an infinite loop bug in the code, so we need to set a low timeout limit (ex. -t 100). This timeout limit depends on your machine capabilites, so you will need to adjust it for your particular case. 170 | 171 | 172 | After a while, you should have multiple crashes: 173 |  174 | 175 | ### Triage 176 | 177 | The ASan trace may look like: 178 | 179 |  180 | 181 | ### Fix the issues 182 | 183 | The last step of the exercise is to fix both bugs. Rebuild your target after the fixes and check that your PoCs don't crash the program anymore. This last part is left as an exercise for the student. 184 | 185 | <details> 186 | <summary>Solution inside</summary> 187 | -------------------------------------------------------------------------------------------------- 188 | 189 | Official fixes: 190 | 191 | - https://gitlab.gnome.org/GNOME/gimp/-/commit/6d804bf9ae77bc86a0a97f9b944a129844df9395 192 | 193 | </details> 194 | 195 | Alternatively, you can download a newer version of GIMP, and check that both bugs have been fixed. 196 | 197 | 198 | ### Bonus 199 | 200 | There are other minor bugs in the code. I've found: 201 | 202 | - A null dereference bug 203 | - An infinite loop bug 204 | - A memory exhaustion bug 205 | 206 | I encourage you to try to find all of them! 207 | 208 | </details> 209 | -------------------------------------------------------------------------------- /Exercise 6/SampleInput.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 6/SampleInput.xcf -------------------------------------------------------------------------------- /Exercise 6/persistent.patch: -------------------------------------------------------------------------------- 1 | --- ../xcf.c 2014-08-20 08:27:58.000000000 -0700 2 | +++ ./app/xcf/xcf.c 2021-10-11 13:02:42.800831192 -0700 3 | @@ -277,6 +277,10 @@ 4 | 5 | filename = g_value_get_string (&args->values[1]); 6 | 7 | +#ifdef __AFL_COMPILER 8 | + while(__AFL_LOOP(10000)){ 9 | +#endif 10 | + 11 | info.fp = g_fopen (filename, "rb"); 12 | 13 | if (info.fp) 14 | @@ -366,6 +370,12 @@ 15 | if (success) 16 | gimp_value_set_image (&return_vals->values[1], image); 17 | 18 | +#ifdef __AFL_COMPILER 19 | + } 20 | +#endif 21 | + 22 | + exit(0); 23 | + 24 | gimp_unset_busy (gimp); 25 | 26 | return return_vals; 27 | -------------------------------------------------------------------------------- /Exercise 7/Images/image0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 7/Images/image0.png -------------------------------------------------------------------------------- /Exercise 7/Images/image1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 7/Images/image1.png -------------------------------------------------------------------------------- /Exercise 7/Images/image2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 7/Images/image2.png -------------------------------------------------------------------------------- /Exercise 7/Images/image3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 7/Images/image3.png -------------------------------------------------------------------------------- /Exercise 7/InputCorpus/short2.wmv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 7/InputCorpus/short2.wmv -------------------------------------------------------------------------------- /Exercise 7/InputCorpus/veryshort.wmv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 7/InputCorpus/veryshort.wmv -------------------------------------------------------------------------------- /Exercise 7/Partial_instrumentation: -------------------------------------------------------------------------------- 1 | demux/asf/asf.c 2 | demux/asf/asfpacket.c 3 | demux/asf/libasf.c 4 | vlc.c 5 | 6 | #fun: Demux 7 | fun: WaitKeyframe 8 | fun: SeekPercent 9 | fun: SeekIndex 10 | fun: SeekPrepare 11 | #fun: Control 12 | fun: Packet_SetAR 13 | fun: Packet_SetSendTime 14 | fun: Packet_UpdateTime 15 | fun: Packet_GetTrackInfo 16 | fun: Packet_DoSkip 17 | fun: Packet_Enqueue 18 | fun: Block_Dequeue 19 | fun: ASF_fillup_es_priorities_ex 20 | fun: ASF_fillup_es_bitrate_priorities_ex 21 | fun: DemuxInit 22 | fun: FlushQueue 23 | fun: FlushQueues 24 | fun: DemuxEnd 25 | 26 | 27 | fun: AsfObjectHelperHave 28 | fun: AsfObjectHelperSkip 29 | fun: AsfObjectHelperReadString 30 | fun: ASF_ReadObjectCommon 31 | fun: ASF_NextObject 32 | fun: ASF_FreeObject_Null 33 | fun: ASF_ReadObject_Header 34 | fun: ASF_ReadObject_Data 35 | fun: ASF_ReadObject_Index 36 | fun: ASF_FreeObject_Index 37 | fun: ASF_ReadObject_file_properties 38 | fun: ASF_FreeObject_metadata 39 | fun: ASF_ReadObject_metadata 40 | fun: ASF_ReadObject_header_extension 41 | fun: ASF_FreeObject_header_extension 42 | fun: ASF_ReadObject_stream_properties 43 | fun: ASF_FreeObject_stream_properties 44 | fun: ASF_FreeObject_codec_list 45 | fun: ASF_ReadObject_codec_list 46 | fun: ASF_ReadObject_content_description 47 | fun: ASF_FreeObject_content_description 48 | fun: ASF_ReadObject_language_list 49 | fun: ASF_FreeObject_language_list 50 | fun: ASF_ReadObject_stream_bitrate_properties 51 | fun: ASF_FreeObject_stream_bitrate_properties 52 | fun: ASF_FreeObject_extended_stream_properties 53 | fun: ASF_ReadObject_extended_stream_properties 54 | fun: ASF_ReadObject_advanced_mutual_exclusion 55 | fun: ASF_FreeObject_advanced_mutual_exclusion 56 | fun: ASF_ReadObject_stream_prioritization 57 | fun: ASF_FreeObject_stream_prioritization 58 | fun: ASF_ReadObject_bitrate_mutual_exclusion 59 | fun: ASF_FreeObject_bitrate_mutual_exclusion 60 | fun: ASF_FreeObject_extended_content_description 61 | fun: ASF_ReadObject_marker 62 | fun: ASF_FreeObject_marker 63 | fun: ASF_ReadObject_Raw 64 | fun: ASF_ParentObject 65 | fun: ASF_GetObject_Function 66 | fun: ASF_ReadObject 67 | fun: ASF_FreeObject 68 | fun: ASF_ObjectDumpDebug 69 | fun: ASF_ReadObjectRoot 70 | fun: ASF_FreeObjectRoot 71 | fun: ASF_CountObject 72 | fun: ASF_FindObject 73 | 74 | 75 | fun: DemuxSubPayload 76 | fun: ParsePayloadExtensions 77 | fun: DemuxPayload 78 | fun: DemuxASFPacket 79 | 80 | 81 | -------------------------------------------------------------------------------- /Exercise 7/Readme.md: -------------------------------------------------------------------------------- 1 | # Exercise 7 - VLC Media Player 2 | 3 | For this exercise, we will fuzz **VLC** media player. The goal is to find a crash/PoC for [**CVE-2019-14776**](https://nvd.nist.gov/vuln/detail/CVE-2019-14776) in VLC 3.0.7.1. 4 | 5 | <details> 6 | <summary>For more information about CVE-2019-14776 vulnerability, click me!</summary> 7 | -------------------------------------------------------------------------------------------------------- 8 | 9 | **CVE-2019-14776** is an Out-of-bounds Read vulnerability that can be triggered via a crafted WMV/ASF (Windows Media Video) file. 10 | 11 | An Out-of-bounds Read is a vulnerability that occurs when the program reads data past the end, or before the beginning, of the intended buffer. 12 | 13 | As a result, it allows remote attackers to cause a denial of service or possibly obtain potentially sensitive information from process memory. 14 | 15 | You can find more information about Out-of-bounds Read vulnerabilities at the following link: https://cwe.mitre.org/data/definitions/125.html 16 | 17 | </details> 18 | 19 | 20 | ## What you will learn 21 | Once you complete this exercise you will know: 22 | - How to use Partial Instrumentation to only instrument the relevant parts of the program 23 | - How to write fuzzing harnesses to test large applications more efficiently 24 | 25 | ## Read Before Start 26 | - I suggest you try to **solve the exercise by yourself** without checking the solution. Try as hard as you can, and only if you get stuck, check out the example solution below. 27 | - AFL uses a non-deterministic testing algorithm, so two fuzzing sessions are never the same. That's why I highly recommend **to set a fixed seed (-s 123)**. This way your fuzzing results will be similar to those shown here and that will allow you to follow the exercises more easily. 28 | - If you find a new vulnerability, **please submit a security report** to the project. If you need help or have any doubt about the process, the [GitHub Security Lab](mailto:securitylab.github.com) can help you with it :) 29 | 30 | ## Contact 31 | Are you stuck and looking for help? Do you have suggestions for making this course better or just positive feedback so that we create more fuzzing content? 32 | Do you want to share your fuzzing experience with the community? 33 | Join the GitHub Security Lab Slack and head to the `#fuzzing` channel. [Request an invite to the GitHub Security Lab Slack](mailto:securitylab-social@github.com?subject=Request%20an%20invite%20to%20the%20GitHub%20Security%20Lab%20Slack) 34 | 35 | ## Environment 36 | 37 | All the exercises have been tested on **Ubuntu 20.04.2 LTS**. I highly recommend you to use **the same OS version** to avoid different fuzzing results and to run AFL++ **on bare-metal** hardware, and not virtualized machines, for best performance. 38 | 39 | Otherwise, you can find an Ubuntu 20.04.2 LTS VMware image [here](https://drive.google.com/file/d/1_m1x-SHcm7Muov2mlmbbt8nkrMYp0Q3K/view?usp=sharing). You can also use VirtualBox instead of VMware. 40 | 41 | The username / password for this VM are `fuzz` / `fuzz`. 42 | 43 | ## Partial Instrumentation 44 | 45 | One of the advantages of using an evolutionary coverage-guided fuzzer is that it’s capable of finding new execution paths all by itself. However, this can often also be a disadvantage. This is particularly true when we face software with a highly modular architecture (as in the case of VLC media player), where each module performs a specific task. 46 | 47 | So, let's assume we fed the fuzzer with a valid MKV file. But after several mutations of the input file, the file “magic bytes” have changed and now the input file is viewed as an AVI file by our program. Therefore, this “mutated MKV file” is now processed by AVI Demux. After some time, the file magic bytes change once again and now the file is viewed as an MPEG file. In both cases, the potential of this newly mutated file to increase our code coverage is very poor because this new file won’t have any valid syntax structure. 48 | 49 | In short, if we don’t put constraints on code coverage, the fuzzer can easily choose a wrong path which in turn makes the fuzzing process less effective. 50 | 51 | To address this problem, AFL++ includes a Partial Instrumentation feature that allows you to specify which functions/files should be compiled with or without instrumentation. This helps the fuzzer focus on the important parts of the program, avoiding undesired noise and disturbance by exercising uninteresting code paths. 52 | 53 | To use it, we set the environment AFL_LLVM_ALLOWLIST variable when compiling. This environment variable must point to a file containing all the functions/filenames that should be instrumented. 54 | 55 | You can find more information about AFL++ partial instrumentation at: https://github.com/AFLplusplus/AFLplusplus/blob/stable/instrumentation/README.instrument_list.md 56 | 57 | ## Do it yourself! 58 | In order to complete this exercise, you need to: 59 | 1) Write a partial instrumentation file containing the ASF demuxing functions and filenames 60 | 2) Create a fuzzing harness for fuzzing ASF file format (persistent mode) 61 | 3) Create a seed corpus of ASF samples 62 | 4) Optional: Create a fuzzing dictionary for the ASF file format 63 | 5) Fuzz VLC until you have a few unique crashes. I recommend you to use as many AFL instances as possible (CPU cores) 64 | 6) Triage the crashes to find a PoC for the vulnerability 65 | 7) Fix the issues 66 | 67 | **Estimated time = 6 hours** 68 | 69 | --------------------------------------------------------------------------------------------------------------------------------------------------- 70 | 71 | <details> 72 | <summary>SPOILER ALERT! : Solution inside</summary> 73 | 74 | ### Download the target 75 | 76 | Let's first get our fuzzing target. Create a new directory for the project you want to fuzz: 77 | ``` 78 | cd $HOME 79 | mkdir fuzzing_vlc && cd fuzzing_vlc 80 | ``` 81 | 82 | Download and uncompress vlc-3.0.7.1.tar.xz: 83 | ``` 84 | wget https://download.videolan.org/pub/videolan/vlc/3.0.7.1/vlc-3.0.7.1.tar.xz 85 | tar -xvf vlc-3.0.7.1.tar.xz && cd vlc-3.0.7.1/ 86 | ``` 87 | 88 | ### Build VLC: 89 | ``` 90 | ./configure --prefix="$HOME/fuzzing_vlc/vlc-3.0.7.1/install" --disable-a52 --disable-lua --disable-qt 91 | make -j$(nproc) 92 | ``` 93 | 94 | To test everything is working properly, just type: 95 | ``` 96 | ./bin/vlc-static --help 97 | ``` 98 | 99 | and you should see something like that 100 | 101 |  102 | 103 | 104 | ### Seed corpus creation 105 | 106 | You can find a lot of video samples in the [ffmpeg samples repository](https://samples.ffmpeg.org/) 107 | 108 | I advise you to pick some samples and then, use a video editor to shrink the video file to the smallest size possible. 109 | 110 | These are some examples of open-source video editors: 111 | 112 | - [OpenShot](https://www.openshot.org/) 113 | - [Shotcut](https://shotcut.org/) 114 | 115 | Or more easily, just copy the [short2.wmv](./InputCorpus/short2.wmv) and [veryshort.wmv](./InputCorpus/veryshort.wmv) files to your AFL input folder. 116 | 117 | 118 | ### Fuzzing harness 119 | 120 | If you try to fuzz directly the ``vlc-static`` binary you'll see that AFL only gets a few executions per second. This is because VLC startup is very time-consuming. That's why I recommend you create a **custom fuzzing harness** for fuzzing VLC. 121 | 122 | I chose to modify the ``./test/vlc-demux-run.c`` file to include my fuzzing harness. In this way, you can compile the harness just by doing: 123 | 124 | ``` 125 | cd test 126 | make vlc-demux-run -j$(nproc) LDFLAGS="-fsanitize=address" 127 | cd .. 128 | ``` 129 | 130 | Since the bug exists in the ASF demuxing, I call to the ``vlc_demux_process_memory`` function. This function try to demux a data buffer previously stored in the memory. You can find my code changes [here](./fuzzing_harness.patch) 131 | 132 | 133 | ### Partial instrumentation 134 | 135 | At first, I tried just including the filenames involved in ASF demuxing. Unfortunately, this approach didn't work. 136 | 137 | It seems that matching on filenames is [not always possible](https://github.com/AFLplusplus/AFLplusplus/issues/1018#issuecomment-879045408), so I opted for a mixing approach including function matching and filename matching: 138 | 139 | 140 |  141 | 142 | You can download my partial instrumentation file [here](./Partial_instrumentation) 143 | 144 | 145 | ### Minor changes 146 | 147 | To speed-up the ASF fuzzing speed, I recommend you to apply this patch to ``modules/demux/libasf.c`` (no more clues at the moment ;) ) : [speedup.patch](./speedup.patch) 148 | 149 | ### Fuzzing time 150 | 151 | Time for building VLC using **afl-clang-fast** as the compiler and with ASAN enabled: 152 | 153 | ``` 154 | CC="afl-clang-fast" CXX="afl-clang-fast++" ./configure --prefix="$HOME/fuzzing_vlc/vlc-3.0.7.1/install" --disable-a52 --disable-lua --disable-qt --with-sanitizer=address 155 | AFL_LLVM_ALLOWLIST=$HOME/fuzzing_vlc/vlc-3.0.7.1/Partial_instrumentation make -j$(nproc) LDFLAGS="-fsanitize=address" 156 | ``` 157 | 158 | Build the fuzzing harness: 159 | ``` 160 | cd test 161 | make vlc-demux-run -j$(nproc) LDFLAGS="-fsanitize=address" 162 | cd .. 163 | ``` 164 | 165 | Now, you can run the fuzzer with the following command: 166 | ``` 167 | afl-fuzz -t 100 -m none -i './afl_in' -o './afl_out' -x asf_dictionary.dict -D -M master -- ./test/vlc-demux-run @@ 168 | ``` 169 | 170 | Some notes: 171 | - The timeout parameter is heavily reliant on the computer. You will need to adjust this value. 172 | 173 | 174 | After a while, you should have multiple crashes: 175 |  176 | 177 | ### Triage 178 | 179 | The ASan trace may look like: 180 | 181 |  182 | 183 | ### Fix the issues 184 | 185 | The last step of the exercise is to fix the bug. Rebuild your target after the fix and check that your PoC doesn't crash the program anymore. This last part is left as an exercise for the student. 186 | 187 | <details> 188 | <summary>Solution inside</summary> 189 | -------------------------------------------------------------------------------------------------- 190 | 191 | Official fixes: 192 | 193 | - https://github.com/videolan/vlc/commit/fdbdd677c1e6262f31771b0ba10afb24aabf108c#diff-a22170125046390274dd33c2cb5bb0e99d485e6708b376f40978de9534ac55a9 194 | 195 | </details> 196 | 197 | Alternatively, you can download a newer version of VLC, and check that both bugs have been fixed. 198 | 199 | -------------------------------------------------------------------------------- /Exercise 7/asf_dictionary.dict: -------------------------------------------------------------------------------- 1 | "\x00\x00\x00\x00" 2 | "\x00\x00" 3 | "\x00\x00\x00\x00\x00\x00\x00\x00" 4 | "\x56\x4C\x43\x52\x4F\x4F\x54\x00" 5 | "\x30\x26\xB2\x75\x8E\x66\xCF\x11\xA6\xD9\x00\xAA\x00\x62\xCE\x6C" 6 | "\x36\x26\xB2\x75\x8E\x66\xCF\x11\xA6\xD9\x00\xAA\x00\x62\xCE\x6C" 7 | "\x90\x08\x00\x33\xB1\xE5\xCF\x11\x89\xF4\x00\xA0\xC9\x03\x49\xCB" 8 | "\xD3\x29\xE2\xD6\xDA\x35\xD1\x11\x90\x34\x00\xA0\xC9\x03\x49\xBE" 9 | "\xA1\xDC\xAB\x8C\x47\xA9\xCF\x11\x8E\xE4\x00\xC0\x0C\x20\x53\x65" 10 | "\x91\x07\xDC\xB7\xB7\xA9\xCF\x11\x8E\xE6\x00\xC0\x0C\x20\x53\x65" 11 | "\xB5\x03\xBF\x5F\x2E\xA9\xCF\x11\x8E\xE3\x00\xC0\x0C\x20\x53\x65" 12 | "\x40\x52\xD1\x86\x1D\x31\xD0\x11\xA3\xA4\x00\xA0\xC9\x03\x48\xF6" 13 | "\x01\xCD\x87\xF4\x51\xA9\xCF\x11\x8E\xE6\x00\xC0\x0C\x20\x53\x65" 14 | "\x33\x26\xB2\x75\x8E\x66\xCF\x11\xA6\xD9\x00\xAA\x00\x62\xCE\x6C" 15 | "\x40\xA4\xD0\xD2\x07\xE3\xD2\x11\x97\xF0\x00\xA0\xC9\x5E\xA8\x50" 16 | "\x74\xD4\x06\x18\xDF\xCA\x09\x45\xA4\xBA\x9A\xAB\xCB\x96\xAA\xE8" 17 | "\xCF\x49\x86\xA0\x75\x47\x70\x46\x8A\x16\x6E\x35\x35\x75\x66\xCD" 18 | "\x5B\xD1\xFE\xD4\xD3\x88\x4F\x45\x81\xF0\xED\x5C\x45\x99\x9E\x24" 19 | "\xEA\xCB\xF8\xC5\xAF\x5B\x77\x48\x84\x67\xAA\x8C\x44\xFA\x4C\xCA" 20 | "\x40\x9E\x69\xF8\x4D\x5B\xCF\x11\xA8\xFD\x00\x80\x5F\x5C\x44\x2B" 21 | "\xC0\xEF\x19\xBC\x4D\x5B\xCF\x11\xA8\xFD\x00\x80\x5F\x5C\x44\x2B" 22 | "\xC0\xCF\xDA\x59\xE6\x59\xD0\x11\xA3\xAC\x00\xA0\xC9\x03\x48\xF6" 23 | "\xE2\x65\xFB\x3A\xEF\x47\xF2\x40\xAC\x2C\x70\xA9\x0D\x71\xD3\x43" 24 | "\xF8\x03\xB1\xFE\xAD\x12\x64\x4C\x84\x0F\x2A\x1D\x2F\x7A\xD4\x8C" 25 | "\xD0\x3F\xB7\x3C\x4A\x0C\x03\x48\x95\x3D\xED\xF7\xB6\x22\x8F\x0C" 26 | "\x30\x1A\xFB\x1E\x62\x0B\xD0\x11\xA3\x9B\x00\xA0\xC9\x03\x48\xF6" 27 | "\xDC\x29\xE2\xD6\xDA\x35\xD1\x11\x90\x34\x00\xA0\xC9\x03\x49\xBE" 28 | "\x35\x26\xB2\x75\x8E\x66\xCF\x11\xA6\xD9\x00\xAA\x00\x62\xCE\x6C" 29 | "\xFA\xB3\x11\x22\x23\xBD\xD2\x11\xB4\xB7\x00\xA0\xC9\x55\xFC\x6E" 30 | "\xCE\x75\xF8\x7B\x8D\x46\xD1\x11\x8D\x82\x00\x60\x97\xC9\xA2\xB2" 31 | "\xFB\xB3\x11\x22\x23\xBD\xD2\x11\xB4\xB7\x00\xA0\xC9\x55\xFC\x6E" 32 | "\x14\xE6\x8A\x29\x22\x26\x17\x4C\xB9\x35\xDA\xE0\x7E\xE9\x28\x9C" 33 | "\xFC\xB3\x11\x22\x23\xBD\xD2\x11\xB4\xB7\x00\xA0\xC9\x55\xFC\x6E" 34 | "\xCB\xA5\xE6\x14\x72\xC6\x32\x43\x83\x99\xA9\x69\x52\x06\x5B\x5A" 35 | "\x40\x5A\x46\xD1\x79\x5A\x38\x43\xB7\x1B\xE3\x6B\x8F\xD6\xC2\x49" 36 | "\xE6\x09\x96\xA6\x7B\x51\xD2\x11\xB6\xAF\x00\xC0\x4F\xD9\x08\xE9" 37 | "\xA9\x46\x43\x7C\xE0\xEF\xFC\x4B\xB2\x29\x39\x3E\xDE\x41\x5C\x85" 38 | "\x94\x1C\x23\x44\x98\x94\xD1\x49\xA1\x41\x1D\x13\x4E\x45\x70\x54" 39 | "\xDF\x29\xE2\xD6\xDA\x35\xD1\x11\x90\x34\x00\xA0\xC9\x03\x49\xBE" 40 | "\xAD\x3B\x20\x6B\x11\x3F\xE4\x48\xAC\xA8\xD7\x61\x3D\xE2\xCF\xA7" 41 | "\x6D\x49\x5E\xF5\x97\x97\x5D\x4B\x8C\x8B\x60\x4D\xFE\x9B\xFB\x24" 42 | "\x5D\x8B\xF1\x26\x84\x45\xEC\x47\x9F\x5F\x0E\x65\x1F\x04\x52\xC9" 43 | "\x33\x85\x05\x43\x81\x69\xE6\x49\x9B\x74\xAD\x12\xCB\x86\xD5\x8C" 44 | "\x9D\x8C\x17\x31\xe1\x03\x28\x45\xB5\x82\x3D\xF9\xDB\x22\xF5\x03" 45 | "\x11\xD2\xD3\xAB\xBA\xA9\xCF\x11\x8E\xE6\x00\xC0\x0C\x20\x53\x65" 46 | "\x41\x52\xD1\x86\x1D\x31\xD0\x11\xA3\xA4\x00\xA0\xC9\x03\x48\xF6" 47 | "\x00\x57\xFB\x20\x55\x5B\xCF\x11\xA8\xFD\x00\x80\x5F\x5C\x44\x2B" 48 | "\x50\xCD\xC3\xBF\x8F\x61\xCF\x11\x8B\xB2\x00\xAA\x00\xB4\xE2\x20" 49 | "\x00\x2A\xE2\xD6\xDA\x35\xD1\x11\x90\x34\x00\xA0\xC9\x03\x49\xBE" 50 | "\x01\x2A\xE2\xD6\xDA\x35\xD1\x11\x90\x34\x00\xA0\xC9\x03\x49\xBE" 51 | "\x02\x2A\xE2\xD6\xDA\x35\xD1\x11\x90\x34\x00\xA0\xC9\x03\x49\xBE" 52 | "\x20\xDE\xAA\xD9\x17\x7C\x9C\x4F\xBC\x28\x85\x55\xDD\x98\xE2\xA2" 53 | "\x5D\x8B\xF1\x26\x84\x45\xEC\x47\x9F\x5F\x0E\x65\x1F\x04\x52\xC9" 54 | "\x50\x94\xBD\xC6\x7F\x86\x07\x49\x83\xA3\xC7\x79\x21\xB7\x33\xAD" 55 | "\x6F\x3C\x2A\xF7\xB4\x6E\xBC\x4E\xB1\x92\x09\xAD\x97\x59\xE8\x28" 56 | "\xEC\x95\x95\x39\x67\x86\x2D\x4E\x8F\xDB\x98\x81\x4C\xE7\x6C\x1E" 57 | "\x0E\xEC\x65\xE1\xED\x19\xD7\x45\xB4\xA7\x25\xCB\xD1\xE2\x8E\x9B" 58 | "\x20\xDC\x90\xD5\xBC\x07\x6C\x43\x9C\xF7\xF3\xBB\xFB\xF1\xA4\xDC" 59 | "\x54\xE5\x1E\x1B\xEA\xF9\xC8\x4B\x82\x1A\x37\x6B\x74\xE4\xC4\xB8" 60 | "\x4E\xB8\x98\x66\xFA\x0A\x30\x43\xAE\xB2\x1C\x0A\x98\xD7\xA4\x4D" 61 | "\x91\x65\x37\x76\x5F\x79\xA1\x4D\x86\xED\x9D\x46\xEC\xA1\x09\x49" 62 | "\xCC\x32\x64\xDD\x29\xE2\xDB\x40\x80\xF6\xD2\x63\x28\xD2\x76\x1F" 63 | "\x2A\xC0\x3C\xFD\xDB\x06\xFA\x4C\x80\x1C\x72\x12\xD3\x87\x45\xE4" 64 | "\x01" 65 | "\x02" 66 | "\x07" 67 | "\x08" 68 | "\xff\xff" 69 | "\x00\x02" 70 | "\x02\x00" 71 | "\x00\x01" 72 | "\x01\x00" 73 | "\xff\xff\xff\xff" 74 | "\xff\xff\xff\xff\xff\xff\xff\xff" -------------------------------------------------------------------------------- /Exercise 7/fuzzing_harness.patch: -------------------------------------------------------------------------------- 1 | --- vlc-demux-run_backup.c 2017-11-24 07:29:18.000000000 -0800 2 | +++ vlc-demux-run.c 2021-11-04 19:03:32.966251147 -0700 3 | @@ -31,7 +31,7 @@ 4 | #include <stdio.h> 5 | #include "src/input/demux-run.h" 6 | 7 | -int main(int argc, char *argv[]) 8 | +int main2(int argc, char *argv[]) 9 | { 10 | const char *filename; 11 | struct vlc_run_args args; 12 | @@ -49,3 +49,66 @@ 13 | 14 | return -vlc_demux_process_path(&args, filename); 15 | } 16 | + 17 | +//#include <fstream> 18 | +#include <errno.h> 19 | +#include <stdlib.h> 20 | +#include <fcntl.h> 21 | + 22 | +#include <sys/types.h> 23 | +#include <sys/stat.h> 24 | +#include <unistd.h> 25 | + 26 | +#include <inttypes.h> 27 | + 28 | +int main(int argc, char **argv){ 29 | + 30 | + if (argc != 2) { 31 | + fprintf(stderr, "Usage %s <input file> \n", argv[0]); 32 | + return -1; 33 | + } 34 | + 35 | + struct vlc_run_args args; 36 | + libvlc_instance_t *vlc; 37 | + 38 | + vlc_run_args_init(&args); 39 | + vlc = libvlc_create(&args); 40 | + 41 | + int len; 42 | + unsigned char *buf; 43 | + 44 | + //string filename(argv[1]); 45 | + 46 | +#ifdef __AFL_COMPILER 47 | + 48 | + while (__AFL_LOOP(1000)) { 49 | + 50 | +#endif 51 | + 52 | + int fd = open(argv[1], O_RDONLY); 53 | + 54 | + if(fd < 0){ 55 | + printf("Error opening file \n"); 56 | + printf("Errno: %i\n", errno); 57 | + return -1; 58 | + } 59 | + 60 | + struct stat st; 61 | + stat(argv[1], &st); 62 | + len = st.st_size; 63 | + 64 | + buf = (unsigned char *)malloc(len); 65 | + 66 | + read(fd, buf, len); 67 | + 68 | +// libvlc_demux_process_memory(vlc, &args, buf, len); 69 | + 70 | + vlc_demux_process_memory(&args, buf, len); 71 | + 72 | +#ifdef __AFL_COMPILER 73 | + 74 | + } 75 | + 76 | +#endif 77 | + 78 | +} 79 | -------------------------------------------------------------------------------- /Exercise 7/speedup.patch: -------------------------------------------------------------------------------- 1 | --- "libasf (copy).c" 2019-05-23 10:09:46.000000000 -0700 2 | +++ libasf.c 2021-11-04 19:31:01.622973586 -0700 3 | @@ -1368,6 +1368,7 @@ 4 | p_mk->i_reserved2 = ASF_READ2(); 5 | p_mk->name = ASF_READS( ASF_READ2() ); 6 | 7 | + if( p_mk->i_count > 1000000 ) p_mk->i_count = 0; //modified 8 | if( p_mk->i_count > 0 ) 9 | { 10 | p_mk->marker = calloc( p_mk->i_count, 11 | -------------------------------------------------------------------------------- /Exercise 8/Images/0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 8/Images/0.png -------------------------------------------------------------------------------- /Exercise 8/Images/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 8/Images/10.png -------------------------------------------------------------------------------- /Exercise 8/Images/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 8/Images/11.png -------------------------------------------------------------------------------- /Exercise 8/Images/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 8/Images/4.png -------------------------------------------------------------------------------- /Exercise 8/Images/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 8/Images/5.png -------------------------------------------------------------------------------- /Exercise 8/Images/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 8/Images/6.png -------------------------------------------------------------------------------- /Exercise 8/Images/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 8/Images/7.png -------------------------------------------------------------------------------- /Exercise 8/Images/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 8/Images/8.png -------------------------------------------------------------------------------- /Exercise 8/Images/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 8/Images/9.png -------------------------------------------------------------------------------- /Exercise 8/Readme.md: -------------------------------------------------------------------------------- 1 | # Exercise 8 - Adobe Reader 2 | 3 | For this exercise, we will fuzz **Adobe Reader** application. The goal is to find an Out-of-bounds vulnerability in Adobe Reader 9.5.1. 4 | 5 | ## What you will learn 6 | Once you complete this exercise you will know: 7 | - How to use AFL++'s QEMU mode to fuzz closed-source applications 8 | - How to enable persistent mode in QEMU mode 9 | - How to use QASAN, a binary-only sanitizer 10 | 11 | ## Read Before Start 12 | - I suggest you try to **solve the exercise by yourself** without checking the solution. Try as hard as you can, and only if you get stuck, check out the example solution below. 13 | - AFL uses a non-deterministic testing algorithm, so two fuzzing sessions are never the same. That's why I highly recommend **to set a fixed seed (-s 123)**. This way your fuzzing results will be similar to those shown here and that will allow you to follow the exercises more easily. 14 | - If you find a new vulnerability, **please submit a security report** to the project. If you need help or have any doubt about the process, the [GitHub Security Lab](mailto:securitylab.github.com) can help you with it :) 15 | 16 | ## Contact 17 | Are you stuck and looking for help? Do you have suggestions for making this course better or just positive feedback so that we create more fuzzing content? 18 | Do you want to share your fuzzing experience with the community? 19 | Join the GitHub Security Lab Slack and head to the `#fuzzing` channel. [Request an invite to the GitHub Security Lab Slack](mailto:securitylab-social@github.com?subject=Request%20an%20invite%20to%20the%20GitHub%20Security%20Lab%20Slack) 20 | 21 | ## Environment 22 | 23 | All the exercises have been tested on **Ubuntu 20.04.2 LTS**. I highly recommend you to use **the same OS version** to avoid different fuzzing results and to run AFL++ **on bare-metal** hardware, and not virtualized machines, for best performance. 24 | 25 | Otherwise, you can find an Ubuntu 20.04.2 LTS VMware image [here](https://drive.google.com/file/d/1_m1x-SHcm7Muov2mlmbbt8nkrMYp0Q3K/view?usp=sharing). You can also use VirtualBox instead of VMware. 26 | 27 | The username / password for this VM are `fuzz` / `fuzz`. 28 | 29 | ## Do it yourself! 30 | In order to complete this exercise, you need to: 31 | 1) Create a seed corpus of PDF samples 32 | 2) Enable persistent mode 33 | 3) Fuzz Adobe Reader using QEMU mode until you have some crashes 34 | 4) Triage the crashes to find a PoC for the vulnerability 35 | 36 | 37 | **Estimated time = 8 hours** 38 | 39 | --------------------------------------------------------------------------------------------------------------------------------------------------- 40 | 41 | <details> 42 | <summary>SPOILER ALERT! : Solution inside</summary> 43 | 44 | ### AFL++'s QEMU installation 45 | 46 | First of all, we need afl-qemu installed in our system. You can check it with the following command: 47 | 48 | ``` 49 | afl-qemu-trace --help 50 | ``` 51 | 52 | and you should see something like that: 53 | 54 |  55 | 56 | If it's not already installed, you can build and install it with: 57 | 58 | ``` 59 | sudo apt install ninja-build libc6-dev-i386 60 | cd ~/Downloads/AFLplusplus/qemu_mode/ 61 | CPU_TARGET=i386 ./build_qemu_support.sh 62 | make distrib 63 | sudo make install 64 | ``` 65 | 66 | where ``/Downloads/AFLplusplus/`` is the [AFL++ root folder](../Exercise%201#install-afl) 67 | 68 | ### Adobe Reader installation 69 | 70 | Install dependencies: 71 | ``` 72 | sudo apt-get install libxml2:i386 73 | ``` 74 | 75 | Download and uncompress ``AdbeRdr9.5.1-1_i386linux_enu.deb``: 76 | 77 | ``` 78 | wget ftp://ftp.adobe.com/pub/adobe/reader/unix/9.x/9.5.1/enu/AdbeRdr9.5.1-1_i386linux_enu.deb 79 | ``` 80 | 81 | Now, we can install it with: 82 | 83 | ``` 84 | sudo dpkg -i AdbeRdr9.5.1-1_i386linux_enu.deb 85 | ``` 86 | 87 | Then just type: 88 | 89 | ``` 90 | ./opt/Adobe/Reader9/bin/acroread 91 | ``` 92 | 93 | Accept the License Agreement and you should see the Adobe Reader interface: 94 | 95 |  96 | 97 | If you type 98 | 99 | ``` 100 | /opt/Adobe/Reader9/bin/acroread -help 101 | ``` 102 | 103 | you can also see the list of available command line options 104 | 105 | ### Seed corpus creation 106 | 107 | For this exercise, I'll make use of a corpus downloaded from **SafeDocs "Issue Tracker" Corpus**. You can find more information about this PDF Corpus [here](https://www.pdfa.org/a-new-stressful-pdf-corpus/). 108 | 109 | Download and uncompress the corpus: 110 | ``` 111 | wget https://corpora.tika.apache.org/base/packaged/pdfs/archive/pdfs_202002/libre_office.zip 112 | unzip libre_office.zip -d extracted 113 | ``` 114 | 115 | Now, we will copy only files **smaller than 2 kB**, to speedup the fuzzing process: 116 | ``` 117 | mkdir -p $HOME/fuzzing_adobe/afl_in 118 | find ./extracted -type f -size -2k \ 119 | -exec cp {} $HOME/fuzzing_adobe/afl_in \; 120 | ``` 121 | 122 | 123 | ### First approach 124 | 125 | The simplest way to fuzz closed-source applications is just running afl-fuzz with the **-Q argument**. 126 | 127 | You need to take care when you run afl-fuzz, because ``/opt/Adobe/Reader9/bin/acroread`` is a shell-script. The real binary path is the following one ``/opt/Adobe/Reader9/Reader/intellinux/bin/acroread``. 128 | 129 | But if you try to execute it you will get an error like this: ``acroread must be executed from the startup script``. That's why we need to set the ``ACRO_INSTALL_DIR`` and ``ACRO_CONFIG`` envvars. We will also set ``LD_LIBRARY_PATH`` to define the directory in which to search for dynamically linkable libraries. 130 | 131 | Said that, you can run the fuzzer with the following command: 132 | ``` 133 | ACRO_INSTALL_DIR=/opt/Adobe/Reader9/Reader ACRO_CONFIG=intellinux LD_LIBRARY_PATH=$LD_LIBRARY_PATH:'/opt/Adobe/Reader9/Reader/intellinux/lib' afl-fuzz -Q -i ./afl_in/ -o ./afl_out/ -t 2000 -- /opt/Adobe/Reader9/Reader/intellinux/bin/acroread -toPostScript @@ 134 | ``` 135 | 136 | And you should see AFL++ running: 137 | 138 |  139 | 140 | Now, though, the fuzzing speed is really slow: around 7 exec/s on my machine. So, how can we improve the fuzzing speed? 141 | 142 | And the answer is... using Persistent fuzzing! 143 | 144 | ### Persistent approach 145 | 146 | As we see in [exercise 6](../Exercise%206), inserting the ``AFL_LOOP`` is the way that we have to tell AFL++ that we want to enable the persistent mode. In this case, however, we don't have access to the source code. 147 | 148 | We can instead make use of the AFL_QEMU_PERSISTENT_ADDR to specify the start of the persistent loop. I advise you to set this address to the beginning of a function. You can find more information about AFL_QEMU persistent options [here](https://github.com/AFLplusplus/AFLplusplus/blob/stable/qemu_mode/README.persistent.md). 149 | 150 | For finding an appropriate offset we can make use of a disassembler like IDA or Ghidra. In my case, I chose the following offset ``0x08546a00``: 151 | 152 |  153 | 154 | There is an easier alternative to use a disassembler: to use **callgrind**. 155 | 156 | First of all, we will install valgrind and kcachegrind with the following command line: 157 | 158 | ``` 159 | sudo apt-get install valgrind 160 | sudo apt-get install kcachegrind 161 | ``` 162 | 163 | Now, we can generate a callgrind report with: 164 | 165 | ``` 166 | ACRO_INSTALL_DIR=/opt/Adobe/Reader9/Reader ACRO_CONFIG=intellinux LD_LIBRARY_PATH=$LD_LIBRARY_PATH:'/opt/Adobe/Reader9/Reader/intellinux/lib' valgrind --tool=callgrind /opt/Adobe/Reader9/Reader/intellinux/bin/acroread -toPostScript [samplePDF] 167 | ``` 168 | 169 | where ``samplePDF`` is the path of a PDF sample. It will generate a ``callgrind.out`` output file in your current folder. Now you can visualize this report running **kachegrind**. Just type: 170 | 171 | ``` 172 | kcachegrind 173 | ``` 174 | 175 | and you should see something like this: 176 | 177 |  178 | 179 | I recommend you to look at the ``count`` field in kcachegrind to identify functions that only get executed 1 time, and to try to achieve a **stability score over 90%** in afl-fuzz. 180 | 181 | We will set also the **AFL_QEMU_PERSISTENT_GPR=1** envvar, that will save the original value of general purpose registers and restore them in each persistent cycle. 182 | 183 | Now, we can run the fuzzer with the following command line 184 | 185 | ``` 186 | AFL_QEMU_PERSISTENT_ADDR=0x085478AC AFL_QEMU_PERSISTENT_GPR=1 ACRO_INSTALL_DIR=/opt/Adobe/Reader9/Reader ACRO_CONFIG=intellinux LD_LIBRARY_PATH=$LD_LIBRARY_PATH:'/opt/Adobe/Reader9/Reader/intellinux/lib' afl-fuzz -Q -i ./afl_in/ -o ./afl_out/ -t 2000 -- /opt/Adobe/Reader9/Reader/intellinux/bin/acroread -toPostScript @@ 187 | ``` 188 | As you can see, it gives a x4 improvement in time of execution. Not bad! 189 | 190 |  191 | 192 | For small projects, this approach might be enough. In a future exercise I will explain a faster approach: **write a custom harness**. 193 | 194 | ### Triage 195 | 196 | In this last step we will try to find a PoC for our OOB read vulnerability. 197 | 198 | Unfortunately, if we feed afl-qemu-trace with the crash file: 199 | 200 | ``` 201 | ACRO_INSTALL_DIR=/opt/Adobe/Reader9/Reader ACRO_CONFIG=intellinux LD_LIBRARY_PATH=$LD_LIBRARY_PATH:'/opt/Adobe/Reader9/Reader/intellinux/lib' /usr/local/bin/afl-qemu-trace -- /opt/Adobe/Reader9/Reader/intellinux/bin/acroread -toPostScript [crashFilePath] 202 | ``` 203 | 204 | (where ``crashFilePath`` is the path of the crash file), all what we can see is a message like this 205 | 206 |  207 | 208 | We can get a more detailes stacktrace using **QASan**. To enable it we only need to set ``AFL_USE_QASAN=1``. You can find more information about QASAN [here](https://github.com/andreafioraldi/qasan). Now we type: 209 | 210 | ``` 211 | AFL_USE_QASAN=1 ACRO_INSTALL_DIR=/opt/Adobe/Reader9/Reader ACRO_CONFIG=intellinux LD_LIBRARY_PATH=$LD_LIBRARY_PATH:'/opt/Adobe/Reader9/Reader/intellinux/lib' /usr/local/bin/afl-qemu-trace -- /opt/Adobe/Reader9/Reader/intellinux/bin/acroread -toPostScript [crashFilePath] 212 | ``` 213 | 214 | and we will get a nicer stacktrace: 215 | 216 |  217 | 218 | </details> 219 | -------------------------------------------------------------------------------- /Exercise 9/Images/Image0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 9/Images/Image0.png -------------------------------------------------------------------------------- /Exercise 9/Images/Image1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 9/Images/Image1.png -------------------------------------------------------------------------------- /Exercise 9/Images/Image2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 9/Images/Image2.png -------------------------------------------------------------------------------- /Exercise 9/Images/Image3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 9/Images/Image3.png -------------------------------------------------------------------------------- /Exercise 9/Images/Image4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 9/Images/Image4.png -------------------------------------------------------------------------------- /Exercise 9/Images/Image5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 9/Images/Image5.png -------------------------------------------------------------------------------- /Exercise 9/Readme.md: -------------------------------------------------------------------------------- 1 | # Exercise 9 - 7-Zip 2 | 3 | For this exercise, we will fuzz **7-Zip** file archiver. The goal is to find a crash/PoC for [**CVE-2016-2334**](https://nvd.nist.gov/vuln/detail/CVE-2016-2334) in 7-Zip 15.05. 4 | 5 | --> Kudos to [icewall](https://github.com/icewall) for such an amazing finding. 6 | 7 | <details> 8 | <summary>For more information about CVE-2016-2334 vulnerability, click me!</summary> 9 | -------------------------------------------------------------------------------------------------------- 10 | 11 | **CVE-2016-2334** is a heap-based buffer overflow that can be triggered via a crafted HFS+ image. 12 | 13 | A heap-based buffer overflow is a type of buffer overflow that occurs in the heap data area, and it's usually related to explicit dynamic memory management (allocation/deallocation with malloc() and free() functions). 14 | 15 | As a result, a remote attacker can exploit this issue to execute arbitrary code within the context of an application using the affected library. 16 | 17 | You can find more information about Heap-based buffer oveflow vulnerabilities at the following link: https://cwe.mitre.org/data/definitions/122.html 18 | 19 | </details> 20 | 21 | 22 | ## What you will learn 23 | Once you complete this exercise you will know: 24 | - How to use WinAFL to fuzz Windows applications 25 | 26 | ## Read Before Start 27 | - I suggest you try to **solve the exercise by yourself** without checking the solution. Try as hard as you can, and only if you get stuck, check out the example solution below. 28 | - AFL uses a non-deterministic testing algorithm, so two fuzzing sessions are never the same. That's why I highly recommend **to set a fixed seed (-s 123)**. This way your fuzzing results will be similar to those shown here and that will allow you to follow the exercises more easily. 29 | - If you find a new vulnerability, **please submit a security report** to the project. If you need help or have any doubt about the process, the [GitHub Security Lab](mailto:securitylab.github.com) can help you with it :) 30 | 31 | ## Contact 32 | Are you stuck and looking for help? Do you have suggestions for making this course better or just positive feedback so that we create more fuzzing content? 33 | Do you want to share your fuzzing experience with the community? 34 | Join the GitHub Security Lab Slack and head to the `#fuzzing` channel. [Request an invite to the GitHub Security Lab Slack](mailto:securitylab-social@github.com?subject=Request%20an%20invite%20to%20the%20GitHub%20Security%20Lab%20Slack) 35 | 36 | ## Environment 37 | 38 | This exercise has been tested on **Windows 10**. I highly recommend you to use **the same OS version** to avoid different fuzzing results 39 | 40 | You can download a free Windows 10 VMware image at the following [link](https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/). You can also use VirtualBox instead of VMware. 41 | 42 |  43 | 44 | The password to the VM is **"Passw0rd!"** 45 | 46 | ## Do it yourself! 47 | In order to complete this exercise, you need to: 48 | 1) Download and build WinAFL (and required dependencies) 49 | 2) Create a seed corpus of HFS+ samples 50 | 3) Optional: Create a fuzzing dictionary for the HFS+ file format 51 | 4) Fuzz 7-Zip until you have a crash 52 | 5) Triage the crash to find a PoC for the vulnerability 53 | 6) Optional: Find a better *target_offset* to speed up the fuzzing process 54 | 55 | **Estimated time = 8 hours** 56 | 57 | --------------------------------------------------------------------------------------------------------------------------------------------------- 58 | 59 | <details> 60 | <summary>SPOILER ALERT! : Solution inside</summary> 61 | 62 | ### Previous steps 63 | 64 | First of all, we need the **Visual Studio compiler** installed in our system. For this exercise, I recommend using Visual Studio 2019. You can find the Visual Studio 2019 Community Edition installer [here](./Resources/vs_community.exe). 65 | 66 | Then we need to select and install the **"Desktop development with C++"** package: 67 | 68 |  69 | 70 | We will also need **DynamoRIO 8.0.0**. We can get DynamoRIO Windows binary package from [here](https://github.com/DynamoRIO/dynamorio/releases/download/release_8.0.0-1/DynamoRIO-Windows-8.0.0-1.zip). 71 | 72 | Then, we need to extract the zip content into the Desktop, as follows: 73 | 74 |  75 | 76 | ### Download and build WinAFL 77 | 78 | Now, we can download WinAFL from the official repository: https://github.com/googleprojectzero/winafl 79 | 80 | After this, open **"Developer Command Prompt for VS2019"** and change the working directory to the WinAFL directory. Then type: 81 | 82 | ``` 83 | mkdir build32 84 | cd build32 85 | cmake -G"Visual Studio 16 2019" -A Win32 .. -DDynamoRIO_DIR=C:\Users\IEUser\Desktop\DynamoRIO-Windows-8.0.0-1\cmake 86 | cmake --build . --config Release 87 | ``` 88 | 89 | where `C:\Users\IEUser\Desktop\DynamoRIO-Windows-8.0.0-1\cmake` is the DynamoRIO path on your own system. 90 | 91 | If all went well, you can now find all the WinAFL binaries in the `winafl-master\build32\bin\Release` folder: 92 | 93 |  94 | 95 | **Be careful! Don't mismatch this folder with the "bin32" folder** 96 | 97 | ### Download 7-Zip 98 | 99 | Now it's time to install 7-Zip 15.05. You can find the installer [here](./Resources/7z1505.exe). 100 | 101 | ### Seed corpus creation 102 | 103 | I recommend you create some HFS+ images to feed your seed corpus. This is a trivial task on a Mac OS. 104 | 105 | In Linux, you can use **hfsprogs** utility. In Windows, you can use **Paragon HFS+** (commercial software with free trial). 106 | 107 | To make life easier, you can find an HFS example file [here](./Resources/example.img). 108 | 109 | **Warning! This is just a starting point, you will need to do some extra work on your own** 110 | 111 | ### Fuzzing time 112 | 113 | The WinAFL command line is a little bit different than AFL++. Let's see a brief explanation of these new options: 114 | - *-coverage_module* : module for which to record coverage. Multiple module flags are supported 115 | - *-target_module* : module which contains the target function to be fuzzed 116 | - *-target_offset* : offset of the method to fuzz from the start of the module 117 | 118 | As we did in [exercise 8](../../main/Exercise%208), we need to find an appopiate function offset from where the fuzzer will loop: 119 | 120 |  121 | 122 | We need the offset of the function from the start of the module. Since the base address is `0x400000`, we will do `0x42F3B3 - 0x400000` and will get `0x02F3B3` as a **target_offset** argument. 123 | 124 | Now, let's check that the target is running correctly under DynamoRIO: 125 | ``` 126 | C:\Users\IEUser\Desktop\DynamoRIO-Windows-8.0.0-1\bin32\drrun.exe -c winafl.dll -debug -target_module 7z.exe -target_offset 0x02F3B3 -fuzz_iterations 10 -nargs 2 -- "C:\Program Files (x86)\7-Zip\7z.exe" l C:\Users\IEUser\Desktop\input\test.img 127 | ``` 128 | 129 | You should see the output corresponding to your target function being run 10 times after which the target executable will exit. 130 | 131 | Finally, we can run the fuzzer with the following command: 132 | ``` 133 | afl-fuzz.exe -i C:\Users\IEUser\Desktop\afl_in -o C:\Users\IEUser\Desktop\afl_out -t 2000 -D C:\Users\IEUser\Desktop\DynamoRIO-Windows-8.0.0-1\bin32 -- -coverage_module 7z.exe -coverage_module 7z.dll -target_module 7z.exe -target_offset 0x02F3B3 -nargs 2 -- "C:\Program Files (x86)\7-Zip\7z.exe" e -y @@ 134 | ``` 135 | 136 | And you should see WinAFL running: 137 | 138 |  139 | 140 | 141 | ### Find a better target_offset 142 | 143 | The last step of the exercise is to find a better target_offset to speed up the fuzzing process. This last part is left as an exercise for the student. 144 | 145 | **Hint**: 7-Zip is open-source. So you can compile it in debug mode and see function names in your debugger ;) 146 | 147 | -------------------------------------------------------------------------------- /Exercise 9/Resources/7z1505.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 9/Resources/7z1505.exe -------------------------------------------------------------------------------- /Exercise 9/Resources/example.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 9/Resources/example.img -------------------------------------------------------------------------------- /Exercise 9/Resources/vs_community.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Exercise 9/Resources/vs_community.exe -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # Fuzzing-101 2 | 3 | Do you want to learn how to fuzz like a real expert, but don't know how to start? 4 | 5 | If so, this is the course for you! 6 | 7 | **10 real targets, 10 exercises.** Are you able to solve all 10? 8 | 9 | ## Structure 10 | 11 | | Exercise No. | Target | CVEs to find | Time estimated | Main topics | 12 | | ------------- | ------------- | ------------- | ------------- | ------------- | 13 | | [Exercise 1](https://github.com/antonio-morales/Fuzzing101/tree/main/Exercise%201) | Xpdf | CVE-2019-13288 | 120 mins | Afl-clang-fast, Afl-fuzz, GDB | 14 | | [Exercise 2](https://github.com/antonio-morales/Fuzzing101/tree/main/Exercise%202) | libexif | CVE-2009-3895, CVE-2012-2836 | 6 hours | Afl-clang-lto, Fuzz libraries, Eclipse IDE| 15 | | [Exercise 3](https://github.com/antonio-morales/Fuzzing101/tree/main/Exercise%203) | TCPdump | CVE-2017-13028 | 4 hours | ASan, Sanitizers | 16 | | [Exercise 4](https://github.com/antonio-morales/Fuzzing101/tree/main/Exercise%204) | LibTIFF | CVE-2016-9297 | 3 hours | Code coverage, LCOV | 17 | | [Exercise 5](https://github.com/antonio-morales/Fuzzing101/tree/main/Exercise%205) | Libxml2 | CVE-2017-9048 | 3 hours | Dictionaries, Basic parallelization, Fuzzing command-line arguments | 18 | | [Exercise 6](https://github.com/antonio-morales/Fuzzing101/tree/main/Exercise%206) | GIMP | CVE-2016-4994, Bonus bugs | 7 hours | Persistent fuzzing, Fuzzing interactive applications| 19 | | [Exercise 7](https://github.com/antonio-morales/Fuzzing101/tree/main/Exercise%207) | VLC media player | CVE-2019-14776 | 6 hours | Partial instrumentation, Fuzzing harness | 20 | | [Exercise 8](https://github.com/antonio-morales/Fuzzing101/tree/main/Exercise%208) | Adobe Reader | | 8 hours | Fuzzing closed-source applications, QEMU instrumentation| 21 | | [Exercise 9](https://github.com/antonio-morales/Fuzzing101/tree/main/Exercise%209) | 7-Zip | CVE-2016-2334 | 8 hours | WinAFL, Fuzzing Windows Applications| 22 | | [**Exercise 10 (Final Challenge)**](https://github.com/antonio-morales/Fuzzing101/tree/main/Exercise%2010) | **Google Chrome / V8** | **CVE-2019-5847** | **8 hours** | **Fuzzilli, Fuzzing Javascript engines** | 23 | 24 | ## Changelog 25 | 26 | - 02/14/2022: Fixed some 'wget' typos in Exercise 5 27 | - 11/25/2021: Exercise 3 updated with some fixes. 28 | 29 | 30 | ## Who is the course intended for? 31 | - Anyone wishing to learn fuzzing basics 32 | - Anyone who wants to learn how to find vulnerabilities in real software projects. 33 | 34 | ## Requirements 35 | - All you need for this course is a running Linux system with an internet connection. You will find a suitable VMware image in the exercises. 36 | - At least basic Linux skills are highly recommended. 37 | - All the exercises have been tested on Ubuntu **20.04.2 LTS**. You can download it from [here](https://ubuntu.com/download/desktop/thank-you?version=20.04.2.0&architecture=amd64) 38 | - In this course we're going to use [AFL++](https://github.com/AFLplusplus/AFLplusplus), a newer and superior fork of Michał "lcamtuf" Zalewski's AFL, for solving the fuzzing exercises. 39 | 40 | ## What is fuzzing? 41 | 42 | **Fuzz testing (or fuzzing)** is an automated software testing technique that is based on feeding the program with random/mutated input values and monitoring it for exceptions/crashes. 43 | 44 | [AFL](https://github.com/google/AFL), [libFuzzer](https://llvm.org/docs/LibFuzzer.html) and [HonggFuzz](https://github.com/google/honggfuzz) are three of the most successful fuzzers when it comes to real world applications. All three are examples of **Coverage-guided evolutionary** fuzzers. 45 | 46 | ### Coverage-guided evolutionary fuzzer 47 | 48 | - **Evolutionary**: is a metaheuristic approach inspired by evolutionary algorithms, which basically consists in the evolution and mutation of the initial subset (seeds) over time, by using a selection criteria (ex. coverage). 49 | 50 | - **Coverage-guided**: To increase the chance of finding new crashes, coverage-guided fuzzers gather and compare code coverage data between different inputs (usually through instrumentation) and pick those inputs which lead to new execution paths. 51 | 52 | 53 | <img src="./Diagram.png"> 54 | 55 | <p align="center"> 56 | Simplification of the coverage gathering process of a coverage-guided evolutionary fuzzer 57 | </p> 58 | 59 | ## Thanks 60 | 61 | Thanks for their help: 62 | - [Xavier RENE-CORAIL](https://github.com/xcorail) 63 | - [Alan Vivona](https://github.com/alanvivona) 64 | - [Jason White](https://github.com/misfir3) 65 | - [Octavio Gianatiempo](https://github.com/ogianatiempo) 66 | - [van Hauser](https://github.com/vanhauser-thc) 67 | - [Marc Poulhiès](https://github.com/dkm) 68 | - [Xu Hanyu](https://github.com/Mundi-Xu) 69 | - [tclan126](https://github.com/tclan126) 70 | - [epi052](https://github.com/epi052) 71 | - [Jeremias Gomes](https://github.com/j3r3mias) 72 | 73 | ## Contact 74 | 75 | Are you stuck and looking for help? Do you have suggestions for making this course better or just positive feedback so that we can create more fuzzing content? 76 | Do you want to share your fuzzing experience with the community? 77 | Join the GitHub Security Lab Slack and head to the `#fuzzing` channel. [Request an invite to the GitHub Security Lab Slack](mailto:securitylab-social@github.com?subject=Request%20an%20invite%20to%20the%20GitHub%20Security%20Lab%20Slack) 78 | 79 | -------------------------------------------------------------------------------- /Resources/SecurityLab.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonio-morales/Fuzzing101/d569cf42f62cd3af289736e4cc7c72484025a73f/Resources/SecurityLab.webp --------------------------------------------------------------------------------