 This video showcases an interesting trick with the SQL Select statement, where we exceed the maximum character length, get a string truncated, and use that to leak out another account's password from a database. Keep watching to learn how to do this and more right now. What's up YouTube? Now we're looking at Natus level 27, and this is a peculiar one because we're looking again at some more like username password credentials. And so we're going to be trying out a user and password set that I guess we can log in with. I don't know. So I'll just try John and the password like wins or something. And it looks like, okay, user John was created. Interesting. Let's refresh the page. And if we were to log in with that, again, if we requested that same John and log in, it'll say, okay, now that you're logged in, here's the data that you're receiving, you can see your username and your password. So that's an interesting thing. Small application looks like it uses SQL database to just check whether or not there's a user in the database. If it isn't there, it will create one. And then if it is there, it will just tell you a little bit about the account in that it will give you the password. So our objective is to check out the password for Natus 28 to beat this level and move on. So I've got the source code pulled up. I've got a sublime text ready to rock with our Python script. And let's take a look at the source code. It looks a little bit better in sublime text for this level, because I don't have the syntax highlighting in the regular page. So here I am in sublime text again. So we've got the same user schema that we've seen the database that we've seen before and other previous levels username and password strings or of our car 64 and length and not know blah, blah, blah, a bunch of functions that are created. But I want to at least take a look at the top level code that runs before everything else. If we are requesting something. So if we actually submit the username and password, it will connect to the database with the password not specified here, select a database to use, and then it will run a couple checks. It'll run valid user, which looks like a function up top on the username that we're just that we're selecting or entering and check credentials. Another function that's to scale this displayed up top. Again, it's using the request username and request password. And it says welcome, the username. Here's your data and dump data looks like it will display the username and password like we saw in the application. So HTML entities is PHP's notion and attempt to secure things down, like remove all the HTML entities, if you were to try and do like cross site scripting or inject HTML elements or JavaScript code into an input field. So HTML entities is going to be a mitigation technique that is harming us here as the attacker, we're not able to run any of those things like injecting script tags, HTML tags, etc. So it looks like they do a good job of noting HTML entities and everything out that they're trying to display. Otherwise, it will give us a wrong password. If the user doesn't exist, it will create it like you saw with my john account that I showed earlier. And we can actually see if I were to log out here, or if I can, I don't think it will let me very easily. And I don't have that I don't have that option. That's fine. I can do it in the source code actually when we try and attack it with our Python script. So the functions that we want to take a look at up here are check credential, looks like we have the user and password that are being passed to this function, just as variables, and they're using the MySQL real escape string function on them. And again, that's another PHP mitigation function that will try and lock down and protect a lot of regular SQL injection techniques. So we don't have that at our disposal. They are doing that to lock us down. You can probably research and Google and find a lot of bypass options or ways to evade this function. And maybe that's worth your while. It's not I've found as a solution to this challenge. But I think that's something that would be really interesting if you do want to look into more of the bypassing this function. So it goes ahead and runs a query here, determining whether or not, okay, does this username exist? Do the credentials work? Are we going to get a results just like that? And that looks like all that function really is valid user is another function that does the same thing, but it's selecting only the username to determine whether or not this user already exists, right? We saw that down below. They're checking if valid user, okay, comment, the user exists. If not, it will create it. So check credentials is just determining whether or not you have the right password. And that is the check credentials appear. Okay. Okay. So that looks like it occurs. In any case, just whether it gets a correct result, it will return true. That's a peculiar thing to note. And dump data is really where we'll just display out that username and password for us. So that's where the magic happens where we can potentially get the password. But again, they're still using the real escape string. So we're they're preventing our regular SQL injection. However, what they do here is they do an interesting thing after they execute this query. They determine whether or not we got a result. Do we have things that we can actually look through? Did we get data back from the database? And it will return a number of rows. And if it's greater than zero, okay, we have multiple results. So what it does is it does this while loop that it iterates through every single row. This is peculiar, right? Because we only expected it to return one result. Like if there's only one user, we're trying to log in as a specific user, that would probably just be one. But what if we are in the case if there are multiple results, if there are multiple rows to look through. And that is kind of the spark of ingenuity that will lead to the toying around tinker and experimenting to find us a trick and a technique that can let us attack this application. So the create user function is simple that we'll just insert into the database. And again, if it actually successfully executed, it will return true otherwise false, et cetera. So let's poke around at what would normally be this database in the schema because there are some interesting tricks and techniques we can use to get around that notion of, okay, we don't know the password for Natus 28, the next level. But because maybe we could get it to return multiple results in some cases, let's try just sending that string over here. If I run get request, I can instead post now where data can equal, I'm going to put this on a new line so I can bring these side by side, trying to minimize my mouse movement. Because I know that's pretty annoying when I'm trying to slide in and out of different pains between the script results and the actual source code. And we don't need the first thing here, we can just post this, get our return output. And you can see I have posted the page, it gives me wrong password for user Natus 28. So I wasn't able to successfully authenticate in that. If I try John wins, just go back to it. Okay, user John was created, the database must have reset. We saw a comment that we didn't get earlier. The database will reset every five minutes. So if I run this again, we are logging in. And it gives us our password and credentials. But Natus 28, not working for us because we don't know the correct password. So now let's tinker a little bit. I want to show off an interesting tool called SQL test net, where we can just experiment with SQL database in a quick and easy way without spinning up a server. So the top right, you can select the database, we're just using my SQL. I'm going to change this to a table name as users. And we'll just use the username as the actual field that we want to work with because that's the peculiar one that we are determining when we are running that check credentials or valid user function here, all the valid user function is testing is whether or not the user exists. And that's the first test here. Okay, do we have a valid user? Well, yes, we can have a valid user is Natus 28 is always going to have to exist. But then we have to get check credentials to work. So check credentials is the hard part. But maybe we could have multiple results or multiple rows for Natus 28. So I'm just going to show this example where I use a var car of 10 as our size. So we can experiment with that. And I'll insert into users values, subscribe. Because, okay, so subscribe is nine letters long, right? Yep. So that's an interesting thing. Let's go ahead and select all from users to just get results here. Scroll down, there's a button execute SQL done on the very bottom. And okay, so we get a result subscribe. So interesting thing to note here is that I set the length of this column, the length of this field to only 10 characters. Keep in mind for the actual application, ours is 64 characters long. But maybe it will act strangely if we give it some data that's longer than that length that's set up. So let's say I have our car 10, right? So let's insert another row, subscribe space, please, right? Cool. Now that we can execute that again, execute SQL, we can see we have subscribe and subscribe. It's returning both of those peculiar, but there's the space kind of at the very, very end there. That's fine. It looks like it got truncated the word please just cut off. So it's being returned with the space. Okay, so let's get let's just narrow this down to see if that space will go away if we were to ask for select all from users where username is equal to subscribe. Go ahead down, execute this, execute this. I am executing it, but you're not seeing the results change because of a really interesting bug here, not a bug, but a strange trick and functionality. So I just removed the results so you can see for real. But if I just re comment that and turn the execution back on, we are getting both of the results subscribe on its own and subscribe with whatever amount of padding using spaces to like exceed that number, the maximum length for us, but the spaces are still going to be returning it on its own. Interesting thing, right? So what if we could take advantage of that? What if we could say, all right, we want to insert into the database because we know there's already a Natus 28 username and password in the database. What if we had Natus 28 inserted with however many spaces, whatever we need to break it up to 64 characters and then exceed that and then we could have literally anything following this because anything will be truncated, but the spaces will remain intact and the select statement will still execute and get us what we're looking for. Execute SQL, Natus 28, both of these are going to be returned and because we're using that MySQL fetch associative because we're looping through every single row, we may still get a result. That's an interesting thing. Let's try it. What I'm going to do is I'm going to use Natus 28 over here, our first insert into and we're going to need to make this an insert into because we have to create the account, the register of the user that has more than 64 characters in the name. This is seven characters long, so 64 minus 7, you know, 57. Let's go ahead. I'm not going to math whatever. I'm not going to quick math on YouTube with people are watching. Let's multiply some spaces. Let's go 58 or something to be safe and then we'll just tack on anything so it will be truncated. We'll go ahead and post the rest, make this call and you'd see user Natus 28, blah, blah, blah, anything was created. Okay, so user Natus 28 is in there. Now that's been created. And now we can try and log in with just the regular Natus account with our anything password, the password that we used previously, because remember in the source code, this check credentials will work on anything where username and password is going to get a result that select will still have it get the Natus 28 we inserted previously with the truncated spaces and it will still return true. Great. Now valid user, since that's going to work through the associative all of these rows here, it's going to loop through all of these queries that's going to return true and we'll be able to see the password. Let's try this. We got it. All right. Welcome to Natus 28. Here's your data array. This guy right here is our password for Natus level 28. Cool. Let's save this as a Natus 28 script so we can keep in mind for that. And we're going to move on. But thank you guys so much for watching. I hope that was kind of cool. I hope that was kind of interesting. I hope I didn't drag it on for too long. But I thought that was a really interesting technique. Honestly, I've never seen that before other than just digging at this and poking at it until we got it. But that's a really peculiar thing is hacking away at that maximum length character, seeing what strange things happen when you experiment with it, when you exceed, when you get your data truncated and how come the spaces just didn't get evaluated or considered in that select statement. Interesting, bizarre things that SQL does, but really cool to know for us in the capture to flag and pen testing scene. So, hey, I got to give a shout out to my supporters here. This list is getting longer. And thank you so much for you guys. I really can't say it enough. That's why I do this in every video is because I cannot say thank you enough. Thank you so much for being willing to go on this journey with me and help and support. It really helps grow me and the channel. It helps motivate me to keep working, keep pumping out really cool things. Hopefully they are really cool for you. Hey, one month on Patreon, $1 a month on Patreon will give you a shout out just like this at the end of every video. $5 and more a month will give you early access quote unquote to the videos that I'm uploading to YouTube in case I record in bulk in mass and they schedule them on YouTube and they're really slowly. So thank you guys again. If you did like this video, please do press that like button. Maybe if you're willing to leave me a comment, let me know what you think, what you liked, what you didn't like, what we could do better, what else you'd like to see, how you solved this. If you'd like to subscribe and if you really want to support me, please check me out on Patreon. Cool. Thanks so much guys. See you in the next video.