 Hey YouTube, this is a video right up for the challenge access denied from Codefest CTF 2018. The challenge prompt here is kind of a silly story to describe a service that is running on a specific host and port, and you have the source code for it. So I've downloaded it already, it's just given in a little Google Doc file, and let's go ahead and copy this host and port we could go ahead and connect to. I'm just going to bang out a simple connect.sh script, not entirely necessary, but again handy to do. So if I want to mark that script as executable and then connect to it, it says enter your name, John, please subscribe, enter your access code, blah, blah, blah, we don't know anything incorrect access code, please enter the code over and over and over again until something were to happen. So not the best thing, whatever, let's take a look at the source code it's given to us in school.py. Looks like it imports random, a module that we know and is built in, and it imports a user functions that we don't know and is not built in. So it reads inputs like okay, what is the name that you're reading in? If it actually knows or has seen this user before, the challenge prompt kind of explained this, it will generate a new access code along with that user ID. It looks like it will generate a number supposedly always in the range of zero to 1000. Because it's mod 1000, that means it's just going to be bounded and wrapped in that number range. So that's pretty handy for us and that while we don't know what this is actually doing or what number is going to be returned here, it is potentially brute forceable because it's just going to be in the range of zero to 1000. Not potentially brute forceable, it is brute forceable, that's the attack we're going to be using here. Also it uses a random seed, but it's seeding with a constant value, the string XOR shift. So again, that's not particularly random, we could seed the same way and do this exact same operation and run the exact same code. Then it determines a variable based off of some of the characters given in the user, whatever, we know, okay, given the seed set, if we can match it, we'll always have the exact same value for count at the very, very end of this loop. And that won't particularly matter for whatever user we give it. But some more loops, again, using random numbers with given a code variable here, and then a final adding on to that, blah, blah, blah. That number eventually will enter, will evaluate to be something that we could potentially figure out because if we just seed our random number generator or pseudo random number generator with that same constant string, we could get the username and access code. If we supply the correct access code, then it will give us the flag. Okay, pretty handy. So let's go ahead and start to write this out. I'm just going to create a script here, call this get flag dot pi again, being pretty arrogant, being pretty, pretty, pretty confident we can solve this whatever, let's import random, let's import, let's do from bone import all. So we can connect to this thing, let's just steal the connect string from netcat, just like that. And okay, so host can equal all of this, just as a string, let's get port to equal this, blah, blah, blah. And let's say the username that we want to work with can just be admin, that works just fine. And then if we're going to figure out this count variable, we know it's going to be in the range up to 1000. In fact, it'll be zero to 999 because it's a modulus operator. So zeros will stay in place. And that will do exactly the same thing as our range functions that works just fine. We actually do want to seed the same time every time we're trying this because the value that we end up creating for code and count or whatever are still going to be going with the same position or setup with our pseudo random number generator. So let's just copy that code to run those operations exactly the way they did. We can replace this string, whatever, that's fine. But we will eventually want to figure out the final and code the exact same way. Okay. So let's try to go ahead and create a connection to it because we saw in our connect script, we can enter the name just fine. And it'll keep asking us the access code over and over and over again. So cool, that works, that works fine for us. Let's actually give it some garbage thing to begin with because it will display these numbers signs it the second time that we give it something if it's wrong. See those numbers following after the blah, blah, blah, cool, whatever. Let's go ahead and try and do this. Let's do s dot s equals remote with host and port and then s dot close at the very end of our script. Let's do s dot receive. So we're prompted for the username s dot sun lined admin or I'm sorry username s dot receive to get the prompt for the access code. And then final will be the code that we want. So we'll do s dot send line. Actually, we should give it some garbage number first, just like I said. 123 s dot receive, should we receive first or second? Let's try and find it. Let's just do print s dot receive, send line string of final, and we don't need this other page any longer, print s dot receive. And let's actually print out what we're trying here. Let's try print final. And that count with it. So now we can Python get flag, see how we do. And user is not defined. Okay, let's run username. We'll actually just change that variable. So we don't have to deal with it, because they're using user down here, not username. That's fine. Run it. Incorrect access code over and over and over again. And sometimes we're going to miss in the receiving order. So let's not run that second receive. Eventually, if we keep rolling through here, we will be iterating over and over and over again. Hopefully we'll get a hit and something will get the correct access code and we will get the flag. I'm gonna pause the video until that happens. Looks like I got a hit over at 439 iterations or whatever. It says the flag is code fest. I see you are a man of randomness. So we got it. Let's go ahead and mark that as a flag dot text. Again, this is kind of a dirty script in that it's not very elegant. It is going to take a little bit of time to finally get the flag. So I won't make this the simple like one line immediately spit the flag out, it will take time to find this and iterate through it. So quick and easy, we can just save this. That is our script to get the flag. So all that attack or the technique really is not so much an attack. It's just seeding the random number generator the same way that they had in our code, taking advantage of the fact that it's a modulus. So we can just brute force that number range and zero to a thousand is not a very big space. It's handy that the service will stay alive for us and we can keep trying access codes rather than having to reconnect like open the connection and close the connection and then reconnect over and over again. That's been handy for us. So good that we can mark that flag. Let's save this challenge, say it is complete and we are good to go. Quick shout out to the people that support me on Patreon. Thank you guys so much. I cannot say it enough. You're fantastic. $1 a month or more on Patreon will give you a special shout out just like this at the end of every video. $5 or more on Patreon will give you early access to everything that released on YouTube. If you did like this video, please do like, comment and subscribe. Join our Discord server link in the description. It's an awesome community full of CTF players, programmers and hackers. If you want to hang out with me or other cool people, that's the best place to do it. We're going to be tackling ICTF and Nox CTF and other upcoming catch the flag competitions as a big team. So it's pretty neat. Thank you guys so much for watching. I'd love to see you on Patreon and I'd love to see you in the next video. Thanks.