Showing posts with label mod_security. Show all posts
Showing posts with label mod_security. Show all posts

Thursday, January 20, 2011

How to disable mod_security in .htaccess file

SkyHi @ Thursday, January 20, 2011
It is quite common that mod_security is interfering the functions of your web applications. mod_security is installed and enabled by your web server admin but you can still disable it for your individual website using .htaccess file by following this tutorial.

“mod_security is an Apache module (for Apache 1 and 2) that provides intrusion detection and prevention for web applications.” — HowtoForge

Disable mod_security in .htaccess file

1. If you do not have one yet, an .htaccess file in the folder of your web application
2. To disable mod_security COMPLETELY, add the following line to the .htaccess file:
SecFilterEngine Off
OR, to disable HTTP POST scanning only, use the following instead:
SecFilterScanPOST Off
3. Save the file and test your web application to check whether disabling mod_security has solved your problem.

I recommend you to try SecFilterScanPOST Off first, instead of disabling mod_security completely.

My two cents

mod_security is good to protect your website but it might cause some problems for certain web applications, especially in file uploads. My server has mod_security enabled and I encountered WordPress upload error: “HTTP error”. The SecFilterScanPOST Off solved the problem immediately.
<Directory /var/www/html/phpmyadmin>
SecRuleEngine Off
</Directory>

<Directory "/var/www/html/phpmyadmin">
Order deny,allow
Deny from all
Allow from 192.168.2
</Directory>
REFERENCES
http://www.liewcf.com/how-to-disable-mod_security-in-htaccess-file-3631/

Tuesday, June 15, 2010

Red Hat / CentOS Install mod_security

SkyHi @ Tuesday, June 15, 2010

Simply type the following command as root user:

# rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-3.noarch.rpm

List new repo:

# yum repolist

Sample output:


Loading "skip-broken" plugin
Loading "fastestmirror" plugin
repo id repo name status
addons CentOS-5 - Addons enabled
base CentOS-5 - Base enabled
<span style="color: rgb(255, 0, 0);">epel Extra Packages for Enterprise Linux 5 - enabled</span>
extras CentOS-5 - Extras enabled
updates CentOS-5 - Updates enabled

Once installed use yum command to list, view and install the packages:

# yum search package-name

# yum install package-name


See how to use yum command for installing and searching packages using various repos.


How do I install ModSecurity - an open source intrusion detection and prevention engine for web applications under CentOS / RHEL / Red Hat Enterprise Linux 5.x server?



ModSecurity operates embedded into the web server (httpd), acting as a powerful umbrella - shielding web applications from attacks. In order to use mod_security, you need to turn on EPEL repo under CentOS / RHEL Linux. Once repo is turned on, type the following command to install ModSecurity:

# yum install mod_security

Sample output:


Loaded plugins: downloadonly, fastestmirror, priorities, protectbase<br />Loading mirror speeds from cached hostfile<br /> * epel: www.gtlib.gatech.edu<br /> * base: mirror.skiplink.com<br /> * updates: centos.aol.com<br /> * addons: mirror.cs.vt.edu<br /> * extras: mirror.trouble-free.net<br />0 packages excluded due to repository protections<br />Setting up Install Process<br />Parsing package install arguments<br />Resolving Dependencies<br />--> Running transaction check<br />---> Package mod_security.x86_64 0:2.5.9-1.el5 set to be updated<br />--> Finished Dependency Resolution<br /><br />Dependencies Resolved<br /><br />==============================================================================================================================================================<br /> Package                                  Arch                               Version                                   Repository                        Size<br />==============================================================================================================================================================<br />Installing:<br /> mod_security                             x86_64                             2.5.9-1.el5                               epel                             935 k<br /><br />Transaction Summary<br />==============================================================================================================================================================<br />Install      1 Package(s)<br />Update       0 Package(s)<br />Remove       0 Package(s)         <br /><br />Total download size: 935 k<br />Is this ok [y/N]: y<br />Downloading Packages:<br />mod_security-2.5.9-1.el5.x86_64.rpm                                                                                                    | 935 kB     00:00<br />Running rpm_check_debug<br />Running Transaction Test<br />Finished Transaction Test<br />Transaction Test Succeeded<br />Running Transaction<br />  Installing     : mod_security                                      [1/1] <br /><br />Installed: mod_security.x86_64 0:2.5.9-1.el5<br />Complete!

mod_security configuration files


  1. /etc/httpd/conf.d/mod_security.conf - main configuration file for the mod_security Apache module.
  2. /etc/httpd/modsecurity.d/ - all other configuration files for the mod_security Apache.
  3. /etc/httpd/modsecurity.d/modsecurity_crs_10_config.conf - Configuration contained in this file should be customized for your specific requirements before deployment.
  4. /var/log/httpd/modsec_debug.log - Use debug messages for debugging mod_security rules and other problems.
  5. /var/log/httpd/modsec_audit.log - All requests that trigger a ModSecurity events (as detected) or a serer error are logged ("RelevantOnly") are logged into this file.

Open /etc/httpd/modsecurity.d/modsecurity_crs_10_config.conf file, enter:

# vi /etc/httpd/modsecurity.d/modsecurity_crs_10_config.conf

Make sure SecRuleEngine set to "On" to protect webserver for the attacks:


SecRuleEngine On

Turn on other required options and policies as per your requirements. Finally, restart httpd:

# service httpd restart

Make sure everything is working:

# tail -f /var/log/httpd/error_log

Sample output:


