1 00:00:06,400 --> 00:00:08,220 - So your strategy when you're fuzzing, 2 00:00:08,220 --> 00:00:09,900 if you don't know a whole lot 3 00:00:09,900 --> 00:00:12,000 about the target that you're fuzzing, 4 00:00:12,000 --> 00:00:15,000 don't wait until you have a complete suite of tests 5 00:00:15,000 --> 00:00:15,900 with the fuzzer. 6 00:00:15,900 --> 00:00:16,820 Always fuzz. 7 00:00:16,820 --> 00:00:19,010 That's my recommendation to you, 8 00:00:19,010 --> 00:00:23,340 is that fuzzing takes a long time. 9 00:00:23,340 --> 00:00:25,050 And so you really don't want to be waiting 10 00:00:25,050 --> 00:00:27,340 until the very end when you have a collection of tests. 11 00:00:27,340 --> 00:00:28,700 Just start fuzzing. 12 00:00:28,700 --> 00:00:31,690 And it could just be a simple mutational fuzzer. 13 00:00:31,690 --> 00:00:33,740 In some cases you're doing an evolutionary fuzzer 14 00:00:33,740 --> 00:00:35,730 you can set up something really quickly. 15 00:00:35,730 --> 00:00:38,540 So fuzzing could take really a long time. 16 00:00:38,540 --> 00:00:41,050 If you want it to be complete, it can take weeks. 17 00:00:41,050 --> 00:00:44,080 And so if you can, try to fuzz in parallel 18 00:00:44,080 --> 00:00:45,870 If you know a target, 19 00:00:45,870 --> 00:00:49,060 if you know the version of software that's being run, 20 00:00:49,060 --> 00:00:51,640 run as many instances of that as you can. 21 00:00:51,640 --> 00:00:53,210 You can even run them in a cloud 22 00:00:53,210 --> 00:00:56,220 like in Amazon Web Services or Azure. 23 00:00:56,220 --> 00:00:57,880 Just have multiple instances of it, 24 00:00:57,880 --> 00:00:59,910 and you're fuzzing at the same time. 25 00:00:59,910 --> 00:01:02,300 Maybe starting from a different test case. 26 00:01:02,300 --> 00:01:04,520 And that way you finish things a lot faster, 27 00:01:04,520 --> 00:01:06,360 and you can get better results. 28 00:01:06,360 --> 00:01:08,550 So when you're looking for fuzzing, 29 00:01:08,550 --> 00:01:10,040 you're looking for code coverage. 30 00:01:10,040 --> 00:01:12,080 In other words, your one exercise as much 31 00:01:12,080 --> 00:01:16,360 of the program's parser and code that's based on the parser. 32 00:01:16,360 --> 00:01:17,980 You know, information that comes from the parser 33 00:01:17,980 --> 00:01:20,570 you want to execute as much of that as possible. 34 00:01:20,570 --> 00:01:22,330 So you can get as much coverage. 35 00:01:22,330 --> 00:01:24,630 Some of the basic fuzzers that you're doing, 36 00:01:24,630 --> 00:01:26,600 where they're like mutational fuzzers, 37 00:01:26,600 --> 00:01:28,490 they really only find results for bugs 38 00:01:28,490 --> 00:01:29,710 that are what are called shallow. 39 00:01:29,710 --> 00:01:32,090 In other words, you're not going very far 40 00:01:32,090 --> 00:01:33,700 into the parser itself. 41 00:01:33,700 --> 00:01:35,600 You're doing maybe just a little bit of things 42 00:01:35,600 --> 00:01:37,000 on the outside. 43 00:01:37,000 --> 00:01:39,160 And really to get any further than that, 44 00:01:39,160 --> 00:01:42,010 you either need to do the generational fuzzer, 45 00:01:42,010 --> 00:01:43,030 where you have information 46 00:01:43,030 --> 00:01:45,350 about how the protocol is supposed to work. 47 00:01:45,350 --> 00:01:46,910 Or the evolutionary fuzzers, 48 00:01:46,910 --> 00:01:48,680 which actually monitor the program 49 00:01:48,680 --> 00:01:52,250 so that you can get more deep into the program. 50 00:01:52,250 --> 00:01:55,210 And so that's what you need to have a complex 51 00:01:55,210 --> 00:01:57,160 and sometimes, even a custom written fuzzer. 52 00:01:57,160 --> 00:01:59,110 So, in other words, you're writing everything 53 00:01:59,110 --> 00:02:01,230 either from scratch or you're using some kind 54 00:02:01,230 --> 00:02:02,720 of fuzzing framework. 55 00:02:02,720 --> 00:02:05,360 And I'll go through some of those a little later on. 56 00:02:05,360 --> 00:02:08,450 And there are certain kinds of vulnerabilities and bugs 57 00:02:08,450 --> 00:02:10,353 that you will not find with fuzzing. 58 00:02:11,420 --> 00:02:14,290 This is an example, there are some vulnerabilities 59 00:02:14,290 --> 00:02:15,830 that will not crash a program, you know, 60 00:02:15,830 --> 00:02:18,290 because they're just basically a logic error. 61 00:02:18,290 --> 00:02:21,910 Or they allow you some additional access to do things 62 00:02:21,910 --> 00:02:25,300 that you shouldn't be doing, like injecting a command. 63 00:02:25,300 --> 00:02:27,310 That's a very common vulnerability, 64 00:02:27,310 --> 00:02:28,870 especially on network equipment, 65 00:02:28,870 --> 00:02:30,970 is a command injection vulnerability. 66 00:02:30,970 --> 00:02:33,540 And what that means is that normally you would 67 00:02:33,540 --> 00:02:36,030 issue a command on the command line interface 68 00:02:36,030 --> 00:02:40,160 and it would run some program on, in the operating system. 69 00:02:40,160 --> 00:02:42,390 And then you may be able to tack on something. 70 00:02:42,390 --> 00:02:43,820 Like if you do a semicolon 71 00:02:43,820 --> 00:02:46,930 you can maybe tack on like a shell command to that 72 00:02:46,930 --> 00:02:49,340 and be able to do things like, you know, 73 00:02:49,340 --> 00:02:51,810 executing a Netcat and calling home to you, 74 00:02:51,810 --> 00:02:53,530 and then getting that, a shell. 75 00:02:53,530 --> 00:02:55,820 Another thing you can do is maybe directory traversal. 76 00:02:55,820 --> 00:02:57,530 So you can access part of the file system 77 00:02:57,530 --> 00:02:59,670 that you shouldn't be able to access. 78 00:02:59,670 --> 00:03:02,230 These are things that fuzzing will not uncover, 79 00:03:02,230 --> 00:03:05,450 because they do not cause the program to crash, 80 00:03:05,450 --> 00:03:07,340 and there's really no way of knowing, you know, 81 00:03:07,340 --> 00:03:08,870 what it is that it was looking at. 82 00:03:08,870 --> 00:03:11,210 So in these cases, you may be able to do some kind 83 00:03:11,210 --> 00:03:13,830 of instrumentation and analysis after the fact 84 00:03:13,830 --> 00:03:15,900 to find out what the device is responding with. 85 00:03:15,900 --> 00:03:18,770 But in other cases, you just won't find them. 86 00:03:18,770 --> 00:03:21,500 So here's how you choose what to fuzz. 87 00:03:21,500 --> 00:03:22,750 When I approach a target 88 00:03:22,750 --> 00:03:25,240 and I want to know what I should work on first, 89 00:03:25,240 --> 00:03:27,850 first I want to know what user inputs are used 90 00:03:27,850 --> 00:03:28,683 by the program. 91 00:03:28,683 --> 00:03:30,750 What actual user inputs can I supply, 92 00:03:30,750 --> 00:03:33,400 and which of those are from an untrusted source? 93 00:03:33,400 --> 00:03:34,540 In other words, are they coming 94 00:03:34,540 --> 00:03:37,640 from a session that is already authenticated? 95 00:03:37,640 --> 00:03:39,770 You know, if I'm already logged in with SSH 96 00:03:39,770 --> 00:03:42,120 it may not be as important 97 00:03:42,120 --> 00:03:44,530 if I had actually been able to send this 98 00:03:44,530 --> 00:03:47,360 as a packet over the internet, for instance. 99 00:03:47,360 --> 00:03:49,550 Okay, so if you have those kinds of inputs 100 00:03:49,550 --> 00:03:51,080 that are untrusted, you wanted, 101 00:03:51,080 --> 00:03:54,423 well, you would want to prioritize those above all others. 102 00:03:55,495 --> 00:03:58,338 What features are mature versus immature? 103 00:03:58,338 --> 00:03:59,171 If it's a new feature, 104 00:03:59,171 --> 00:04:01,550 it may have been implemented just recently 105 00:04:01,550 --> 00:04:04,980 and the code may not have been tested as well. 106 00:04:04,980 --> 00:04:07,360 And so if you know a part of the feature, 107 00:04:07,360 --> 00:04:10,040 or you know a feature of the code that is newer, 108 00:04:10,040 --> 00:04:13,470 you may fuzz that first because the code 109 00:04:13,470 --> 00:04:14,870 has not been as well vetted. 110 00:04:16,070 --> 00:04:18,140 And then there are other things that you need to worry 111 00:04:18,140 --> 00:04:19,500 about when you're choosing what to fuzz. 112 00:04:19,500 --> 00:04:20,960 Are there input constraints that, 113 00:04:20,960 --> 00:04:22,890 which the parser checks first? 114 00:04:22,890 --> 00:04:25,750 In other words, does the input have to be null-terminated? 115 00:04:25,750 --> 00:04:26,890 In other words, are they doing something 116 00:04:26,890 --> 00:04:28,640 like we did earlier with a string copy? 117 00:04:28,640 --> 00:04:30,210 Are they using a stir copy? 118 00:04:30,210 --> 00:04:32,130 So the input must be null-terminated, 119 00:04:32,130 --> 00:04:34,290 otherwise it just continues to copy. 120 00:04:34,290 --> 00:04:37,070 You have certain packets and payloads that you need 121 00:04:37,070 --> 00:04:38,765 that have a checksum in them. 122 00:04:38,765 --> 00:04:40,310 And that checksum has to be correct 123 00:04:40,310 --> 00:04:43,500 before it'll ever look any further into the packet. 124 00:04:43,500 --> 00:04:45,160 You need to know that 125 00:04:45,160 --> 00:04:47,470 that checksum has to be fixed up first. 126 00:04:47,470 --> 00:04:50,110 Otherwise, the parser will just see that that's no good 127 00:04:50,110 --> 00:04:51,200 and just throw the packet away. 128 00:04:51,200 --> 00:04:52,290 And the same thing, 129 00:04:52,290 --> 00:04:55,600 if you're doing a secure connection using TLS, 130 00:04:55,600 --> 00:04:58,660 you need to have, maybe you have to have that set up first. 131 00:04:58,660 --> 00:05:01,310 You have to actually have a connection set up first. 132 00:05:01,310 --> 00:05:02,750 The input may have length fields. 133 00:05:02,750 --> 00:05:03,950 It has count fields 134 00:05:03,950 --> 00:05:06,160 and those have to match some kind of payload. 135 00:05:06,160 --> 00:05:08,570 Those are all fix ups that you would have to do 136 00:05:08,570 --> 00:05:10,910 when you're choosing what to fuzz. 137 00:05:10,910 --> 00:05:13,700 And so here is a drawing of program input. 138 00:05:13,700 --> 00:05:15,720 Some of these may be fairly obvious to you, 139 00:05:15,720 --> 00:05:17,650 like maybe a socket that you're listening 140 00:05:17,650 --> 00:05:19,410 on the network for. 141 00:05:19,410 --> 00:05:20,243 And then, there are others 142 00:05:20,243 --> 00:05:22,700 that may not be very obvious to you. 143 00:05:22,700 --> 00:05:23,760 You have environment, 144 00:05:23,760 --> 00:05:26,740 which are values that are stored with the program 145 00:05:26,740 --> 00:05:27,880 when the program executes. 146 00:05:27,880 --> 00:05:31,480 Those can be like the path variable that allows you 147 00:05:31,480 --> 00:05:34,490 to look in the file system for certain programs. 148 00:05:34,490 --> 00:05:36,530 You may be able to modify that environment 149 00:05:36,530 --> 00:05:38,030 before you invoke a program. 150 00:05:38,030 --> 00:05:39,610 You have file systems and files 151 00:05:39,610 --> 00:05:42,040 that are accessible from the application. 152 00:05:42,040 --> 00:05:43,580 Maybe when you're running the application 153 00:05:43,580 --> 00:05:45,260 it has files that it uses 154 00:05:45,260 --> 00:05:46,970 on the file system for doing sockets. 155 00:05:46,970 --> 00:05:49,360 That's called a UNIX domain socket. 156 00:05:49,360 --> 00:05:50,193 You have memory. 157 00:05:50,193 --> 00:05:52,900 So memory could be mapped into an application 158 00:05:52,900 --> 00:05:54,170 from somewhere else. 159 00:05:54,170 --> 00:05:55,980 It could be shared memory based on a file. 160 00:05:55,980 --> 00:05:57,920 So if you write into that file 161 00:05:57,920 --> 00:06:00,410 and that memory is executable, 162 00:06:00,410 --> 00:06:02,630 then you might be able to run things that are directly 163 00:06:02,630 --> 00:06:03,600 in that shared memory. 164 00:06:03,600 --> 00:06:05,220 You have POSIX message queues, 165 00:06:05,220 --> 00:06:07,470 and then you have libraries that are mapped in. 166 00:06:07,470 --> 00:06:09,450 And those libraries can either be libraries 167 00:06:09,450 --> 00:06:11,140 that are on disk, like the libc. 168 00:06:11,140 --> 00:06:12,340 There's also libraries called 169 00:06:12,340 --> 00:06:14,010 the virtual dynamic shared object, 170 00:06:14,010 --> 00:06:17,080 which are libraries that the kernel itself provides 171 00:06:17,080 --> 00:06:18,880 to each process. 172 00:06:18,880 --> 00:06:21,270 If you ever heard of a, an attack recently 173 00:06:21,270 --> 00:06:22,760 called Dirty Cow, 174 00:06:22,760 --> 00:06:25,220 one of the ways to be able to exploit a process 175 00:06:25,220 --> 00:06:28,030 was to overwrite the virtual dynamic shared object. 176 00:06:28,030 --> 00:06:31,380 So that when something got called in there from the kernel, 177 00:06:31,380 --> 00:06:33,340 you're actually calling some attack or code 178 00:06:33,340 --> 00:06:35,960 and you've actually taken the process over. 179 00:06:35,960 --> 00:06:37,280 So this is the fuzzing process. 180 00:06:37,280 --> 00:06:39,700 We're gonna start from the top and work our way down. 181 00:06:39,700 --> 00:06:41,420 So what you'll do first is you'll set 182 00:06:41,420 --> 00:06:43,670 up the test environment so that it's in the state 183 00:06:43,670 --> 00:06:44,630 that you want. 184 00:06:44,630 --> 00:06:46,560 You'll pick a random seed. 185 00:06:46,560 --> 00:06:48,520 Typically, when you're doing some kind of fuzzing 186 00:06:48,520 --> 00:06:50,230 you'll have a random number generator 187 00:06:50,230 --> 00:06:53,000 that will determine what inputs you actually fuzz 188 00:06:53,000 --> 00:06:54,700 and then the values that you might use. 189 00:06:54,700 --> 00:06:56,320 So you want to have a random seed 190 00:06:56,320 --> 00:06:58,270 that is available that you know, 191 00:06:58,270 --> 00:06:59,690 so that when you're fuzzing 192 00:06:59,690 --> 00:07:01,510 and then you cause a crash later on, 193 00:07:01,510 --> 00:07:04,420 you want to be able to start from that random seed. 194 00:07:04,420 --> 00:07:06,360 So if you're not recording that anywhere, 195 00:07:06,360 --> 00:07:08,100 if you fuzz again, you use a different seed, 196 00:07:08,100 --> 00:07:09,900 you may have different test cases. 197 00:07:09,900 --> 00:07:11,520 So then you also want to choose the input. 198 00:07:11,520 --> 00:07:13,930 You wanna choose what value you want to fuzz. 199 00:07:13,930 --> 00:07:16,210 And then, the fuzzer will create a test case. 200 00:07:16,210 --> 00:07:19,300 In other words, it creates an anomalous message 201 00:07:19,300 --> 00:07:20,570 based on that field. 202 00:07:20,570 --> 00:07:22,090 And then, you run the target 203 00:07:22,090 --> 00:07:23,710 with that test case as the input. 204 00:07:23,710 --> 00:07:25,450 And then, you instrument the target 205 00:07:25,450 --> 00:07:27,120 and you check for a crash. 206 00:07:27,120 --> 00:07:28,610 And if you have a crash, 207 00:07:28,610 --> 00:07:31,310 then you would record the test case inputs 208 00:07:31,310 --> 00:07:33,500 and then the crash data. 209 00:07:33,500 --> 00:07:35,410 And then, you would move on and go back 210 00:07:35,410 --> 00:07:36,820 to choose the input again. 211 00:07:36,820 --> 00:07:39,880 And if you don't crash, then I guess it was okay. 212 00:07:39,880 --> 00:07:41,430 And there wasn't anything that happened. 213 00:07:41,430 --> 00:07:43,960 So you may kill the target and then restart it again, 214 00:07:43,960 --> 00:07:46,260 just to get you back into that original state.