1 00:00:13,580 --> 00:00:15,060 Hey, welcome back. 2 00:00:15,060 --> 00:00:22,820 Hey, AppSecVillage, we're getting down to the last few speakers of our time together here on day three of AppSecVillage at DEF CON 2020. 3 00:00:22,820 --> 00:00:26,980 I want to thank you for coming and for making this possible. 4 00:00:26,980 --> 00:00:31,280 I want to make sure to thank our sponsors and the folks that run AppSecVillage. 5 00:00:31,600 --> 00:00:34,580 They've done a wonderful job both years that we've been here. 6 00:00:34,580 --> 00:00:37,360 This has become my home away from home when I come to DEF CON. 7 00:00:37,360 --> 00:00:40,900 I look forward to it every year and I hope you do too. 8 00:00:40,900 --> 00:00:46,940 And I hope to see you again next year when we do this, hopefully in person, but we're going to do it one way or the other. 9 00:00:47,000 --> 00:00:52,300 Our next discussion is going to be Secure Your Code, Injections and Logging by Philip Kren. 10 00:00:52,300 --> 00:00:55,080 Philip lives to demo interesting technology. 11 00:00:55,200 --> 00:01:02,720 Having worked as a web infrastructure and database engineer for more than 10 years, Philip is now working as a developer advocate at Elastic. 12 00:01:03,120 --> 00:01:15,850 Based in Vienna, Austria, he is consistently traveling Europe and beyond to speak and discuss on topics such as open source software, search technology, databases, infrastructure, and security in general. 13 00:01:16,160 --> 00:01:19,560 Please welcome Philip to the AppSecVillage stage. 14 00:01:20,620 --> 00:01:22,240 Hi, I'm Philip. 15 00:01:22,240 --> 00:01:24,520 Let's dive into the next session. 16 00:01:24,520 --> 00:01:27,780 Let me share my screen. 17 00:01:28,760 --> 00:01:30,440 And there we go. 18 00:01:30,500 --> 00:01:33,220 Secure Your Code, Injections and Logging. 19 00:01:33,220 --> 00:01:34,720 Let's see what we can do here. 20 00:01:34,840 --> 00:01:44,320 So when we talk about security, we normally keep telling ourselves that everything is fine, especially when we say everybody's job is security. 21 00:01:44,320 --> 00:01:48,740 It's normally nobody's job, and we can all pretend that this is all good. 22 00:01:48,740 --> 00:01:54,480 And then you look at the OWASP top 10, and you see at number one is still injections. 23 00:01:54,480 --> 00:02:07,720 So good old SQL injection, maybe LLAP injection, NoSQL injection, or whatever other form of unsecured user input you are throwing at your application, and that is wreaking havoc. 24 00:02:07,720 --> 00:02:13,520 And then you might reconsider and say like, well, maybe this is not so fine anymore. 25 00:02:13,780 --> 00:02:32,460 And then you look further down the OWASP top 10 list, and then you see, for example, number 10, insufficient logging and monitoring, where you then realize that on average, it takes something like 200 days or so until you normally find a breach, maybe a bit quicker if the attacker asked for some ransomware or ransom money, 26 00:02:32,460 --> 00:02:34,620 but it might take a while. 27 00:02:34,620 --> 00:02:44,400 And then you both or you might end up at the point where you say, well, this is no longer fine or good, and everything is terrible and on fire. 28 00:02:44,400 --> 00:02:46,240 And we don't want to get to this point. 29 00:02:46,240 --> 00:02:48,820 So what can we do about that? 30 00:02:49,440 --> 00:02:50,520 I'm Philipp. 31 00:02:50,520 --> 00:02:54,540 I work for Elastic, the company behind Elasticsearch, Kibana, Beats, Logstash. 32 00:02:54,540 --> 00:02:58,160 You might have heard of us or might be using us already somewhere. 33 00:02:58,160 --> 00:03:00,180 My official title is developer advocate. 34 00:03:00,180 --> 00:03:02,940 So I mostly talk about the good stuff that we do. 35 00:03:02,940 --> 00:03:04,400 And today is no exception. 36 00:03:04,400 --> 00:03:06,360 So let's see what we can do here. 37 00:03:07,020 --> 00:03:10,540 I generally build highly monitored Hello World applications. 38 00:03:11,000 --> 00:03:12,480 Today is no exception. 39 00:03:12,480 --> 00:03:15,700 And we will pretty much dive into that right away. 40 00:03:15,700 --> 00:03:21,880 So like in any good cooking show, I have prepared something and a very bad application. 41 00:03:21,880 --> 00:03:25,400 So xiera.wtf is where this is running. 42 00:03:25,400 --> 00:03:27,340 And I will let this run. 43 00:03:27,340 --> 00:03:30,340 So while this is pre-recorded, I will let the demo run. 44 00:03:30,340 --> 00:03:35,340 So you can actually destroy it or play around with it live afterwards as well. 45 00:03:35,340 --> 00:03:41,320 If you're wondering where Xiera is coming from, it has something to do with my name. 46 00:03:41,320 --> 00:03:43,560 If you're bored, try to figure it out. 47 00:03:43,560 --> 00:03:48,340 And obviously, WTF is the right domain for any demo. 48 00:03:48,340 --> 00:03:50,340 So let's hope this works out. 49 00:03:50,340 --> 00:03:57,400 And let's head over to my very bad and well, average demo application. 50 00:03:57,400 --> 00:04:01,080 So we have some Elastic employees here. 51 00:04:01,080 --> 00:04:07,000 And I added our CEO Shai, one of our co-founders Simon, and myself. 52 00:04:07,460 --> 00:04:11,500 And well, maybe we want to add more employees. 53 00:04:11,500 --> 00:04:14,740 And to do that, obviously, you need to log in. 54 00:04:14,740 --> 00:04:23,080 If you want to regularly log in, my username is Philip, and my password is secret. 55 00:04:23,660 --> 00:04:25,160 This works. 56 00:04:25,160 --> 00:04:33,700 And then we can say, other edition is, I don't know, maybe in New York. 57 00:04:33,720 --> 00:04:38,940 And they have some salary and they also have a password of let's say secret. 58 00:04:38,980 --> 00:04:42,000 Okay, so that worked. 59 00:04:42,000 --> 00:04:47,960 But looking at this form, this is not secure. 60 00:04:47,960 --> 00:04:52,720 And by design, this is using the Hello World application of SQL injections. 61 00:04:52,720 --> 00:05:00,080 So we can just use one parameter like Philip and in the other feed, we will just do an or true. 62 00:05:00,100 --> 00:05:07,120 So I will do an or true and try to log in like that. 63 00:05:07,800 --> 00:05:18,720 This worked, unfortunately, and I can now add a bad user in, I don't know, from Gotham, and have a much higher salary. 64 00:05:18,760 --> 00:05:20,860 And they also have some random password. 65 00:05:21,400 --> 00:05:26,480 Okay, so we have added the bad user, nothing super surprising here. 66 00:05:28,020 --> 00:05:35,560 This has the classic SQL injection problem, I don't escape my user input, I just pass in whatever I'm doing here. 67 00:05:35,560 --> 00:05:45,680 I'm hashing my password, but I'm just breaking out of that and doing or true, for example, or whatever other variation you want to have of this. 68 00:05:46,200 --> 00:05:48,460 You've seen this plenty of times. 69 00:05:48,600 --> 00:05:56,340 It's called an SQL injection, or some people call it accidental GraphQL, if that is more your thing, and which might be the deeper thing. 70 00:05:56,340 --> 00:05:59,600 But classically, this is an SQL injection. 71 00:05:59,600 --> 00:06:05,780 And I'm pretty sure all or most of you have seen little bobby tables. 72 00:06:06,180 --> 00:06:18,120 If you give your child the right name, like drop table students, you will have a lot of fun at school, or your school just should write better systems. 73 00:06:18,120 --> 00:06:19,820 But that's a different discussion. 74 00:06:19,820 --> 00:06:22,900 So let's have another look around. 75 00:06:22,900 --> 00:06:25,440 So I can also display users. 76 00:06:25,440 --> 00:06:30,480 So for example, looking at our CEO shy here, this looks all nice and good. 77 00:06:30,480 --> 00:06:32,560 And you can go back and forth. 78 00:06:32,640 --> 00:06:38,240 What I'm doing here is I'm just passing the ID of my user directly in. 79 00:06:38,240 --> 00:06:41,980 So I could just change that to two and pass over to Simon. 80 00:06:43,480 --> 00:06:49,920 This is insecure, again, like unsurprisingly, since this is a broken application. 81 00:06:49,960 --> 00:06:58,240 And before we try to actually throw some bad parameters as it, I want to quickly jump to SQL map. 82 00:06:58,240 --> 00:07:05,380 If you've never seen or used SQL map, it's an automatic SQL injection and database takeover tool. 83 00:07:05,380 --> 00:07:21,860 And you can basically say like, hey, there is this parameter like the ID and I would like to check that and it will go through a lot of variations of SQL injections to actually say like, well, this looks like it might be interesting or not. 84 00:07:21,860 --> 00:07:30,920 Okay, so let's open my shell and let me paste in my command so you don't have to see me type this. 85 00:07:30,920 --> 00:07:35,120 So I'm running SQL map against that URL that I've shown you. 86 00:07:35,120 --> 00:07:38,440 And at the end, we add a purge because I've run this before. 87 00:07:38,440 --> 00:07:43,000 And purge will just make sure we don't use any records that we've created before. 88 00:07:43,000 --> 00:07:44,780 So we will start fresh. 89 00:07:44,780 --> 00:07:53,000 So we will start running this and SQL map will just figure out what is possible here. 90 00:07:53,000 --> 00:07:57,140 It will ask me a couple of questions of how it should treat this. 91 00:07:58,180 --> 00:08:04,400 So you can see it's already trying to do stuff and it figured out that I'm using MySQL here. 92 00:08:04,400 --> 00:08:06,740 So yes, this is the right database. 93 00:08:06,740 --> 00:08:13,100 And I want to skip tests for other databases because this is MySQL, we can focus on this. 94 00:08:13,100 --> 00:08:18,100 And I'm okay to run these risk level queries here. 95 00:08:19,300 --> 00:08:22,720 So you can see it's trying out various things. 96 00:08:24,780 --> 00:08:31,880 And at the end, it will then tell me what is actually vulnerable. 97 00:08:32,000 --> 00:08:41,320 It will also ask me if it should run or check any other parameters, which we will not do here because there's only one parameter that is interesting. 98 00:08:41,600 --> 00:08:44,920 I don't want to test anything else, so we're done here. 99 00:08:44,920 --> 00:08:55,420 So looking at the result, you can see, for example, okay, this is running against NGINX and against the more or less recent version of MySQL. 100 00:08:55,420 --> 00:09:00,320 We would have some logs in this folder here, though they're not super interesting. 101 00:09:00,320 --> 00:09:05,160 They're mostly what we have here and all the SQL commands that have been running. 102 00:09:05,260 --> 00:09:08,500 So we will stick to what we see here. 103 00:09:08,500 --> 00:09:13,960 So you can see in 81 HTTP requests, we figured out a couple of things. 104 00:09:13,960 --> 00:09:30,880 So for example, we see a Boolean-based blind attack where you can do something like ID 1 and something equals something, or you can have a time -based attack where we add a sleep and we see indeed the query takes that amount of sleep plus a little more maybe, 105 00:09:30,880 --> 00:09:36,000 or that you can have a union query and that you can try to join data together. 106 00:09:36,000 --> 00:09:40,500 So this is clearly vulnerable to something. 107 00:09:40,500 --> 00:09:44,140 So let's have a look of what I have actually in here. 108 00:09:45,540 --> 00:09:47,340 Again, a very bad query. 109 00:09:47,340 --> 00:09:49,080 I'm just taking that parameter. 110 00:09:49,080 --> 00:09:51,080 I'm not escaping it in any way. 111 00:09:51,080 --> 00:09:53,580 I'm just trimming any spaces off of it. 112 00:09:53,760 --> 00:09:57,920 And then I take this query and I run it. 113 00:09:58,580 --> 00:10:04,280 The good thing here, by the way, is that I actually logged the query that people are sending to my system. 114 00:10:04,280 --> 00:10:09,080 So this will help us afterwards to figure out what has actually been happening here. 115 00:10:09,080 --> 00:10:14,260 So we will log this into a var log app log file. 116 00:10:14,320 --> 00:10:20,240 The bad thing here is that I'm using MySQL multi-query. 117 00:10:20,240 --> 00:10:23,760 So this will allow me to run multiple queries in one go. 118 00:10:23,760 --> 00:10:29,480 So besides that select, I might do another insert, for example. 119 00:10:29,840 --> 00:10:43,100 So if I add this to the end of the URL and it will automatically then be URL escaped and work properly, I could just say insert into employees some bad actor. 120 00:10:43,100 --> 00:10:48,580 So if I run that, let's see in our application. 121 00:10:49,400 --> 00:10:53,060 Right now we have a bad user, but we don't have a bad actor. 122 00:10:53,060 --> 00:11:04,000 So if I have to that parameter here, I just add after semicolon the insert statement, run this, it looks like nothing happened. 123 00:11:04,000 --> 00:11:08,480 But when I go back here, you now have a bad actor. 124 00:11:08,840 --> 00:11:13,440 So this works as expected or not expected. 125 00:11:13,820 --> 00:11:16,120 Maybe this is mostly up to your expectation. 126 00:11:16,120 --> 00:11:21,020 By the way, this doesn't escape like the visualization in any way or the output. 127 00:11:21,020 --> 00:11:30,460 So you could run any random JavaScript here, which I didn't do because it will be kind of annoying to have various pop-ups pop up. 128 00:11:30,480 --> 00:11:34,120 You could break the entire site with some weird JavaScript. 129 00:11:34,160 --> 00:11:36,080 So there is no other protection here. 130 00:11:36,080 --> 00:11:38,600 So we don't do any escaping. 131 00:11:38,600 --> 00:11:42,360 So this is easy to pick apart. 132 00:11:43,600 --> 00:11:45,840 So what's going on in our application? 133 00:11:45,840 --> 00:11:54,420 Now is the interesting part, like at first before I want to secure it, I want to get a bit of a better idea of what even has been going on in my application. 134 00:11:55,080 --> 00:12:00,120 And yeah, if you don't have any log files, nobody can remove your log files. 135 00:12:00,120 --> 00:12:06,640 So let's assume we want to have log files and we also want to ship them off and have them hopefully in a secure location. 136 00:12:06,640 --> 00:12:17,740 So even if somebody breaks into that instance and manipulates it, they cannot actually do anything with your logs and you still keep some trace of what has been happening. 137 00:12:18,120 --> 00:12:23,460 So we want to collect all the things and having a log file is a very good starting point. 138 00:12:23,460 --> 00:12:26,800 Maybe ship it off in case somebody breaks into the instance. 139 00:12:27,120 --> 00:12:32,480 The main downside is these log files have the ugly tendency to get very large. 140 00:12:32,480 --> 00:12:42,400 So maybe at some point you end up as this little submarine, basically, and then you have gigabytes and gigabytes of log files in which you try to find something. 141 00:12:42,760 --> 00:12:46,020 Maybe successfully, maybe not so successfully. 142 00:12:47,320 --> 00:12:55,360 Scrap is great until you have multiple servers and various big log files, because then it's not going to be so much fun. 143 00:12:55,360 --> 00:12:59,620 So you probably want to use something else that is making your life a bit easier. 144 00:12:59,820 --> 00:13:03,860 One of the most wily tools there probably is the Elk Stack. 145 00:13:03,860 --> 00:13:11,580 You can see Elasticsearch, Logstash, and Kibana, one sitting on top of the other, and that makes up the good old Elk. 146 00:13:11,640 --> 00:13:20,660 So Elasticsearch is the thing that stores your data, Logstash is the thing that gets, parses, and enriches your data, and Kibana can visualize it. 147 00:13:20,660 --> 00:13:28,420 By the way, when I say parse, you normally have some logline, and out of that logline you want to extract some piece of information . 148 00:13:29,000 --> 00:13:37,080 So, for example, you have a log level, or you have the URL where something came from, or maybe you have some user information, or a timestamp. 149 00:13:37,080 --> 00:13:54,360 All of these you might want to extract to actually be able to filter down and then say, oh, give me all the logs from this specific time frame, or for this specific user, or for this specific application, or URL within the application, or any way you want to slice and dice your data. 150 00:13:55,160 --> 00:14:11,680 When I say enrich, it might be something like you have the IP address of the person requesting the website, and then you could add the GeoIP information to that IP address, and then you could draw it out on a map, and then you could draw where are all my visitors coming from, 151 00:14:11,680 --> 00:14:12,500 for example. 152 00:14:12,500 --> 00:14:20,720 Or you could just filter down and say like, oh, give me all the users coming from Russia or China, because that's kind of unusual. 153 00:14:20,720 --> 00:14:22,640 I normally don't have any visitors from there. 154 00:14:22,700 --> 00:14:25,900 Let's figure out what they have been up to. 155 00:14:26,780 --> 00:14:28,100 That works. 156 00:14:28,300 --> 00:14:36,080 The only thing is that by now the stack has evolved slightly, so we still have Kibana for the visualization Elasticsearch that stores it. 157 00:14:36,080 --> 00:14:41,000 Sometimes, by the way, people are slightly confused and ask like, what is the database behind Elasticsearch? 158 00:14:41,000 --> 00:14:43,260 There is no other database anymore. 159 00:14:43,420 --> 00:14:51,620 There is the library Apache Lucene, which writes it down to disk, but otherwise there is no other data store behind that anymore. 160 00:14:52,260 --> 00:15:06,080 Logstash is still that versatile, bit more like ETL tool, so extract, transform, load, so it can get data from various systems, change and transform that, then push that out to Elasticsearch or other systems. 161 00:15:06,440 --> 00:15:14,120 But to make life a bit easier and also slimmer, we have added bits in various versions so far. 162 00:15:14,120 --> 00:15:23,020 So, for example, for log files, we have Filebit, and it basically tails a file over the network and a bit on steroids. 163 00:15:23,020 --> 00:15:30,320 So, we basically will say like, this is a log file that I'm interested in, take that, tail it, store it into Elasticsearch. 164 00:15:30,320 --> 00:15:40,360 To keep my demo simple, I will actually skip Logstash and Filebit will tail my log file, put the data into Elasticsearch, and then we can visualize it in Kibana directly. 165 00:15:41,840 --> 00:15:46,580 So, let's see what we have actually here. 166 00:15:46,580 --> 00:15:55,340 So, maybe before we dive into the visualization, let's take a very quick look at what we have done here. 167 00:15:55,340 --> 00:16:04,560 So, this is the configuration of this entire demo, and this is all being set up automatically, so you can get all the configs afterwards. 168 00:16:04,760 --> 00:16:10,220 What I have done here is, there are maybe two interesting things in this file. 169 00:16:10,220 --> 00:16:13,280 So, this is the Filebit configuration HTML. 170 00:16:13,360 --> 00:16:20,920 What will be interesting at first is, so, I'm getting some log files from the system, and there are so-called modules. 171 00:16:20,980 --> 00:16:24,680 These are four well-known things that you have often installed. 172 00:16:24,680 --> 00:16:38,540 So, for example, I have Nginx running here, as we have seen in SQLMAP before, and it will know automatically for the server that I'm running, where is that log file located by default, and what does it look like. 173 00:16:38,540 --> 00:16:50,100 So, basically, by saying, use this Nginx module, it will then pick up the right file, be able to parse it in its individual pieces, and then store it, and we're done. 174 00:16:50,100 --> 00:16:54,800 We don't need to care about any log file locations or anything anymore. 175 00:16:54,800 --> 00:17:00,520 With that var log app log, which my application is writing, it's not so standardized. 176 00:17:00,520 --> 00:17:08,120 So, for this one, I have this configuration here, where I basically tell FileGrid, this is the file that you need to collect. 177 00:17:08,240 --> 00:17:26,020 So, it is of the type log, this is the path, you could also use a wildcard and point to a directory, for example, and then what is also interesting, I will store this with an additional field called application app, and this is what we will be able to filter on right away, 178 00:17:26,020 --> 00:17:33,440 because I'm collecting all these other logs, so we might see a lot of logs coming together in Kibana right away. 179 00:17:33,620 --> 00:17:36,500 So, let's take a quick look. 180 00:17:36,520 --> 00:17:41,680 So, maybe you have used Discover before, which was the kind of like old way to do that. 181 00:17:41,680 --> 00:17:49,600 We have now a dedicated logs UI, where you can filter down and live stream data. 182 00:17:49,600 --> 00:17:58,700 So, with the live streaming, this is a bit more like tail F, where you just see all the log messages that come in right away. 183 00:17:58,700 --> 00:18:05,460 So, whatever happened here to my SQL, we might investigate that later on, but it will just live tail anything that is happening here. 184 00:18:05,460 --> 00:18:21,540 But what I'm interested in right now is application, as I have said that before, and let me change my screen zoom in slightly, and my application's name was app. 185 00:18:21,560 --> 00:18:28,060 So, I just want to filter down only on the application that I'm running here. 186 00:18:28,060 --> 00:18:35,200 I don't want to see anything about Apache, or Nginx, or anything else that I have running. 187 00:18:35,680 --> 00:18:36,800 Here we go. 188 00:18:36,840 --> 00:18:41,640 So, this is the log file of my log that I have collected. 189 00:18:41,640 --> 00:18:51,080 So, you can see here from the login page, this is where I was logging in successfully with Philip and Sigrid. 190 00:18:52,260 --> 00:18:59,420 I can see that here I created, for example, my other realistician that you saw. 191 00:18:59,420 --> 00:19:05,520 Then here you can see the SQL injection as I was running it already. 192 00:19:06,100 --> 00:19:12,740 And then you can see here, these are the tests that SQL map has been running. 193 00:19:12,740 --> 00:19:16,360 And you can see as or whatever has happened here. 194 00:19:16,360 --> 00:19:19,000 You can also live stream these here. 195 00:19:19,000 --> 00:19:22,800 So, you would just see any SQL queries that come in here. 196 00:19:22,800 --> 00:19:27,520 So, for example, this one here at the very end, this was the last query that I ran. 197 00:19:27,880 --> 00:19:39,020 When I ran or added to the parameter of the ID one, I added the insert statement and added that bad actor value to my data store. 198 00:19:39,020 --> 00:19:42,040 So, this is what happened here in the very last statement. 199 00:19:42,360 --> 00:19:47,500 So, this is all pretty easy to see what my application has been doing. 200 00:19:47,500 --> 00:19:54,920 As long as you write out the right log statements that make sense, you can then easily collect them and see what is happening here. 201 00:19:54,920 --> 00:19:59,540 And you can also correlate that, for example, with the nginx logs, for example, afterwards. 202 00:20:02,440 --> 00:20:04,320 I hope that makes sense so far. 203 00:20:04,380 --> 00:20:07,560 Oh, by the way, you could also search in this one here with highlighting. 204 00:20:07,560 --> 00:20:11,200 You could then just say, let's quickly do that. 205 00:20:11,200 --> 00:20:15,540 In highlighting, I want to search for insert. 206 00:20:15,540 --> 00:20:18,560 And I'm only interested in the insert statements right now. 207 00:20:18,560 --> 00:20:20,720 So, we have one insert here. 208 00:20:21,120 --> 00:20:24,900 So, highlighting, another point done. 209 00:20:24,900 --> 00:20:26,260 Let's move on. 210 00:20:26,960 --> 00:20:41,000 If you try to delete any record or drop the entire table, this will not work, by the way, because if I was running this live, it would be very annoying if suddenly all the data was gone and I couldn't demo anything anymore. 211 00:20:41,000 --> 00:20:47,820 So, the user that is running the SQL queries doesn't have the permissions to delete or drop anything. 212 00:20:47,820 --> 00:20:49,440 Feel free to try it. 213 00:20:49,540 --> 00:20:55,580 You can see it in the logs, but your requests will fail because those commands are not allowed here. 214 00:20:56,020 --> 00:21:01,360 Now, we know that something is happening, but we also want to protect against it. 215 00:21:01,360 --> 00:21:05,800 And that is where mod security is coming into play here. 216 00:21:05,800 --> 00:21:08,880 So, what is mod security if you have never used it? 217 00:21:08,880 --> 00:21:10,740 It's an open source tool. 218 00:21:10,740 --> 00:21:13,220 It's a web application firewall. 219 00:21:13,220 --> 00:21:23,980 It's basically intercepting your traffic and either monitoring stuff or even blocking or fixing things as it goes along. 220 00:21:23,980 --> 00:21:32,540 And it is based on rules where, for example, this is an SQL injection, so I will deny that request, for example. 221 00:21:32,840 --> 00:21:36,220 It has two sets of rules. 222 00:21:36,220 --> 00:21:41,520 There is a free core rule set that you can use that I'm using in my demo as well here. 223 00:21:41,520 --> 00:21:47,740 So, for example, it can have a real-time blacklist lookup to deny certain things. 224 00:21:47,740 --> 00:21:52,600 It can try to figure out an HTTP denial of service attack. 225 00:21:52,600 --> 00:21:56,300 It can detect SQL injections and other things. 226 00:21:56,300 --> 00:22:07,040 There is also a commercial version which has a totally separate rule set which has some more additional or maybe more advanced features. 227 00:22:07,040 --> 00:22:12,940 Though I'm not using that here, I'm only sticking to the free version of the core rule set. 228 00:22:13,580 --> 00:22:25,400 So, to make this simple, I have the same vulnerable application running behind Apache as well, only that Apache is running on port 8080. 229 00:22:25,400 --> 00:22:27,240 So, the code is exactly the same. 230 00:22:27,240 --> 00:22:29,900 It's even referencing the same files and everything. 231 00:22:29,900 --> 00:22:34,680 It's just Apache has more security added as well. 232 00:22:34,680 --> 00:22:40,060 So, if I run my SQL map against that... 233 00:22:42,340 --> 00:22:46,680 So, let's run the SQL map command against Apache. 234 00:22:46,680 --> 00:22:51,280 So, I'm adding this against port 8080 now. 235 00:22:51,280 --> 00:22:52,840 Let's run this. 236 00:22:54,840 --> 00:22:58,460 This won't be as successful as before. 237 00:22:59,640 --> 00:23:01,820 So, you can see it is running. 238 00:23:01,820 --> 00:23:04,220 It hasn't figured out the database yet. 239 00:23:05,180 --> 00:23:11,300 And it will not because it cannot really see any of the typical MySQL things. 240 00:23:12,020 --> 00:23:19,070 Do I want to reduce the number of requests? 241 00:23:19,070 --> 00:23:21,010 No, I don't want to reduce the number of requests. 242 00:23:21,010 --> 00:23:23,350 It should run all the requests here. 243 00:23:23,470 --> 00:23:26,510 So, please try everything you can. 244 00:23:31,030 --> 00:23:38,170 And it's actually telling me that 126 times it ran into a 403, so into a forbidden. 245 00:23:38,170 --> 00:23:42,990 It actually says that potentially this is running behind a web application firewall. 246 00:23:42,990 --> 00:23:58,410 So, we could, with the dash dash tamper command, we could run various ways to tamper the requests so that maybe they are not being detected by mod security or a web application firewall in general. 247 00:23:58,410 --> 00:24:09,970 So, with sqlmap dash dash list tamper, it will show you all the different ways or all the different scripts that are included to avoid tampering. 248 00:24:09,970 --> 00:24:16,790 There are some which are specific to mod security, for example, but they don't make any difference for our example here. 249 00:24:16,790 --> 00:24:21,490 So, I will keep this simple and I will just add the tampering. 250 00:24:21,490 --> 00:24:23,610 So, I will use a random agent. 251 00:24:24,150 --> 00:24:28,650 So, if somebody tried to block on a specific user agent, we would avoid that. 252 00:24:28,650 --> 00:24:36,430 And then we add spaces to the comments to maybe avoid detection, which won't be successful here. 253 00:24:36,890 --> 00:24:41,390 But, well, yeah. 254 00:24:41,830 --> 00:24:46,070 Now, it did detect that this is protected by something. 255 00:24:46,070 --> 00:24:50,930 I still want to continue my investigation. 256 00:24:52,370 --> 00:25:02,530 But again, it won't be successful and it won't circumvent mod security in the current default implementation that I have. 257 00:25:02,530 --> 00:25:05,470 I don't want to reduce the number of requests again. 258 00:25:05,470 --> 00:25:08,090 I just want to run this plainly. 259 00:25:13,160 --> 00:25:13,880 Okay. 260 00:25:13,880 --> 00:25:18,400 And we have the same result, 118 requests were forbidden. 261 00:25:18,400 --> 00:25:22,320 So, we have just 403 results here. 262 00:25:23,660 --> 00:25:26,120 Well, that is what you get. 263 00:25:27,860 --> 00:25:33,660 Which leads us, by the way, so we could do two things here to actually look at. 264 00:25:33,660 --> 00:25:40,980 So, in the logs, let's trash this filter here. 265 00:25:40,980 --> 00:25:47,100 And in the logs, just let me make this slightly smaller so I can see what I'm typing here. 266 00:25:47,320 --> 00:25:56,920 So, we could, for example, say Apache error module and I want any. 267 00:25:57,240 --> 00:26:03,880 So , and now you can see these are all Apache messages that we have been collected. 268 00:26:03,900 --> 00:26:08,600 So, here now I'm in the live streaming mode. 269 00:26:08,600 --> 00:26:13,660 You can see these were rejected by mod security already. 270 00:26:13,660 --> 00:26:18,440 We can, by the way, look at the details of one request here. 271 00:26:19,300 --> 00:26:23,460 So, you can see that this is running. 272 00:26:24,300 --> 00:26:25,780 Filebit has collected it. 273 00:26:25,780 --> 00:26:28,780 I have this enriched this, by the way, with the cloud information. 274 00:26:28,780 --> 00:26:31,900 So, you can see that this is running in an AWS data center. 275 00:26:31,900 --> 00:26:35,720 You can see the AMI ID on which this is based, the instance ID. 276 00:26:35,720 --> 00:26:39,820 So, you could correlate this, for example, to a specific instance ID. 277 00:26:39,820 --> 00:26:46,060 Or I have also added the host information, which is like the operating system. 278 00:26:46,060 --> 00:26:54,520 So, for example, if an attack is only successful against a specific version of Ubuntu, for example, you could easily filter down on this as well. 279 00:26:54,520 --> 00:27:03,320 So, here you could just say, like, give me everything that is Ubuntu 18.04.4, because I know only this one is vulnerable to some specific attack. 280 00:27:03,320 --> 00:27:12,640 And then you could just see the logs only for this one, which is not the case here, but just as an additional idea of what kind of information you might want to add. 281 00:27:12,660 --> 00:27:14,520 And then you can see this was an error. 282 00:27:14,520 --> 00:27:18,740 And you can see here the error came from mod security, actually. 283 00:27:18,740 --> 00:27:24,940 And since I have live streaming on, let me run my tests once more. 284 00:27:24,940 --> 00:27:28,540 And we should see... let me close this one here. 285 00:27:28,860 --> 00:27:37,000 We should see, from this timestamp here, we should see stuff move on a bit. 286 00:27:38,720 --> 00:27:41,820 I mean, it will take a little while. 287 00:27:41,820 --> 00:27:43,480 So, I run my attack. 288 00:27:43,480 --> 00:27:45,200 Apache is generating the log file. 289 00:27:45,200 --> 00:27:48,180 File bit is picking up the logs. 290 00:27:48,180 --> 00:27:50,800 And then it will be stored in Elasticsearch. 291 00:27:50,800 --> 00:27:53,080 And after that, you can then see it in Kibana. 292 00:27:53,080 --> 00:28:01,180 And you can see here now it is appearing in Kibana that this was the attack that has just been happened. 293 00:28:01,260 --> 00:28:05,080 So, you can see the anomaly score is 65. 294 00:28:05,080 --> 00:28:10,120 And it was because of these individual pieces that mod security figured out. 295 00:28:10,120 --> 00:28:21,540 So, we have an SQL injection, cross-site scripting, remote filing inclusion, local file inclusion, remote code execution. 296 00:28:21,540 --> 00:28:25,040 So , all of these factor into a total score. 297 00:28:25,080 --> 00:28:28,860 And then, based on the threshold, an attack might be... 298 00:28:28,860 --> 00:28:31,240 or a request might be blocked or not. 299 00:28:31,240 --> 00:28:36,660 And this one here has been because it definitely breached the rules here. 300 00:28:37,000 --> 00:28:48,780 So, the other thing that I actually wanted to show you is in Kibana, you can also have as a dashboard, you can see a bit of an overview of what is happening in your system. 301 00:28:48,780 --> 00:28:54,180 So, for example, you could see here, these were the average or the general requests that have been running. 302 00:28:54,180 --> 00:28:59,260 And let me refresh this view because I think this data is slightly outdated now. 303 00:29:00,320 --> 00:29:04,380 So, this one here just shows you the number of requests you can see here. 304 00:29:04,380 --> 00:29:08,640 These were the requests that I have just been running with the SQL map. 305 00:29:08,640 --> 00:29:10,960 So, that's why they are peaking here a bit. 306 00:29:10,960 --> 00:29:13,520 And the different shades of green are not ideal. 307 00:29:13,520 --> 00:29:16,580 Let me change this to more this pinkish. 308 00:29:16,580 --> 00:29:21,500 And I don't know, this I'll change to blue so we can keep them a bit better apart. 309 00:29:21,500 --> 00:29:25,440 But you can see, for example, these here are the 403s. 310 00:29:25,440 --> 00:29:29,220 And we ran into a lot of 403s with more security now. 311 00:29:29,220 --> 00:29:31,500 Or you could see where the requests are coming from. 312 00:29:31,500 --> 00:29:33,840 So, this here would be me. 313 00:29:34,500 --> 00:29:37,020 We surprisingly have some requests from the U.S. 314 00:29:37,020 --> 00:29:37,880 as well. 315 00:29:38,840 --> 00:29:44,660 Nothing from Russia or China today, which is almost disappointing. 316 00:29:45,200 --> 00:29:48,780 But depending on the day, you might have more requests from there. 317 00:29:48,780 --> 00:29:58,060 And then you could, for example, see which URLs were hit the most and what response codes you got, what clients or browsers people used, how many errors you have. 318 00:29:58,060 --> 00:30:06,980 And here you can see these are, for example, the errors that are the Apache log that have been generated by more security. 319 00:30:06,980 --> 00:30:08,440 And you can see all of those. 320 00:30:08,440 --> 00:30:19,380 By the way, you could filter just on the notices here or just on the errors if you have too much noise or just on one specific browser or user agent, just to drill down into that data. 321 00:30:19,380 --> 00:30:23,860 Since this is all based on a search engine, this is kind of the value of having a search engine. 322 00:30:23,860 --> 00:30:27,400 You can easily drill down and filter into all of that data. 323 00:30:27,400 --> 00:30:30,140 So, this is what you can see in the dashboard here. 324 00:30:30,880 --> 00:30:33,900 But let's take another look at ModSecurity. 325 00:30:34,320 --> 00:30:41,880 So, in ModSecurity, you have the setting SecRuleEngine and you have it either off detection only or on. 326 00:30:41,880 --> 00:30:49,500 So, I have set it to on and that's what blocked the request, especially when you want to roll this out to a production site. 327 00:30:49,500 --> 00:30:56,940 You probably want to start with detection only to see what would happen if I would run this or if this would be active. 328 00:30:56,940 --> 00:31:02,820 And then you might find interesting things like in San Francisco, there's Union Square. 329 00:31:02,820 --> 00:31:17,540 And I think ModSecurity had a bug at some point where it saw Union anywhere in the post request, for example, and assumed that this was an SQL Union attack, even though it was a regular address that was just Union Square. 330 00:31:17,540 --> 00:31:18,840 It would block that. 331 00:31:18,840 --> 00:31:24,400 And I think the rules got slightly smarter now, so that this is not having this false positive. 332 00:31:24,400 --> 00:31:32,960 But it's just one thing that you might run into and you might create a bad user experience by being a bit too over-ambitious with your security settings. 333 00:31:32,960 --> 00:31:39,540 So, that's why it makes sense to actually start with detection only and then review what is happening. 334 00:31:39,860 --> 00:31:48,740 You can also limit how big file uploads are, for example, here or how big a post request can be. 335 00:31:48,960 --> 00:31:56,340 So, these here would just limit how big requests are so that nobody can overload your server with unnecessarily large requests. 336 00:31:56,340 --> 00:32:01,780 And obviously, it would make sense to change those to some reasonable value for your setup. 337 00:32:02,580 --> 00:32:17,240 In terms of logging, what would be very helpful is if you turned the logging format to JSON, because the non-JSON format is pretty terrible to parse and nobody wants to do that. 338 00:32:17,240 --> 00:32:19,340 By the way, how would you parse that? 339 00:32:19,340 --> 00:32:20,760 How do you normally parse? 340 00:32:20,760 --> 00:32:22,360 Writing a regular expression. 341 00:32:22,360 --> 00:32:24,940 Who enjoys writing a regular expression? 342 00:32:25,360 --> 00:32:27,040 I guess not so many. 343 00:32:27,040 --> 00:32:37,180 Those who say they do, I would always say that this is the Stockholm syndrome, that you got so used to writing regular expressions that you kind of accepted that this is the right way to do stuff. 344 00:32:38,160 --> 00:32:40,900 But I am lazy and you should be lazy too. 345 00:32:40,900 --> 00:32:44,080 So, if you can avoid it, don't write regular expressions. 346 00:32:44,080 --> 00:32:47,140 It's just... maybe it's job security. 347 00:32:47,140 --> 00:32:49,020 So, maybe that's why you would want to do it. 348 00:32:49,020 --> 00:32:54,380 But otherwise, it's just a lot of work and it might go wrong and there are too many edge cases. 349 00:32:54,380 --> 00:33:02,420 So, if you can have something in a structured format, ideally JSON, since Elasticsearch also stores JSON, that would definitely be preferred. 350 00:33:02,420 --> 00:33:04,300 So, that is what I have done here. 351 00:33:04,300 --> 00:33:08,420 I have taken that JSON format. 352 00:33:08,880 --> 00:33:13,200 Who remembers where or as what we have stored it? 353 00:33:13,200 --> 00:33:17,460 How would I see my logs for that? 354 00:33:17,720 --> 00:33:20,000 Let me switch back here. 355 00:33:21,280 --> 00:33:22,440 Let's remove this. 356 00:33:22,440 --> 00:33:23,860 It was application. 357 00:33:26,570 --> 00:33:31,770 Space, colon, and it was mod security. 358 00:33:32,110 --> 00:33:46,140 And if I stop streaming and filter down on this one, it will show me just the logs from mod security. 359 00:33:46,600 --> 00:33:51,240 Which has, even though it's a JSON format, has a pretty terrible format. 360 00:33:51,240 --> 00:33:54,220 So, let's look at one of those here. 361 00:33:56,020 --> 00:33:58,000 So, we're looking at the details. 362 00:33:58,000 --> 00:34:00,980 By the way, the other option would be to see the surrounding. 363 00:34:01,640 --> 00:34:18,180 So, timestamp wise, it could show you a couple of messages before and after, potentially from Nginx or Apache or whatever other logs you collected around that time, which might be kind of related to just to have this overview of this specific timeframe. 364 00:34:18,180 --> 00:34:21,960 That would have been the other option, but we don't need that here. 365 00:34:22,520 --> 00:34:26,280 So, here, these are all the pieces of information we have connected. 366 00:34:26,280 --> 00:34:30,860 So, application mod security, that was the field on which I actually filtered down. 367 00:34:31,280 --> 00:34:41,060 And you can see, this was the pattern which we used to actually figure out that this was this specific attack here. 368 00:34:41,060 --> 00:34:52,620 So, it was detected as a remote code execution Windows command injection, which I'm not sure that was really what happened, but it was detected as that. 369 00:34:52,620 --> 00:35:02,360 And you can see, if you like writing regular expressions, if you're in that Stockholm syndrome, then you will feel right at home here. 370 00:35:02,360 --> 00:35:05,560 So, enjoy the glory of the regular expression here. 371 00:35:05,560 --> 00:35:10,820 And then you can see all the details of this rule and how it is structured. 372 00:35:11,640 --> 00:35:16,540 Yeah, which might not be the most readable format, but this is what is being used here. 373 00:35:16,540 --> 00:35:20,920 And you have various other fields where you can see what has been up here. 374 00:35:23,280 --> 00:35:24,160 Cool. 375 00:35:24,300 --> 00:35:29,900 And again, we added the cloud information, we added the host information, just in case this makes sense. 376 00:35:29,900 --> 00:35:37,940 If you don't use that, don't edit, because it will just add more weight to your logs in Elasticsearch, but it's just easy to collect. 377 00:35:37,940 --> 00:35:45,440 Just to give you an idea how I got those, just add this one here. 378 00:35:45,440 --> 00:35:57,040 I just said add cloud metadata and add host metadata, and those two would just add that to the logs. 379 00:35:57,120 --> 00:36:05,300 So, here is the Ubuntu set, for example, the settings about Ubuntu, and this one has the one about AWS. 380 00:36:05,300 --> 00:36:16,720 And after that here, by the way, I just renamed one field, because otherwise I have a collision of how fields are named, and this is just an easy way to fix up some data when you collect it. 381 00:36:17,380 --> 00:36:20,040 And that's all there is to this. 382 00:36:22,320 --> 00:36:24,720 You can also write custom rules. 383 00:36:24,720 --> 00:36:39,300 So, I have added a custom rule, and this might be very useful, like you have, I don't know, a forum software, and somebody is posting ads for Rolexes or Viagra or whatever other stuff you don't want to have there. 384 00:36:39,300 --> 00:36:42,000 I have created a different rule. 385 00:36:42,000 --> 00:36:53,440 So, what I tried to do here is, on my create.php file, I'm adding a rule that will deny any request that detects a fake SHI. 386 00:36:53,440 --> 00:36:55,540 So, SHI is our CEO. 387 00:36:55,540 --> 00:37:00,980 Let's assume there should be no other SHI in the company, otherwise somebody is trying to add a fake SHI. 388 00:37:00,980 --> 00:37:13,940 So, when a post happens, I check the body of that post and say, like, if there is the string SHI or Bannon in the post, I want to reject that request. 389 00:37:13,940 --> 00:37:19,700 So, let's head over to the browser to see how that was going. 390 00:37:19,700 --> 00:37:25,680 So, this one is not running against Nginx, but let's head over to Apache. 391 00:37:25,820 --> 00:37:28,400 So, again, this is running exactly the same thing. 392 00:37:28,520 --> 00:37:30,840 It's using the same database, the same files. 393 00:37:31,460 --> 00:37:36,420 When I try to log in here, by the way, the SQL injection is not working anymore. 394 00:37:36,420 --> 00:37:53,040 So, if I tried Philip and I tried or true, this would then, for example, reject my request because it detected an SQL injection and would just kick me out. 395 00:37:53,120 --> 00:37:56,740 So, I would have to log in correctly. 396 00:37:56,740 --> 00:37:58,320 So, secret was the password. 397 00:37:58,320 --> 00:38:02,000 If I do that, I can now create a regular user. 398 00:38:02,000 --> 00:38:11,020 So, let's say I want to create SHI other and he is also based in San Francisco and he has some salary and he has a password . 399 00:38:11,380 --> 00:38:21,200 And when I try to send in that other SHI, again, I get a rejection because the fake SHI rule kicked in here. 400 00:38:22,760 --> 00:38:37,920 If I stream the logs for this one, it should, as the very last rule, in a moment show me or already now show me that we just detected this fake SHI and rejected the fake SHI. 401 00:38:38,380 --> 00:38:44,880 So, this is showing that my rule worked and we rejected the fake SHI. 402 00:38:44,880 --> 00:39:04,300 So, even if you have some broken application where you cannot easily add like a spam filter or fix something else, you could just write some custom rules in what security to reject certain things or filter out certain things that you don't think should end up in your application. 403 00:39:04,980 --> 00:39:10,200 And then you have a more or less smiling SHI again because there cannot be any fake SHIs. 404 00:39:10,200 --> 00:39:13,880 And this was the log message that we have just seen, basically. 405 00:39:15,120 --> 00:39:18,260 ModSecurity is not 100% foolproof though. 406 00:39:18,260 --> 00:39:31,140 So, for example, if you would run this one here with these parentheses or one equals one and parentheses, this will still allow you to bypass the login. 407 00:39:31,140 --> 00:39:35,840 So, let me just quickly copy that and try it in the form. 408 00:39:35,840 --> 00:39:39,240 So, here we have a forbidden. 409 00:39:39,760 --> 00:39:48,380 I'll try to... I need to create another random user to actually pass or get logged out. 410 00:39:49,160 --> 00:39:50,520 So, let's do that. 411 00:39:50,520 --> 00:39:53,740 Now, I'm trying to log in again and now I'm... 412 00:39:54,800 --> 00:39:59,540 foobar doesn't exist, but I add that or query. 413 00:39:59,880 --> 00:40:05,780 And this, even though there is ModSecurity here at play, I still bypass that. 414 00:40:05,780 --> 00:40:07,260 So, ModSecurity is not 100%. 415 00:40:07,260 --> 00:40:18,680 There are potentially ways to work around it, but it will filter out some things and you might have to tweak your rules according to what might be valid input or not. 416 00:40:19,900 --> 00:40:25,260 Yes, everything is terrible and everything is on fire and what the fuck were we even thinking? 417 00:40:26,840 --> 00:40:29,920 I guess that's a very good description of security. 418 00:40:29,920 --> 00:40:35,440 So, to wrap this up, security incidents generally come in three levels. 419 00:40:35,440 --> 00:40:39,260 The for your information, what the fuck, and oh my god. 420 00:40:40,100 --> 00:40:46,280 And today I think we were only in the between for your information, what the fuck. 421 00:40:46,280 --> 00:40:54,480 It was definitely not the oh my god yet, though you frequently see those in the media anyway. 422 00:40:55,300 --> 00:41:01,500 Yeah, write better code than me and use the right libraries or frameworks, especially around injections. 423 00:41:02,300 --> 00:41:13,500 Nobody should have SQL injections anymore by using the right tools or libraries, unless you just pass around plain strings like me, which is not a smart idea. 424 00:41:14,040 --> 00:41:17,420 Is anybody using ModSecurity, for example? 425 00:41:17,420 --> 00:41:18,820 Yeah, quite a few people. 426 00:41:18,820 --> 00:41:32,360 So, for example, if you're using GitLab and deploy it in Kubernetes, since almost a year ago on the Ingress app, ModSecurity has been added to GitLab. 427 00:41:32,940 --> 00:41:39,720 So, this is just one of many places where ModSecurity is being used as of today. 428 00:41:39,900 --> 00:41:45,520 And for the Elastic Stack, that's also pretty widely used just for the security use case. 429 00:41:45,520 --> 00:41:52,800 Three companies which I think I can name publicly would be Slack, anything related to security around Slack. 430 00:41:52,880 --> 00:42:01,140 Mozilla has a project and Cisco is also a pretty heavy user just to get logs into the Elastic Stack around security. 431 00:42:01,140 --> 00:42:02,760 And that's not all. 432 00:42:02,760 --> 00:42:06,600 We recently added SIEM and Endpoint Security. 433 00:42:06,860 --> 00:42:08,720 So, those would play into that. 434 00:42:08,720 --> 00:42:16,000 And since I think I have like one minute or so extra, let me give you a quick idea of what SIEM might look like. 435 00:42:16,000 --> 00:42:22,380 So, here I have already, let me zoom out one level again. 436 00:42:22,380 --> 00:42:25,780 So, here these are all the requests in the last hour. 437 00:42:25,780 --> 00:42:27,040 You can see these are all the hosts. 438 00:42:27,040 --> 00:42:29,560 I have a single host here to keep it simple. 439 00:42:29,680 --> 00:42:36,980 All my login requests into that one were successful and I could then dive into all the hosts that I have identified. 440 00:42:36,980 --> 00:42:42,420 You can see it also gives you a good overview of what is running on that machine here. 441 00:42:42,980 --> 00:42:48,340 And for example, I might be interested in not the login attempts because, well, they were all successful. 442 00:42:48,340 --> 00:42:49,640 That's not so interesting. 443 00:42:49,640 --> 00:42:52,020 Let's have a quick look at the events. 444 00:42:52,080 --> 00:42:56,900 In the events, we can see everything that happened on that host here. 445 00:42:56,900 --> 00:43:00,560 So, for example, maybe somebody said like that application is kind of fishy. 446 00:43:00,560 --> 00:43:04,160 And let's have a look at what is happening on that host. 447 00:43:04,160 --> 00:43:06,880 So, that is what we are trying to get here. 448 00:43:06,880 --> 00:43:10,160 And these are all the events that we have collected over time. 449 00:43:10,160 --> 00:43:12,060 So, we have NetFlow. 450 00:43:12,060 --> 00:43:21,420 So, any network connections that have been going on, user logins, processes that have been stopped or started, sessions, etc. 451 00:43:21,420 --> 00:43:31,900 And then at the events further down here, you could see, for example, that this is already our application with Apache. 452 00:43:31,900 --> 00:43:43,380 So, let's drag and drop this one into our timeline filter here because I want to see anything that touches this port 8080. 453 00:43:43,480 --> 00:43:48,280 And then you could see, okay, this was Apache that was serving the request. 454 00:43:48,280 --> 00:43:49,940 You could see where it was coming from. 455 00:43:49,940 --> 00:43:53,000 You could see that many packets, etc. 456 00:43:53,040 --> 00:44:10,360 And then dive further down into that information and figure out why maybe your Apache server is throwing so many errors because ModSecurity is blocking lots of bad stuff, for example, or whatever else you might find interesting in here. 457 00:44:10,360 --> 00:44:13,200 And you can slice and dice your data any way you want. 458 00:44:13,800 --> 00:44:15,980 Okay, enough of this. 459 00:44:16,780 --> 00:44:18,520 Let's close this out. 460 00:44:18,560 --> 00:44:22,540 So, ModSecurity and logging go very well hand in hand. 461 00:44:22,540 --> 00:44:30,480 If you just run ModSecurity without looking what it actually blocks or rightfully or wrongfully blocks, you're pretty much blind. 462 00:44:30,480 --> 00:44:40,960 So, you want to combine this with some proper logging, as well as logging in general in your application to figure out if somebody has potentially breached something or not. 463 00:44:40,960 --> 00:44:52,320 And especially if somebody breached it, when did that happen and what were they actually able to do to your system to actually know afterwards and not just stir some murky water. 464 00:44:52,680 --> 00:45:00,100 If you want to try out all of this, the code is on my GitHub page in ModSecurity.log. 465 00:45:00,100 --> 00:45:03,300 If you want to try out the dashboards, I will also let this run. 466 00:45:03,300 --> 00:45:05,740 I hope nobody kills it. 467 00:45:05,860 --> 00:45:10,060 You will automatically be logged into Kibana with a read-only user. 468 00:45:10,440 --> 00:45:14,980 So, this is running a reverse proxy that automatically logs you in with a read-only user. 469 00:45:14,980 --> 00:45:26,260 So, if you go to dashboard.xiera.wtf, you will end up in Kibana already logged in and you can play around with the logs UI or with the dashboards and just see what is going on there. 470 00:45:26,260 --> 00:45:35,300 The application is running on xiera.wtf, so any requests that you generate, you should be able to find in Kibana as well. 471 00:45:35,740 --> 00:45:39,380 Just if lots of users are doing that, it might overload the system. 472 00:45:39,380 --> 00:45:47,060 No guarantees that it will be up or you might see a lot of noise because of everybody else doing it, but happy exploring around that. 473 00:45:47,480 --> 00:45:54,240 If you want to get the slides, that is the QR code, I will share the link if I can live as well. 474 00:45:54,700 --> 00:45:58,460 And with that, let's head over to the questions. 475 00:45:59,180 --> 00:46:00,500 Find me on this course. 476 00:46:00,500 --> 00:46:04,560 I'm happy to answer whatever you have or ping me on Twitter. 477 00:46:04,560 --> 00:46:06,340 I'm also happy to answer there. 478 00:46:06,340 --> 00:46:07,580 Thanks a lot for joining.