Whitelist.

An admin can maintain a whitelist of host, domain name and ip numbers.
In the NIDS export lines containing whitelist items are commented out.
pull/61/head
noud 2012-08-06 10:42:46 +02:00
parent 2dea0e347d
commit b24acfb4a5
9 changed files with 370 additions and 17 deletions

88
app/Controller/Component/NidsExportComponent.php Normal file → Executable file
View File

@ -16,6 +16,7 @@ class NidsExportComponent extends Component {
}
function suricataRules($items, $start_sid) {
$this->whitelist = $this->populateWhitelist();
$this->explain();
@ -41,7 +42,7 @@ class NidsExportComponent extends Component {
# proto src_ip src_port direction dst_ip dst_port msg rule_content tag sid rev
$rule_format_msg = 'msg: "CyDefSIG e'.$item['Event']['id'].' %s"';
$rule_format_reference = 'reference:url,'.Configure::read('CyDefSIG.baseurl').'/events/view/'.$item['Event']['id'];
$rule_format = 'alert %s %s %s %s %s %s ('.$rule_format_msg.'; %s %s classtype:'.$classtype.'; sid:%d; rev:%d; priority:'.$priority.'; '.$rule_format_reference.';) ';
$rule_format = '%salert %s %s %s %s %s %s ('.$rule_format_msg.'; %s %s classtype:'.$classtype.'; sid:%d; rev:%d; priority:'.$priority.'; '.$rule_format_reference.';) ';
$sid = $start_sid+($item['Attribute']['id']*10); // leave 9 possible rules per attribute type
$attribute = &$item['Attribute'];
@ -99,7 +100,9 @@ class NidsExportComponent extends Component {
}
function ipDstRule($rule_format, $attribute, &$sid) {
$overruled = in_array($attribute['value'], $this->whitelist);
$this->rules[] = sprintf($rule_format,
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
'ip', // proto
'$HOME_NET', // src_ip
'any', // src_port
@ -116,7 +119,9 @@ class NidsExportComponent extends Component {
}
function ipSrcRule($rule_format, $attribute, &$sid) {
$this->rules[] = sprintf($rule_format,
$overruled = in_array($attribute['value'], $this->whitelist);
$this->rules[] = sprintf($rule_format,
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
'ip', // proto
$attribute['value'], // src_ip
'any', // src_port
@ -132,8 +137,9 @@ class NidsExportComponent extends Component {
}
function emailSrcRule($rule_format, $attribute, &$sid) {
$content = 'flow:established,to_server; content:"MAIL FROM|3a|"; nocase; content:"'.$attribute['value'].'"; nocase;';
$content = 'flow:established,to_server; content:"MAIL FROM|3a|"; nocase; content:"'.$attribute['value'].'"; nocase;';
$this->rules[] = sprintf($rule_format,
(false) ? '#OVERRULED BY WHITELIST# ' : '',
'tcp', // proto
'$EXTERNAL_NET', // src_ip
'any', // src_port
@ -149,8 +155,9 @@ class NidsExportComponent extends Component {
}
function emailDstRule($rule_format, $attribute, &$sid) {
$content = 'flow:established,to_server; content:"RCPT TO|3a|"; nocase; content:"'.$attribute['value'].'"; nocase;';
$this->rules[] = sprintf($rule_format,
$content = 'flow:established,to_server; content:"RCPT TO|3a|"; nocase; content:"'.$attribute['value'].'"; nocase;';
$this->rules[] = sprintf($rule_format,
(false) ? '#OVERRULED BY WHITELIST# ' : '',
'tcp', // proto
'$EXTERNAL_NET', // src_ip
'any', // src_port
@ -166,9 +173,10 @@ class NidsExportComponent extends Component {
}
function emailSubjectRule($rule_format, $attribute, &$sid) {
// LATER nids - email-subject rule might not match because of line-wrapping
// LATER nids - email-subject rule might not match because of line-wrapping
$content = 'flow:established,to_server; content:"Subject|3a|"; nocase; content:"'.$attribute['value'].'"; nocase;';
$this->rules[] = sprintf($rule_format,
(false) ? '#OVERRULED BY WHITELIST# ' : '',
'tcp', // proto
'$EXTERNAL_NET', // src_ip
'any', // src_port
@ -184,9 +192,10 @@ class NidsExportComponent extends Component {
}
function emailAttachmentRule($rule_format, $attribute, &$sid) {
// LATER nids - email-attachment rule might not match because of line-wrapping
// LATER nids - email-attachment rule might not match because of line-wrapping
$content = 'flow:established,to_server; content:"Content-Disposition: attachment|3b| filename=|22|"; content:"'.$attribute['value'].'|22|";';
$this->rules[] = sprintf($rule_format,
(false) ? '#OVERRULED BY WHITELIST# ' : '',
'tcp', // proto
'$EXTERNAL_NET', // src_ip
'any', // src_port
@ -202,8 +211,10 @@ class NidsExportComponent extends Component {
}
function hostnameRule($rule_format, $attribute, &$sid) {
$content = 'content:"'.$this->dnsNameToRawFormat($attribute['value'], 'hostname').'"; nocase;';
$this->rules[] = sprintf($rule_format,
$overruled = $this->checkNames($attribute['value']);
$content = 'content:"'.$this->dnsNameToRawFormat($attribute['value'], 'hostname').'"; nocase;';
$this->rules[] = sprintf($rule_format,
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
'udp', // proto
'any', // src_ip
'any', // src_port
@ -217,7 +228,8 @@ class NidsExportComponent extends Component {
1 // rev
);
$sid++;
$this->rules[] = sprintf($rule_format,
$this->rules[] = sprintf($rule_format,
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
'tcp', // proto
'any', // src_ip
'any', // src_port
@ -234,7 +246,8 @@ class NidsExportComponent extends Component {
// also do http requests
// warning: only suricata compatible
$content = 'flow:to_server,established; content: "Host: '.$attribute['value'].'"; nocase; http_header; ';
$this->rules[] = sprintf($rule_format,
$this->rules[] = sprintf($rule_format,
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
'http', // proto
'$HOME_NET', // src_ip
'any', // src_port
@ -249,8 +262,10 @@ class NidsExportComponent extends Component {
);
}
function domainRule($rule_format, $attribute, &$sid) {
$content = 'content:"'.$this->dnsNameToRawFormat($attribute['value']).'"; nocase;';
$overruled = $this->checkNames($attribute['value']);
$content = 'content:"'.$this->dnsNameToRawFormat($attribute['value']).'"; nocase;';
$this->rules[] = sprintf($rule_format,
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
'udp', // proto
'any', // src_ip
'any', // src_port
@ -265,6 +280,7 @@ class NidsExportComponent extends Component {
);
$sid++;
$this->rules[] = sprintf($rule_format,
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
'tcp', // proto
'any', // src_ip
'any', // src_port
@ -281,7 +297,8 @@ class NidsExportComponent extends Component {
// also do http requests,
// warning: only suricata compatible
$content = 'flow:to_server,established; content: "Host:"; nocase; http_header; content:"'.$attribute['value'].'"; nocase; http_header; ';
$this->rules[] = sprintf($rule_format,
$this->rules[] = sprintf($rule_format,
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
'http', // proto
'$HOME_NET', // src_ip
'any', // src_port
@ -297,9 +314,12 @@ class NidsExportComponent extends Component {
}
function urlRule($rule_format, $attribute, &$sid) {
// warning: only suricata compatible
$hostpart = parse_url($attribute['value'], PHP_URL_HOST);
$overruled = $this->checkNames($hostpart);
// warning: only suricata compatible
$content = 'flow:to_server,established; content:"'.$attribute['value'].'"; nocase; http_uri;';
$this->rules[] = sprintf($rule_format,
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
'http', // proto
'$HOME_NET', // src_ip
'any', // src_port
@ -421,7 +441,41 @@ class NidsExportComponent extends Component {
return $rawName;
}
public $whitelist = array();
function populateWhitelist() {
$whitelistCheck = array();
$this->Whitelist = ClassRegistry::init('Whitelist');
$whitelist = $this->Whitelist->find('all', array('recursive' => 0,'fields' => 'name'));
// loop through whitelist table,
foreach ($whitelist as $whitelistItem) {
$ipl = array();
$ipl = $this->nametoipl($whitelistItem['Whitelist']['name']);
$whitelistCheck = array_merge($whitelistCheck,$ipl);
if (count($ipl) > 0 && $whitelistItem != $ipl[0]) {
$dummyArray = array();
$dummyArray[] = $whitelistItem['Whitelist']['name'];
$whitelistCheck = array_merge($whitelistCheck,$dummyArray);
}
}
return $whitelistCheck;
}
function nametoipl($name) {
if (!$ips = gethostbynamel($name)) $ips = array();
return $ips;
}
function checkNames($name) {
$ipl = $this->nametoipl($name);
$ipl[] = $name;
$overruled = false;
foreach ($ipl as $ip) {
$overruled = in_array($ip, $this->whitelist);
if ($overruled) break;
}
return $overruled;
}
}

View File

@ -0,0 +1,96 @@
<?php
App::uses('AppController', 'Controller');
/**
* Whitelists Controller
*
* @property Whitelist $Whitelist
*/
class WhitelistsController extends AppController {
/**
* index method
*
* @return void
*/
public function admin_index() {
$this->Whitelist->recursive = 0;
$this->set('whitelists', $this->paginate());
}
/**
* view method
*
* @param string $id
* @return void
*/
public function admin_view($id = null) {
$this->Whitelist->id = $id;
if (!$this->Whitelist->exists()) {
throw new NotFoundException(__('Invalid whitelist'));
}
$this->set('whitelist', $this->Whitelist->read(null, $id));
}
/**
* add method
*
* @return void
*/
public function admin_add() {
if ($this->request->is('post')) {
$this->Whitelist->create();
if ($this->Whitelist->save($this->request->data)) {
$this->Session->setFlash(__('The whitelist has been saved'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The whitelist could not be saved. Please, try again.'));
}
}
}
/**
* edit method
*
* @param string $id
* @return void
*/
public function admin_edit($id = null) {
$this->Whitelist->id = $id;
if (!$this->Whitelist->exists()) {
throw new NotFoundException(__('Invalid whitelist'));
}
if ($this->request->is('post') || $this->request->is('put')) {
if ($this->Whitelist->save($this->request->data)) {
$this->Session->setFlash(__('The whitelist has been saved'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The whitelist could not be saved. Please, try again.'));
}
} else {
$this->request->data = $this->Whitelist->read(null, $id);
}
}
/**
* delete method
*
* @param string $id
* @return void
*/
public function admin_delete($id = null) {
if (!$this->request->is('post')) {
throw new MethodNotAllowedException();
}
$this->Whitelist->id = $id;
if (!$this->Whitelist->exists()) {
throw new NotFoundException(__('Invalid whitelist'));
}
if ($this->Whitelist->delete()) {
$this->Session->setFlash(__('Whitelist deleted'));
$this->redirect(array('action' => 'index'));
}
$this->Session->setFlash(__('Whitelist was not deleted'));
$this->redirect(array('action' => 'index'));
}
}

6
app/MYSQL.whitelist.sql Executable file
View File

@ -0,0 +1,6 @@
DROP TABLE IF EXISTS `whitelist`;
CREATE TABLE `whitelist` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(254) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=118 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

93
app/Model/Whitelist.php Normal file
View File

@ -0,0 +1,93 @@
<?php
App::uses('AppModel', 'Model');
/**
* Whitelist Model
*
*/
class Whitelist extends AppModel {
/**
* Use table
*
* @var mixed False or table name
*/
public $useTable = 'whitelist';
/**
* Display field
*
* @var string
*/
public $displayField = 'name';
/**
* Validation rules
*
* @var array
*/
public $validate = array(
'name' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'Please fill in this field',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
'userdefined' => array(
'rule' => array('validateValue'),
'message' => 'Name not in the right format. Please double check the name.',
//'allowEmpty' => false,
//'required' => true,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
'unique' => array(
'rule' => 'isUnique', //array('valueIsUnique'),
'message' => 'A similar name already exists.',
//'allowEmpty' => false,
//'required' => true,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
);
function validateValue ($fields) {
$value = $fields['name'];
// check data validation
// host domainname maybe..
if(preg_match("#^[A-Z0-9.-]+\.[A-Z]{2,4}$#i", $value))
return true;
// IP maybe..
$parts = explode("/", $value);
// [0] = the ip
// [1] = the network address
if (count($parts) <= 2 ) {
// ipv4 and ipv6 matching
if (filter_var($parts[0],FILTER_VALIDATE_IP)) {
// ip is validated, now check if we have a valid network mask
if (empty($parts[1]))
return true;
else if(is_numeric($parts[1]) && $parts[1] < 129)
return true;
}
}
return false;
}
function valueIsUnique ($fields) {
$value = $fields['name'];
$whitelist = $this->find('all', array('recursive' => 0,'fields' => 'name'));
foreach ($whitelist as $whitelistItem) {
if ($value == $whitelistItem['Whitelist']['name']) {
return false;
}
}
return true;
}
}

View File

@ -21,6 +21,8 @@
<?php if($isAdmin): ?>
<li>&nbsp;</li>
<h3><?php echo __('Administration'); ?></h3>
<li><?php echo $this->Html->link(__('Whitelist', true), array('controller' => 'whitelists', 'action' => 'index', 'admin' => true)); ?> </li>
<li>&nbsp;</li>
<li><?php echo $this->Html->link(__('New User', true), array('controller' => 'users', 'action' => 'add', 'admin' => true)); ?> </li>
<li><?php echo $this->Html->link(__('List Users', true), array('controller' => 'users', 'action' => 'index', 'admin' => true)); ?> </li>
<?php endif; ?>

View File

@ -0,0 +1,17 @@
<div class="whitelists form">
<?php echo $this->Form->create('Whitelist');?>
<fieldset>
<legend><?php echo __('Add Whitelist'); ?></legend>
<?php
echo $this->Form->input('name');
?>
</fieldset>
<?php echo $this->Form->end(__('Submit'));?>
</div>
<div class="actions">
<h3><?php echo __('Actions'); ?></h3>
<ul>
<li><?php echo $this->Html->link(__('List Whitelists'), array('admin' => true, 'action' => 'index'));?></li>
</ul>
</div>

View File

@ -0,0 +1,19 @@
<div class="whitelists form">
<?php echo $this->Form->create('Whitelist');?>
<fieldset>
<legend><?php echo __('Edit Whitelist'); ?></legend>
<?php
echo $this->Form->input('id');
echo $this->Form->input('name');
?>
</fieldset>
<?php echo $this->Form->end(__('Submit'));?>
</div>
<div class="actions">
<h3><?php echo __('Actions'); ?></h3>
<ul>
<li><?php echo $this->Form->postLink(__('Delete'), array('admin' => true, 'action' => 'delete', $this->Form->value('Whitelist.id')), null, __('Are you sure you want to delete # %s?', $this->Form->value('Whitelist.id'))); ?></li>
<li><?php echo $this->Html->link(__('List Whitelists'), array('admin' => true, 'action' => 'index'));?></li>
</ul>
</div>

View File

@ -0,0 +1,42 @@
<div class="whitelists index">
<h2><?php echo __('Whitelists');?></h2>
<table cellpadding="0" cellspacing="0">
<tr>
<th><?php echo $this->Paginator->sort('id');?></th>
<th><?php echo $this->Paginator->sort('name');?></th>
<th class="actions"><?php echo __('Actions');?></th>
</tr>
<?php
foreach ($whitelists as $whitelist): ?>
<tr>
<td><?php echo h($whitelist['Whitelist']['id']); ?>&nbsp;</td>
<td><?php echo h($whitelist['Whitelist']['name']); ?>&nbsp;</td>
<td class="actions">
<?php echo $this->Html->link(__('View'), array('admin' => true, 'action' => 'view', $whitelist['Whitelist']['id'])); ?>
<?php echo $this->Html->link(__('Edit'), array('admin' => true, 'action' => 'edit', $whitelist['Whitelist']['id'])); ?>
<?php echo $this->Form->postLink(__('Delete'), array('admin' => true, 'action' => 'delete', $whitelist['Whitelist']['id']), null, __('Are you sure you want to delete # %s?', $whitelist['Whitelist']['id'])); ?>
</td>
</tr>
<?php endforeach; ?>
</table>
<p>
<?php
echo $this->Paginator->counter(array(
'format' => __('Page {:page} of {:pages}, showing {:current} records out of {:count} total, starting on record {:start}, ending on {:end}')
));
?> </p>
<div class="paging">
<?php
echo $this->Paginator->prev('< ' . __('previous'), array(), null, array('class' => 'prev disabled'));
echo $this->Paginator->numbers(array('separator' => ''));
echo $this->Paginator->next(__('next') . ' >', array(), null, array('class' => 'next disabled'));
?>
</div>
</div>
<div class="actions">
<h3><?php echo __('Actions'); ?></h3>
<ul>
<li><?php echo $this->Html->link(__('New Whitelist'), array('admin' => true, 'action' => 'add')); ?></li>
</ul>
</div>

View File

@ -0,0 +1,24 @@
<div class="whitelists view">
<h2><?php echo __('Whitelist');?></h2>
<dl>
<dt><?php echo __('Id'); ?></dt>
<dd>
<?php echo h($whitelist['Whitelist']['id']); ?>
&nbsp;
</dd>
<dt><?php echo __('Name'); ?></dt>
<dd>
<?php echo h($whitelist['Whitelist']['name']); ?>
&nbsp;
</dd>
</dl>
</div>
<div class="actions">
<h3><?php echo __('Actions'); ?></h3>
<ul>
<li><?php echo $this->Html->link(__('Edit Whitelist'), array('admin' => true, 'action' => 'edit', $whitelist['Whitelist']['id'])); ?> </li>
<li><?php echo $this->Form->postLink(__('Delete Whitelist'), array('admin' => true, 'action' => 'delete', $whitelist['Whitelist']['id']), null, __('Are you sure you want to delete # %s?', $whitelist['Whitelist']['id'])); ?> </li>
<li><?php echo $this->Html->link(__('List Whitelists'), array('admin' => true, 'action' => 'index')); ?> </li>
<li><?php echo $this->Html->link(__('New Whitelist'), array('admin' => true, 'action' => 'add')); ?> </li>
</ul>
</div>