1# Summary 2 3This directory contains a couple NFC fuzzers targeting different part of the 4NFC code. Due to the complexity of NFC codebase, it's not easy to directly 5fuzzing an E2E NFC scenario. Instead, it's much easier to simply target a 6specific function which does the packet parsing, and link only related code 7with some external dependencies stubbed out. That's how these fuzzers are 8created. 9 10 11* nci: 12NCI packet parsing code -- vulnerabilites found in this fuzzer usually require 13NFC firmware compromise. 14 15* rw: 16NFC tag Read/Write code -- vulnerabilities found here are possibly reachable by 17an attacker countrolled NFC tag or tag emulator. 18 19* ce: 20NFC tag emulation code -- vulnerabilities found here are possibly reachable by 21an attacker controlled NFC tag reader. 22 23 24# Running fuzzers 25 26Here are the steps to run these fuzzers locally. These steps are verified with 27an engineering Android device, and my linux workstation with all the necessary 28tools installed: 29 301. Getting an Android device capable of HWASAN 31 32 I've been using Pixel 3 (Blueline) and it works great. So we will use 33 "blueline" for the rest of the steps. If you are using a different device, 34 you need to adjust the command accordingly. 35 362. Preparing the device: 37 38 You need to flash the device with a HWASAN userdebug build. For a blueline 39 device, it will be "blueline_hwasan-userdebug". After that, make sure the 40 device connects to your workstation and adb root access is enabled. 41 423. Preparing build environment: 43 44 All the fuzzers in this change need to be built with "hwasan userdebug" 45 configuration. For the blueline device, that will be the 46 "blueline_hwasan-userdebug" option from lunch menu. All the commands from 47 the rest steps need to run from this environment. 48 494. `fuzz.sh` helper script: 50 51 There are quite a lot setups required to build and run the fuzzer. To make 52 it easier, a `fuzz.sh` helper script is included. It needs to be run with 53 current working directory set to the fuzzer directory. You can also source 54 it and then use the "fuzz" function defined in it. 55 565. Building the fuzzer: 57 58 Here we use "nci" fuzzer as an example for building and running. The same 59 steps apply to the other two fuzzers. 60 61 Run the following commands to build the fuzzer: 62 63 cd $ANDROID_BUILD_TOP/system/nfc/src/fuzzers/nci 64 ../fuzz.sh build 65 66 The above commands will build the nci fuzzer and push it to the device. 67 686. Running the fuzzer: 69 70 To run the fuzzer for a single iteration, assuming you are at the fuzzer 71 directory ($ANDROID_BUILD_TOP/system/nfc/src/fuzzers/nci), all you need is 72 this command: 73 74 ../fuzz.sh run --once 75 76 This will run the fuzzer and stop when a crash is found. The crash log will 77 be printed on console directly. 78 79 To run the fuzzer repeatedly, simply use the same command but without 80 "--once" option. It will keep the fuzzer running, and do the following 81 processfor every time a crash is found: 82 83 1. Collecting the binary input causing the crash 84 2. Re-running the fuzzer with this input to verify the crash reproduces 85 3. Parsing the crash log to find out the crashing source location 86 4. Archiving all the logs into a directory named by the crashing function 87 5. Collecting code goverage data 88 89 By default "fuzz run" will continue with whatever left last time. However, 90 you can make it a fresh restart by passing a "-c" argument. 91 927. Other tools provided by `fuzz.sh`: 93 94 Here are some extra options provided by `fuzz.sh` script: 95 * "fuzz gcov" pulls the coverage data from device, and generate a 96 visualization of accumulated code coverage. 97 * "fuzz gdb" setup gdb instance with the fuzz input so you can debug a 98 specific crash. 99 100