1 00:00:00,000 --> 00:00:02,340 So, yeah, a little bit about me. 2 00:00:02,760 --> 00:00:08,140 No one really cares about who the speaker is, so read this whenever you want. 3 00:00:08,140 --> 00:00:10,580 I do podcasting and blogging and shit like that. 4 00:00:12,520 --> 00:00:17,060 I am a firm believer in the wisest man is he that knows that he knows nothing. 5 00:00:17,440 --> 00:00:22,200 I am not an expert and I'm quite happy to admit that I know absolutely nothing. 6 00:00:24,680 --> 00:00:26,820 I kind of like edge case stuff. 7 00:00:26,980 --> 00:00:28,900 It's kind of ‑‑ it's freaky. 8 00:00:28,900 --> 00:00:31,480 Most people are like, oh, it's just an edge case, no one really cares. 9 00:00:32,000 --> 00:00:36,020 But the edge case stuff, the freaky stuff, the weird stuff kind of really interests me. 10 00:00:36,020 --> 00:00:39,460 It makes me think that's really cool, I should really dive into that. 11 00:00:39,460 --> 00:00:43,720 So this is part of the edge case stuff that people really don't give a shit about. 12 00:00:43,720 --> 00:00:47,780 But apparently all you guys do, otherwise you wouldn't have woken up early to come and see this. 13 00:00:49,020 --> 00:00:50,980 So I'm going to start with a quick warning. 14 00:00:51,220 --> 00:00:56,780 This presentation, it contains numbers and jokes and traces of peanuts. 15 00:00:58,040 --> 00:01:00,420 Who has ever seen me give a talk before? 16 00:01:00,960 --> 00:01:02,580 So if you had, you wouldn't be here. 17 00:01:03,920 --> 00:01:09,320 Everyone who has seen me give a talk before, I'm sorry, I use the same jokes every time. 18 00:01:09,660 --> 00:01:12,800 So just laugh when everyone else does. 19 00:01:14,220 --> 00:01:16,080 Not you, Ed, you have to stay. 20 00:01:17,060 --> 00:01:21,960 So I'm going to give everyone the TLDR on what I'm going to be talking about today. 21 00:01:23,260 --> 00:01:27,760 The goal of this talk is to describe the defensive uses of HTTP status codes. 22 00:01:28,400 --> 00:01:31,340 That sounds really sexy, doesn't it? 23 00:01:32,580 --> 00:01:36,300 This is an absolute must see at DEF CON on a Sunday morning. 24 00:01:38,780 --> 00:01:41,900 So back to why are you guys awake again? 25 00:01:42,900 --> 00:01:50,760 I'm going to run through the what, the why, the how, the goals and then we're going to bring it together and we're going to review what we've covered. 26 00:01:51,000 --> 00:01:55,780 So I'm going to try to run through this reasonably fast so I can get everything in. 27 00:01:56,060 --> 00:01:57,360 So let's start with the what. 28 00:01:57,360 --> 00:01:58,680 HTTP status code. 29 00:01:58,680 --> 00:02:01,240 Who has never seen an HTTP status code? 30 00:02:02,040 --> 00:02:03,740 Yeah, okay, I thought so. 31 00:02:03,760 --> 00:02:06,480 So we know what an HTTP request looks like. 32 00:02:06,640 --> 00:02:08,300 We're picking out the specific section. 33 00:02:08,300 --> 00:02:10,640 This is the status code or the response code. 34 00:02:11,380 --> 00:02:15,360 The terms are interchangeable depending on how much you had to drink. 35 00:02:16,600 --> 00:02:24,400 It's like a really small little thing every time you make a request or every time you get an answer from a server. 36 00:02:24,400 --> 00:02:26,440 It comes with some kind of status code. 37 00:02:26,720 --> 00:02:28,460 No one really cares what they are. 38 00:02:28,460 --> 00:02:35,820 The browser doesn't really tell you what it is, but it's an important feature of the HTTP standard. 39 00:02:36,980 --> 00:02:41,420 What I'm going to show you is a really small detail, but it's a really big impact. 40 00:02:41,820 --> 00:02:47,160 If you don't really pay attention to the status codes, then some bad things can seriously happen. 41 00:02:47,400 --> 00:02:50,340 So a little bit of history on HTTP status codes. 42 00:02:50,480 --> 00:02:51,480 This is an RFC. 43 00:02:51,480 --> 00:02:53,300 I'm sure everyone here has read that, right? 44 00:02:54,800 --> 00:02:56,160 I couldn't sleep last night. 45 00:02:56,160 --> 00:03:00,320 I thought maybe I should read the RFC again, but yeah, that didn't happen. 46 00:03:00,940 --> 00:03:03,240 So there's five main classes of responses. 47 00:03:03,240 --> 00:03:06,920 You get the one, 100, which is the informational stuff. 48 00:03:07,040 --> 00:03:08,560 You don't get to see that very much. 49 00:03:08,680 --> 00:03:11,880 You get the 200, which is most of the time success. 50 00:03:11,880 --> 00:03:13,020 Your web page is here. 51 00:03:13,020 --> 00:03:13,920 Here is the content. 52 00:03:13,920 --> 00:03:14,560 Thank you very much. 53 00:03:14,560 --> 00:03:15,460 Please go away. 54 00:03:15,800 --> 00:03:17,980 You get the 300, which is the redirect stuff. 55 00:03:18,820 --> 00:03:21,040 You get the 400, which means you fucked up. 56 00:03:21,200 --> 00:03:23,320 You get the 500, which means they fucked up. 57 00:03:25,140 --> 00:03:26,400 Simple as that, okay? 58 00:03:26,480 --> 00:03:35,180 There's also a wonderful RFC, and this one is actually worth reading for the 700 codes by John Barton. 59 00:03:35,460 --> 00:03:38,340 If you go to his GitHub page, there's an entire section. 60 00:03:39,240 --> 00:03:40,540 I like the meh. 61 00:03:40,980 --> 00:03:42,540 I am not a teapot. 62 00:03:43,960 --> 00:03:47,620 I specifically like this one, fucking unicode. 63 00:03:53,220 --> 00:03:56,820 So, yeah, there's like 300 of these things. 64 00:03:56,880 --> 00:04:01,060 So I have no idea how they squeezed it all into the 700 range, because there's 300 of them. 65 00:04:02,300 --> 00:04:06,260 These are amazing, and I have no idea where did the 600 range go? 66 00:04:06,580 --> 00:04:13,440 So, yeah, I really hope they accept that RFC and start implementing that in some stuff. 67 00:04:13,600 --> 00:04:15,320 So let's go through the basic stuff. 68 00:04:15,320 --> 00:04:16,420 This is the theory bit. 69 00:04:16,420 --> 00:04:19,700 It's boring, and I'm sorry, but this is the theory. 70 00:04:19,700 --> 00:04:21,120 So you get the 100 informationals. 71 00:04:21,120 --> 00:04:24,100 You get the 100 continue, switch protocols, processing. 72 00:04:24,180 --> 00:04:26,820 As I said, these are the things you don't get to see very much. 73 00:04:26,940 --> 00:04:30,460 Moving into the 200 stuff, it means it worked. 74 00:04:30,460 --> 00:04:32,420 It means it understood. 75 00:04:32,540 --> 00:04:36,380 So you're getting a 200 okay, which is most of the web is returning a 200 okay. 76 00:04:37,820 --> 00:04:41,420 You also get some weird stuff that you don't get to see very much, like 204 no content. 77 00:04:41,740 --> 00:04:43,320 Great, thanks for the header. 78 00:04:46,840 --> 00:04:50,420 There's also some interesting stuff that isn't supported by Apache. 79 00:04:51,920 --> 00:04:53,320 Low on storage space. 80 00:04:53,320 --> 00:04:56,420 I've never seen that one returned by a server, but I'd really like it. 81 00:04:56,420 --> 00:04:58,000 But they're not supported by Apache. 82 00:04:59,600 --> 00:05:03,420 You get the 300 redirection stuff. 83 00:05:03,420 --> 00:05:06,120 So most people know what a 301 is, what a 302 is. 84 00:05:06,540 --> 00:05:08,360 300 you don't get to see very much. 85 00:05:08,360 --> 00:05:09,420 Multiple choices. 86 00:05:09,700 --> 00:05:11,260 It's like an exam. 87 00:05:11,520 --> 00:05:13,100 Tick boxes or something. 88 00:05:14,640 --> 00:05:20,460 304 not modified as well is something you see quite a lot if you're looking at the way data flows backwards and forwards. 89 00:05:20,460 --> 00:05:23,520 You also get some weird stuff that isn't used anymore, like switch proxy. 90 00:05:23,880 --> 00:05:24,960 Sounds like fun. 91 00:05:25,000 --> 00:05:26,300 Use proxy is also interesting. 92 00:05:26,300 --> 00:05:31,500 If you return a proxy setting in the location header, it says, oh, you should use this proxy for your communications. 93 00:05:31,920 --> 00:05:35,040 I'm sure no one would use that for malicious purposes in any way. 94 00:05:36,860 --> 00:05:41,400 So moving on to the 400, which is the you fucked up section. 95 00:05:41,980 --> 00:05:45,100 So forbidden, unauthorized, usual stuff. 96 00:05:45,180 --> 00:05:51,720 404 not found being quite a reasonable response for I search on random crap on the Internet. 97 00:05:53,080 --> 00:05:54,760 And then you get some interesting stuff. 98 00:05:54,760 --> 00:05:57,560 I quite like the 407 proxy authentication required. 99 00:05:58,320 --> 00:06:00,480 I'll talk a little bit more about that later on. 100 00:06:01,000 --> 00:06:04,140 Interesting ways to do some malicious stuff with that. 101 00:06:04,500 --> 00:06:06,080 This is a long list. 102 00:06:08,380 --> 00:06:10,440 I quite like the 418. 103 00:06:10,440 --> 00:06:11,460 I'm a teapot. 104 00:06:11,460 --> 00:06:16,200 It's only in April Fools and quite a lot of web servers don't implement it, but this is interesting. 105 00:06:16,200 --> 00:06:18,320 It's like I am indeed a teapot. 106 00:06:20,860 --> 00:06:27,680 Moving into the 500 stuff, internal server error, which is unfortunately used quite a lot for SQL injection. 107 00:06:27,680 --> 00:06:28,760 Oh, I got a 500 error. 108 00:06:28,760 --> 00:06:30,500 That must be a SQL injection trigger. 109 00:06:31,960 --> 00:06:35,900 You don't get to see it very much if you're not abusing websites. 110 00:06:35,900 --> 00:06:38,340 Still, it's interesting. 111 00:06:38,340 --> 00:06:40,740 Wow, that's a lot of fucking numbers. 112 00:06:42,620 --> 00:06:43,240 All right. 113 00:06:43,240 --> 00:06:46,320 So everyone here knows every single HTTP response code now, right? 114 00:06:47,140 --> 00:06:47,980 Great. 115 00:06:47,980 --> 00:06:49,800 I don't have to talk about them anymore. 116 00:06:49,800 --> 00:06:51,140 So why are we doing this? 117 00:06:51,140 --> 00:06:53,000 It started off as a little idea. 118 00:06:53,360 --> 00:06:54,840 I read a couple of books. 119 00:06:55,280 --> 00:06:57,100 I do that on occasion. 120 00:06:57,480 --> 00:06:59,680 I don't know if any of the authors are in the room. 121 00:06:59,940 --> 00:07:01,260 I'm really sorry. 122 00:07:01,920 --> 00:07:03,640 I'm plagiarizing your work. 123 00:07:04,700 --> 00:07:07,340 And I started to have a little think, what can we do with that? 124 00:07:07,800 --> 00:07:10,300 We can do some interesting stuff with scanners. 125 00:07:11,040 --> 00:07:13,980 And screwing with script kitties is a hobby. 126 00:07:15,000 --> 00:07:16,800 It's more of a life calling. 127 00:07:18,720 --> 00:07:20,620 And that sounds like fun. 128 00:07:20,620 --> 00:07:22,640 That sounds like something I want to do at a weekend. 129 00:07:23,080 --> 00:07:27,280 And I started to look around and there's a guy that everyone follows on Twitter, right? 130 00:07:27,280 --> 00:07:28,180 The Grug. 131 00:07:28,400 --> 00:07:30,940 He's not here because he's drunk, but he should be. 132 00:07:31,960 --> 00:07:40,480 He said in one of his quotes, stop dismissing obscurity as a security feature because unpredictability in your defense works to your advantage. 133 00:07:40,920 --> 00:07:41,780 Well, that's great. 134 00:07:42,000 --> 00:07:45,920 We can increase attacker costs being unpredictable. 135 00:07:46,740 --> 00:07:48,980 And we can waste attacker time. 136 00:07:49,080 --> 00:07:55,920 We can say that, you know, an attacker is going to waste three hours attacking a website that should take 15 minutes. 137 00:07:55,940 --> 00:07:59,300 Why should we just stand there and let someone smash us in the face? 138 00:07:59,680 --> 00:08:01,960 We should be more active on our defense. 139 00:08:02,320 --> 00:08:05,120 So there's some prior art. 140 00:08:05,160 --> 00:08:06,360 I kind of looked around. 141 00:08:06,360 --> 00:08:08,520 I was trying to find who else has talked about this stuff before. 142 00:08:08,520 --> 00:08:11,060 Because in my mind, this was just obvious stuff. 143 00:08:11,060 --> 00:08:13,860 I was like, someone's bound to have already implemented this stuff. 144 00:08:14,480 --> 00:08:24,680 There was a 2004 talk by Harun Mir and the guys at SensePost where they mentioned using HTTP status codes to slow down attackers. 145 00:08:24,840 --> 00:08:28,080 It was one line comment in a slide deck. 146 00:08:28,080 --> 00:08:28,900 That was it. 147 00:08:28,900 --> 00:08:29,720 Okay. 148 00:08:29,720 --> 00:08:32,700 Well, someone's mentioned it, so there must be more. 149 00:08:33,400 --> 00:08:36,340 There was an interesting paper by Gunter Ohlum. 150 00:08:36,340 --> 00:08:38,880 I probably totally mispronounced his name there. 151 00:08:38,880 --> 00:08:42,100 There's a PDF where he talks about stopping automated attack tools. 152 00:08:42,100 --> 00:08:43,940 I was like, okay, this must cover it. 153 00:08:43,960 --> 00:08:50,540 He covers lots and lots of stuff, but he doesn't really dig deep into using HTTP status codes to do this stuff. 154 00:08:50,540 --> 00:09:03,760 So I carried on, and I was informed, should we say, of a mailing list comment where Ryan Barnett said that, well, maybe we can reply with a 503 with a retry after header. 155 00:09:04,560 --> 00:09:05,740 That was interesting. 156 00:09:05,740 --> 00:09:07,020 I tested it out. 157 00:09:07,020 --> 00:09:11,260 It didn't really seem to work, because most scanners just completely ignore a retry after header. 158 00:09:11,260 --> 00:09:12,500 But maybe things have moved on. 159 00:09:12,500 --> 00:09:14,740 This was 2006 when that comment was made. 160 00:09:15,020 --> 00:09:17,900 So, yeah, no one seems to have discussed this stuff. 161 00:09:18,380 --> 00:09:21,740 So how are we going to work this in? 162 00:09:21,860 --> 00:09:24,960 So browsers have to be as flexible as possible. 163 00:09:24,960 --> 00:09:37,580 You get websites written by kiddies in notepad, and you get professional websites written in HTML5 with web APIs and SOAP interfaces, and the browser has to be able to support it all. 164 00:09:37,760 --> 00:09:49,220 And this leads to a certain amount of flexibility on how things are understood, how things are supported, which obviously leads to the dark side. 165 00:09:49,680 --> 00:09:53,020 And then, of course, there's RFCs, which some would say is the dark side. 166 00:09:54,400 --> 00:09:56,300 They're more of a guideline, really. 167 00:09:56,940 --> 00:10:02,860 This is the way you should do it, but we're not going to tell you exactly how, so it depends how drunk you were when you read it. 168 00:10:03,920 --> 00:10:05,380 Maybe this makes sense. 169 00:10:05,380 --> 00:10:08,340 So, yeah, what could possibly go wrong? 170 00:10:08,340 --> 00:10:17,200 You have 300‑page RFC and people who are going to interpret it, and you implement it into a piece of software which has to be as flexible as possible, otherwise things don't work. 171 00:10:17,420 --> 00:10:18,820 Things are going to start to go wrong. 172 00:10:18,820 --> 00:10:21,400 So I started to do a little bit of testing. 173 00:10:22,320 --> 00:10:24,780 I wanted to restrict myself to the big three. 174 00:10:25,040 --> 00:10:27,760 Internet Explorer, Chrome, Chromium and Firefox. 175 00:10:28,860 --> 00:10:29,580 No? 176 00:10:29,580 --> 00:10:30,300 Yes. 177 00:10:33,840 --> 00:10:39,840 Apparently Opera turned really bad, or there's Lynx, but who uses Lynx? 178 00:10:40,620 --> 00:10:42,300 One guy uses Lynx. 179 00:10:42,320 --> 00:10:44,160 Welcome to the 20th century. 180 00:10:47,220 --> 00:10:52,220 So I wanted to take the easy option on testing, so I thought, okay, well, there's man in the middle proxy. 181 00:10:52,900 --> 00:10:56,660 It's a Python‑based system for man in the middling HTTP connections. 182 00:10:56,940 --> 00:10:59,840 It allows you to set up this really interesting reverse proxy. 183 00:10:59,920 --> 00:11:01,960 It's all script‑based and it does all the work for you. 184 00:11:01,960 --> 00:11:05,060 You just write something like this in a script file. 185 00:11:05,740 --> 00:11:06,540 That's it. 186 00:11:07,180 --> 00:11:10,220 All this does is change every response code to a 200. 187 00:11:12,400 --> 00:11:13,420 That's easy. 188 00:11:13,420 --> 00:11:14,940 Even I can code that shit. 189 00:11:16,360 --> 00:11:20,220 Unfortunately, man in the middle proxy tends to use up all of the memory you have on your machine. 190 00:11:21,920 --> 00:11:24,640 Even if you have 8 gigabytes of memory in your laptop. 191 00:11:25,220 --> 00:11:29,600 I would highly recommend man in the middle dump, which doesn't cache everything into memory. 192 00:11:30,340 --> 00:11:32,160 Just a side note there. 193 00:11:32,160 --> 00:11:36,640 I also used PHP, the amazing personal home page. 194 00:11:38,320 --> 00:11:41,680 It allows you to set response codes, but there's some downsides. 195 00:11:41,740 --> 00:11:47,140 You can also prepend a file, which is going to allow you to set specific response codes or do some logic in the background. 196 00:11:47,140 --> 00:11:57,120 The problem is if the web server says, no, this is an incorrect request, the PHP is never going to get to actually see the request, so you can't set response codes. 197 00:11:57,120 --> 00:11:58,720 So you can do some interesting stuff. 198 00:11:58,720 --> 00:12:03,480 For testing, it's useful, but in production, it's not really going to be as useful as it could be. 199 00:12:03,480 --> 00:12:10,120 So I used a mismatch of Python and PHP for most of the testing. 200 00:12:10,560 --> 00:12:24,600 You don't need to write this down, because I'll release all the slides afterwards, but simple testing of browsers, how things are supported, you just call a PHP page, which sets the response code, you tell it what code in the URL, and you hope no one cross‑sites your website. 201 00:12:26,040 --> 00:12:27,080 As simple as that. 202 00:12:27,080 --> 00:12:43,200 You get a response, you get the requested response code and the actual response code, because with PHP, you can set that response code to 999 if you want, but Python is just going to say, oh, sorry, Apache is just going to turn around and say, I don't know what that response code is, 203 00:12:43,200 --> 00:12:48,180 and then it just returns a 500, which is the they fucked up section of it. 204 00:12:48,220 --> 00:13:02,860 So, yeah, you get to see what you requested, you get to see what the response was, and you get to see what the headers are, so simple JavaScript running in the browser, so great, I can run off and start testing these browsers, which seemed like an easy thing. 205 00:13:03,140 --> 00:13:14,340 I started to think, I've got all this data on how all these browsers work, and how can I graphically display that in a nice fashion? 206 00:13:14,980 --> 00:13:17,940 Let's just say that I'm not good at charting. 207 00:13:22,120 --> 00:13:29,200 Sorry, for the women in the room, also, I'm trying to keep this even across the sexes. 208 00:13:29,900 --> 00:13:37,380 So I didn't really know how to display this, so I spoke to some guys who do visualization, and they were like, oh, yeah, we can do this and we can do that, and it was just all shit. 209 00:13:38,300 --> 00:13:41,540 So what I ended up with was a table. 210 00:13:46,640 --> 00:13:52,700 Yeah, this is the reason why I cut it down to three browsers, because otherwise the table would be like this fucking wide. 211 00:13:53,600 --> 00:14:06,460 So, yeah, there's a full table online, which I'll release after the talk, which has a lot of other browsers and scripting languages in it, but this is the core three, so you start to see quite a lot of conformity in this section about how the browsers respond to things. 212 00:14:06,460 --> 00:14:12,440 So I run it into three sections, so can you load HTML with a 100 response code? 213 00:14:12,720 --> 00:14:26,680 Well, you can, but nothing appears, it doesn't render anything, so the browser just doesn't support it, unless it's an iframe with Chrome, in which case it tries to download it, because I guess Chrome just likes to download shit. 214 00:14:28,800 --> 00:14:44,760 What's kind of interesting, if you have Chrome on an Android phone and you respond with a 100 code, it tries to download it, but it never finishes, so you have to restart your Android to get it to stop, which is fun. 215 00:14:46,820 --> 00:14:48,840 I'm sure no one would fuck with that. 216 00:14:51,980 --> 00:15:01,900 So looking at this, you're like, okay, well, all the browsers are kind of mostly conform, except IE, obviously, which doesn't care about a 205 and just renders the stuff, it doesn't care. 217 00:15:01,900 --> 00:15:18,900 You start to see differences when you're looking at the 300 codes, for example, Firefox just doesn't load JavaScript if you respond with a 300 or a 301, IE pretty much just ignores everything if you respond with anything in the 300 range which isn't a redirection, 218 00:15:18,900 --> 00:15:22,080 but Chrome pretty much accepts everything because it doesn't give a shit. 219 00:15:22,600 --> 00:15:24,880 It's the honey badger of browsers. 220 00:15:27,140 --> 00:15:32,500 Moving kind of into the 400 stuff, you start to see more conformity, again, IE being the weird one. 221 00:15:32,500 --> 00:15:35,660 It just doesn't like loading iframes with weird response codes. 222 00:15:36,400 --> 00:15:41,380 And you see these at a time when it says 407 proxy, proxy, proxy. 223 00:15:43,040 --> 00:15:48,420 Basically what that means is that Chrome, depending if you have a proxy set or not, will load it. 224 00:15:48,420 --> 00:15:54,960 So if you have a proxy, an HTTP proxy set, then Chrome will load the content when it's responded with a 407. 225 00:15:55,020 --> 00:15:56,640 If you don't, then it won't. 226 00:15:58,680 --> 00:16:04,800 Again with the 500s, things are pretty standard, again, IE being kind of a little bit of a weird outlier on things. 227 00:16:04,940 --> 00:16:05,320 Okay. 228 00:16:05,320 --> 00:16:07,740 So think about this for a second. 229 00:16:07,800 --> 00:16:11,440 You've got browsers that kind of handle things in slightly different ways. 230 00:16:11,820 --> 00:16:13,600 What can we do with that kind of stuff? 231 00:16:13,780 --> 00:16:18,420 But a majority of stuff is like, okay, that's just content. 232 00:16:18,420 --> 00:16:19,640 I don't care what it is. 233 00:16:19,640 --> 00:16:20,740 It's loading stuff. 234 00:16:20,740 --> 00:16:25,440 It's like you get a 400 response and it's like, oh, I see HTML, I'm just going to render that for you. 235 00:16:25,440 --> 00:16:28,480 Or I see JavaScript, I'm just going to run that JavaScript for you. 236 00:16:28,520 --> 00:16:33,800 So most things, mostly, things are loaded quite normally. 237 00:16:33,800 --> 00:16:35,880 But there's some weird kind of outliers. 238 00:16:36,540 --> 00:16:41,280 So with HTML responses, almost all response codes are rendered correctly. 239 00:16:41,340 --> 00:16:42,320 It doesn't care. 240 00:16:42,380 --> 00:16:49,060 When you try and load an iframe and it comes back with a response, there's some special cases for IE because IE is special. 241 00:16:49,900 --> 00:16:52,100 But most of the time kind of things are even. 242 00:16:52,100 --> 00:16:56,740 And if you start looking at JavaScript, there's very limited support for it. 243 00:16:56,740 --> 00:17:00,260 Chrome being the exception because they just don't care. 244 00:17:00,900 --> 00:17:04,540 So we know what browsers interpret differently. 245 00:17:05,300 --> 00:17:07,520 So what do all the browsers have in common? 246 00:17:07,720 --> 00:17:10,540 What are they doing the same across the board? 247 00:17:10,540 --> 00:17:16,420 The 100 codes, retries, confusion, as I said, fun on Android, never-ending downloads. 248 00:17:16,980 --> 00:17:19,240 And it times out eventually. 249 00:17:19,660 --> 00:17:22,120 Because the browser thinks there's more coming. 250 00:17:22,200 --> 00:17:24,820 The browser thinks, oh, you're going to send more data in a minute. 251 00:17:24,820 --> 00:17:26,800 I'll just sit here and wait for you. 252 00:17:27,960 --> 00:17:29,580 Which is kind of interesting. 253 00:17:29,660 --> 00:17:32,880 The 200 codes, again, you get the no content or not modified. 254 00:17:32,940 --> 00:17:36,320 You get headers saying, no, there's nothing here. 255 00:17:36,360 --> 00:17:44,360 So as you would expect, all the browsers just ignore any kind of content that you're responding because it doesn't expect there to actually be any content within those things. 256 00:17:45,540 --> 00:17:46,840 So what about headers? 257 00:17:47,520 --> 00:17:47,760 Okay. 258 00:17:47,760 --> 00:18:00,680 So RFCs quite a lot of the time in kind of a muddy language say if you're responding with a free XX response code, whether it's 301 or 302 or 303, there should be a location header. 259 00:18:01,340 --> 00:18:03,120 It doesn't mean it has to. 260 00:18:03,700 --> 00:18:10,960 If you respond and you don't have a location header, it just kind of ignores the fact that it's meant to do a redirect and then renders whatever content you give it. 261 00:18:12,920 --> 00:18:15,200 Specifically, no location header, no redirect. 262 00:18:15,200 --> 00:18:16,220 This makes sense. 263 00:18:16,220 --> 00:18:21,080 Because you're responding with a 302, it's looking for the location header, it doesn't find one. 264 00:18:21,080 --> 00:18:25,980 Instead of just giving you an unhelpful error in your browser, it's just going to render what you returned and ignore. 265 00:18:26,260 --> 00:18:27,300 Simple as that. 266 00:18:27,320 --> 00:18:35,940 So the 401 unauthorized as well, if you're not sending back a www authenticate header, it's not going to prompt you. 267 00:18:35,940 --> 00:18:36,980 Simple as that. 268 00:18:38,240 --> 00:18:43,540 And I mentioned previously about the 407 proxy authentication required, the way Chrome deals with it. 269 00:18:43,540 --> 00:18:48,560 Again, if you're not requesting the authentication, then it's never going to prompt you. 270 00:18:49,240 --> 00:18:56,560 On the flip side, just because an RFC says a specific status code shouldn't have a header, doesn't mean it can't have a header. 271 00:18:57,220 --> 00:19:03,740 So if you read the RFCs, there's 300 multiple choices. 272 00:19:04,720 --> 00:19:06,620 Now, this shouldn't have a location header. 273 00:19:06,740 --> 00:19:08,020 It doesn't redirect you. 274 00:19:08,020 --> 00:19:12,440 It should come up with an HTML where you can specifically select where you would like to go. 275 00:19:12,780 --> 00:19:18,340 Unless, of course, you're Firefox or IE, in which case if you give it a location header, it's just going to redirect. 276 00:19:18,860 --> 00:19:20,180 But Chrome isn't. 277 00:19:20,660 --> 00:19:23,380 And there are so many headers out there you can play with. 278 00:19:23,380 --> 00:19:24,500 I've played with quite a lot of them. 279 00:19:24,500 --> 00:19:27,220 Most of them are not particularly interesting, unfortunately. 280 00:19:27,420 --> 00:19:30,920 But there's more work to be done in that kind of area. 281 00:19:30,920 --> 00:19:36,760 There's a load of headers like the retry after header that can really be played with and a little bit more research is required there. 282 00:19:37,180 --> 00:19:40,160 So each browser is handling something a little bit differently. 283 00:19:41,380 --> 00:19:43,400 We know how things are handled the same. 284 00:19:43,400 --> 00:19:45,040 We know how things are handled differently. 285 00:19:45,900 --> 00:19:47,400 I wonder what we can do with that. 286 00:19:48,940 --> 00:19:51,620 So what can we do with that? 287 00:19:51,620 --> 00:19:53,000 What are the goals? 288 00:19:53,000 --> 00:19:53,140 Okay. 289 00:19:53,140 --> 00:19:55,900 So each browser handles things differently. 290 00:19:55,900 --> 00:20:05,080 You have the handled codes, you have the unhandled codes, and then you get this little browser weirdness thing where it just does random stuff you just didn't expect it to do depending on the headers. 291 00:20:05,760 --> 00:20:08,080 So browser fingerprinting. 292 00:20:08,200 --> 00:20:08,380 Okay. 293 00:20:08,380 --> 00:20:13,060 So, yeah, you can check user agent strings, but that's client side controlled. 294 00:20:13,060 --> 00:20:14,780 You can easily spoof that stuff. 295 00:20:15,420 --> 00:20:23,020 But if you take the differences, you can really do some interesting fingerprinting work on Firefox, on Chrome, and on IE. 296 00:20:23,020 --> 00:20:28,200 So on Firefox, based on the information we have, it doesn't load JavaScript return with a 300. 297 00:20:28,700 --> 00:20:30,060 The other browsers do. 298 00:20:30,060 --> 00:20:34,700 So you simply return a JavaScript with a 300, and if the JavaScript runs, it's Firefox. 299 00:20:34,760 --> 00:20:35,900 Simple as that. 300 00:20:36,180 --> 00:20:36,800 Okay? 301 00:20:37,380 --> 00:20:45,260 With Chrome as well, it loads Java return with a 307, temporary redirect, without a location header, but the other browsers don't. 302 00:20:45,260 --> 00:20:48,140 So again, we can do the same kind of thing, and we can do some fingerprinting. 303 00:20:48,420 --> 00:20:54,560 And with IE, it loads JavaScript return with a reset content status code, and nothing else does. 304 00:20:54,600 --> 00:21:02,040 So if we can add all that stuff together, you can get a nice way of fingerprinting the main browsers without even bothering to look at the location header. 305 00:21:02,160 --> 00:21:12,400 Or you can use the user agent header, and then specifically say, well, I'm going to check that by seeing how your browser really works. 306 00:21:12,500 --> 00:21:14,640 So I'm going to do a quick demo. 307 00:21:15,000 --> 00:21:15,900 Well, actually, I lied. 308 00:21:15,900 --> 00:21:19,700 I'm going to run a quick video of a demo, because I didn't want to connect to the network here. 309 00:21:23,200 --> 00:21:24,200 First talk. 310 00:21:24,200 --> 00:21:32,040 So all this is doing is loading a PHP page, and then running through and loading three individual pages. 311 00:21:33,880 --> 00:21:44,240 It then checks the responses, checks the JavaScript, and says, so this JavaScript ran, this JavaScript didn't, so you must be using this specific browser. 312 00:21:44,320 --> 00:21:50,520 So if you zoom in, well, if I zoom in, there you go. 313 00:21:50,520 --> 00:21:52,260 So you can see the specific responses. 314 00:21:52,260 --> 00:22:01,860 You can see that it's loading an HTML, it's coming back with a 300, a 307, and a 205, which are the three specific response codes we talked about for the different browsers. 315 00:22:01,860 --> 00:22:09,740 It's then sending all of that stuff to a PHP page on the server, and the PHP page is returning and saying, okay, this is the specific browser. 316 00:22:10,180 --> 00:22:15,580 So obviously I'm returning back to the browser to display a pop‑up to say this is the browser. 317 00:22:15,680 --> 00:22:23,180 In most cases, you're sending it to the server, and then you're never responding back, because I know I'm running IE. 318 00:22:23,180 --> 00:22:24,880 I have the little IE bar at the top. 319 00:22:24,880 --> 00:22:27,000 I don't need you to do a pop‑up and tell me. 320 00:22:27,160 --> 00:22:30,420 But the server now knows exactly what kind of browser you're using. 321 00:22:30,420 --> 00:22:39,640 So if you're spoofing a user agent string, then I can say, okay, so user agent string says you're running Firefox, but you're actually running Chrome. 322 00:22:39,640 --> 00:22:43,560 That's suspicious, and that's something that we should be looking at, okay? 323 00:22:44,080 --> 00:22:47,520 So there's various other options for fingerprinting. 324 00:22:47,520 --> 00:22:51,520 This specific option I selected was kind of the easiest option. 325 00:22:51,520 --> 00:22:52,480 There's various other stuff. 326 00:22:52,480 --> 00:22:56,520 There's a 300 redirect, there's a 400 iframe on Internet Explorer. 327 00:22:56,900 --> 00:23:06,260 If you want to look at the proof of concept, if you go to C22.cc, fingerprint.html, it will run the same example I just ran. 328 00:23:06,260 --> 00:23:09,240 You can look at the traffic, and the code is available. 329 00:23:09,240 --> 00:23:10,580 I'll link to that at the end. 330 00:23:10,580 --> 00:23:12,680 So user agents can be spoofed. 331 00:23:12,680 --> 00:23:13,460 Everyone knows that. 332 00:23:13,460 --> 00:23:15,480 Even script kiddies, unfortunately, know that. 333 00:23:15,880 --> 00:23:18,140 But browser traits are really hard. 334 00:23:18,500 --> 00:23:22,280 Because your browser responds and does things in specific ways. 335 00:23:22,400 --> 00:23:23,420 So we've done that. 336 00:23:23,420 --> 00:23:24,700 We can fingerprint browsers. 337 00:23:24,700 --> 00:23:25,300 So what else can we do? 338 00:23:25,300 --> 00:23:26,420 Proxy detection. 339 00:23:26,420 --> 00:23:29,600 We specifically talked about the way Chrome handles things. 340 00:23:29,800 --> 00:23:34,960 And if you have an HTTP proxy set, you can specifically say, okay, I know they're using Chrome. 341 00:23:35,180 --> 00:23:37,120 I'm going to respond with a 407. 342 00:23:37,220 --> 00:23:41,000 If it loads the page, then they're using an HTTP proxy. 343 00:23:41,200 --> 00:23:42,940 There's unfortunately limitations here. 344 00:23:42,940 --> 00:23:44,700 It doesn't pick up with SOX proxies. 345 00:23:44,780 --> 00:23:47,180 But your average user isn't using a SOX proxy anyway. 346 00:23:47,760 --> 00:23:53,720 It's a limited interest, but it's something that needs further testing. 347 00:23:53,720 --> 00:24:01,280 As I said, all you do is respond with a 407 with a proxy authentication header or without a proxy authentication header. 348 00:24:01,280 --> 00:24:04,020 And if Chrome responds, then HTTP proxy is set. 349 00:24:04,080 --> 00:24:11,660 So while I was doing this research, I decided I was going to try a couple of different HTTP proxies. 350 00:24:11,660 --> 00:24:16,440 And one of the proxies I selected was Privoxy. 351 00:24:16,920 --> 00:24:21,160 It's quite a popular privatizing HTTP proxy. 352 00:24:21,700 --> 00:24:33,060 So I found while I was testing this, if you respond with a ‑‑ so your web server, you go to my web server, you respond with a 407 proxy authentication required, you get the pop‑up in your browser. 353 00:24:33,260 --> 00:24:36,320 But it doesn't say that my web server asked you for a username and password. 354 00:24:36,320 --> 00:24:39,040 It says Privoxy asked you for a username and password. 355 00:24:40,020 --> 00:24:41,120 Which is interesting. 356 00:24:41,120 --> 00:24:43,920 So why is my local proxy asking for a username and password, I thought. 357 00:24:43,920 --> 00:24:47,380 So I typed in test, test, and I clicked send. 358 00:24:47,880 --> 00:24:51,300 And my web server gets my username and password. 359 00:24:52,720 --> 00:24:54,120 That's kind of interesting. 360 00:24:54,120 --> 00:24:56,380 I'm sure we can use that for some malicious stuff. 361 00:24:56,820 --> 00:24:58,340 But this is a defensive talk. 362 00:24:58,340 --> 00:25:00,040 So I'm not going to dive too much into that. 363 00:25:00,040 --> 00:25:01,520 But it's kind of interesting. 364 00:25:01,980 --> 00:25:06,760 Let's just say proxies aren't always configured quite so securely as they could be. 365 00:25:07,020 --> 00:25:08,140 There's a fix for that now. 366 00:25:08,140 --> 00:25:09,800 So you can download the latest version. 367 00:25:09,880 --> 00:25:11,620 But it's not just Privoxy. 368 00:25:11,620 --> 00:25:17,360 Any transparent proxy, things like burp or zap, they're designed to pass everything you give it. 369 00:25:17,560 --> 00:25:23,380 So if my web server responds with a 407 and asks for authentication, burp suite will just pass it to your browser. 370 00:25:23,380 --> 00:25:24,280 Simple as that. 371 00:25:24,620 --> 00:25:31,740 So you can start screwing with people who you know are doing malicious things on your site with intercepting proxies. 372 00:25:32,460 --> 00:25:39,180 Of course, if you're doing a test with burp suite and it says what's your username and password, I'm probably not going to type in my real username and password. 373 00:25:39,360 --> 00:25:40,500 But you never know. 374 00:25:40,500 --> 00:25:42,320 Script kiddies type in weird stuff. 375 00:25:43,900 --> 00:25:46,300 So let's bring all this stuff together. 376 00:25:46,300 --> 00:25:49,780 So we've got status codes that are treated like content. 377 00:25:49,780 --> 00:25:50,700 They don't care. 378 00:25:50,860 --> 00:25:55,940 You've got status codes that really are not specifically well handled, specifically the 100 codes. 379 00:25:55,940 --> 00:25:58,740 And you've got lots of little browser quirks that we can abuse. 380 00:25:59,040 --> 00:25:59,880 So what can we do? 381 00:25:59,880 --> 00:26:05,200 We can play with things just in case there's children in the room. 382 00:26:05,960 --> 00:26:09,360 We can make the people who like RFCs cry into their beer. 383 00:26:09,720 --> 00:26:13,340 So let's try to use what we've discovered. 384 00:26:13,340 --> 00:26:15,060 Let's break some spidering tools. 385 00:26:15,980 --> 00:26:18,220 Cause some false positives, false negatives. 386 00:26:19,000 --> 00:26:22,900 Slow down attackers, which is probably one of the most important things that we can do. 387 00:26:22,900 --> 00:26:26,440 Give us time to respond to how people are attacking us. 388 00:26:26,860 --> 00:26:29,080 And then block successful exploitation. 389 00:26:29,380 --> 00:26:35,960 So even if they do manage to exploit the server, if you're responding specifically with different codes, maybe their exploit is not going to work. 390 00:26:35,960 --> 00:26:38,600 So let's talk a little bit about spiders. 391 00:26:39,620 --> 00:26:43,100 This is a very simplistic and naive view of spiders. 392 00:26:43,240 --> 00:26:47,840 But you access the target URL, you read the links, you test them. 393 00:26:47,840 --> 00:26:49,180 If true, continue. 394 00:26:49,180 --> 00:26:53,400 So if you get a 200 okay, that's true, right? 395 00:26:53,400 --> 00:26:57,780 And if you get a 404, that's false, right? 396 00:26:57,880 --> 00:27:01,980 But what happens if everything is a 200? 397 00:27:02,220 --> 00:27:04,420 And what happens if everything is a 404? 398 00:27:04,420 --> 00:27:06,000 You start to get some weird stuff. 399 00:27:06,000 --> 00:27:07,560 And what happens if everything is a 500? 400 00:27:08,480 --> 00:27:11,900 Sometimes if everything is a 500, then everything is a SQL injection attack. 401 00:27:12,400 --> 00:27:18,620 So if everything is a 200, you end up with this interesting loop of, oh, I found another directory. 402 00:27:18,840 --> 00:27:21,700 I will just keep scanning and keep scanning and keep scanning. 403 00:27:21,720 --> 00:27:23,440 You get this never‑ending spider. 404 00:27:23,460 --> 00:27:26,100 Unfortunately I couldn't find a picture of a spider eating itself. 405 00:27:26,380 --> 00:27:29,740 So if anyone has one, please send it to me. 406 00:27:30,940 --> 00:27:33,940 And if everything is a 404, what website? 407 00:27:34,400 --> 00:27:36,120 I don't know if you can see this at the back. 408 00:27:36,120 --> 00:27:40,520 This is the wonderful Acunetix tool, the script kiddies tool of choice. 409 00:27:41,340 --> 00:27:46,540 The crawler found zero pages, zero files, and validated zero findings. 410 00:27:47,260 --> 00:27:47,700 Yeah. 411 00:27:47,700 --> 00:27:48,860 So what website? 412 00:27:49,000 --> 00:27:50,480 There is no website there. 413 00:27:50,900 --> 00:27:52,480 Skipfish loves it. 414 00:27:52,640 --> 00:27:55,640 It just keeps going and going and going until it kills itself. 415 00:27:57,660 --> 00:28:03,200 I'm guessing at this point my test server just decided it didn't have enough memory to deal with all the responses. 416 00:28:03,500 --> 00:28:11,880 If you look closely, there is also 2,000 low, 2,000 medium false findings on the scan alone. 417 00:28:12,040 --> 00:28:13,720 So, yeah. 418 00:28:14,120 --> 00:28:17,780 Playing with people's spiders is kind of interesting. 419 00:28:17,860 --> 00:28:20,220 So false positives, false negatives. 420 00:28:20,220 --> 00:28:26,320 We can start to hide how bad or how good our servers are, start to really screw with people and waste their time. 421 00:28:26,800 --> 00:28:29,920 So most scanners use response codes in some way. 422 00:28:29,920 --> 00:28:30,940 They kind of have to. 423 00:28:30,940 --> 00:28:32,700 You speed up detection. 424 00:28:33,800 --> 00:28:35,560 You can't use rejects for everything. 425 00:28:35,560 --> 00:28:37,040 It's the easy solution. 426 00:28:37,140 --> 00:28:58,600 So if we start to respond with, again, 200 okay, 404, 500, and if we start to play with them and respond with random codes, random being a selection of codes that are handled well by all normal browsers, so the normal people browsing the website are not going to be affected in any way, 427 00:28:58,600 --> 00:29:00,740 you start to see some really interesting stuff. 428 00:29:00,740 --> 00:29:03,780 So it's a quick baseline using W3AF. 429 00:29:04,000 --> 00:29:06,080 I didn't particularly pick on these people. 430 00:29:06,080 --> 00:29:08,240 It just happens to be an interesting baseline. 431 00:29:08,240 --> 00:29:19,540 So a standard baseline for my test system was 79 informational points, 65 vulnerabilities, no shells, which kind of took an hour and 37 minutes to do a scan. 432 00:29:20,120 --> 00:29:25,240 So if everything responds with a 200 okay, you still get everything. 433 00:29:25,500 --> 00:29:29,460 So we're not winning on the false positives and false negatives. 434 00:29:29,520 --> 00:29:34,100 It takes you nine hours to run the scan, which is kind of interesting. 435 00:29:34,100 --> 00:29:37,080 It lets us win time, but it's not really working. 436 00:29:37,080 --> 00:29:39,340 So a 200 okay isn't really going to do what we need it to do. 437 00:29:39,340 --> 00:29:44,620 So if everything is a 404, it's a lot quicker to do the scan because you're not finding everything. 438 00:29:44,620 --> 00:29:48,640 But it's missing a majority of the information points and a majority of the vulnerabilities. 439 00:29:49,260 --> 00:29:51,620 So you're starting to see some interesting stuff. 440 00:29:51,620 --> 00:29:55,140 If we start responding with weird codes, they don't find everything. 441 00:29:55,140 --> 00:29:55,440 Okay. 442 00:29:55,440 --> 00:29:56,540 That's interesting. 443 00:29:56,920 --> 00:29:59,960 If you respond with everything with a 500, wow. 444 00:30:00,780 --> 00:30:02,300 False positives. 445 00:30:02,380 --> 00:30:05,200 If it's a 500, like I said, it's SQL injection. 446 00:30:05,380 --> 00:30:08,220 9,000 informational points. 447 00:30:09,460 --> 00:30:11,960 Try digging through that report, you know. 448 00:30:12,280 --> 00:30:15,060 9,000 confusing information and confirmed vulnerabilities. 449 00:30:15,640 --> 00:30:17,720 I can just see that pen test report, sorry. 450 00:30:17,720 --> 00:30:19,440 That vulnerability analysis. 451 00:30:19,660 --> 00:30:21,740 That's going to be about 1,000 pages long. 452 00:30:21,740 --> 00:30:23,020 Oh, no, we found all this stuff. 453 00:30:23,020 --> 00:30:25,420 We have IAS vulnerabilities and this and that. 454 00:30:25,420 --> 00:30:28,880 It's an Apache server, but we still have all of these IAS vulnerabilities. 455 00:30:30,140 --> 00:30:32,840 So any people who use Nessus in the room? 456 00:30:32,840 --> 00:30:33,340 No. 457 00:30:34,020 --> 00:30:40,440 So if we start using random status codes, I did multiple runs of this to make sure that I'm getting accurate. 458 00:30:40,440 --> 00:30:43,280 Because if it's being random, maybe I just had a bad run. 459 00:30:43,440 --> 00:30:47,900 It averaged out as giving you a reasonable amount of false positives. 460 00:30:48,240 --> 00:30:51,700 And it took less time to run the scan. 461 00:30:52,100 --> 00:31:00,080 What I found interesting on this was a majority of the things that it did find, it didn't find the real vulnerabilities, it just found weird stuff. 462 00:31:00,240 --> 00:31:06,820 So even though it found more vulnerabilities and you get lots of false positives, they're pretty much all false positives. 463 00:31:06,860 --> 00:31:09,420 So the real stuff just doesn't get found at all, okay? 464 00:31:10,620 --> 00:31:13,680 So skip fish and random, wow. 465 00:31:14,500 --> 00:31:16,160 It doesn't like random. 466 00:31:16,160 --> 00:31:18,380 Let's just say skip fish is particularly picky about it. 467 00:31:18,380 --> 00:31:22,200 So the first scan time took ten hours and the second scan time took four seconds. 468 00:31:24,400 --> 00:31:26,040 Yeah, and then again 16 hours. 469 00:31:26,040 --> 00:31:29,620 I ran it about five times and it would just randomly flick between times. 470 00:31:29,620 --> 00:31:33,440 So skip fish is a wonderful denial of service tool for web applications. 471 00:31:34,200 --> 00:31:40,640 I think in my proxy it sent like 33,000 requests inside five, six minutes. 472 00:31:41,380 --> 00:31:43,480 Yeah, it would pretty much take down everything. 473 00:31:45,800 --> 00:31:49,220 So we're not really slowing attackers down. 474 00:31:49,340 --> 00:31:51,740 So what can we do to slow the attackers down? 475 00:31:52,540 --> 00:31:54,820 What's our WAF really doing at the moment? 476 00:31:55,500 --> 00:32:00,840 A standard WAF, again, a naive view, oh, my God, I'm being attacked. 477 00:32:01,000 --> 00:32:08,480 Block or return an error whether or not that's a 403, a 500, or a 404, or a 200 with a nice message telling them to piss off. 478 00:32:09,880 --> 00:32:10,700 Profit? 479 00:32:10,700 --> 00:32:11,980 There's no profit there. 480 00:32:11,980 --> 00:32:16,620 Okay, for us as defenders, with my defender hat on, we've won nothing. 481 00:32:16,620 --> 00:32:19,880 All we've done is blocked an IP address or blocked an attack. 482 00:32:20,000 --> 00:32:24,720 They come back with an obfuscation, we bypass it, game over, okay? 483 00:32:24,720 --> 00:32:26,780 So why are we doing that? 484 00:32:27,900 --> 00:32:34,200 Remember this big list of things that browsers don't handle very well, specifically the 100 stuff? 485 00:32:34,200 --> 00:32:36,020 Well, scanners don't like them either. 486 00:32:36,500 --> 00:32:40,040 Surprising there, because a scanner thinks it's going to be a browser. 487 00:32:40,040 --> 00:32:42,140 It's trying to do everything that a browser does. 488 00:32:42,140 --> 00:32:46,920 So looking at the 100 codes, we can start to really screw with stuff. 489 00:32:46,920 --> 00:32:49,120 So does anyone remember the library topic? 490 00:32:51,300 --> 00:32:54,380 So it should be Tomlisten, not Timlisten. 491 00:32:55,020 --> 00:32:56,860 Apologies, Tim. 492 00:32:57,580 --> 00:33:02,380 So it was originally designed to slow the spread of code red, and it slows down attackers. 493 00:33:02,380 --> 00:33:03,940 I mean, this was a great idea. 494 00:33:04,720 --> 00:33:07,140 Did we forget that this was a great idea? 495 00:33:07,140 --> 00:33:10,640 Did we think that, okay, well, it's been done now, we can just forget about it? 496 00:33:10,640 --> 00:33:17,640 In our drive to kind of find new and interesting research, it's been done once, so we should just ignore it for the rest of time. 497 00:33:18,400 --> 00:33:20,500 So I had this interesting idea. 498 00:33:20,680 --> 00:33:22,660 How about an HTTP tar pit? 499 00:33:23,600 --> 00:33:29,620 People have probably talked about this a thousand times before, but, you know, it was interesting to me. 500 00:33:29,620 --> 00:33:30,180 Whoa. 501 00:33:34,800 --> 00:33:37,420 This is the problem when you run PowerPoint. 502 00:33:44,860 --> 00:33:48,140 Drink, drink, oh. 503 00:33:53,460 --> 00:33:55,160 Morning DEF CON. 504 00:33:56,380 --> 00:33:58,360 It's Sunday morning, you know what that means? 505 00:33:58,520 --> 00:34:00,820 Drink, that's right. 506 00:34:00,820 --> 00:34:03,120 Say a round of applause for our first-time speaker. 507 00:34:06,960 --> 00:34:08,500 How's he doing so far? 508 00:34:08,540 --> 00:34:09,360 Doing okay? 509 00:34:11,740 --> 00:34:13,100 All right, hook us up. 510 00:34:13,100 --> 00:34:15,080 I am not drinking all of those. 511 00:34:17,620 --> 00:34:20,660 All right, who's first time at DEF CON? 512 00:34:21,040 --> 00:34:23,460 First hand up, right here, come on up on stage. 513 00:34:29,960 --> 00:34:32,580 If it's Sunday morning, that means this is the hard core, right? 514 00:34:32,580 --> 00:34:34,620 Right here, you guys all got up, good job. 515 00:34:34,880 --> 00:34:35,580 All right. 516 00:34:36,100 --> 00:34:36,820 Congratulations. 517 00:34:36,960 --> 00:34:37,500 Cheers. 518 00:34:41,020 --> 00:34:46,880 That reminds me of last night. 519 00:34:50,020 --> 00:34:51,260 So where was I? 520 00:34:52,660 --> 00:34:54,520 Oh, yeah, I was in a tar pit. 521 00:34:54,720 --> 00:34:58,020 So simple scenario. 522 00:34:58,940 --> 00:35:00,600 So the WAF detects the scan. 523 00:35:00,780 --> 00:35:03,360 Again, we are at the oh, my God, attack section. 524 00:35:04,120 --> 00:35:07,020 It adds the IP address to the naughty list. 525 00:35:07,680 --> 00:35:09,860 And then it starts to rewrite all the responses. 526 00:35:10,260 --> 00:35:14,640 So you get the usual 100, 101, 102 status codes. 527 00:35:14,640 --> 00:35:18,640 We just randomly rotate between them, depending on how bored we are all the time. 528 00:35:19,020 --> 00:35:25,040 We can also use 204, 304, which could be useful, but it's not nearly as fun as the 100 status codes. 529 00:35:25,040 --> 00:35:29,040 So let's do some experimentation, shall we? 530 00:35:29,420 --> 00:35:32,000 There's no actual science included in this. 531 00:35:33,420 --> 00:35:36,680 So Nikto, wonderful tool. 532 00:35:37,220 --> 00:35:38,160 I like it a lot. 533 00:35:38,160 --> 00:35:39,660 I especially like the logo. 534 00:35:40,360 --> 00:35:44,920 So the baseline scan, 2 minutes, 18 seconds to find 18 findings. 535 00:35:45,400 --> 00:35:46,720 Simple as that. 536 00:35:47,640 --> 00:35:54,840 With the tar pit, yeah, we're winning some time there. 537 00:35:54,840 --> 00:35:56,040 Let's just say that. 538 00:35:56,640 --> 00:36:01,320 It's like a 340 fold increase in time. 539 00:36:01,320 --> 00:36:03,480 But it's still finding quite a lot of stuff. 540 00:36:03,480 --> 00:36:09,200 This is mostly informational stuff, like you have an Apache whatever version as your server header. 541 00:36:09,380 --> 00:36:13,320 Even if you respond with 100 code, it's still going to get that header. 542 00:36:13,320 --> 00:36:15,280 So most of that stuff is kind of uninteresting. 543 00:36:15,280 --> 00:36:17,800 Some of the findings, they disappear. 544 00:36:18,320 --> 00:36:21,180 And the script kitty spends 14 hours scanning your web server. 545 00:36:21,180 --> 00:36:22,960 So we're kind of winning. 546 00:36:23,380 --> 00:36:29,160 So W3AF, again, same baseline as before, 1 hour, 37 minutes, 65 findings. 547 00:36:29,480 --> 00:36:31,560 But wait a minute, this is going in the wrong direction. 548 00:36:31,580 --> 00:36:33,840 18 minutes instead of 1 hour, 37. 549 00:36:34,200 --> 00:36:35,220 It's weird. 550 00:36:35,220 --> 00:36:36,160 That shouldn't be happening. 551 00:36:36,160 --> 00:36:37,620 But it didn't find anything. 552 00:36:37,680 --> 00:36:47,540 So I'm guessing there was some kind of algorithm there that said I'm just going to stop bothering to scan your web server now because it's kind of weird and I don't know what the fuck is going on. 553 00:36:49,960 --> 00:36:54,420 So yeah, back to the denial of service skip fish tool. 554 00:36:55,920 --> 00:37:07,160 18 minutes, 10 seconds to find around, 2,500 low, mediums and a couple of highs, which unfortunately even on the baseline were mostly false positives, but whatever, each to their own. 555 00:37:07,160 --> 00:37:08,520 So 5 seconds. 556 00:37:09,500 --> 00:37:11,300 Again, we're going in the wrong direction. 557 00:37:11,300 --> 00:37:15,140 But there was no lows and there was no mediums and there was only three highs. 558 00:37:15,660 --> 00:37:21,420 What I thought was interesting was the three highs that it found were not any of the 12 highs that it found previously. 559 00:37:22,400 --> 00:37:27,360 So not only false positives but different false positives to the normal scan. 560 00:37:27,360 --> 00:37:34,780 So okay, it's kind of doing weird stuff and we like weird stuff because we're mucking around with automated scanners and we're screwing the script kiddies. 561 00:37:34,780 --> 00:37:35,760 So random is good. 562 00:37:36,280 --> 00:37:40,440 So Acunetix, as I said before, the script kiddy tool of choice. 563 00:37:41,620 --> 00:37:47,720 So you get a one‑hour scan, it's quite reasonable, with a huge amount of informational stuff that you probably don't care about. 564 00:37:48,440 --> 00:37:55,660 And again, we're going in the wrong direction and this HTTP target should be slowing stuff down but it's making stuff faster depending on what scanner you're using. 565 00:37:56,600 --> 00:38:02,260 But again, okay, that's an interesting ratio of complete false negatives. 566 00:38:02,560 --> 00:38:04,080 So it's just not finding stuff. 567 00:38:04,080 --> 00:38:10,300 So some of these scanners are just like, okay, now this web server is just playing silly buggers, I'm just going to stop bothering to scan it at all. 568 00:38:10,300 --> 00:38:14,420 What's interesting, it doesn't tell you that it's just going to give up. 569 00:38:14,420 --> 00:38:15,700 It just says, I'm finished. 570 00:38:16,280 --> 00:38:17,740 It just says, no, I'm done. 571 00:38:18,560 --> 00:38:20,140 So what do we find? 572 00:38:20,140 --> 00:38:30,220 So you can slow down some scanners, things like Nikto, others give up quicker because they just get tired of getting responses from the server or a timeout and say the server is not there anymore. 573 00:38:30,380 --> 00:38:35,780 If you look through a log file, I'm sure somewhere along the line it says the web server stopped responding even though it didn't. 574 00:38:36,320 --> 00:38:38,840 But you get a lot of unreliable and aborted scans. 575 00:38:38,980 --> 00:38:41,880 So up to 100% less findings. 576 00:38:42,020 --> 00:38:43,580 That's a win for us. 577 00:38:45,480 --> 00:38:49,180 So let's move on to blocking successful exploitation. 578 00:38:49,180 --> 00:38:53,840 So even if someone can get past all of this, they can find a high criticality in your web server. 579 00:38:54,620 --> 00:38:59,540 So we've made it hard for them to find them, but people are going to find these vulnerabilities no matter what. 580 00:38:59,540 --> 00:39:06,960 We've made it so that possibly it's going to take them 15,000 times longer to find the vulnerabilities, but they're going to find stuff. 581 00:39:06,960 --> 00:39:10,200 So let's stop them from popping shells with Metasploit. 582 00:39:11,120 --> 00:39:15,600 Now, how often does Metasploit reference status codes? 583 00:39:16,180 --> 00:39:17,860 Anyone care to guess? 584 00:39:19,900 --> 00:39:20,320 No? 585 00:39:20,320 --> 00:39:22,200 It's about 1,000. 586 00:39:22,420 --> 00:39:23,480 Give or take. 587 00:39:23,480 --> 00:39:36,060 This is not scientifically sound and it depends very much on how people are wording things and how they're using their variables, but this is a simple grab through searching for res.code, resp.code and response.code. 588 00:39:36,060 --> 00:39:39,260 These are the usual things that people use. 589 00:39:39,260 --> 00:39:42,520 And there's lots of dependency on status codes. 590 00:39:42,980 --> 00:39:46,200 Unfortunately even the stuff I wrote uses status codes. 591 00:39:46,200 --> 00:39:54,300 So I know it's bad programming, but it's quick and it's what we all do because we use status codes to check the response from servers. 592 00:39:54,300 --> 00:40:01,640 So here's an example of a simple snippet of code from one of the Metasploit checks. 593 00:40:01,640 --> 00:40:06,920 So all it's doing is checking if the response code is less than a 200 or more than a 300. 594 00:40:08,020 --> 00:40:09,940 So I can return a 500. 595 00:40:10,540 --> 00:40:11,200 That's great. 596 00:40:11,200 --> 00:40:13,440 I can return a 500 with the content. 597 00:40:13,980 --> 00:40:15,380 And then it's failing. 598 00:40:15,800 --> 00:40:21,360 So if it's not anywhere in the 200 range, which is the okay, then the exploit just fails. 599 00:40:21,380 --> 00:40:22,200 Simple as that. 600 00:40:22,260 --> 00:40:23,000 Okay, great. 601 00:40:23,000 --> 00:40:28,780 So if we're spoofing 404 but still giving you the content, then this exploit is always just going to fail. 602 00:40:29,120 --> 00:40:36,580 And if you're good enough to go in and edit the code and change things and you really know what's going on, then you're not really the target of this talk. 603 00:40:36,580 --> 00:40:39,300 We're targeting script kiddies who know absolutely nothing. 604 00:40:39,300 --> 00:40:43,200 All they know how to do is run the code and if it doesn't work they just cry in a corner. 605 00:40:45,080 --> 00:40:54,380 Interesting side effect, if it is a 401, it just starts to print out the response headers like the www authenticate or the authentication header. 606 00:40:54,460 --> 00:40:57,420 Of course, as we mentioned before, we don't need to send those headers. 607 00:40:57,420 --> 00:41:00,860 So what happens if you don't send those headers? 608 00:41:00,940 --> 00:41:11,980 You start to get errors within Metasploit because it's trying to print out stuff that it shouldn't really ‑‑ should be there but it's actually a nil value because we haven't actually set it at all because we haven't provided it. 609 00:41:12,080 --> 00:41:13,680 So that's an interesting side effect. 610 00:41:14,080 --> 00:41:16,140 So no match, no shell. 611 00:41:16,640 --> 00:41:17,200 Okay? 612 00:41:17,200 --> 00:41:18,340 No cookie for you. 613 00:41:18,340 --> 00:41:19,100 Simple as that. 614 00:41:19,580 --> 00:41:22,740 So quickly running through what we've talked about here, okay? 615 00:41:22,740 --> 00:41:26,320 So we can use status codes to our benefit. 616 00:41:26,440 --> 00:41:27,160 It's fun. 617 00:41:27,780 --> 00:41:28,680 It's useful. 618 00:41:28,780 --> 00:41:30,380 We can slow people down with it. 619 00:41:30,960 --> 00:41:32,500 But browsers can be quirky. 620 00:41:32,500 --> 00:41:34,400 So we need to do it in specific ways. 621 00:41:35,120 --> 00:41:39,740 And scanners and attack toolkits are, you know, they're set in their ways. 622 00:41:39,900 --> 00:41:44,320 This is the way we did it in 1990 and goddammit this is the way we're going to do it in 2013. 623 00:41:44,820 --> 00:41:46,260 Get off my lawn. 624 00:41:48,460 --> 00:41:49,840 It's just the way things are. 625 00:41:49,840 --> 00:41:51,720 Why change things if it's working? 626 00:41:52,020 --> 00:41:54,740 So my goal here is to make it not work. 627 00:41:55,620 --> 00:42:02,120 WAFs need to seriously get more offensive about their defense because they're being far too passive as far as I'm concerned. 628 00:42:02,200 --> 00:42:12,520 So just blocking a request, providing a snazzy little ASCII art that tells people to go and scan someone else's web server, it's great and it's fun but it's not really going to help us. 629 00:42:12,720 --> 00:42:14,640 And I'm not talking hacking back. 630 00:42:14,660 --> 00:42:27,940 I don't want to start hacking back people who attack my web service but I want to be more active in fighting back and saying to people that this is not right. 631 00:42:27,940 --> 00:42:31,880 If you're scanning my server I'm going to screw with you and I'm going to screw with you until you cry. 632 00:42:31,920 --> 00:42:34,100 It's just the way things are. 633 00:42:34,100 --> 00:42:36,280 So slowing attackers down is good. 634 00:42:36,880 --> 00:42:40,020 Making life harder for skitties is absolutely priceless. 635 00:42:41,080 --> 00:42:43,140 I should have put the MasterCard logo on that. 636 00:42:43,380 --> 00:42:47,820 So current tools are very much the same as APT. 637 00:42:48,260 --> 00:42:49,520 Yeah, I said that. 638 00:42:50,860 --> 00:42:59,720 They are adequate and they do what they do and until someone fights back and says this is not good enough anymore then they're just going to keep doing what they're doing. 639 00:42:59,720 --> 00:43:00,420 Simple as that. 640 00:43:00,420 --> 00:43:03,240 So they're only advanced as they need to be. 641 00:43:03,380 --> 00:43:04,780 It's just like people attacking you. 642 00:43:04,780 --> 00:43:09,760 If they can get you with a phishing attack then why would I bother wasting a zero day on you. 643 00:43:09,760 --> 00:43:10,580 Simple as that. 644 00:43:11,640 --> 00:43:14,320 I think this is the key to this entire talk. 645 00:43:14,380 --> 00:43:16,260 Screwing with skitties is fun. 646 00:43:17,480 --> 00:43:33,600 I've had this running on my web server for a while now and just checking the logs it's absolutely hilarious the amount of automated scans that hit your web server searching for like Tim Thumb and how long it takes them to finish just a simple scan of your web server. 647 00:43:35,020 --> 00:43:37,720 Just scanning your web server for random stuff. 648 00:43:38,540 --> 00:43:40,540 So how can people implement this? 649 00:43:40,540 --> 00:43:43,700 There's no point in me talking about this stuff if we don't know how we can implement this stuff. 650 00:43:43,820 --> 00:43:46,320 Let's talk about the ghetto option. 651 00:43:46,340 --> 00:43:48,880 We can implement it using PHP. 652 00:43:49,140 --> 00:43:50,920 It's the lowest common denominator. 653 00:43:51,340 --> 00:43:54,160 People probably wrote it in notepad but that's life. 654 00:43:54,160 --> 00:44:04,040 You can auto prepend a PHP file to say randomize the response code within a specific section of response codes that are supported by the browser. 655 00:44:04,480 --> 00:44:07,500 We're limited by resources that are PHP handled. 656 00:44:07,580 --> 00:44:14,540 If your web server starts to error out because people are sending stuff that isn't to be expected then the web server is going to respond back. 657 00:44:14,660 --> 00:44:16,260 There's limited functionality there. 658 00:44:16,260 --> 00:44:17,880 There's man in the middle dump. 659 00:44:19,500 --> 00:44:20,920 It's a real memory hulk. 660 00:44:20,920 --> 00:44:22,580 It will use everything you've got. 661 00:44:22,580 --> 00:44:31,800 If you put man in the middle dump as a reverse proxy in front of your web server you can have simple scripts that are just going to change the response codes. 662 00:44:31,800 --> 00:44:32,540 That works. 663 00:44:32,540 --> 00:44:33,140 It works. 664 00:44:33,140 --> 00:44:34,740 But it's not the best solution. 665 00:44:34,740 --> 00:44:38,760 So what's this enterprise approved solution? 666 00:44:39,180 --> 00:44:41,200 Everyone knows NGINX, right? 667 00:44:41,680 --> 00:44:43,340 It's like Apache but better. 668 00:44:44,700 --> 00:44:46,920 It's a usable implementation. 669 00:44:47,500 --> 00:44:50,260 NGINX is used quite often as a reverse proxy. 670 00:44:51,140 --> 00:44:59,280 And if you use something like NGINX lure you can write some interesting scripts that are going to change the response codes that are going out of NGINX. 671 00:44:59,740 --> 00:45:05,660 So you simply load NGINX lure and using NGINX status you can specifically set stuff. 672 00:45:05,800 --> 00:45:10,180 So the only problem is there's kind of a few bugs in the non‑Git version. 673 00:45:10,340 --> 00:45:16,440 Specific codes that are supported just tend to get returned as nil which is kind of a pain. 674 00:45:16,440 --> 00:45:21,760 But if you use the version from Git it shouldn't be so much of a problem. 675 00:45:22,280 --> 00:45:30,600 But if you do an apt‑get install and install NGINX and install the optional extras you're going to run across a couple of problems. 676 00:45:31,220 --> 00:45:34,680 So what does the future hold? 677 00:45:34,720 --> 00:45:36,000 What's the next step? 678 00:45:36,000 --> 00:45:45,240 Well, the next step, I've been trying to get this into mod security to ease adoption by implementing it into something that people are using already on a daily basis. 679 00:45:45,240 --> 00:45:48,440 Because no one wants to implement another layer of stuff. 680 00:45:48,680 --> 00:45:52,400 Because the more you install, you're increasing your attack surface. 681 00:45:52,400 --> 00:45:58,760 So you want to put something, change a couple of configuration files in mod security and just have it do this stuff without you having to think about it. 682 00:45:58,820 --> 00:46:00,060 But it's not simple. 683 00:46:00,060 --> 00:46:01,040 It's not easy. 684 00:46:01,640 --> 00:46:08,760 I've been discussing it with various people for about a year and everyone is like, yeah, that should be possible, maybe, kind of. 685 00:46:09,780 --> 00:46:11,120 But I don't know how. 686 00:46:11,960 --> 00:46:16,280 So this is kind of a long shot, but I need some help with this stuff. 687 00:46:16,360 --> 00:46:26,200 I'm not a C coder and I'm not into writing Apache modules, but if anyone is interested in this kind of stuff and they really want to implement it into mod security, then I would really appreciate their help. 688 00:46:27,120 --> 00:46:29,440 So how do we counter this research? 689 00:46:29,820 --> 00:46:32,000 We've told the scanners that they're crap. 690 00:46:32,060 --> 00:46:36,240 We've told the scanners that they aren't doing stuff in the right way. 691 00:46:37,040 --> 00:46:38,800 I really need a new microphone here. 692 00:46:39,560 --> 00:46:42,380 So less reliance on status codes. 693 00:46:42,420 --> 00:46:49,880 I know it's easy to say, but we're going to have to slow scanners down in order for them to be more reliable. 694 00:46:50,020 --> 00:46:53,640 Because right now they're just taking the response codes and ignoring everything else. 695 00:46:53,640 --> 00:46:57,440 So start paying more attention to the actual content of the site itself. 696 00:46:57,440 --> 00:47:01,240 Some scanners are doing this already, but things need to be double‑checked. 697 00:47:01,240 --> 00:47:03,740 You get better matching if you do that. 698 00:47:03,740 --> 00:47:06,740 The problem is Regex matching is kind of slow. 699 00:47:07,160 --> 00:47:11,800 It's going to use more memory, it's going to take more time, it's not easy. 700 00:47:11,940 --> 00:47:13,820 But this is the cat and mouse game. 701 00:47:14,180 --> 00:47:25,740 Every time we come up with something new or increase our security, then people who are attacking websites or testing websites increase the productivity and increase the accuracy of their tools. 702 00:47:25,820 --> 00:47:29,400 So hopefully we can move this to the next level. 703 00:47:30,500 --> 00:47:33,700 So that's all I've got. 704 00:47:33,700 --> 00:47:34,740 Any questions? 705 00:47:35,580 --> 00:47:36,580 So, yeah. 706 00:47:47,760 --> 00:47:55,860 So the question is, have I specifically looked at detecting specific scanners and how they look when they're attacking a web server? 707 00:47:56,440 --> 00:47:58,500 Yes, I have looked at it. 708 00:47:58,500 --> 00:48:00,820 Not as part of this research, as part of other research. 709 00:48:00,820 --> 00:48:02,040 Yeah, it's interesting stuff. 710 00:48:02,040 --> 00:48:05,660 You can also detect quite easily when Nikto is attacking your website. 711 00:48:07,020 --> 00:48:09,680 The problem is, it's the same as this stuff. 712 00:48:09,680 --> 00:48:17,380 As soon as you start detecting how specific scanners look when they hit your website, the scanners are just going to start randomizing how they request stuff. 713 00:48:17,380 --> 00:48:21,240 So it's another step in the kind of cat and mouse game. 714 00:48:21,280 --> 00:48:22,480 So, yeah. 715 00:48:26,140 --> 00:48:26,600 Okay 716 00:48:31,140 --> 00:48:31,600 . 717 00:48:33,200 --> 00:48:37,100 Yeah, so F5, you can write scripts to specifically do this stuff. 718 00:48:37,100 --> 00:48:38,420 So it's interesting. 719 00:48:38,420 --> 00:48:41,060 So I'm sure everyone here has an F5, yeah. 720 00:48:42,280 --> 00:48:43,400 So, yeah. 721 00:48:46,720 --> 00:48:50,520 So yeah, the question was, do different versions of browsers respond in different ways? 722 00:48:50,840 --> 00:48:55,420 At the beginning of my testing, I was checking all the different versions of IE. 723 00:48:55,700 --> 00:48:59,500 IE6 tends to do things in a kind of weird way. 724 00:48:59,780 --> 00:49:02,380 You get some weird stuff. 725 00:49:02,680 --> 00:49:06,200 Like with the 100 codes, it tries to download stuff. 726 00:49:06,480 --> 00:49:11,200 But it's ‑‑ between specific versions, they don't tend to change the logic at all. 727 00:49:11,220 --> 00:49:12,900 So I'm getting the wave. 728 00:49:12,900 --> 00:49:21,040 So if anyone has any further questions or any further comments, the code is available on my GitHub site. 729 00:49:21,100 --> 00:49:24,440 I'd just like to leave you with the thought that whatever doesn't kill you makes you smaller. 730 00:49:24,760 --> 00:49:25,580 Thank you.