October 20th, 2008

I have seen many attempted rfi attacks and almost all of these are basically the same. PHPfreaks has seen thousands of these attacks and most have a url somewhere in the query string. The good news is that we can use a simple rewrite to prevent these attacks.

Here we check our query string for http://, https:// or ftp://

RewriteCond %{QUERY_STRING} (.*)(http|https|ftp):\/\/(.*)

If you are using this rewrite within a .htaccess all you have left is to deny access from all matching requests.

RewriteRule ^(.+)$ - [F]

If you have access to your vhost you could also log those requests like this:

<IfModule mod_rewrite.c>
   RewriteEngine on
   RewriteCond %{QUERY_STRING} (.*)(http|https|ftp):\/\/(.*)
   RewriteRule ^(.+)$ - [env=rfi:true]
</IfModule>
CustomLog /path/to/logs/rfi.log combined env=rfi

You will also have to deny access from requests that have been caught by the above rewrite

Deny from env=rfi

Comments

In case anyone is interested, the log file we have for this gets a new entry at least once per second. Sometimes even quicker.

1. Daniel Egeberg on May 28, 2008 3:11:40 AM

Entirely offtopic, but… Do you mean for this tutorial or someone trying to do an attack like this?

Anyway, a real comment:

If someone doesn’t have access to mod_rewrite, he/she could always just use PHP (like they should in the first place!).

Methods of protecting file paths can come in many forms…

  1. <?php
  2. //pretend $path is some user input or something
  3. $path = str_replace(array(‘..’, ‘/’,), , $path); //this way is as plain as it gets…
  4. if(preg_match(‘/some_pattern/’, $path)) { //only allow certain things…
  5. }
  6. //Or…  This is a fun little way if you want to give access to subdirectories, but no where else….  (To be honest, I’ve never extensively tested this or thought of ways around it or anything…. so…)
  7. $here = realpath(‘.’);
  8. $path = realpath($path);
  9. if(strpos($path, $here) === 0) {
  10. //$path starts with $here and all relative directives are removed….  therefore (excluding symbolic links and what not), $path must be under $here
  11. }
  12. ?>

Anyway, just a few ways to do it in PHP….

(Sorry if something doesn’t make sense or if there’s a type…. 3:30 AM.

2. Corbin H on May 28, 2008 4:35:59 AM

This is not about directory traversal, but remote file inclusion attacks 😉

3. Daniel Egeberg on May 28, 2008 5:03:21 AM

But cant you just use regex to check whether the $_GET contains someting dangerous? It might be possible to stop remote file inclusion that way right?

4. Wasim Ilyas on May 28, 2008 6:38:09 AM

@Wasim Ilyas: Yes, but this works on server level whereas using PHP would work on application level. We implemented this on our server to protect SMF.

5. Daniel Egeberg on May 28, 2008 6:46:15 AM

@Wasim llyas: As Daniel said, this works on a server level instead of an application level. We literally see thousands of these attacks each day and we would see a large drop in performance if we processed each of those requests with php. This way those requests never touch our applications. This approach really makes sense when working with third party applications(wordpress, drupal, smf ect) as you would most likely have no idea that a vulnerability existed in the first place.

6. Thomas Johnson on May 28, 2008 8:24:38 AM

Yeah I guess my script wasn’t specifically RFI, but it could help protect at a PHP level against that. (If you can’t traverse a directory, chances are you can’t include a remote file ;p.) (If you try to find examples you probably will be able to lol)

@ Thomas’ last comment:
I didn’t really think of it that way…. I was thinking it would be slower because each and every request would have to be checked, but in php each and every request (that involved an include) would have to be checked too…. And I can see where it would be extremely useful for third party apps like you said.

Edit: (P.S… Sorry about the lack of code tags in my earlier post who ever editted them in [or are they automatic?]. I tried PHP tags, but it didn’t work, and then I was lazy and gave up.)

7. Corbin H on May 28, 2008 11:28:17 AM

Re the formatting of posts. I have created this page. It’s aimed towards tutorial and blog authors, but some of it is applicable for comments as well.

Edit: Seeing as you’re a guru, it is actually for you as well 😛

8. Daniel Egeberg on May 28, 2008 11:34:33 AM

“[code=lang]code[/code]” (hopefully that doesn’t parse when I submit)

Hrmmm didn’t think of that x.x. Better than 10 diff languages in brackets I guess lol…

I glanced through that page last night, but I didn’t look through the BBCode… Guess I should’ve ;p.

*Blushes* (Hrmm that was kinda girly…. Oh well.)

Edit: And I should’ve looked when I didn’t know the BBCode. Laziness at 3AM ftl :(.

9. Corbin H on May 28, 2008 11:38:42 AM

Login or register to post a comment.

There are no comments yet, add one below.

Leave a Comment


You must be logged in to post a comment.