Forum Moderators: phranque

Message Too Old, No Replies

rewrite rules to prevent common php injection exploits

example rewrite rules to prevent common php injection exploits

         

ninja_byte

3:11 am on Aug 20, 2005 (gmt 0)

10+ Year Member



check out what I've got...

I'm running it via an 'Include' directive.
apache 1.3.33

only problem is, it's matching *all* queries. There's gotta be a greedy regular expression in there somewhere...

I'm a perl fellow, so this apache regular expression stuff is a bit new.


RewriteEngine on
RewriteLog logs/rewrite.log
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)/modules/coppermine/themes/default/theme\.php?THEME_DIR=http://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)oneadmin/config\.php\?path[docroot]=http://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)config\.php\?path[docroot]=http://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)include/write\.php\?dir=http://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)includes/functions_admin\.php\?phpbb_root_path=http://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)ezupload/.*\.php\?path=http://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)displayCategory\.php\?basepath=http://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)theme\.php\?THEME_DIR=http://:(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)print_category\.php\?setup[use_category]dir=https?://(.*) [NC,OR]
#RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)print_category\.php\?(.*)setup%5Buse_category%5D(.*)dir=https?://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)index\.php\?(.*)include_location=http://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)announcements\.php\?includePath=http://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)outlogin\.php\?_zb_path=http://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)\.jpg\?(.*)&cmd=(.*)https?://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)\.txt\?(.*)&cmd=(.*)https?://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)\.gif\?(.*)&cmd=(.*)https?://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)\.php\?(.*)page=(.*)https?://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)\.php\?(.*)ath=http://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)\.php\?(.*)p=.*http://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)\.php\?(.*)file=.*http://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)\.php\?(.*)news_file=http://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)\.php\?(.*)include_dir=http://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)\.php\?(.*)pid=http://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)\.php\?(.*)pathtoashnews=http://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)index\.php\?(.*)p_url=.*http://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)Main\.php\?(.*)contentquery=(.*)http://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)survey\.inc\.php\?(.*)path=(.*)http://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)fromTemplate=¦(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)awstats\.pl\?(.*)configdir=¦(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)poc\.php\?sourcedir=http://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)mail_autocheck\.php\?(.*)pm_path=http://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)pipe\.php\?(.*)HCL_path=http://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)Packages\.php\?(.*)sourcedir=http://(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)viewtopic\.php\?(.*)rush=(.*)highlight(.*) [NC,OR]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)viewtopic\.php\?(.*)highlight(.*)rush=(.*) [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)highlight.*system\(.* [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)visualcoders\.net.* [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)echr%20(.*) [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)wget%20(.*)http://(.*) [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)wget%20(.*)ftp://(.*) [NC,OR]
#RewriteCond%{QUERY_STRING} ^(.*)fetch%20(.*)http://(.*) [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)fetch%20(.*)ftp://(.*) [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)curl%20(.*)http://(.*) [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)curl%20(.*)ftp://(.*) [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)lynx%20(.*)http://(.*) [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)lynx%20(.*)ftp://(.*) [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)ls%20-(.*) [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)/var/tmp(.*) [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)cd%20(.*) [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)rm%20-fr(.*) [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)rm%20-rf(.*) [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)esystem(.*) [NC]
RewriteRule ^.*$ http://localhost/ [R,L]

ninja_byte

3:13 am on Aug 20, 2005 (gmt 0)

10+ Year Member



btw, I'm also unsure as to which environmental variable I should be attempting to match against...

REQUEST_URI?
QUERY_STRING?
etc?

thanks in advance.

jdMorgan

5:26 am on Aug 20, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



ninja_byte,

Welcome to WebmasterWorld!

Here:


RewriteCond %{REQUEST_URI}?%{QUERY_STRING} ^(.*)fromTemplate=¦(.*) [NC,OR]

Translation: Match if the query string is <anything>fromTemplate= OR <anything> [NoCase, OR]

So that will match any query string, including blank.

There are several other problems with this code:

^(.*) and (.*)$ are a waste of characters and CPU time. You can safely remove them without changing the function of the pattern in the least.

You are mixing the URL-path with the query string in many of these RewriteConds, and it won't work.

If the request is "GET /file.type?p1=a&p2=b HTTP/1.1", then %{REQUEST_URI} will contain "/file.type" and %{QUERY_STRING} will contain "p1=a&p2=b"

If you need to check combined URLs and query strings, then use %{THE_REQUEST}. It will contain the entire client request header, so don't forget that there is an HTTP method such as "GET" or "PUT" at the start, and "HTTP/1.0" or "HTTP/1.1" at the end. Be careful to escape literal "?" and "." characters as well as spaces -- and possibly others.

Rather than starting with a huge mass of code like this, I strongly suggest you test small pieces and get it working one small increment at a time.

Jim

ninja_byte

5:30 am on Aug 20, 2005 (gmt 0)

10+ Year Member



thank you very much! I am actually converting an existing script I have(it is written in perl, and searches for these same strings within apache log files), hence the mass rules.

Success!

= )

jd01

5:40 am on Aug 20, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Could you be more clear as to what you are trying to do? It appears you are trying to deny requests to a large number of php combinations, and it appears it would be much simpler to rewrite the php to html, then deny requests for the php files. EG:

1. Deny browser or link click requests to .php files.

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /[^.]+\.php.*\ HTTP/
RewriteRule \.php - [F]

2. Strip the? and everything after from original (browser or link click) requests so all Query_Strings that make it to the php page have qualified for the rewrite regular expression before they ever make it to the php page.

RewriteCond %{THE_REQUEST} \?.*\ HTTP/ [NC]
RewriteRule (.*)$ /$1? [R=301,L]

Using the above code, you cannot open a php file in a browser, and you cannot add a QUERY_STRING in a browser... they can only be opened or added through a 'silent' or internal redirect.

Justin

Added: We were posting at the same time - did not see the post immediately above mine.

netscan

7:03 pm on Aug 22, 2005 (gmt 0)

10+ Year Member



Wouldn't mod_security be a better fit here?

jd01

9:56 pm on Aug 22, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I think both have advantages - the biggest I see from mod_security is the ability to check POST information.

I do things the way I do so I can accomplish more tasks at once. Here's one reason I strip all query strings from original requests.

Let's pretend I am a competitor who does not like you - If you use a pattern match for your get variables, and have missed the fundamental of serving a 404 if no information is found in the php file (or have a misconfiguration in the delivery of your 404), or if you allow a query string on html files, I can duplicate your content by finding the pattern your are matching and editing a little

EG if you allow?page=n on you site, and you do not have a system set up to deliver the correct information (404 or 301 redirect to the non-query string page), your site will most likely deliver the actual page (try it out) with the query string on the URL, because there is no action on the query string. So, I can create new 'dynamic' pages for you, with duplicate content of course =):

http://www.yoursite.com/?page=1
http://www.yoursite.com/?page=2
http://www.yoursite.com/?page=3

If I know the pattern I *can* hurt you in the SEs.

If someone wants to hack bad enough, they will, but how many people can get into a site that does not allow query strings, any direct access to php files, POST information, has globals off, and uses a pattern match in rewrites and another on the php page serving the information, which returns a 404 and exits if the pattern does not match?

Anyway, just how I do things, maybe I am missing something?

Hope this gives you some ideas.

Justin