mirror of https://github.com/MISP/MISP
First version of the RPZ export
- still undocumented - very naive policy settings - limit per event / tags / date rangepull/567/head
parent
235262fcd3
commit
99f79ec318
|
@ -1792,6 +1792,41 @@ class AttributesController extends AppController {
|
|||
$this->set('attributes', $attributes);
|
||||
}
|
||||
|
||||
public function rpz($key='download', $tags=false, $eventId=false, $from=false, $to=false, $policy='DROP') {
|
||||
$simpleFalse = array('eventId', 'tags', 'from', 'to');
|
||||
foreach ($simpleFalse as $sF) {
|
||||
if (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false') ${$sF} = false;
|
||||
}
|
||||
if (!in_array($policy, array('NXDOMAIN', 'NODATA', 'DROP'))) $policy = 'DROP';
|
||||
if ($from) $from = $this->Attribute->Event->dateFieldCheck($from);
|
||||
if ($to) $from = $this->Attribute->Event->dateFieldCheck($to);
|
||||
if ($key != 'download') {
|
||||
// check if the key is valid -> search for users based on key
|
||||
$user = $this->checkAuthUser($key);
|
||||
if (!$user) {
|
||||
throw new UnauthorizedException('This authentication key is not authorized to be used for exports. Contact your administrator.');
|
||||
}
|
||||
} else {
|
||||
if (!$this->Auth->user('id')) {
|
||||
throw new UnauthorizedException('You have to be logged in to do that.');
|
||||
}
|
||||
}
|
||||
$values = $this->Attribute->rpz($this->_checkOrg(), $this->_isSiteAdmin(), $tags, $eventId, $from, $to);
|
||||
$this->response->type('txt'); // set the content type
|
||||
$file = '';
|
||||
if ($tags) $file = 'filtered.';
|
||||
if ($eventId) $file .= 'event-' . $eventId . '.';
|
||||
if ($from) $file .= 'from-' . $from . '.';
|
||||
if ($to) $file .= 'to-' . $to . '.';
|
||||
if ($file == '') $file = 'all';
|
||||
$this->header('Content-Disposition: download; filename="misp.rpz.' . $file . '.txt"');
|
||||
$this->layout = 'text/default';
|
||||
$this->loadModel('Whitelist');
|
||||
$values = $this->Whitelist->removeWhitelistedValuesFromArray($values);
|
||||
$this->set('values', $values);
|
||||
$this->set('policy', $policy);
|
||||
//debug($values);
|
||||
}
|
||||
|
||||
public function reportValidationIssuesAttributes() {
|
||||
// TODO improve performance of this function by eliminating the additional SQL query per attribute
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
class RPZExport {
|
||||
|
||||
public function explain($type, $policy) {
|
||||
$explanations = array(
|
||||
'ip' => '# The following list of IP addresses will ',
|
||||
'domain' => '# The following domain names and all of their sub-domains will ',
|
||||
'hostname' => '# The following hostnames will '
|
||||
);
|
||||
$policy_explanations = array(
|
||||
'NXDOMAIN' => 'return NXDOMAIN (name does not exist) irrespective of actual result received.',
|
||||
'NODATA' => 'returns NODATA (name exists but no answers returned) irrespective of actual result received.',
|
||||
'DROP' => 'timeout.',
|
||||
);
|
||||
return $explanations[$type] . $policy_explanations[$policy] . PHP_EOL . PHP_EOL;
|
||||
}
|
||||
|
||||
public function export($items, $policy) {
|
||||
switch ($policy) {
|
||||
case 'NXDOMAIN':
|
||||
$action = '.';
|
||||
break;
|
||||
case 'NODATA':
|
||||
$action = '*.';
|
||||
break;
|
||||
default:
|
||||
$policy = 'DROP';
|
||||
$action = 'rpz-drop.';
|
||||
}
|
||||
$result = '';
|
||||
|
||||
$result .= $this->explain('ip', $policy);
|
||||
foreach ($items['ip'] as $item) {
|
||||
$result .= $this->__convertIP($item, $action);
|
||||
}
|
||||
|
||||
$result .= $this->explain('domain', $policy);
|
||||
foreach ($items['domain'] as $item) {
|
||||
$result .= $this->__convertdomain($item, $action);
|
||||
}
|
||||
|
||||
$result .= $this->explain('hostname', $policy);
|
||||
foreach ($items['hostname'] as $item) {
|
||||
|
||||
$result .= $this->__converthostname($item, $action);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function __convertdomain($input, $action) {
|
||||
return $input . ' CNAME ' . $action . PHP_EOL . '*.' . $input . ' CNAME ' . $action . PHP_EOL;
|
||||
}
|
||||
|
||||
private function __converthostname($input, $action) {
|
||||
return $input . ' CNAME ' . $action . PHP_EOL;
|
||||
}
|
||||
|
||||
private function __convertip($input, $action) {
|
||||
$type = filter_var($input, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) ? 'ipv6' : 'ipv4';
|
||||
if ($type == 'ipv6') $prefix = '128';
|
||||
else $prefix = '32';
|
||||
if (strpos($input, '/')) {
|
||||
list($input, $prefix) = explode('/', $input);
|
||||
}
|
||||
return $prefix . '.' . $this->{'__' . $type}($input) . ' CNAME ' . $action . PHP_EOL;
|
||||
}
|
||||
|
||||
private function __ipv6($input) {
|
||||
return implode('.', array_reverse(preg_split('/:/', str_replace('::', ':zz:', $input), NULL, PREG_SPLIT_NO_EMPTY)));
|
||||
}
|
||||
|
||||
private function __ipv4($input) {
|
||||
return implode('.', array_reverse(explode('.', $input)));
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1314,6 +1314,55 @@ class Attribute extends AppModel {
|
|||
return $attributes;
|
||||
}
|
||||
|
||||
public function rpz($org, $isSiteAdmin, $tags = false, $eventId = false, $from = false, $to = false) {
|
||||
// we can group hostname and domain as well as ip-src and ip-dst in this case
|
||||
$conditions['AND'] = array('Attribute.to_ids' => 1, 'Event.published' => 1);
|
||||
$typesToFetch = array('ip' => array('ip-src', 'ip-dst'), 'hostname' => array('hostname'), 'domain' => array('domain'));
|
||||
if ($from) $conditions['AND']['Event.date >='] = $from;
|
||||
if ($to) $conditions['AND']['Event.date <='] = $to;
|
||||
if (!$isSiteAdmin) {
|
||||
$temp = array();
|
||||
$distribution = array();
|
||||
array_push($temp, array('Attribute.distribution >' => 0));
|
||||
array_push($temp, array('(SELECT events.org FROM events WHERE events.id = Attribute.event_id) LIKE' => $org));
|
||||
$conditions['OR'] = $temp;
|
||||
}
|
||||
if ($eventId !== false) {
|
||||
$conditions['AND'][] = array('Event.id' => $eventId);
|
||||
} elseif ($tags !== false) {
|
||||
// If we sent any tags along, load the associated tag names for each attribute
|
||||
$tag = ClassRegistry::init('Tag');
|
||||
$args = $this->dissectArgs($tags);
|
||||
$tagArray = $tag->fetchEventTagIds($args[0], $args[1]);
|
||||
$temp = array();
|
||||
foreach ($tagArray[0] as $accepted) {
|
||||
$temp['OR'][] = array('Event.id' => $accepted);
|
||||
}
|
||||
$conditions['AND'][] = $temp;
|
||||
$temp = array();
|
||||
foreach ($tagArray[1] as $rejected) {
|
||||
$temp['AND'][] = array('Event.id !=' => $rejected);
|
||||
}
|
||||
$conditions['AND'][] = $temp;
|
||||
}
|
||||
|
||||
foreach ($typesToFetch as $k => $v) {
|
||||
$params = array(
|
||||
'conditions' => array('AND' =>
|
||||
$conditions,
|
||||
array('type' => $v),
|
||||
),
|
||||
'fields' => array('Attribute.value'), //array of field names
|
||||
'order' => array('Attribute.value'), //string or array defining order
|
||||
'group' => array('Attribute.value'), //fields to GROUP BY
|
||||
);
|
||||
$temp = $this->find('all', $params);
|
||||
foreach ($temp as $value) $values[$k][] = $value['Attribute']['value'];
|
||||
unset($temp);
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
|
||||
public function generateCorrelation() {
|
||||
$this->Correlation = ClassRegistry::init('Correlation');
|
||||
$this->Correlation->deleteAll(array('id !=' => ''), false);
|
||||
|
|
|
@ -126,4 +126,20 @@ class Whitelist extends AppModel {
|
|||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
// A simplified whitelist removal, for when we just want to throw values against the list instead of attributes / events
|
||||
public function removeWhitelistedValuesFromArray($data) {
|
||||
$whitelists = $this->getBlockedValues();
|
||||
// if we don't have any whitelist items in the db, don't loop through each attribute
|
||||
if (!empty($whitelists)) {
|
||||
foreach ($data as $k => $value) {
|
||||
foreach ($whitelists as $wlitem) {
|
||||
if (preg_match($wlitem, $value)) {
|
||||
unset($data[$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
App::uses('RPZExport', 'Export');
|
||||
$rpzExport = new RPZExport();
|
||||
echo ($rpzExport->export($values, $policy));
|
Loading…
Reference in New Issue