| 1 |
<?PHP
|
| 2 |
// $Id: phpids.module,v 1.8.4.2.2.8 2008/04/21 20:17:00 swentel Exp $
|
| 3 |
|
| 4 |
/**
|
| 5 |
* @file
|
| 6 |
*
|
| 7 |
* phpids tries to identify attacks (xss, sql-injections ...) and
|
| 8 |
* uses an external package called PHPIDS (php-ids.org) to scan
|
| 9 |
* incoming and POST & GET variables. It's able to log, redirect
|
| 10 |
* or send out mails to warn the site administrator.
|
| 11 |
*/
|
| 12 |
|
| 13 |
/**
|
| 14 |
* Implementation of hook_menu().
|
| 15 |
*/
|
| 16 |
function phpids_menu() {
|
| 17 |
$items['admin/settings/logging/phpids'] = array(
|
| 18 |
'title' => 'PHPIDS Settings',
|
| 19 |
'description' => t('Configure PHPIDS settings and levels'),
|
| 20 |
'page callback' => 'drupal_get_form',
|
| 21 |
'page arguments' => array('phpids_admin_settings'),
|
| 22 |
'access arguments' => array('administer site configuration'),
|
| 23 |
'file' => 'phpids.admin.inc'
|
| 24 |
);
|
| 25 |
$items['phpidswarning'] = array(
|
| 26 |
'title' => 'PHPIDS warning',
|
| 27 |
'page callback' => 'phpids_warning',
|
| 28 |
'access callback' => TRUE,
|
| 29 |
'type' => MENU_CALLBACK
|
| 30 |
);
|
| 31 |
return $items;
|
| 32 |
}
|
| 33 |
|
| 34 |
/**
|
| 35 |
* Implementation of hook_init().
|
| 36 |
* $ignore : value depends which action will happen
|
| 37 |
* 0 = do nothing
|
| 38 |
* 1 = only log
|
| 39 |
* 2 = log & actions
|
| 40 |
*/
|
| 41 |
function phpids_init() {
|
| 42 |
|
| 43 |
if (file_exists(variable_get('phpids_path',realpath(dirname(__FILE__))). '/IDS/Config/Config.ini')) {
|
| 44 |
|
| 45 |
global $user, $base_root;
|
| 46 |
|
| 47 |
// default is logging
|
| 48 |
$ignore = 1;
|
| 49 |
// anonymous user
|
| 50 |
if ($user->uid == 0) {
|
| 51 |
$anon = variable_get('phpids_anonymous',2);
|
| 52 |
if ($anon == 2) $ignore = 2;
|
| 53 |
}
|
| 54 |
// authenticated user - always ignore user 1
|
| 55 |
if ($user->uid != 0) {
|
| 56 |
if ($user->uid == 1) $ignore = 0;
|
| 57 |
else {
|
| 58 |
$auth = variable_get('phpids_authenticated',2);
|
| 59 |
if ($auth == 1) $ignore = 0;
|
| 60 |
if ($auth == 3) $ignore = 2;
|
| 61 |
}
|
| 62 |
}
|
| 63 |
|
| 64 |
// start PHPIDS if ignore is not 0
|
| 65 |
if ($ignore != 0) {
|
| 66 |
|
| 67 |
$request_uri = $base_root . request_uri();
|
| 68 |
|
| 69 |
// set include path and required the needed files
|
| 70 |
$phpids_path = variable_get('phpids_path',realpath(dirname(__FILE__)));
|
| 71 |
$phpids_tmppath = variable_get('phpids_tmppath',ini_get('upload_tmp_dir'). 'phpids');
|
| 72 |
set_include_path(get_include_path(). PATH_SEPARATOR. $phpids_path);
|
| 73 |
require_once 'IDS/Init.php';
|
| 74 |
|
| 75 |
// instanciate the needed stuff
|
| 76 |
$request = array_merge_recursive($_GET, $_POST, $_COOKIE);
|
| 77 |
$init = IDS_Init::init($phpids_path.'/IDS/Config/Config.ini');
|
| 78 |
$init->config['General']['tmp_path'] = $phpids_tmppath;
|
| 79 |
$init->config['General']['filter_path'] = $phpids_path . '/IDS/default_filter.xml';
|
| 80 |
$init->config['Caching']['caching'] = 'file';
|
| 81 |
$init->config['Caching']['path'] = $phpids_tmppath. '/default_filter.cache';
|
| 82 |
|
| 83 |
$request = new IDS_Monitor($request, $init);
|
| 84 |
$report = $request->run();
|
| 85 |
|
| 86 |
// if report is not empty, always log
|
| 87 |
// depending on variables, take other actions if impact level matches settings criteria.
|
| 88 |
if (!$report->isEmpty()) {
|
| 89 |
// default action is log
|
| 90 |
$action = 0;
|
| 91 |
|
| 92 |
// level of severity
|
| 93 |
$severity = $report->getImpact();
|
| 94 |
|
| 95 |
// get variables to see if we need to take more action than only logging
|
| 96 |
$mail_level = variable_get('phpids_maillevel',9);
|
| 97 |
$mail_sent = variable_get('phpids_mail','');
|
| 98 |
$warn_level = variable_get('phpids_warnlevel',27);
|
| 99 |
if ($severity >= $mail_level && !empty($mail_sent) && $ignore == 2) $action = 1;
|
| 100 |
if ($severity >= $warn_level && $ignore == 2) $action = 2;
|
| 101 |
|
| 102 |
// create detailed report
|
| 103 |
$message = 'Total impact: ' . $severity . '<br />';
|
| 104 |
$message .= 'All tags: ' . join(", ", $report->getTags()) . '<br />';
|
| 105 |
// iterate through the result an get every event (IDS_Event)
|
| 106 |
foreach ($report as $event) {
|
| 107 |
$message .= '<hr>Variable: '.$event->getName().' | Value: ' . htmlspecialchars($event->getValue()) . '<br />';
|
| 108 |
$message .= 'Impact: '.$event->getImpact().' | Tags: ' . join(", ", $event->getTags()) . '<br />';
|
| 109 |
// iterator throught every filter
|
| 110 |
$message .= '<ul>';
|
| 111 |
foreach ($event as $filter) {
|
| 112 |
$message .= '<li>Rule: '. $filter->getRule() .'<br />';
|
| 113 |
$message .= 'Description: '. $filter->getDescription() .'<br />';
|
| 114 |
$message .= 'Tags: ' . join(", ", $filter->getTags()) . '</li>';
|
| 115 |
}
|
| 116 |
$message .= '</ul>';
|
| 117 |
}
|
| 118 |
|
| 119 |
// log the impact
|
| 120 |
//phpids_addevent($user,$message,$severity,$action,$request_uri);
|
| 121 |
watchdog('phpids',wordwrap($message,'100',' ',TRUE));
|
| 122 |
|
| 123 |
// send out mail if needed
|
| 124 |
if ($action == 1) {
|
| 125 |
drupal_mail('phpids','warning',$mail_sent,user_preferred_language($account),array('severity' => $severity));
|
| 126 |
watchdog('phpids',wordwrap('Send warning mail to '.$mail_sent,'100',' ',TRUE));
|
| 127 |
}
|
| 128 |
// Warning : redirect the user to a warning page so nothing can happen to the system
|
| 129 |
if ($action == 2) {
|
| 130 |
// load common.inc and path.inc if necessary
|
| 131 |
if (!function_exists('drupal_goto')) {
|
| 132 |
require_once './includes/common.inc';
|
| 133 |
require_once './includes/path.inc';
|
| 134 |
}
|
| 135 |
drupal_goto('phpidswarning');
|
| 136 |
}
|
| 137 |
}
|
| 138 |
}
|
| 139 |
}
|
| 140 |
}
|
| 141 |
|
| 142 |
/**
|
| 143 |
* Mail function
|
| 144 |
* @todo more info in mail
|
| 145 |
*/
|
| 146 |
function phpids_mail($key,&$message,$params) {
|
| 147 |
$language = $message['language'];
|
| 148 |
$message['subject'] = t('Notification from !site', $variables, $language->language);
|
| 149 |
$body = 'Check your logs to see a full detail of the report.';
|
| 150 |
$message['subject'] = t('PHPIDS detected an attack with impact !severity', array('!severity' => $params['severity']));
|
| 151 |
$message['body'] = t($body);
|
| 152 |
}
|
| 153 |
|
| 154 |
/**
|
| 155 |
* Warning page: display this page if the attack has reached warning level thus
|
| 156 |
* making the action of the (anonymous) user completely worthless.
|
| 157 |
*/
|
| 158 |
function phpids_warning() {
|
| 159 |
$output = t('We have detected malicious input and blocked your attempt.<br />If you keep experiencing problems but feel like you are doing nothing wrong, please contact the site administrator.');
|
| 160 |
return $output;
|
| 161 |
}
|