Denial of Service | Web Security with Python

Transcript

English (Auto-generated)

Hello. All my code casting compatriots today. We're gonna learn about denial of service. That's where you make a website or web resource or any resource for that matter unavailable to its legitimate users. This was originally done in uh forums and IRC chats and all of that as basically a prank when you got mad at people. And from there it became kind of a tool of activism, you know, taking down services that we're doing something wicked and nowadays it's often actually used for ransom is taking stuff down and demanding money in order to allow it to come back up in this one. We're gonna look at a simple service that we're developing. It's gonna be vulnerable to the os to denial of service. We're gonna look at one naive way of trying to fix it. And in a more sophisticated way That will make us a little stronger because the 9th way will have a simple workaround. So here we have our code. Let me say before you can see this is going to return the and Fibonacci numbers. So it's a web api for just returning Fibonacci numbers. So first we actually need a function that returns the end to the Nazi number. There we go. I'm using a what's that called? Get up? Co pilot. So it's like auto writing some of the code. It's pretty cool. Anyway, so we have our endpoint. It gives us the answer. Fibonacci. So we're just gonna say return and food. We close at seven and we will return a string because in a flat you have to return a string, not mint And we'll run that and see if it works. Mm hmm. Hey, looking good so far. Let's try to access that And it returns the 6th Fibonacci number, which is eight. The next one should be 15. That should be 21. It looks like it works. Okay. So the problem here is let's say we try to get a really big fit match number like 600 to take 12345678. Still hasn't returned anything. So in other words, what we could do is it's hard to calculate those big Fibonacci numbers, but it's easy to make a request that causes the server to start calculating them. So what we would do here as we would, we would just send tons of requests, tons of them and the servers and start calculating and calculating these numbers. That means that the server will be using a lot of resources but we won't. So we can just launch a ton a ton of these requests until the server actually goes down because we're using a ton of CPU or memory or what have you. So how do we prevent that? Well, in this case it's still our junior dev. Okay. We've got our junior down here looking at this code and he's like, yeah, you know what? That's gonna be a problem. So he decides to rate limit this. It can only be so many connections after that amount. He says, you know, the server will go down so he doesn't want that many more than that many. So we'll call it like we'll save live connections. Okay. I will be in a ray. I'm sorry, a list in python. Let me save this. So you guys probably can't even see that code. So we have this list of our connections when we get, when someone comes in with the connection, just add something to this list and then we'll get rid of it afterwards. We'll say pop Right? So the length of life connections at any point will be equal to the number of fibonacci functions we have. Right? So for this day, as long as Equals zero, if it's less than some basically some maximum. Right. So we'll say like max connections greater than the max connections, overcome an error, let's say too many connections. And that's a server side error. And we won't we won't let it won't work. Right, Okay, beautiful. But the problem here, so this works, this works. This will keep our server alive. But the problem is you can have one person just make a ton a ton, a ton a ton, a ton of here, let's just say So that 100 concurrent connections is the maximum one person can make 100 simultaneous connections and now no one else can use the API in other words we're not denying service to the server like before where it would just crash, right if we just had all these numbers going to infinity. But what it will do is cause it's so that other users can't go because the max connections are still at 100. And to demonstrate that let's create a quick quick script called D O S dot Js. I'm gonna make this one a note just because concurrent requests in python are kind of less convenient. But I know this is web security with python, so the back end will still all be in python. So let me see. I don't I don't spend a lot of time doing this. So I think we're gonna use Axios. I just got to google how to do a get request. Sorry, embarrassing. Okay. So let's say it's axios. Hmm. I'm gonna make a request to our local Api which I have here running at at this end point. I'm just gonna make a get request. I don't even care about the outcome, but I really want is errors. So I'll just play catch and I put console dot log, um, Error found because if an error is found, that means it probably returned 503. And if it returned 503, that means we did it with a million service. But obviously it's not gonna do it within one single request. I just want to see if I'm even doing this right. So let's say node dot Js and I don't have axios quick nPM install on that. So we're gonna be in this video is gonna be a little longer than usual because kind of all over the place with it, uh error found. That's random. Let me add about that, just see what happens. This shouldn't be an error. In reality, it should be totally cool with this. Alright, I'm council logging it. This is supposed to be a it's supposed to be a callback right here. So I say their console dialog here, it's fun to be in javascript. Alright, I'm doing a big one, so it's not gonna be happy about that, let's fix that. And beta is eight great. So I can say he's giving me this whole request object but I can just get data from it and I think it wants me to format the argument. Certainly there we go. There we go, so I get 88 is the correct answer. Okay, so what I would do though here is I would get rid of this console dot block, I would just say hey, if it's successful, I don't even care. We only want failures here um Oh we're gonna do 600. Why? Because we want it to be big, so it will take more time so we can more easily filled back you so let's try to get some errors. Alright, my bad, my bad. So what we're gonna do is we're gonna say while true, we're just gonna infinitely look this and try to get to this error condition that we want so badly that I want. So bad man. I should say, okay you should be receiving a lot of requests over here but but we are not that strange. Okay. Because I would expect that over here would be getting a ton of requests over and over and over again. Right, nope. Okay. Killed me. Probably because I was making too many requests. Yeah, heap javascript heap out of memory. Okay, so I'm gonna try a different approach. I'm just gonna do a for loop and just do this like 1000 times or something Just to make it easier on this will set this down 1250 because the principle is the same either way and I'm missing that looking bracket. You guys weren't expecting to learn a bunch of dogs script this time. Huh? There we go. Okay. So it's printing our hair. And what I really want to see is the status code. Because the status code, if it's if it's failing for the reason we think it is, the status code should be like 5.03. I think we said it too. But no connection reset. That's weird. Mhm. Okay. So connection reset Connection reset connection reset. So it actually stopped responding to us completely which is actually not what we want. So let me try it again. Address is already in use. Okay. Alright I'm running flat screen again. Okay. No Js let's just start throwing these areas at me, okay shoo what I'm gonna look at is axios get air status code. I don't see the status code and I'm googling it. You guys don't think you guys can see it but I'm totally good thing. So it's not response dot status here if you'll be able to see that in one moment. Okay. According to some person on stack overflow, that's totally how we do it. I read properties under. Okay. So I think it's giving us it's it's mhm mad but it's not matter for the reason we expected and I'm right here. Okay Connection reset what? Let me scroll way up. Okay instead of doing this 1000 times I'm just gonna try doing it 100 times. Okay And oh well we actually do have it showing up with these 50. Threes you know so that's pretty interesting. Okay so I see that it's giving me 50. Threes which means it's obviously executing the correct air condition so we know the D. O. S. Is working but now I'm just bothered by this this silly javascript issue that I want to see why I can't see the status code so let me see. Okay so it should be dot response dot status but maybe just after enough 503 is for whatever reason it just threw in the towel. Okay let's check it out. Mhm. Dot response dot status. Okay. There we go. 503. Beautiful. Alright I don't know why didn't work before. Okay so we see that we get 50 threes. It's wonderful that we know exactly what that means. That means that no one else can access this and just to just to show that that's legit um we'll try to access it in our browser just using a small number as though we were a normal user. Right so we're gonna set this up. Get nice up there, Can we start getting five or threes because that means that we've taken the service offline for for everyone Now it doesn't want to give us 503 sunset, Yep, started giving five on threes if we try loading in the browser for one it's going really slow because the back end is trying to do all this crazy stuff. I can't even load it just because I'm overwhelming the CPU doing all these requests so as you say, I mean I've made hundreds, I make 100 requests here so it's taking a long time to even serve them and it won't even respond to Firefox? So service effectively has been denied. Now the question is or maybe the question you've been waiting for, I should say is what do you do about this? Right like okay so we found a way to keep the server from literally dying but I mean that's like a little standard right? How could we make it so that the server doesn't go down but also like we're protected from this in a way that doesn't allow people to still take the ap I down for everyone else. What we would want to do in that case is set these limits per I. P address. So rate limit by I. P. Address or by some cookie. If they're already logged in Instead of just across the site as a whole, we could even still allow a set number of connections because like let's say you have five per user and you have 1000 users do it. That's 5000. That's still enough to take this down. Right? So what we want to say though, so we can keep this. I mean this is also good because it will keep our service online but what we would want to do is add a limit per I. P address. Okay, so we would say like basically what we would do is we would say connected I ps we could just make this into the dictionary right here. Yeah I know we said we could still keep it and we still can because we just add up like so for each I. P address we'll see how many connections it has, add those all up. And those are total life connections. So it'll still work. So let me google real quick how to get the I. P address and flask flask get request I. P address. I know it's request dot something ad or something like that request dot remote at her always forget that. Okay so let's get rid of this, Get rid of this. But so a new request comes in. We're going to set live connections of the current I. P address. Okay. To equal To be plus equal one. Right? There's a way in a dictionary that if it doesn't exist you can set it to zero. I'm just gonna google that because I forget how to do that not exist. Like there's a really elegant way to. Mhm But unfortunately I completely forget how to do it on some random crazy site that you guys can't see right now. Okay. Oh yeah I totally remember now. Anyway, so what we'll say is let's see if that's already in live connections and we just add one to it. If not then it will equal one. Okay beautiful. So it either equals one or it equals one more than however many already have if it's already in there. And then here we just say that if It's equal to one and go ahead and delete it will use the del keyword else. It will equal -1. Beautiful. Not the most elegant code in the universe, but it'll do the trick. All right, so we set up our live connections, we have this over here. The only thing we're missing is the actual check to say, hey is this user connected to many times and if so send them an error. And the only thing we'll have to do for that. I will say if this it's above however many they should have let's say two because why would you need to find two Fibonacci numbers at the same time. Return from the connections from its I. p. address and a 401 forbidden error. Unauthorized or whatever it is. The point is that it's definitely an error. So I only have one I. P. Address on the machine I'm on right now but we can see that we can run it and make sure that that it does limit me to my two connections. There you go. Just give me a bunch of 500 errors and was like Yep, nope. Don't care. So on this weird though it should have actually given me maybe there was an error, yep. That is indeed bad. So it's angry about the key I'm using Probably because remote ADDers like it might be an integer or something. No, but it's clearly not patriots like I mean it's clearly extreme happened. Okay. Times I'm glad we, I'm glad we decided to debug this. Alright because we check that it's over to before we see if it's in there. So so we should add this to this. Check after we see there we go. If it's in there then check if it's over two and if so return an error. Oh that is beautiful. Okay make sure be able to see that. This limits us to two. Try it again and beautiful. We get all four or three errors based on our p address which is of course the local I. P. Address. You see that we're returning for three to all of these. That is exactly what it should be and we should see if we scroll down just a little more. Okay. The only thing I want to make sure is that it does allow it should because it should be allowing to requests to go through so if it's not it's not allowing any of them. That's also not good. Right so let's make a request here manually by going to I'm going to go to R. D. O. S script real quick, grab this U. R. L. And then just try going to it and it still works. Mhm. Even if I refresh a bunch they have to be completely simultaneous and I think you know what I can actually say. Well it's less than two. It should. That's not gonna give me any errors at all. Right, yep. And then we have some successful gets right here just make sure those are coming from our script. I know it has a different error. Oh no wonder what's complaining about now find out. And then over here we'll come onto the log we'll get our data again. Sorry so much of this is unrelated to the core thesis of this but I don't just hack around too many connections from this ip address. What? Okay I think because I had that uh committee connections from its I. P. Address. Thank you. So what I can do is I have a print live connections. I think there's still a problem here. Which is that doesn't necessarily get here very easily like it doesn't have a chance to properly. Yeah like in other words if it has an exception up here I don't think it has the chance to really get here to where it's supposed to go and that is definitely an issue. So so let's see let's see what happens. I'm gonna run this script again. Oh dang I'm still using that big number if you have I'm still using 600. Let me try that with six 888. Okay that's good news. Let's try this too. That sounds appropriate to me. He ate and ate because obviously some of them are finishing on time. Let's see if I start getting to 10. If they start becoming simultaneous. Okay Because six is still too easy. Let me try 10. Okay. It's just fun to see ya. The computer stopped being able to, yep there goes too many connections to many connections and and now if we run it again we'll still get eight because why eventually those connections finished? So all that was happening earlier was we had an exception happening inside of our handler function here And because of that exception. Never got to believe it but now that it's not that it's fixed. That's no longer a problem. It'll just it'll start rejecting your requests until it can finish the ones you've already made, and then it will start accepting your request from you. There we go. Senior Samantha has fixed our issue. Beautiful. Wonderful. 22 minutes for a fairly simple vulnerability. I appreciate your time and hope you learned something from this. Thanks a lot and see you next time, right.
10 Views 0 Likes 0 Comments

From the halcyon days of Anonymous hacktivism, to today's blackmailers taking down services for ransom, DoS is a perennial weapon in the blackhat arsenal

Comment
Leave a comment (supports markdown format)