 Hey, what's up YouTube? This is John Hammond. I'm coming back at you with another video for Natus. This time level 12 as part of the Over-the-Wire Wargames, looking at web application security. So what we're greeted with here in this level is what looks like some file upload functionality. The problem here is choose a JPEG to upload, JPEG file, JPEG image. And I poked around with this a little bit. I gave it some like default files that I had, like some I had saved in like a Python Challenge video or something. Whenever I would try to upload this, it wouldn't actually work. I don't know why. It says there's an error uploaded in the file. Please try again, whatever. So we can get back to the page and we can view the source, like the same kind of functionality all the other levels have had for us. But let's take a look at this in Sublime Text or in our editor, so we can see it with syntax highlighting and it looks pretty good. So I've got the same like Skeleton code I've had before, the username and password we're using, requests and regular expressions to scrape stuff out, and I just make get request to the page. So here we can see it. Let's set the syntax to like HTML, whatever. And now we can go to that view source, like index source page. Cool. All right. That's kind of messy. So let's de-entitize it just like we've been doing before. And there are a ton of break characters that aren't really important for some reason. So we can see the PHP code behind this application. And it looks like just looking at the original HTML for us, we have a form that's doing a multi-part form data. So it's able to take in files. And it looks like there are hidden values that get posted along with the request, maximum file size, maybe we can tinker with that. A file name looks like it is actually going to be using a function called GenRandomString or I'm assuming GeneratorRandomString. And it just tacked on a JPEG extension here. And then it actually allows us to browse to a file with that file input type. And the variable name is UploadedFile. So we can upload that and maybe it will happen or maybe it won't. Let's see why our previous one didn't work. It looks like it declares a bunch of functions up top in the PHP code. But the actual logic right now to start with is to testing if a file name exists in the post request. So if we actually posted to the form, sorry, to the web page, it gets a target path based off of MakeRandomPathFromFileName upload and the post file name. So MakeRandomPathFromFileName looks like another function that we have here. And that takes in a directory, which we know is just upload right now. We can see that string and I'm assuming fn for file name. So the post file name that it gets here. And in the function, we run this ext variable. Looks like it's running PHP function path info getting out. I'm assuming the extension or the file type extension for the file name that we pass in. And it looks like by default it's JPEG, but we can probably change that if we get in the middle of it. And then it will return MakeRandomPath on this. And MakeRandomPath looks like another function here where it will create a path over and over again with a random string until the file does not exist. So while the file exists, that path, it will keep creating a new one over and over again. Trying to generate a new random string until it hits something that it hasn't randomly gotten before. Generating random string, that function up top just looks like it uses all the letters and numbers. Lowercase grabs a random one 10 times and puts it together to create a random string. So it must be creating a random file name. And we could see that even in the source code if we wanted to. Like when we zoomed in, take a look at that file name input in the HTML. It is a random file name if I keep refreshing this page. But by default, it always has a JPEG value. But it looks like that functionality in the PHP code actually keeps track of the extension that is given. So what if we were to give it something that wasn't a JPEG image? Like what if we were to give it PHP code that it could actually execute? Let's try that. I guess let's find out. I'm going to go ahead and create a new file. And that can be just a simple PHP reverse shell. So I have this already saved as a rev shell from some previous testing, but it'll just have our PHP opening close tags. And we will echo out the system output of our get request C. And C can just be the variable that we want to have here. And I think echo will also display it while system already does to begin with. So we can probably just run system get C. And let's just do that experiment to see if it will display it out on the screen for us. So let's try that. I don't know how in the request module we can upload a file, but let's go find out. We can just use some simple Google thing. Python requests. Get to the documentation. Let's look for file upload, control F. Are we at the quick start? I want to be at the quick start. Upload. Okay, cool. So there's the documentation here. Looks like we can give in our post request, when we make that function call, we can just give it another keyword argument files, and that's just another dictionary with the file name, that variable name for the HTTP post, and then just an open object, like a Python file object created with the open function. So just a file name, really. Sweet. Let's go ahead and do that. So back to Sublime Text. Let's try and do a new function, rather than urinating the get HTTP method from post. Keep the auth that we need, but let's say our data, like we have for a normal post call, or post method, we have file name, and that can be revshell.php, because we're going to try and do something other than a JPEG file, but some PHP code that we want to be able to have it execute for us, and that max file size will include that just to be safe. That was by default a thousand or so, right? Okay, so there's the data, but let's get the files in there as well, since this form that we're working with can actually interpret those AOK. So files can equal uploaded file, and that was the variable name if you check the source. That's what it's using to read in that variable, and the HTTP method, that post request. So we want to open up our revshell.php, and the documentation said down below here. Try and make sure you open this in binary mode, so rb, the mode here for that file. Okay, now let's run this, see what we get, and I think I posted that to index source, so let's not do that. Now let's run this function. We have different build output. Looks like it did upload, though, on that other page here. Let me open that source code back up, sorry. So the response was the file dislocation. So this must be the random string that we had given to us.php, so it kept our extension because that's how the source code explained it, and that's been uploaded successfully. Okay, cool. So let's go to that location, and let's see if we can get it to run system commands for us, because that's what we just told PHP to do. So response can equal session.get, get the URL plus the upload, and auth can build the same username and password that we've been working with all along. So now when we run this, we get some PHP notices and warnings. So notice undefined index C in this PHP. Okay, so that's because we didn't supply the variable, and we're getting a warning because system can't execute a blank command. So that C variable, that get variable that we wanted to include, we'll have to include it now. So question mark C. So we're going to note some HTTP get variables, and C will equal, like, who am I? Let's run this, and we get NAT as 12. Okay, so that's our user. Awesome. Looks like we have command execution. We can run ID, run this, and got output again. Perfect. Now let's try and go ahead and do the good stuff. Let's try and get or cat out the password for the next level, NAT as 13. Run this, cat, et cetera, NAT as web pass, NAT as 13. And we've got the password just like that. So cool. We totally just took advantage of some file upload functionality where we were able to keep our file extension and upload something that it didn't expect. Like maybe it wanted a JPEG, just that's how the application it asked for. That's what it requested. But we gave it some PHP code, and we were able to take advantage of that, get it to execute that, and run system commands or shell commands, stuff like you'd see in Bash. So we got remote code execution on that box. If we wanted to, we could create our own reverse shell, like through our Bash terminal, like create a NAT cat session and stuff like that. But for this RCE, or remote code execution, this is just fine for us. We were able to get the password for the next level, and we can move on here. Let's go ahead and save this as NAT as 13, and let's see what that level is asking for us. Cool. Now we only accept image files. Okay, so we got a similar vulnerability, or at least a similar task, but maybe there's something else here that we can work with to find a vulnerability and get remote code execution one more time. Cool. Thanks for watching this video, guys. Hope you're enjoying these. If you are, please like the video. Maybe leave me a comment what you think. What else I can do? What else you'd like to see? Share the video. Tell your friends. Subscribe if you'd like. And if you... Thanks for watching, guys, again. Hope you're enjoying these, and I'll see you in a later video.