| 1 | {{{ |
| 2 | #!html |
| 3 | <div style="text-align: center"> |
| 4 | }}} |
| 5 | Prev: [wiki:zzuf/tutorial1 1. Basic zzuf usage] | Next: [wiki:zzuf zzuf home] |
| 6 | {{{ |
| 7 | #!html |
| 8 | </div> |
| 9 | }}} |
| 10 | |
| 11 | = 2. `zzuf` as a batch testing tool = |
| 12 | |
| 13 | The most useful aspect of `zzuf` is its use as an automated tool, testing thousands of different fuzzing combinations and analysing the fuzzed application’s behaviour in each situation. |
| 14 | |
| 15 | == 2.1. Debug mode == |
| 16 | |
| 17 | Consider this invocation of `zzuf` with the `file` utility: |
| 18 | |
| 19 | {{{ |
| 20 | % zzuf file /bin/ls |
| 21 | /etc/magic, 4: Warning: using regular magic file `/usr/share/file/magic' |
| 22 | /usr/share/file/magic, 33: Warning: Printf format `d' is not valid for type `string' in description `RISC OS outline font data,>5 byte x varsion %d' |
| 23 | /usr/share/file/magic, 47: Warning: type `stri?g \x02\x01\x13\x13\x13\x01\x0d\x10 Digital Symphony sound sample (RISC OS),' invalid |
| 24 | [...] |
| 25 | }}} |
| 26 | |
| 27 | This is not the expected behaviour at all. What happens exactly? The problem is that `file` also opens its own configuration files to gather information about file formats, and of course `zzuf` fuzzes these files, since no one told it that they were special. |
| 28 | |
| 29 | We may run `zzuf` in '''debug mode''' to learn more about what happens, using the '''`-d` flag''': |
| 30 | |
| 31 | {{{ |
| 32 | % zzuf -d file /bin/ls |
| 33 | ** zzuf debug ** libzzuf initialised for PID 29526 |
| 34 | ** zzuf debug ** fopen("/etc/magic", "r") = [3] |
| 35 | ** zzuf debug ** fgets(0x7fffc46e04b0, 8192, [3]) = 0x7fffc46e04b0 |
| 36 | ** zzuf debug ** fgets(0x7fffc46e04b0, 8192, [3]) = 0x7fffc46e04b0 |
| 37 | ** zzuf debug ** fgets(0x7fffc46e04b0, 8192, [3]) = 0x7fffc46e04b0 |
| 38 | ** zzuf debug ** fgets(0x7fffc46e04b0, 8192, [3]) = NULL |
| 39 | ** zzuf debug ** fclose([3]) = 0 |
| 40 | ** zzuf debug ** open("/usr/share/file/magic.mgc", 0) = 3 |
| 41 | ** zzuf debug ** mmap(NULL, 1636608, 3, 2, 3, 0) = 0x2acce776e000 "\x1c\x04\x1c\xf1... |
| 42 | ** zzuf debug ** close(3) = 0 |
| 43 | ** zzuf debug ** fopen("/usr/share/file/magic", "r") = [3] |
| 44 | ** zzuf debug ** fgets(0x7fffc46e04b0, 8192, [3]) = 0x7fffc46e04b0 |
| 45 | ** zzuf debug ** fgets(0x7fffc46e04b0, 8192, [3]) = 0x7fffc46e04b0 |
| 46 | ** zzuf debug ** fgets(0x7fffc46e04b0, 8192, [3]) = 0x7fffc46e04b0 |
| 47 | [...] |
| 48 | }}} |
| 49 | |
| 50 | We see that `file` opens at least `/etc/magic`, `/usr/share/file/magic.mgc` and `/usr/share/file/magic`. Since they are installed in trusted directories, it is useless to fuzz these files, unless of course we wish to test `file`’s robustness against corruption of these files. |
| 51 | |
| 52 | == 2.2. Include and exclude patterns == |
| 53 | |
| 54 | One way to make `zzuf` ignore files is to '''exclude''' them, using the '''`-E` flag''' as many times as necessary. This flag specifies that files matching a given regular expression should not be fuzzed: |
| 55 | |
| 56 | {{{ |
| 57 | % zzuf -d -E /etc/ -E /usr/share/ file /bin/ls |
| 58 | ** zzuf debug ** libzzuf initialised for PID 30541 |
| 59 | ** zzuf debug ** open("/bin/ls", 0) = 3 |
| 60 | ** zzuf debug ** read(3, 0x60a590, 98304) = 98304 "\x7fENF... |
| 61 | ** zzuf debug ** close(3) = 0 |
| 62 | /bin/ls: data |
| 63 | % |
| 64 | }}} |
| 65 | |
| 66 | Another way to avoid the issue is to only '''include''' the files or directories we want to fuzz, using the '''`-I` flag''' as many times as necessary: |
| 67 | |
| 68 | {{{ |
| 69 | % zzuf -d -I /bin/ file /bin/ls |
| 70 | ** zzuf debug ** libzzuf initialised for PID 30550 |
| 71 | ** zzuf debug ** open("/bin/ls", 0) = 3 |
| 72 | ** zzuf debug ** read(3, 0x606c20, 98304) = 98304 "\x7fENF... |
| 73 | ** zzuf debug ** close(3) = 0 |
| 74 | /bin/ls: data |
| 75 | % |
| 76 | }}} |
| 77 | |
| 78 | Yet another way is to tell `zzuf` to only fuzz files that appear on the fuzzed application’s commandline, using the '''`-c` flag''': |
| 79 | |
| 80 | {{{ |
| 81 | % zzuf -d -c file /bin/ls |
| 82 | ** zzuf debug ** libzzuf initialised for PID 30555 |
| 83 | ** zzuf debug ** open("/bin/ls", 0) = 3 |
| 84 | ** zzuf debug ** read(3, 0x608de0, 98304) = 98304 "\x7fENF... |
| 85 | ** zzuf debug ** close(3) = 0 |
| 86 | /bin/ls: data |
| 87 | % |
| 88 | }}} |
| 89 | |
| 90 | We can now properly fuzz the `file` application. |
| 91 | |
| 92 | == 2.3. Seed ranges == |
| 93 | |
| 94 | Instead of specifying a random seed with the `-s` flag, one can specify a whole range by separating values with a colon. `zzuf` will simply run the program several times, each time with another seed in the range: |
| 95 | |
| 96 | {{{ |
| 97 | % zzuf -c -s 0:5 file /bin/ls |
| 98 | /bin/ls: data |
| 99 | /bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped |
| 100 | /bin/ls: ELF 64-bit LSB executable, x86-64, (SYSV), statically linked (uses shared libs), stripped |
| 101 | /bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), for GNU/Linux 2.6.8388616, statically linked (uses shared libs), corrupted section header size |
| 102 | /bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked (uses shared libs), stripped |
| 103 | % |
| 104 | }}} |
| 105 | |
| 106 | As can be seen, the file analysed by `file` is slightly corrupted in a different way each time. |
| 107 | |
| 108 | Using the '''`-v` flag''' for more verbosity helps understanding what is going on, especially with large seed ranges: |
| 109 | |
| 110 | {{{ |
| 111 | % zzuf -vc -s 0:5 file /bin/ls |
| 112 | zzuf[s=0,r=0.004]: launched `file' |
| 113 | /bin/ls: data |
| 114 | zzuf[s=1,r=0.004]: launched `file' |
| 115 | /bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped |
| 116 | zzuf[s=2,r=0.004]: launched `file' |
| 117 | /bin/ls: ELF 64-bit LSB executable, x86-64, (SYSV), statically linked (uses shared libs), stripped |
| 118 | zzuf[s=3,r=0.004]: launched `file' |
| 119 | /bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), for GNU/Linux 2.6.8388616, statically linked (uses shared libs), corrupted section header size |
| 120 | zzuf[s=4,r=0.004]: launched `file' |
| 121 | /bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked (uses shared libs), stripped |
| 122 | % |
| 123 | }}} |
| 124 | |
| 125 | == 2.4. Ratio ranges == |
| 126 | |
| 127 | When a seed range is being used with `-s`, a ratio range can be used with `-r`. Instead of using the same bit fuzzing ratio for each seed, `zzuf` will pick one at random within the specified interval: |
| 128 | |
| 129 | {{{ |
| 130 | % zzuf -vc -s 0:5 -r 0.0001:0.01 file /bin/ls |
| 131 | zzuf[s=0,r=0.0001:0.01]: launched `file' |
| 132 | /bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), for GNU/Linux 2.6.8, dynamically linked (uses shared libs), stripped |
| 133 | zzuf[s=1,r=0.0001:0.01]: launched `file' |
| 134 | /bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked (uses shared libs), stripped |
| 135 | zzuf[s=2,r=0.0001:0.01]: launched `file' |
| 136 | /bin/ls: ERROR: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), for GNU/Linux 2.6.8, dynamically linked (uses shared libs)error reading |
| 137 | zzuf[s=3,r=0.0001:0.01]: launched `file' |
| 138 | /bin/ls: ERROR: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linkedCannot allocate memory for note (Cannot allocate memory) |
| 139 | zzuf[s=4,r=0.0001:0.01]: launched `file' |
| 140 | /bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped |
| 141 | % |
| 142 | }}} |
| 143 | |
| 144 | To generate a file that reproduces a given behaviour, the corresponding `-s` flag and the exact same `-r` flag need to be used: |
| 145 | |
| 146 | {{{ |
| 147 | % zzuf -s 4 -r 0.0001:0.01 < /bin/ls > output.file |
| 148 | % file output.file |
| 149 | output.file: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped |
| 150 | % |
| 151 | }}} |
| 152 | |
| 153 | {{{ |
| 154 | #!html |
| 155 | <div style="text-align: center"> |
| 156 | }}} |
| 157 | Prev: [wiki:zzuf/tutorial1 1. Basic zzuf usage] | Next: [wiki:zzuf zzuf home] |
| 158 | {{{ |
| 159 | #!html |
| 160 | </div> |
| 161 | }}} |