 In this video, I'm going to show you a super cool attack that leverages local file inclusion against a blacklist to achieve remote code execution by abusing PHP code injection in the HTTP user agent header. Keep watching to learn how to do this and more right now. What's up everybody? My name is John Hammond. We're looking at Natus level 25 and I think this level is awesome because it ties together a lot of cool techniques that we've seen in previous levels and things knowledge that we've built up so far and it bundles them together into one really cool attack. So I'm showing you this in the web browser first because for one thing the source code looks better in the web browser for these levels because it has the PHP highlight file like syntax highlighting and all that. But in this case, I want to show you the functionality of this before we jump into attacking it and writing our script. So it looks like it's just a static page with blank text, which is weird. We haven't seen that before in Natus, but we do have a little bit of functionality up at the top right. It looks like it'll let us change the language that we're viewing this text in. It looks like EN for English and DE for German and that's about all that we can do. So thankfully over the wire in Natus these wargames let us see the source code as to what the code is doing. So let's take a look at what that actually is here. HTML stuff is not important, but the PHP stuff that's highlighted is interesting to us. So a lot of functions being defined at the very, very bottom. It just gets the content of the web page. Looks like there's a PHP function or a set of the PHP code running this list files function that it defines up top. And then the main section of the content creates a new session uses the set language function that it defines up top. And then I think these variables that are being displayed come from something earlier in the code. So let's actually explore what those functions really are. List files, language as F, so a temporary variable for just displaying the options for what it's reading out. Looks like list files must be used to see the potential like English or German or other different languages that we want to read this message or this blog post in. And that looks like it's going to be used as an include because we see for each list files and list files it gets read all those things out just as file names. And that option that we give it looks to be a form. You can see just barely in the HTML here. It's not highlighted pretty, but on the form submit the option that gets sent to it up at the very top you can see a function set language that determines. Okay, if we have in the request a language being set, whether or not we chose English or German, it's being passed to the safe include function by default will just return English. So this safe include function looks like it takes an argument for the file name and it tries to check for directory traversal. Okay, interesting. If string string file name, okay, dot dot forward slash so trying to determine if the notion of the parent directory is present inside the string. Then it runs this thing log request that will say, okay, directory traversal attempt fixing request. And it looks like it just replaces and tries to remove that up directory notion or that that attempt to go into the parent directory. So that's trying to prevent local file inclusion, which we've seen before is a significant vulnerability. It looks like it does that log request, which is another function down here. Log request gets the current date adds it to a string that it keeps concatenating and adding things onto. It adds the HTTP user agent. So it would say like Firefox or Chrome or Internet Explorer, whatever browser you are using. And we've seen that before also we may be able to change. It's another HTTP header that we can manipulate. That's interesting thing to note. And it adds the message. So that must be the, okay, directory traversal attempt fixing request, the argument that's passed in. And it puts this in var www natus natus 25 logs session ID. Okay. And that session ID is that PHP session ID that we've seen before in our, in our cookies. So we know that value when we're working in our script because we can just get that out from our cookies. Interesting thing to keep in mind. Another interesting thing that we saw in the safe include function is it tests if the natus web pastoring is in the file name. It will log, okay, illegal file access detected aborting. It's not going to allow us to simply type natus web pass in whatever file we're trying to read out of the language keyword or the language variable that we're passing to it. And then it looks like it makes sure the file exists. It'll actually include it at the very, very end. So that looks like it's how it's getting that greeting message and footer variable that's displayed on the page. So okay, really the only thing we have to work with is this language variable. So let's try and hit that local file inclusion. Let's see if we can actually get it to trigger this directory traversal attempt and see if you can replace those dot dot forward slash dot slash as to see that up directory or the parent directory and what we're looking for. Okay. So over to sublime text. I've got it printing out these page results right here. And there is a long quote, blah, blah, blah. Okay. So let's try and post to this something with the language parameter being set post with data. Lang can equal. Let's see D just by default that will give it to us in German right because that is okay. Yeah, that's the file name that it's getting. So let's try and change that to just forward slash or dot dot slash dot slash dot slash go up a couple many directories and let's try and read et cetera password because we know that file will be on the system. So if we were to get a result, we would be able to see it. And it looks like we don't have anything that that fires. But that makes sense because that log request function is just writing to the file as we know in the source code. It's not writing out to any output or anything that we can particularly see. But we know that it is replacing those forward slash is the dot dot forward slash is in the up directory because that would at least be removed. According to that string replace function. So let's try and actually not give it a file here and see what it does because I had an interesting hiccup that I saw earlier. We see a lot of PHP warnings and notices if we get it to fail without reading actual file. It says here fails to open stream. No such file directory in the current location of that script index dot PHP, et cetera, et cetera. So an interesting thing because it's not able to actually read these variables. It's not able to include anything. So we know we do have that local file inclusion potential. Now we have to actually get around that blacklist or trying to replace these dot dot forward slashes. So it's an interesting thing because it's simply doing a replacement operation. Because what's to stop us from trying to hide or kind of camouflage or whatever you'd like to think of it as or trying to sneak in some more or like an actual parent directory or up up dot forward dot dot forward slash notation inside another one. Right. Because if we're running a string to replace dot dot forward slash with nothing so it'll go away. Why don't we try and put a another dot dot forward slash inside what we have before. So it'll replace maybe the innermost one. This will go away. But then once it's left after it's completed that replace operation. You'll have just okay the skeleton or the makings of an original like up up like dot forward slash you'll be able to actually transverse that see because I was able to put in just another one here. That's all that it tried to find and replace. And then once that is gone, you're just simply left with the same string that you wanted to begin with. So that's going to be an interesting tactic. Let's see if we can actually get some local file inclusion by using that style. I'm going to include that a couple times many times because we don't exactly know how far up the directory we're going to going. But let's try and include a set of a password. Let's run the script. See if we get it and we do. Okay, cool. We just leaked out a set of a password on the box. So now we need to figure out how we can actually get the password for the next user. This is an interesting thing, right? Because the source code has this explicit other blacklist operation. If Natus web pass is in the original file name that we supply, it will log the request and exit it won't let us actually have the functionality anymore. So what can we do instead? This is a really cool attack. And I think this is an awesome thing because it takes a little bit of ingenuity thinking outside the box. But also keeping in mind the things that we've learned in previous levels and combining them for an awesome attack. So let's think what files do we have access to right now? Literally everything on the file system, right? Literally everything on the file system, including the logs that this application like saves and reports for us. Because we know the location of this log, we can potentially get it to be displayed for us. So we know we are going to have one entry in this log file because we're using this directory traversal. It'll say, okay, directory traversal attempt fixing request. Now let's see if we can actually read that file by trying to locate this file in the file system. So we need to know the session ID, but we can do that right because we've got a session that we can create. Let's write a get request to begin with. So we actually get a session set up and then let's determine what our cookies are when we try print session cookies PHP session ID. Let's not display the other things just so we know we have a session here. Cool. Yep. That works just fine for us. We can index it just like that. So let's go ahead and try to like read that file. We know in the source code it's var www, natus natus 25 natus 25, et cetera, session ID dot log. So changing the file that we're trying to read now to not et cetera password, but that string. Remember to concatenate on the dot log extension. And remember we do want to have our session dot cookies PHP session ID right there. And that should be concatenated on just fine. And now we should be able to read that. Remember to print out the output. I managed to drop that. Cool. Now we're seeing that log entry. We're seeing the time and date. This has occurred. We're seeing our user agent, which right now is Python requests because we're doing this in the script. And we see that message directory traversal attempt fixing the request. So we know it's no replacing the dot dot forward slash. Okay. Now here is the next cool and awesome part. Because we can control what this HTTP user agent is. We actually that that is input for us. We can modify that HTTP header. So because we're including this file and because it's being spat out from the web server that is looking at PHP code normally, right? We've got notices and warnings and all these other issues that are coming through. What if we put PHP code as our user agent? Let's try this. That's going to be really cool, right? Let's get a headers dictionary here. Headers can equal user attack agent. So that's set up. And then let's use just the syntax to run a PHP file command right here. And now what do we want to do? Oh, how about determine the contents of, you know, the natus password that we want natus 26? So how can we do that? Well, it's PHP, right? We can just run shell commands. We've got system, pass through, et cetera, all those things. So let's just try system. And let's use our classic cat, et cetera, natus web pass natus 26. Settle display it on center out for us. And we'll be able to read it because we can specify we want our user agent to be this string, which will get injected into that log entry, which we'll be able to read because of local file inclusion. And then it'll evaluate that PHP and give us remote code execution with this super, super cool. Try headers equals headers to make sure we include that user agent. Let's run this. And what do we got here? Excellent. Our user agent is now the password for natus level 26. Sweet. Let's go ahead and save this as a new script. Natus 26. We can clear up the junk that we have here. Go ahead and make just a regular get request. And let's see if we are greeted with the next level, make sure that's the right password. And it certainly is we are on natus level 26. So cool. Thank you guys so much for watching. I really do hope you enjoyed this. I love this level, honestly. This is I think one of the coolest levels that natus has so far and that you're combining all the other tactics and techniques that we've seen so far and making a really interesting attack. Take advantage of that HTTP user agent injecting that PHP code so you get remote code execution through the local file inclusion that you already ran through like some little like blacklist evasion and I thought that's awesome. So, hey, thank you guys for watching. I want to give a shout out to my supporters here. This list is getting pretty lengthy and long, so I'm super duper grateful. Thank you guys so much for all of your support. I love that you are willing to go on this adventure and journey with me. So, hey, if you did like this video, please do press that like button. Maybe leave me a comment. Let me know what you think, what you'd like, what you'd like to see, what we could have done better, how you solve this, etc. If you're willing to subscribe and if you really want to support me, check me out on Patreon. Cool. See you soon, guys.