[Sat May 09 23:18:31 2009] [notice] caught SIGTERM, shutting down<br />[Sat May 09 23:18:33 2009] [notice] suEXEC mechanism enabled (wrapper: /usr/sbin/suexec)<br />[Sat May 09 23:18:34 2009] [notice] ModSecurity for Apache/2.5.9 (http://www.modsecurity.org/) configured.<br />[Sat May 09 23:18:34 2009] [notice] Original server signature: Apache/2.2.3 (CentOS)<br />[Sat May 09 23:18:34 2009] [notice] Digest: generating secret for digest authentication ...<br />[Sat May 09 23:18:34 2009] [notice] Digest: done<br />[Sat May 09 23:18:35 2009] [notice] Apache/2.2.0 (Fedora) configured -- resuming normal operations

Refer mod_security documentations to understand security policies.


REFERENCES

http://www.cyberciti.biz/faq/rhel-fedora-centos-httpd-mod_security-configuration/

Friday, February 26, 2010

Getting Started With ModSecurity

SkyHi @ Friday, February 26, 2010

Using ModSecurity is not easy.  The complexity of your site, your use of PHP, MySQL and other scripting languages will make it more difficult to configure correctly.   Basically, the more complex your site, the more time  you will need to work out issues with rules.  This tutorial will provide you with several important tips to get started with ModSecurity.

Tip #1: Develop A Basic Understanding of ModSecurity
Go to the modsecurity.org website, download and read the documentation.  Once that is done you need to know how to find a policy number.

1. Locate a Policy
The rules will be located in the directory you create, probably named modsecurity, and in that directory will be a list of  rules.  These Core Rules provide generic protection from many unknown vulnerabilities.  You will not want to modify the Core Rules, except to turn them on,  as when you update you will erase your settings.  There are two files that have been created to create custom rules.  The first is the modsecurity_crs_15_customrules.conf which lists rules that have been tested for your site and are working effectively.  The second is a bailout ruleset, in other words, if you cannot get something to work you can place it in the modsecurity_crs_65_temporary.conf  until you can get it fixed.  For example, if you need to run ModSecurity but cannot get a specific rule to work you can disable it in this file until you can get it working.

You can see that the file represent different kinds of rules.  The 10_config provides the basic configuration and this is the file that you will use to turn on ModSecurity rules.  The collection of rules provide protection for your web server, detects and protects against bots, crawlers,scanners, it detects and protects against trojans and limits error messages that will provide too much information to attackers.

modsecurity_crs_10_config.conf
modsecurity_crs_15_customrules.conf
modsecurity_crs_20_protocol_violations.conf
modsecurity_crs_21_protocol_anomalies.conf
modsecurity_crs_23_request_limits.conf
modsecurity_crs_30_http_policy.conf
modsecurity_crs_35_bad_robots.conf
modsecurity_crs_40_generic_attacks.conf
modsecurity_crs_45_trojans.conf
modsecurity_crs_50_outbound.conf
modsecurity_crs_65_temporary.conf

2. Locate Your Logs
The logs for ModSecurity will be located in /var/log/httpd and you will have two of them, modsec_audit.log and modsec_debug.log.

3. Locate Rule Numbers in Logs
You will need to be able to find the rule numbers so you can work with problems that may develop.  Here you can see the rule number highlighted after the letters “id”.

[Sun May 17 06:11:34 2009] [error] [client 192.168.5.26] ModSecurity: Access denied with code 501 (phase 2). Pattern match “(?:\\b(?:\\.(?:ht(?:access|passwd|group)|www_?acl)|global\\.asa|httpd\\.conf|boot\\.ini)\\b|\\/etc\\/)” at ARGS:content. [file "/etc/httpd/conf.d/modsecurity/modsecurity_crs_40_generic_attacks.conf"] [line "114"] [id "950005"] [msg "Remote File Access Attempt"] [data "/etc/"] [severity "CRITICAL"] [tag "WEB_ATTACK/FILE_INJECTION"] [hostname "example.com"] [uri "/blog/wp-admin/post.php"] [unique_id "lC3YnH8AAAEAAFoKCK0AAAAL"]

4.  Locate IP Address of a Client in the Logs
You can see the IP Address of the client highlighted.

[Sun May 17 06:11:34 2009] [error] [client 192.168.5.26] ModSecurity: Access denied with code 501 (phase 2). Pattern match “(?:\\b(?:\\.(?:ht(?:access|passwd|group)|www_?acl)|global\\.asa|httpd\\.conf|boot\\.ini)\\b|\\/etc\\/)” at ARGS:content. [file "/etc/httpd/conf.d/modsecurity/modsecurity_crs_40_generic_attacks.conf"] [line "114"] [id "950005"] [msg "Remote File Access Attempt"] [data "/etc/"] [severity "CRITICAL"] [tag "WEB_ATTACK/FILE_INJECTION"] [hostname "example.com"] [uri "/blog/wp-admin/post.php"] [unique_id "lC3YnH8AAAEAAFoKCK0AAAAL"]

5. Locate Rule File and Line
You will need to know what rule file that is causing you problems and the line number.  These are highlighted.

[Sun May 17 06:11:34 2009] [error] [client 192.168.5.26] ModSecurity: Access denied with code 501 (phase 2). Pattern match “(?:\\b(?:\\.(?:ht(?:access|passwd|group)|www_?acl)|global\\.asa|httpd\\.conf|boot\\.ini)\\b|\\/etc\\/)” at ARGS:content. [file "/etc/httpd/conf.d/modsecurity/modsecurity_crs_40_generic_attacks.conf"] [line "114"] [id "950005"] [msg "Remote File Access Attempt"] [data "/etc/"] [severity "CRITICAL"] [tag "WEB_ATTACK/FILE_INJECTION"] [hostname "example.com"] [uri "/blog/wp-admin/post.php"] [unique_id "lC3YnH8AAAEAAFoKCK0AAAAL"]

After running the default rules on a web site using PHP, Apache 2 and MySQL database with about 1300 visitors a day I received these violations to the ModSecurity rules.   That is 1636 violations which you will have to determine are they legitimate or false positives.  In other words, to get ModSecurity to work like you want for your site you have to expect to make some custom changes and verify that things are working correctly.

960903 – 55
960015 – 1271
970903 – 84
970902 – 56
960017 – 170

The more you know about ModSecurity the easier it will be but be prepared this is not something to add to your site and walk away, you must keep up with your logs.

Tip #2: Be Prepared to Disable Problem Rules
As much as you will want to install ModSecurity and be done with it, you will probably have issues with several rules that are troubling to solve.  What I did was create the file, modsecurity_crs_65_temporary.conf  and in the file I listed rules to disable until I could resolve the problems.  This should only be a temporary situation but I did this instead of disabling all of ModSecurity.  This strategy allows you to protect most elements of your site without shutting the whole thing down.  Yes, it is a great idea to set up a test server before you go ahead with ModeSecurity but in reality nothing will prepare you for going live, there are just too many variables in terms of how your site is accessed.

Disable rules
If you need to disable a rule you can do that based on the rule number.

SecRuleRemoveById 960015

Whenever you will disable a rule you need to place it after the actual rule so you will want to put the rules that you will disable in a special list at the end of your configuration that is why the file has the number 65.  add them one line at a time.

Tip #3: Create a Custom Rule Set
Regardless of your site you will probably want to create some custom rules. Create your custom rules and place them in modsecurity_crs_15_customrules.conf.  Here are some examples of custom rules that you may consider.

Secure Administration Logins
You certainly will want to secure your login areas for your administrators.  Here is an example of a Wordpress login (wp-login.php) that does not allow anyone to access accept the two IP Addresses listed.  They are chained together so you do not need to rewite the rule several times.  The first two lines have the chain option so that it is included with the last line.

SecRule SCRIPT_BASENAME “^wp-login.php$” chain,t:none
SecRule REMOTE_ADDR “!^192\.168\.3\.119$” chain,t:none
SecRule REMOTE_ADDR “!^192\.168\.3\.57$”

LocationMatch
You can also add a LocationMatch for a specific rule or rules so that it only applies to a specific directory or file.   This example removes the three rules for this directory so that it will work for Wordpress.

<LocationMatch “/wp-includes/”>
SecRuleRemoveById 960010
SecRuleRemoveById 960012
SecRuleRemoveById 950006
</LocationMatch>

Tip #4: Increase SecResponseBodyLimit

If you are using Wordpress one of the first modifications that you will want to make is to the SecResponseBodyLimit.  This is the maximum response body size that will be accepted for buffering.  When you go over this limit you will see a 500 Internal Server error.  The default is 512 KB but should be increased.  Here is the setting that will likely work for most Wordpress sites.

Edit modsecurity_crs_10_config.conf    and find the line for SecResponseBodyLimit and make changes.

SecResponseBodyLimit 1572864

Without this update you will see some errors with your plugins.

Tip #5: Modify PHP Memory Limit
When you use output buffering ModSecurity keeps the whole page output in memory and as a result you may run out of memory and get errors with php.  Edit your /etc/php.ini and double the memory that you were using in order to allow ModSecurity to keep those pages in memory.

memory_limit = 32M      ; Maximum amount of memory a script may consume

Tip #6: Create Whitelists
You may want some IP Addresses to be whitelisted so that those IP Addresses can work without having any restrictions.

SecRule REMOTE_ADDR “!^192\.168\.3\.119$” “nolog,phase:1,allow”


REFERENCE
http://beginlinux.com/blog/2009/05/getting-started-with-modsecurity/



Wednesday, February 17, 2010

Apache mod_security on CentOS 5 x86_64

SkyHi @ Wednesday, February 17, 2010
These docs are targeted at users that need to configure the rules for non-ASL environments.

Contents

[hide]

[edit] About the rules

The gotroot.com rules are written by us - we are the gotroot guys. Same great rules, same team. gotroot.com is our Information Assurance lab and Atomicorp is the product arm of Prometheus Global (the parent company for both). So when you get the gotroot.com rules from atomicorp.com or gotroot.com - you're getting the same rules from the same people that created, write and maintain them. In the future we will be merging the gotroot.com, atomicrocketturtle and atomicorp websites into the atomicorp.com website.
Installation of the rules assumes a certain level of comfort with configuring apache. If you are not comfortable with configuring apache, you should contact someone that is, or use our [Atomic Secured Linux] product which does this for you, and does not require you to configure apache.

[edit] Real Time Rule Support

If you have a subscription to the real time rules, you can request email support by sending an email to:
support@atomicorp.com
The Customer Support Forums are located here (you can post here, but these forums are for the labs and free rules, if you post the customer forums the support team monitors those forums regularly):
Customer Support Forums
And the Custom Support Portal is located here (you can submit bug reports and open cases through the portal):
Customer Support Portal
You will need to request a portal account the first time you access the portal. Support accounts are issued manually by checking the status of a customers account and the process may take some time if the office is closed. In the future, the process will be completely automated when a new sign up occurs.

[edit] ModSecurity 2.5 download

If you are running ASL - do not manually install modsecurity. ASL will install modsecurity for you, and always use the modsecurity rpms we include with ASL.
Atomicorp RPM repository
You can also build modsecurity from source. We do not support source installs of modsecurity or third party builds of modsecurity. To download the source for modsecurity please visit this website:
http://sourceforge.net/projects/mod-security/

[edit] ModSecurity Rules download

If you have not already setup a subscription for the RealTime feed, you can do so here:
Real Time Feed Signup
Once your account is setup, you can download the Real Time rules from here:
Real Time Rules Download

For other users, you can download the Free Delayed/Unsupported feed below. Keep in mind the Delayed feed is released 30 days after the realtime feed (that includes any fixes).
Delayed/Unsupported Feed Download
If you want to try out Atomic Secured Linux (ASL) on a trial basis, please send an email to sales@atomicorp.com and we'll set you up an account!

[edit] The differences between the Real Time and Delayed Feeds

The Real Time feed is available via subscription, it includes the latest updates we produce on a daily basis and any fixes. The Real Time feed comes with support to help you with any issues you may experience with the rules, including fixing false positives. When false positives are reported to us we generally get an update out the same day. So no more hassles working with modsecurity if you use the Real Time feed!
The Real Time feed also comes with an unsupported rules updater. It works for most systems, but because every system differs we can't know for sure if it will work with your modsecurity setup. If you need support for a rules updater then you are encouraged to upgrade to the full Atomic Secured Linux package which includes a fully intergrated automatic rules updater, rules management tools, SIM, web based GUI, real time malware prevention, the strongest kernel security on the market, FTP and web malware protection, built in vulnerability scanner/auto-fix system and more!
The Delayed Feed is a free version of the Real Time feed and is released on a delayed schedule of at least 30 days. It does not include any support.
Note: Atomic Secured Linux includes the Real Time feed.

[edit] Licenses

The Real Time Atomic ModSecurity Rules are licensed by the server. For each license you can also run the rules on one Development and one QA server.
If you require additional licenses please log into the AtomiCorp License Manager. You can add additional systems there, you can control your payment methods and you can also sign up to become an affiliate.
You can run the Free/Delayed rules on as many systems as you like.

[edit] Setting up modsecurity 2.5.x

Assuming you have a modsecurity 2.5.12 rpm (or higher) installed from the atomic archives, you will want to create these directories as root:
Note: You are encouraged to use our rpms, any issues involving non-atomicorp builds of mod_security are not supported under rules-only subscriptions.
mkdir /etc/httpd/modsecurity.d
 mkdir /var/asl
 mkdir /var/asl/tmp
 mkdir /var/asl/data
 mkdir /var/asl/data/msa
 mkdir /var/asl/data/audit
 mkdir /var/asl/data/suspicious
Then set the following permissions on these directories as follows below. In this example these directories are set to be owned by "apache" and the group "apache", which is standard on a normal Centos or RHEL system. However some control panels configure apache to run as a different user, such as nobody, or http. Check your system to see what user your system uses. You can use this command to find the user:
ps auxwww | grep httpd
The output will look similiar to this:
(RHEL/Centos example with or without Plesk)
root     26755  0.0  4.3 430752 86432 ?        Ss   04:30   0:01 /usr/sbin/httpd
 apache   26908  0.0  3.7 300564 75076 ?        S    04:30   0:00 /usr/sbin/httpd
 apache   26909  0.1  5.5 495812 112084 ?       S    04:30   0:37 /usr/sbin/httpd
 apache   26910  0.0  5.3 495424 106672 ?       S    04:30   0:23 /usr/sbin/httpd
 apache   26911  0.1  5.7 495892 114368 ?       S    04:30   0:57 /usr/sbin/httpd
 apache   26912  0.1  5.7 496056 114440 ?       S    04:30   0:52 /usr/sbin/httpd
 apache   26913  0.1  5.5 496604 110692 ?       S    04:30   0:57 /usr/sbin/httpd
 apache   26914  0.0  5.7 499324 116236 ?       S    04:30   0:16 /usr/sbin/httpd
 apache   26915  0.2  5.5 493600 112192 ?       S    04:30   1:09 /usr/sbin/httpd
 apache   26916  0.1  6.4 513760 129992 ?       S    04:30   0:30 /usr/sbin/httpd
In this example the user in bold is "apache". This is the user you will want to set the directory permissions to (as in the example below):
chown apache.apache /var/asl/data/msa
 chown apache.apache /var/asl/data/audit
 chown apache.apache /var/asl/data/suspicious
 chmod o-rx -R /var/asl/data/*
 chmod ug+rwx -R /var/asl/data/*
(RHEL/Centos example with Cpanel)
root     20594 86.8  3.1 255148 181232 ?       Ss   11:39   0:04 /usr/local/apache/bin/httpd -k restart
 root     20611  0.0  3.1 255060 179596 ?       S    11:39   0:00 /usr/local/apache/bin/httpd -k restart
 nobody   20612  0.0  3.1 255148 180224 ?       S    11:39   0:00 /usr/local/apache/bin/httpd -k restart
 nobody   20613  0.0  3.1 255148 180224 ?       S    11:39   0:00 /usr/local/apache/bin/httpd -k restart
 nobody   20614  0.0  3.1 255148 180224 ?       S    11:39   0:00 /usr/local/apache/bin/httpd -k restart
 nobody   20615  0.0  3.1 255148 180224 ?       S    11:39   0:00 /usr/local/apache/bin/httpd -k restart
 nobody   20616  0.0  3.1 255148 180224 ?       S    11:39   0:00 /usr/local/apache/bin/httpd -k restart
In this example from a Centos system running Cpanel the user is "nobody", so you would want to use these commands:
chown nobody.nobody /var/asl/data/msa
 chown nobody.nobody /var/asl/data/audit
 chown nobody.nobody /var/asl/data/suspicious
 chmod o-rx -R /var/asl/data/*
 chmod ug+rwx -R /var/asl/data/*

These directories must as be created if you use optional rules updater. Create these directories as root and they only need to be accessed by root:
mkdir /var/asl/updates
 mkdir /var/asl/rules/
 mkdir /var/asl/rules/clamav
Create this file:
touch /etc/asl/whitelist
This file contains a list of IPs you want to exclude from ALL rules. That means those IPs can do anything to your system - so be very very careful about what IPs you add to this list. This is a dangerous thing to do. The format of the file is a single IP, per line.
Cpanel users should skip to the notes at the bottom of this page for special additional actions for cpanel systems. All other users should continue with these instructions.
You then need to tell apache to load modsecurity. Depending on your apache configuration, apache should be configured to include configuration files. If you have a setting like this in your apache config:
Include conf.d/*.conf
Then you are setup to load external configuration files. If you do not have this setup, its highly recommend you do this. This installation guide is written for this type of configuration. Loading mod_security occurs by including a modsecurity.conf file in that directory. We recommend you name the name 00_modsecurity.conf to ensure it runs first. Its vitally important that modsecurity load before other modules, otherwise attacks can occur before modsecurity scans them and some attacks can be missed.
An example 00_modsecurity file that works with our files is included here:
LoadModule security2_module modules/mod_security2.so
 LoadModule unique_id_module modules/mod_unique_id.so
 
 Include modsecurity.d/modsecurity_crs_10_config.conf
 Include modsecurity.d/*asl*.conf
 
Install this file in your conf.d directory. On a standard RHEL or Centos system that directory is located here:
/etc/httpd/conf.d/
You then need to create your modsecurity_crs_10_config.conf. Here is an example file that also works with our rules:
SecRuleEngine On
 SecRequestBodyAccess On
 SecResponseBodyAccess On
 SecResponseBodyMimeType (null) text/html text/plain text/xml
 SecResponseBodyLimit 2621440
 SecServerSignature Apache
 SecComponentSignature 200911012341
 SecUploadDir /var/asl/data/suspicious
 SecUploadKeepFiles Off
 SecAuditEngine RelevantOnly
 SecAuditLogRelevantStatus "^(?:5|4(?!04))"
 SecAuditLogType Concurrent
 SecAuditLog logs/audit_log
 SecAuditLogParts ABIFHZ
 SecArgumentSeparator "&" 
 SecCookieFormat 0
 SecRequestBodyInMemoryLimit 131072
 SecDataDir /var/asl/data/msa
 SecTmpDir /tmp
 SecAuditLogStorageDir /var/asl/data/audit
 SecResponseBodyLimitAction ProcessPartial
Note: If you are not using our mod_security rpms you will need to add these additional lines to your mod_security configuration:
SecPcreMatchLimit 100000 SecPcreMatchLimitRecursion 100000
You will want to install this file in your modsecurity.d directory, which is located here if you follow the instructions above:
/etc/httpd/modsecurity.d
You are now ready to install the rules.

[edit] Installing the rules

If you configure the rules updater, this process should be taken care of for you. If you choose to do this manually, follow the instructions below.
Download the rules to a temporary directory using your favorite download tool. Extract the rules:
tar zxvf /var/asl/updates/modsec-200911012341.tar.gz
Then copy the ASL rules into /etc/httpd/modsecurity.d:
cp modsec/*  /etc/httpd/modsecurity.d/
Finally, load the rules. Make sure you have this line in your
Then make sure you have this line are the bottom of 00_modsecurity.conf, if you want to load all the rules:
Include /full/path/to/your/rules/modsecurity.d/*asl*.conf
Or if you want to load some of the rules, make sure you specify only those rule files. For example:
Include /full/path/to/your/rules/modsecurity.d/10_asl_rules.conf
Include /full/path/to/your/rules/modsecurity.d/99_asl_jitp.conf
NOTE: If you use this file:
05_asl_scanner.conf
Make sure you have clamd installed and configured correctly to list on a TCP port, or if you use a socket, make sure apache can read/write to this socket or as a last resort, run clamd as root. Using this file will force all web uploads on your system to go thru clamav to look for malware, viruses, etc. If you dont need that, then you can leave this config file out. You will also to setup the scanner script, written in PERL, which you can download here:
modsec-clamscan.pl
Setup of this tool is not supported in the rules subscription. You will need to install it on your system and ensure that it is working with your apache setup.
Real time malware upload protection is supported in ASL. So if you need realtime malware upload protection (for web, FTP, or even realtime), then upgrade to ASL which highspeed malware upload protection, full support, automatic and hassle free installation, and also protects against HTTP, SSH and FTP uploads and includes our real-time malware detection and prevention system amongst the many features of ASL.

[edit] Testing

Before restarting apache we recommend you test your configuration by running apache with the "configtest" command. On a standard system you can do this by calling your apache init file like this:
/etc/init.d/httpd configtest
If you get errors, check to see that you don't have some extraneous files installed. You should only have these rule files:
05_asl_exclude.conf
 05_asl_user_exclude.conf
 10_asl_antimalware.conf
 10_asl_rules.conf
 20_asl_useragents.conf
 30_asl_antispam.conf
 40_asl_apache2-rules.conf
 50_asl_rootkits.conf
 60_asl_recons.conf
 99_asl_jitp.conf
 blacklist.txt
 domain-blacklist.txt
 domain-spam-whitelist.conf
 malware-blacklist.txt
 referer_spam.txt
 sql.txt
 trusted-domains.conf
 whitelist.txt

[edit] Rule Updater

ASL users: DO NOT USE THIS. YOU DO NOT NEED IT. ASL DOES THIS FOR YOU. INSTALLING ASL-LITE WILL BREAK YOUR SETUP.
ASL automatically updates rules.
ASL Lite is a new lightweight rule updater project designed specifically as an atomicorp.com mod_security rule downloader for custom apache environments, control panel software like cpanel and directadmin, or non-apache/mixed web server implementations. ASL Lite supports a guided dialog similar to the standard asl configuration, that allows for the definition of custom commands for restarting web services, location of configuration files, and use via cron.
ASL Lite is available in the Atomic channel:
wget -q -O - http://www.atomicorp.com/installers/atomic |sh
yum install asl-lite
You can also download it from the following page:
http://www.atomicorp.com/downloads.html
ASL Lite will ultimately replace the "Rules-Only" subscription, however it is optional now. You do not need it to download the rules, but you are encouraged to use it. It is currently available for RHEL 4/5, CentOS 4/5, and Fedora 6-12. Other operating systems can be added upon request.
To install ASL Lite:
1) Add the atomic repository
wget -q -O - http://www.atomicorp.com/installers/atomic |sh
2) Install asl-lite and its support packages
yum install asl-lite
3) Configure ASL lite with your username/password, set path information, configured rules, and restart commands
asl-lite -c
4) Update your ruleset:
asl-lite -u
ASL users: DO NOT USE THIS. YOU DO NOT NEED IT AND WILL BREAK YOUR SETUP. ASL DOES THIS FOR YOUR AUTOMATICALLY.

[edit] Tuning the Rules/Disabling Rules

See the mod_security page for details.

[edit] Troubleshoot the Rules

See the Atomicorp WAF Rules Troubleshooting page for details.

[edit] Reporting False Positives

See the Reporting False Positives page for details.

[edit] Special notes for CPANEL users not using ASL

Cpanel also includes a very minimal configuration for modsecurity and does not include all of the required and optimal settings documented here. Therefore its critical that if you use mod_security with Cpanel you most add these additional settings to experience the full feature set of mod_security.
If you are using our module and configuration files with cpanel - or you are using ASL with cpanel - then you do not need to follow any of these notes.
These installation notes are reguired for users that choose to use cpanels modsecurity module and configuration files with our rules.
Cpanel includes its own modsecurity configuration files and its own modsecurity module. These should be able to work just with our rules if they are configured correctly according to this page, and if you are using at least version 2.5.11 of modsecurity.
Make sure you have all of the settings on this page to use modsecurity with cpanel correctly, failing to do that will make it impossible for us to support you and modsecurity will not work correctly exposing your system to attack.
A typical cpanel configuration file looks like this:
LoadFile /opt/xml2/lib/libxml2.so
 LoadFile /opt/lua/lib/liblua.so
 LoadModule security2_module  modules/mod_security2.so
 
 SecRuleEngine On
 # See http://www.modsecurity.org/documentation/ModSecurity-Migration-Matrix.pdf
 #  "Add the rules that will do exactly the same as the directives"
 # SecFilterCheckURLEncoding On
 # SecFilterForceByteRange 0 255
 SecAuditEngine RelevantOnly
 SecAuditLog logs/modsec_audit.log
 SecDebugLog logs/modsec_debug_log
 SecDebugLogLevel 0
 SecDefaultAction "phase:2,deny,log,status:406"
 SecRule REMOTE_ADDR "^127.0.0.1$" nolog,allow
 Include "/usr/local/apache/conf/modsec2.user.conf"
 
This configuration is missing several important and key directives, so you will need to change it to this:
LoadFile /opt/xml2/lib/libxml2.so
 LoadFile /opt/lua/lib/liblua.so
 LoadModule security2_module  modules/mod_security2.so
 
 SecRuleEngine On
 # See http://www.modsecurity.org/documentation/ModSecurity-Migration-Matrix.pdf
 #  "Add the rules that will do exactly the same as the directives"
 # SecFilterCheckURLEncoding On
 # SecFilterForceByteRange 0 255
 SecRequestBodyAccess On
 SecResponseBodyAccess On
 SecResponseBodyMimeType (null) text/html text/plain text/xml
 SecResponseBodyLimit 2621440
 SecServerSignature Apache
 SecComponentSignature 201001051959
 SecUploadDir /var/asl/data/suspicious
 SecUploadKeepFiles Off
 SecAuditEngine RelevantOnly
 SecAuditLogRelevantStatus "^(?:5|4(?!04))"
 SecAuditLogType Concurrent
 SecAuditLog logs/modsec_audit.log
 SecAuditLogParts ABIFHZ
 SecArgumentSeparator "&" 
 SecCookieFormat 0
 SecRequestBodyInMemoryLimit 131072
 SecDataDir /var/asl/data/msa
 SecTmpDir /tmp
 SecAuditLogStorageDir /var/asl/data/audit
 SecResponseBodyLimitAction ProcessPartial
 SecDataDir /var/asl/data/msa
 SecDefaultAction "phase:2,deny,log,status:406"
 SecRule REMOTE_ADDR "^127.0.0.1$" nolog,allow
 Include "/usr/local/apache/conf/modsec2.user.conf"
 
We've highlighted the changes in italics. Cpanel users will need to manually verify that the mod_unique_id module is loaded by cpanel's apache.
Loading rules occurs through this file:
/usr/local/apache/conf/modsec2.user.conf
For example, if you want to load all the ASL rules, add this line to the bottom of modsec2.user.conf:
Include /full/path/to/your/rules/modsecurity.d/*asl*.conf
If you want to load just some of the rules, make sure you specify only those rule files. For example:
Include /full/path/to/your/rules/modsecurity.d/10_asl_rules.conf
Include /full/path/to/your/rules/modsecurity.d/99_asl_jitp.conf
NOTE: If you use this file:
05_asl_scanner.conf
Make sure you have clamd installed and configured correctly to list on a TCP port, or if you use a socket, make sure apache can read/write to this socket or as a last resort, run clamd as root. Using this file will forces all web uploads on your system to go thru clamav to look for malware, viruses, etc. If you dont need that, then you can leave this config file out.
You will have to adjust the path to the specific location you choose for your system. Another option is to use symlinks to create the same directories in different locations. This is a typical cpanel path, but check your system to make sure it is correct:
/usr/local/apache/conf/modsec2.user.conf
Cpanel also does not run apache as a standard user (such as apache) but as the older non-priviliged user "nobody". You will need to ensure then that the work directories that mod_security uses are owned by the user that Cpanel runs apache as. To find this out you can run this command as root:
ps auxwww | grep httpd
root     20594 86.8  3.1 255148 181232 ?       Ss   11:39   0:04 /usr/local/apache/bin/httpd -k restart
root     20611  0.0  3.1 255060 179596 ?       S    11:39   0:00 /usr/local/apache/bin/httpd -k restart
nobody   20612  0.0  3.1 255148 180224 ?       S    11:39   0:00 /usr/local/apache/bin/httpd -k restart
nobody   20613  0.0  3.1 255148 180224 ?       S    11:39   0:00 /usr/local/apache/bin/httpd -k restart
nobody   20614  0.0  3.1 255148 180224 ?       S    11:39   0:00 /usr/local/apache/bin/httpd -k restart
nobody   20615  0.0  3.1 255148 180224 ?       S    11:39   0:00 /usr/local/apache/bin/httpd -k restart
nobody   20616  0.0  3.1 255148 180224 ?       S    11:39   0:00 /usr/local/apache/bin/httpd -k restart
In this example from a Centos system running Cpanel the user is "nobody", so you would want to use these commands:
chown nobody.nobody /var/asl/data/msa
chown nobody.nobody /var/asl/data/audit
chown nobody.nobody /var/asl/data/suspicious
chmod o-rx -R /var/asl/data/*
chmod ug+rwx -R /var/asl/data/*

[edit] Testing to see if the rules are loaded

Note: This test assumes you do not have any rules disabled.
Here is an easy test to know for sure. On the system where the rules are installed run this command (this assumes you have wget installed):

wget http://localhost/foo.php?foo=http://fakeattacker.com

You should get a 403 error if the rules are loaded, which will look similar to this:
--2010-05-27 20:12:25--  http://localhost/foo.php?foo=http://fakeattacker.com
Resolving localhost... 127.0.0.1
Connecting to localhost|127.0.0.1|:80... connected.
HTTP request sent, awaiting response... 403 Forbidden
2010-05-27 20:12:25 ERROR 403: Forbidden.
If you do not have wget installed, then you will need to install it or a similar tool. You can also use your browser to test the rules by going to this URL:

http://YOUR_HOST/foo.php?foo=http://fakeattacker.com

If the rules are properly loaded, you should get a 403 error, if you do not get a 403 error, the rules are not loaded and you need to check your configuration to ensure that you have followed the instructions above correctly.

References:

the end…


Monday, February 15, 2010

CentOS 5.4 ModSecurity Installation

SkyHi @ Monday, February 15, 2010

Apache Installation
yum install httpd-devel mod_ssl libxml2 libxml2-devel curl-devel pcre-devel gcc-c++
service httpd stop

ModSecurity Installation
wget http://www.modsecurity.org/download/modsecurity-apache_2.5.10.tar.gz
tar -xzvf modsecurity-apache_2.5.10.tar.gz
cd modsecurity-apache_2.5.10
cd apache2
./configure
make
make install
mkdir /etc/httpd/conf/modsecurity
cp ../modsecurity.conf-minimal /etc/httpd/conf/modsecurity/

Settings
vi /etc/httpd/conf/httpd.conf

# ModSecurity
LoadFile /usr/lib/libxml2.so
LoadModule unique_id_module modules/mod_unique_id.so
LoadModule security2_module modules/mod_security2.so
Include conf/modsecurity/modsecurity.conf-minimal

service httpd start
ls /var/log/httpd

access_log  error_log  modsec_audit.log  modsec_debug.log

tail /var/log/httpd/error_log

[Sat Oct 31 20:22:35 2009] [notice] suEXEC mechanism enabled (wrapper: /usr/sbin/suexec)
[Sat Oct 31 20:22:36 2009] [notice] ModSecurity for Apache/2.5.10 (http://www.modsecurity.org/) configured.
[Sat Oct 31 20:22:36 2009] [notice] Digest: generating secret for digest authentication …
[Sat Oct 31 20:22:36 2009] [notice] Digest: done
[Sat Oct 31 20:22:37 2009] [notice] Apache/2.2.3 (CentOS) configured — resuming normal operations



REFERENCE

http://secfx.wordpress.com/2009/10/31/modsecurity-installation/

Monday, December 28, 2009

Mod security

SkyHi @ Monday, December 28, 2009

Contents

[hide]

[edit] Disabling Mod_Security Globally

Step 1) Disable config file

mv /etc/httpd/conf.d/00_mod_security.conf /etc/httpd/conf.d/00_mod_security.conf.disabled

Step 2) Restart Apache

service httpd restart<br />

[edit] Disabling Mod_security per domain

Step 1) Edit the vhost/vhost_ssl.conf for the domain

 vim /var/www/vhosts/<DOMAINNAME>/conf/vhost.conf<br />

Step 2) Add the following

<IfModule mod_security2.c><br />  SecRuleEngine Off<br /></IfModule><br />

Step 3) Add vhost.conf to domain config

/usr/local/psa/admin/bin/websrvmng -a<br />

Step 4) Restart Apache

service httpd restart<br />

[edit] Disable Mod_security on a global URL

Step 1) Create a global exclude file

vim /etc/httpd/modsecurity.d/00_asl_custom_exclude.conf<br />

Step 2) Add the LocationMatch for the url to exclude. Example: /server.php

<LocationMatch /server.php><br />  <IfModule mod_security2.c><br />    SecRuleEngine Off <br />  </IfModule><br /></LocationMatch><br />

Step 3) Restart apache

service httpd restart<br />

[edit] Disable a Mod_security rule (or rules) for all applications in a single domain

Step 1) Edit the vhost/vhost_ssl.conf for the domain

vim /var/www/vhosts/<DOMAINNAME>/conf/vhost.conf<br />

Step 2) Add the LocationMatch for the rule to exclude. Example, ruleid 950005

<LocationMatch .*><br />  <IfModule mod_security2.c><br />    SecRuleRemoveById 950005<br />  </IfModule><br /></LocationMatch><br />

If you want to disable multiple rules:

Step 2) Add the LocationMatch for the rule to exclude. Example, ruleids 950005 and 950006

<LocationMatch .*><br />  <IfModule mod_security2.c><br />    SecRuleRemoveById 950005<br />    SecRuleRemoveById 950006<br />  </IfModule><br /></LocationMatch><br />

[edit] Disable Mod_security rule for a specific application in a single domain

Step 1) Edit the vhost/vhost_ssl.conf for the domain

vim /var/www/vhosts/<DOMAINNAME>/conf/vhost.conf<br />

Step 2) Add the LocationMatch for the rule to exclude. Example, ruleid 950005

<LocationMatch /URL/path/to/application.php><br />  <IfModule mod_security2.c><br />    SecRuleRemoveById 950005<br />  </IfModule><br /></LocationMatch><br />

[edit] Disable Mod_security rule for all domains

Use ASL utility to disable rule by ID. Example: 950005

asl --disable-signature 950005<br />

Note: This requires that Atomic Secured Linux be installed.

If you do not have Atomic Secured Linux you can disable a rule globally manually by adding a rule like this:

<LocationMatch .*><br />  <IfModule mod_security2.c><br />    SecRuleRemoveById 340000<br />  </IfModule><br /></LocationMatch><br />

[edit] Disable Mod_security rules globally for a specific application

Add this to either you vhost.conf file, or if your want to make this global make sure this exclusion is loaded after your rules are loaded. A good place to add this in the 999_asl_user_exclude.conf file. If you don't have this file, just create it. The system is smart enough to know to load it.

<LocationMatch /url/to/your/application><br />  <IfModule mod_security2.c><br />    SecRuleRemoveById 1234567<br />    SecRuleRemoveById 9999999<br />  </IfModule><br /></LocationMatch><br />

Whats important to remember is that the LocationMatch variable must match the URL, not the path on the system.

[edit] Disable Mod_security rules by domain, for a specific application, for a list of IPs

Step 1) Edit the vhost/vhost_ssl.conf for the domain

vim /var/www/vhosts/<DOMAINNAME>/conf/vhost.conf<br />

Step 2) Add the LocationMatch for the rule to exclude.

<LocationMatch /foo/bar.php><br />  <IfModule mod_security2.c><br />    SecRule REMOTE_ADDR "@pmFromFile /etc/asl/whitelist" "nolog,phase:1,allow"<br />  </IfModule><br /></LocationMatch><br />

Step 3) Add IP to /etc/asl/whitelist

echo "10.11.12.13" >> /etc/asl/whitelist<br />

Or:

If you want to create a special whitelist for just that application:

Step 1) Edit the vhost/vhost_ssl.conf for the domain

vim /var/www/vhosts/<DOMAINNAME>/conf/vhost.conf<br />

Step 2) Add the LocationMatch for the rule to exclude.

<LocationMatch /foo/bar.php><br />  <IfModule mod_security2.c><br />    SecRule REMOTE_ADDR "@pmFromFile /path/to/your/custom/whitelist_for_this_application" "nolog,phase:1,allow"<br />  </IfModule><br /></LocationMatch><br />

Step 3) Create your custom whitelist and add IP to /etc/asl/whitelist

echo "10.11.12.13" >> /path/to/your/custom/whitelist_for_this_application<br />

Keep in mind these custom lists are *not* managed by ASL, so if you want to add IPs to these lists you will need to do it from the command line.

[edit] Configuring and Setting up mod_security

If you are running ASL you do not need to do this. ASL will setup and manage mod_security for you. The page linked to below is only for non-ASL customers that must setup mod_security manually.

To setup and configured modsecurity, please see the Atomic_ModSecurity_Rules wiki page.



Reference: http://www.atomicorp.com/wiki/index.php/Mod_security

Thursday, December 3, 2009

Blocking Common Attacks using ModSecurity 2.5: Part 3

SkyHi @ Thursday, December 03, 2009
Blocking Common Attacks using ModSecurity 2.5: Part 3

Read Part One of Blocking Common Attacks using ModSecurity 2.5 here.

Read Part Two of Blocking Common Attacks using ModSecurity 2.5 here.

Source code revelation

Normally, requesting a file with a .php extension will cause mod_php to execute the PHP code contained within the file and then return the resulting web page to the user. If the web server is misconfigured (for example if mod_php is not loaded) then the .php file will be sent by the server without interpretation, and this can be a security problem. If the source code contains credentials used to connect to an SQL database then that opens up an avenue for attack, and of course the source code being available will allow a potential attacker to scrutinize the code for vulnerabilities.

Preventing source code revelation is easy. With response body access on in ModSecurity, simply add a rule to detect the opening PHP tag:

Prevent PHP source code from being disclosed

SecRule RESPONSE_BODY "

Preventing Perl and JSP source code from being disclosed works in a similar manner:

# Prevent Perl source code from being disclosed

SecRule RESPONSE_BODY "#!/usr/bin/perl" "deny,msg:'Perl

source code disclosure blocked'"

# Prevent JSP source code from being disclosed

SecRule RESPONSE_BODY "

Directory traversal attacks

Normally, all web servers should be configured to reject attempts to access any document that is not under the web server's root directory. For example, if your web server root is /home/www, then attempting to retrieve /home/joan/.bashrc should not be possible since this file is not located under the /home/www web server root. The obvious attempt to access the /home/joan directory is, of course, easy for the web server to block, however there is a more subtle way to access this directory which still allows the path to start with /home/www, and that is to make use of the .. symbolic directory link which links to the parent directory in any given directory.

Even though most web servers are hardened against this sort of attack, web applications that accept input from users may still not be checking it properly, potentially allowing users to get access to files they shouldn't be able to view via simple directory traversal attacks. This alone is reason to implement protection against this sort of attack using ModSecurity rules. Furthermore, keeping with the principle of Defense in Depth, having multiple protections against this vulnerability can be beneficial in case the web server should contain a flaw that allows this kind of attack in certain circumstances.

There is more than one way to validly represent the .. link to the parent directory. URL encoding of .. yields % 2e% 2e, and adding the final slash at the end we end up with % 2e% 2e% 2f(please ignore the space).

Here, then is a list of what needs to be blocked:

../

..% 2f

.% 2e/

%  2e%  2e% 2f

% 2e% 2e/

% 2e./

Fortunately, we can use the ModSecurity transformation t:urlDecode. This function does all the URL decoding for us, and will allow us to ignore the percent-encoded values, and thus only one rule is needed to block these attacks:

SecRule REQUEST_URI "../" "t:urlDecode,deny"

Blog spam

The rise of weblogs, or blogs, as a new way to present information, share thoughts, and keep an online journal has made way for a new phenomenon: blog comments designed to advertise a product or drive traffic to a website.

Blog spam isn't a security problem per se, but it can be annoying and cost a lot of time when you have to manually remove spam comments (or delete them from the approval queue, if comments have to be approved before being posted on the blog).

Blog spam can be mitigated by collecting a list of the most common spam phrases, and using the ability of ModSecurity to scan POST data. Any attempted blog comment that contains one of the offending phrases can then be blocked.

From both a performance and maintainability perspective, using the @pmFromFile operator is the best choice when dealing with large word lists such as spam phrases. To create the list of phrases to be blocked, simply insert them into a text file, for example, /usr/local/spamlist.txt:

viagra

v1agra

auto insurance

rx medications

cheap medications

...

Then create ModSecurity rules to block those phrases when they are used in locations such as the page that creates new blog comments:

#

# Prevent blog spam by checking comment against known spam

# phrases in file /usr/local/spamlist.txt

#

SecRule ARGS "@pmFromFile /usr/local/spamlist.txt" "t:

lowercase,deny,msg:'Blog spam blocked'"

Keep in mind that the spam list file can contain whole sentences—not just single words—so be sure to take advantage of that fact when creating the list of known spam phrases.

SQL injection

SQL injection attacks can occur if an attacker is able to supply data to a web application that is then used in unsanitized form in an SQL query. This can cause the SQL query to do completely different things than intended by the developers of the web application. Consider an SQL query like this:

SELECT * FROM user WHERE username = '%s' AND password = '%s';

The flaw here is that if someone can provide a password that looks like ' OR '1'='1, then the query, with username and password inserted, will become:

SELECT * FROM user WHERE username = 'anyuser' AND password = ''

OR '1'='1';

This query will return all users in the results table, since the OR '1'='1' part at the end of the statement will make the entire statement true no matter what username and password is provided.

Standard injection attempts

Let's take a look at some of the most common ways SQL injection attacks are performed.

Retrieving data from multiple tables with UNION

An SQL UNION statement can be used to retrieve data from two separate tables. If there is one table named cooking_recipes and another table named user_credentials, then the following SQL statement will retrieve data from both tables:

SELECT dish_name FROM recipe UNION SELECT username, password

FROM user_credentials;

It's easy to see how the UNION statement can allow an attacker to retrieve data from other tables in the database if he manages to sneak it into a query. A similar SQL statement is UNION ALL, which works almost the same way as UNION—the only difference is that UNION ALL will not eliminate any duplicate rows returned in the result.

Multiple queries in one call

If the SQL engine allows multiple statements in a single SQL query then seemingly harmless statements such as the following can present a problem:

SELECT * FROM products WHERE id = %d;

If an attacker is able to provide an ID parameter of 1; DROP TABLE products;, then the statement suddenly becomes:

SELECT * FROM products WHERE id = 1; DROP TABLE products;

When the SQL engine executes this, it will first perform the expected SELECT query, and then the DROP TABLE products statement, which will cause the products table to be deleted.

Reading arbitrary files

MySQL can be used to read data from arbitrary files on the system. This is done by using the LOAD_FILE() function:

SELECT LOAD_FILE("/etc/passwd");

This command returns the contents of the file /etc/passwd. This works for any file to which the MySQL process has read access.

Writing data to files

MySQL also supports the command INTO OUTFILE which can be used to write data into files. This attack illustrates how dangerous it can be to include user-supplied data in SQL commands, since with the proper syntax, an SQL command can not only affect the database, but also the underlying file system.

This simple example shows how to use MySQL to write the string some data into the file test.txt:

mysql> SELECT "some data" INTO OUTFILE "test.txt";

Preventing SQL injection attacks

There are three important steps you need to take to prevent SQL injection attacks:

Use SQL prepared statements.

Sanitize user data.

Use ModSecurity to block SQL injection code supplied to web applications.

These are in order of importance, so the most important consideration should always be to make sure that any code querying SQL databases that relies on user input should use prepared statements. A prepared statement looks as follows:

SELECT * FROM books WHERE isbn = ? AND num_copies

This allows the SQL engine to replace the question marks with the actual data. Since the SQL engine knows exactly what is data and what SQL syntax, this prevents SQL injection from taking place.

The advantages of using prepared statements are twofold:

They effectively prevent SQL injection.

They speed up execution time, since the SQL engine can compile the statement once, and use the pre-compiled statement on all subsequent query invocations.

So not only will using prepared statements make your code more secure—it will also make it quicker.

The second step is to make sure that any user data used in SQL queries is sanitized. Any unsafe characters such as single quotes should be escaped. If you are using PHP, the function mysql_real_escape_string() will do this for you.

Finally, let's take a look at strings that ModSecurity can help block to prevent SQL injection attacks.

What to block

The following table lists common SQL commands that you should consider blocking, together with a suggested regular expression for blocking. The regular expressions are in lowercase and therefore assume that the t:lowercase transformation function is used.

SQL code

Regular expression

UNION SELECT

unions+select

UNION ALL SELECT

unions+alls+select

INTO OUTFILE

intos+outfile

DROP TABLE

drops+table

ALTER TABLE

alters+table

LOAD_FILE

load_file

SELECT *

selects+*

For example, a rule to detect attempts to write data into files using INTO OUTFILE looks as follows:

SecRule ARGS "intos+outfile" "t:lowercase,deny,msg:

'SQL Injection'"

The s+ regular expression syntax allows for detection of an arbitrary number of whitespace characters. This will detect evasion attempts such as INTO OUTFILE where multiple spaces are used between the SQL command words.

Website defacement

We've all seen the news stories: "Large Company X was yesterday hacked and their homepage was replaced with an obscene message". This sort of thing is an everyday occurrence on the Internet.

After the company SCO initiated a lawsuit against Linux vendors citing copyright violations in the Linux source code, the SCO corporate website was hacked and an image was altered to read WE OWN ALL YOUR CODE—pay us all your money. The hack was subtle enough that the casual visitor to the SCO site would likely not be able to tell that this was not the official version of the homepage:



The above image shows what the SCO homepage looked like after being defaced—quite subtle, don't you think?

Preventing website defacement is important for a business for several reasons:

Potential customers will turn away when they see the hacked site

There will be an obvious loss of revenue if the site is used for any sort of e-commerce sales

Bad publicity will tarnish the company's reputation

Defacement of a site will of course depend on a vulnerability being successfully exploited. The measures we will look at here are aimed to detect that a defacement has taken place, so that the real site can be restored as quickly as possible.

Detection of website defacement is usually done by looking for a specific token in the outgoing web pages. This token has been placed within the pages in advance specifically so that it may be used to detect defacement—if the token isn't there then the site has likely been defaced. This can be sufficient, but it can also allow the attacker to insert the same token into his defaced page, defeating the detection mechanism. Therefore, we will go one better and create a defacement detection technology that will be difficult for the hacker to get around.

To create a dynamic token, we will be using the visitor's IP address. The reason we use the IP address instead of the hostname is that a reverse lookup may not always be possible, whereas the IP address will always be available.

The following example code in JSP illustrates how the token is calculated and inserted into the page.

%s",

tokenHashed));

%>

Assuming the background of the page is white, the  markup will ensure it is not visible to website viewers.

Now for the ModSecurity rules to handle the defacement detection. We need to look at outgoing pages and make sure that they include the appropriate token. Since the token will be different for different users, we need to calculate the same MD5 sum token in our ModSecurity rule and make sure that this token is included in the output. If not, we block the page from being sent and sound the alert by sending an email message to the website administrator.

#

# Detect and block outgoing pages not containing our token

#

SecRule REMOTE_ADDR ".*" "phase:4,deny,chain,t:md5,t:hexEncode,

  exec:/usr/bin/emailadmin.sh"

SecRule RESPONSE_BODY "!@contains %{MATCHED_VAR}"

We are placing the rule in phase 4 since this is required when we want to inspect the response body. The exec action is used to send an email to the website administrator to let him know of the website defacement.

ModSecurity 2.5









Prevent web application hacking with this easy to use guide

Secure your system by knowing exactly how a hacker would break into it

Covers writing rules in-depth and Modsecurity rule language elements such as variables, actions, and request phases

Covers the common attacks in use on the Web, and ways to find the geographical location of an attacker and send alert emails when attacks are discovered

Packed with many real-life examples for better understanding http://www.packtpub.com/modsecurity-2-5/book

Brute force attacks

Brute force attacks involve an attacker repeatedly trying to gain access to a resource by guessing usernames, passwords, email addresses, and similar credentials. They can be incredibly effective if no protection is in place, since most users choose passwords that are short and easy to remember. Furthermore, most users will use nearly identical passwords on all websites for which a login is required, and so compromise of one password can lead to the user having his account compromised at a whole range of other sites.

A good way to defend against brute force attacks is to allow a certain number of login attempts, say three, and after that start delaying or blocking further attempts. Let's see how we can use ModSecurity to accomplish this.

If your login verification page is situated at yoursite.com/login, then the following rules will keep track of the number of login attempts by users:

#

# Block further login attempts after 3 failed attempts

#

# Initalize IP collection with user's IP address

SecAction "initcol:ip=%{REMOTE_ADDR},pass,nolog"

# Detect failed login attempts

SecRule RESPONSE_BODY "Username does not exist" "phase:4,pass,setvar:

ip.failed_logins=+1,expirevar:ip.failed_logins=60"

# Block subsequent login attempts

SecRule IP:FAILED_LOGINS "@gt 3" deny

The rules initialize the ip collection and increase the field ip.failed_logins after each failed login attempt. Once more than three failed logins are detected, further attempts are blocked. The expirevar action is used to reset the number of failed login attempts to zero after 60 seconds, so the block will be in effect for a maximum of 60 seconds.

Another approach is to start delaying requests once the threshold number of login attempts has been reached. This has the advantage of not denying access in case a legitimate user has actually forgotten his password and needs more attempts to remember it. Here are the rules to do that:

#

# Throttle login attempts after 3 failed attempts

#

SecAction "initcol:ip=%{REMOTE_ADDR},pass,nolog"

SecRule RESPONSE_BODY "Username does not exist" "phase:4,pass,setvar:

ip.failed_logins=+1,expirevar:ip.failed_logins=10"

SecRule IP:FAILED_LOGINS "@gt 3" "phase:4,allow,pause:3000"

The pause action is what delays the request, and the time specified is in milliseconds, so the above will delay the response for three seconds once the limit of three failed login attempts has been exceeded.

Directory indexing

When a user requests an URL like http://www.example.com/, with no filename specification, Apache will look for the file specified by the DirectoryIndex setting (for example index.html). If this file is found, it is served to the user. If it doesn't exist, what happens next is determined by whether the Apache option called Indexes is enabled or not.

The Indexes option can be enabled for a directory in the following way:

Options +Indexes

If the Indexes option is active then Apache will generate a directory listing and display it to the user if the default DirectoryIndex file is not found. This listing contains the names of all files and sub-directories in the requested directory, and this can be a problem for several reasons:

Files that were never meant to be publicly disclosed can be requested by the user, even if they are not linked from anywhere

Names of subdirectories are displayed, and again this may lead to the user wandering into directories that were never meant for public disclosure

In a perfect world, you would never have files under the web server root that users should not be able to download, and all directories or files requiring authorization should be protected by the appropriate HTTP authentication settings. However, in the real world, files and directories do sometimes end up under the web server root even when they are not meant to be accessible by all users. Therefore it makes sense to turn off directory indexing so that this listing is never generated:

Options -Indexes

Even with this in place, sometimes directory indexing can get turned back on—configuration files get edited or replaced with defaults. One option would be to comment out the line for the mod_autoindex module in the Apache configuration file:

#

# Disable directory indexing

#

# LoadModule autoindex_module modules/mod_autoindex.so

However, even this can fail should the configuration file be returned to its default at some point, or if a web server vulnerability causes the directory index to be returned even though Options -Indexes is set. Consider for example the vulnerability discovered in 2001 that affected Apache version 1.3.20 and earlier, described as follows in the changelog for Apache when the corrected version 1.3.22 was released:

A vulnerability was found when Multiviews are used to negotiate the directory index. In some configurations, requesting a URI with a QUERY_STRING of M=D could return a directory listing rather than the expected index page.

This shows that unexpected circumstances can cause directory indexes to be returned even when the web server administrator does everything correctly. Therefore, in keeping with the Defense in Depth principle, adding a precautionary set of rules to ModSecurity to block any directory index from escaping the web server can be a good idea.

These rules will block the Apache directory index from being returned:

#

# Prevent directory listings from accidentally being returned

#

SecRule REQUEST_URI "/$" "phase:4,deny,chain,log,

  msg:'Directory index returned'"

SecRule RESPONSE_BODY "Index of /"

The above rule chain is placed in phase 4, since we need to examine the response body for the telltale signature Index of /, which is what Apache returns in directory index pages. This string could potentially be contained within regular HTML documents, so we do an additional check in the first rule—the request URI has to end with a forward slash, which it does when the user requests a directory. Even if the user were to request /example, without a trailing slash, the Apache module mod_dir will issue a 301—Moved permanently redirect to /example/ before the directory listing is returned (or not returned, as will be the case with the rule chain above active).

Detecting the real IP address of an attacker

If you're under attack by a sophisticated adversary, he will most likely be hiding behind an anonymizing proxy—sometimes he will even be using multiple chained proxies to avoid detection. The illustration below shows how this works when two proxy servers are involved. The web server will only see the IP address of the last proxy server, and even if the proxy server administrator co-operated to help find an attacker, the logs would only show the IP address of the proxy server before it in the chain.



Wouldn't it be great to be able to get the real IP address of an attacker and have it logged if a severe enough attack is taking place? The real IP address can be what makes or breaks an investigation if an attack ever has to be reported to the police.

The first step in implementing real IP address detection is to realize that ModSecurity's redirect action can be used to redirect to a different page when an attack is detected. We will just be redirecting to a standard 404—Not Found error page.

Now the remaining problem is: What do we put on this modified error page to detect the attacker's IP address? One possible avenue of approach would be to include some JavaScript code in the error page to try to find out his IP address. Unfortunately, it's not possible to detect the IP address of a computer using JavaScript—using the function java.net.InetAddress.getLocalHost() returns localhost on all systems.

However, what if the attacker has Java enabled in his browser? In that case, it is actually possible to use Java to detect the IP address of the attacking computer. We will basically be turning the attacker's own web browser against him by loading a Java applet that will detect his IP address and transmit it to our server. The following diagram illustrates how this works:



Lars Kindermann has a ready-made Java applet to detect IP addresses called "MyAddress" which is available at http://www.reglos.de/myaddress/MyAddress.html. Simply download this to your web server by saving the MyAddress.class file that is linked to on the page.

To get the attacker's IP address we will be using a technique familiar from the section on cross-site scripting attacks—the use of an  tag to transmit data back to our server. In this case, the data we will be transmitting is the attacker's IP address. Once we have the attacker's IP address—say 1.2.3.4—we will include the following  tag on the error page to capture his IP address:

This will cause the attacker's web browser to perform a GET request to the page at www.ourserver.com/log_ip.php, handily providing the IP address in the query string. It is then a simple matter for the script log_ip.php to record the IP address in a database table or a text file.

This is the code that needs to be included on our modified error page in order to retrieve the IP address by invoking the Java applet and then printing out the  tag:

function MyAddress(IP) {

  document.write("");

}

This first line uses an  tag to load the Java applet called MyAddress.class. The subsequent lines execute JavaScript code that does two things:

Retrieves the IP address of the attacker's computer.

Writes an  tag to the web page that references our own server to send the IP address back to us.

You can see that the second step is what makes this similar to cross-site scripting.

This suffers from a small problem—the  tag doesn't actually reference a valid image, which will cause the attacker to see a page with a "broken image" icon. Luckily, this is easily resolved by setting the width and height attributes of the image to zero:

function MyAddress(IP) {

  document.write("");

}

Now, the final piece of the puzzle is just to redirect detected attacks to the log_ip.php page. The following ModSecurity rule illustrates how to do this:

SecRule ARGS "/etc/passwd" "pass,redirect:/log_ip.php"

Though real IP-detection may not be preferable for "everyday" attacks, it can be a handy tool in those cases where finding out the IP of the attacker is essential to prevent further crimes from taking place or assisting the police in an investigation.

Summary

In this article, we looked at different methods of attack currently used against web applications and servers. We learned the anatomy behind attacks such as cross-site scripting, cross-site request forgeries, and SQL injection. We saw how ModSecurity can be used to mitigate or block these attacks, and how ModSecurity can be a vital part of applying the Defense in Depth strategy. In the last sections of the article we learned how to defeat HTTP fingerprinting and how to detect the real IP address of an attacker if he is surfing via a proxy server but has Java enabled in his browser.

[ 1 | 2 | 3 ]

Blocking Common Attacks using ModSecurity 2.5: Part 2

SkyHi @ Thursday, December 03, 2009
Blocking Common Attacks using ModSecurity 2.5: Part 2

Read Part One of Blocking Common Attacks using ModSecurity 2.5 here.

Cross-site scripting

Cross-site scripting attacks occur when user input is not properly sanitized and ends up in pages sent back to users. This makes it possible for an attacker to include malicious scripts in a page by providing them as input to the page. The scripts will be no different than scripts included in pages by the website creators, and will thus have all the privileges of an ordinary script within the page—such as the ability to read cookie data and session IDs. In this article we will look in more detail on how to prevent attacks.

The name "cross-site scripting" is actually rather poorly chosen—the name stems from the first such vulnerability that was discovered, which involved a malicious website using HTML framesets to load an external site inside a frame. The malicious site could then manipulate the loaded external site in various ways—for example, read form data, modify the site, and basically perform any scripting action that a script within the site itself could perform. Thus cross-site scripting, or XSS, was the name given to this kind of attack.

The attacks described as XSS attacks have since shifted from malicious frame injection (a problem that was quickly patched by web browser developers) to the class of attacks that we see today involving unsanitized user input. The actual vulnerability referred to today might be better described as a "malicious script injection attack", though that doesn't give it quite as flashy an acronym as XSS. (And in case you're curious why the acronym is XSS and not CSS, the simple explanation is that although CSS was used as short for cross-site scripting in the beginning, it was changed to XSS because so many people were confusing it with the acronym used for Cascading Style Sheets, which is also CSS.)

Cross-site scripting attacks can lead not only to cookie and session data being stolen, but also to malware being downloaded and executed and injection of arbitrary content into web pages.

Cross-site scripting attacks can generally be divided into two categories:

Reflected attacks

This kind of attack exploits cases where the web application takes data provided by the user and includes it without sanitization in output pages. The attack is called "reflected" because an attacker causes a user to provide a malicious script to a server in a request that is then reflected back to the user in returned pages, causing the script to execute.

Stored attacks

In this type of XSS attack, the attacker is able to include his malicious payload into data that is permanently stored on the server and will be included without any HTML entity encoding to subsequent visitors to a page. Examples include storing malicious scripts in forum posts or user presentation pages. This type of XSS attack has the potential to be more damaging since it can affect every user who views a certain page.

Preventing XSS attacks

The most important measure you can take to prevent XSS attacks is to make sure that all user-supplied data that is output in your web pages is properly sanitized. This means replacing potentially unsafe characters, such as angled brackets () with their corresponding HTML-entity encoded versions—in this case  and >.

Here is a list of characters that you should encode when present in user-supplied data that will later be included in web pages:

Character

HTML-encoded version



>

>

(

(

)

)

#

#

&

&

"

"

'

'

In PHP, you can use the htmlentities() function to achieve this. When encoded, the string  will be converted into . This latter version will be displayed as  in the web browser, without being interpreted as the start of a script by the browser.

In general, users should not be allowed to input any HTML markup tags if it can be avoided. If you do allow markup such as  to be input by users in blog comments, forum posts, and similar places then you should be aware that simply filtering out the  tag is not enough, as this simple example shows:

Innocent link

This link will execute the JavaScript code contained within the onMouseOver attribute whenever the user hovers his mouse pointer over the link. You can see why even if the web application replaced  tags with their HTML-encoded version, an XSS exploit would still be possible by simply using onMouseOver or any of the other related events available, such as onClick or onMouseDown.

I want to stress that properly sanitizing user input as just described is the most important step you can take to prevent XSS exploits from occurring. That said, if you want to add an additional line of defense by creating ModSecurity rules, here are some common XSS script fragments and regular expressions for blocking them:

Script fragment

Regular expression

eval(

evals*(

onMouseOver

onmouseover

onMouseOut

onmouseout

onMouseDown

onmousedown

onMouseMove

onmousemove

onClick

onclick

onDblClick

ondblclick

onFocus

onfocus

PDF XSS protection

You may have seen the ModSecurity directive SecPdfProtect mentioned, and wondered what it does. This directive exists to protect users from a particular class of cross-site scripting attack that affects users running a vulnerable version of the Adobe Acrobat PDF reader.

A little background is required in order to understand what SecPdfProtect does and why it is necessary. In 2007, Stefano Di Paola and Giorgio Fedon discovered a vulnerability in Adobe Acrobat that allows attackers to insert JavaScript into requests, which is then executed by Acrobat in the context of the site hosting the PDF file. Sound confusing? Hang on, it will become clearer in a moment.

The vulnerability was quickly fixed by Adobe in version 7.0.9 of Acrobat. However, there are still many users out there running old versions of the reader, which is why preventing this sort of attack is still an ongoing concern.

The basic attack works like this: An attacker entices the victim to click a link to a PDF file hosted on www.example.com. Nothing unusual so far, except for the fact that the link looks like this:

http://www.example.com/document.pdf#x=javascript:alert('XSS');

Surprisingly, vulnerable versions of Adobe Acrobat will execute the JavaScript in the above link. It doesn't even matter what you place before the equal sign, gibberish= will work just as well as x= in triggering the exploit.

Since the PDF file is hosted on the domain www.example.com, the JavaScript will run as if it was a legitimate piece of script within a page on that domain. This can lead to all of the standard cross-site scripting attacks that we have seen examples of before.

This diagram shows the chain of events that allows this exploit to function:



The vulnerability does not exist if a user downloads the PDF file and then opens it from his local hard drive.

ModSecurity solves the problem of this vulnerability by issuing a redirect for all PDF files. The aim is to convert any URLs like the following:

http://www.example.com/document.pdf#x=javascript:alert('XSS');

into a redirected URL that has its own hash character:

http://www.example.com/document.pdf#protection

This will block any attacks attempting to exploit this vulnerability. The only problem with this approach is that it will generate an endless loop of redirects, as ModSecurity has no way of knowing what is the first request for the PDF file, and what is a request that has already been redirected. ModSecurity therefore uses a one-time token to keep track of redirect requests. All redirected requests get a token included in the new request string. The redirect link now looks like this:

http://www.example.com/document.pdf?PDFTOKEN=XXXXX#protection

ModSecurity keeps track of these tokens so that it knows which links are valid and should lead to the PDF file being served. Even if a token is not valid, the PDF file will still be available to the user, he will just have to download it to the hard drive.

These are the directives used to configure PDF XSS protection in ModSecurity:

SecPdfProtect On

SecPdfProtectMethod TokenRedirection

SecPdfProtectSecret "SecretString"

SecPdfProtectTimeout 10

SecPdfProtectTokenName "token"

The above configures PDF XSS protection, and uses the secret string SecretString to generate the one-time tokens. The last directive, SecPdfProtectTokenName, can be used to change the name of the token argument (the default is PDFTOKEN). This can be useful if you want to hide the fact that you are running ModSecurity, but unless you are really paranoid it won't be necessary to change this.

The SecPdfProtectMethod can also be set to ForcedDownload, which will force users to download the PDF files instead of viewing them in the browser. This can be an inconvenience to users, so you would probably not want to enable this unless circumstances warrant (for example, if a new PDF vulnerability of the same class is discovered in the future).

HttpOnly cookies to prevent XSS attacks

One mechanism to mitigate the impact of XSS vulnerabilities is the HttpOnly flag for cookies. This extension to the cookie protocol was proposed by Microsoft (see http://msdn.microsoft.com/en-us/library/ms533046.aspx for a description), and is currently supported by the following browsers:

Internet Explorer (IE6 SP1 and later)

Firefox (2.0.0.5 and later)

Google Chrome (all versions)

Safari (3.0 and later)

Opera (version 9.50 and later)

HttpOnly cookies work by adding the HttpOnly flag to cookies that are returned by the server, which instructs the web browser that the cookie should only be used when sending HTTP requests to the server and should not be made available to client-side scripts via for example the document.cookie property. While this doesn't completely solve the problem of XSS attacks, it does mitigate those attacks where the aim is to steal valuable information from the user's cookies, such as for example session IDs.

A cookie header with the HttpOnly flag set looks like this:

Set-Cookie: SESSID=d31cd4f599c4b0fa4158c6fb; HttpOnly

HttpOnly cookies need to be supported on the server-side for the clients to be able to take advantage of the extra protection afforded by them. Some web development platforms currently support HttpOnly cookies through the use of the appropriate configuration option. For example, PHP 5.2.0 and later allow HttpOnly cookies to be enabled for a page by using the following ini_set() call:

Tomcat (a Java Servlet and JSP server) version 6.0.19 and later supports HttpOnly cookies, and they can be enabled by modifying a context's configuration so that it includes the useHttpOnly option, like so:

  

In case you are using a web platform that doesn't support HttpOnly cookies, it is actually possible to use ModSecurity to add the flag to outgoing cookies. We will see how to do this now.

Session identifiers

Assuming we want to add the HttpOnly flag to session identifier cookies, we need to know which cookies are associated with session identifiers. The following table lists the name of the session identifier cookie for some of the most common languages:

Language

Session identifier cookie name

PHP

PHPSESSID

JSP

JSESSIONID

ASP

ASPSESSIONID

ASP.NET

ASP.NET_SessionId

The table shows us that a good regular expression to identify session IDs would be (sessionid|sessid), which can be shortened to sess(ion)?id. The web programming language you are using might use another name for the session cookie. In that case, you can always find out what it is by looking at the headers returned by the server:

echo -e "GET / HTTP/1.1nHost:yourserver.comnn"|nc yourserver.com

80|head

Look for a line similar to:

Set-Cookie: JSESSIONID=4EFA463BFB5508FFA0A3790303DE0EA5; Path=/

This is the session cookie—in this case the name of it is JESSIONID, since the server is running Tomcat and the JSP web application language.

The following rules are used to add the HttpOnly flag to session cookies:

#

# Add HttpOnly flag to session cookies

#

SecRule RESPONSE_HEADERS:Set-Cookie "!(?i:HttpOnly)"

"phase:3,chain,pass"

SecRule MATCHED_VAR "(?i:sess(ion)?id)" "setenv:session_

cookie=%{MATCHED_VAR}"

Header set Set-Cookie "%{SESSION_COOKIE}e; HttpOnly" env=session_

cookie

We are putting the rule chain in phase 3—RESPONSE_HEADERS, since we want to inspect the response headers for the presence of a Set-Cookie header. We are looking for those Set-Cookie headers that do not contain an HttpOnly flag. The (?i: ) parentheses are a regular expression construct known as a mode-modified span. This tells the regular expression engine to ignore the case of the HttpOnly string when attempting to match. Using the t:lowercase transform would have been more complicated, as we will be using the matched variable in the next rule, and we don't want the case of the variable modified when we set the environment variable.

ModSecurity 2.5









Prevent web application hacking with this easy to use guide

# Secure your system by knowing exactly how a hacker would break into it

Covers writing rules in-depth and Modsecurity rule language elements such as variables, actions, and request phases

Covers the common attacks in use on the Web, and ways to find the geographical location of an attacker and send alert emails when attacks are discovered

Packed with many real-life examples for better understanding http://www.packtpub.com/modsecurity-2-5/book

If a cookie header without the HttpOnly flag is found, the second rule looks to see if it is a session identifier cookie. If it is, the setenv action is used to set the environment variable %{SESSION_COOKIE}. ModSecurity cannot be used to modify the cookie header directly (ModSecurity content injection can only prepend data to the beginning of the response or append it to the end of the response), so we are using a plain Apache directive—the Header directive—to modify the cookie header:

Header set Set-Cookie "%{session_cookie}e; HttpOnly" env=session_

cookie

Header directives can use the env= syntax, which means that they will only be invoked if the named environment variable is set. In this case, the Header directive will only be invoked if the %{SESSION_COOKIE} environment variable was set by the ModSecurity rule chain. When invoked, the header directive sets the Set-Cookie header to its previous value (%{SESSION_COOKIE}e is what does this—the e at the end is used to identify this as an environment variable). The string ; HttpOnly is then appended to the end of the previous header.

If we now look at the HTTP headers returned by the server, the session ID cookie will have the HttpOnly flag set:

$ echo -e "GET / HTTP/1.0nn" | nc localhost 80 | head

...

Set-Cookie: JSESSIONID=4EFA463BFB5508FFA0A3790303DE0EA5; Path=/;

HttpOnly

Cleaning XSS Code from Databases

Scrubbr is the name of a tool for cleaning databases of stored XSS attacks that is made available at no charge by the Open Web Application Security Project (OWASP). Scrubbr works by examining database tables for stored malicious scripts.

The developers have this to say about how the tool works: If you can tell Scrubbr how to access your database, it will search through every field capable of holding strings in the database for malicious code. If you want it to, it will search through every table, every row, and every column.

Scrubbr can be downloaded at http://code.google.com/p/owaspscrubbr/, and more information on the tool is available on the OWASP homepage at http://www.owasp.org/index.php/Category:OWASP_Scrubbr.

Cross-site request forgeries

Cross-site request forgeries (CSRF) are attacks that trick the victim's browser into submitting a request to another site where the user is logged in, causing that site to believe the user has initiated an action, and that action is then executed as if the user had initiated it. In other words, cross-site request forgeries execute some action on a site that the user never intended.

One example would be if while you are logged into your bank's online banking site someone got you to visit a page that contained the following  tag:

As we already know that an  tag can be used to execute GET requests, this would cause money to be transferred from one account to another assuming the banking site can do this via GET requests. This is the essence of CSRF attacks—to embed code into a page that causes an action to be executed without the user's knowledge. The aim can be to transfer money, get the user to buy things at auction sites, make him send messages to other users on a site, or any number of things to make it look like the logged-in user on a site has performed some action which was in reality initiated by the CSRF code.

To get a clearer picture, imagine this scenario:

You do your online banking with Acme Bank

Acme Bank's website is vulnerable to CSRF attacks

You also regularly visit the gardening forum at gardening.com

Now suppose your long-time enemy Ned is aware of your browsing habits. Since he's got an axe to grind he hatches a scheme to transfer $10,000 from your personal savings account to his own account. Since Ned knows that you use Acme bank and are also a regular visitor at gardening.com, he starts a topic at the gardening forum with the title "Wild fuchsias for sale", knowing you are a fan of fuchsias and have been looking for quality specimens for some time.

If you take the bait and click on the topic in the forum, Ned's evil HTML tag will get downloaded by your browser:

If you are logged into your banking site at the time your browser attempts to render the forum topic, your well-meaning browser will attempt to fetch the image located at bank.acme.com/transfer.php, passing the entire query string along with it. Unbeknownst to you, you have just transferred enough money to buy a small car to Ned.

Protecting against cross-site request forgeries

Protecting against CSRF attacks can be challenging. Superficially, it might look like only GET requests are vulnerable, since that is what the browser uses in our examples with the malicious  tags. However, that is not true as with the right script code it is possible for a client-side script to perform POST requests. The following code uses Ajax technology to do just that:

var post_data = 'name=value';

var xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");

xmlhttp.open("POST", 'http://url/path/file.ext', true);

xmlhttp.onreadystatechange = function () {

  if (xmlhttp.readyState == 4) {

    alert(xmlhttp.responseText);

  }

};

xmlhttp.send(post_data);

The core of the problem is that the requests come from the user's own browser and look like legitimate requests. The mainstream solutions today revolve around giving the user's browser some piece of information that it must then transmit back when performing an action. Examples include:

Generating a token that is sent together with forms to the user. Any action taken must then include this token or it will be rejected.

Randomizing page names. This gives a user unique URLs to perform actions, and should preferably be changed for each new user session. This makes it difficult for the attacker to know where to submit the requests.

Requiring authentication to perform important actions. Usually this is done by requesting the username and password to be entered, but for high-security sites such as banking sites this can also involve the user using a small hardware device to generate an authorization code that is submitted to the server.

Shell command execution attempts

As we have already seen, accepting unfiltered input from users can be dangerous. A particular class of exploit occurs when data submitted by users is used to cause the execution or display of a file which the user normally wouldn't have privileges to.

Attackers often combine multiple vulnerabilities to achieve maximum effect. Shell command execution is one exploit scenario which usually doesn't happen on its own—after all, very few web applications take user input and perform the exec() system call on them. However, consider the following chain of events:



In this chain of event, we can see how two vulnerabilities were combined to deadly effect:

The SQL injection vulnerability was used to create a PHP file

The failure to filter out shell command execution attempts allowed the attacker to call the exec.php script to remove all files on the web server

This shows that trying to prevent shell command execution is worthwhile (and once again reaffirms the principle of Defense in Depth). I say "trying" since there will always be ways to write system commands that circumvent any detection patterns, however some protection is better than none.

The following are some common Linux system commands, program names, and paths that you may wish to block:

rm

ls

kill

mail

sendmail

cat

echo

/bin/

/etc/

/tmp/

The following rule will block the above when present in arguments:

SecRule ARGS "(rm|ls|kill|(send)?mail|cat|echo|/bin/|/etc/|/tmp/)"

"deny"

Null byte attacks

Null byte attacks exploit the fact that the C programming language (and related languages) use a null byte (0x00) to signify the end of a string. The string dog, for example, is stored in memory in the following way when the C programming language is used:



In other programming languages, such as Java, strings are stored as arrays, and the total length of the string is stored in a separate location, which means that a Java string is perfectly capable of containing a null byte in the middle of the string.

This difference in how strings and null bytes are handled by different programming languages enable some attacks to take place that exploit the null byte to fool one part of a system by making it think a string has ended at a null byte, while another part will happily process the full input string

Consider a simple JSP page that displays a text file to a visitor by using the filename parameter supplied to the page:

The page attempts to ensure that only files with the extension .txt can be displayed to the visitor. However, if an attacker supplies a filename argument of /etc/passwd�.txt, then a null byte attack is possible. Since Java strings can contain null bytes, the filename will pass the check filename.endsWith(".txt"). When the filename string is passed to an underlying operating system function to open the file, a problem will arise if that system function treats the string as null-terminated since anything after the null byte will be ignored. The operating system will end up opening the file /etc/passwd instead, and this file will then be displayed to the attacker.

ModSecurity and null bytes

ModSecurity contains two transformation functions to deal with null bytes in input: replaceNulls and removeNulls. The first function replaces null bytes with whitespace, while the second one removes null bytes completely. Since null bytes are very rarely needed for valid input, it is a good idea to include one of these transformation functions in the SecDefaultAction list:

SecDefaultAction "phase:2,deny,log,status:403,t:removeNulls"

Should a null byte ever be required in input, then the transformation function can be overridden using the t:-removeNulls syntax:

SecRule ARGS:data "pass,t:-removeNulls"

Null byte attacks are a perfect example of how fragile web applications can be since they are glued together using many different programming languages, and how subtle the attacks can be—who would have expected that the differences in string handling between Java and the operating system could lead to problems like this? It is something that could be easily missed even during a code review.

>> Continue Reading Blocking Common Attacks using ModSecurity 2.5: Part 3

[ 1 | 2 | 3 ]