mirror of https://github.com/MISP/MISP
Merge branch 'develop' into feature/XML_and_UI
commit
0cb7653d41
|
@ -295,6 +295,8 @@ class AppController extends Controller {
|
|||
$this->loadModel('Role');
|
||||
$this->Role->recursive = -1;
|
||||
$role = $this->Role->findById($user['User']['role_id']);
|
||||
$user['User']['siteAdmin'] = false;
|
||||
if ($role['Role']['perm_admin'] && $user['User']['org'] == 'ADMIN') $user['User']['siteAdmin'] = true;
|
||||
if ($role['Role']['perm_auth']) {
|
||||
return $user;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,10 @@ class AttributesController extends AppController {
|
|||
|
||||
public function beforeFilter() {
|
||||
parent::beforeFilter();
|
||||
|
||||
$this->Auth->allow('restSearch');
|
||||
$this->Auth->allow('returnAttributes');
|
||||
$this->Auth->allow('downloadAttachment');
|
||||
|
||||
// permit reuse of CSRF tokens on the search page.
|
||||
if ('search' == $this->request->params['action']) {
|
||||
|
@ -246,19 +250,18 @@ class AttributesController extends AppController {
|
|||
if (!$this->Attribute->exists()) {
|
||||
throw new NotFoundException(__('Invalid attribute'));
|
||||
}
|
||||
|
||||
$this->Attribute->read();
|
||||
if (!$this->_isSiteAdmin() &&
|
||||
$this->Auth->user('org') !=
|
||||
$this->Attribute->data['Event']['org'] &&
|
||||
($this->Attribute->data['Event']['distribution'] == 0 ||
|
||||
$this->Attribute->data['Attribute']['distribution'] == 0
|
||||
)) {
|
||||
throw new UnauthorizedException('You do not have the permission to view this event.');
|
||||
$this->Auth->user('org') !=
|
||||
$this->Attribute->data['Event']['org'] &&
|
||||
($this->Attribute->data['Event']['distribution'] == 0 ||
|
||||
$this->Attribute->data['Attribute']['distribution'] == 0
|
||||
)) {
|
||||
throw new UnauthorizedException('You do not have the permission to view this event.');
|
||||
}
|
||||
$this->__downloadAttachment($this->Attribute->data['Attribute']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function __downloadAttachment($attribute) {
|
||||
$path = "files" . DS . $attribute['event_id'] . DS;
|
||||
$file = $attribute['id'];
|
||||
|
@ -1069,4 +1072,172 @@ class AttributesController extends AppController {
|
|||
|
||||
$this->set('fails', $this->Attribute->checkComposites());
|
||||
}
|
||||
|
||||
// Use the rest interface to search for attributes. Usage:
|
||||
// MISP-base-url/attributes/restSearch/[api-key]/[value]/[type]/[category]/[orgc]
|
||||
// value, type, category, orgc are optional
|
||||
// the last 4 fields accept the following operators:
|
||||
// && - you can use && between two search values to put a logical OR between them. for value, 1.1.1.1&&2.2.2.2 would find attributes with the value being either of the two.
|
||||
// ! - you can negate a search term. For example: google.com&&!mail would search for all attributes with value google.com but not ones that include mail. www.google.com would get returned, mail.google.com wouldn't.
|
||||
public function restSearch($key, $value=null, $type=null, $category=null, $org=null) {
|
||||
$user = $this->checkAuthUser($key);
|
||||
if (!$user) {
|
||||
throw new UnauthorizedException('This authentication key is not authorized to be used for exports. Contact your administrator.');
|
||||
}
|
||||
$this->response->type('xml'); // set the content type
|
||||
$this->layout = 'xml/default';
|
||||
$this->header('Content-Disposition: download; filename="misp.search.attribute.results.xml"');
|
||||
$conditions['AND'] = array();
|
||||
$subcondition = array();
|
||||
$this->loadModel('Attribute');
|
||||
// add the values as specified in the 2nd parameter to the conditions
|
||||
$values = explode('&&', $value);
|
||||
$parameters = array('value', 'type', 'category', 'org');
|
||||
|
||||
foreach ($parameters as $k => $param) {
|
||||
if (isset(${$parameters[$k]})) {
|
||||
$elements = explode('&&', ${$parameters[$k]});
|
||||
foreach($elements as $v) {
|
||||
if (substr($v, 0, 1) == '!') {
|
||||
$subcondition['AND'][] = array('Attribute.' . $parameters[$k] . ' NOT LIKE' => '%'.substr($v, 1).'%');
|
||||
} else {
|
||||
$subcondition['OR'][] = array('Attribute.' . $parameters[$k] . ' LIKE' => '%'.$v.'%');
|
||||
}
|
||||
}
|
||||
array_push ($conditions['AND'], $subcondition);
|
||||
$subcondition = array();
|
||||
}
|
||||
}
|
||||
|
||||
// If we are looking for an attribute, we want to retrieve some extra data about the event to be able to check for the permissions.
|
||||
|
||||
if (!$user['User']['siteAdmin']) {
|
||||
$temp = array();
|
||||
$temp['AND'] = array('Event.distribution >' => 0, 'Attribute.distribution >' => 0);
|
||||
$subcondition['OR'][] = $temp;
|
||||
$subcondition['OR'][] = array('Event.org' => $user['User']['org']);
|
||||
array_push($conditions['AND'], $subcondition);
|
||||
}
|
||||
|
||||
// change the fields here for the attribute export!!!! Don't forget to check for the permissions, since you are not going through fetchevent. Maybe create fetchattribute?
|
||||
|
||||
$params = array(
|
||||
'conditions' => $conditions,
|
||||
'fields' => array('Attribute.*', 'Event.org', 'Event.distribution'),
|
||||
'contain' => 'Event'
|
||||
);
|
||||
|
||||
$results = $this->Attribute->find('all', $params);
|
||||
$this->loadModel('Whitelist');
|
||||
$results = $this->Whitelist->removeWhitelistedFromArray($results, false);
|
||||
if (empty($results)) throw new NotFoundException('No matches.');
|
||||
$this->set('results', $results);
|
||||
}
|
||||
|
||||
// returns an XML with attributes that belong to an event. The type of attributes to be returned can be restricted by type using the 3rd parameter.
|
||||
// Similar to the restSearch, this parameter can be chained with '&&' and negations are accepted too. For example filename&&!filename|md5 would return all filenames that don't have an md5
|
||||
// The usage of returnAttributes is the following: [MISP-url]/attributes/returnAttributes/<API-key>/<type>/<signature flag>
|
||||
// The signature flag is off by default, enabling it will only return attribugtes that have the to_ids flag set to true.
|
||||
public function returnAttributes($key, $id, $type = null, $sigOnly = false) {
|
||||
$user = $this->checkAuthUser($key);
|
||||
// if the user is authorised to use the api key then user will be populated with the user's account
|
||||
// in addition we also set a flag indicating whether the user is a site admin or not.
|
||||
if (!$user) {
|
||||
throw new UnauthorizedException('This authentication key is not authorized to be used for exports. Contact your administrator.');
|
||||
}
|
||||
$this->loadModel('Event');
|
||||
$this->Event->read(null, $id);
|
||||
$myEventOrAdmin = false;
|
||||
if ($user['User']['siteAdmin'] || $this->Event->data['Event']['org'] == $user['User']['org']) {
|
||||
$myEventOrAdmin = true;
|
||||
}
|
||||
|
||||
if (!$myEventOrAdmin) {
|
||||
if ($this->Event->data['Event']['distribution'] == 0) {
|
||||
throw new UnauthorizedException('You don\'t have access to that event.');
|
||||
}
|
||||
}
|
||||
$this->response->type('xml'); // set the content type
|
||||
$this->layout = 'xml/default';
|
||||
$this->header('Content-Disposition: download; filename="misp.search.attribute.results.xml"');
|
||||
// check if user can see the event!
|
||||
$conditions['AND'] = array();
|
||||
$include = array();
|
||||
$exclude = array();
|
||||
$attributes = array();
|
||||
// If there is a type set, create the include and exclude arrays from it
|
||||
if (isset($type)) {
|
||||
$elements = explode('&&', $type);
|
||||
foreach($elements as $v) {
|
||||
if (substr($v, 0, 1) == '!') {
|
||||
$exclude[] = substr($v, 1);
|
||||
} else {
|
||||
$include[] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check each attribute
|
||||
foreach($this->Event->data['Attribute'] as $k => $attribute) {
|
||||
$contained = false;
|
||||
// If the include list is empty, then we just then the first check should always set contained to true (basically we chose type = all - exclusions, or simply all)
|
||||
if (empty($include)) {
|
||||
$contained = true;
|
||||
} else {
|
||||
// If we have elements in $include we should check if the attribute's type should be included
|
||||
foreach ($include as $inc) {
|
||||
if (strpos($attribute['type'], $inc) !== false) {
|
||||
$contained = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If we have either everything included or the attribute passed the include check, we should check if there is a reason to exclude the attribute
|
||||
// For example, filename may be included, but md5 may be excluded, meaning that filename|md5 should be removed
|
||||
if ($contained) {
|
||||
foreach ($exclude as $exc) {
|
||||
if (strpos($attribute['type'], $exc) !== false) {
|
||||
$contained = false;
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If we still didn't throw the attribute away, let's check if the user requesting the attributes is of the owning organisation of the event
|
||||
// and if not, whether the distribution of the attribute allows the user to see it
|
||||
if ($contained && !$myEventOrAdmin && $attribute['distribution'] == 0) {
|
||||
$contained = false;
|
||||
}
|
||||
|
||||
// If we have set the sigOnly parameter and the attribute has to_ids set to false, discard it!
|
||||
if ($contained && $sigOnly === 'true' && !$attribute['to_ids']) {
|
||||
$contained = false;
|
||||
}
|
||||
|
||||
// If after all of this $contained is still true, let's add the attribute to the array
|
||||
if ($contained) $attributes[] = $attribute;
|
||||
}
|
||||
if (empty($attributes)) throw new NotFoundException('No matches.');
|
||||
$this->set('results', $attributes);
|
||||
}
|
||||
|
||||
public function downloadAttachment($key, $id) {
|
||||
$user = $this->checkAuthUser($key);
|
||||
// if the user is authorised to use the api key then user will be populated with the user's account
|
||||
// in addition we also set a flag indicating whether the user is a site admin or not.
|
||||
if (!$user) {
|
||||
throw new UnauthorizedException('This authentication key is not authorized to be used for exports. Contact your administrator.');
|
||||
}
|
||||
$this->Attribute->id = $id;
|
||||
if(!$this->Attribute->exists()) {
|
||||
throw new NotFoundException('Invalid attribute or no authorisation to view it.');
|
||||
}
|
||||
$this->Attribute->read(null, $id);
|
||||
if (!$user['User']['siteAdmin'] &&
|
||||
$user['User']['org'] != $this->Attribute->data['Event']['org'] &&
|
||||
($this->Attribute->data['Event']['distribution'] == 0 ||
|
||||
$this->Attribute->data['Attribute']['distribution'] == 0
|
||||
)) {
|
||||
throw new NotFoundException('Invalid attribute or no authorisation to view it.');
|
||||
}
|
||||
$this->__downloadAttachment($this->Attribute->data['Attribute']);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,11 @@ class NidsExportComponent extends Component {
|
|||
|
||||
public $classtype = 'trojan-activity';
|
||||
|
||||
public $format = ""; // suricata (default), snort
|
||||
|
||||
public function explain() {
|
||||
$this->rules[] = '# MISP export of IDS rules - optimized for '.$this->format;
|
||||
$this->rules[] = '#';
|
||||
$this->rules[] = '# These NIDS rules contain some variables that need to exist in your configuration.';
|
||||
$this->rules[] = '# Make sure you have set:';
|
||||
$this->rules[] = '#';
|
||||
|
@ -19,12 +23,15 @@ class NidsExportComponent extends Component {
|
|||
|
||||
private $whitelist = null;
|
||||
|
||||
public function export($items, $startSid) {
|
||||
|
||||
public function export($items, $startSid, $format="suricata") {
|
||||
$this->format = $format;
|
||||
$this->Whitelist = ClassRegistry::init('Whitelist');
|
||||
$this->whitelist = $this->Whitelist->getBlockedValues();
|
||||
|
||||
// output a short explanation
|
||||
$this->explain();
|
||||
|
||||
// generate the rules
|
||||
foreach ($items as &$item) {
|
||||
switch ($item['Event']['risk']) {
|
||||
case 'Undefined':
|
||||
|
@ -99,6 +106,7 @@ class NidsExportComponent extends Component {
|
|||
|
||||
public function ipDstRule($ruleFormat, $attribute, &$sid) {
|
||||
$overruled = $this->checkWhitelist($attribute['value']);
|
||||
$attribute['value'] = NidsExportComponent::replaceIllegalChars($attribute['value']); // substitute chars not allowed in rule
|
||||
$this->rules[] = sprintf($ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'ip', // proto
|
||||
|
@ -108,8 +116,8 @@ class NidsExportComponent extends Component {
|
|||
$attribute['value'], // dst_ip
|
||||
'any', // dst_port
|
||||
'Outgoing To IP: ' . $attribute['value'], // msg
|
||||
'', // rule_content
|
||||
'', // tag
|
||||
'', // rule_content
|
||||
'', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
|
@ -117,6 +125,7 @@ class NidsExportComponent extends Component {
|
|||
|
||||
public function ipSrcRule($ruleFormat, $attribute, &$sid) {
|
||||
$overruled = $this->checkWhitelist($attribute['value']);
|
||||
$attribute['value'] = NidsExportComponent::replaceIllegalChars($attribute['value']); // substitute chars not allowed in rule
|
||||
$this->rules[] = sprintf($ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'ip', // proto
|
||||
|
@ -126,8 +135,8 @@ class NidsExportComponent extends Component {
|
|||
'$HOME_NET', // dst_ip
|
||||
'any', // dst_port
|
||||
'Incoming From IP: ' . $attribute['value'], // msg
|
||||
'', // rule_content
|
||||
'', // tag
|
||||
'', // rule_content
|
||||
'', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
|
@ -135,13 +144,14 @@ class NidsExportComponent extends Component {
|
|||
|
||||
public function emailSrcRule($ruleFormat, $attribute, &$sid) {
|
||||
$overruled = $this->checkWhitelist($attribute['value']);
|
||||
$content = 'flow:established,to_server; content:"MAIL FROM|3a|"; nocase; content:"' . $attribute['value'] . '"; nocase;';
|
||||
$attribute['value'] = NidsExportComponent::replaceIllegalChars($attribute['value']); // substitute chars not allowed in rule
|
||||
$content = 'flow:established,to_server; content:"MAIL FROM|3a|"; nocase; content:"' . $attribute['value'] . '"; fast_pattern; nocase; content:"|0D 0A 0D 0A|"; within:8192;';
|
||||
$this->rules[] = sprintf($ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'tcp', // proto
|
||||
'$EXTERNAL_NET', // src_ip
|
||||
'any', // src_port
|
||||
'<>', // direction
|
||||
'->', // direction
|
||||
'$SMTP_SERVERS', // dst_ip
|
||||
'25', // dst_port
|
||||
'Source Email Address: ' . $attribute['value'], // msg
|
||||
|
@ -154,18 +164,19 @@ class NidsExportComponent extends Component {
|
|||
|
||||
public function emailDstRule($ruleFormat, $attribute, &$sid) {
|
||||
$overruled = $this->checkWhitelist($attribute['value']);
|
||||
$content = 'flow:established,to_server; content:"RCPT TO|3a|"; nocase; content:"' . $attribute['value'] . '"; nocase;';
|
||||
$attribute['value'] = NidsExportComponent::replaceIllegalChars($attribute['value']); // substitute chars not allowed in rule
|
||||
$content = 'flow:established,to_server; content:"RCPT TO|3a|"; nocase; content:"' . $attribute['value'] . '"; fast_pattern; nocase; content:"|0D 0A 0D 0A|"; within:8192;';
|
||||
$this->rules[] = sprintf($ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'tcp', // proto
|
||||
'$EXTERNAL_NET', // src_ip
|
||||
'any', // src_port
|
||||
'<>', // direction
|
||||
'->', // direction
|
||||
'$SMTP_SERVERS', // dst_ip
|
||||
'25', // dst_port
|
||||
'Destination Email Address: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'tag:session,600,seconds;', // tag
|
||||
'tag:session,600,seconds;', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
|
@ -174,13 +185,14 @@ class NidsExportComponent extends Component {
|
|||
public function emailSubjectRule($ruleFormat, $attribute, &$sid) {
|
||||
// LATER nids - email-subject rule might not match because of line-wrapping
|
||||
$overruled = $this->checkWhitelist($attribute['value']);
|
||||
$content = 'flow:established,to_server; content:"Subject|3a|"; nocase; content:"' . $attribute['value'] . '"; nocase;';
|
||||
$attribute['value'] = NidsExportComponent::replaceIllegalChars($attribute['value']); // substitute chars not allowed in rule
|
||||
$content = 'flow:established,to_server; content:"Subject|3a|"; nocase; content:"' . $attribute['value'] . '"; fast_pattern; nocase; content:"|0D 0A 0D 0A|"; within:8192;';
|
||||
$this->rules[] = sprintf($ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'tcp', // proto
|
||||
'$EXTERNAL_NET', // src_ip
|
||||
'any', // src_port
|
||||
'<>', // direction
|
||||
'->', // direction
|
||||
'$SMTP_SERVERS', // dst_ip
|
||||
'25', // dst_port
|
||||
'Bad Email Subject', // msg
|
||||
|
@ -194,13 +206,14 @@ class NidsExportComponent extends Component {
|
|||
public function emailAttachmentRule($ruleFormat, $attribute, &$sid) {
|
||||
// LATER nids - email-attachment rule might not match because of line-wrapping
|
||||
$overruled = $this->checkWhitelist($attribute['value']);
|
||||
$content = 'flow:established,to_server; content:"Content-Disposition: attachment|3b| filename=|22|"; content:"' . $attribute['value'] . '|22|";';
|
||||
$attribute['value'] = NidsExportComponent::replaceIllegalChars($attribute['value']); // substitute chars not allowed in rule
|
||||
$content = 'flow:established,to_server; content:"Content-Disposition|3a| attachment|3b| filename|3d 22|"; content:"' . $attribute['value'] . '|22|"; fast_pattern; content:"|0D 0A 0D 0A|"; within:8192;';
|
||||
$this->rules[] = sprintf($ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'tcp', // proto
|
||||
'$EXTERNAL_NET', // src_ip
|
||||
'any', // src_port
|
||||
'<>', // direction
|
||||
'->', // direction
|
||||
'$SMTP_SERVERS', // dst_ip
|
||||
'25', // dst_port
|
||||
'Bad Email Attachment', // msg
|
||||
|
@ -213,7 +226,8 @@ class NidsExportComponent extends Component {
|
|||
|
||||
public function hostnameRule($ruleFormat, $attribute, &$sid) {
|
||||
$overruled = $this->checkWhitelist($attribute['value']);
|
||||
$content = 'content:"' . $this->dnsNameToRawFormat($attribute['value'], 'hostname') . '"; nocase;';
|
||||
$attribute['value'] = NidsExportComponent::replaceIllegalChars($attribute['value']); // substitute chars not allowed in rule
|
||||
$content = 'content:"|01 00 00 01 00 00 00 00 00 00|"; depth:10; offset:2; content:"' . NidsExportComponent::dnsNameToRawFormat($attribute['value'], 'hostname') . '"; fast_pattern; nocase;';
|
||||
$this->rules[] = sprintf($ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'udp', // proto
|
||||
|
@ -224,7 +238,7 @@ class NidsExportComponent extends Component {
|
|||
'53', // dst_port
|
||||
'Hostname: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'', // tag
|
||||
'', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
|
@ -238,26 +252,25 @@ class NidsExportComponent extends Component {
|
|||
'any', // dst_ip
|
||||
'53', // dst_port
|
||||
'Hostname: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'', // tag
|
||||
$content. ' flow:established;', // rule_content
|
||||
'', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
$sid++;
|
||||
// also do http requests
|
||||
// warning: only suricata compatible
|
||||
$content = 'flow:to_server,established; content: "Host: ' . $attribute['value'] . '"; nocase; http_header; pcre: "/[^A-Za-z0-9-]' . preg_quote($attribute['value']) . '[^A-Za-z0-9-]/";';
|
||||
$content = 'flow:to_server,established; content: "Host|3a| ' . $attribute['value'] . '"; nocase; http_header; pcre: "/[^A-Za-z0-9-\.]' . preg_quote($attribute['value']) . '[^A-Za-z0-9-\.]/H";';
|
||||
$this->rules[] = sprintf($ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'http', // proto
|
||||
'tcp', // proto
|
||||
'$HOME_NET', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'$EXTERNAL_NET', // dst_ip
|
||||
'any', // dst_port
|
||||
'$HTTP_PORTS', // dst_port
|
||||
'Outgoing HTTP Hostname: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'tag:session,600,seconds;', // tag
|
||||
'tag:session,600,seconds;', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
|
@ -265,7 +278,8 @@ class NidsExportComponent extends Component {
|
|||
|
||||
public function domainRule($ruleFormat, $attribute, &$sid) {
|
||||
$overruled = $this->checkWhitelist($attribute['value']);
|
||||
$content = 'content:"' . $this->dnsNameToRawFormat($attribute['value']) . '"; nocase;';
|
||||
$attribute['value'] = NidsExportComponent::replaceIllegalChars($attribute['value']); // substitute chars not allowed in rule
|
||||
$content = 'content:"|01 00 00 01 00 00 00 00 00 00|"; depth:10; offset:2; content:"' . NidsExportComponent::dnsNameToRawFormat($attribute['value']) . '"; fast_pattern; nocase;';
|
||||
$this->rules[] = sprintf($ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'udp', // proto
|
||||
|
@ -276,7 +290,7 @@ class NidsExportComponent extends Component {
|
|||
'53', // dst_port
|
||||
'Domain: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'', // tag
|
||||
'', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
|
@ -290,26 +304,25 @@ class NidsExportComponent extends Component {
|
|||
'any', // dst_ip
|
||||
'53', // dst_port
|
||||
'Domain: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'', // tag
|
||||
$content. ' flow:established;', // rule_content
|
||||
'', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
$sid++;
|
||||
// also do http requests,
|
||||
// warning: only suricata compatible
|
||||
$content = 'flow:to_server,established; content: "Host:"; nocase; http_header; content:"' . $attribute['value'] . '"; nocase; http_header; pcre: "/[^A-Za-z0-9-]' . preg_quote($attribute['value']) . '[^A-Za-z0-9-]/";';
|
||||
$content = 'flow:to_server,established; content: "Host|3a|"; nocase; http_header; content:"' . $attribute['value'] . '"; nocase; http_header; pcre: "/[^A-Za-z0-9-]' . preg_quote($attribute['value']) . '[^A-Za-z0-9-\.]/H";';
|
||||
$this->rules[] = sprintf($ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'http', // proto
|
||||
'tcp', // proto
|
||||
'$HOME_NET', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'$EXTERNAL_NET', // dst_ip
|
||||
'any', // dst_port
|
||||
'$HTTP_PORTS', // dst_port
|
||||
'Outgoing HTTP Domain: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'tag:session,600,seconds;', // tag
|
||||
'tag:session,600,seconds;', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
|
@ -319,32 +332,50 @@ class NidsExportComponent extends Component {
|
|||
// TODO in hindsight, an url should not be excluded given a host or domain name.
|
||||
//$hostpart = parse_url($attribute['value'], PHP_URL_HOST);
|
||||
//$overruled = $this->checkNames($hostpart);
|
||||
// warning: only suricata compatible
|
||||
$overruled = $this->checkWhitelist($attribute['value']);
|
||||
$attribute['value'] = NidsExportComponent::replaceIllegalChars($attribute['value']); // substitute chars not allowed in rule
|
||||
$content = 'flow:to_server,established; content:"' . $attribute['value'] . '"; nocase; http_uri;';
|
||||
$this->rules[] = sprintf($ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'http', // proto
|
||||
'tcp', // proto
|
||||
'$HOME_NET', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'$EXTERNAL_NET', // dst_ip
|
||||
'any', // dst_port
|
||||
'$HTTP_PORTS', // dst_port
|
||||
'Outgoing HTTP URL: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'tag:session,600,seconds;', // tag
|
||||
'tag:session,600,seconds;', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
}
|
||||
|
||||
public function userAgentRule($ruleFormat, $attribute, &$sid) {
|
||||
// TODO nids - write snort user-agent rule
|
||||
$overruled = $this->checkWhitelist($attribute['value']);
|
||||
$attribute['value'] = NidsExportComponent::replaceIllegalChars($attribute['value']); // substitute chars not allowed in rule
|
||||
$content = 'flow:to_server,established; content:"' . $attribute['value'] . '"; http_header;';
|
||||
$this->rules[] = sprintf($ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'tcp', // proto
|
||||
'$HOME_NET', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'$EXTERNAL_NET', // dst_ip
|
||||
'$HTTP_PORTS', // dst_port
|
||||
'Outgoing User-Agent: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'tag:session,600,seconds;', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
}
|
||||
|
||||
public function snortRule($ruleFormat, $attribute, &$sid, $ruleFormatMsg, $ruleFormatReference) {
|
||||
// LATER nids - test using lots of snort rules.
|
||||
$tmpRule = $attribute['value'];
|
||||
// LATER nids - test using lots of snort rules, some rules don't contain all the necessary to be a valid rule.
|
||||
|
||||
// store the value in the rule, but also strip out the newlines
|
||||
$tmpRule = str_replace(array("\r","\n"), " ", $attribute['value']);
|
||||
|
||||
// rebuild the rule by overwriting the different keywords using preg_replace()
|
||||
// sid - '/sid\s*:\s*[0-9]+\s*;/'
|
||||
|
@ -388,15 +419,15 @@ class NidsExportComponent extends Component {
|
|||
$this->rules[] = $tmpRule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a DNS name to a raw format usable in NIDS like Snort.
|
||||
* example host: foobar.com becomes |00||06|foobar|03|com|00|
|
||||
* example domain: foobar.com becomes |06|foobar|03|com|00|
|
||||
* @param string $name dns name to be converted
|
||||
* @param string $type the type of dns name - domain (default) or hostname
|
||||
* @return string raw snort compatible format of the dns name
|
||||
*/
|
||||
public function dnsNameToRawFormat($name, $type='domain') {
|
||||
/**
|
||||
* Converts a DNS name to a raw format usable in NIDS like Snort.
|
||||
* example host: foobar.com becomes |00||06|foobar|03|com|00|
|
||||
* example domain: foobar.com becomes |06|foobar|03|com|00|
|
||||
* @param string $name dns name to be converted
|
||||
* @param string $type the type of dns name - domain (default) or hostname
|
||||
* @return string raw snort compatible format of the dns name
|
||||
*/
|
||||
public static function dnsNameToRawFormat($name, $type='domain') {
|
||||
$rawName = "";
|
||||
if ('hostname' == $type) $rawName = '|00|';
|
||||
// explode using the dot
|
||||
|
@ -416,14 +447,14 @@ class NidsExportComponent extends Component {
|
|||
return $rawName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a DNS name to a MS DNS log format.
|
||||
* Practical usage is to use these strings to search in logfiles
|
||||
* example: foobar.com becomes (6)foobar(3)com(0)
|
||||
* @param string $name dns name to be converted
|
||||
* @return string raw snort compatible format of the dns name
|
||||
*/
|
||||
public function dnsNameToMSDNSLogFormat($name) {
|
||||
/**
|
||||
* Converts a DNS name to a MS DNS log format.
|
||||
* Practical usage is to use these strings to search in logfiles
|
||||
* example: foobar.com becomes (6)foobar(3)com(0)
|
||||
* @param string $name dns name to be converted
|
||||
* @return string raw snort compatible format of the dns name
|
||||
*/
|
||||
public static function dnsNameToMSDNSLogFormat($name) {
|
||||
$rawName = "";
|
||||
// in MS DNS log format we can't use (0) to distinguish between hostname and domain (including subdomains)
|
||||
// explode using the dot
|
||||
|
@ -438,10 +469,27 @@ class NidsExportComponent extends Component {
|
|||
}
|
||||
// put all together
|
||||
$rawName .= '(0)';
|
||||
// and append |00| to terminate the name
|
||||
// and append (0) to terminate the name
|
||||
return $rawName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces characters that are not allowed in a signature.
|
||||
* example: " is converted to |22|
|
||||
* @param unknown_type $value
|
||||
*/
|
||||
public static function replaceIllegalChars($value) {
|
||||
$replace_pairs = array(
|
||||
'|' => '|7c|', // Needs to stay on top !
|
||||
'"' => '|22|',
|
||||
';' => '|3b|',
|
||||
':' => '|3a|',
|
||||
'\\' => '|5c|',
|
||||
'0x' => '|30 78|'
|
||||
);
|
||||
return strtr($value, $replace_pairs);
|
||||
}
|
||||
|
||||
public function checkWhitelist($value) {
|
||||
foreach ($this->whitelist as $wlitem) {
|
||||
if (preg_match($wlitem, $value)) {
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
App::uses('NidsExportComponent', 'Controller/Component');
|
||||
|
||||
|
||||
class NidsSnortExportComponent extends NidsExportComponent {
|
||||
|
||||
public function export($items, $startSid) {
|
||||
// set the specific format
|
||||
$this->format = 'snort';
|
||||
// call the generic function
|
||||
return parent::export($items, $startSid);
|
||||
}
|
||||
|
||||
// below overwrite functions from NidsExportComponent
|
||||
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
<?php
|
||||
|
||||
App::uses('NidsExportComponent', 'Controller/Component');
|
||||
|
||||
|
||||
class NidsSuricataExportComponent extends NidsExportComponent {
|
||||
|
||||
public function export($items, $startSid) {
|
||||
// set the specific format
|
||||
$this->format = 'suricata';
|
||||
// call the generic function
|
||||
return parent::export($items, $startSid);
|
||||
}
|
||||
|
||||
// below overwrite functions from NidsExportComponent
|
||||
public function hostnameRule($ruleFormat, $attribute, &$sid) {
|
||||
$overruled = $this->checkWhitelist($attribute['value']);
|
||||
$attribute['value'] = NidsExportComponent::replaceIllegalChars($attribute['value']); // substitute chars not allowed in rule
|
||||
$content = 'content:"|01 00 00 01 00 00 00 00 00 00|"; depth:10; offset:2; content:"' . NidsExportComponent::dnsNameToRawFormat($attribute['value'], 'hostname') . '"; fast_pattern; nocase;';
|
||||
$this->rules[] = sprintf($ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'udp', // proto
|
||||
'any', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'any', // dst_ip
|
||||
'53', // dst_port
|
||||
'Hostname: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
$sid++;
|
||||
$this->rules[] = sprintf($ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'tcp', // proto
|
||||
'any', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'any', // dst_ip
|
||||
'53', // dst_port
|
||||
'Hostname: ' . $attribute['value'], // msg
|
||||
$content. ' flow:established;', // rule_content
|
||||
'', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
$sid++;
|
||||
// also do http requests
|
||||
// warning: only suricata compatible
|
||||
$content = 'flow:to_server,established; content: "Host|3a| ' . $attribute['value'] . '"; fast_pattern; nocase; http_header; pcre: "/[^A-Za-z0-9-\.]' . preg_quote($attribute['value']) . '[^A-Za-z0-9-\.]/H";';
|
||||
$this->rules[] = sprintf($ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'http', // proto
|
||||
'$HOME_NET', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'$EXTERNAL_NET', // dst_ip
|
||||
'any', // dst_port
|
||||
'Outgoing HTTP Hostname: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'tag:session,600,seconds;', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
}
|
||||
|
||||
public function domainRule($ruleFormat, $attribute, &$sid) {
|
||||
$overruled = $this->checkWhitelist($attribute['value']);
|
||||
$attribute['value'] = NidsExportComponent::replaceIllegalChars($attribute['value']); // substitute chars not allowed in rule
|
||||
$content = 'content:"|01 00 00 01 00 00 00 00 00 00|"; depth:10; offset:2; content:"' . NidsExportComponent::dnsNameToRawFormat($attribute['value']) . '"; fast_pattern; nocase;';
|
||||
$this->rules[] = sprintf($ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'udp', // proto
|
||||
'any', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'any', // dst_ip
|
||||
'53', // dst_port
|
||||
'Domain: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
$sid++;
|
||||
$this->rules[] = sprintf($ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'tcp', // proto
|
||||
'any', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'any', // dst_ip
|
||||
'53', // dst_port
|
||||
'Domain: ' . $attribute['value'], // msg
|
||||
$content. ' flow:established;', // rule_content
|
||||
'', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
$sid++;
|
||||
// also do http requests,
|
||||
// warning: only suricata compatible
|
||||
$content = 'flow:to_server,established; content: "Host|3a|"; nocase; http_header; content:"' . $attribute['value'] . '"; fast_pattern; nocase; http_header; pcre: "/[^A-Za-z0-9-]' . preg_quote($attribute['value']) . '[^A-Za-z0-9-\.]/H";';
|
||||
$this->rules[] = sprintf($ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'http', // proto
|
||||
'$HOME_NET', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'$EXTERNAL_NET', // dst_ip
|
||||
'any', // dst_port
|
||||
'Outgoing HTTP Domain: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'tag:session,600,seconds;', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
}
|
||||
|
||||
public function urlRule($ruleFormat, $attribute, &$sid) {
|
||||
// TODO in hindsight, an url should not be excluded given a host or domain name.
|
||||
//$hostpart = parse_url($attribute['value'], PHP_URL_HOST);
|
||||
//$overruled = $this->checkNames($hostpart);
|
||||
// warning: only suricata compatible
|
||||
$overruled = $this->checkWhitelist($attribute['value']);
|
||||
$attribute['value'] = NidsExportComponent::replaceIllegalChars($attribute['value']); // substitute chars not allowed in rule
|
||||
$content = 'flow:to_server,established; content:"' . $attribute['value'] . '"; fast_pattern; nocase; http_uri;';
|
||||
$this->rules[] = sprintf($ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'http', // proto
|
||||
'$HOME_NET', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'$EXTERNAL_NET', // dst_ip
|
||||
'any', // dst_port
|
||||
'Outgoing HTTP URL: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'tag:session,600,seconds;', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
}
|
||||
|
||||
public function userAgentRule($ruleFormat, $attribute, &$sid) {
|
||||
$overruled = $this->checkWhitelist($attribute['value']);
|
||||
$attribute['value'] = NidsExportComponent::replaceIllegalChars($attribute['value']); // substitute chars not allowed in rule
|
||||
// warning: only suricata compatible
|
||||
$content = 'flow:to_server,established; content:"' . $attribute['value'] . '"; fast_pattern; http_user_agent;';
|
||||
$this->rules[] = sprintf($ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'http', // proto
|
||||
'$HOME_NET', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'$EXTERNAL_NET', // dst_ip
|
||||
'any', // dst_port
|
||||
'Outgoing User-Agent: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'tag:session,600,seconds;', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -20,7 +20,7 @@ class EventsController extends AppController {
|
|||
'RequestHandler',
|
||||
'HidsMd5Export',
|
||||
'HidsSha1Export',
|
||||
'NidsExport',
|
||||
//'NidsSuricataExport',
|
||||
'IOCExport',
|
||||
'IOCImport'
|
||||
);
|
||||
|
@ -29,7 +29,7 @@ class EventsController extends AppController {
|
|||
'limit' => 60,
|
||||
'maxLimit' => 9999, // LATER we will bump here on a problem once we have more than 9999 events <- no we won't, this is the max a user van view/page.
|
||||
'order' => array(
|
||||
'Event.id' => 'DESC'
|
||||
'Event.timestamp' => 'DESC'
|
||||
),
|
||||
);
|
||||
|
||||
|
@ -45,6 +45,7 @@ class EventsController extends AppController {
|
|||
$this->Auth->allow('hids_sha1');
|
||||
$this->Auth->allow('text');
|
||||
$this->Auth->allow('dot');
|
||||
$this->Auth->allow('restSearch');
|
||||
|
||||
// TODO Audit, activate logable in a Controller
|
||||
if (count($this->uses) && $this->{$this->modelClass}->Behaviors->attached('SysLogLogable')) {
|
||||
|
@ -263,7 +264,7 @@ class EventsController extends AppController {
|
|||
}
|
||||
$this->Session->write('pivot_thread', $pivot);
|
||||
}
|
||||
|
||||
|
||||
private function __insertPivot($pivot, $oldId, $newPivot, $depth) {
|
||||
$depth++;
|
||||
if ($pivot['id'] == $oldId) {
|
||||
|
@ -276,7 +277,7 @@ class EventsController extends AppController {
|
|||
}
|
||||
return $pivot;
|
||||
}
|
||||
|
||||
|
||||
private function __checkForPivot($pivot, $id) {
|
||||
if ($id == $pivot['id']) return true;
|
||||
foreach ($pivot['children'] as $k => $v) {
|
||||
|
@ -286,7 +287,7 @@ class EventsController extends AppController {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private function __arrangePivotVertical(&$pivot) {
|
||||
if (empty($pivot)) return null;
|
||||
$max = count($pivot['children']) - 1;
|
||||
|
@ -300,7 +301,7 @@ class EventsController extends AppController {
|
|||
}
|
||||
return $temp;
|
||||
}
|
||||
|
||||
|
||||
public function removePivot($id, $eventId, $self = false) {
|
||||
$pivot = $this->Session->read('pivot_thread');
|
||||
if ($pivot['id'] == $id) {
|
||||
|
@ -314,7 +315,7 @@ class EventsController extends AppController {
|
|||
$pivot = $this->__arrangePivotVertical($pivot);
|
||||
$this->redirect(array('controller' => 'events', 'action' => 'view', $eventId, true, $eventId));
|
||||
}
|
||||
|
||||
|
||||
private function __removeChildren(&$pivot, $id) {
|
||||
if ($pivot['id'] == $id) {
|
||||
$pivot['children'] = array();
|
||||
|
@ -324,7 +325,7 @@ class EventsController extends AppController {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function __doRemove(&$pivot, $id) {
|
||||
foreach ($pivot['children'] as $k => $v) {
|
||||
if ($v['id'] == $id) {
|
||||
|
@ -336,7 +337,7 @@ class EventsController extends AppController {
|
|||
}
|
||||
return $pivot;
|
||||
}
|
||||
|
||||
|
||||
private function __setDeletable(&$pivot, $id, $root=false) {
|
||||
if ($pivot['id'] == $id && !$root) {
|
||||
$pivot['deletable'] = false;
|
||||
|
@ -349,123 +350,7 @@ class EventsController extends AppController {
|
|||
}
|
||||
return !$pivot['deletable'];
|
||||
}
|
||||
|
||||
/*
|
||||
public function view($id = null) {
|
||||
// If the length of the id provided is 36 then it is most likely a Uuid - find the id of the event, change $id to it and proceed to read the event as if the ID was entered.
|
||||
$perm_publish = $this->userRole['perm_publish'];
|
||||
if (strlen($id) == 36) {
|
||||
$this->Event->recursive = -1;
|
||||
$temp = $this->Event->findByUuid($id);
|
||||
if ($temp == null) throw new NotFoundException(__('Invalid event'));
|
||||
$id = $temp['Event']['id'];
|
||||
}
|
||||
$isSiteAdmin = $this->_isSiteAdmin();
|
||||
|
||||
$this->Event->id = $id;
|
||||
if(!$this->Event->exists()) {
|
||||
throw new NotFoundException(__('Invalid event, it already exists.'));
|
||||
}
|
||||
|
||||
$this->Event->recursive = 2;
|
||||
$this->Event->contain('Attribute', 'ShadowAttribute', 'User.email');
|
||||
$this->Event->read();
|
||||
$myEvent = true;
|
||||
if (!$isSiteAdmin) {
|
||||
// check private
|
||||
if (($this->Event->data['Event']['distribution'] == 0) && ($this->Event->data['Event']['org'] != $this->Auth->user('org'))) {
|
||||
$this->Session->setFlash(__('Invalid event.'));
|
||||
$this->redirect(array('controller' => 'events', 'action' => 'index'));
|
||||
}
|
||||
}
|
||||
if ($this->Event->data['Event']['org'] != $this->Auth->user('org')) {
|
||||
$myEvent = false;
|
||||
}
|
||||
|
||||
// Now that we're loaded the event and made sure that we can actually see it, let's do 2 thngs:
|
||||
// run through each attribute and unset it if it's private and we're not an admin or from the owner org of the event
|
||||
// if we didn't unset the attribute, rearrange the shadow attributes
|
||||
foreach ($this->Event->data['Attribute'] as $key => &$attribute) {
|
||||
if (!$isSiteAdmin && !$myEvent && ($attribute['distribution'] == 0)) {
|
||||
unset($this->Event->data['Attribute'][$key]);
|
||||
} else {
|
||||
if (!isset($attribute['ShadowAttribute'])) $attribute['ShadowAttribute'] = array();
|
||||
foreach ($this->Event->data['ShadowAttribute'] as $k => &$sa) {
|
||||
if ($sa['old_id'] == $attribute['id']) {
|
||||
$this->Event->data['Attribute'][$key]['ShadowAttribute'][] = $sa;
|
||||
unset($this->Event->data['ShadowAttribute'][$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// since we unset some attributes and shadowattributes, let's reindex them.
|
||||
$this->Event->data['ShadowAttribute'] = array_values($this->Event->data['ShadowAttribute']);
|
||||
$this->Event->data['Attribute'] = array_values($this->Event->data['Attribute']);
|
||||
|
||||
$this->set('analysisLevels', $this->Event->analysisLevels);
|
||||
|
||||
$relatedEvents = $this->Event->getRelatedEvents($this->Auth->user());
|
||||
$relatedAttributes = $this->Event->getRelatedAttributes($this->Auth->user());
|
||||
$this->loadModel('Attribute');
|
||||
if ($this->_isRest()) {
|
||||
foreach ($this->Event->data['Attribute'] as &$attribute) {
|
||||
// for REST requests also add the encoded attachment
|
||||
if ($this->Attribute->typeIsAttachment($attribute['type'])) {
|
||||
// LATER check if this has a serious performance impact on XML conversion and memory usage
|
||||
$encodedFile = $this->Attribute->base64EncodeAttachment($attribute);
|
||||
$attribute['data'] = $encodedFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
// set up the ShadowAttributes for the view - the only shadow attributes that should be passed to the view are the ones that the user is eligible to see
|
||||
// This means: Proposals of other organisations to own events, if the user is a publisher
|
||||
// Also: proposals made by the current user's organisation
|
||||
if (!$this->_isRest()) {
|
||||
foreach ($this->Event->data['Attribute'] as &$attribute) {
|
||||
// if the user is of the same org as the event and has publishing rights, just show everything
|
||||
if (($this->Auth->user('org') != $this->Event->data['Event']['org'] || !$perm_publish) && !$this->_isSiteAdmin()) {
|
||||
$counter = 0;
|
||||
foreach ($attribute['ShadowAttribute'] as &$shadow) {
|
||||
if ($shadow['org'] != $this->Auth->user('org')) unset($attribute['ShadowAttribute'][$counter]);
|
||||
$counter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// params for the jQuery RESTfull interface
|
||||
$this->set('authkey', $this->Auth->user('authkey'));
|
||||
$this->set('baseurl', Configure::read('CyDefSIG.baseurl'));
|
||||
|
||||
$this->set('relatedAttributes', $relatedAttributes);
|
||||
// passing decriptions for model fields
|
||||
$this->set('eventDescriptions', $this->Event->fieldDescriptions);
|
||||
$this->set('attrDescriptions', $this->Attribute->fieldDescriptions);
|
||||
$this->set('event', $this->Event->data);
|
||||
if(isset($this->Event->data['ShadowAttribute'])) {
|
||||
$this->set('remaining', $this->Event->data['ShadowAttribute']);
|
||||
}
|
||||
$this->set('relatedEvents', $relatedEvents);
|
||||
|
||||
$this->set('categories', $this->Attribute->validate['category']['rule'][1]);
|
||||
|
||||
// passing type and category definitions (explanations)
|
||||
$this->set('typeDefinitions', $this->Attribute->typeDefinitions);
|
||||
$this->set('categoryDefinitions', $this->Attribute->categoryDefinitions);
|
||||
|
||||
// combobox for analysis
|
||||
$this->set('distributionDescriptions', $this->Event->distributionDescriptions);
|
||||
$this->set('distributionLevels', $this->Event->distributionLevels);
|
||||
|
||||
// combobox for analysis
|
||||
$analysiss = $this->Event->validate['analysis']['rule'][1];
|
||||
$analysiss = $this->_arrayToValuesIndexArray($analysiss);
|
||||
$this->set('analysiss', $analysiss);
|
||||
// tooltip for analysis
|
||||
$this->set('analysisDescriptions', $this->Event->analysisDescriptions);
|
||||
$this->set('analysisLevels', $this->Event->analysisLevels);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* add method
|
||||
|
@ -1497,7 +1382,7 @@ class EventsController extends AppController {
|
|||
|
||||
// Grab an event or a list of events for the event view or any of the XML exports. The returned object includes an array of events (or an array that only includes a single event if an ID was given)
|
||||
// Included with the event are the attached attributes, shadow attributes, related events, related attribute information for the event view and the creating user's email address where appropriate
|
||||
private function __fetchEvent($eventid = null, $idList = null) {
|
||||
private function __fetchEvent($eventid = null, $idList = null, $orgFromFetch = null) {
|
||||
if (isset($eventid)) {
|
||||
$this->Event->id = $eventid;
|
||||
if (!$this->Event->exists()) {
|
||||
|
@ -1507,11 +1392,22 @@ class EventsController extends AppController {
|
|||
} else {
|
||||
$conditions = array();
|
||||
}
|
||||
// if we come from automation, we may not be logged in - instead we used an auth key in the URL.
|
||||
if (!empty($orgFromFetch)) {
|
||||
$org = $orgFromFetch;
|
||||
if ($orgFromFetch == 'ADMIN') $isSiteAdmin = true;
|
||||
else $isSiteAdmin = false;
|
||||
} else {
|
||||
$org = $this->_checkOrg();
|
||||
$isSiteAdmin = $this->_isSiteAdmin();
|
||||
}
|
||||
|
||||
$conditionsAttributes = array();
|
||||
$conditionsShadowAttributes = array();
|
||||
//restricting to non-private or same org if the user is not a site-admin.
|
||||
if (!$this->_isSiteAdmin()) {
|
||||
$org = $this->_checkOrg();
|
||||
if (!$isSiteAdmin) {
|
||||
if (!empty($orgFromFetch)) $org = $orgFromFetch;
|
||||
else $org = $this->_checkOrg();
|
||||
$conditions['AND']['OR'] = array(
|
||||
'Event.distribution >' => 0,
|
||||
'Event.org LIKE' => $org
|
||||
|
@ -1527,10 +1423,8 @@ class EventsController extends AppController {
|
|||
array('(SELECT events.org FROM events WHERE events.id = ShadowAttribute.event_id) LIKE' => $org),
|
||||
array('ShadowAttribute.org LIKE' => $org),
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if ($idList) {
|
||||
$conditions['AND'][] = array('Event.id' => $idList);
|
||||
}
|
||||
|
@ -1559,7 +1453,7 @@ class EventsController extends AppController {
|
|||
),
|
||||
)
|
||||
);
|
||||
if ($this->_isAdmin()) $params['contain']['User'] = array('fields' => 'email');
|
||||
if ($isSiteAdmin) $params['contain']['User'] = array('fields' => 'email');
|
||||
$results = $this->Event->find('all', $params);
|
||||
// Do some refactoring with the event
|
||||
foreach ($results as $eventKey => &$event) {
|
||||
|
@ -1584,7 +1478,14 @@ class EventsController extends AppController {
|
|||
return $results;
|
||||
}
|
||||
|
||||
public function nids($key) {
|
||||
public function nids($format = 'suricata', $key = '') {
|
||||
|
||||
// backwards compatibility, swap key and format
|
||||
if ($format != 'snort' && $format != 'suricata') {
|
||||
$key = $format;
|
||||
$format = 'suricata'; // default format
|
||||
}
|
||||
|
||||
if ($key != 'download') {
|
||||
$this->response->type('txt'); // set the content type
|
||||
$this->header('Content-Disposition: inline; filename="misp.rules"');
|
||||
|
@ -1627,7 +1528,17 @@ class EventsController extends AppController {
|
|||
unset($this->Attribute->virtualFields['category_order']); // not needed for IDS export and speeds things up
|
||||
$items = $this->Attribute->find('all', $params);
|
||||
|
||||
// export depending of the requested type
|
||||
switch ($format) {
|
||||
case 'suricata':
|
||||
$this->NidsExport = $this->Components->load('NidsSuricataExport');
|
||||
break;
|
||||
case 'snort':
|
||||
$this->NidsExport = $this->Components->load('NidsSnortExport');
|
||||
break;
|
||||
}
|
||||
$rules = $this->NidsExport->export($items, $user['User']['nids_sid']);
|
||||
|
||||
$this->set('rules', $rules);
|
||||
}
|
||||
|
||||
|
@ -2217,7 +2128,73 @@ class EventsController extends AppController {
|
|||
$this->set('results', $results);
|
||||
$this->render('xml');
|
||||
}
|
||||
|
||||
|
||||
// Use the rest interface to search for attributes or events. Usage:
|
||||
// MISP-base-url/events/restSearch/[api-key]/[value]/[type]/[category]/[orgc]
|
||||
// value, type, category, orgc are optional
|
||||
// target can be either "event" or "attribute"
|
||||
// the last 4 fields accept the following operators:
|
||||
// && - you can use && between two search values to put a logical OR between them. for value, 1.1.1.1&&2.2.2.2 would find attributes with the value being either of the two.
|
||||
// ! - you can negate a search term. For example: google.com&&!mail would search for all attributes with value google.com but not ones that include mail. www.google.com would get returned, mail.google.com wouldn't.
|
||||
public function restSearch($key, $value=null, $type=null, $category=null, $org=null) {
|
||||
$user = $this->checkAuthUser($key);
|
||||
if (!$user) {
|
||||
throw new UnauthorizedException('This authentication key is not authorized to be used for exports. Contact your administrator.');
|
||||
}
|
||||
$this->response->type('xml'); // set the content type
|
||||
$this->layout = 'xml/default';
|
||||
$this->header('Content-Disposition: download; filename="misp.search.events.results.xml"');
|
||||
$conditions['AND'] = array();
|
||||
$subcondition = array();
|
||||
$this->loadModel('Attribute');
|
||||
// add the values as specified in the 2nd parameter to the conditions
|
||||
$values = explode('&&', $value);
|
||||
$parameters = array('value', 'type', 'category', 'org');
|
||||
|
||||
foreach ($parameters as $k => $param) {
|
||||
if (isset(${$parameters[$k]})) {
|
||||
$elements = explode('&&', ${$parameters[$k]});
|
||||
foreach($elements as $v) {
|
||||
if (substr($v, 0, 1) == '!') {
|
||||
$subcondition['AND'][] = array('Attribute.' . $parameters[$k] . ' NOT LIKE' => '%'.substr($v, 1).'%');
|
||||
} else {
|
||||
$subcondition['OR'][] = array('Attribute.' . $parameters[$k] . ' LIKE' => '%'.$v.'%');
|
||||
}
|
||||
}
|
||||
array_push ($conditions['AND'], $subcondition);
|
||||
$subcondition = array();
|
||||
}
|
||||
}
|
||||
|
||||
// If we are looking for an attribute, we want to retrieve some extra data about the event to be able to check for the permissions.
|
||||
|
||||
if (!$user['User']['siteAdmin']) {
|
||||
$temp = array();
|
||||
$temp['AND'] = array('Event.distribution >' => 0, 'Attribute.distribution >' => 0);
|
||||
$subcondition['OR'][] = $temp;
|
||||
$subcondition['OR'][] = array('Event.org' => $user['User']['org']);
|
||||
array_push($conditions['AND'], $subcondition);
|
||||
}
|
||||
|
||||
$params = array(
|
||||
'conditions' => $conditions,
|
||||
'fields' => array('Attribute.event_id'),
|
||||
);
|
||||
$attributes = $this->Attribute->find('all', $params);
|
||||
$eventIds = array();
|
||||
foreach ($attributes as $attribute) {
|
||||
if (!in_array($attribute['Attribute']['event_id'], $eventIds)) $eventIds[] = $attribute['Attribute']['event_id'];
|
||||
}
|
||||
if (!empty($eventIds)) {
|
||||
$results = $this->__fetchEvent(null, $eventIds, $user['User']['org']);
|
||||
} else {
|
||||
throw new NotFoundException('No matches.');
|
||||
}
|
||||
$this->loadModel('Whitelist');
|
||||
$results = $this->Whitelist->removeWhitelistedFromArray($results, true);
|
||||
$this->set('results', $results);
|
||||
}
|
||||
|
||||
public function downloadOpenIOCEvent($eventid) {
|
||||
|
||||
// return a downloadable text file called misp.openIOC.<eventId>.ioc for individual events
|
||||
|
|
|
@ -93,6 +93,7 @@ class ShadowAttribute extends AppModel {
|
|||
public $typeDefinitions = array(
|
||||
'md5' => array('desc' => 'A checksum in md5 format', 'formdesc' => "You are encouraged to use filename|md5 instead. <br/>A checksum in md5 format, only use this if you don't know the correct filename"),
|
||||
'sha1' => array('desc' => 'A checksum in sha1 format', 'formdesc' => "You are encouraged to use filename|sha1 instead. <br/>A checksum in sha1 format, only use this if you don't know the correct filename"),
|
||||
'sha256' => array('desc' => 'A checksum in sha256 format', 'formdesc' => "You are encouraged to use filename|sha256 instead. A checksum in sha256 format, o nly use this if you don't know the correct filename"),
|
||||
'filename' => array('desc' => 'Filename'),
|
||||
'filename|md5' => array('desc' => 'A filename and an md5 hash separated by a |', 'formdesc' => "A filename and an md5 hash separated by a | (no spaces)"),
|
||||
'filename|sha1' => array('desc' => 'A filename and an sha1 hash separated by a |', 'formdesc' => "A filename and an sha1 hash separated by a | (no spaces)"),
|
||||
|
@ -105,7 +106,8 @@ class ShadowAttribute extends AppModel {
|
|||
'email-subject' => array('desc' => "The subject of the email"),
|
||||
'email-attachment' => array('desc' => "File name of the email attachment."),
|
||||
'url' => array('desc' => 'url'),
|
||||
'user-agent' => array('desc' => "The user-agent used by the malware in the HTTP request."),
|
||||
'http-method' => array('desc' => "HTTP method used by the malware (e.g. POST, GET, ...)."),
|
||||
'user-agent' => array('desc' => "The user-agent used by the malware in the HTTP request."),
|
||||
'regkey' => array('desc' => "Registry key or value"),
|
||||
'regkey|value' => array('desc' => "Registry value + data separated by |"),
|
||||
'AS' => array('desc' => 'Autonomous system'),
|
||||
|
@ -120,6 +122,8 @@ class ShadowAttribute extends AppModel {
|
|||
'link' => array('desc' => 'Link to an external information'),
|
||||
'comment' => array('desc' => 'Comment or description in a human language', 'formdesc' => 'Comment or description in a human language. <br/> This will not be correlated with other attributes (NOT IMPLEMENTED YET)'),
|
||||
'text' => array('desc' => 'Name, ID or a reference'),
|
||||
'named pipe' => array('desc' => 'Named pipe, use the format \\.\pipe\<PipeName>'),
|
||||
'mutex' => array('desc' => 'Mutex, use the format \BaseNamedObjects\<Mutex>'),
|
||||
'other' => array('desc' => 'Other attribute')
|
||||
);
|
||||
|
||||
|
@ -137,16 +141,16 @@ class ShadowAttribute extends AppModel {
|
|||
'Payload delivery' => array(
|
||||
'desc' => 'Information about how the malware is delivered',
|
||||
'formdesc' => 'Information about the way the malware payload is initially delivered, <br/>for example information about the email or web-site, vulnerability used, originating IP etc. <br/>Malware sample itself should be attached here.',
|
||||
'types' => array('md5', 'sha1', 'filename', 'filename|md5', 'filename|sha1', 'ip-src', 'ip-dst', 'hostname', 'domain', 'email-src', 'email-dst', 'email-subject', 'email-attachment', 'url', 'ip-dst', 'user-agent', 'AS', 'pattern-in-file', 'pattern-in-traffic', 'yara', 'attachment', 'malware-sample', 'link', 'comment', 'text', 'vulnerability', 'other')
|
||||
'types' => array('md5', 'sha1', 'sha256', 'filename', 'filename|md5', 'filename|sha1', 'filename|sha256', 'ip-src', 'ip-dst', 'hostname', 'domain', 'email-src', 'email-dst', 'email-subject', 'email-attachment', 'url', 'ip-dst', 'user-agent', 'http-method', 'AS', 'pattern-in-file', 'pattern-in-traffic', 'yara', 'attachment', 'malware-sample', 'link', 'comment', 'text', 'vulnerability', 'other')
|
||||
),
|
||||
'Artifacts dropped' => array(
|
||||
'desc' => 'Any artifact (files, registry keys etc.) dropped by the malware or other modifications to the system',
|
||||
'types' => array('md5', 'sha1', 'filename', 'filename|md5', 'filename|sha1', 'regkey', 'regkey|value', 'pattern-in-file', 'pattern-in-memory', 'yara', 'attachment', 'malware-sample', 'comment', 'text', 'other')
|
||||
'types' => array('md5', 'sha1', 'sha256', 'filename', 'filename|md5', 'filename|sha256', 'filename|sha1', 'regkey', 'regkey|value', 'pattern-in-file', 'pattern-in-memory', 'yara', 'attachment', 'malware-sample', 'comment', 'text', 'other', 'named pipe', 'mutex')
|
||||
),
|
||||
'Payload installation' => array(
|
||||
'desc' => 'Info on where the malware gets installed in the system',
|
||||
'formdesc' => 'Location where the payload was placed in the system and the way it was installed.<br/>For example, a filename|md5 type attribute can be added here like this:<br/>c:\\windows\\system32\\malicious.exe|41d8cd98f00b204e9800998ecf8427e.',
|
||||
'types' => array('md5', 'sha1', 'filename', 'filename|md5', 'filename|sha1', 'pattern-in-file', 'pattern-in-traffic', 'pattern-in-memory', 'yara', 'vulnerability', 'attachment', 'malware-sample', 'comment', 'text', 'other')
|
||||
'types' => array('md5', 'sha1', 'sha256', 'filename', 'filename|md5', 'filename|sha1', 'filename|sha256', 'pattern-in-file', 'pattern-in-traffic', 'pattern-in-memory', 'yara', 'vulnerability', 'attachment', 'malware-sample', 'comment', 'text', 'other')
|
||||
),
|
||||
'Persistence mechanism' => array(
|
||||
'desc' => 'Mechanisms used by the malware to start at boot',
|
||||
|
@ -155,7 +159,7 @@ class ShadowAttribute extends AppModel {
|
|||
),
|
||||
'Network activity' => array(
|
||||
'desc' => 'Information about network traffic generated by the malware',
|
||||
'types' => array('ip-src', 'ip-dst', 'hostname', 'domain', 'email-dst', 'url', 'user-agent', 'AS', 'snort', 'pattern-in-file', 'pattern-in-traffic', 'attachment', 'comment', 'text', 'other')
|
||||
'types' => array('ip-src', 'ip-dst', 'hostname', 'domain', 'email-dst', 'url', 'user-agent', 'http-method','AS', 'snort', 'pattern-in-file', 'pattern-in-traffic', 'attachment', 'comment', 'text', 'other')
|
||||
),
|
||||
'Payload type' => array(
|
||||
'desc' => 'Information about the final payload(s)',
|
||||
|
@ -169,7 +173,7 @@ class ShadowAttribute extends AppModel {
|
|||
'External analysis' => array(
|
||||
'desc' => 'Any other result from additional analysis of the malware like tools output',
|
||||
'formdesc' => 'Any other result from additional analysis of the malware like tools output<br/>Examples: pdf-parser output, automated sandbox analysis, reverse engineering report.',
|
||||
'types' => array('md5', 'sha1', 'filename', 'filename|md5', 'filename|sha1', 'ip-src', 'ip-dst', 'hostname', 'domain', 'url', 'user-agent', 'regkey', 'regkey|value', 'AS', 'snort', 'pattern-in-file', 'pattern-in-traffic', 'pattern-in-memory', 'vulnerability', 'attachment', 'malware-sample', 'link', 'comment', 'text', 'other')
|
||||
'types' => array('md5', 'sha1', 'sha256', 'filename', 'filename|md5', 'filename|sha1', 'filename|sha256', 'ip-src', 'ip-dst', 'hostname', 'domain', 'url', 'user-agent', 'http-method', 'regkey', 'regkey|value', 'AS', 'snort', 'pattern-in-file', 'pattern-in-traffic', 'pattern-in-memory', 'vulnerability', 'attachment', 'malware-sample', 'link', 'comment', 'text', 'other')
|
||||
),
|
||||
'Other' => array(
|
||||
'desc' => 'Attributes that are not part of any other category',
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
$xmlArray = array();
|
||||
foreach ($results as $k => $v) {
|
||||
unset (
|
||||
$results[$k]['Event'],
|
||||
$results[$k]['Attribute']['value1'],
|
||||
$results[$k]['Attribute']['value2'],
|
||||
$results[$k]['Attribute']['category_order']
|
||||
);
|
||||
$xmlArray['response']['Attribute'][] = $results[$k]['Attribute'];
|
||||
}
|
||||
$xmlObject = Xml::fromArray($xmlArray, array('format' => 'tags'));
|
||||
echo $xmlObject->asXML();
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
$xmlArray = array();
|
||||
foreach ($results as $k => $v) {
|
||||
unset (
|
||||
$results[$k]['value1'],
|
||||
$results[$k]['value2'],
|
||||
$results[$k]['category_order']
|
||||
);
|
||||
$xmlArray['response']['Attribute'][] = $results[$k];
|
||||
}
|
||||
$xmlObject = Xml::fromArray($xmlArray, array('format' => 'tags'));
|
||||
echo $xmlObject->asXML();
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
$xmlArray = array();
|
||||
foreach ($results as $k => $v) {
|
||||
unset (
|
||||
$results[$k]['Event'],
|
||||
$results[$k]['Attribute']['value1'],
|
||||
$results[$k]['Attribute']['value2'],
|
||||
$results[$k]['Attribute']['category_order']
|
||||
);
|
||||
$xmlArray['response']['Attribute'][] = $results[$k]['Attribute'];
|
||||
}
|
||||
$xmlObject = Xml::fromArray($xmlArray, array('format' => 'tags'));
|
||||
echo $xmlObject->asXML();
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
$xmlArray = array();
|
||||
foreach ($results as $k => $v) {
|
||||
unset (
|
||||
$results[$k]['value1'],
|
||||
$results[$k]['value2'],
|
||||
$results[$k]['category_order']
|
||||
);
|
||||
$xmlArray['response']['Attribute'][] = $results[$k];
|
||||
}
|
||||
$xmlObject = Xml::fromArray($xmlArray, array('format' => 'tags'));
|
||||
echo $xmlObject->asXML();
|
|
@ -17,10 +17,11 @@ You can <?php echo $this->Html->link('reset', array('controller' => 'users', 'ac
|
|||
<p>Also check out the <?php echo $this->Html->link(__('User Guide', true), array('controller' => 'pages', 'action' => 'display', 'using_the_system', '#' => 'rest')); ?> to read about the REST API.</p>
|
||||
<p></p>
|
||||
|
||||
<h3>NIDS signatures export</h3>
|
||||
<h3>NIDS rules export</h3>
|
||||
<p>Automatic export of all network related attributes is available under the Snort rule format. Only <em>published</em> events and attributes marked as <em>IDS Signature</em> are exported.</p>
|
||||
<p>You can configure your tools to automatically download the following file:</p>
|
||||
<pre><?php echo Configure::read('CyDefSIG.baseurl');?>/events/nids/<?php echo $me['authkey']; ?></pre>
|
||||
<pre><?php echo Configure::read('CyDefSIG.baseurl');?>/events/nids/suricata/<?php echo $me['authkey']."\n"; ?>
|
||||
<?php echo Configure::read('CyDefSIG.baseurl');?>/events/nids/snort/<?php echo $me['authkey']; ?></pre>
|
||||
<p></p>
|
||||
<p>Administration is able to maintain a white-list containing host, domain name and IP numbers to exclude from the NIDS export.</p>
|
||||
|
||||
|
@ -45,16 +46,51 @@ foreach ($sigTypes as $sigType) {
|
|||
</pre>
|
||||
<p></p>
|
||||
|
||||
<h3>Saved search XML export</h3>
|
||||
<p>We plan to make it possible to export data using searchpatterns.<br/>
|
||||
This would enable you to export:</p>
|
||||
<ul>
|
||||
<li>only your own attributes</li>
|
||||
<li>date ranges</li>
|
||||
<li>only specific attribute types (domain)</li>
|
||||
<li>...</li>
|
||||
</ul>
|
||||
<h3>RESTful searches with XML result export</h3>
|
||||
<p>It is possible to search the database for attributes based on a list of criteria. </p>
|
||||
<p>To return an event with all of its attributes, relations, shadowAttributes, use the following syntax:</p>
|
||||
<pre>
|
||||
<?php
|
||||
echo Configure::read('CyDefSIG.baseurl').'/events/restSearch/'.$me['authkey'].'/[value]/[type]/[category]/[org]';
|
||||
?>
|
||||
</pre>
|
||||
<p>To just return a list of attributes, use the following syntax:</p>
|
||||
<pre>
|
||||
<?php
|
||||
echo Configure::read('CyDefSIG.baseurl').'/attributes/restSearch/'.$me['authkey'].'/[value]/[type]/[category]/[org]';
|
||||
?>
|
||||
</pre>
|
||||
<p>value, type, category and org are optional. It is possible to search for several terms in each category by joining them with the '&&' operator. It is also possible to negate a term with the '!' operator.
|
||||
For example, in order to search for all attributes created by your organisation that contain 192.168 or 127.0 but not 0.1 and are of the type ip-src use the following syntax:</p>
|
||||
<pre>
|
||||
<?php
|
||||
echo Configure::read('CyDefSIG.baseurl').'/attributes/restSearch/'.$me['authkey'].'/192.168&&127.0&&!0.1/ip-src/null/' . $me['org'];
|
||||
?>
|
||||
</pre>
|
||||
|
||||
<h3>Export attributes of event with specified type as XML</h3>
|
||||
<p>If you want to export all attributes of a pre-defined type that belong to an event, use the following syntax:</p>
|
||||
<pre>
|
||||
<?php
|
||||
echo Configure::read('CyDefSIG.baseurl').'/attributes/returnAttributes/'.$me['authkey'].'/[id]/[type]/[sigOnly]';
|
||||
?>
|
||||
</pre>
|
||||
<p>sigOnly is an optional flag that will block all attributes from being exported that don't have the IDS flag turned on.
|
||||
It is possible to search for several types with the '&&' operator and to exclude values with the '!' operator.
|
||||
For example, to get all IDS signature attributes of type md5 and sha256, but not filename|md5 and filename|sha256 from event 25, use the following: </p>
|
||||
<pre>
|
||||
<?php
|
||||
echo Configure::read('CyDefSIG.baseurl').'/attributes/returnAttributes/'.$me['authkey'].'/25/md5&&sha256&&!filename/true';
|
||||
?>
|
||||
</pre>
|
||||
|
||||
<h3>Download attachment or malware sample</h3>
|
||||
<p>If you know the attribute ID of a malware-sample or an attachment, you can download it with the following syntax:</p>
|
||||
<pre>
|
||||
<?php
|
||||
echo Configure::read('CyDefSIG.baseurl').'/attributes/downloadAttachment/'.$me['authkey'].'/[Attribute_id]';
|
||||
?>
|
||||
</pre>
|
||||
</div>
|
||||
<?php
|
||||
echo $this->element('side_menu', array('menuList' => 'event-collection', 'menuItem' => 'automation'));
|
||||
|
|
|
@ -28,7 +28,8 @@
|
|||
</div>
|
||||
<div class="row bottom-buffer">
|
||||
<div class="span3">
|
||||
<?php echo $this->Html->link('Download NIDS signatures', array('action' => 'nids', 'download'), array('class' => 'btn btn-block full-width')); ?>
|
||||
<?php echo $this->Html->link('Download Suricata rules', array('action' => 'nids', 'suricata', 'download'), array('class' => 'btn btn-block full-width')); ?>
|
||||
<?php echo $this->Html->link('Download Snort rules', array('action' => 'nids', 'snort', 'download'), array('class' => 'btn btn-block full-width')); ?>
|
||||
</div>
|
||||
<div class="span9">Click this to download all network related attributes that you
|
||||
have access to under the Snort rule format. Only <em>published</em>
|
||||
|
@ -65,4 +66,4 @@
|
|||
</div>
|
||||
<?php
|
||||
echo $this->element('side_menu', array('menuList' => 'event-collection', 'menuItem' => 'export'));
|
||||
?>
|
||||
?>
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
$xmlArray = array();
|
||||
foreach ($results as $result) {
|
||||
$result['Event']['Attribute'] = $result['Attribute'];
|
||||
$result['Event']['ShadowAttribute'] = $result['ShadowAttribute'];
|
||||
$result['Event']['RelatedEvent'] = $result['RelatedEvent'];
|
||||
|
||||
//
|
||||
// cleanup the array from things we do not want to expose
|
||||
//
|
||||
unset($result['Event']['user_id']);
|
||||
// hide the org field is we are not in showorg mode
|
||||
if ('true' != Configure::read('CyDefSIG.showorg') && !$isSiteAdmin) {
|
||||
unset($result['Event']['org']);
|
||||
unset($result['Event']['orgc']);
|
||||
unset($result['Event']['from']);
|
||||
}
|
||||
// remove value1 and value2 from the output and remove invalid utf8 characters for the xml parser
|
||||
foreach ($result['Event']['Attribute'] as $key => $value) {
|
||||
$result['Event']['Attribute'][$key]['value'] = preg_replace ('/[^\x{0009}\x{000a}\x{000d}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]+/u', ' ', $result['Event']['Attribute'][$key]['value']);
|
||||
unset($result['Event']['Attribute'][$key]['value1']);
|
||||
unset($result['Event']['Attribute'][$key]['value2']);
|
||||
unset($result['Event']['Attribute'][$key]['category_order']);
|
||||
}
|
||||
// remove invalid utf8 characters for the xml parser
|
||||
foreach($result['Event']['ShadowAttribute'] as $key => $value) {
|
||||
$result['Event']['ShadowAttribute'][$key]['value'] = preg_replace ('/[^\x{0009}\x{000a}\x{000d}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]+/u', ' ', $result['Event']['ShadowAttribute'][$key]['value']);
|
||||
}
|
||||
|
||||
if (isset($result['Event']['RelatedEvent'])) {
|
||||
foreach ($result['Event']['RelatedEvent'] as $key => $value) {
|
||||
unset($result['Event']['RelatedEvent'][$key]['user_id']);
|
||||
if ('true' != Configure::read('CyDefSIG.showorg') && !$isAdmin) {
|
||||
unset($result['Event']['RelatedEvent'][$key]['org']);
|
||||
unset($result['Event']['RelatedEvent'][$key]['orgc']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$xmlArray['response']['Event'][] = $result['Event'];
|
||||
}
|
||||
|
||||
$xmlObject = Xml::fromArray($xmlArray, array('format' => 'tags'));
|
||||
echo $xmlObject->asXML();
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
$xmlArray = array();
|
||||
foreach ($results as $result) {
|
||||
$result['Event']['Attribute'] = $result['Attribute'];
|
||||
$result['Event']['ShadowAttribute'] = $result['ShadowAttribute'];
|
||||
$result['Event']['RelatedEvent'] = $result['RelatedEvent'];
|
||||
|
||||
//
|
||||
// cleanup the array from things we do not want to expose
|
||||
//
|
||||
unset($result['Event']['user_id']);
|
||||
// hide the org field is we are not in showorg mode
|
||||
if ('true' != Configure::read('CyDefSIG.showorg') && !$isSiteAdmin) {
|
||||
unset($result['Event']['org']);
|
||||
unset($result['Event']['orgc']);
|
||||
unset($result['Event']['from']);
|
||||
}
|
||||
// remove value1 and value2 from the output and remove invalid utf8 characters for the xml parser
|
||||
foreach ($result['Event']['Attribute'] as $key => $value) {
|
||||
$result['Event']['Attribute'][$key]['value'] = preg_replace ('/[^\x{0009}\x{000a}\x{000d}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]+/u', ' ', $result['Event']['Attribute'][$key]['value']);
|
||||
unset($result['Event']['Attribute'][$key]['value1']);
|
||||
unset($result['Event']['Attribute'][$key]['value2']);
|
||||
unset($result['Event']['Attribute'][$key]['category_order']);
|
||||
}
|
||||
// remove invalid utf8 characters for the xml parser
|
||||
foreach($result['Event']['ShadowAttribute'] as $key => $value) {
|
||||
$result['Event']['ShadowAttribute'][$key]['value'] = preg_replace ('/[^\x{0009}\x{000a}\x{000d}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]+/u', ' ', $result['Event']['ShadowAttribute'][$key]['value']);
|
||||
}
|
||||
|
||||
if (isset($result['Event']['RelatedEvent'])) {
|
||||
foreach ($result['Event']['RelatedEvent'] as $key => $value) {
|
||||
unset($result['Event']['RelatedEvent'][$key]['user_id']);
|
||||
if ('true' != Configure::read('CyDefSIG.showorg') && !$isAdmin) {
|
||||
unset($result['Event']['RelatedEvent'][$key]['org']);
|
||||
unset($result['Event']['RelatedEvent'][$key]['orgc']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$xmlArray['response']['Event'][] = $result['Event'];
|
||||
}
|
||||
|
||||
$xmlObject = Xml::fromArray($xmlArray, array('format' => 'tags'));
|
||||
echo $xmlObject->asXML();
|
Loading…
Reference in New Issue