Zend Framework Intruder Detection System
LICENSE
See \library\zids\Plugin\Ids.php for license information.
VERSION
This is ZIDS Version 0.6.1
WHAT IS ZIDS
"Never ever trust user input!" - ZIDS helps you follow this golden rule of programming web applications. ZIDS uses PHP-IDS to analyze user inputs. The impact of a request is an integer value returned by PHP-IDS that indicates the severity of the attack. The higher the impact, the more likely the request was an attack!
ZIDS enables you to easily integrate PHP-IDS in your Zend Framework project. It allows you to define any number of levels of attack: e.g., 'unlikely', 'likely', 'very likely' and 'attack'.
For each level you may define:
- an interval that defines how the impact will be categorized, e.g. impact 0-10 will be considered as an 'unlikely' attack whereas an impact between 11 and 30 will be considered as a 'likely' attack.
- how to deal with an attack, e.g. ignore the attack, log the attack, send an email to the admin, redirect the user to a special side (controller/action), etc.
Furthermore, ZIDS enables you to aggregate all impacts in your session. This is useful as usually an attacker will start to analyze your website with a series of "small" attacks, i.e. attacks with an impact below 15. If you enable aggregation, four attacks with an impact of 5 will aggregate to an attack with an impact of 20 (5 + 5 + 5 + 5).
ZIDS is open source! In case you are using ZIDS, I would appreciate if you could send a short email to admin@web-punk.com.
Follow me on twitter to keep up to date.
INSTALLING ZIDS
- Download latest version of ZIDS from http://code.google.com/p/zids/downloads/list
- Download PHP-IDS (http://php-ids.org/). ZIDS has been tested with PHP-IDS 0.6.4
- Extract and copy the PHP-IDS code to your project's \library folder, e.g. \library\phpids-0.6.4
- Open \library\phpids-0.6.4\lib\IDS\Config\Config.ini.php! Set base_path to your IDS folder
and enable use_base_path, e.g.
base_path = "C:/myproject/library/phpids-0.6.4/lib/IDS/" use_base_path = true
- Extract and copy the ZIDS code to your project's \library folder, e.g. \library\zids\Plugin\Ids.php
- Adopt your application.ini file (see \zids\application\config\application.ini in the ZIDS package for a sample
configuration).
ZIDS also supports application.xml files. The only difference to using an INI file is that you have to use the<all>tag instead of an asterisk. Please, have a look at Specific and Global Options for more information. - Adopt your bootstrap.php file (see next chapter)
REGISTER THE ZIDS PLUGIN
Copy and paste the following source into your bootstrap.php file:
protected function _initZIDS() {
// Setup autoloader with namespace
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->registerNamespace('ZIDS');
// Ensure the front controller is initialized
$this->bootstrap('FrontController');
// Retrieve the front controller from the bootstrap registry
$front = $this->getResource('FrontController');
// Only enable zfdebug if options have been specified for it
if ($this->hasOption('zids'))
{
// Create ZIDS instance
$zids = new ZIDS_Plugin_Ids($this->getOption('zids'));
// create a logger (ADOPT THIS TO YOUR NEEDS!)
$logger = new Zend_Log ();
$filter = new Zend_Log_Filter_Priority(Zend_Log::ERR);
$writer = new Zend_Log_Writer_Stream ("../data/logs/log.txt");
$logger->addWriter ( $writer );
// register all plugins that you need
$zids->registerPlugin(new ZIDS_Plugin_ActionPlugin_Ignore());
$zids->registerPlugin(new ZIDS_Plugin_ActionPlugin_Email());
$zids->registerPlugin(new ZIDS_Plugin_ActionPlugin_Log($logger));
$zids->registerPlugin(new ZIDS_Plugin_ActionPlugin_Redirect());
// Register ZIDS with the front controller
$front->registerPlugin($zids);
}
}
This code will register all standard ZIDS plugins. In case you don't need all ZIDS plugin, simply
remove the corresponding registerPlugin lines.
IMPACT LEVELS
In order to deal with the impact of a request as returned by PHP_IDS you have to define so called impact levels.
Basically, an impact level corresponds to an interval. You define these intervals using the upto option.
For each impact level you have to define an action or a sequence of actions using the action option.
ZIDS will iterate through all defined impact levels (in the order as they are defined in application.ini). The first level
where the condition impact <= level.upto returns true is the level which will fire. 'fireing' in this context
means that all actions defined for this level will fire.
zids.level.unlikely.upto = 5 zids.level.unlikely.action.0 = ignore zids.level.likely.upto = 25 zids.level.likely.action.0 = log zids.level.attack.action.0 = log zids.level.attack.action.1 = email
In this example, we define a set of three impact levels: 'unlikely', 'likely' and 'attack'. The unlikely impact level will fire if an impact between 0 and 5 occurs. The likely impact level will fire, if an impact between 6 and 25 occurs. For all impacts greater than 25, the attack impact level will fire.
Furthermore we defined, that we are going to ignore all possible attacks categorized as 'unlikely'. For the 'likely' impact level we are going to write a log entry. If the 'attack' impact level fires we are going to write a log entry and send an email.
ZIDS PLUGINS
Specific and Global Options
Options for all ZIDS plugins may be set in two different ways: specific or general. In the following example, we define the loglevel option for the log plugin:zids.level.unlikely.option.log.loglevel = 6 zids.level.*.option.log.loglevel = 3The first definition is a specific definition as it specifically sets the loglevel for the impact level 'unlikely' to 6. The second definition is a general definition as uses the asterisk (*).
If you don't use an 'ini'-file for your application configuration but prefer xml, please use the <all> tag instead of the asterisk (*). Hence, your application.xml could look like this:
<zids>
...
<level>
<all>
<option>
<log>
<loglevel>3</loglevel>
</log>
</option>
</all>
</level>
...
</zids>
A general definition sets an option for all impact levels. A specific definition sets an option only for the specified level.
Specific options always override general options!This is especially useful, if you have multiple options and only want to change some of them for specific impact levels. The following example defines how to send emails in case of an attack. Furthermore, it defines that all emails will be sent to webadmin@yourhost.com except for the impact level 'verylikely'. In this case we directly want to send the email to the ceo@yourhost.com!
zids.level.*.option.email.smtp.auth = "login" zids.level.*.option.email.smtp.port = "465" zids.level.*.option.email.smtp.ssl = "SSL" zids.level.*.option.email.smtp.username = "username" zids.level.*.option.email.smtp.password = "password" zids.level.*.option.email.smtp.host = "mail.yourhost.com" zids.level.*.option.email.from = "zids@yourhost.com" zids.level.*.option.email.to = "webadmin@yourhost.com" zids.level.verylikely.option.email.to = "ceo@yourhost.com"
Standard Plugins
ZIDS comes with the following standard plugins.Ignore
ATTENTION! Do not mistake the Ignore plugin for the Ignore option (see "ZIDS configuration".
The ignore plugin will fire, after a possible attack has been detected, and - if you set the aggregate_in_session to true - after the impact
has been aggregated in the session. In contrast, ignoring a request using the ignore option means that PHP_IDS doesn't even start! Please, have a look at the "ZIDS configuration" chapter for more details.
Log
application.ini options (example & description)
zids.level.LEVELNAME.option.log.loglevel = 3 zids.level.LEVELNAME.option.log.items = ip, impact, tags, variables
loglevel defines the Zend_Log level to use, e.g. ALERT, EMERG, etc. The example given above logs all attacks that fall into the LEVELNAME impact level at Zend_Log level 3 (= Zend_Log::ERR)
items is a list of all items that should be written to the log. Currently, this plugin supports four items:
- ip = the IP of the attacker
- impact = the impact of the attack
- tags = the list of affected tags, e.g. sqli (for SQL Injections), xss, lfi, ...
- variables = the variable in the request that contained the potential attack
application.ini options (example & description)
zids.level.LEVELNAME.option.email.smtp.auth = "login" zids.level.LEVELNAME.option.email.smtp.port = "465" zids.level.LEVELNAME.option.email.smtp.ssl = "SSL" zids.level.LEVELNAME.option.email.smtp.username = "username" zids.level.LEVELNAME.option.email.smtp.password = "password" zids.level.LEVELNAME.option.email.smtp.host = "mail.yourhost.com" zids.level.LEVELNAME.option.email.from = "zids@yourhost.com" zids.level.LEVELNAME.option.email.to = "webadmin@yourhost.com" zids.level.LEVELNAME.option.email.subject = "ZIDS: attack detected" zids.level.LEVELNAME.option.email.items = ip, impact, tags, variables
auth, port, ssl, username, password, host, from, to and subject are options that will be simply passed to Zend_Mail. Have a look at the Zend_Mail manual in case of any questions regarding these parameters.
items is a list of all items that should be part of the email. Currently, this plugin supports four items:
- ip = the IP of the attacker
- impact = the impact of the attack
- tags = the list of affected tags, e.g. sqli (for SQL Injections), xss, lfi, ...
- variables = the variable in the request that contained the potential attack
Redirect
application.ini options (example & description)
zids.level.LEVELNAME.option.redirect.module = default zids.level.LEVELNAME.option.redirect.controller = index zids.level.LEVELNAME.option.redirect.action = attack
module, controller and action are used to define the target for the redirect plugin. Hence, in this example the user would be redirected to \index\attack in the default module.
Writing your own Plugin
You may define your own plugins by extending ZIDS_Plugin_ActionPlugin_Action. All you have to do is to implement the following two methods (see ZIDS_Plugin_ActionPlugin_Interface):/** * If an impact triggers this action, this method will be called. * * @param IDS_Report $ids_result The result of the PHP IDS scan * @param int $impact The impact. If zids.aggregate_in_session = true, * $impact consists of the aggregated impact * otherwise $impact is the non aggregated impact * @param string $levelname Name of the impact level that fires the action * @return void */ public function fires(IDS_Report $ids_result, $impact, $levelname); /** * Each plugin has to return a unique identifier / name * * @return string */ public function getIdentifier();
ZIDS CONFIGURATION (application.ini)
Beside the options defined for the ZIDS plugins, ZIDS uses the following options in the application.ini:application.ini options (example & description)
zids.aggregate_in_session = true zids.ignore.requests.module.0 = default zids.ignore.requests.controller.0 = index zids.ignore.requests.action.0 = sidebar zids.phpids.config = APPLICATION_PATH "/library/phpids-0.6.4/lib/IDS/Config/Config.ini.php"
aggregate_in_session if set to true, ZIDS will aggregate the impact of each attack in the session.
For instance, if the attacker submits a request with an impact of 5, and later on submits a
request with an impact of 10, the second request will be treated as a request with an impact
of 15 (=5 + 10)
ignore.request.module, ignore.request.controller, ignore.request.action. Use these options to define which requests should be completely ignored by
ZIDS!
Please note that you don't have to specify all three options: If all three options are set, ZIDS will ignore all requests where all three parameters match. If only the module and controller have been specified, both parameters have to match (action is being ignored). If only module has been specified, the module has to match (controller & action are being ignored).
phpids.config defines where to find the PHP_IDS configuration file.
QUESTIONS?
Got questions? Please, send an email to admin@web-punk.comCHANGE LOG
- Version 0.6.1
- Feature: ZIDS now also supports XML configuration files, i.e. use application.xml instead of application.ini (thanks to panosru for her/his contribution)
- Version 0.6.0
- Feature: define any number of levels you want
- Design: actions (log, email, redirect, etc.) are now plugins
- Design: enables you to define new action plugins
- Feature: all parameters for all action plugins may be specified for each level or globally
- Log Plugin: new option 'loglevel' which defines the level (e.g. 'ALERT', 'EMERG', ...) used when logging a message
- Feature: define which module/controller/action to ignore. If you specify only a module, all requests to this module will be ignored. If you specify a module + controller, all actions in this controller will be ignored