Merge branch '2.4' into issues_1643

pull/1809/head
devnull- 2017-04-27 10:04:32 +02:00 committed by GitHub
commit 9835b8932f
197 changed files with 3527 additions and 2277 deletions

View File

@ -48,7 +48,6 @@ sudo apt-get install libapache2-mod-php php php-cli php-crypt-gpg php-dev php-js
# Apply all changes
sudo systemctl restart apache2
3/ MISP code
------------
# Download MISP using git in the /var/www/ directory.
@ -77,7 +76,6 @@ cd /var/www/MISP/app/files/scripts/python-stix
sudo -u www-data git checkout v1.1.1.4
sudo python setup.py install
4/ CakePHP
-----------
# CakePHP is included as a submodule of MISP, execute the following commands to let git fetch it:

View File

@ -131,7 +131,7 @@ CREATE TABLE IF NOT EXISTS `events` (
`uuid` varchar(40) COLLATE utf8_bin NOT NULL,
`published` tinyint(1) NOT NULL DEFAULT 0,
`analysis` tinyint(4) NOT NULL,
`attribute_count` int(11) unsigned DEFAULT NULL,
`attribute_count` int(11) unsigned DEFAULT 0,
`orgc_id` int(11) NOT NULL,
`timestamp` int(11) NOT NULL DEFAULT 0,
`distribution` tinyint(4) NOT NULL DEFAULT 0,
@ -149,6 +149,18 @@ CREATE TABLE IF NOT EXISTS `events` (
INDEX `orgc_id` (`orgc_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE IF NOT EXISTS `event_blacklists` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`event_uuid` varchar(40) COLLATE utf8_bin NOT NULL,
`created` datetime NOT NULL,
`event_info` TEXT CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`comment` TEXT CHARACTER SET utf8 COLLATE utf8_unicode_ci,
`event_orgc` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`id`),
INDEX `event_uuid` (`event_uuid`),
INDEX `event_orgc` (`event_orgc`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
-- -------------------------------------------------------
--
@ -393,6 +405,17 @@ CREATE TABLE `organisations` (
FULLTEXT INDEX `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE IF NOT EXISTS `org_blacklists` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`org_uuid` varchar(40) COLLATE utf8_bin NOT NULL,
`created` datetime NOT NULL,
`org_name` varchar(255) COLLATE utf8_bin NOT NULL,
`comment` TEXT CHARACTER SET utf8 COLLATE utf8_unicode_ci,
PRIMARY KEY (`id`),
INDEX `org_uuid` (`org_uuid`),
INDEX `org_name` (`org_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
-- --------------------------------------------------------
--
@ -453,6 +476,7 @@ CREATE TABLE IF NOT EXISTS `roles` (
`perm_template` tinyint(1) NOT NULL DEFAULT 0,
`perm_sharing_group` tinyint(1) NOT NULL DEFAULT 0,
`perm_tag_editor` tinyint(1) NOT NULL DEFAULT 0,
`perm_sighting` tinyint(1) NOT NULL DEFAULT 0,
`default_role` tinyint(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
@ -700,7 +724,7 @@ CREATE TABLE IF NOT EXISTS `taxonomy_entries` (
`taxonomy_predicate_id` int(11) NOT NULL,
`value` text COLLATE utf8_bin NOT NULL,
`expanded` text COLLATE utf8_bin,
`colour` varchar(7) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`colour` varchar(7) CHARACTER SET utf8 COLLATE utf8_bin,
PRIMARY KEY (`id`),
INDEX `taxonomy_predicate_id` (`taxonomy_predicate_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
@ -716,7 +740,7 @@ CREATE TABLE IF NOT EXISTS `taxonomy_predicates` (
`taxonomy_id` int(11) NOT NULL,
`value` text COLLATE utf8_bin NOT NULL,
`expanded` text COLLATE utf8_bin,
`colour` varchar(7) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`colour` varchar(7) CHARACTER SET utf8 COLLATE utf8_bin,
PRIMARY KEY (`id`),
INDEX `taxonomy_id` (`taxonomy_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
@ -1001,23 +1025,23 @@ INSERT INTO `feeds` (`id`, `provider`, `name`, `url`, `distribution`, `default`,
-- 7. Read Only - read
--
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `default_role`)
VALUES (1, 'admin', NOW(), NOW(), 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0);
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `default_role`)
VALUES (1, 'admin', NOW(), NOW(), 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0);
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `default_role`)
VALUES (2, 'Org Admin', NOW(), NOW(), 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0);
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `default_role`)
VALUES (2, 'Org Admin', NOW(), NOW(), 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0);
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `default_role`)
VALUES (3, 'User', NOW(), NOW(), 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1);
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `default_role`)
VALUES (3, 'User', NOW(), NOW(), 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1);
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `default_role`)
VALUES (4, 'Publisher', NOW(), NOW(), 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0);
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `default_role`)
VALUES (4, 'Publisher', NOW(), NOW(), 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0);
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `default_role`)
VALUES (5, 'Sync user', NOW(), NOW(), 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0);
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `default_role`)
VALUES (5, 'Sync user', NOW(), NOW(), 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0);
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `default_role`)
VALUES (6, 'Read Only', NOW(), NOW(), 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0);
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `default_role`)
VALUES (6, 'Read Only', NOW(), NOW(), 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-- --------------------------------------------------------
@ -1141,3 +1165,7 @@ INSERT INTO `template_element_texts` (`id`, `name`, `template_element_id`, `text
(10, 'Other Network Activity', 33, 'If any other Network activity (such as an internet connection test) was detected during the analysis, please specify it using the following fields'),
(11, 'Persistence mechanism', 41, 'The following fields allow you to describe the persistence mechanism used by the malware'),
(12, 'Indicators', 45, 'Just paste your list of indicators based on type into the appropriate field. All of the fields are optional, so inputting a list of IP addresses into the Network indicator field for example is sufficient to complete this template.');
INSERT INTO `org_blacklists` (`org_uuid`, `created`, `org_name`, `comment`) VALUES
('58d38339-7b24-4386-b4b4-4c0f950d210f', NOW(), 'Setec Astrononomy', 'default example'),
('58d38326-eda8-443a-9fa8-4e12950d210f', NOW(), 'Acme Finance', 'default example');

View File

@ -207,3 +207,8 @@ INSERT INTO template_element_texts (id, name, template_element_id, text) VALUES
(11, 'Persistence mechanism', 41, 'The following fields allow you to describe the persistence mechanism used by the malware'),
(12, 'Indicators', 45, 'Just paste your list of indicators based on type into the appropriate field. All of the fields are optional, so inputting a list of IP addresses into the Network indicator field for example is sufficient to complete this template.');
SELECT SETVAL('template_element_texts_id_seq', (SELECT MAX(id) FROM template_element_texts));
INSERT INTO org_blacklists (id, org_uuid, created, org_name, comment) VALUES
(1, '58d38339-7b24-4386-b4b4-4c0f950d210f', NOW(), 'Setec Astrononomy', 'default example'),
(2, '58d38326-eda8-443a-9fa8-4e12950d210f', NOW(), 'Acme Finance', 'default example');
SELECT SETVAL('org_blacklists_id_seq', (SELECT MAX(id) FROM org_blacklists));

View File

@ -29,7 +29,7 @@ CREATE TABLE IF NOT EXISTS attributes (
timestamp bigint NOT NULL DEFAULT 0,
distribution smallint NOT NULL DEFAULT 0,
sharing_group_id bigint NOT NULL,
comment text NOT NULL,
comment text DEFAULT "",
deleted smallint NOT NULL DEFAULT 0,
PRIMARY KEY (id),
UNIQUE (uuid)

View File

@ -33,7 +33,7 @@ yum install vim
yum install gcc git httpd zip redis mysql-server python-devel python-pip libxslt-devel zlib-devel
# Install PHP 5.6 from SCL, see https://www.softwarecollections.org/en/scls/rhscl/rh-php56/
yum install rh-php56 rh-php56-php-fpm rh-php56-php-devel rh-php56-php-mysqlnd rh-php56-php-mbstring rh-php56-php-xml rh-php56-bcmath
yum install rh-php56 rh-php56-php-fpm rh-php56-php-devel rh-php56-php-mysqlnd rh-php56-php-mbstring rh-php56-php-xml rh-php56-php-bcmath
# rh-php56-php only provided mod_php for httpd24-httpd from SCL
# if we want to use httpd from CentOS base we can use rh-php56-php-fpm instead

2
PyMISP

@ -1 +1 @@
Subproject commit 4be491b7a0427ea214f0e06dc03184a5f4ed7b05
Subproject commit c74cdd19c638c624c6b5e1f9271319472579af8d

View File

@ -1 +1 @@
{"major":2, "minor":4, "hotfix":67}
{"major":2, "minor":4, "hotfix":72}

View File

@ -46,7 +46,8 @@ class EmailConfig {
// to set the return-path header, simply uncomment the line below and change you@localhost to the desired e-mail address
public $default = array(
'transport' => 'Mail',
'charset' => 'utf-8',
'charset' => 'utf-8',
'headers' => array('Precedence' => 'bulk'),
//'additionalParameters' => '-f you@localhost'
);

View File

@ -55,7 +55,7 @@ class EventShell extends AppShell
if (!empty($eventIds)) {
foreach ($eventIds as $k => $eventId) {
$temp = $this->Event->fetchEvent($user, array('eventid' => $eventId['Event']['id'], 'includeAttachments' => Configure::read('MISP.cached_attachments')));
$file->append($converter->event2XML($temp[0], $user['Role']['perm_site_admin']) . PHP_EOL);
$file->append($converter->convert($temp[0], $user['Role']['perm_site_admin']) . PHP_EOL);
$this->Job->saveField('progress', ($k+1) / $eventCount *100);
}
}
@ -88,7 +88,7 @@ class EventShell extends AppShell
$file->write('{"response":[');
foreach ($eventIds as $k => $eventId) {
$result = $this->Event->fetchEvent($user, array('eventid' => $eventId['Event']['id'], 'includeAttachments' => Configure::read('MISP.cached_attachments')));
$file->append($converter->event2JSON($result[0]));
$file->append($converter->convert($result[0]));
if ($k < count($eventIds) -1 ) $file->append(',');
$this->Job->saveField('progress', ($k+1) / $eventCount *100);
}

View File

@ -46,10 +46,10 @@ class AppController extends Controller {
public $helpers = array('Utility');
private $__jsVersion = '2.4.67';
public $pyMispVersion = '2.4.65';
private $__queryVersion = '9';
public $pyMispVersion = '2.4.71';
public $phpmin = '5.6.5';
public $phprec = '7.0.0';
public $phprec = '7.0.16';
// Used for _isAutomation(), a check that returns true if the controller & action combo matches an action that is a non-xml and non-json automation method
// This is used to allow authentication via headers for methods not covered by _isRest() - as that only checks for JSON and XML formats
@ -92,7 +92,7 @@ class AppController extends Controller {
throw new Exception('datasource not supported: ' . $dataSource);
}
$this->set('jsVersion', $this->__jsVersion);
$this->set('queryVersion', $this->__queryVersion);
$this->loadModel('User');
$auth_user_fields = $this->User->describeAuthFields();
@ -518,7 +518,7 @@ class AppController extends Controller {
$counter = 0;
// load this so we can remove the blacklist item that will be created, this is the one case when we do not want it.
if (Configure::read('MISP.enableEventBlacklisting')) $this->EventBlacklist = ClassRegistry::init('EventBlacklist');
if (Configure::read('MISP.enableEventBlacklisting') !== false) $this->EventBlacklist = ClassRegistry::init('EventBlacklist');
foreach ($duplicates as $duplicate) {
$events = $this->Event->find('all', array(
@ -532,7 +532,7 @@ class AppController extends Controller {
$counter++;
// remove the blacklist entry that we just created with the event deletion, if the feature is enabled
// We do not want to block the UUID, since we just deleted a copy
if (Configure::read('MISP.enableEventBlacklisting')) {
if (Configure::read('MISP.enableEventBlacklisting') !== false) {
$this->EventBlacklist->deleteAll(array('EventBlacklist.event_uuid' => $uuid));
}
}

View File

@ -73,10 +73,28 @@ class AttributesController extends AppController {
$this->set('categoryDefinitions', $this->Attribute->categoryDefinitions);
}
public function add($eventId = null) {
public function add($eventId) {
if (!$this->userRole['perm_add']) {
throw new MethodNotAllowedException('You don\'t have permissions to create attributes');
}
$this->loadModel('Event');
if (Validation::uuid($eventId)) {
$temp = $this->Event->find('first', array('recursive' => -1, 'fields' => array('Event.id'), 'conditions' => array('Event.uuid' => $eventId)));
if (empty($temp)) throw new NotFoundException('Invalid event');
$eventId = $temp['Event']['id'];
} else if (!is_numeric($eventId)) {
throw new NotFoundException(__('Invalid event'));
}
$this->Event->id = $eventId;
if (!$this->Event->exists()) {
throw new NotFoundException(__('Invalid event'));
}
// remove the published flag from the event
$this->Event->recursive = -1;
$this->Event->read(null, $eventId);
if (!$this->_isSiteAdmin() && ($this->Event->data['Event']['orgc_id'] != $this->_checkOrg() || !$this->userRole['perm_modify'])) {
throw new UnauthorizedException('You do not have permission to do that.');
}
if ($this->request->is('ajax')) {
$this->set('ajax', true);
$this->layout = 'ajax';
@ -85,174 +103,135 @@ class AttributesController extends AppController {
}
if ($this->request->is('post')) {
if ($this->request->is('ajax')) $this->autoRender = false;
$this->loadModel('Event');
$date = new DateTime();
// remove the published flag from the event
$this->Event->recursive = -1;
if (isset($eventId)) {
$this->Event->read(null, $eventId);
$this->request->data['Attribute']['event_id'] = $eventId;
} else $this->Event->read(null, $this->request->data['Attribute']['event_id']);
if (!$this->_isSiteAdmin() && ($this->Event->data['Event']['orgc_id'] != $this->_checkOrg() || !$this->userRole['perm_modify'])) {
throw new UnauthorizedException('You do not have permission to do that.');
if (!isset($this->request->data['Attribute'])) {
$this->request->data = array('Attribute' => $this->request->data);
}
$this->Event->set('timestamp', $date->getTimestamp());
$this->Event->set('published', 0);
$this->Event->save($this->Event->data, array('fieldList' => array('published', 'timestamp', 'info')));
if (isset($this->request->data['Attribute']['id'])) unset($this->request->data['Attribute']['id']);
//
// multiple attributes in batch import
//
if ((isset($this->request->data['Attribute']['batch_import']) && $this->request->data['Attribute']['batch_import'] == 1) || is_array($this->request->data['Attribute']['value'])) {
// make array from value field
$attributes = array();
if (!empty($this->request->data['Attribute']['batch_import']) || (!empty($this->request->data['Attribute']['value']) && is_array($this->request->data['Attribute']['value']))) {
$attributes = array();
if (is_array($this->request->data['Attribute']['value'])) {
$attributes = $this->request->data['Attribute']['value'];
$values = $this->request->data['Attribute']['value'];
} else {
$attributes = explode("\n", $this->request->data['Attribute']['value']);
$values = explode("\n", $this->request->data['Attribute']['value']);
}
$fails = ""; // will be used to keep a list of the lines that failed or succeeded
$successes = "";
$failCount = 0;
$successCount = 0;
// TODO loopholes,
// the value null value thing
$validationErrors = array();
foreach ($attributes as $key => $attribute) {
$attribute = trim($attribute);
if (strlen($attribute) == 0)
continue; // don't do anything for empty lines
$this->Attribute->create();
$this->request->data['Attribute']['value'] = $attribute; // set the value as the content of the single line
// TODO loopholes,
// there seems to be a loophole in MISP here
// be it an create and not an update
$this->Attribute->id = null;
if ($this->Attribute->save($this->request->data)) {
$successes .= " " . ($key + 1);
$successCount++;
foreach ($values as $value) {
$this->request->data['Attribute']['value'] = $value;
$attributes[] = $this->request->data['Attribute'];
}
} else {
$attributes = $this->request->data['Attribute'];
}
if (!isset($attributes[0])) {
$attributes = array(0 => $attributes);
}
$uuids = array();
foreach ($attributes as $k => $attribute) {
if (isset($attribute['id'])) {
unset($attribute['id']);
}
$attributes[$k]['event_id'] = $eventId;
if (isset($attribute['uuid'])) {
$uuids[$k] = $attribute['uuid'];
if (!isset($attribute['timestamp'])) {
$attributes[$k]['timestamp'] = $date->getTimestamp();
}
if (isset($attribute['base64'])) {
$attributes[$k]['data'] = $attribute['base64'];
}
}
if (isset($attribute['type']) && !isset($attribute['category'])) {
$attributes[$k]['category'] = $this->Attribute->typeDefinitions[$attribute['type']]['default_category'];
}
if (!isset($attribute['to_ids'])) {
$attributes[$k]['to_ids'] = $this->Attribute->typeDefinitions[$attribute['type']]['to_ids'];
}
}
$fails = array();
$successes = array();
$attributeCount = count($attributes);
if (!empty($uuids)) {
$existingAttributes = $this->Attribute->find('list', array(
'recursive' => -1,
'fields' => array('Attribute.uuid'),
'conditions' => array('Attribute.uuid' => array_values($uuids))
));
if (!empty($existingAttributes)) {
foreach ($uuids as $k => $uuid) {
if (in_array($uuid, $existingAttributes)) {
unset($attributes[$k]);
$fails["attribute_$k"] = array('uuid' => array('An attribute with this uuid already exists.'));
unset($uuids[$k]);
}
}
}
}
foreach ($attributes as $k => $attribute) {
$this->Attribute->create();
$result = $this->Attribute->save($attribute);
if (!$result) {
$fails["attribute_$k"] = $this->Attribute->validationErrors;
} else {
$successes[$k] = $this->Attribute->id;
}
}
if (!empty($successes)) {
$this->Event->set('timestamp', $date->getTimestamp());
$this->Event->set('published', 0);
$this->Event->save($this->Event->data, array('fieldList' => array('published', 'timestamp', 'info')));
}
if ($this->_isRest()) {
if (!empty($successes)) {
$attributes = $this->Attribute->find('all', array(
'recursive' => -1,
'conditions' => array('Attribute.id' => array_values($successes))
));
if (count($attributes) == 1) {
$attributes = $attributes[0];
}
return $this->RestResponse->viewData($attributes, $this->response->type(), $fails);
} else {
if ($attributeCount == 1) {
return $this->RestResponse->saveFailResponse('Attributes', 'add', false, $fails["attribute_0"], $this->response->type());
} else {
$fails .= " " . ($key + 1);
$failCount++;
$validationErrors[] = array($attribute => $this->Attribute->validationErrors);
return $this->RestResponse->saveFailResponse('Attributes', 'add', false, $fails, $this->response->type());
}
}
} else {
$message = '';
$redirect = '/events/view/' . $eventId;
if (empty($fails)) {
$message = 'Attributes saved.';
} else {
if (count($attributes) > 1) {
$failKeys = array_keys($fails);
foreach ($failKeys as $k => $v) {
$failKeys[$k] = intval($v) + 1;
}
$message = 'Attributes saved, however, attributes ' . implode(', ', $failKeys) . ' could not be saved.';
} else {
$message = 'Attribute could not be saved.';
}
}
if ($this->request->is('ajax')) {
$this->autoRender = false;
if ($fails) {
$error_message = 'The lines' . $fails . ' could not be saved. Please, try again.';
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'errors' => $error_message)), 'status' => 200));
$errors = ($attributeCount > 1) ? $message : $this->Attribute->validationErrors;
if (!empty($successes)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => $message)),'status' => 200));
} else {
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => $successCount . ' Attributes added')), 'status' => 200));
}
} else if ($this->_isRest()) {
$name = 'Attribute(s) could not be added.';
$message = 'Could not save any of the POSTed attributes. Check errors field to see what caused the failures.';
if ($successCount) {
$name = 'Attribute(s) added.';
$message = $successCount . ' attribute(s) successfuly added.';
if ($failCount) {
$name = 'Only a subset of the attributes could be added.';
$message = $successCount . ' attribute(s) added, but ' . $failCount . ' of them failed the validation. Check the errors field for more details.';
}
}
$this->set('name', $name);
$this->set('message', $message);
$this->set('errors', $validationErrors);
$this->set('url', '/attributes/add/' . $eventId);
$this->set('_serialize', array('name', 'message', 'url', 'errors'));
return false;
} else {
// we added all the attributes
if ($fails) {
// list the ones that failed
if (!CakeSession::read('Message.flash')) {
$this->Session->setFlash(__('The lines' . $fails . ' could not be saved. Please, try again.', true), 'default', array(), 'error');
} else {
$existingFlash = CakeSession::read('Message.flash');
$this->Session->setFlash(__('The lines' . $fails . ' could not be saved. ' . $existingFlash['message'], true), 'default', array(), 'error');
}
}
if ($successes) {
// list the ones that succeeded
$this->Session->setFlash(__('The lines' . $successes . ' have been saved', true));
}
$this->redirect(array('controller' => 'events', 'action' => 'view', $this->request->data['Attribute']['event_id']));
}
} else {
if (isset($this->request->data['Attribute']['uuid'])) { // TODO here we should start RESTful dialog
// check if the uuid already exists and also save the existing attribute for further checks
$existingAttribute = null;
$existingAttribute = $this->Attribute->find('first', array('conditions' => array('Attribute.uuid' => $this->request->data['Attribute']['uuid'])));
if ($existingAttribute) {
// TODO RESTful, set response location header so client can find right URL to edit
$this->response->header('Location', Configure::read('MISP.baseurl') . '/attributes/' . $existingAttribute['Attribute']['id']);
$this->response->send();
throw new NotFoundException('Attribute already exists, if you would like to edit it, use the url in the location header.');
} else {
// if the attribute doesn't exist yet, check whether it has a timestamp - if yes, it's from a push, keep the timestamp we had, if no create a timestamp
if (!isset($this->request->data['Attribute']['timestamp'])) {
$this->request->data['Attribute']['timestamp'] = $date->getTimestamp();
}
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => $errors)),'status' => 200));
}
} else {
if (!isset($this->request->data['Attribute']['timestamp'])) {
$this->request->data['Attribute']['timestamp'] = $date->getTimestamp();
}
}
if (isset($this->request->data['Attribute']['base64'])) $this->request->data['Attribute']['data'] = $this->request->data['Attribute']['base64'];
//
// single attribute
//
// create the attribute
$this->Attribute->create();
if ($this->Attribute->save($this->request->data)) {
if ($this->_isRest() || $this->response->type() === 'application/json') {
$saved_attribute = $this->Attribute->find('first', array(
'conditions' => array('id' => $this->Attribute->id),
'recursive' => -1,
'fields' => array('id', 'type', 'to_ids', 'category', 'uuid', 'event_id', 'distribution', 'timestamp', 'comment', 'value'),
));
$response = array('response' => array('Attribute' => $saved_attribute['Attribute']));
$this->set('response', $response);
if ($this->response->type() === 'application/json') $this->render('/Attributes/json/view');
else $this->render('view');
return false;
} else if ($this->request->is('ajax')) {
$this->autoRender = false;
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => 'Attribute added.')),'status'=>200));
} else {
// inform the user and redirect
$this->Session->setFlash(__('The attribute has been saved'));
$this->redirect(array('controller' => 'events', 'action' => 'view', $this->request->data['Attribute']['event_id']));
}
} else {
if ($this->_isRest()) { // TODO return error if REST
// REST users want to see the failed attribute
$message = '';
foreach ($this->Attribute->validationErrors as $k => $v) {
$message .= '[' . $k . ']: ' . $v[0] . PHP_EOL;
}
throw new NotFoundException('Could not save the attribute. ' . $message);
} else if ($this->request->is('ajax')) {
$this->autoRender = false;
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => $this->Attribute->validationErrors)),'status'=>200));
} else {
if (!CakeSession::read('Message.flash')) {
$this->Session->setFlash(__('The attribute could not be saved. Please, try again.'));
}
$this->Session->setFlash($message);
if (count($successes) > 0) {
$this->redirect(array('controller' => 'events', 'action' => 'view', $eventId));
}
}
}
} else {
// set the event_id in the form
$this->request->data['Attribute']['event_id'] = $eventId;
}
// combobox for types
$types = array_keys($this->Attribute->typeDefinitions);
foreach ($types as $key => $value) {
@ -648,7 +627,7 @@ class AttributesController extends AppController {
if ($temp == null) throw new NotFoundException('Invalid attribute');
$id = $temp['Attribute']['id'];
} else if (!is_numeric($id)) {
throw new NotFoundException(__('Invalid event id.'));
throw new NotFoundException(__('Invalid attribute'));
}
$this->Attribute->id = $id;
$date = new DateTime();
@ -680,7 +659,7 @@ class AttributesController extends AppController {
}
if ($this->request->is('post') || $this->request->is('put')) {
if (!isset($this->request->data['Attribute'])) {
$this->request->data['Attribute'] = $this->request->data;
$this->request->data = array('Attribute' => $this->request->data);
}
$existingAttribute = $this->Attribute->findByUuid($this->Attribute->data['Attribute']['uuid']);
// check if the attribute has a timestamp already set (from a previous instance that is trying to edit via synchronisation)
@ -851,7 +830,7 @@ class AttributesController extends AppController {
$event['Event']['published'] = 0;
$this->Attribute->Event->save($event, array('fieldList' => array('published', 'timestamp', 'info')));
$this->autoRender = false;
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => 'Field updated.')),'status'=>200));
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => 'Field updated.', 'check_publish' => true)),'status'=>200));
} else {
$this->autoRender = false;
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => $this->Attribute->validationErrors)),'status'=>200));
@ -881,7 +860,15 @@ class AttributesController extends AppController {
}
}
public function delete($id = null, $hard = false) {
public function delete($id, $hard = false) {
if (Validation::uuid($id)) {
$this->Attribute->recursive = -1;
$temp = $this->Attribute->findByUuid($id);
if ($temp == null) throw new NotFoundException('Invalid attribute');
$id = $temp['Attribute']['id'];
} else if (!is_numeric($id)) {
throw new NotFoundException('Invalid attribute');
}
$this->set('id', $id);
$conditions = array('id' => $id);
if (!$hard) $conditions['deleted'] = 0;
@ -1654,6 +1641,8 @@ 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
@ -1666,14 +1655,14 @@ class AttributesController extends AppController {
foreach ($simpleFalse as $sF) {
if (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false') ${$sF} = false;
}
if ($key != null && $key != 'download') {
if ($key != null && strlen($key) == 40) {
$user = $this->checkAuthUser($key);
if (!$user) {
throw new UnauthorizedException('This authentication key is not authorized to be used for exports. Contact your administrator.');
}
} else {
$key = strtolower($key);
if (!$this->Auth->user()) throw new UnauthorizedException('You are not authorized. Please send the Authorization header with your auth key along with an Accept header for application/xml.');
$user = $this->checkAuthUser($this->Auth->user('authkey'));
}
if (!$user) {
throw new UnauthorizedException('This authentication key is not authorized to be used for exports. Contact your administrator.');
}
// request handler for POSTed queries. If the request is a post, the parameters (apart from the key) will be ignored and replaced by the terms defined in the posted json or xml object.
// The correct format for both is a "request" root element, as shown by the examples below:
@ -1682,8 +1671,14 @@ class AttributesController extends AppController {
// the response type is used to determine the parsing method (xml/json)
if ($this->request->is('post')) {
if ($this->response->type() === 'application/json') {
if ($key == 'xml') {
throw new MethodNotAllowedException('Content type and parameter mismatch. Expecting JSON.');
}
$data = $this->request->input('json_decode', true);
} else if ($this->response->type() === 'application/xml' && !empty($this->request->data)) {
if ($key == 'json') {
throw new MethodNotAllowedException('Content type and parameter mismatch. Expecting XML.');
}
$data = $this->request->data;
} else {
throw new BadRequestException('Either specify the search terms in the url, or POST a json array / xml (with the root element being "request" and specify the correct accept and content type headers.');
@ -1705,116 +1700,26 @@ class AttributesController extends AppController {
if ($from) $from = $this->Attribute->Event->dateFieldCheck($from);
if ($to) $to = $this->Attribute->Event->dateFieldCheck($to);
if ($last) $last = $this->Attribute->Event->resolveTimeDelta($last);
if (!isset($this->request->params['ext']) || $this->request->params['ext'] !== 'json') {
$this->response->type('xml'); // set the content type
$this->layout = 'xml/default';
$this->header('Content-Disposition: download; filename="misp.search.attribute.results.xml"');
} else {
$this->response->type('json'); // set the content type
$this->layout = 'json/default';
$this->header('Content-Disposition: download; filename="misp.search.attribute.results.json"');
}
$conditions['AND'] = array();
$subcondition = array();
$this->loadModel('Attribute');
// add the values as specified in the 2nd parameter to the conditions
$parameters = array('value', 'type', 'category', 'org', 'eventid', 'uuid');
foreach ($parameters as $k => $param) {
if (isset(${$parameters[$k]}) && ${$parameters[$k]}!==false) {
if (is_array(${$parameters[$k]})) $elements = ${$parameters[$k]};
else $elements = explode('&&', ${$parameters[$k]});
foreach ($elements as $v) {
if (empty($v)) continue;
if (substr($v, 0, 1) == '!') {
// check for an IPv4 address and subnet in CIDR notation (e.g. 127.0.0.1/8)
if ($parameters[$k] === 'value' && $this->Cidr->checkCIDR(substr($v, 1), 4)) {
$cidrresults = $this->Cidr->CIDR(substr($v, 1));
foreach ($cidrresults as $result) {
$subcondition['AND'][] = array('Attribute.value NOT LIKE' => $result);
}
} else if ($parameters[$k] === 'org') {
// from here
$found_orgs = $this->Attribute->Event->Org->find('all', array(
'recursive' => -1,
'conditions' => array('LOWER(name) LIKE' => '%' . strtolower(substr($v, 1)) . '%'),
));
foreach ($found_orgs as $o) $subcondition['AND'][] = array('Event.orgc_id !=' => $o['Org']['id']);
} else if ($parameters[$k] === 'eventid') {
$subcondition['AND'][] = array('Attribute.event_id !=' => substr($v, 1));
} else if ($parameters[$k] === 'uuid') {
$subcondition['AND'][] = array('Event.uuid !=' => substr($v, 1));
$subcondition['AND'][] = array('Attribute.uuid !=' => substr($v, 1));
} else {
$subcondition['AND'][] = array('Attribute.' . $parameters[$k] . ' NOT LIKE' => '%'.substr($v, 1).'%');
}
} else {
// check for an IPv4 address and subnet in CIDR notation (e.g. 127.0.0.1/8)
if ($parameters[$k] === 'value' && $this->Cidr->checkCIDR($v, 4)) {
$cidrresults = $this->Cidr->CIDR($v);
foreach ($cidrresults as $result) {
$subcondition['OR'][] = array('Attribute.value LIKE' => $result);
}
} else if ($parameters[$k] === 'org') {
// from here
$found_orgs = $this->Attribute->Event->Org->find('all', array(
'recursive' => -1,
'conditions' => array('LOWER(name) LIKE' => '%' . strtolower($v) . '%'),
));
foreach ($found_orgs as $o) $subcondition['OR'][] = array('Event.orgc_id' => $o['Org']['id']);
} else if ($parameters[$k] === 'eventid') {
if (!empty($v)) $subcondition['OR'][] = array('Attribute.event_id' => $v);
} else if ($parameters[$k] === 'uuid') {
$subcondition['OR'][] = array('Attribute.uuid' => $v);
$subcondition['OR'][] = array('Event.uuid' => $v);
} else {
if (!empty($v)) $subcondition['OR'][] = array('Attribute.' . $parameters[$k] . ' LIKE' => '%'.$v.'%');
}
}
}
array_push ($conditions['AND'], $subcondition);
$subcondition = array();
if (isset(${$parameters[$k]}) && ${$parameters[$k]} !== false) {
$conditions = $this->Attribute->setSimpleConditions($parameters[$k], ${$parameters[$k]}, $conditions);
}
}
// If we sent any tags along, load the associated tag names for each attribute
if ($tags) {
$args = $this->Attribute->dissectArgs($tags);
$this->loadModel('Tag');
$tagArray = $this->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;
}
if ($tags) $conditions = $this->Attribute->setTagConditions($tags, $conditions);
if ($from) $conditions['AND'][] = array('Event.date >=' => $from);
if ($to) $conditions['AND'][] = array('Event.date <=' => $to);
if ($publish_timestamp) {
if (is_array($publish_timestamp)) {
$conditions['AND'][] = array('Event.publish_timestamp >=' => $publish_timestamp[0]);
$conditions['AND'][] = array('Event.publish_timestamp <=' => $publish_timestamp[1]);
} else {
$conditions['AND'][] = array('Event.publish_timestamp >=' => $publish_timestamp);
}
}
if ($publish_timestamp) $conditions = $this->Attribute->setPublishTimestampConditions($publish_timestamp, $conditions);
if ($last) $conditions['AND'][] = array('Event.publish_timestamp >=' => $last);
if ($published) $conditions['AND'][] = array('Event.published' => $published);
if ($timestamp) $conditions['AND'][] = array('Attribute.timestamp >=' => $timestamp);
if ($to_ids) {
if ($to_ids === 'exclude') {
$conditions['AND'][] = array('Attribute.to_ids' => 0);
} else {
$conditions['AND'][] = array('Attribute.to_ids' => 1);
}
}
if ($to_ids) $conditions = $this->Attribute->setToIDSConditions($to_ids, $conditions);
// 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,
@ -1831,8 +1736,29 @@ class AttributesController extends AppController {
$results = $this->Attribute->fetchAttributes($this->Auth->user(), $params);
$this->loadModel('Whitelist');
$results = $this->Whitelist->removeWhitelistedFromArray($results, true);
if (empty($results)) throw new NotFoundException('No matches.');
$this->set('results', $results);
if ($key == 'openioc') {
App::uses('IOCExportTool', 'Tools');
$this->IOCExport = new IOCExportTool();
$results = $this->IOCExport->buildAll($this->Auth->user(), $results, 'attribute');
} else {
if (!empty($results)) {
$results = array('response' => array('Attribute' => $results));
foreach ($results['response']['Attribute'] as $k => $v) {
$results['response']['Attribute'][$k] = $results['response']['Attribute'][$k]['Attribute'];
unset(
$results['response']['Attribute'][$k]['value1'],
$results['response']['Attribute'][$k]['value2']
);
}
} else {
$results = array('response' => array());
}
}
$responseType = $this->response->type();
if ($key == 'openioc') {
$responseType = 'openioc';
}
return $this->RestResponse->viewData($results, $responseType);
}
// 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.
@ -2228,7 +2154,11 @@ class AttributesController extends AppController {
}
}
$this->layout = 'ajax';
if ($field == 'distribution') $this->set('distributionLevels', $this->Attribute->shortDist);
if ($field == 'distribution') {
$distributionLevels = $this->Attribute->shortDist;
unset($distributionLevels[4]);
$this->set('distributionLevels', $distributionLevels);
}
if ($field == 'category') {
$typeCategory = array();
foreach ($this->Attribute->categoryDefinitions as $k => $category) {
@ -2850,8 +2780,7 @@ class AttributesController extends AppController {
if ($this->_isRest()) {
return $this->RestResponse->saveSuccessResponse('attributes', 'toggleCorrelation', $id, false, 'Correlation ' . ($attribute['Attribute']['disable_correlation'] ? 'disabled' : 'enabled') . '.');
} else {
$this->Session->setFlash('Correlation ' . ($attribute['Attribute']['disable_correlation'] ? 'disabled' : 'enabled') . '.');
$this->redirect(array('controller' => 'events', 'action' => 'view', $attribute['Event']['id']));
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => ('Correlation ' . ($attribute['Attribute']['disable_correlation'] ? 'disabled' : 'enabled')), 'check_publish' => true)),'status'=>200));
}
} else {
$this->set('attribute', $attribute);

View File

@ -118,7 +118,7 @@ class ACLComponent extends Component {
'strposarray' => array(),
'toggleCorrelation' => array('perm_add'),
'updateGraph' => array('*'),
'upload_sample' => array('perm_auth'),
'upload_sample' => array('AND' => array('perm_auth', 'perm_add')),
'view' => array('*'),
'viewEventAttributes' => array('*'),
'viewGraph' => array('*'),
@ -241,11 +241,12 @@ class ACLComponent extends Component {
'getPyMISPVersion' => array('*'),
'getVersion' => array('*'),
'index' => array('OR' => array('perm_sync', 'perm_admin')),
'postTest' => array('perm_sync'),
'previewEvent' => array(),
'previewIndex' => array(),
'pull' => array('perm_auth'),
'pull' => array(),
'purgeSessions' => array(),
'push' => array('perm_auth'),
'push' => array(),
'restartWorkers' => array(),
'serverSettings' => array(),
'serverSettingsEdit' => array(),

View File

@ -1,112 +1,6 @@
<?php
class IOCExportComponent extends Component {
private $final = array();
public function buildAll($user, $event) {
$this->__buildTop($event);
foreach ($event['Attribute'] as $attribute) {
$this->__buildAttribute($attribute);
}
$this->__buildBottom();
return $this->final;
}
// Builds the top with the event information
private function __buildTop($event) {
// We will start adding all the components that will be in the xml file here
$this->final[] = '<?xml version="1.0" encoding="utf-8"?>';
$this->final[] = '<ioc xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" id="' . $event['Event']['uuid'] . '" last-modified="' . $event['Event']['date'] . 'T00:00:00" xmlns="http://schemas.mandiant.com/2010/ioc">';
$this->final[] = ' <short_description>Event #' . h($event['Event']['id']) . '</short_description>';
$this->final[] = ' <description>' . h($event['Event']['info']) . '</description>';
$this->final[] = ' <keywords />';
$this->final[] = ' <authored_by>' . h($event['Orgc']['name']) . '</authored_by>';
$this->final[] = ' <authored_date>' . h($event['Event']['date']) . 'T00:00:00</authored_date>';
$this->final[] = ' <links />';
$this->final[] = ' <definition>';
// for now, since we don't have any logical links between attributes, we'll OR all of them
$this->final[] = ' <Indicator operator="OR" id="' . h($event['Event']['uuid']) . '">';
}
public $mapping = array(
'composite' => array(
'regkey|value' => array(array('Network', 'RegistryItem/KeyPath', 'string'), array('Network', 'RegistryItem/Value', 'string')),
'filename|md5' => array(array('FileItem', 'FileItem/FileName', 'string'), array('FileItem', 'FileItem/Md5sum', 'md5')),
'filename|sha1' => array(array('FileItem', 'FileItem/FileName', 'string'), array('FileItem', 'FileItem/Sha1sum', 'sha1')),
'filename|sha256' => array(array('FileItem', 'FileItem/FileName', 'string'), array('FileItem', 'FileItem/Sha256sum', 'sha256')),
'malware-sample' => array(array('FileItem', 'FileItem/FileName', 'string'), array('FileItem', 'FileItem/Md5sum', 'md5')),
'domain|ip' => array(array('Network', 'Network/DNS', 'string'), array('PortItem', 'PortItem/remoteIP', 'IP')),
),
'simple' => array(
'md5' => array('FileItem', 'FileItem/Md5sum', 'md5'),
'sha1' => array('FileItem', 'FileItem/Sha1sum', 'sha1'),
'sha256' => array('FileItem', 'FileItem/Sha256sum', 'sha256'),
'filename' => array('FileItem', 'FileItem/FileName', 'string'),
'ip-src' => array('PortItem', 'PortItem/remoteIP', 'IP'),
'ip-dst' => array('RouteEntryItem', 'RouteEntryItem/Destination', 'IP'),
'hostname' => array('RouteEntryItem', 'RouteEntryItem/Destination', 'string'),
'email-src' => array('Email', 'Email/From', 'string'),
'email-dst' => array('Email', 'Email/To', 'string'),
'email-subject' => array('Email', 'Email/Subject', 'string'),
'email-attachment' => array('Email', 'Email/Attachment/Name', 'string'),
'domain' => array('Network', 'Network/DNS', 'string'),
'url' => array('UrlHistoryItem', 'UrlHistoryItem/URL', 'string'),
'user-agent' => array('Network', 'Network/UserAgent', 'string'),
'regkey' => array('Network', 'RegistryItem/KeyPath', 'string'),
'snort' => array('Snort', 'Snort/Snort', 'string'),
'attachment' => array('FileItem', 'FileItem/FileName', 'string'),
'link' => array('URL', 'UrlHistoryItem/URL', 'md5')
)
);
private function __frameComposite($attribute) {
$values = explode('|', $attribute['value']);
$this->final[] = ' <Indicator operator="AND" id="' . h($attribute['uuid']) . '">';
$this->__frameIndicator($this->mapping['composite'][$attribute['type']][0], $attribute['uuid'], $values[0], true);
$this->__frameIndicator($this->mapping['composite'][$attribute['type']][1], $attribute['uuid'], $values[1], true);
$this->final[] = ' </Indicator>';
}
private function __frameIndicator($mapping, $uuid, $value, $extraIndent = false) {
$padding = 6;
if ($extraIndent) {
$padding = 8;
}
$this->final[] = str_repeat(' ', $padding) . '<IndicatorItem id="' . h($uuid) . '" condition="is">';
$this->final[] = str_repeat(' ', ($padding + 2)) . '<Context document="' . $mapping[0] . '" search="' . $mapping[1] . '" type="mir" />';
$this->final[] = str_repeat(' ', ($padding + 2)) . '<Content type="' . $mapping[2] . '">' . h($value) . '</Content>';
$this->final[] = str_repeat(' ', $padding) . '</IndicatorItem>';
}
// This method will turn each eligible attribute into an indicator
private function __buildAttribute($attribute) {
// Hop over attributes that don't have the to ids flag turned on and check whether the attribute is sent for IOC export based on category/type
if (!$this->__checkValidTypeForIOC($attribute) || $attribute['to_ids'] == 0) return;
if ($attribute['type'] == 'malware-sample') $attribute['type'] = 'filename|md5';
if (strpos($attribute['type'], '|')) {
if ($this->mapping['composite'][$attribute['type']]) {
$this->__frameComposite($attribute);
}
} else {
if (isset($this->mapping['simple'][$attribute['type']])) {
$this->__frameIndicator($this->mapping['simple'][$attribute['type']], $attribute['uuid'], $attribute['value'], false);
}
}
}
// Just closing some tags at the bottom of the .ioc file
private function __buildBottom() {
$this->final[] = ' </Indicator>';
$this->final[] = ' </definition>';
$this->final[] = '</ioc>';
}
// Simple check for valid categories and types for IOC generation
private function __checkValidTypeForIOC($attribute) {
// categories that should be included
$Category = array('Payload delivery', 'Artifacts dropped', 'Payload installation', 'Persistence mechanism', 'Network activity');
if (!in_array($attribute['category'], $Category)) return false;
return true;
}
// removed in favour of th IOCExportTool
// File used as a placeholder to avoid model caching issues
}

View File

@ -29,6 +29,17 @@ class RestResponseComponent extends Component {
'mandatory' => array('name'),
'optional' => array('anonymise', 'description', 'type', 'nationality', 'sector', 'uuid', 'contacts', 'local')
)
),
'Server' => array(
'add' => array(
'description' => "POST an Server object in JSON format to this API to add a server.",
'mandatory' => array('url', 'name', 'organisation_type', 'authkey', 'json'),
'optional' => array('push', 'pull', 'push_rules', 'pul_rules', 'submitted_cert', 'submitted_client_cert')
),
'edit' => array(
'description' => "POST an Server object in JSON format to this API to edit a server.",
'optional' => array('url', 'name', 'organisation_type', 'authkey', 'json', 'push', 'pull', 'push_rules', 'pul_rules', 'submitted_cert', 'submitted_client_cert')
)
)
);
@ -54,12 +65,14 @@ class RestResponseComponent extends Component {
return $this->__sendResponse($response, 200, $format);
}
private function __sendResponse($response, $code, $format = false) {
private function __sendResponse($response, $code, $format = false, $raw = false) {
if (strtolower($format) === 'application/xml') {
$response = Xml::build($response);
if (!$raw) $response = Xml::build($response);
$type = 'xml';
} else if(strtolower($format) == 'openioc') {
$type = 'xml';
} else {
$response = json_encode($response, JSON_PRETTY_PRINT);
if (!$raw) $response = json_encode($response, JSON_PRETTY_PRINT);
$type = 'json';
}
return new CakeResponse(array('body'=> $response,'status' => $code, 'type' => $type));
@ -78,8 +91,11 @@ class RestResponseComponent extends Component {
return array('action' => $action, 'admin' => $admin);
}
public function viewData($data, $format = false) {
return $this->__sendResponse($data, 200, $format);
public function viewData($data, $format = false, $errors = false, $raw = false) {
if (!empty($errors)) {
$data['errors'] = $errors;
}
return $this->__sendResponse($data, 200, $format, $raw);
}
public function describe($controller, $action, $id = false, $format = false) {

View File

@ -7,7 +7,7 @@ class EventBlacklistsController extends AppController {
public function beforeFilter() {
parent::beforeFilter();
if (!$this->_isSiteAdmin()) $this->redirect('/');
if (!Configure::read('MISP.enableEventBlacklisting')) {
if (false === Configure::read('MISP.enableEventBlacklisting')) {
$this->Session->setFlash(__('Event Blacklisting is not currently enabled on this instance.'));
$this->redirect('/');
}

View File

@ -84,7 +84,7 @@ class EventDelegationsController extends AppController {
$delegation = $this->EventDelegation->find('first', array(
'conditions' => array('EventDelegation.id' => $id),
'recursive' => -1,
'contain' => array('Org', 'Event'),
'contain' => array('Org', 'Event', 'RequesterOrg'),
));
if (empty($delegation) || (!$this->_isSiteAdmin() && $this->Auth->user('org_id') != $delegation['EventDelegation']['org_id'])) throw new MethodNotAllowedException('You are not authorised to do that.');
if ($this->request->is('post')) {
@ -129,13 +129,13 @@ class EventDelegationsController extends AppController {
$delegation = $this->EventDelegation->find('first', array(
'conditions' => array('EventDelegation.id' => $id),
'recursive' => -1,
'contain' => array('Org', 'Event'),
'contain' => array('Org', 'Event', 'RequesterOrg'),
));
if (empty($delegation) || (!$this->_isSiteAdmin() && !in_array($this->Auth->user('org_id'), array($delegation['EventDelegation']['requester_org_id'], $delegation['EventDelegation']['org_id'])))) throw new MethodNotAllowedException('You are not authorised to do that.');
if ($this->request->is('post')) {
$this->EventDelegation->delete($delegation['EventDelegation']['id']);
$this->Session->setFlash('Delegation request deleted.');
$this->redirect(array('controller' => 'events', 'action' => 'view', $delegation['EventDelegation']['event_id']));
$this->redirect(array('controller' => 'events', 'action' => 'index'));
} else {
$this->set('delegationRequest', $delegation);
$this->render('ajax/delete_delegation');

View File

@ -8,7 +8,6 @@ class EventsController extends AppController {
'Security',
'Email',
'RequestHandler',
'IOCExport',
'IOCImport',
'Cidr'
);
@ -256,7 +255,7 @@ class EventsController extends AppController {
// list the events
$passedArgsArray = array();
$urlparams = "";
$overrideAbleParams = array('all', 'attribute', 'published', 'eventid', 'Datefrom', 'Dateuntil', 'org', 'eventinfo', 'tag', 'distribution', 'analysis', 'threatlevel', 'email', 'hasproposal', 'timestamp', 'publishtimestamp');
$overrideAbleParams = array('all', 'attribute', 'published', 'eventid', 'Datefrom', 'Dateuntil', 'org', 'eventinfo', 'tag', 'distribution', 'analysis', 'threatlevel', 'email', 'hasproposal', 'timestamp', 'publishtimestamp', 'publish_timestamp', 'minimal');
$passedArgs = $this->passedArgs;
if (isset($this->request->data)) {
if (isset($this->request->data['request'])) $this->request->data = $this->request->data['request'];
@ -269,8 +268,10 @@ class EventsController extends AppController {
// check each of the passed arguments whether they're a filter (could also be a sort for example) and if yes, add it to the pagination conditions
foreach ($passedArgs as $k => $v) {
if (substr($k, 0, 6) === 'search') {
if ($urlparams != "") $urlparams .= "/";
$urlparams .= $k . ":" . $v;
if (!is_array($v)) {
if ($urlparams != "") $urlparams .= "/";
$urlparams .= $k . ":" . $v;
}
$searchTerm = strtolower(substr($k, 6));
switch ($searchTerm) {
case 'all' :
@ -325,9 +326,16 @@ class EventsController extends AppController {
if ($v == "") continue 2;
$this->paginate['conditions']['AND'][] = array('Event.timestamp >=' => $v);
break;
case 'publish_timestamp':
case 'publishtimestamp':
if ($v == "") continue 2;
$this->paginate['conditions']['AND'][] = array('Event.publish_timestamp <=' => $v);
if (is_array($v) && isset($v[0]) && isset($v[1])) {
$this->paginate['conditions']['AND'][] = array('Event.publish_timestamp >=' => $v[0]);
$this->paginate['conditions']['AND'][] = array('Event.publish_timestamp <=' => $v[1]);
} else {
$this->paginate['conditions']['AND'][] = array('Event.publish_timestamp >=' => $v);
}
break;
case 'org' :
if ($v == "") continue 2;
@ -516,9 +524,9 @@ class EventsController extends AppController {
}
}
if (Configure::read('MISP.tagging') && !$this->_isRest()) {
$this->Event->contain(array('User.email', 'EventTag' => array('Tag')));
$this->paginate['contain'] = array_merge($this->paginate['contain'], array('User.email', 'EventTag' => array('Tag')));
} else {
$this->Event->contain('User.email');
$this->paginate['contain'] = array_merge($this->paginate['contain'], array('User.email'));
}
$this->set('urlparams', $urlparams);
$this->set('passedArgsArray', $passedArgsArray);
@ -550,19 +558,31 @@ class EventsController extends AppController {
$rules['page'] = intval($passedArgs['page']);
}
$rules['contain'] = $this->paginate['contain'];
if (Configure::read('MISP.tagging')) {
if (Configure::read('MISP.tagging') && empty($passedArgs['searchminimal'])) {
$rules['contain']['EventTag'] = array('Tag' => array('fields' => array('id', 'name', 'colour', 'exportable'), 'conditions' => array('Tag.exportable' => true)));
}
if (isset($this->paginate['conditions'])) $rules['conditions'] = $this->paginate['conditions'];
$events = $this->Event->find('all', $rules);
foreach ($events as $k => $event) {
foreach ($event['EventTag'] as $k2 => $et) {
if (empty($et['Tag'])) unset($events[$k]['EventTag'][$k2]);
}
$events[$k]['EventTag'] = array_values($events[$k]['EventTag']);
if (!empty($passedArgs['searchminimal'])) {
unset($rules['contain']);
$rules['recursive'] = -1;
$rules['fields'] = array('id', 'timestamp', 'published', 'uuid');
}
$events = $this->Event->find('all', $rules);
if (empty($passedArgs['searchminimal'])) {
foreach ($events as $k => $event) {
foreach ($event['EventTag'] as $k2 => $et) {
if (empty($et['Tag'])) unset($events[$k]['EventTag'][$k2]);
}
$events[$k]['EventTag'] = array_values($events[$k]['EventTag']);
}
$events = $this->GalaxyCluster->attachClustersToEventIndex($events);
$this->set('events', $events);
} else {
foreach ($events as $key => $event) {
$events[$key] = $event['Event'];
}
return $this->RestResponse->viewData($events, $this->response->type());
}
$events = $this->GalaxyCluster->attachClustersToEventIndex($events);
$this->set('events', $events);
} else {
$events = $this->paginate();
if (count($events) == 1 && isset($this->passedArgs['searchall'])) {
@ -1318,6 +1338,7 @@ class EventsController extends AppController {
}
// Workaround for different structure in XML/array than what CakePHP expects
if (isset($this->request->data['response'])) $this->request->data = $this->request->data['response'];
if (!isset($this->request->data['Event'])) $this->request->data = array('Event' => $this->request->data);
$result = $this->Event->_edit($this->request->data, $this->Auth->user(), $id);
if ($result === true) {
// REST users want to see the newly created event
@ -1420,16 +1441,17 @@ class EventsController extends AppController {
throw new NotFoundException(__('Invalid event'));
}
// find the uuid
$result = $this->Event->findById($id);
$this->Event->read();
$event = $this->Event->find('first', array(
'conditions' => array('Event.id' => $id),
'fields' => array('Event.orgc_id', 'Event.id'),
'recursive' => -1
));
if (!$this->_isSiteAdmin()) {
if ($this->Event->data['Event']['orgc_id'] != $this->_checkOrg() || !$this->userRole['perm_modify']) {
if ($event['Event']['orgc_id'] != $this->_checkOrg() || !$this->userRole['perm_modify']) {
throw new MethodNotAllowedException();
}
}
if ($this->Event->delete()) {
if ($this->Event->quickDelete($event)) {
if ($this->_isRest() || $this->response->type() === 'application/json') {
$this->set('message', 'Event deleted.');
$this->set('_serialize', array('message'));
@ -1648,7 +1670,7 @@ class EventsController extends AppController {
$filesize_units = array('B', 'KB', 'MB', 'GB', 'TB');
if ($this->_isSiteAdmin()) $this->Session->setFlash('Warning, you are logged in as a site admin, any export that you generate will contain the FULL UNRESTRICTED data-set. If you would like to generate an export for your own organisation, please log in with a different user.');
// Check if the background jobs are enabled - if not, fall back to old export page.
if (Configure::read('MISP.background_jobs')) {
if (Configure::read('MISP.background_jobs') && !Configure::read('MISP.disable_cached_exports')) {
$now = time();
// as a site admin we'll use the ADMIN identifier, not to overwrite the cached files of our own org with a file that includes too much data.
@ -1745,6 +1767,9 @@ class EventsController extends AppController {
}
public function downloadExport($type, $extra = null) {
if (Configure::read('MISP.disable_cached_exports')) {
throw new MethodNotAllowedException('This feature is currently disabled');
}
if ($this->_isSiteAdmin()) $org = 'ADMIN';
else $org = $this->Auth->user('Organisation')['name'];
$this->autoRender = false;
@ -1844,7 +1869,7 @@ class EventsController extends AppController {
}
}
$result = $this->Whitelist->removeWhitelistedFromArray($result, false);
$final .= $converter->event2XML($result[0]) . PHP_EOL;
$final .= $converter->convert($result[0]) . PHP_EOL;
}
if ($validEvents == 0) throw new NotFoundException('No events found that match the passed parameters.');
$final .= '</response>' . PHP_EOL;
@ -1865,7 +1890,7 @@ class EventsController extends AppController {
return $results;
}
public function nids($format = 'suricata', $key = 'download', $id = false, $continue = false, $tags = false, $from = false, $to = false, $last = false, $type = false, $enforceWarninglist = false) {
public function nids($format = 'suricata', $key = 'download', $id = false, $continue = false, $tags = false, $from = false, $to = false, $last = false, $type = false, $enforceWarninglist = false, $includeAllTags = false) {
if ($this->request->is('post')) {
if (empty($this->request->data)) {
throw new BadRequestException('Either specify the search terms in the url, or POST a json or xml with the filter parameters. Valid filters: id (event ID), tags (list of tags), from (from date in YYYY-MM-DD format), to (to date in YYYY-MM-DD format), last (events with a published timestamp newer than - valid options are in time + unit format such as 6d or 2w, etc)');
@ -1882,7 +1907,7 @@ class EventsController extends AppController {
}
}
$simpleFalse = array('id', 'continue', 'tags', 'from', 'to', 'last', 'type', 'enforceWarninglist');
$simpleFalse = array('id', 'continue', 'tags', 'from', 'to', 'last', 'type', 'enforceWarninglist', 'includeAllTags');
foreach ($simpleFalse as $sF) {
if (!is_array(${$sF}) && (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false')) {
${$sF} = false;
@ -1918,7 +1943,7 @@ class EventsController extends AppController {
// display the full snort rulebase
$this->loadModel('Attribute');
$rules = $this->Attribute->nids($user, $format, $id, $continue, $tags, $from, $to, $last, $type, $enforceWarninglist);
$rules = $this->Attribute->nids($user, $format, $id, $continue, $tags, $from, $to, $last, $type, $enforceWarninglist, $includeAllTags);
$this->set('rules', $rules);
$this->render('/Events/nids');
}
@ -2456,15 +2481,14 @@ class EventsController extends AppController {
// 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 = 'download', $value = false, $type = false, $category = false, $org = false, $tags = false, $searchall = false, $from = false, $to = false, $last = false, $eventid = false, $withAttachments = false, $metadata = false, $uuid = false, $publish_timestamp = false, $timestamp = false, $published = false, $enforceWarninglist = false) {
if ($key != 'download') {
public function restSearch($key = 'download', $value = false, $type = false, $category = false, $org = false, $tags = false, $searchall = false, $from = false, $to = false, $last = false, $eventid = false, $withAttachments = false, $metadata = false, $uuid = false, $publish_timestamp = false, $timestamp = false, $published = false, $enforceWarninglist = false, $sgReferenceOnly = false) {
if ($key != null && strlen($key) == 40) {
if (!$this->checkAuthUser($key)) {
throw new UnauthorizedException('This authentication key is not authorized to be used for exports. Contact your administrator.');
}
} else {
if (!$this->Auth->user()) {
throw new UnauthorizedException('You are not authorized. Please send the Authorization header with your auth key along with an Accept header for application/xml.');
}
$key = strtolower($key);
if (!$this->Auth->user()) throw new UnauthorizedException('You are not authorized. Please send the Authorization header with your auth key along with an Accept header for application/xml.');
}
if (!is_array($value)) $value = str_replace('|', '/', $value);
// request handler for POSTed queries. If the request is a post, the parameters (apart from the key) will be ignored and replaced by the terms defined in the posted json or xml object.
@ -2483,7 +2507,7 @@ class EventsController extends AppController {
if (!isset($data['request'])) {
$data['request'] = $data;
}
$paramArray = array('value', 'type', 'category', 'org', 'tags', 'searchall', 'from', 'to', 'last', 'eventid', 'withAttachments', 'metadata', 'uuid', 'published', 'publish_timestamp', 'timestamp', 'enforceWarninglist');
$paramArray = array('value', 'type', 'category', 'org', 'tags', 'searchall', 'from', 'to', 'last', 'eventid', 'withAttachments', 'metadata', 'uuid', 'published', 'publish_timestamp', 'timestamp', 'enforceWarninglist', 'sgReferenceOnly');
foreach ($paramArray as $p) {
if (isset($data['request'][$p])) {
${$p} = $data['request'][$p];
@ -2492,7 +2516,7 @@ class EventsController extends AppController {
}
}
}
$simpleFalse = array('value' , 'type', 'category', 'org', 'tags', 'searchall', 'from', 'to', 'last', 'eventid', 'withAttachments', 'uuid', 'publish_timestamp', 'timestamp', 'enforceWarninglist');
$simpleFalse = array('value' , 'type', 'category', 'org', 'tags', 'searchall', 'from', 'to', 'last', 'eventid', 'withAttachments', 'uuid', 'publish_timestamp', 'timestamp', 'enforceWarninglist', 'sgReferenceOnly');
foreach ($simpleFalse as $sF) {
if (!is_array(${$sF}) && (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false')) {
${$sF} = false;
@ -2513,104 +2537,15 @@ class EventsController extends AppController {
$parameters = array('value', 'type', 'category', 'org', 'eventid', 'uuid');
foreach ($parameters as $k => $param) {
if (isset(${$parameters[$k]})) {
if (is_array(${$parameters[$k]})) {
$elements = ${$parameters[$k]};
} else {
$elements = explode('&&', ${$parameters[$k]});
}
foreach ($elements as $v) {
if ($v == '') continue;
if (substr($v, 0, 1) == '!') {
// check for an IPv4 address and subnet in CIDR notation (e.g. 127.0.0.1/8)
if ($parameters[$k] === 'value' && $this->Cidr->checkCIDR(substr($v, 1), 4)) {
$cidrresults = $this->Cidr->CIDR(substr($v, 1));
foreach ($cidrresults as $result) {
$subcondition['AND'][] = array('Attribute.value NOT LIKE' => $result);
}
} else {
if ($parameters[$k] === 'org') {
$found_orgs = $this->Event->Org->find('all', array(
'recursive' => -1,
'conditions' => array('LOWER(name) LIKE' => '%' . strtolower(substr($v, 1)) . '%'),
));
foreach ($found_orgs as $o) {
$subcondition['AND'][] = array('Event.orgc_id !=' => $o['Org']['id']);
}
} else if ($parameters[$k] === 'eventid') {
$subcondition['AND'][] = array('Attribute.event_id !=' => substr($v, 1));
} else if ($parameters[$k] === 'uuid') {
$subcondition['AND'][] = array('Event.uuid !=' => substr($v, 1));
$subcondition['AND'][] = array('Attribute.uuid !=' => substr($v, 1));
} else {
$subcondition['AND'][] = array('Attribute.' . $parameters[$k] . ' NOT LIKE' => '%'.substr($v, 1).'%');
}
}
} else {
// check for an IPv4 address and subnet in CIDR notation (e.g. 127.0.0.1/8)
if ($parameters[$k] === 'value' && $this->Cidr->checkCIDR($v, 4)) {
$cidrresults = $this->Cidr->CIDR($v);
foreach ($cidrresults as $result) {
if (!empty($result)) $subcondition['OR'][] = array('Attribute.value LIKE' => $result);
}
} else {
if ($parameters[$k] === 'org') {
$found_orgs = $this->Event->Org->find('all', array(
'recursive' => -1,
'conditions' => array('LOWER(name) LIKE' => '%' . strtolower($v) . '%'),
));
foreach ($found_orgs as $o) {
$subcondition['OR'][] = array('Event.orgc_id' => $o['Org']['id']);
}
} else if ($parameters[$k] === 'eventid') {
$subcondition['OR'][] = array('Attribute.event_id' => $v);
} else if ($parameters[$k] === 'uuid') {
$subcondition['OR'][] = array('Attribute.uuid' => $v);
$subcondition['OR'][] = array('Event.uuid' => $v);
}else {
if (!empty($v)) $subcondition['OR'][] = array('Attribute.' . $parameters[$k] . ' LIKE' => '%'.$v.'%');
}
}
}
}
if (!empty($subcondition)) array_push ($conditions['AND'], $subcondition);
$subcondition = array();
$conditions = $this->Event->setSimpleConditions($parameters[$k], ${$parameters[$k]}, $conditions);
}
}
// If we sent any tags along, load the associated tag names for each attribute
if ($tags) {
$args = $this->Event->Attribute->dissectArgs($tags);
$this->loadModel('Tag');
$tagArray = $this->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;
}
if ($tags) $conditions = $this->Event->Attribute->setTagConditions($tags, $conditions);
if ($from) $conditions['AND'][] = array('Event.date >=' => $from);
if ($to) $conditions['AND'][] = array('Event.date <=' => $to);
if ($publish_timestamp) {
if (is_array($publish_timestamp)) {
$conditions['AND'][] = array('Event.publish_timestamp >=' => $publish_timestamp[0]);
$conditions['AND'][] = array('Event.publish_timestamp <=' => $publish_timestamp[1]);
} else {
$conditions['AND'][] = array('Event.publish_timestamp >=' => $publish_timestamp);
}
}
if ($timestamp) {
if (is_array($timestamp)) {
$conditions['AND'][] = array('Event.timestamp >=' => $timestamp[0]);
$conditions['AND'][] = array('Event.timestamp <=' => $timestamp[1]);
} else {
$conditions['AND'][] = array('Event.timestamp >=' => $timestamp);
}
}
if ($publish_timestamp) $conditions = $this->Event->Attribute->setPublishTimestampConditions($publish_timestamp, $conditions);
if ($timestamp) $conditions = $this->Event->Attribute->setTimestampConditions($timestamp, $conditions);
if ($last) $conditions['AND'][] = array('Event.publish_timestamp >=' => $last);
if ($published) $conditions['AND'][] = array('Event.published' => $published);
$params = array(
@ -2626,61 +2561,56 @@ class EventsController extends AppController {
if (!in_array($attribute['Attribute']['event_id'], $eventIds)) $eventIds[] = $attribute['Attribute']['event_id'];
}
}
if (!empty($eventIds)) {
$this->loadModel('Whitelist');
if ((!isset($this->request->params['ext']) || $this->request->params['ext'] !== 'json') && $this->response->type() !== 'application/json') {
App::uses('XMLConverterTool', 'Tools');
$converter = new XMLConverterTool();
$final = "";
$final .= '<?xml version="1.0" encoding="UTF-8"?>' . PHP_EOL . '<response>' . PHP_EOL;
foreach ($eventIds as $currentEventId) {
$result = $this->Event->fetchEvent($this->Auth->user(), array(
'eventid' => $currentEventId,
'includeAttachments' => $withAttachments,
'metadata' => $metadata,
'enforceWarninglist' => $enforceWarningist
));
if (!empty($result)) {
$result = $this->Whitelist->removeWhitelistedFromArray($result, false);
$final .= $converter->event2XML($result[0]) . PHP_EOL;
}
}
$final .= '</response>' . PHP_EOL;
if (isset($eventid) && $eventid) {
$final_filename="misp.event." . $eventid . "." . $result[0]['Event']['uuid'] . ".xml";
} else {
$final_filename="misp.search.events.results.xml";
}
$this->response->body($final);
$this->response->type('xml');
$this->response->download($final_filename);
} else {
App::uses('JSONConverterTool', 'Tools');
$converter = new JSONConverterTool();
$final = '{"response":[';
foreach ($eventIds as $k => $currentEventId) {
$result = $this->Event->fetchEvent($this->Auth->user(), array(
'eventid' => $currentEventId,
'includeAttachments' => $withAttachments,
'metadata' => $metadata,
'enforceWarninglist' => $enforceWarninglist
));
$final .= $converter->event2JSON($result[0]);
if ($k < count($eventIds) -1 ) $final .= ',';
}
$final .= ']}';
if (isset($eventid) && $eventid) {
$final_filename="misp.event." . $eventid . "." . $result[0]['Event']['uuid'] . ".json";
} else {
$final_filename="misp.search.events.results.json";
}
$this->response->body($final);
$this->response->type('json');
$this->response->download($final_filename);
}
$this->loadModel('Whitelist');
$responseType = 'xml';
$converters = array(
'xml' => 'XMLConverterTool',
'json' => 'JSONConverterTool',
'openioc' => 'IOCExportTool'
);
if (in_array($key, array('json', 'xml', 'openioc'))) {
$responseType = $key;
} else if (((isset($this->request->params['ext']) && $this->request->params['ext'] == 'xml')) || $this->response->type() == 'application/xml') {
$responseType = 'xml';
} else {
throw new NotFoundException('No matches.');
$responseType = 'json';
}
App::uses($converters[$responseType], 'Tools');
$converter = new $converters[$responseType]();
$final = $converter->generateTop($this->Auth->user());
$eventCount = count($eventIds);
$i = 0;
foreach ($eventIds as $currentEventId) {
$i++;
$result = $this->Event->fetchEvent($this->Auth->user(), array(
'eventid' => $currentEventId,
'includeAttachments' => $withAttachments,
'metadata' => $metadata,
'enforceWarninglist' => $enforceWarninglist,
'sgReferenceOnly' => $sgReferenceOnly
));
if (!empty($result)) {
$result = $this->Whitelist->removeWhitelistedFromArray($result, false);
$final .= $converter->convert($result[0]);
if ($i < $eventCount) {
$final .= ',' . PHP_EOL;
}
}
}
$final .= $converter->generateBottom($responseType, $final);
$extension = $responseType;
if ($key == 'openioc') {
$extension = '.ioc';
}
if (isset($eventid) && $eventid) {
$final_filename="misp.event." . $eventid . "." . $result[0]['Event']['uuid'] . '.' . $extension;
} else {
$final_filename="misp.search.events.results." . $extension;
}
$this->response->type($responseType);
$this->autoRender = false;
$this->response->body($final);
$this->response->download($final_filename);
return $this->response;
}
@ -2690,8 +2620,6 @@ class EventsController extends AppController {
$this->response->type('text'); // set the content type
if ($eventid == null) {
throw new Exception('Not yet implemented');
} else {
$this->header('Content-Disposition: download; filename="misp.openIOC' . $eventid . '.ioc"');
}
$this->layout = 'text/default';
@ -2718,8 +2646,14 @@ class EventsController extends AppController {
$event = $temp[0];
// send the event and the vars needed to check authorisation to the Component
App::uses('IOCExportTool', 'Tools');
$this->IOCExport = new IOCExportTool();
$final = $this->IOCExport->buildAll($this->Auth->user(), $event);
$this->set('final', $final);
$this->response->type('xml');
$this->autoRender = false;
$this->response->body($final);
$this->response->download('misp.openIOC' . $eventid . '.ioc');
return $this->response;
}
public function create_dummy_event() {
@ -3067,6 +3001,13 @@ class EventsController extends AppController {
$typeCategoryMapping[$type][$k] = $k;
}
}
$distributions = $this->Event->Attribute->distributionLevels;
$sgs = $this->Event->SharingGroup->fetchAllAuthorised($this->Auth->user(), 'name', 1);
if (empty($sgs)) {
unset($distributions[4]);
}
$this->set('distributions', $distributions);
$this->set('sgs', $sgs);
$this->set('event', $event);
$this->set('typeList', array_keys($this->Event->Attribute->typeDefinitions));
$this->set('defaultCategories', $this->Event->Attribute->defaultCategories);
@ -3136,7 +3077,6 @@ class EventsController extends AppController {
foreach ($types as $type) {
$this->Event->$objectType->create();
$attribute['type'] = $type;
$attribute['distribution'] = 5;
if (empty($attribute['comment'])) $attribute['comment'] = $this->request->data['Attribute']['default_comment'];
$attribute['event_id'] = $id;
if ($objectType == 'ShadowAttribute') {
@ -3282,7 +3222,7 @@ class EventsController extends AppController {
$message= "";
$success = true;
$counter = 0;
if (!$this->userRole['perm_sync']) throw new MethodNotAllowedException('You do not have the permission to do that.');
if (!$this->userRole['perm_sync'] || !$this->userRole['perm_add']) throw new MethodNotAllowedException('You do not have the permission to do that.');
if ($this->request->is('post')) {
$event = $this->Event->find('first', array(
'conditions' => array('Event.uuid' => $uuid),
@ -3761,8 +3701,8 @@ class EventsController extends AppController {
} else {
$current_relation_id = $this->__graphJsonContains('event', $relation, $json);
if ($current_relation_id === false) {
if ($this->__orgImgExists($relatedEvents[$relation['id']]['Orgc']['name'])) {
$image = '/img/orgs/' . $relatedEvents[$relation['id']]['Orgc']['name'] . '.png';
if ($this->__orgImgExists($relatedEvents[$relation['id']]['Event']['Orgc']['name'])) {
$image = '/img/orgs/' . $relatedEvents[$relation['id']]['Event']['Orgc']['name'] . '.png';
} else {
$image = '/img/orgs/MISP.png';
}
@ -3771,7 +3711,7 @@ class EventsController extends AppController {
'type' => 'event', 'id' => $relation['id'],
'expanded' => 0, 'image' => $image,
'info' => $relatedEvents[$relation['id']]['Event']['info'],
'org' => $relatedEvents[$relation['id']]['Orgc']['name'],
'org' => $relatedEvents[$relation['id']]['Event']['Orgc']['name'],
'analysis' => $this->Event->analysisLevels[$relatedEvents[$relation['id']]['Event']['analysis']],
'date' => $relatedEvents[$relation['id']]['Event']['date']
);
@ -3936,7 +3876,7 @@ class EventsController extends AppController {
$importComment = $result['comment'];
}
else {
$importComment = 'Enriched via the ' . $module . ' module';
$importComment = $attribute[0]['Attribute']['value'] . ': Enriched via the ' . $module . ' module';
}
$typeCategoryMapping = array();
foreach ($this->Event->Attribute->categoryDefinitions as $k => $cat) {
@ -3960,6 +3900,13 @@ class EventsController extends AppController {
$resultArray[$key]['data'] = basename($tempFile) . '|' . filesize($tempFile);
}
}
$distributions = $this->Event->Attribute->distributionLevels;
$sgs = $this->Event->SharingGroup->fetchAllAuthorised($this->Auth->user(), 'name', 1);
if (empty($sgs)) {
unset($distributions[4]);
}
$this->set('distributions', $distributions);
$this->set('sgs', $sgs);
$this->set('event', array('Event' => $attribute[0]['Event']));
$this->set('resultArray', $resultArray);
$this->set('typeList', array_keys($this->Event->Attribute->typeDefinitions));
@ -4057,6 +4004,13 @@ class EventsController extends AppController {
);
$resultArray[$key]['related'] = $this->Event->Attribute->fetchAttributes($this->Auth->user(), $options);
}
$distributions = $this->Event->Attribute->distributionLevels;
$sgs = $this->Event->SharingGroup->fetchAllAuthorised($this->Auth->user(), 'name', 1);
if (empty($sgs)) {
unset($distributions[4]);
}
$this->set('distributions', $distributions);
$this->set('sgs', $sgs);
$this->set('event', array('Event' => array('id' => $eventId)));
$this->set('resultArray', $resultArray);
$this->set('typeList', array_keys($this->Event->Attribute->typeDefinitions));

View File

@ -101,6 +101,9 @@ class JobsController extends AppController {
}
public function cache($type) {
if (Configure::read('MISP.disable_cached_exports')) {
throw new MethodNotAllowedException('This feature is currently disabled');
}
if ($this->_isSiteAdmin()) {
$target = 'All events.';
} else {

View File

@ -118,14 +118,22 @@ class LogsController extends AppController {
'conditions' => array('User.org_id' => $this->Auth->user('org_id')),
'fields' => array('User.id', 'User.email')
));
foreach ($list as &$item) {
if (!in_array($item['Log']['email'], $emails)) $item['Log']['email'] = '';
foreach ($list as $k => $item) {
if (!in_array($item['Log']['email'], $emails)) $list[$k]['Log']['email'] = '';
}
}
$this->set('event', $this->Event->data);
$this->set('list', $list);
$this->set('eventId', $id);
$this->set('mayModify', $mayModify);
if ($this->_isRest()) {
foreach ($list as $k => $item) {
$list[$k] = $item['Log'];
}
$list = array('Log' => $list);
return $this->RestResponse->viewData($list, $this->response->type());
} else {
$this->set('event', $this->Event->data);
$this->set('list', $list);
$this->set('eventId', $id);
$this->set('mayModify', $mayModify);
}
}
public $helpers = array('Js' => array('Jquery'), 'Highlight');

View File

@ -7,7 +7,7 @@ class OrgBlacklistsController extends AppController {
public function beforeFilter() {
parent::beforeFilter();
if (!$this->_isSiteAdmin()) $this->redirect('/');
if (!Configure::read('MISP.enableOrgBlacklisting')) {
if (Configure::check('MISP.enableOrgBlacklisting') && !Configure::read('MISP.enableOrgBlacklisting') !== false) {
$this->Session->setFlash(__('Organisation Blacklisting is not currently enabled on this instance.'));
$this->redirect('/');
}

View File

@ -99,6 +99,14 @@ class OrganisationsController extends AppController {
}
}
if ($this->Organisation->save($this->request->data)) {
if (isset($this->request->data['Organisation']['logo']['size']) && $this->request->data['Organisation']['logo']['size'] > 0 && $this->request->data['Organisation']['logo']['error'] == 0) {
$filename = basename($this->request->data['Organisation']['name'] . '.png');
if (preg_match("/^[0-9a-z\-\_\.]*\.(png)$/i", $filename)) {
if (!empty($this->request->data['Organisation']['logo']['tmp_name']) && is_uploaded_file($this->request->data['Organisation']['logo']['tmp_name'])) {
$result = move_uploaded_file($this->request->data['Organisation']['logo']['tmp_name'], APP . 'webroot/img/orgs/' . $filename);
}
}
}
if ($this->_isRest()) {
$org = $this->Organisation->find('first', array(
'conditions' => array('Organisation.id' => $this->Organisation->id),
@ -149,6 +157,14 @@ class OrganisationsController extends AppController {
}
$this->request->data['Organisation']['id'] = $id;
if ($this->Organisation->save($this->request->data)) {
if (isset($this->request->data['Organisation']['logo']['size']) && $this->request->data['Organisation']['logo']['size'] > 0 && $this->request->data['Organisation']['logo']['error'] == 0) {
$filename = basename($this->request->data['Organisation']['name'] . '.png');
if (preg_match("/^[0-9a-z\-\_\.]*\.(png)$/i", $filename)) {
if (!empty($this->request->data['Organisation']['logo']['tmp_name']) && is_uploaded_file($this->request->data['Organisation']['logo']['tmp_name'])) {
$result = move_uploaded_file($this->request->data['Organisation']['logo']['tmp_name'], APP . 'webroot/img/orgs/' . $filename);
}
}
}
if ($this->_isRest()) {
$org = $this->Organisation->find('first', array(
'conditions' => array('Organisation.id' => $this->Organisation->id),

View File

@ -156,6 +156,11 @@ class ServersController extends AppController {
public function add() {
if (!$this->_isSiteAdmin()) $this->redirect(array('controller' => 'servers', 'action' => 'index'));
if ($this->request->is('post')) {
if($this->_isRest()) {
if (!isset($this->request->data['Server'])) {
$this->request->data = array('Server' => $this->request->data);
}
}
$json = json_decode($this->request->data['Server']['json'], true);
$fail = false;
@ -163,12 +168,22 @@ class ServersController extends AppController {
// test the filter fields
if (!empty($this->request->data['Server']['pull_rules']) && !$this->Server->isJson($this->request->data['Server']['pull_rules'])) {
$fail = true;
$this->Session->setFlash(__('The pull filter rules must be in valid JSON format.'));
$error_msg = __('The pull filter rules must be in valid JSON format.');
if($this->_isRest()) {
return $this->RestResponse->saveFailResponse('Servers', 'add', false, array('pull_rules' => $error_msg), $this->response->type());
} else {
$this->Session->setFlash($error_msg);
}
}
if (!$fail && !empty($this->request->data['Server']['push_rules']) && !$this->Server->isJson($this->request->data['Server']['push_rules'])) {
$fail = true;
$this->Session->setFlash(__('The push filter rules must be in valid JSON format.'));
$error_msg = __('The push filter rules must be in valid JSON format.');
if($this->_isRest()) {
return $this->RestResponse->saveFailResponse('Servers', 'add', false, array('push_rules' => $error_msg), $this->response->type());
} else {
$this->Session->setFlash($error_msg);
}
}
if (!$fail) {
@ -183,7 +198,11 @@ class ServersController extends AppController {
));
if (!empty($existingOrgs)) {
$fail = true;
$this->Session->setFlash(__('That organisation could not be created as the uuid is in use already.'));
if($this->_isRest()) {
return $this->RestResponse->saveFailResponse('Servers', 'add', false, array('Organisation' => 'Remote Organisation\'s uuid already used'), $this->response->type());
} else {
$this->Session->setFlash(__('That organisation could not be created as the uuid is in use already.'));
}
}
if (!$fail) {
@ -196,7 +215,11 @@ class ServersController extends AppController {
));
if (!$orgSave) {
$this->Session->setFlash(__('Couldn\'t save the new organisation, are you sure that the uuid is in the correct format?.'));
if($this->_isRest()) {
return $this->RestResponse->saveFailResponse('Servers', 'add', false, $this->Server->Organisation->validationError, $this->response->type());
} else {
$this->Session->setFlash(__('Couldn\'t save the new organisation, are you sure that the uuid is in the correct format?.'));
}
$fail = true;
$this->request->data['Server']['external_name'] = $json['name'];
$this->request->data['Server']['external_uuid'] = $json['uuid'];
@ -217,49 +240,65 @@ class ServersController extends AppController {
if (isset($this->request->data['Server']['submitted_client_cert']) && $this->request->data['Server']['submitted_client_cert']['size'] != 0) {
$this->__saveCert($this->request->data, $this->Server->id, true);
}
$this->Session->setFlash(__('The server has been saved'));
$this->redirect(array('action' => 'index'));
if($this->_isRest()) {
$server = $this->Server->find('first', array(
'conditions' => array('Server.id' => $this->Server->id),
'recursive' => -1
));
return $this->RestResponse->viewData($server, $this->response->type());
} else {
$this->Session->setFlash(__('The server has been saved'));
$this->redirect(array('action' => 'index'));
}
} else {
$this->Session->setFlash(__('The server could not be saved. Please, try again.'));
if($this->_isRest()) {
return $this->RestResponse->saveFailResponse('Servers', 'add', false, $this->Server->validationError, $this->response->type());
} else {
$this->Session->setFlash(__('The server could not be saved. Please, try again.'));
}
}
}
}
}
$organisationOptions = array(0 => 'Local organisation', 1 => 'External organisation', 2 => 'New external organisation');
$temp = $this->Server->Organisation->find('all', array(
'conditions' => array('local' => true),
'fields' => array('id', 'name'),
'order' => array('lower(Organisation.name) ASC')
));
$localOrganisations = array();
$allOrgs = array();
foreach ($temp as $o) {
$localOrganisations[$o['Organisation']['id']] = $o['Organisation']['name'];
$allOrgs[] = array('id' => $o['Organisation']['id'], 'name' => $o['Organisation']['name']);
}
$temp = $this->Server->Organisation->find('all', array(
'conditions' => array('local' => false),
'fields' => array('id', 'name'),
'order' => array('lower(Organisation.name) ASC')
));
$externalOrganisations = array();
foreach ($temp as $o) {
$externalOrganisations[$o['Organisation']['id']] = $o['Organisation']['name'];
$allOrgs[] = array('id' => $o['Organisation']['id'], 'name' => $o['Organisation']['name']);
}
$this->set('host_org_id', Configure::read('MISP.host_org_id'));
$this->set('organisationOptions', $organisationOptions);
$this->set('localOrganisations', $localOrganisations);
$this->set('externalOrganisations', $externalOrganisations);
$this->set('allOrganisations', $allOrgs);
if($this->_isRest()) {
return $this->RestResponse->describe('Servers', 'add', false, $this->response->type());
} else {
$organisationOptions = array(0 => 'Local organisation', 1 => 'External organisation', 2 => 'New external organisation');
$temp = $this->Server->Organisation->find('all', array(
'conditions' => array('local' => true),
'fields' => array('id', 'name'),
'order' => array('lower(Organisation.name) ASC')
));
$localOrganisations = array();
$allOrgs = array();
foreach ($temp as $o) {
$localOrganisations[$o['Organisation']['id']] = $o['Organisation']['name'];
$allOrgs[] = array('id' => $o['Organisation']['id'], 'name' => $o['Organisation']['name']);
}
$temp = $this->Server->Organisation->find('all', array(
'conditions' => array('local' => false),
'fields' => array('id', 'name'),
'order' => array('lower(Organisation.name) ASC')
));
$externalOrganisations = array();
foreach ($temp as $o) {
$externalOrganisations[$o['Organisation']['id']] = $o['Organisation']['name'];
$allOrgs[] = array('id' => $o['Organisation']['id'], 'name' => $o['Organisation']['name']);
}
$this->set('host_org_id', Configure::read('MISP.host_org_id'));
$this->set('organisationOptions', $organisationOptions);
$this->set('localOrganisations', $localOrganisations);
$this->set('externalOrganisations', $externalOrganisations);
$this->set('allOrganisations', $allOrgs);
// list all tags for the rule picker
$this->loadModel('Tag');
$temp = $this->Tag->find('all', array('recursive' => -1));
$allTags = array();
foreach ($temp as $t) $allTags[] = array('id' => $t['Tag']['id'], 'name' => $t['Tag']['name']);
$this->set('allTags', $allTags);
$this->set('host_org_id', Configure::read('MISP.host_org_id'));
// list all tags for the rule picker
$this->loadModel('Tag');
$temp = $this->Tag->find('all', array('recursive' => -1));
$allTags = array();
foreach ($temp as $t) $allTags[] = array('id' => $t['Tag']['id'], 'name' => $t['Tag']['name']);
$this->set('allTags', $allTags);
$this->set('host_org_id', Configure::read('MISP.host_org_id'));
}
}
public function edit($id = null) {
@ -271,76 +310,119 @@ class ServersController extends AppController {
if (!$this->_isSiteAdmin()) $this->redirect(array('controller' => 'servers', 'action' => 'index'));
if ($this->request->is('post') || $this->request->is('put')) {
if (empty(Configure::read('MISP.host_org_id'))) $this->request->data['Server']['internal'] = 0;
$json = json_decode($this->request->data['Server']['json'], true);
if($this->_isRest()) {
if (!isset($this->request->data['Server'])) {
$this->request->data = array('Server' => $this->request->data);
}
}
if(isset($this->request->data['Server']['json'])) {
$json = json_decode($this->request->data['Server']['json'], true);
} else {
$json = NULL;
}
$fail = false;
// test the filter fields
if (!empty($this->request->data['Server']['pull_rules']) && !$this->Server->isJson($this->request->data['Server']['pull_rules'])) {
$fail = true;
$this->Session->setFlash(__('The pull filter rules must be in valid JSON format.'));
$error_msg = __('The pull filter rules must be in valid JSON format.');
if($this->_isRest()) {
return $this->RestResponse->saveFailResponse('Servers', 'edit', false, array('pull_rules' => $error_msg), $this->response->type());
} else {
$this->Session->setFlash($error_msg);
}
}
if (!$fail && !empty($this->request->data['Server']['push_rules']) && !$this->Server->isJson($this->request->data['Server']['push_rules'])) {
$fail = true;
$this->Session->setFlash(__('The push filter rules must be in valid JSON format.'));
$error_msg = __('The push filter rules must be in valid JSON format.');
if($this->_isRest()) {
return $this->RestResponse->saveFailResponse('Servers', 'edit', false, array('push_rules' => $error_msg), $this->response->type());
} else {
$this->Session->setFlash($error_msg);
}
}
if (!$fail) {
// say what fields are to be updated
$fieldList = array('id', 'url', 'push', 'pull', 'unpublish_event', 'publish_without_email', 'remote_org_id', 'name' ,'self_signed', 'cert_file', 'client_cert_file', 'push_rules', 'pull_rules', 'internal');
$fieldList = array('id', 'url', 'push', 'pull', 'unpublish_event', 'publish_without_email', 'remote_org_id', 'name' ,'self_signed', 'cert_file', 'client_cert_file', 'push_rules', 'pull_rules', 'internal');
$this->request->data['Server']['id'] = $id;
if ("" != $this->request->data['Server']['authkey']) $fieldList[] = 'authkey';
if ($this->request->data['Server']['organisation_type'] < 2) $this->request->data['Server']['remote_org_id'] = $json['id'];
else {
$existingOrgs = $this->Server->Organisation->find('first', array(
'conditions' => array('uuid' => $json['uuid']),
'recursive' => -1,
'fields' => array('id', 'uuid')
));
if (!empty($existingOrgs)) {
$fail = true;
$this->Session->setFlash(__('That organisation could not be created as the uuid is in use already.'));
}
if (!$fail) {
$this->Server->Organisation->create();
$orgSave = $this->Server->Organisation->save(array(
'name' => $json['name'],
'uuid' => $json['uuid'],
'local' => 0,
'created_by' => $this->Auth->user('id')
if (isset($this->request->data['Server']['authkey']) && "" != $this->request->data['Server']['authkey']) $fieldList[] = 'authkey';
if(isset($this->request->data['Server']['organisation_type']) && isset($json)) {
// adds 'remote_org_id' in the fields to update
$fieldList[] = 'remote_org_id';
if ($this->request->data['Server']['organisation_type'] < 2) $this->request->data['Server']['remote_org_id'] = $json['id'];
else {
$existingOrgs = $this->Server->Organisation->find('first', array(
'conditions' => array('uuid' => $json['uuid']),
'recursive' => -1,
'fields' => array('id', 'uuid')
));
if (!$orgSave) {
$this->Session->setFlash(__('Couldn\'t save the new organisation, are you sure that the uuid is in the correct format?.'));
if (!empty($existingOrgs)) {
$fail = true;
$this->request->data['Server']['external_name'] = $json['name'];
$this->request->data['Server']['external_uuid'] = $json['uuid'];
} else {
$this->request->data['Server']['remote_org_id'] = $this->Server->Organisation->id;
if($this->_isRest()) {
return $this->RestResponse->saveFailResponse('Servers', 'edit', false, array('Organisation' => 'Remote Organisation\'s uuid already used'), $this->response->type());
} else {
$this->Session->setFlash(__('That organisation could not be created as the uuid is in use already.'));
}
}
if (!$fail) {
$this->Server->Organisation->create();
$orgSave = $this->Server->Organisation->save(array(
'name' => $json['name'],
'uuid' => $json['uuid'],
'local' => 0,
'created_by' => $this->Auth->user('id')
));
if (!$orgSave) {
if($this->_isRest()) {
return $this->RestResponse->saveFailResponse('Servers', 'edit', false, $this->Server->Organisation->validationError, $this->response->type());
} else {
$this->Session->setFlash(__('Couldn\'t save the new organisation, are you sure that the uuid is in the correct format?.'));
}
$fail = true;
$this->request->data['Server']['external_name'] = $json['name'];
$this->request->data['Server']['external_uuid'] = $json['uuid'];
} else {
$this->request->data['Server']['remote_org_id'] = $this->Server->Organisation->id;
}
}
}
}
if (empty(Configure::read('MISP.host_org_id')) || $this->request->data['Server']['remote_org_id'] != Configure::read('MISP.host_org_id')) {
$this->request->data['Server']['internal'] = 0;
if (empty(Configure::read('MISP.host_org_id')) || $this->request->data['Server']['remote_org_id'] != Configure::read('MISP.host_org_id')) {
$this->request->data['Server']['internal'] = 0;
}
}
}
if (!$fail) {
// Save the data
if ($this->Server->save($this->request->data, true, $fieldList)) {
if (isset($this->request->data['Server']['submitted_cert']) && $this->request->data['Server']['submitted_cert']['size'] != 0 && !$this->request->data['Server']['delete_cert']) {
if (isset($this->request->data['Server']['submitted_cert']) && $this->request->data['Server']['submitted_cert']['size'] != 0 && (!isset($this->request->data['Server']['delete_cert']) || !$this->request->data['Server']['delete_cert'])) {
$this->__saveCert($this->request->data, $this->Server->id, false);
} else {
if ($this->request->data['Server']['delete_cert']) $this->__saveCert($this->request->data, $this->Server->id, false, true);
if (isset($this->request->data['Server']['delete_cert']) && $this->request->data['Server']['delete_cert']) $this->__saveCert($this->request->data, $this->Server->id, false, true);
}
if (isset($this->request->data['Server']['submitted_client_cert']) && $this->request->data['Server']['submitted_client_cert']['size'] != 0 && !$this->request->data['Server']['delete_client_cert']) {
if (isset($this->request->data['Server']['submitted_client_cert']) && $this->request->data['Server']['submitted_client_cert']['size'] != 0 && (!isset($this->request->data['Server']['delete_client_cert']) || !$this->request->data['Server']['delete_client_cert'])) {
$this->__saveCert($this->request->data, $this->Server->id, true);
} else {
if ($this->request->data['Server']['delete_client_cert']) $this->__saveCert($this->request->data, $this->Server->id, true, true);
if (isset($this->request->data['Server']['delete_client_cert']) && $this->request->data['Server']['delete_client_cert']) $this->__saveCert($this->request->data, $this->Server->id, true, true);
}
if($this->_isRest()) {
$server = $this->Server->find('first', array(
'conditions' => array('Server.id' => $this->Server->id),
'recursive' => -1
));
return $this->RestResponse->viewData($server, $this->response->type());
} else {
$this->Session->setFlash(__('The server has been saved'));
$this->redirect(array('action' => 'index'));
}
$this->Session->setFlash(__('The server has been saved'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The server could not be saved. Please, try again.'));
if($this->_isRest()) {
return $this->RestResponse->saveFailResponse('Servers', 'edit', false, $this->Server->validationError, $this->response->type());
} else {
$this->Session->setFlash(__('The server could not be saved. Please, try again.'));
}
}
}
} else {
@ -348,48 +430,52 @@ class ServersController extends AppController {
$this->Server->set('authkey', '');
$this->request->data = $this->Server->data;
}
$organisationOptions = array(0 => 'Local organisation', 1 => 'External organisation', 2 => 'New external organisation');
$temp = $this->Server->Organisation->find('all', array(
'conditions' => array('local' => true),
'fields' => array('id', 'name'),
'order' => array('lower(Organisation.name) ASC')
));
$localOrganisations = array();
$allOrgs = array();
foreach ($temp as $o) {
$localOrganisations[$o['Organisation']['id']] = $o['Organisation']['name'];
$allOrgs[] = array('id' => $o['Organisation']['id'], 'name' => $o['Organisation']['name']);
if($this->_isRest()) {
return $this->RestResponse->describe('Servers', 'edit', false, $this->response->type());
} else {
$organisationOptions = array(0 => 'Local organisation', 1 => 'External organisation', 2 => 'New external organisation');
$temp = $this->Server->Organisation->find('all', array(
'conditions' => array('local' => true),
'fields' => array('id', 'name'),
'order' => array('lower(Organisation.name) ASC')
));
$localOrganisations = array();
$allOrgs = array();
foreach ($temp as $o) {
$localOrganisations[$o['Organisation']['id']] = $o['Organisation']['name'];
$allOrgs[] = array('id' => $o['Organisation']['id'], 'name' => $o['Organisation']['name']);
}
$temp = $this->Server->Organisation->find('all', array(
'conditions' => array('local' => false),
'fields' => array('id', 'name'),
'order' => array('lower(Organisation.name) ASC')
));
$externalOrganisations = array();
foreach ($temp as $o) {
$externalOrganisations[$o['Organisation']['id']] = $o['Organisation']['name'];
$allOrgs[] = array('id' => $o['Organisation']['id'], 'name' => $o['Organisation']['name']);
}
$oldRemoteSetting = 0;
if (!$this->Server->data['RemoteOrg']['local']) $oldRemoteSetting = 1;
$this->set('host_org_id', Configure::read('MISP.host_org_id'));
$this->set('oldRemoteSetting', $oldRemoteSetting);
$this->set('oldRemoteOrg', $this->Server->data['RemoteOrg']['id']);
$this->set('organisationOptions', $organisationOptions);
$this->set('localOrganisations', $localOrganisations);
$this->set('externalOrganisations', $externalOrganisations);
$this->set('allOrganisations', $allOrgs);
// list all tags for the rule picker
$this->loadModel('Tag');
$temp = $this->Tag->find('all', array('recursive' => -1));
$allTags = array();
foreach ($temp as $t) $allTags[] = array('id' => $t['Tag']['id'], 'name' => $t['Tag']['name']);
$this->set('allTags', $allTags);
$this->set('server', $s);
$this->set('host_org_id', Configure::read('MISP.host_org_id'));
}
$temp = $this->Server->Organisation->find('all', array(
'conditions' => array('local' => false),
'fields' => array('id', 'name'),
'order' => array('lower(Organisation.name) ASC')
));
$externalOrganisations = array();
foreach ($temp as $o) {
$externalOrganisations[$o['Organisation']['id']] = $o['Organisation']['name'];
$allOrgs[] = array('id' => $o['Organisation']['id'], 'name' => $o['Organisation']['name']);
}
$oldRemoteSetting = 0;
if (!$this->Server->data['RemoteOrg']['local']) $oldRemoteSetting = 1;
$this->set('host_org_id', Configure::read('MISP.host_org_id'));
$this->set('oldRemoteSetting', $oldRemoteSetting);
$this->set('oldRemoteOrg', $this->Server->data['RemoteOrg']['id']);
$this->set('organisationOptions', $organisationOptions);
$this->set('localOrganisations', $localOrganisations);
$this->set('externalOrganisations', $externalOrganisations);
$this->set('allOrganisations', $allOrgs);
// list all tags for the rule picker
$this->loadModel('Tag');
$temp = $this->Tag->find('all', array('recursive' => -1));
$allTags = array();
foreach ($temp as $t) $allTags[] = array('id' => $t['Tag']['id'], 'name' => $t['Tag']['name']);
$this->set('allTags', $allTags);
$this->set('server', $s);
$this->set('host_org_id', Configure::read('MISP.host_org_id'));
}
public function delete($id = null) {
@ -676,6 +762,10 @@ class ServersController extends AppController {
// check if the current version of MISP is outdated or not
$version = $this->__checkVersion();
$this->set('version', $version);
$gitStatus = $this->Server->getCurrentGitStatus();
$this->set('branch', $gitStatus['branch']);
$this->set('commit', $gitStatus['commit']);
$this->set('latestCommit', $gitStatus['latestCommit']);
$phpSettings = array(
'max_execution_time' => array(
'explanation' => 'The maximum duration that a script can run (does not affect the background workers). A too low number will break long running scripts like comprehensive API exports',
@ -720,7 +810,7 @@ class ServersController extends AppController {
// if Proxy is set up in the settings, try to connect to a test URL
$proxyStatus = $this->Server->proxyDiagnostics($diagnostic_errors);
$moduleTypes = array('Enrichment', 'Import', 'Export');
foreach ($moduleTypes as $type) {
$moduleStatus[$type] = $this->Server->moduleDiagnostics($diagnostic_errors, $type);
@ -738,7 +828,7 @@ class ServersController extends AppController {
$writeableFiles = $this->Server->writeableFilesDiagnostics($diagnostic_errors);
$readableFiles = $this->Server->readableFilesDiagnostics($diagnostic_errors);
$extensions = $this->Server->extensionDiagnostics();
// check if the encoding is not set to utf8
$dbEncodingStatus = $this->Server->databaseEncodingDiagnostics($diagnostic_errors);
@ -1055,6 +1145,31 @@ class ServersController extends AppController {
$this->render('ajax/fetch_servers_for_sg');
}
public function postTest() {
if ($this->request->is('post')) {
// Fix for PHP-FPM / Nginx / etc
// Fix via https://www.popmartian.com/tipsntricks/2015/07/14/howto-use-php-getallheaders-under-fastcgi-php-fpm-nginx-etc/
if (!function_exists('getallheaders')) {
$headers = [];
foreach ($_SERVER as $name => $value) {
if (substr($name, 0, 5) == 'HTTP_') {
$headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
}
}
} else {
$headers = getallheaders();
}
$result = array();
$result['body'] = $this->request->data;
$result['headers']['Content-type'] = isset($headers['Content-type']) ? $headers['Content-type'] : 0;
$result['headers']['Accept'] = isset($headers['Accept']) ? $headers['Accept'] : 0;
$result['headers']['Authorization'] = isset($headers['Authorization']) ? 'OK' : 0;
return new CakeResponse(array('body'=> json_encode($result)));
} else {
throw new MethodNotAllowedException('Invalid request, expecting a POST request.');
}
}
public function testConnection($id = false) {
if (!$this->Auth->user('Role')['perm_sync'] && !$this->Auth->user('Role')['perm_site_admin']) throw new MethodNotAllowedException('You don\'t have permission to do that.');
$this->Server->id = $id;
@ -1073,6 +1188,10 @@ class ServersController extends AppController {
$mismatch = false;
$newer = false;
$parts = array('major', 'minor', 'hotfix');
if ($version[0] == 2 && $version[1] == 4 && $version[2] > 68) {
$post = $this->Server->runPOSTTest($id);
}
$testPost = false;
foreach ($parts as $k => $v) {
if (!$mismatch) {
if ($version[$k] > $local_version[$v]) {
@ -1095,7 +1214,7 @@ class ServersController extends AppController {
return new CakeResponse(array('body'=> json_encode($result)));
}
}
return new CakeResponse(array('body'=> json_encode(array('status' => 1, 'local_version' => implode('.', $local_version), 'version' => implode('.', $version), 'mismatch' => $mismatch, 'newer' => $newer))));
return new CakeResponse(array('body'=> json_encode(array('status' => 1, 'local_version' => implode('.', $local_version), 'version' => implode('.', $version), 'mismatch' => $mismatch, 'newer' => $newer, 'post' => isset($post) ? $post : 'too old'))));
} else {
$result['status'] = 3;
}
@ -1163,4 +1282,24 @@ class ServersController extends AppController {
$this->set('response', array('version' => $this->pyMispVersion));
$this->set('_serialize', 'response');
}
public function getGit() {
$status = $this->Server->getCurrentGitStatus();
}
public function checkout() {
$result = $this->Server->checkoutMain();
}
public function update() {
if ($this->request->is('post')) {
$status = $this->Server->getCurrentGitStatus();
$update = $this->Server->update($status);
return new CakeResponse(array('body'=> $update));
} else {
$branch = $this->Server->getCurrentBranch();
$this->set('branch', $branch);
$this->render('ajax/update');
}
}
}

View File

@ -288,13 +288,16 @@ class ShadowAttributesController extends AppController {
}
}
public function add($eventId = null) {
public function add($eventId) {
if ($this->request->is('ajax')) {
$this->set('ajax', true);
$this->layout = 'ajax';
} else {
$this->set('ajax', false);
}
if (empty($eventId)) {
if (empty($event)) throw new NotFoundException('Invalid Event');
}
$event = $this->ShadowAttribute->Event->fetchEvent($this->Auth->user(), array('eventid' => $eventId));
if (empty($event)) throw new NotFoundException('Invalid Event');
$event = $event[0];
@ -308,14 +311,17 @@ class ShadowAttributesController extends AppController {
$this->request->data['ShadowAttribute'] = $this->request->data[$iN];
}
}
if (!isset($this->request->data['ShadowAttribute'])) {
$this->request->data = array('ShadowAttribute' => $this->request->data);
}
if ($this->request->is('ajax')) $this->autoRender = false;
// Give error if someone tried to submit a attribute with attachment or malware-sample type.
// TODO change behavior attachment options - this is bad ... it should rather by a messagebox or should be filtered out on the view level
if (isset($this->request->data['ShadowAttribute']['type']) && $this->ShadowAttribute->typeIsAttachment($this->request->data['ShadowAttribute']['type'])) {
if (isset($this->request->data['ShadowAttribute']['type']) && $this->ShadowAttribute->typeIsAttachment($this->request->data['ShadowAttribute']['type']) && !$this->_isRest()) {
$this->Session->setFlash(__('Attribute has not been added: attachments are added by "Add attachment" button', true), 'default', array(), 'error');
$this->redirect(array('controller' => 'events', 'action' => 'view', $this->request->data['ShadowAttribute']['event_id']));
$this->redirect(array('controller' => 'events', 'action' => 'view', $eventId));
}
if (isset($eventId)) $this->request->data['ShadowAttribute']['event_id'] = $eventId;
$this->request->data['ShadowAttribute']['event_id'] = $eventId;
//
// multiple attributes in batch import
//
@ -839,7 +845,7 @@ class ShadowAttributesController extends AppController {
if ($this->_isRest()) {
$temp = $this->ShadowAttribute->find('all', array(
'conditions' => $conditions,
'fields' => array('ShadowAttribute.id', 'ShadowAttribute.old_id', 'ShadowAttribute.event_id', 'ShadowAttribute.type', 'ShadowAttribute.category', 'ShadowAttribute.uuid', 'ShadowAttribute.to_ids', 'ShadowAttribute.value', 'ShadowAttribute.comment', 'ShadowAttribute.org_id', 'ShadowAttribute.timestamp'),
'fields' => array('ShadowAttribute.id', 'ShadowAttribute.old_id', 'ShadowAttribute.event_id', 'ShadowAttribute.type', 'ShadowAttribute.category', 'ShadowAttribute.uuid', 'ShadowAttribute.to_ids', 'ShadowAttribute.value', 'ShadowAttribute.comment', 'ShadowAttribute.org_id', 'ShadowAttribute.timestamp', 'ShadowAttribute.proposal_to_delete'),
'contain' => array(
'Event' => array(
'fields' => array('id', 'org_id', 'info', 'orgc_id'),

View File

@ -466,9 +466,7 @@ class TagsController extends AppController {
}
} else if ($taxonomy_id === 'all') {
$conditions = array('Tag.org_id' => array(0, $this->Auth->user('org_id')));
if (Configure::read('MISP.incoming_tags_disabled_by_default')) {
$conditions['Tag.hide_tag'] = 0;
}
$conditions['Tag.hide_tag'] = 0;
$options = $this->Tag->find('list', array('fields' => array('Tag.name'), 'conditions' => $conditions));
$expanded = $options;
} else {
@ -499,6 +497,14 @@ class TagsController extends AppController {
unset($expanded[$banned_tag]);
}
}
$hidden_tags = $this->Tag->find('list', array(
'conditions' => array('Tag.hide_tag' => 1),
'fields' => array('Tag.id')
));
foreach ($hidden_tags as $hidden_tag) {
unset($options[$hidden_tag]);
unset($expanded[$hidden_tag]);
}
if ($attributeTag !== false) {
$this->set('attributeTag', true);
}
@ -596,28 +602,45 @@ class TagsController extends AppController {
return $object;
}
public function attachTagToObject($object_uuid, $tag) {
if (!Validation::uuid($object_uuid)) {
public function attachTagToObject($uuid = false, $tag = false) {
if (!$this->request->is('post')) {
throw new MethodNotAllowedException('This method is only accessible via POST requests.');
}
if (empty($uuid)) {
if (!empty($this->request->data['uuid'])) {
$uuid = $this->request->data['uuid'];
} else {
throw new MethodNotAllowedException('Invalid object uuid');
}
}
if (!Validation::uuid($uuid)) {
throw new InvalidArgumentException('Invalid UUID');
}
if (empty($tag)) {
if (!empty($this->request->data['tag'])) {
$tag = $this->request->data['tag'];
} else {
throw new MethodNotAllowedException('Invalid tag');
}
}
if (is_numeric($tag)) {
$conditions = array('Tag.id' => $tag);
} else {
$conditions = array('LOWER(Tag.name) LIKE' => strtolower(trim($tag)));
}
$objectType = '';
$object = $this->__findObjectByUuid($object_uuid, $objectType);
$object = $this->__findObjectByUuid($uuid, $objectType);
$existingTag = $this->Tag->find('first', array('conditions' => $conditions, 'recursive' => -1));
if (empty($existingTag)) {
if (!is_numeric($tag)) {
if (!$this->userRole['perm_tag_editor']) {
throw new InvalidArgumentException('Tag not found and insufficient privileges to create it.');
throw new MethodNotAllowedException('Tag not found and insufficient privileges to create it.');
}
$this->Tag->create();
$this->Tag->save(array('Tag' => array('name' => $tag, 'colour' => $this->Tag->random_color())));
$existingTag = $this->Tag->find('first', array('recursive' => -1, 'conditions' => array('Tag.id' => $this->Tag->id)));
} else {
throw new InvalidArgumentException('Invalid Tag.');
throw new NotFoundException('Invalid Tag.');
}
}
if (!$this->_isSiteAdmin()) {
@ -649,10 +672,27 @@ class TagsController extends AppController {
}
}
public function removeTagFromObject($object_uuid, $tag) {
if (!Validation::uuid($object_uuid)) {
public function removeTagFromObject($uuid = false, $tag = false) {
if (!$this->request->is('post')) {
throw new MethodNotAllowedException('This method is only accessible via POST requests.');
}
if (empty($uuid)) {
if (!empty($this->request->data['uuid'])) {
$uuid = $this->request->data['uuid'];
} else {
throw new MethodNotAllowedException('Invalid object uuid');
}
}
if (!Validation::uuid($uuid)) {
throw new InvalidArgumentException('Invalid UUID');
}
if (empty($tag)) {
if (!empty($this->request->data['tag'])) {
$tag = $this->request->data['tag'];
} else {
throw new MethodNotAllowedException('Invalid tag');
}
}
if (is_numeric($tag)) {
$conditions = array('Tag.id' => $tag);
} else {
@ -663,7 +703,7 @@ class TagsController extends AppController {
throw new MethodNotAllowedException('Invalid Tag.');
}
$objectType = '';
$object = $this->__findObjectByUuid($object_uuid, $objectType);
$object = $this->__findObjectByUuid($uuid, $objectType);
if (empty($object)) {
throw new MethodNotAllowedException('Invalid Target.');
}

View File

@ -28,7 +28,7 @@ class TaxonomiesController extends AppController {
$total += empty($predicate['TaxonomyEntry']) ? 1 : count($predicate['TaxonomyEntry']);
}
$taxonomies[$key]['total_count'] = $total;
$taxonomies[$key]['current_count'] = $this->Tag->find('count', array('conditions' => array('lower(Tag.name) LIKE ' => strtolower($taxonomy['Taxonomy']['namespace']) . ':%')));
$taxonomies[$key]['current_count'] = $this->Tag->find('count', array('conditions' => array('lower(Tag.name) LIKE ' => strtolower($taxonomy['Taxonomy']['namespace']) . ':%', 'hide_tag' => 0)));
unset($taxonomies[$key]['TaxonomyPredicate']);
}
$this->set('taxonomies', $taxonomies);
@ -198,6 +198,24 @@ class TaxonomiesController extends AppController {
$this->redirect($this->referer());
}
public function disableTag($taxonomy_id = false) {
if ((!$this->_isSiteAdmin() && !$this->userRole['perm_tagger']) || !$this->request->is('post')) throw new NotFoundException('You don\'t have permission to do that.');
if ($taxonomy_id) {
$result = $this->Taxonomy->disableTags($taxonomy_id);
} else {
if (isset($this->request->data['Taxonomy'])) {
$this->request->data['Tag'] = $this->request->data['Taxonomy'];
unset($this->request->data['Taxonomy']);
}
if (isset($this->request->data['Tag']['request'])) $this->request->data['Tag'] = $this->request->data['Tag']['request'];
if (!isset($this->request->data['Tag']['nameList'])) $this->request->data['Tag']['nameList'] = array($this->request->data['Tag']['name']);
else $this->request->data['Tag']['nameList'] = json_decode($this->request->data['Tag']['nameList'], true);
$result = $this->Taxonomy->disableTags($this->request->data['Tag']['taxonomy_id'], $this->request->data['Tag']['nameList']);
}
$this->Session->setFlash($result ? 'The tag(s) has been hidden.' : 'The tag(s) could not be hidden. Please, try again.');
$this->redirect($this->referer());
}
public function taxonomyMassConfirmation($id) {
if (!$this->_isSiteAdmin() && !$this->userRole['perm_tagger']) throw new NotFoundException('You don\'t have permission to do that.');
$this->set('id', $id);

View File

@ -1,4 +1,4 @@
<?php
<?php
App::uses('AppController', 'Controller');
class UsersController extends AppController {
@ -93,6 +93,9 @@ class UsersController extends AppController {
$this->User->set('password', '');
$this->request->data = $this->User->data;
}
$this->loadModel('Server');
$this->set('complexity', !empty(Configure::read('Security.password_policy_complexity')) ? Configure::read('Security.password_policy_complexity') : $this->Server->serverSettings['Security']['password_policy_complexity']['value']);
$this->set('length', !empty(Configure::read('Security.password_policy_length')) ? Configure::read('Security.password_policy_length') : $this->Server->serverSettings['Security']['password_policy_length']['value']);
$roles = $this->User->Role->find('list');
$this->set(compact('roles'));
$this->set('id', $id);
@ -115,6 +118,9 @@ class UsersController extends AppController {
$this->Session->setFlash(__('The password could not be updated. Please, try again.'));
}
} else {
$this->loadModel('Server');
$this->set('complexity', !empty(Configure::read('Security.password_policy_complexity')) ? Configure::read('Security.password_policy_complexity') : $this->Server->serverSettings['Security']['password_policy_complexity']['value']);
$this->set('length', !empty(Configure::read('Security.password_policy_length')) ? Configure::read('Security.password_policy_length') : $this->Server->serverSettings['Security']['password_policy_length']['value']);
$this->User->recursive = 0;
$this->User->read(null, $id);
$this->User->set('password', '');
@ -365,6 +371,8 @@ class UsersController extends AppController {
if (!isset($this->request->data['User'][$key])) $this->request->data['User'][$key] = $value;
}
}
$this->request->data['User']['date_created'] = time();
$this->request->data['User']['date_modified'] = time();
if (!array_key_exists($this->request->data['User']['role_id'], $syncRoles)) $this->request->data['User']['server_id'] = 0;
$this->User->create();
// set invited by
@ -393,10 +401,10 @@ class UsersController extends AppController {
throw new Exception('You are not authorised to assign that role to a user.');
}
}
$fieldList = array('password', 'email', 'external_auth_required', 'external_auth_key', 'enable_password', 'confirm_password', 'org_id', 'role_id', 'authkey', 'nids_sid', 'server_id', 'gpgkey', 'certif_public', 'autoalert', 'contactalert', 'disabled', 'invited_by', 'change_pw', 'termsaccepted', 'newsread');
$fieldList = array('password', 'email', 'external_auth_required', 'external_auth_key', 'enable_password', 'confirm_password', 'org_id', 'role_id', 'authkey', 'nids_sid', 'server_id', 'gpgkey', 'certif_public', 'autoalert', 'contactalert', 'disabled', 'invited_by', 'change_pw', 'termsaccepted', 'newsread', 'date_created', 'date_modified');
if ($this->User->save($this->request->data, true, $fieldList)) {
$notification_message = '';
if ($this->request->data['User']['notify']) {
if (!empty($this->request->data['User']['notify'])) {
$user = $this->User->find('first', array('conditions' => array('User.id' => $this->User->id), 'recursive' => -1));
$password = isset($this->request->data['User']['password']) ? $this->request->data['User']['password'] : false;
$result = $this->User->initiatePasswordReset($user, true, true, $password);
@ -437,7 +445,9 @@ class UsersController extends AppController {
));
$this->set('orgs', $orgs);
// generate auth key for a new user
$this->loadModel('Server');
$this->loadModel('Server');
$this->set('complexity', !empty(Configure::read('Security.password_policy_complexity')) ? Configure::read('Security.password_policy_complexity') : $this->Server->serverSettings['Security']['password_policy_complexity']['value']);
$this->set('length', !empty(Configure::read('Security.password_policy_length')) ? Configure::read('Security.password_policy_length') : $this->Server->serverSettings['Security']['password_policy_length']['value']);
$conditions = array();
if (!$this->_isSiteAdmin()) $conditions['Server.org_id LIKE'] = $this->Auth->user('org_id');
$temp = $this->Server->find('all', array('conditions' => $conditions, 'recursive' => -1, 'fields' => array('id', 'name', 'url')));
@ -519,7 +529,10 @@ class UsersController extends AppController {
else array_push($fieldsOldValues, $this->User->field('password'));
}
// TODO Audit, __extralog, fields get orig END
if (isset($this->request->data['User']['password']) && "" != $this->request->data['User']['password']) {
if (
isset($this->request->data['User']['enable_password']) && $this->request->data['User']['enable_password'] != '0' &&
isset($this->request->data['User']['password']) && "" != $this->request->data['User']['password']
) {
$fields[] = 'password';
if ($this->_isRest() && !isset($this->request->data['User']['confirm_password'])) {
$this->request->data['User']['confirm_password'] = $this->request->data['User']['password'];
@ -613,6 +626,8 @@ class UsersController extends AppController {
$orgs = array();
}
$this->loadModel('Server');
$this->set('complexity', !empty(Configure::read('Security.password_policy_complexity')) ? Configure::read('Security.password_policy_complexity') : $this->Server->serverSettings['Security']['password_policy_complexity']['value']);
$this->set('length', !empty(Configure::read('Security.password_policy_length')) ? Configure::read('Security.password_policy_length') : $this->Server->serverSettings['Security']['password_policy_length']['value']);
$conditions = array();
if (!$this->_isSiteAdmin()) $conditions['Server.org_id LIKE'] = $this->Auth->user('org_id');
$temp = $this->Server->find('all', array('conditions' => $conditions, 'recursive' => -1, 'fields' => array('id', 'name', 'url')));
@ -1122,6 +1137,18 @@ class UsersController extends AppController {
if (isset($this->request->data['User']['firstTime'])) $firstTime = $this->request->data['User']['firstTime'];
return new CakeResponse($this->User->initiatePasswordReset($user, $id, $firstTime));
} else {
$error = false;
$encryption = false;
if (!empty($user['User']['gpgkey'])) {
$encryption = 'PGP';
} else if (!$error && !empty($user['User']['certif_public'])){
$encryption = 'SMIME';
}
$this->set('encryption', $encryption);
if (!$encryption && (Configure::read('GnuPG.onlyencrypted') || Configure::read('GnuPG.bodyonlyencrypted'))) {
$error = 'No encryption key found for the user and the instance posture blocks non encrypted e-mails from being sent.';
}
$this->set('error', $error);
$this->layout = 'ajax';
$this->set('user', $user);
$this->set('firstTime', $firstTime);
@ -1172,6 +1199,7 @@ class UsersController extends AppController {
$stats['attribute_count'] = $this->User->Event->Attribute->find('count', array('conditions' => array('Attribute.deleted' => 0)));
$stats['attribute_count_month'] = $this->User->Event->Attribute->find('count', array('conditions' => array('Attribute.timestamp >' => $this_month, 'Attribute.deleted' => 0)));
$stats['attributes_per_event'] = round($stats['attribute_count'] / $stats['event_count']);
$this->loadModel('Correlation');
$this->Correlation->recursive = -1;

View File

@ -35,9 +35,17 @@ class NidsExport {
}
// generate the rules
foreach ($items as $item) {
// retrieve all tags for this item to add them to the msg
$tagsArray = [];
foreach ($item['AttributeTag'] as $tag_attr) {
if (array_key_exists('name', $tag_attr['Tag'])) {
array_push($tagsArray, $tag_attr['Tag']['name']);
}
}
$ruleFormatMsgTags = implode(",", $tagsArray);
# proto src_ip src_port direction dst_ip dst_port msg rule_content tag sid rev
$ruleFormatMsg = 'msg: "MISP e' . $item['Event']['id'] . ' %s"';
$ruleFormatMsg = 'msg: "MISP e' . $item['Event']['id'] . ' [' . $ruleFormatMsgTags . '] %s"';
$ruleFormatReference = 'reference:url,' . Configure::read('MISP.baseurl') . '/events/view/' . $item['Event']['id'];
$ruleFormat = '%salert %s %s %s %s %s %s (' . $ruleFormatMsg . '; %s %s classtype:' . $this->classtype . '; sid:%d; rev:%d; priority:' . $item['Event']['threat_level_id'] . '; ' . $ruleFormatReference . ';) ';
@ -53,6 +61,12 @@ class NidsExport {
case 'ip-src':
$this->ipSrcRule($ruleFormat, $item['Attribute'], $sid);
break;
case 'ip-dst|port':
$this->ipDstRule($ruleFormat, $item['Attribute'], $sid);
break;
case 'ip-src|port':
$this->ipSrcRule($ruleFormat, $item['Attribute'], $sid);
break;
case 'email-src':
$this->emailSrcRule($ruleFormat, $item['Attribute'], $sid);
break;
@ -104,15 +118,15 @@ class NidsExport {
public function ipDstRule($ruleFormat, $attribute, &$sid) {
$overruled = $this->checkWhitelist($attribute['value']);
$attribute['value'] = NidsExport::replaceIllegalChars($attribute['value']); // substitute chars not allowed in rule
$ipport = NidsExport::getIpPort($attribute);
$this->rules[] = sprintf($ruleFormat,
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
'ip', // proto
'$HOME_NET', // src_ip
'any', // src_port
'->', // direction
$attribute['value'], // dst_ip
'any', // dst_port
$ipport[0], // dst_ip
$ipport[1], // dst_port
'Outgoing To IP: ' . $attribute['value'], // msg
'', // rule_content
'', // tag
@ -123,12 +137,12 @@ class NidsExport {
public function ipSrcRule($ruleFormat, $attribute, &$sid) {
$overruled = $this->checkWhitelist($attribute['value']);
$attribute['value'] = NidsExport::replaceIllegalChars($attribute['value']); // substitute chars not allowed in rule
$ipport = NidsExport::getIpPort($attribute);
$this->rules[] = sprintf($ruleFormat,
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
'ip', // proto
$attribute['value'], // src_ip
'any', // src_port
$ipport[0], // src_ip
$ipport[1], // src_port
'->', // direction
'$HOME_NET', // dst_ip
'any', // dst_port
@ -497,31 +511,42 @@ class NidsExport {
return false;
}
public static function getProtocolPort($protocol, $customPort) {
if($customPort == null) {
switch ($protocol) {
case "http":
return '$HTTP_PORTS';
case "https":
return '443';
case "ssh":
return '22';
case "ftp":
return '[20,21]';
default:
return 'any';
}
} else {
return $customPort;
}
}
public static function getCustomIP($customIP) {
if(filter_var($customIP, FILTER_VALIDATE_IP)) {
return $customIP;
}
else {
return '$EXTERNAL_NET';
}
}
public static function getProtocolPort($protocol, $customPort) {
if($customPort == null) {
switch ($protocol) {
case "http":
return '$HTTP_PORTS';
case "https":
return '443';
case "ssh":
return '22';
case "ftp":
return '[20,21]';
default:
return 'any';
}
} else {
return $customPort;
}
}
public static function getCustomIP($customIP) {
if(filter_var($customIP, FILTER_VALIDATE_IP)) {
return $customIP;
}
else {
return '$EXTERNAL_NET';
}
}
public static function getIpPort($attribute) {
$ipport = array();
if (strpos($attribute['type'],'port') !== false) {
$ipport = explode('|', $attribute['value']);
} else {
$ipport[0] = $attribute['value'];
$ipport[1] = 'any';
}
return $ipport;
}
}

View File

@ -93,8 +93,13 @@ class NidsSuricataExport extends NidsExport {
$scheme = parse_url($attribute['value'], PHP_URL_SCHEME);
$data = parse_url($attribute['value']);
if (!array_key_exists('port', $data)) {
$data['port'] = null;
if (is_array($data)) {
if (!array_key_exists('port', $data)) {
$data['port'] = null;
}
if (!array_key_exists('host', $data)) {
$data['host'] = '';
}
}
switch ($scheme) {
@ -228,4 +233,4 @@ class NidsSuricataExport extends NidsExport {
);
}
}
}

View File

@ -0,0 +1,56 @@
<?php
class CIDRTool {
function CIDR($cidr) {
list($address, $prefix) = explode('/', $cidr, 2);
$address = decbin(ip2long($address));
$address = substr("00000000000000000000000000000000",0,32 - strlen($address)) . $address;
$min = '';
$max = '';
for ($i = 0; $i < $prefix; $i++) {
$min .= $address[$i];
}
$max = $min;
$min = str_pad($min, 32, '0', STR_PAD_RIGHT);
$max = str_pad($max, 32, '1', STR_PAD_RIGHT);
$minArray = array();
$maxArray = array();
$searchTermLeft = '';
$searchTermMin = 0;
$searchTermMax = 0;
$results = array();
for ($i = 0; $i < 4; $i++) {
$minArray[] = bindec(substr($min, ($i*8), 8));
$maxArray[] = bindec(substr($max, ($i*8), 8));
if ($minArray[$i] === $maxArray[$i]) $searchTermLeft .= $minArray[$i] . '.';
else {
$searchTermMin = $minArray[$i];
$searchTermMax = $maxArray[$i];
break;
}
}
$length = $i;
for ($i = 0; $i < ($searchTermMax - $searchTermMin + 1); $i++) {
$results[$i] = $searchTermLeft . ($searchTermMin + $i);
if ($length < 3) $results[$i] .= '.%';
}
return $results;
}
function checkCIDR($cidr, $ipVersion) {
if (strpos($cidr, '/') === FALSE || substr_count($cidr, '/') !== 1) {
return false;
}
list($net, $maskbits) = explode('/', $cidr);
if (!is_numeric($maskbits) || $maskbits < 0) {
return false;
}
if ($ipVersion == 4) {
return ($maskbits <= 32) && filter_var($net, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
} else if ($ipVersion == 6) {
return ($maskbits <= 128) && filter_var($net, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6);
} else {
throw new InvalidArgumentException('checkCIDR does only support IPv4 & IPv6');
}
}
}

View File

@ -0,0 +1,158 @@
<?php
class IOCExportTool {
public function buildAll($user, $data, $scope = 'event') {
$final = '';
if (!isset($data['Attribute'])) {
$data = array('Attribute' => $data);
}
if ($scope == 'event') {
$final = $this->generateSingleTop($data);
} else {
$final = $this->generateTop($user, $data);
}
foreach ($data['Attribute'] as $attribute) {
$final .= $this->generateAttribute($attribute);
}
$final .= $this->generateBottom();
return $final;
}
public function convert($data) {
$final = '';
foreach ($data['Attribute'] as $attribute) {
$final .= $this->generateAttribute($attribute);
}
return $final;
}
public function getResult() {
return $this->__final;
}
// generates the top with the event information
public function generateSingleTop($event) {
// We will start adding all the components that will be in the xml file here
$temp = '<?xml version="1.0" encoding="utf-8"?>' . PHP_EOL;
$temp .= '<ioc xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" id="' . $event['Event']['uuid'] . '" last-modified="' . $event['Event']['date'] . 'T00:00:00" xmlns="http://schemas.mandiant.com/2010/ioc">' . PHP_EOL;
$temp .= ' <short_description>Event #' . h($event['Event']['id']) . '</short_description>' . PHP_EOL;
$temp .= ' <description>' . h($event['Event']['info']) . ' (' . h($event['Event']['uuid']) . ')</description>' . PHP_EOL;
$temp .= ' <keywords />' . PHP_EOL;
$temp .= ' <authored_by>' . h($event['Orgc']['name']) . '</authored_by>' . PHP_EOL;
$temp .= ' <authored_date>' . h($event['Event']['date']) . 'T00:00:00</authored_date>' . PHP_EOL;
$temp .= ' <links />' . PHP_EOL;
$temp .= ' <definition>' . PHP_EOL;
$temp .= ' <Indicator operator="OR" id="' . CakeText::uuid() . '">' . PHP_EOL;
return $temp;
}
public function generateTop($user) {
$temp = '';
// We will start adding all the components that will be in the xml file here
$date = date("Y-m-d\Th:i:s");
$temp .= '<?xml version="1.0" encoding="utf-8"?>' . PHP_EOL;
$temp .= '<ioc xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" id="' . CakeText::uuid() . '" last-modified="' . $date . '" xmlns="http://schemas.mandiant.com/2010/ioc">' . PHP_EOL;
$temp .= ' <short_description>Filtered indicator list</short_description>' . PHP_EOL;
$temp .= ' <description>Filtered indicator list</description>' . PHP_EOL;
$temp .= ' <keywords />' . PHP_EOL;
$temp .= ' <authored_by>' . h($user['Organisation']['name']) . '</authored_by>' . PHP_EOL;
$temp .= ' <authored_date>' . $date . '</authored_date>' . PHP_EOL;
$temp .= ' <links />' . PHP_EOL;
$temp .= ' <definition>' . PHP_EOL;
$temp .= ' <Indicator operator="OR" id="' . CakeText::uuid() . '">' . PHP_EOL;
return $temp;
}
public $mapping = array(
'composite' => array(
'regkey|value' => array(array('Network', 'RegistryItem/KeyPath', 'string'), array('Network', 'RegistryItem/Value', 'string')),
'filename|md5' => array(array('FileItem', 'FileItem/FileName', 'string'), array('FileItem', 'FileItem/Md5sum', 'md5')),
'filename|sha1' => array(array('FileItem', 'FileItem/FileName', 'string'), array('FileItem', 'FileItem/Sha1sum', 'sha1')),
'filename|sha256' => array(array('FileItem', 'FileItem/FileName', 'string'), array('FileItem', 'FileItem/Sha256sum', 'sha256')),
'malware-sample' => array(array('FileItem', 'FileItem/FileName', 'string'), array('FileItem', 'FileItem/Md5sum', 'md5')),
'domain|ip' => array(array('Network', 'Network/DNS', 'string'), array('PortItem', 'PortItem/remoteIP', 'IP')),
),
'simple' => array(
'md5' => array('FileItem', 'FileItem/Md5sum', 'md5'),
'sha1' => array('FileItem', 'FileItem/Sha1sum', 'sha1'),
'sha256' => array('FileItem', 'FileItem/Sha256sum', 'sha256'),
'filename' => array('FileItem', 'FileItem/FileName', 'string'),
'ip-src' => array('PortItem', 'PortItem/remoteIP', 'IP'),
'ip-dst' => array('RouteEntryItem', 'RouteEntryItem/Destination', 'IP'),
'hostname' => array('RouteEntryItem', 'RouteEntryItem/Destination', 'string'),
'email-src' => array('Email', 'Email/From', 'string'),
'email-dst' => array('Email', 'Email/To', 'string'),
'email-subject' => array('Email', 'Email/Subject', 'string'),
'email-attachment' => array('Email', 'Email/Attachment/Name', 'string'),
'domain' => array('Network', 'Network/DNS', 'string'),
'url' => array('UrlHistoryItem', 'UrlHistoryItem/URL', 'string'),
'user-agent' => array('Network', 'Network/UserAgent', 'string'),
'regkey' => array('Network', 'RegistryItem/KeyPath', 'string'),
'snort' => array('Snort', 'Snort/Snort', 'string'),
'attachment' => array('FileItem', 'FileItem/FileName', 'string'),
'link' => array('URL', 'UrlHistoryItem/URL', 'md5')
)
);
public function frameComposite($attribute) {
$temp = '';
$values = explode('|', $attribute['value']);
$temp .= ' <Indicator operator="AND" id="' . h($attribute['uuid']) . '">' . PHP_EOL;
$temp .= $this->frameIndicator($this->mapping['composite'][$attribute['type']][0], $attribute['uuid'], $values[0], true);
$temp .= $this->frameIndicator($this->mapping['composite'][$attribute['type']][1], $attribute['uuid'], $values[1], true);
$temp .= ' </Indicator>' . PHP_EOL;
return $temp;
}
public function frameIndicator($mapping, $uuid, $value, $extraIndent = false) {
$temp = '';
$padding = 6;
if ($extraIndent) {
$padding = 8;
}
$temp .= str_repeat(' ', $padding) . '<IndicatorItem id="' . h($uuid) . '" condition="is">' . PHP_EOL;
$temp .= str_repeat(' ', ($padding + 2)) . '<Context document="' . $mapping[0] . '" search="' . $mapping[1] . '" type="mir" />' . PHP_EOL;
$temp .= str_repeat(' ', ($padding + 2)) . '<Content type="' . $mapping[2] . '">' . h($value) . '</Content>' . PHP_EOL;
$temp .= str_repeat(' ', $padding) . '</IndicatorItem>' . PHP_EOL;
return $temp;
}
// This method will turn each eligible attribute into an indicator
public function generateAttribute($attribute) {
$temp = '';
if (isset($attribute['Attribute'])) {
$attribute = $attribute['Attribute'];
}
// Hop over attributes that don't have the to ids flag turned on and check whether the attribute is sent for IOC export based on category/type
if (!$this->checkValidTypeForIOC($attribute) || $attribute['to_ids'] == 0) return false;
if ($attribute['type'] == 'malware-sample') $attribute['type'] = 'filename|md5';
if (strpos($attribute['type'], '|')) {
if ($this->mapping['composite'][$attribute['type']]) {
$temp .= $this->frameComposite($attribute);
}
} else {
if (isset($this->mapping['simple'][$attribute['type']])) {
$temp .= $this->frameIndicator($this->mapping['simple'][$attribute['type']], $attribute['uuid'], $attribute['value'], false);
}
}
return $temp;
}
// Just closing some tags at the bottom of the .ioc file
public function generateBottom() {
$temp = '';
$temp .= ' </Indicator>' . PHP_EOL;
$temp .= ' </definition>' . PHP_EOL;
$temp .= '</ioc>' . PHP_EOL;
return $temp;
}
// Simple check for valid categories and types for IOC generation
public function checkValidTypeForIOC($attribute) {
// categories that should be included
$Category = array('Payload delivery', 'Artifacts dropped', 'Payload installation', 'Persistence mechanism', 'Network activity');
if (!in_array($attribute['category'], $Category)) return false;
return true;
}
}

View File

@ -1,12 +1,24 @@
<?php
class JSONConverterTool {
public function event2JSON($event, $isSiteAdmin=false) {
public function generateTop() {
return '{"response":[';
}
public function generateBottom() {
return ']}' . PHP_EOL;
}
public function convert($event, $isSiteAdmin=false) {
$toRearrange = array('Org', 'Orgc', 'SharingGroup', 'Attribute', 'ShadowAttribute', 'RelatedAttribute', 'RelatedEvent', 'Galaxy');
foreach ($toRearrange as $object) {
if (isset($event[$object])) {
$event['Event'][$object] = $event[$object];
unset($event[$object]);
}
if ($object == 'SharingGroup' && isset($event['Event']['SharingGroup']) && empty($event['Event']['SharingGroup'])) {
unset($event['Event']['SharingGroup']);
}
}
if (isset($event['EventTag'])) {
@ -15,7 +27,7 @@ class JSONConverterTool {
$event['Event']['Tag'][$k] = $tag['Tag'];
}
}
//
// cleanup the array from things we do not want to expose
//
@ -30,6 +42,9 @@ class JSONConverterTool {
if (isset($event['Event']['Attribute'])) {
// remove value1 and value2 from the output and remove invalid utf8 characters for the xml parser
foreach ($event['Event']['Attribute'] as $key => $value) {
if (isset($value['SharingGroup']) && empty($value['SharingGroup'])) {
unset($event['Event']['Attribute'][$key]['SharingGroup']);
}
unset($event['Event']['Attribute'][$key]['value1']);
unset($event['Event']['Attribute'][$key]['value2']);
unset($event['Event']['Attribute'][$key]['category_order']);
@ -84,7 +99,7 @@ class JSONConverterTool {
public function eventCollection2Format($events, $isSiteAdmin=false) {
$results = array();
foreach ($events as $event) $results[] = $this->event2JSON($event, $isSiteAdmin);
foreach ($events as $event) $results[] = $this->convert($event, $isSiteAdmin);
return implode(',' . PHP_EOL, $results);
}

View File

@ -63,7 +63,7 @@ class PubSubTool {
$settings = $this->__setupPubServer();
App::uses('JSONConverterTool', 'Tools');
$jsonTool = new JSONConverterTool();
$json = $jsonTool->event2JSON($event);
$json = $jsonTool->convert($event);
$redis = new Redis();
$redis->connect($settings['redis_host'], $settings['redis_port']);
$redis->select($settings['redis_database']);

View File

@ -0,0 +1,19 @@
<?php
class QueryTool {
private $__pdoMap = array(
'integer' => PDO::PARAM_INT,
'float' => PDO::PARAM_STR,
'boolean' => PDO::PARAM_BOOL,
'string' => PDO::PARAM_STR,
'text' => PDO::PARAM_STR
);
public function quickDelete($table, $field, $value, $model) {
$db = $model->getDataSource();
$connection = $db->getConnection();
$query = $connection->prepare('DELETE FROM ' . $table . ' WHERE ' . $field . ' = :value');
$query->bindValue(':value', $value, $this->__pdoMap[$db->introspectType($value)]);
$query->execute();
}
}

View File

@ -4,6 +4,14 @@ class XMLConverterTool {
private $__toEscape = array("&", "<", ">", "\"", "'");
private $__escapeWith = array('&amp;', '&lt;', '&gt;', '&quot;', '&apos;');
public function generateTop() {
return '<?xml version="1.0" encoding="UTF-8"?>' . PHP_EOL . '<response>' . PHP_EOL;
}
public function generateBottom() {
return '</response>' . PHP_EOL;
}
public function recursiveEcho($array) {
$text = "";
if (is_array($array)) foreach ($array as $k => $v) {
@ -27,7 +35,7 @@ class XMLConverterTool {
return $text;
}
public function event2xmlArray($event, $isSiteAdmin=false) {
public function convertArray($event, $isSiteAdmin=false) {
$event['Event']['Org'][0] = $event['Org'];
$event['Event']['Orgc'][0] = $event['Orgc'];
if (isset($event['SharingGroup']['SharingGroupOrg'])) {
@ -157,8 +165,8 @@ class XMLConverterTool {
return $result;
}
public function event2XML($event, $isSiteAdmin=false) {
$xmlArray = $this->event2xmlArray($event, $isSiteAdmin);
public function convert($event, $isSiteAdmin=false) {
$xmlArray = $this->convertArray($event, $isSiteAdmin);
$result = array('Event' => array(0 => $xmlArray['Event']));
if (isset($xmlArray['errors']) && !empty($xmlArray['errors'])) $result['errors'] = array($xmlArray['errors']);
return $this->recursiveEcho($result);
@ -171,7 +179,7 @@ class XMLConverterTool {
public function eventCollection2Format($events, $isSiteAdmin=false) {
$result = "";
foreach ($events as $event) $result .= $this->event2XML($event) . PHP_EOL;
foreach ($events as $event) $result .= $this->convert($event) . PHP_EOL;
return $result;
}

@ -1 +1 @@
Subproject commit 73dcbf2aa33b79512373baa63b39adf3fb838608
Subproject commit 8d0e1fadf77dcde9d48262f8501b7c9c2b6f8aac

View File

@ -41,7 +41,8 @@ class AppModel extends Model {
42 => false, 44 => false, 45 => false, 49 => true, 50 => false,
51 => false, 52 => false, 55 => true, 56 => true, 57 => true,
58 => false, 59 => false, 60 => false, 61 => false, 62 => false,
63 => false, 64 => false, 65 => false, 66 => false, 67 => true
63 => false, 64 => false, 65 => false, 66 => false, 67 => true,
68 => false, 69 => false, 71 => false
)
)
);
@ -90,6 +91,21 @@ class AppModel extends Model {
$this->Sighting->addUuids();
$this->Sighting->deleteAll(array('NOT' => array('Sighting.type' => array(0, 1, 2))));
break;
case '2.4.71':
$this->OrgBlacklist = Classregistry::init('OrgBlacklist');
$values = array(
array('org_uuid' => '58d38339-7b24-4386-b4b4-4c0f950d210f', 'org_name' => 'Setec Astrononomy', 'comment' => 'default example'),
array('org_uuid' => '58d38326-eda8-443a-9fa8-4e12950d210f', 'org_name' => 'Acme Finance', 'comment' => 'default example')
);
foreach ($values as $value) {
$found = $this->OrgBlacklist->find('first', array('conditions' => array('org_uuid' => $value['org_uuid']), 'recursive' => -1));
if (empty($found)) {
$this->OrgBlacklist->create();
$this->OrgBlacklist->save($value);
}
}
$this->updateDatabase($command);
break;
default:
$this->updateDatabase($command);
break;
@ -627,6 +643,44 @@ class AppModel extends Model {
$sqlArray[] = "ALTER TABLE `roles` ADD `perm_sighting` tinyint(1) NOT NULL DEFAULT 0;";
$sqlArray[] = 'UPDATE `roles` SET `perm_sighting` = 1 WHERE `perm_add` = 1;';
break;
case '2.4.68':
$sqlArray[] = 'ALTER TABLE events CHANGE attribute_count attribute_count int(11) unsigned DEFAULT 0;';
$sqlArray[] = 'CREATE TABLE IF NOT EXISTS `event_blacklists` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`event_uuid` varchar(40) COLLATE utf8_bin NOT NULL,
`created` datetime NOT NULL,
`event_info` TEXT CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`comment` TEXT CHARACTER SET utf8 COLLATE utf8_unicode_ci,
`event_orgc` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;';
$indexArray[] = array('event_blacklists', 'event_uuid');
$indexArray[] = array('event_blacklists', 'event_orgc');
$sqlArray[] = 'CREATE TABLE IF NOT EXISTS `org_blacklists` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`org_uuid` varchar(40) COLLATE utf8_bin NOT NULL,
`created` datetime NOT NULL,
`org_name` varchar(255) COLLATE utf8_bin NOT NULL,
`comment` TEXT CHARACTER SET utf8 COLLATE utf8_unicode_ci,
PRIMARY KEY (`id`),
INDEX `org_uuid` (`org_uuid`),
INDEX `org_name` (`org_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;';
$indexArray[] = array('org_blacklists', 'org_uuid');
$indexArray[] = array('org_blacklists', 'org_name');
$sqlArray[] = "ALTER TABLE shadow_attributes CHANGE proposal_to_delete proposal_to_delete BOOLEAN DEFAULT 0";
$sqlArray[] = "ALTER TABLE taxonomy_predicates CHANGE colour colour varchar(7) CHARACTER SET utf8 COLLATE utf8_bin;";
$sqlArray[] = "ALTER TABLE taxonomy_entries CHANGE colour colour varchar(7) CHARACTER SET utf8 COLLATE utf8_bin;";
break;
case '2.4.69':
$sqlArray[] = "ALTER TABLE taxonomy_entries CHANGE colour colour varchar(7) CHARACTER SET utf8 COLLATE utf8_bin;";
$sqlArray[] = "ALTER TABLE users ADD COLUMN date_created bigint(20);";
$sqlArray[] = "ALTER TABLE users ADD COLUMN date_modified bigint(20);";
break;
case '2.4.71':
$sqlArray[] = "UPDATE attributes SET comment = '' WHERE comment is NULL;";
$sqlArray[] = "ALTER TABLE attributes CHANGE comment comment text COLLATE utf8_bin NOT NULL;";
break;
case 'fixNonEmptySharingGroupID':
$sqlArray[] = 'UPDATE `events` SET `sharing_group_id` = 0 WHERE `distribution` != 4;';
$sqlArray[] = 'UPDATE `attributes` SET `sharing_group_id` = 0 WHERE `distribution` != 4;';

View File

@ -47,7 +47,7 @@ class Attribute extends AppModel {
0 => 'Your organisation only', 1 => 'This community only', 2 => 'Connected communities', 3 => 'All communities', 4 => 'Sharing group', 5 => 'Inherit event'
);
public $shortDist = array(0 => 'Organisation', 1 => 'Community', 2 => 'Connected', 3 => 'All', 4 => ' sharing Group', 5 => 'Inherit');
public $shortDist = array(0 => 'Organisation', 1 => 'Community', 2 => 'Connected', 3 => 'All', 4 => ' Sharing Group', 5 => 'Inherit');
// these are definitions of possible types + their descriptions and maybe later other behaviors
// e.g. if the attribute should be correlated with others or not
@ -74,6 +74,24 @@ class Attribute extends AppModel {
'nationality'
);
public $searchResponseTypes = array(
'xml' => array(
'type' => 'xml',
'layout' => 'xml/default',
'header' => 'Content-Disposition: download; filename="misp.search.attribute.results.xml"'
),
'json' => array(
'type' => 'json',
'layout' => 'json/default',
'header' => 'Content-Disposition: download; filename="misp.search.attribute.results.json"'
),
'openioc' => array(
'type' => 'xml',
'layout' => 'xml/default',
'header' => 'Content-Disposition: download; filename="misp.search.attribute.results.openioc.xml"'
),
);
public $typeDefinitions = array(
'md5' => array('desc' => 'A checksum in md5 format', 'formdesc' => "You are encouraged to use filename|md5 instead. A checksum in md5 format, only use this if you don't know the correct filename", 'default_category' => 'Payload delivery', 'to_ids' => 1),
'sha1' => array('desc' => 'A checksum in sha1 format', 'formdesc' => "You are encouraged to use filename|sha1 instead. A checksum in sha1 format, only use this if you don't know the correct filename", 'default_category' => 'Payload delivery', 'to_ids' => 1),
@ -92,6 +110,7 @@ class Attribute extends AppModel {
'email-dst' => array('desc' => "A recipient email address", 'formdesc' => "A recipient email address that is not related to your constituency.", 'default_category' => 'Network activity', 'to_ids' => 1),
'email-subject' => array('desc' => "The subject of the email", 'default_category' => 'Payload delivery', 'to_ids' => 0),
'email-attachment' => array('desc' => "File name of the email attachment.", 'default_category' => 'Payload delivery', 'to_ids' => 1),
'float' => array('desc' => "A floating point value.", 'default_category' => 'Other', 'to_ids' => 0),
'url' => array('desc' => 'url', 'default_category' => 'External analysis', 'to_ids' => 1),
'http-method' => array('desc' => "HTTP method used by the malware (e.g. POST, GET, ...).", 'default_category' => 'Network activity', 'to_ids' => 0),
'user-agent' => array('desc' => "The user-agent used by the malware in the HTTP request.", 'default_category' => 'Network activity', 'to_ids' => 0),
@ -103,12 +122,14 @@ class Attribute extends AppModel {
'pattern-in-traffic' => array('desc' => 'Pattern in network traffic that identifies the malware', 'default_category' => 'Network activity', 'to_ids' => 1),
'pattern-in-memory' => array('desc' => 'Pattern in memory dump that identifies the malware', 'default_category' => 'Payload installation', 'to_ids' => 1),
'yara' => array('desc' => 'Yara signature', 'default_category' => 'Payload installation', 'to_ids' => 1),
'sigma' => array('desc' => 'Sigma - Generic Signature Format for SIEM Systems', 'default_category' => 'Payload installation', 'to_ids' => 1),
'vulnerability' => array('desc' => 'A reference to the vulnerability used in the exploit', 'default_category' => 'External analysis', 'to_ids' => 0),
'attachment' => array('desc' => 'Attachment with external information', 'formdesc' => "Please upload files using the <em>Upload Attachment</em> button.", 'default_category' => 'External analysis', 'to_ids' => 0),
'malware-sample' => array('desc' => 'Attachment containing encrypted malware sample', 'formdesc' => "Please upload files using the <em>Upload Attachment</em> button.", 'default_category' => 'Payload delivery', 'to_ids' => 1),
'link' => array('desc' => 'Link to an external information', 'default_category' => 'External analysis', 'to_ids' => 0),
'comment' => array('desc' => 'Comment or description in a human language', 'formdesc' => 'Comment or description in a human language. This will not be correlated with other attributes', 'default_category' => 'Other', 'to_ids' => 0),
'text' => array('desc' => 'Name, ID or a reference', 'default_category' => 'Other', 'to_ids' => 0),
'hex' => array('desc' => 'A value in hexadecimal format', 'default_category' => 'Other', 'to_ids' => 0),
'other' => array('desc' => 'Other attribute', 'default_category' => 'Other', 'to_ids' => 0),
'named pipe' => array('desc' => 'Named pipe, use the format \\.\pipe\<PipeName>', 'default_category' => 'Artifacts dropped', 'to_ids' => 0),
'mutex' => array('desc' => 'Mutex, use the format \BaseNamedObjects\<Mutex>', 'default_category' => 'Artifacts dropped', 'to_ids' => 1),
@ -135,6 +156,7 @@ class Attribute extends AppModel {
'ssdeep' => array('desc' => 'A checksum in ssdeep format', 'formdesc' => "You are encouraged to use filename|ssdeep instead. A checksum in the SSDeep format, only use this if you don't know the correct filename", 'default_category' => 'Payload delivery', 'to_ids' => 1),
'imphash' => array('desc' => 'Import hash - a hash created based on the imports in the sample.', 'formdesc' => "You are encouraged to use filename|imphash instead. A hash created based on the imports in the sample, only use this if you don't know the correct filename", 'default_category' => 'Payload delivery', 'to_ids' => 1),
'pehash' => array('desc' => 'PEhash - a hash calculated based of certain pieces of a PE executable file', 'default_category' => 'Payload delivery', 'to_ids' => 1),
'impfuzzy' => array('desc' => 'A fuzzy hash of import table of Portable Executable format', 'formdesc' => "You are encouraged to use filename|impfuzzy instead. A fuzzy hash created based on the imports in the sample, only use this if you don't know the correct filename", 'default_category' => 'Payload delivery', 'to_ids' => 1),
'sha224' => array('desc' => 'A checksum in sha-224 format', 'formdesc' => "You are encouraged to use filename|sha224 instead. A checksum in sha224 format, only use this if you don't know the correct filename", 'default_category' => 'Payload delivery', 'to_ids' => 1),
'sha384' => array('desc' => 'A checksum in sha-384 format', 'formdesc' => "You are encouraged to use filename|sha384 instead. A checksum in sha384 format, only use this if you don't know the correct filename", 'default_category' => 'Payload delivery', 'to_ids' => 1),
'sha512' => array('desc' => 'A checksum in sha-512 format', 'formdesc' => "You are encouraged to use filename|sha512 instead. A checksum in sha512 format, only use this if you don't know the correct filename", 'default_category' => 'Payload delivery', 'to_ids' => 1),
@ -144,6 +166,7 @@ class Attribute extends AppModel {
'filename|authentihash' => array('desc' => 'A checksum in md5 format', 'default_category' => 'Payload delivery', 'to_ids' => 1),
'filename|ssdeep' => array('desc' => 'A checksum in ssdeep format', 'default_category' => 'Payload delivery', 'to_ids' => 1),
'filename|imphash' => array('desc' => 'Import hash - a hash created based on the imports in the sample.', 'default_category' => 'Payload delivery', 'to_ids' => 1),
'filename|impfuzzy' => array('desc' => 'Import fuzzy hash - a fuzzy hash created based on the imports in the sample.', 'default_category' => 'Payload delivery', 'to_ids' => 1),
'filename|pehash' => array('desc' => 'A filename and a PEhash separated by a |', 'default_category' => 'Payload delivery', 'to_ids' => 1),
'filename|sha224' => array('desc' => 'A filename and a sha-224 hash separated by a |', 'default_category' => 'Payload delivery', 'to_ids' => 1),
'filename|sha384' => array('desc' => 'A filename and a sha-384 hash separated by a |', 'default_category' => 'Payload delivery', 'to_ids' => 1),
@ -221,7 +244,7 @@ class Attribute extends AppModel {
public $categoryDefinitions = array(
'Internal reference' => array(
'desc' => 'Reference used by the publishing party (e.g. ticket number)',
'types' => array('text', 'link', 'comment', 'other')
'types' => array('text', 'link', 'comment', 'other', 'hex')
),
'Targeting data' => array(
'desc' => 'Internal Attack Targeting and Compromise Information',
@ -231,30 +254,30 @@ class Attribute extends AppModel {
'Antivirus detection' => array(
'desc' => 'All the info about how the malware is detected by the antivirus products',
'formdesc' => 'List of anti-virus vendors detecting the malware or information on detection performance (e.g. 13/43 or 67%). Attachment with list of detection or link to VirusTotal could be placed here as well.',
'types' => array('link', 'comment', 'text', 'attachment', 'other')
'types' => array('link', 'comment', 'text', 'hex', 'attachment', 'other')
),
'Payload delivery' => array(
'desc' => 'Information about how the malware is delivered',
'formdesc' => 'Information about the way the malware payload is initially delivered, for example information about the email or web-site, vulnerability used, originating IP etc. Malware sample itself should be attached here.',
'types' => array('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512', 'sha512/224', 'sha512/256', 'ssdeep', 'imphash', 'authentihash', 'pehash', 'tlsh', 'filename', 'filename|md5', 'filename|sha1', 'filename|sha224', 'filename|sha256', 'filename|sha384', 'filename|sha512', 'filename|sha512/224', 'filename|sha512/256', 'filename|authentihash', 'filename|ssdeep', 'filename|tlsh', 'filename|imphash', 'filename|pehash', 'ip-src', 'ip-dst', 'ip-dst|port', 'ip-src|port', 'hostname', 'domain', 'email-src', 'email-dst', 'email-subject', 'email-attachment', 'url', 'user-agent', 'AS', 'pattern-in-file', 'pattern-in-traffic', 'yara', 'attachment', 'malware-sample', 'link', 'malware-type', 'comment', 'text', 'vulnerability', 'x509-fingerprint-sha1', 'other', 'ip-dst|port', 'ip-src|port', 'hostname|port', 'email-dst-display-name', 'email-src-display-name', 'email-header', 'email-reply-to', 'email-x-mailer', 'email-mime-boundary', 'email-thread-index', 'email-message-id', 'mobile-application-id')
'types' => array('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512', 'sha512/224', 'sha512/256', 'ssdeep', 'imphash', 'impfuzzy','authentihash', 'pehash', 'tlsh', 'filename', 'filename|md5', 'filename|sha1', 'filename|sha224', 'filename|sha256', 'filename|sha384', 'filename|sha512', 'filename|sha512/224', 'filename|sha512/256', 'filename|authentihash', 'filename|ssdeep', 'filename|tlsh', 'filename|imphash','filename|impfuzzy', 'filename|pehash', 'ip-src', 'ip-dst', 'ip-dst|port', 'ip-src|port', 'hostname', 'domain', 'email-src', 'email-dst', 'email-subject', 'email-attachment', 'url', 'user-agent', 'AS', 'pattern-in-file', 'pattern-in-traffic', 'yara', 'sigma', 'attachment', 'malware-sample', 'link', 'malware-type', 'comment', 'text', 'hex', 'vulnerability', 'x509-fingerprint-sha1', 'other', 'ip-dst|port', 'ip-src|port', 'hostname|port', 'email-dst-display-name', 'email-src-display-name', 'email-header', 'email-reply-to', 'email-x-mailer', 'email-mime-boundary', 'email-thread-index', 'email-message-id', 'mobile-application-id')
),
'Artifacts dropped' => array(
'desc' => 'Any artifact (files, registry keys etc.) dropped by the malware or other modifications to the system',
'types' => array('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512', 'sha512/224', 'sha512/256', 'ssdeep', 'imphash', 'authentihash', 'filename', 'filename|md5', 'filename|sha1', 'filename|sha224', 'filename|sha256', 'filename|sha384', 'filename|sha512', 'filename|sha512/224', 'filename|sha512/256', 'filename|authentihash', 'filename|ssdeep', 'filename|tlsh', 'filename|imphash', 'filename|pehash', 'regkey', 'regkey|value', 'pattern-in-file', 'pattern-in-memory','pdb', 'yara', 'attachment', 'malware-sample', 'named pipe', 'mutex', 'windows-scheduled-task', 'windows-service-name', 'windows-service-displayname', 'comment', 'text', 'x509-fingerprint-sha1', 'other')
'types' => array('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512', 'sha512/224', 'sha512/256', 'ssdeep', 'imphash', 'impfuzzy','authentihash', 'filename', 'filename|md5', 'filename|sha1', 'filename|sha224', 'filename|sha256', 'filename|sha384', 'filename|sha512', 'filename|sha512/224', 'filename|sha512/256', 'filename|authentihash', 'filename|ssdeep', 'filename|tlsh', 'filename|imphash', 'filename|impfuzzy','filename|pehash', 'regkey', 'regkey|value', 'pattern-in-file', 'pattern-in-memory','pdb', 'yara', 'sigma', 'attachment', 'malware-sample', 'named pipe', 'mutex', 'windows-scheduled-task', 'windows-service-name', 'windows-service-displayname', 'comment', 'text', 'hex', 'x509-fingerprint-sha1', 'other')
),
'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. For example, a filename|md5 type attribute can be added here like this: c:\\windows\\system32\\malicious.exe|41d8cd98f00b204e9800998ecf8427e.',
'types' => array('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512', 'sha512/224', 'sha512/256', 'ssdeep', 'imphash', 'authentihash', 'pehash', 'tlsh', 'filename', 'filename|md5', 'filename|sha1', 'filename|sha224', 'filename|sha256', 'filename|sha384', 'filename|sha512', 'filename|sha512/224', 'filename|sha512/256', 'filename|authentihash', 'filename|ssdeep', 'filename|tlsh', 'filename|imphash', 'filename|pehash', 'pattern-in-file', 'pattern-in-traffic', 'pattern-in-memory', 'yara', 'vulnerability', 'attachment', 'malware-sample', 'malware-type', 'comment', 'text', 'x509-fingerprint-sha1', 'mobile-application-id', 'other')
'types' => array('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512', 'sha512/224', 'sha512/256', 'ssdeep', 'imphash','impfuzzy','authentihash', 'pehash', 'tlsh', 'filename', 'filename|md5', 'filename|sha1', 'filename|sha224', 'filename|sha256', 'filename|sha384', 'filename|sha512', 'filename|sha512/224', 'filename|sha512/256', 'filename|authentihash', 'filename|ssdeep', 'filename|tlsh', 'filename|imphash', 'filename|impfuzzy','filename|pehash', 'pattern-in-file', 'pattern-in-traffic', 'pattern-in-memory', 'yara', 'sigma', 'vulnerability', 'attachment', 'malware-sample', 'malware-type', 'comment', 'text', 'hex', 'x509-fingerprint-sha1', 'mobile-application-id', 'other')
),
'Persistence mechanism' => array(
'desc' => 'Mechanisms used by the malware to start at boot',
'formdesc' => 'Mechanisms used by the malware to start at boot. This could be a registry key, legitimate driver modification, LNK file in startup',
'types' => array('filename', 'regkey', 'regkey|value', 'comment', 'text', 'other')
'types' => array('filename', 'regkey', 'regkey|value', 'comment', 'text', 'other', 'hex')
),
'Network activity' => array(
'desc' => 'Information about network traffic generated by the malware',
'types' => array('ip-src', 'ip-dst', 'ip-dst|port', 'ip-src|port', 'hostname', 'domain', 'domain|ip', 'email-dst', 'url', 'uri', 'user-agent', 'http-method', 'AS', 'snort', 'pattern-in-file', 'pattern-in-traffic', 'attachment', 'comment', 'text', 'x509-fingerprint-sha1', 'other')
'types' => array('ip-src', 'ip-dst', 'ip-dst|port', 'ip-src|port', 'hostname', 'domain', 'domain|ip', 'email-dst', 'url', 'uri', 'user-agent', 'http-method', 'AS', 'snort', 'pattern-in-file', 'pattern-in-traffic', 'attachment', 'comment', 'text', 'x509-fingerprint-sha1', 'other', 'hex')
),
'Payload type' => array(
'desc' => 'Information about the final payload(s)',
@ -273,11 +296,11 @@ class Attribute extends AppModel {
'Financial fraud' => array(
'desc' => 'Financial Fraud indicators',
'formdesc' => 'Financial Fraud indicators, for example: IBAN Numbers, BIC codes, Credit card numbers, etc.',
'types' => array('btc', 'iban', 'bic', 'bank-account-nr', 'aba-rtn', 'bin', 'cc-number', 'prtn', 'comment', 'text', 'other'),
'types' => array('btc', 'iban', 'bic', 'bank-account-nr', 'aba-rtn', 'bin', 'cc-number', 'prtn', 'comment', 'text', 'other', 'hex'),
),
'Support Tool' => array(
'desc' => 'Tools supporting analysis or detection of the event',
'types' => array('link', 'text', 'attachment', 'comment', 'text', 'other')
'types' => array('link', 'text', 'attachment', 'comment', 'text', 'other', 'hex')
),
'Social network' => array(
'desc' => 'Social networks and platforms',
@ -290,7 +313,7 @@ class Attribute extends AppModel {
),
'Other' => array(
'desc' => 'Attributes that are not part of any other category or are meant to be used as a component in MISP objects in the future',
'types' => array('size-in-bytes', 'counter', 'datetime', 'cpe', 'port', 'comment', 'text', 'other')
'types' => array('comment', 'text', 'other', 'size-in-bytes', 'counter', 'datetime', 'cpe', 'port', 'float', 'hex')
)
);
@ -305,6 +328,7 @@ class Attribute extends AppModel {
'sha512/256' => 'Payload delivery',
'authentihash' => 'Payload delivery',
'imphash' => 'Payload delivery',
'impfuzzy'=> 'Payload delivery',
'pehash' => 'Payload delivery',
'filename|md5' => 'Payload delivery',
'filename|sha1' => 'Payload delivery',
@ -320,6 +344,7 @@ class Attribute extends AppModel {
'email-src' => 'Payload delivery',
'email-dst' => 'Payload delivery',
'text' => 'Other',
'hex' => 'Other',
'attachment' => 'External analysis',
'malware-sample' => 'Payload delivery'
);
@ -329,7 +354,7 @@ class Attribute extends AppModel {
// whilst filenames and hashes are file related attribute types
// This helps generate quick filtering for the event view, but we may reuse this and enhance it in the future for other uses (such as the API?)
public $typeGroupings = array(
'file' => array('attachment', 'pattern-in-file', 'md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512', 'sha512/224', 'sha512/256', 'ssdeep', 'imphash', 'authentihash', 'pehash', 'tlsh', 'filename', 'filename|md5', 'filename|sha1', 'filename|sha224', 'filename|sha256', 'filename|sha384', 'filename|sha512', 'filename|sha512/224', 'filename|sha512/256', 'filename|authentihash', 'filename|ssdeep', 'filename|tlsh', 'filename|imphash', 'filename|pehash', 'malware-sample', 'x509-fingerprint-sha1'),
'file' => array('attachment', 'pattern-in-file', 'md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512', 'sha512/224', 'sha512/256', 'ssdeep', 'imphash', 'impfuzzy','authentihash', 'pehash', 'tlsh', 'filename', 'filename|md5', 'filename|sha1', 'filename|sha224', 'filename|sha256', 'filename|sha384', 'filename|sha512', 'filename|sha512/224', 'filename|sha512/256', 'filename|authentihash', 'filename|ssdeep', 'filename|tlsh', 'filename|imphash', 'filename|pehash', 'malware-sample', 'x509-fingerprint-sha1'),
'network' => array('ip-src', 'ip-dst', 'ip-src|port', 'ip-dst|port', 'hostname', 'hostname|port', 'domain', 'domain|ip', 'email-dst', 'url', 'uri', 'user-agent', 'http-method', 'AS', 'snort', 'pattern-in-traffic', 'x509-fingerprint-sha1'),
'financial' => array('btc', 'iban', 'bic', 'bank-account-nr', 'aba-rtn', 'bin', 'cc-number', 'prtn')
);
@ -493,16 +518,15 @@ class Attribute extends AppModel {
if (!empty($this->data['Attribute']['type'])) {
$compositeTypes = $this->getCompositeTypes();
// explode composite types in value1 and value2
$pieces = explode('|', $this->data['Attribute']['value']);
if (in_array($this->data['Attribute']['type'], $compositeTypes)) {
$pieces = explode('|', $this->data['Attribute']['value']);
if (2 != count($pieces)) {
throw new InternalErrorException('Composite type, but value not explodable');
}
$this->data['Attribute']['value1'] = $pieces[0];
$this->data['Attribute']['value2'] = $pieces[1];
} else {
$total = implode('|', $pieces);
$this->data['Attribute']['value1'] = $total;
$this->data['Attribute']['value1'] = $this->data['Attribute']['value'];
$this->data['Attribute']['value2'] = '';
}
}
@ -565,6 +589,10 @@ class Attribute extends AppModel {
if (empty($this->data['Attribute']['to_ids'])) {
$this->data['Attribute']['to_ids'] = 0;
}
if (empty($this->data['Attribute']['comment'])) {
$this->data['Attribute']['comment'] = "";
}
// generate UUID if it doesn't exist
if (empty($this->data['Attribute']['uuid'])) {
$this->data['Attribute']['uuid'] = CakeText::uuid();
@ -751,24 +779,20 @@ class Attribute extends AppModel {
break;
case 'ip-src':
case 'ip-dst':
$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])) {
$returnValue = true;
} else {
if (is_numeric($parts[1]) && $parts[1] < 129) {
$returnValue = true;
}
}
$returnValue = true;
if (strpos($value, '/') !== false) {
$parts = explode("/", $value);
// [0] = the IP
// [1] = the network address
if (count($parts) != 2 || (!is_numeric($parts[1]) || !($parts[1] < 129 && $parts[1] > 0))) {
$returnValue = 'Invalid CIDR notation value found.';
}
$ip = $parts[0];
} else {
$ip = $value;
}
if (!$returnValue) {
$returnValue = 'IP address has an invalid format. Please double check the value or select type "other".';
if (!filter_var($ip, FILTER_VALIDATE_IP)) {
$returnValue = 'IP address has an invalid format.';
}
break;
case 'port':
@ -855,6 +879,7 @@ class Attribute extends AppModel {
case 'pattern-in-traffic':
case 'pattern-in-memory':
case 'yara':
case 'sigma':
case 'attachment':
case 'malware-sample':
$returnValue = true;
@ -870,6 +895,11 @@ class Attribute extends AppModel {
case 'other':
$returnValue = true;
break;
case 'hex':
if (preg_match("/^[0-9a-f]*$/i", $value)) {
$returnValue = true;
}
break;
case 'target-user':
case 'campaign-name':
case 'campaign-id':
@ -975,6 +1005,12 @@ class Attribute extends AppModel {
$returnValue = true;
}
break;
case 'float':
$value = floatval($value);
if (is_float($value)) {
$returnValue = true;
}
break;
}
return $returnValue;
}
@ -1076,6 +1112,12 @@ class Attribute extends AppModel {
$value = strtolower($value);
str_replace(':', '|', $value);
break;
case 'float':
$value = floatval($value);
break;
case 'hex':
$value = strtoupper($value);
break;
}
return $value;
}
@ -1532,7 +1574,7 @@ class Attribute extends AppModel {
}
public function nids($user, $format, $id = false, $continue = false, $tags = false, $from = false, $to = false, $last = false, $type = false, $enforceWarninglist = false) {
public function nids($user, $format, $id = false, $continue = false, $tags = false, $from = false, $to = false, $last = false, $type = false, $enforceWarninglist = false, $includeAllTags = false) {
if (empty($user)) throw new MethodNotAllowedException('Could not read user.');
$eventIds = $this->Event->fetchEventIds($user, $from, $to, $last);
@ -1565,7 +1607,7 @@ class Attribute extends AppModel {
$rules = array();
foreach ($eventIds as $event) {
$conditions['AND'] = array('Attribute.to_ids' => 1, "Event.published" => 1, 'Attribute.event_id' => $event['Event']['id']);
$valid_types = array('ip-dst', 'ip-src', 'email-src', 'email-dst', 'email-subject', 'email-attachment', 'domain', 'domain|ip', 'hostname', 'url', 'user-agent', 'snort');
$valid_types = array('ip-dst', 'ip-src', 'ip-dst|port', 'ip-src|port', 'email-src', 'email-dst', 'email-subject', 'email-attachment', 'domain', 'domain|ip', 'hostname', 'url', 'user-agent', 'snort');
$conditions['AND']['Attribute.type'] = $valid_types;
if (!empty($type)) {
$conditions['AND'][] = array('Attribute.type' => $type);
@ -1577,7 +1619,8 @@ class Attribute extends AppModel {
'fields' => array('Attribute.id', 'Attribute.event_id', 'Attribute.type', 'Attribute.value'),
'contain' => array('Event'=> array('fields' => array('Event.id', 'Event.threat_level_id'))),
'group' => array('Attribute.type', 'Attribute.value1'), // fields to GROUP BY
'enforceWarninglist' => $enforceWarninglist
'enforceWarninglist' => $enforceWarninglist,
'includeAllTags' => $includeAllTags
);
$items = $this->fetchAttributes($user, $params);
if (empty($items)) continue;
@ -1710,7 +1753,7 @@ class Attribute extends AppModel {
$intel = array();
foreach ($types as $type) {
//restricting to non-private or same org if the user is not a site-admin.
$conditions['AND'] = array('Attribute.to_ids =' => 1, 'Event.published =' => 1);
$conditions['AND'] = array('Attribute.to_ids' => 1, 'Event.published' => 1);
if ($from) $conditions['AND']['Event.date >='] = $from;
if ($to) $conditions['AND']['Event.date <='] = $to;
if ($last) $conditions['AND']['Event.publish_timestamp >='] = $last;
@ -2295,4 +2338,111 @@ class Attribute extends AppModel {
}
return true;
}
public function convertToOpenIOC($user, $attributes) {
return $this->IOCExport->buildAll($this->Auth->user(), $event);
}
public function setTagConditions($tags, $conditions) {
$args = $this->dissectArgs($tags);
$tagArray = $this->AttributeTag->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;
return $conditions;
}
public function setPublishTimestampConditions($publish_timestamp, $conditions) {
if (is_array($publish_timestamp)) {
$conditions['AND'][] = array('Event.publish_timestamp >=' => $publish_timestamp[0]);
$conditions['AND'][] = array('Event.publish_timestamp <=' => $publish_timestamp[1]);
} else {
$conditions['AND'][] = array('Event.publish_timestamp >=' => $publish_timestamp);
}
return $conditions;
}
public function setTimestampConditions($timestamp, $conditions, $scope = 'Event') {
if (is_array($timestamp)) {
$conditions['AND'][] = array($scope . '.timestamp >=' => $timestamp[0]);
$conditions['AND'][] = array($scope . '.timestamp <=' => $timestamp[1]);
} else {
$conditions['AND'][] = array($scope . '.timestamp >=' => $timestamp);
}
return $conditions;
}
public function setToIDSConditions($to_ids, $conditions) {
if ($to_ids === 'exclude') {
$conditions['AND'][] = array('Attribute.to_ids' => 0);
} else {
$conditions['AND'][] = array('Attribute.to_ids' => 1);
}
return $conditions;
}
public function setSimpleConditions($parameterKey, $parameterValue, $conditions) {
$subcondition = array();
App::uses('CIDRTool', 'Tools');
$cidr = new CIDRTool();
if (is_array($parameterValue)) $elements = $parameterValue;
else $elements = explode('&&', $parameterValue);
foreach ($elements as $v) {
if (empty($v)) continue;
if (substr($v, 0, 1) == '!') {
// check for an IPv4 address and subnet in CIDR notation (e.g. 127.0.0.1/8)
if ($parameterKey === 'value' && $cidr->checkCIDR(substr($v, 1), 4)) {
$cidrresults = $cidr->CIDR(substr($v, 1));
foreach ($cidrresults as $result) {
$subcondition['AND'][] = array('Attribute.value NOT LIKE' => $result);
}
} else if ($parameterKey === 'org') {
// from here
$found_orgs = $this->Event->Org->find('all', array(
'recursive' => -1,
'conditions' => array('LOWER(name) LIKE' => '%' . strtolower(substr($v, 1)) . '%'),
));
foreach ($found_orgs as $o) $subcondition['AND'][] = array('Event.orgc_id !=' => $o['Org']['id']);
} else if ($parameterKey === 'eventid') {
$subcondition['AND'][] = array('Attribute.event_id !=' => substr($v, 1));
} else if ($parameterKey === 'uuid') {
$subcondition['AND'][] = array('Event.uuid !=' => substr($v, 1));
$subcondition['AND'][] = array('Attribute.uuid !=' => substr($v, 1));
} else {
$subcondition['AND'][] = array('Attribute.' . $parameterKey . ' NOT LIKE' => '%'.substr($v, 1).'%');
}
} else {
// check for an IPv4 address and subnet in CIDR notation (e.g. 127.0.0.1/8)
if ($parameterKey === 'value' && $cidr->checkCIDR($v, 4)) {
$cidrresults = $cidr->CIDR($v);
foreach ($cidrresults as $result) {
$subcondition['OR'][] = array('Attribute.value LIKE' => $result);
}
} else if ($parameterKey === 'org') {
// from here
$found_orgs = $this->Event->Org->find('all', array(
'recursive' => -1,
'conditions' => array('LOWER(name) LIKE' => '%' . strtolower($v) . '%'),
));
foreach ($found_orgs as $o) $subcondition['OR'][] = array('Event.orgc_id' => $o['Org']['id']);
} else if ($parameterKey === 'eventid') {
if (!empty($v)) $subcondition['OR'][] = array('Attribute.event_id' => $v);
} else if ($parameterKey === 'uuid') {
$subcondition['OR'][] = array('Attribute.uuid' => $v);
$subcondition['OR'][] = array('Event.uuid' => $v);
} else {
if (!empty($v)) $subcondition['OR'][] = array('Attribute.' . $parameterKey . ' LIKE' => '%'.$v.'%');
}
}
}
array_push ($conditions['AND'], $subcondition);
return $conditions;
}
}

View File

@ -327,7 +327,7 @@ class Event extends AppModel {
public function beforeDelete($cascade = true) {
// blacklist the event UUID if the feature is enabled
if (Configure::read('MISP.enableEventBlacklisting')) {
if (Configure::read('MISP.enableEventBlacklisting') !== false) {
$this->EventBlacklist = ClassRegistry::init('EventBlacklist');
$this->EventBlacklist->create();
$orgc = $this->Orgc->find('first', array('conditions' => array('Orgc.id' => $this->data['Event']['orgc_id']), 'recursive' => -1, 'fields' => array('Orgc.name')));
@ -597,6 +597,15 @@ class Event extends AppModel {
)
)
);
$fieldsToRearrange = array('Org', 'Orgc');
foreach ($relatedEvents as $k => $relatedEvent) {
foreach ($fieldsToRearrange as $field) {
if (isset($relatedEvent[$field])) {
$relatedEvents[$k]['Event'][$field] = $relatedEvent[$field];
unset($relatedEvents[$k][$field]);
}
}
}
return $relatedEvents;
}
@ -695,6 +704,7 @@ class Event extends AppModel {
// single attribute
$data['Event'][$object] = array(0 => $data['Event'][$object]);
}
$data['Event'][$object] = array_values($data['Event'][$object]);
}
}
$objects = array('Org', 'Orgc', 'SharingGroup');
@ -734,10 +744,10 @@ class Event extends AppModel {
public function uploadEventToServer($event, $server, $HttpSocket = null) {
$this->Server = ClassRegistry::init('Server');
$push = $this->Server->checkVersionCompatibility($server['Server']['id'], false, $HttpSocket);
if (!isset($push['perm_sync'])) {
$this->Server->checkLegacyServerSyncPrivilege($server['Server']['id'], $HttpSocket);
if (!isset($push['canPush'])) {
$test = $this->Server->checkLegacyServerSyncPrivilege($server['Server']['id'], $HttpSocket);
} else {
if (!$push['perm_sync']) {
if (!$push['canPush']) {
return 'The remote user is not a sync user - the upload of the event has been blocked.';
}
}
@ -754,17 +764,12 @@ class Event extends AppModel {
$event['Attribute'] = array_values($event['Attribute']);
}
if (!isset($push['canPush']) || !$push['canPush']) {
if ($push === 'mangle' && $event['Event']['distribution'] != 4) {
$event['Event']['orgc'] = $event['Orgc']['name'];
$event['mangle'] = true;
} else return 'Trying to push to an outdated instance.';
}
$unpublish_event = $server['Server']['unpublish_event'];
// $publish_without_email = $server['Server']['publish_without_email'];
// if ($publish_without_email) {
if ($unpublish_event) {
$event['Event']['published'] = 0;
}
return 'Trying to push to an outdated instance.';
}
$unpublish_event = $server['Server']['unpublish_event'];
if ($unpublish_event) {
$event['Event']['published'] = 0;
}
$updated = null;
$newLocation = $newTextBody = '';
$result = $this->restfulEventToServer($event, $server, null, $newLocation, $newTextBody, $HttpSocket);
@ -886,85 +891,74 @@ class Event extends AppModel {
}
$data = json_encode($event);
// LATER validate HTTPS SSL certificate
$this->Dns = ClassRegistry::init('Dns');
if ($this->Dns->testipaddress(parse_url($uri, PHP_URL_HOST))) {
// TODO NETWORK for now do not know how to catch the following..
// TODO NETWORK No route to host
$response = $HttpSocket->post($uri, $data, $request);
switch ($response->code) {
case '200': // 200 (OK) + entity-action-result
if ($response->isOk()) {
$newTextBody = $response->body();
$newLocation = null;
$response = $HttpSocket->post($uri, $data, $request);
switch ($response->code) {
case '200': // 200 (OK) + entity-action-result
if ($response->isOk()) {
$newTextBody = $response->body();
$newLocation = null;
return true;
} else {
try {
$jsonArray = json_decode($response->body, true);
} catch (Exception $e) {
return true; // TODO should be false
}
if (strpos($jsonArray['name'],"Event already exists")) { // strpos, so i can piggyback some value if needed.
return true;
} else {
try {
$jsonArray = json_decode($response->body, true);
} catch (Exception $e) {
return true; // TODO should be false
}
if (strpos($jsonArray['name'],"Event already exists")) { // strpos, so i can piggyback some value if needed.
return true;
} else {
return $jsonArray['name'];
}
return $jsonArray['name'];
}
break;
case '302': // Found
$newLocation = $response->headers['Location'];
$newTextBody = $response->body();
return true;
break;
case '404': // Not Found
$newLocation = $response->headers['Location'];
$newTextBody = $response->body();
return 404;
break;
case '405':
return 405;
break;
case '403': // Not authorised
return 403;
break;
}
}
break;
case '302': // Found
$newLocation = $response->headers['Location'];
$newTextBody = $response->body();
return true;
break;
case '404': // Not Found
$newLocation = $response->headers['Location'];
$newTextBody = $response->body();
return 404;
break;
case '405':
return 405;
break;
case '403': // Not authorised
return 403;
break;
}
}
private function __updateEventForSync($event, $server) {
$mangle = isset($event['mangle']);
if (!$mangle) {
// rearrange things to be compatible with the Xml::fromArray()
$objectsToRearrange = array('Attribute', 'Orgc', 'SharingGroup', 'EventTag', 'Org', 'ShadowAttribute');
foreach ($objectsToRearrange as $o) {
if (isset($event[$o])) {
$event['Event'][$o] = $event[$o];
unset($event[$o]);
}
// rearrange things to be compatible with the Xml::fromArray()
$objectsToRearrange = array('Attribute', 'Orgc', 'SharingGroup', 'EventTag', 'Org', 'ShadowAttribute');
foreach ($objectsToRearrange as $o) {
if (isset($event[$o])) {
$event['Event'][$o] = $event[$o];
unset($event[$o]);
}
}
// cleanup the array from things we do not want to expose
foreach (array('Org', 'org_id', 'orgc_id', 'proposal_email_lock', 'org', 'orgc') as $field) unset($event['Event'][$field]);
foreach ($event['Event']['EventTag'] as $kt => $tag) {
if (!$tag['Tag']['exportable']) {
unset($event['Event']['EventTag'][$kt]);
} else {
unset($tag['org_id']);
$event['Event']['Tag'][] = $tag['Tag'];
}
// cleanup the array from things we do not want to expose
foreach (array('Org', 'org_id', 'orgc_id', 'proposal_email_lock', 'org', 'orgc') as $field) unset($event['Event'][$field]);
foreach ($event['Event']['EventTag'] as $kt => $tag) {
if (!$tag['Tag']['exportable']) {
unset($event['Event']['EventTag'][$kt]);
} else {
unset($tag['org_id']);
$event['Event']['Tag'][] = $tag['Tag'];
}
unset($event['Event']['EventTag']);
}
unset($event['Event']['EventTag']);
// Add the local server to the list of instances in the SG
if (isset($event['Event']['SharingGroup']) && isset($event['Event']['SharingGroup']['SharingGroupServer'])) {
foreach ($event['Event']['SharingGroup']['SharingGroupServer'] as &$s) {
if ($s['server_id'] == 0) {
$s['Server'] = array('id' => 0, 'url' => Configure::read('MISP.baseurl'));
}
// Add the local server to the list of instances in the SG
if (isset($event['Event']['SharingGroup']) && isset($event['Event']['SharingGroup']['SharingGroupServer'])) {
foreach ($event['Event']['SharingGroup']['SharingGroupServer'] as &$s) {
if ($s['server_id'] == 0) {
$s['Server'] = array('id' => 0, 'url' => Configure::read('MISP.baseurl'));
}
}
} else {
foreach (array('org_id', 'orgc_id', 'proposal_email_lock', 'org') as $field) unset($event['Event'][$field]);
foreach (array('Org', 'Orgc', 'SharingGroup', 'EventTag') as $field) unset($event[$field]);
}
// remove value1 and value2 from the output
if (isset($event['Event']['Attribute'])) {
@ -1020,76 +1014,14 @@ class Event extends AppModel {
}
}
if ($mangle) {
$event['Event']['timestamp'] = $event['Event']['timestamp'] -1;
if (isset($event['Attribute'])) {
foreach ($event['Attribute'] as $key => &$attribute) {
$event['Attribute'][$key]['timestamp'] = $event['Attribute'][$key]['timestamp'] -1;
if ($attribute['distribution'] == 5) $attribute['distribution'] = $event['Event']['distribution'];
if ($attribute['distribution'] < 2) {
unset($event['Event']['Attribute'][$key]);
continue;
}
if ($attribute['distribution'] == 2) {
$attribute['distribution'] = 1;
}
unset($event['Attribute'][$key]['SharingGroup'], $event['Attribute'][$key]['sharing_group_id']);
if ($attribute['distribution'] == 4) {
unset($event['Event']['Attribute'][$key]);
continue;
}
// remove value1 and value2 from the output
unset($attribute['value1']);
unset($attribute['value2']);
// also add the encoded attachment
if ($this->Attribute->typeIsAttachment($attribute['type'])) {
$encodedFile = $this->Attribute->base64EncodeAttachment($attribute);
$attribute['data'] = $encodedFile;
}
unset($attribute['id']);
}
}
}
// Downgrade the event from connected communities to community only
if (!$server['Server']['internal'] && $event['Event']['distribution'] == 2) {
$event['Event']['distribution'] = 1;
}
$event['Event']['Attribute'] = array_values($event['Event']['Attribute']);
return $event;
}
public function deleteEventFromServer($uuid, $server, $HttpSocket=null) {
// TODO private and delete(?)
$url = $server['Server']['url'];
$authkey = $server['Server']['authkey'];
if (null == $HttpSocket) {
App::uses('SyncTool', 'Tools');
$syncTool = new SyncTool();
$HttpSocket = $syncTool->setupHttpSocket($server);
}
$request = array(
'header' => array(
'Authorization' => $authkey,
'Accept' => 'application/xml',
'Content-Type' => 'application/xml',
//'Connection' => 'keep-alive' // // LATER followup cakephp issue about this problem: https://github.com/cakephp/cakephp/issues/1961
)
);
$request = $this->addHeaders($request);
$uri = $url . '/events/0?uuid=' . $uuid;
// LATER validate HTTPS SSL certificate
$this->Dns = ClassRegistry::init('Dns');
if ($this->Dns->testipaddress(parse_url($uri, PHP_URL_HOST))) {
// TODO NETWORK for now do not know how to catch the following..
// TODO NETWORK No route to host
$response = $HttpSocket->delete($uri, array(), $request);
// TODO REST, DELETE, some responce needed
}
}
public function downloadEventFromServer($eventId, $server, $HttpSocket=null) {
$url = $server['Server']['url'];
$authkey = $server['Server']['authkey'];
@ -1118,6 +1050,77 @@ class Event extends AppModel {
return null;
}
public function quickDelete($event) {
$id = $event['Event']['id'];
$this->Thread = ClassRegistry::init('Thread');
$thread = $this->Thread->find('first', array(
'conditions' => array('Thread.event_id' => $id),
'fields' => array('Thread.id'),
'recursive' => -1
));
$thread_id = !empty($thread) ? $thread['Thread']['id'] : false;
$relations = array(
array(
'table' => 'attributes',
'foreign_key' => 'event_id',
'value' => $id
),
array(
'table' => 'shadow_attributes',
'foreign_key' => 'event_id',
'value' => $id
),
array(
'table' => 'event_tags',
'foreign_key' => 'event_id',
'value' => $id
),
array(
'table' => 'attribute_tags',
'foreign_key' => 'event_id',
'value' => $id
),
array(
'table' => 'threads',
'foreign_key' => 'event_id',
'value' => $id
),
array(
'table' => 'correlations',
'foreign_key' => 'event_id',
'value' => $id
),
array(
'table' => 'correlations',
'foreign_key' => '1_event_id',
'value' => $id
),
array(
'table' => 'sightings',
'foreign_key' => 'event_id',
'value' => $id
),
array(
'table' => 'event_delegations',
'foreign_key' => 'event_id',
'value' => $id
)
);
if ($thread_id) {
$relations[] = array(
'table' => 'posts',
'foreign_key' => 'thread_id',
'value' => $thread_id
);
}
App::uses('QueryTool', 'Tools');
$queryTool = new QueryTool();
foreach ($relations as $relation) {
$queryTool->quickDelete($relation['table'], $relation['foreign_key'], $relation['value'], $this);
}
return $this->delete($id, false);
}
public function downloadProposalsFromServer($uuidList, $server, $HttpSocket = null) {
$url = $server['Server']['url'];
$authkey = $server['Server']['authkey'];
@ -1204,7 +1207,7 @@ class Event extends AppModel {
// includeAttachments: true will attach the attachments to the attributes in the data field
public function fetchEvent($user, $options = array()) {
if (isset($options['Event.id'])) $options['eventid'] = $options['Event.id'];
$possibleOptions = array('eventid', 'idList', 'tags', 'from', 'to', 'last', 'to_ids', 'includeAllTags', 'includeAttachments', 'event_uuid', 'distribution', 'sharing_group_id', 'disableSiteAdmin', 'metadata', 'includeGalaxy', 'enforceWarninglist');
$possibleOptions = array('eventid', 'idList', 'tags', 'from', 'to', 'last', 'to_ids', 'includeAllTags', 'includeAttachments', 'event_uuid', 'distribution', 'sharing_group_id', 'disableSiteAdmin', 'metadata', 'includeGalaxy', 'enforceWarninglist', 'sgReferenceOnly');
if (!isset($options['excludeGalaxy']) || !$options['excludeGalaxy']) {
$this->GalaxyCluster = ClassRegistry::init('GalaxyCluster');
}
@ -1339,7 +1342,8 @@ class Event extends AppModel {
if (!$options['includeAllTags']) $tagConditions = array('exportable' => 1);
else $tagConditions = array();
$params = array('conditions' => $conditions,
$params = array(
'conditions' => $conditions,
'recursive' => 0,
'fields' => $fields,
'contain' => array(
@ -1364,6 +1368,10 @@ class Event extends AppModel {
)
)
);
if ($options['sgReferenceOnly']) {
unset($params['contain']['SharingGroup']);
unset($params['contain']['Attribute']['SharingGroup']);
}
if ($options['metadata']) {
unset($params['contain']['Attribute']);
unset($params['contain']['ShadowAttribute']);
@ -1386,14 +1394,16 @@ class Event extends AppModel {
$event['Event']['event_creator_email'] = $UserEmail;
}
// unset the empty sharing groups that are created due to the way belongsTo is handled
if (isset($event['SharingGroup']['SharingGroupServer'])) {
foreach ($event['SharingGroup']['SharingGroupServer'] as &$sgs) {
if ($sgs['server_id'] == 0) {
$sgs['Server'] = array('id' => '0', 'url' => Configure::read('MISP.baseurl'), 'name' => Configure::read('MISP.baseurl'));
if (isset($event['SharingGroup'])) {
if (isset($event['SharingGroup']['SharingGroupServer'])) {
foreach ($event['SharingGroup']['SharingGroupServer'] as &$sgs) {
if ($sgs['server_id'] == 0) {
$sgs['Server'] = array('id' => '0', 'url' => Configure::read('MISP.baseurl'), 'name' => Configure::read('MISP.baseurl'));
}
}
}
if ($event['SharingGroup']['id'] == null) unset($event['SharingGroup']);
}
if ($event['SharingGroup']['id'] == null) unset($event['SharingGroup']);
$event['Galaxy'] = array();
// unset empty event tags that got added because the tag wasn't exportable
if (!empty($event['EventTag'])) {
@ -1457,10 +1467,12 @@ class Event extends AppModel {
$event['Attribute'][$key]['data'] = $encodedFile;
}
}
if (isset($attribute['SharingGroup']['SharingGroupServer'])) {
foreach ($attribute['SharingGroup']['SharingGroupServer'] as &$sgs) {
if ($sgs['server_id'] == 0) {
$sgs['Server'] = array('id' => '0', 'url' => Configure::read('MISP.baseurl'), 'name' => Configure::read('MISP.baseurl'));
if (isset($attribute['SharingGroup'])) {
if (isset($attribute['SharingGroup']['SharingGroupServer'])) {
foreach ($attribute['SharingGroup']['SharingGroupServer'] as &$sgs) {
if ($sgs['server_id'] == 0) {
$sgs['Server'] = array('id' => '0', 'url' => Configure::read('MISP.baseurl'), 'name' => Configure::read('MISP.baseurl'));
}
}
}
}
@ -1945,7 +1957,7 @@ class Event extends AppModel {
$data['Event']['sharing_group_id'] = $sg;
unset($data['Event']['SharingGroup']);
}
if (isset($data['Event']['Attribute'])) {
if (!empty($data['Event']['Attribute'])) {
foreach ($data['Event']['Attribute'] as $k => $a) {
unset($data['Event']['Attribute']['id']);
if (isset($a['distribution']) && $a['distribution'] == 4) {
@ -1986,7 +1998,7 @@ class Event extends AppModel {
unset($data['Event']['Tag']);
}
if (isset($data['Event']['Attribute'])) {
if (!empty($data['Event']['Attribute'])) {
foreach ($data['Event']['Attribute'] as $k => $a) {
if (isset($data['Event']['Attribute'][$k]['AttributeTag'])) {
if (isset($data['Event']['Attribute'][$k]['AttributeTag']['id'])) $data['Event']['Attribute'][$k]['AttributeTag'] = array($data['Event']['Attribute'][$k]['AttributeTag']);
@ -2017,7 +2029,7 @@ class Event extends AppModel {
if ($jobId) {
App::uses('AuthComponent', 'Controller/Component');
}
if (Configure::read('MISP.enableEventBlacklisting') && isset($data['Event']['uuid'])) {
if (Configure::read('MISP.enableEventBlacklisting') !== false && isset($data['Event']['uuid'])) {
$this->EventBlacklist = ClassRegistry::init('EventBlacklist');
$r = $this->EventBlacklist->find('first', array('conditions' => array('event_uuid' => $data['Event']['uuid'])));
if (!empty($r)) return 'blocked';
@ -2044,9 +2056,13 @@ class Event extends AppModel {
}
if (isset($data['Event']['orgc_id']) && $data['Event']['orgc_id'] != $user['org_id'] && !$user['Role']['perm_sync'] && !$user['Role']['perm_site_admin']) throw new MethodNotAllowedException('Event cannot be created as you are not a member of the creator organisation.');
}
if (Configure::read('MISP.enableOrgBlacklisting')) {
if (!Configure::check('MISP.enableOrgBlacklisting') || Configure::read('MISP.enableOrgBlacklisting') !== false) {
$this->OrgBlacklist = ClassRegistry::init('OrgBlacklist');
$orgc = $this->Orgc->find('first', array('conditions' => array('Orgc.id' => $data['Event']['orgc_id']), 'fields' => array('Orgc.uuid'), 'recursive' => -1));
if (!isset($data['Event']['Orgc']['uuid'])) {
$orgc = $this->Orgc->find('first', array('conditions' => array('Orgc.id' => $data['Event']['orgc_id']), 'fields' => array('Orgc.uuid'), 'recursive' => -1));
} else {
$orgc = array('Orgc' => array('uuid' => $data['Event']['Orgc']['uuid']));
}
if ($this->OrgBlacklist->hasAny(array('OrgBlacklist.org_uuid' => $orgc['Orgc']['uuid']))) return 'blocked';
}
if ($fromXml) {
@ -2148,7 +2164,7 @@ class Event extends AppModel {
'action' => 'add',
'user_id' => $user['id'],
'title' => 'Attribute dropped due to validation for Event ' . $this->id . ' failed: ' . $attribute_short,
'change' => json_encode($this->Attribute->validationErrors),
'change' => 'Validation errors: ' . json_encode($this->Attribute->validationErrors) . ' Full Attribute: ' . json_encode($attribute),
));
} else {
if (isset($attribute['AttributeTag'])) {
@ -2243,6 +2259,7 @@ class Event extends AppModel {
if ($saveResult) {
$validationErrors = array();
if (isset($data['Event']['Attribute'])) {
$data['Event']['Attribute'] = array_values($data['Event']['Attribute']);
foreach ($data['Event']['Attribute'] as $k => $attribute) {
$attribute['event_id'] = $existingEvent['Event']['id'];
if (isset($attribute['encrypt'])) {
@ -2334,7 +2351,7 @@ class Event extends AppModel {
'action' => 'edit',
'user_id' => $user['id'],
'title' => 'Attribute dropped due to validation for Event ' . $this->id . ' failed: ' . $attribute_short,
'change' => json_encode($this->Attribute->validationErrors),
'change' => 'Validation errors: ' . json_encode($this->Attribute->validationErrors) . ' Full Attribute: ' . json_encode($attribute),
));
} else {
if (isset($data['Event']['Attribute'][$k]['Tag']) && $user['Role']['perm_tagger']) {
@ -2454,7 +2471,7 @@ class Event extends AppModel {
// If the distribution is org only / comm only, return false
// If the distribution is sharing group only, check if the sync user is in the sharing group or not, return true if yes, false if no
public function checkDistributionForPush($object, $server, $context = 'Event') {
if (empty(Configure::read('MISP.host_org_id')) || !$server['Server']['internal'] || Configure::read('MISP.host_org_id') != $server['Server']['remote_org_id']) {
if (empty(Configure::read('MISP.host_org_id')) || !$server['Server']['internal'] || Configure::read('MISP.host_org_id') != $server['Server']['remote_org_id']) {
if ($object[$context]['distribution'] < 2) return false;
}
if ($object[$context]['distribution'] == 4) {
@ -2522,9 +2539,9 @@ class Event extends AppModel {
if ($passAlong) $conditions[] = array('Server.id !=' => $passAlong);
$servers = $this->Server->find('all', array('conditions' => $conditions));
// iterate over the servers and upload the event
if (empty($servers))
if (empty($servers)) {
return true;
}
$uploaded = true;
$failedServers = array();
App::uses('SyncTool', 'Tools');
@ -3168,6 +3185,7 @@ class Event extends AppModel {
$temp['default_category'] = $r['categories'][0];
}
if (isset($r['data'])) $temp['data'] = $r['data'];
if (isset($r['distribution'])) $temp['distribution'] = $r['distribution'];
// if data_is_handled is set then MISP assumes that the sample is already zipped and encrypted
// in this case it will not try to do this by itself - however it also won't create additional hashes
if (isset($r['data_is_handled'])) $temp['data_is_handled'] = $r['data_is_handled'];
@ -3188,6 +3206,11 @@ class Event extends AppModel {
$events = $this->fetchEvent($user, $options);
if (empty($events)) return 'Invalid event.';
$modulePayload = array('module' => $module['name']);
if (isset($module['meta']['config'])) {
foreach ($module['meta']['config'] as $conf) {
$modulePayload['config'][$conf] = Configure::read('Plugin.Export_' . $module['name'] . '_' . $conf);
}
}
$modulePayload['data'] = $events;
$result = $this->Module->queryModuleServer('/query', json_encode($modulePayload, true), false, 'Export');
return array(
@ -3276,4 +3299,71 @@ class Event extends AppModel {
}
return array('data' => array(), 'csv' => array());
}
public function setSimpleConditions($parameterKey, $parameterValue, $conditions) {
if (is_array($parameterValue)) {
$elements = $parameterValue;
} else {
$elements = explode('&&', $parameterValue);
}
App::uses('CIDRTool', 'Tools');
$cidr = new CIDRTool();
$subcondition = array();
foreach ($elements as $v) {
if ($v == '') continue;
if (substr($v, 0, 1) == '!') {
// check for an IPv4 address and subnet in CIDR notation (e.g. 127.0.0.1/8)
if ($parameterKey === 'value' && $cidr->checkCIDR(substr($v, 1), 4)) {
$cidrresults = $cidr->CIDR(substr($v, 1));
foreach ($cidrresults as $result) {
$subcondition['AND'][] = array('Attribute.value NOT LIKE' => $result);
}
} else {
if ($parameterKey === 'org') {
$found_orgs = $this->Org->find('all', array(
'recursive' => -1,
'conditions' => array('LOWER(name) LIKE' => '%' . strtolower(substr($v, 1)) . '%'),
));
foreach ($found_orgs as $o) {
$subcondition['AND'][] = array('Event.orgc_id !=' => $o['Org']['id']);
}
} else if ($parameterKey === 'eventid') {
$subcondition['AND'][] = array('Attribute.event_id !=' => substr($v, 1));
} else if ($parameterKey === 'uuid') {
$subcondition['AND'][] = array('Event.uuid !=' => substr($v, 1));
$subcondition['AND'][] = array('Attribute.uuid !=' => substr($v, 1));
} else {
$subcondition['AND'][] = array('Attribute.' . $parameterKey . ' NOT LIKE' => '%'.substr($v, 1).'%');
}
}
} else {
// check for an IPv4 address and subnet in CIDR notation (e.g. 127.0.0.1/8)
if ($parameterKey === 'value' && $cidr->checkCIDR($v, 4)) {
$cidrresults = $cidr->CIDR($v);
foreach ($cidrresults as $result) {
if (!empty($result)) $subcondition['OR'][] = array('Attribute.value LIKE' => $result);
}
} else {
if ($parameterKey === 'org') {
$found_orgs = $this->Org->find('all', array(
'recursive' => -1,
'conditions' => array('LOWER(name) LIKE' => '%' . strtolower($v) . '%'),
));
foreach ($found_orgs as $o) {
$subcondition['OR'][] = array('Event.orgc_id' => $o['Org']['id']);
}
} else if ($parameterKey === 'eventid') {
$subcondition['OR'][] = array('Attribute.event_id' => $v);
} else if ($parameterKey === 'uuid') {
$subcondition['OR'][] = array('Attribute.uuid' => $v);
$subcondition['OR'][] = array('Event.uuid' => $v);
}else {
if (!empty($v)) $subcondition['OR'][] = array('Attribute.' . $parameterKey . ' LIKE' => '%'.$v.'%');
}
}
}
}
if (!empty($subcondition)) array_push ($conditions['AND'], $subcondition);
return $conditions;
}
}

View File

@ -29,14 +29,16 @@ class Organisation extends AppModel{
'uuid' => array(
'unique' => array(
'rule' => 'isUnique',
'message' => 'An organisation with this UUID already exists.',
'allowEmpty' => true
'message' => 'An organisation with this UUID already exists.'
),
'uuid' => array(
'rule' => array('uuid'),
'message' => 'Please provide a valid UUID',
'allowEmpty' => true
),
'valueNotEmpty' => array(
'rule' => array('valueNotEmpty'),
)
)
);
@ -80,7 +82,7 @@ class Organisation extends AppModel{
public function beforeValidate($options = array()) {
parent::beforeValidate();
if (empty($this->data['Organisation']['uuid']) && (isset($this->data['Organisation']['local']) && $this->data['Organisation']['local'])) {
if (empty($this->data['Organisation']['uuid'])) {
$this->data['Organisation']['uuid'] = CakeText::uuid();
}
$date = date('Y-m-d H:i:s');

View File

@ -41,7 +41,7 @@ class Role extends AppModel {
public $permFlags = array(
'perm_admin' => array('id' => 'RolePermAdmin', 'text' => 'Admin', 'readonlyenabled' => false),
'perm_site_admin' => array('id' => 'RolePermSiteAdmin', 'text' => 'Site Admin', 'readonlyenabled' => false),
'perm_sync' => array('id' => 'RolePermSync', 'text' => 'Sync Actions', 'readonlyenabled' => false),
'perm_sync' => array('id' => 'RolePermSync', 'text' => 'Sync Actions', 'readonlyenabled' => true),
'perm_audit' => array('id' => 'RolePermAudit', 'text' => 'Audit Actions', 'readonlyenabled' => true),
'perm_auth' => array('id' => 'RolePermAuth', 'text' => 'Auth key access', 'readonlyenabled' => true),
'perm_regexp_access' => array('id' => 'RolePermRegexpAccess', 'text' => 'Regex Actions', 'readonlyenabled' => false),

View File

@ -161,6 +161,16 @@ class Server extends AppModel {
'test' => 'testForEmpty',
'type' => 'string',
),
'disable_cached_exports' => array(
'level' => 1,
'description' => 'Cached exports can take up a considerable amount of space and can be disabled instance wide using this setting. Disabling the cached exports is not recommended as it\'s a valuable feature, however, if your server is having free space issues it might make sense to take this step.',
'value' => false,
'null' => true,
'errorMessage' => '',
'test' => 'testDisableCache',
'type' => 'boolean',
'afterHook' => 'disableCacheAfterHook',
),
'header' => array(
'level' => 3,
'description' => 'This setting is deprecated and can be safely removed.',
@ -532,18 +542,16 @@ class Server extends AppModel {
'enableEventBlacklisting' => array(
'level' => 1,
'description' => 'Since version 2.3.107 you can start blacklisting event UUIDs to prevent them from being pushed to your instance. This functionality will also happen silently whenever an event is deleted, preventing a deleted event from being pushed back from another instance.',
'value' => false,
'value' => true,
'type' => 'boolean',
'test' => 'testBool',
'beforeHook' => 'eventBlacklistingBeforeHook'
'test' => 'testBool'
),
'enableOrgBlacklisting' => array(
'level' => 1,
'description' => 'Blacklisting organisation UUIDs to prevent the creation of any event created by the blacklisted organisation.',
'value' => false,
'value' => true,
'type' => 'boolean',
'test' => 'testBool',
'beforeHook' => 'orgBlacklistingBeforeHook'
'test' => 'testBool'
),
'log_client_ip' => array(
'level' => 1,
@ -562,15 +570,6 @@ class Server extends AppModel {
'test' => 'testBool',
'type' => 'boolean',
),
'ManglePushTo23' => array(
'level' => 0,
'description' => 'When enabled, your 2.4+ instance can push events to MISP 2.3 installations. This is highly advised against and will result in degraded events and lost information. Use this at your own risk.',
'value' => false,
'errorMessage' => '',
'test' => 'testMangle',
'type' => 'boolean',
'null' => true
),
'delegation' => array(
'level' => 1,
'description' => 'This feature allows users to created org only events and ask another organisation to take owenership of the event. This allows organisations to remain anonymous by asking a partner to publish an event for them.',
@ -886,16 +885,16 @@ class Server extends AppModel {
),
'password_policy_length' => array(
'level' => 2,
'description' => 'Password length requirement. If it is not set or it is set to 0, then the default value is assumed (6).',
'value' => '',
'description' => 'Password length requirement. If it is not set or it is set to 0, then the default value is assumed (12).',
'value' => '12',
'errorMessage' => '',
'test' => 'testPasswordLength',
'type' => 'numeric',
),
'password_policy_complexity' => array(
'level' => 2,
'description' => 'Password complexity requirement. Leave it empty for the default setting (3 out of 4, with either a digit or a special char) or enter your own regex. Keep in mind that the length is checked in another key. Example (simple 4 out of 4): /((?=.*\d)|(?=.*\W+))(?![\n])(?=.*[A-Z])(?=.*[a-z]).*$/',
'value' => '',
'description' => 'Password complexity requirement. Leave it empty for the default setting (3 out of 4, with either a digit or a special char) or enter your own regex. Keep in mind that the length is checked in another key. Default (simple 3 out of 4 or minimum 16 characters): /^((?=.*\d)|(?=.*\W+))(?![\n])(?=.*[A-Z])(?=.*[a-z]).*$|.{16,}/',
'value' => '/^((?=.*\d)|(?=.*\W+))(?![\n])(?=.*[A-Z])(?=.*[a-z]).*$|.{16,}/',
'errorMessage' => '',
'test' => 'testPasswordRegex',
'type' => 'string',
@ -1442,7 +1441,7 @@ class Server extends AppModel {
$server);
if (null != $event) {
$blocked = false;
if (Configure::read('MISP.enableEventBlacklisting')) {
if (Configure::read('MISP.enableEventBlacklisting') !== false) {
$this->EventBlacklist = ClassRegistry::init('EventBlacklist');
$r = $this->EventBlacklist->find('first', array('conditions' => array('event_uuid' => $event['Event']['uuid'])));
if (!empty($r)) {
@ -1655,6 +1654,7 @@ class Server extends AppModel {
)
);
$uri = $url . '/events/index';
$filter_rules['minimal'] = 1;
try {
$response = $HttpSocket->post($uri, json_encode($filter_rules), $request);
if ($response->isOk()) {
@ -1730,20 +1730,17 @@ class Server extends AppModel {
} else {
$this->redirect(array('action' => 'index'));
}
if ($push !== 'mangle') {
$sgs = $this->Event->SharingGroup->find('all', array(
'recursive' => -1,
'contain' => array('Organisation', 'SharingGroupOrg', 'SharingGroupServer')
));
$sgIds = array();
foreach ($sgs as $k => $sg) {
if (!$this->Event->SharingGroup->checkIfServerInSG($sg, $this->data)) {
unset($sgs[$k]);
continue;
}
$sgIds[] = $sg['SharingGroup']['id'];
$sgs = $this->Event->SharingGroup->find('all', array(
'recursive' => -1,
'contain' => array('Organisation', 'SharingGroupOrg', 'SharingGroupServer')
));
$sgIds = array();
foreach ($sgs as $k => $sg) {
if (!$this->Event->SharingGroup->checkIfServerInSG($sg, $this->data)) {
unset($sgs[$k]);
continue;
}
$sgIds[] = $sg['SharingGroup']['id'];
}
if (!isset($sgIds) || empty($sgIds)) {
$sgIds = array(-1);
@ -2102,7 +2099,7 @@ class Server extends AppModel {
public function testForPath($value) {
if ($value === '') return true;
if (preg_match('@^\/?(([a-z0-9_.]+[a-z0-9_.\- ]*[a-z0-9_.\-]|[a-z0-9_.])+\/?)+$@i', $value)) return true;
if (preg_match('@^\/?(([a-z0-9_.]+[a-z0-9_.\-.\:]*[a-z0-9_.\-.\:]|[a-z0-9_.])+\/?)+$@i', $value)) return true;
return 'Invalid characters in the path.';
}
@ -2162,14 +2159,13 @@ class Server extends AppModel {
return true;
}
public function testMangle($value) {
if ($this->testBool($value) !== true) return $this->testBool($value);
if ($value) return 'Enabled, expect issues.';
public function testDisableEmail($value) {
if (isset($value) && $value) return 'E-mailing is blocked.';
return true;
}
public function testDisableEmail($value) {
if (isset($value) && $value) return 'E-mailing is blocked.';
public function testDisableCache($value) {
if (isset($value) && $value) return 'Export caches are disabled.';
return true;
}
@ -2310,6 +2306,29 @@ class Server extends AppModel {
return true;
}
public function disableCacheAfterHook($setting, $value) {
if ($value) {
$this->Event = ClassRegistry::init('Event');
App::uses('Folder', 'Utility');
App::uses('File', 'Utility');
// delete all cache files
foreach ($this->Event->export_types as $type => $settings) {
$dir = new Folder(APP . 'tmp/cached_exports/' . $type);
// No caches created for this type of export, move on
if ($dir == null) {
continue;
}
$files = $dir->find('.*' . $settings['extension']);
foreach ($files as $file) {
$file = new File($dir->pwd() . DS . $file);
$file->delete();
$file->close();
}
}
}
return true;
}
public function correlationAfterHook($setting, $value) {
if (!Configure::read('MISP.background_jobs')) {
$this->Attribute = ClassRegistry::init('Attribute');
@ -2358,40 +2377,12 @@ class Server extends AppModel {
return true;
}
public function eventBlacklistingBeforeHook($setting, $value) {
$this->cleanCacheFiles();
if ($value) {
try {
$this->EventBlacklist = ClassRegistry::init('EventBlacklist');
$schema = $this->EventBlacklist->schema();
if (!isset($schema['event_info'])) $this->updateDatabase('addEventBlacklistsContext');
} catch (Exception $e) {
$this->updateDatabase('addEventBlacklists');
}
}
return true;
}
public function customAuthBeforeHook($setting, $value) {
if ($value) $this->updateDatabase('addCustomAuth');
$this->cleanCacheFiles();
return true;
}
public function orgBlacklistingBeforeHook($setting, $value) {
$this->cleanCacheFiles();
if ($value) {
try {
$this->OrgBlacklist = ClassRegistry::init('OrgBlacklist');
$schema = $this->OrgBlacklist->schema();
} catch (Exception $e) {
$this->updateDatabase('addOrgBlacklists');
}
}
return true;
}
// never come here directly, always go through a secondary check like testForTermsFile in order to also pass along the expected file path
private function __testForFile($value, $path) {
if ($this->testForEmpty($value) !== true) return $this->testForEmpty($value);
@ -2545,6 +2536,71 @@ class Server extends AppModel {
}
}
public function runPOSTtest($id) {
$server = $this->find('first', array('conditions' => array('Server.id' => $id)));
App::uses('SyncTool', 'Tools');
$syncTool = new SyncTool();
$HttpSocket = $syncTool->setupHttpSocket($server);
$request = array(
'header' => array(
'Authorization' => $server['Server']['authkey'],
'Accept' => 'application/json',
'Content-Type' => 'application/json',
)
);
$testFile = file_get_contents(APP . 'files/scripts/test_payload.txt');
$uri = $server['Server']['url'] . '/servers/postTest';
$this->Log = ClassRegistry::init('Log');
try {
$response = $HttpSocket->post($uri, json_encode(array('testString' => $testFile)), $request);
$response = json_decode($response, true);
} catch (Exception $e) {
$this->Log->create();
$this->Log->save(array(
'org' => 'SYSTEM',
'model' => 'Server',
'model_id' => $id,
'email' => 'SYSTEM',
'action' => 'error',
'user_id' => 0,
'title' => 'Error: POST connection test failed. Reason: ' . json_encode($e->getMessage()),
));
return 8;
}
if (!isset($response['body']['testString']) || $response['body']['testString'] !== $testFile) {
$responseString = isset($response['body']['testString']) ? $response['body']['testString'] : 'Response was empty.';
$this->Log->create();
$this->Log->save(array(
'org' => 'SYSTEM',
'model' => 'Server',
'model_id' => $id,
'email' => 'SYSTEM',
'action' => 'error',
'user_id' => 0,
'title' => 'Error: POST connection test failed due to the message body not containing the expected data. Response: ' . PHP_EOL . PHP_EOL . $responseString,
));
return 9;
}
$headers = array('Accept', 'Content-type');
foreach ($headers as $header) {
if (!isset($response['headers'][$header]) || $response['headers'][$header] != 'application/json') {
$responseHeader = isset($response['headers'][$header]) ? $response['headers'][$header] : 'Header was not set.';
$this->Log->create();
$this->Log->save(array(
'org' => 'SYSTEM',
'model' => 'Server',
'model_id' => $id,
'email' => 'SYSTEM',
'action' => 'error',
'user_id' => 0,
'title' => 'Error: POST connection test failed due to a header not matching the expected value. Expected: "application/json", received "' . $responseHeader,
));
return 10;
}
}
return 1;
}
public function checkVersionCompatibility($id, $user = array(), $HttpSocket = false) {
// for event publishing when we don't have a user.
if (empty($user)) $user = array('Organisation' => array('name' => 'SYSTEM'), 'email' => 'SYSTEM', 'id' => 0);
@ -2552,7 +2608,6 @@ class Server extends AppModel {
$file = new File(ROOT . DS . 'VERSION.json', true);
$localVersion = json_decode($file->read(), true);
$file->close();
$server = $this->find('first', array('conditions' => array('Server.id' => $id)));
if (!$HttpSocket) {
App::uses('SyncTool', 'Tools');
@ -2588,6 +2643,7 @@ class Server extends AppModel {
return 1;
}
$remoteVersion = json_decode($response->body, true);
$canPush = isset($remoteVersion['perm_sync']) ? $remoteVersion['perm_sync'] : false;
$remoteVersion = explode('.', $remoteVersion['version']);
if (!isset($remoteVersion[0])) {
$this->Log = ClassRegistry::init('Log');
@ -2605,33 +2661,24 @@ class Server extends AppModel {
}
$response = false;
$success = false;
$canPush = false;
$issueLevel = "warning";
if ($localVersion['major'] > $remoteVersion[0]) $response = "Sync to Server ('" . $id . "') aborted. The remote instance's MISP version is behind by a major version.";
if ($response === false && $localVersion['major'] < $remoteVersion[0]) {
$response = "Sync to Server ('" . $id . "') aborted. The remote instance is at least a full major version ahead - make sure you update your MISP instance!";
$canPush = true;
}
if ($response === false && $localVersion['minor'] > $remoteVersion[1]) $response = "Sync to Server ('" . $id . "') aborted. The remote instance's MISP version is behind by a minor version.";
if ($response === false && $localVersion['minor'] < $remoteVersion[1]) {
$response = "Sync to Server ('" . $id . "') aborted. The remote instance is at least a full minor version ahead - make sure you update your MISP instance!";
$canPush = true;
}
// if we haven't set a message yet, we're good to go. We are only behind by a hotfix version
if ($response === false) {
$success = true;
$canPush = true;
}
else $issueLevel = "error";
if ($response === false && $localVersion['hotfix'] > $remoteVersion[2]) $response = "Sync to Server ('" . $id . "') initiated, but the remote instance is a few hotfixes behind.";
if ($response === false && $localVersion['hotfix'] < $remoteVersion[2]) $response = "Sync to Server ('" . $id . "') initiated, but the remote instance is a few hotfixes ahead. Make sure you keep your instance up to date!";
if (Configure::read('MISP.ManglePushTo23') && !$canPush) {
$canPush = 'mangle';
$response = "Sync to Server ('" . $id . "') should have been blocked, but mangle sync override is enabled. A downgraded synchronisation is highly advised again, please upgrade your instance as soon as possible.";
}
if ($response !== false) {
$this->Log = ClassRegistry::init('Log');
$this->Log->create();
@ -3306,6 +3353,7 @@ class Server extends AppModel {
}
$validServers[] = $server;
}
return $validServers;
}
@ -3331,4 +3379,39 @@ class Server extends AppModel {
}
return true;
}
public function getLatestGitRemote() {
return exec('git ls-remote https://github.com/MISP/MISP | head -1 | sed "s/HEAD//"');
}
public function getCurrentGitStatus() {
$status = array();
$status['commit'] = exec('git rev-parse HEAD');
$status['branch'] = $this->getCurrentBranch();
$status['latestCommit'] = $this->getLatestGitremote();
return $status;
}
public function getCurrentBranch() {
return exec("git symbolic-ref HEAD | sed 's!refs\/heads\/!!'");
}
public function checkoutMain() {
$mainBranch = '2.4';
return exec('git checkout ' . $mainBranch);
}
public function update($status) {
$final = '';
$command1 = 'git pull origin ' . $status['branch'] . ' 2>&1';
$command2 = 'git submodule init && git submodule update 2>&1';
$final = $command1 . "\n\n";
exec($command1, $output);
$final .= implode("\n", $output) . "\n\n=================================\n\n";
$output = array();
$final .= $command2 . "\n\n";
exec($command2, $output);
$final .= implode("\n", $output);
return $final;
}
}

View File

@ -71,13 +71,18 @@ class ShadowAttribute extends AppModel {
public $validate = array(
'event_id' => array(
'numeric' => array(
'rule' => array('numeric'),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
'rule' => array('numeric')
)
),
'org_id' => array(
'numeric' => array(
'rule' => array('numeric')
)
),
'event_org_id' => array(
'numeric' => array(
'rule' => array('numeric')
)
),
'type' => array(
// currently when adding a new attribute type we need to change it in both places
@ -281,6 +286,8 @@ class ShadowAttribute extends AppModel {
$this->data['ShadowAttribute']['timestamp'] = $date->getTimestamp();
}
if (!isset($this->data['ShadowAttribute']['proposal_to_delete'])) $this->data['ShadowAttribute']['proposal_to_delete'] = 0;
// make some last changes to the inserted value
$this->data['ShadowAttribute']['value'] = $this->Event->Attribute->modifyBeforeValidation($this->data['ShadowAttribute']['type'], $this->data['ShadowAttribute']['value']);

View File

@ -280,7 +280,7 @@ class SharingGroup extends AppModel {
public function checkIfServerInSG($sg, $server) {
$conditional = false;
if (isset($sg['SharingGroupServer']) && !empty($sg['SharingGroupServer']) && !$sg['SharingGroup']['roaming']) {
if (isset($sg['SharingGroupServer']) && !empty($sg['SharingGroupServer']) && (empty($sg['SharingGroup']['roaming']) && empty($sg['roaming']))) {
foreach ($sg['SharingGroupServer'] as $s) {
if ($s['server_id'] == $server['Server']['id']) {
if ($s['all_orgs']) {

View File

@ -66,6 +66,9 @@ class Tag extends AppModel {
if (!isset($this->data['Tag']['hide_tag'])) {
$this->data['Tag']['hide_tag'] = Configure::read('MISP.incoming_tags_disabled_by_default') ? 1 : 0;
}
if (!isset($this->data['Tag']['exportable'])) {
$this->data['Tag']['exportable'] = 1;
}
return true;
}
@ -188,15 +191,25 @@ class Tag extends AppModel {
return ($this->save($data));
}
public function quickEdit($tag, $name, $colour) {
if ($tag['Tag']['colour'] !== $colour || $tag['Tag']['name'] !== $name) {
public function quickEdit($tag, $name, $colour, $hide = false) {
if ($tag['Tag']['colour'] !== $colour || $tag['Tag']['name'] !== $name || $hide !== false) {
$tag['Tag']['name'] = $name;
$tag['Tag']['colour'] = $colour;
if ($hide !== false) {
$tag['Tag']['hide_tag'] = $hide;
}
return ($this->save($tag['Tag']));
}
return true;
}
public function disableTags($tags) {
foreach ($tags as $k => $v) {
$tags[$k]['Tag']['hide_tag'] = 1;
}
return ($this->saveAll($tags));
}
public function getTagsForNamespace($namespace) {
$contain = array('EventTag');
$contain[] = 'AttributeTag';

View File

@ -233,7 +233,6 @@ class Taxonomy extends AppModel {
$this->Tag = ClassRegistry::init('Tag');
App::uses('ColourPaletteTool', 'Tools');
$paletteTool = new ColourPaletteTool();
App::uses('ColourPaletteTool', 'Tools');
$taxonomy = $this->__getTaxonomy($id, array('full' => true));
$tags = $this->Tag->getTagsForNamespace($taxonomy['Taxonomy']['namespace']);
$colours = $paletteTool->generatePaletteFromString($taxonomy['Taxonomy']['namespace'], count($taxonomy['entries']));
@ -246,7 +245,7 @@ class Taxonomy extends AppModel {
foreach ($tagList as $tagName) {
if ($tagName === $entry['tag']) {
if (isset($tags[strtoupper($entry['tag'])])) {
$this->Tag->quickEdit($tags[strtoupper($entry['tag'])], $tagName, $colour);
$this->Tag->quickEdit($tags[strtoupper($entry['tag'])], $tagName, $colour, 0);
} else {
$this->Tag->quickAdd($tagName, $colour);
}
@ -254,7 +253,7 @@ class Taxonomy extends AppModel {
}
} else {
if (isset($tags[strtoupper($entry['tag'])])) {
$this->Tag->quickEdit($tags[strtoupper($entry['tag'])], $entry['tag'], $colour);
$this->Tag->quickEdit($tags[strtoupper($entry['tag'])], $entry['tag'], $colour, 0);
} else {
$this->Tag->quickAdd($entry['tag'], $colour);
}
@ -263,6 +262,32 @@ class Taxonomy extends AppModel {
return true;
}
public function disableTags($id, $tagList = false) {
if ($tagList && !is_array($tagList)) $tagList = array($tagList);
$this->Tag = ClassRegistry::init('Tag');
$tags = array();
if ($tagList) {
$tags = $tagList;
} else {
$taxonomy = $this->__getTaxonomy($id, array('full' => true));
foreach ($taxonomy['entries'] as $entry) {
$tags[] = $entry['tag'];
}
}
if (empty($tags)) {
return true;
}
$tags = $this->Tag->find('all', array(
'conditions' => array('Tag.name' => $tags, 'Tag.hide_tag' => 0),
'recursive' => -1
));
if (empty($tags)) {
return true;
}
$this->Tag->disableTags($tags);
return true;
}
public function listTaxonomies($options = array('full' => false, 'enabled' => false)) {
$recursive = -1;
if (isset($options['full']) && $options['full']) $recursive = 2;

View File

@ -249,6 +249,7 @@ App::uses('RandomTool', 'Tools');
}
public function beforeSave($options = array()) {
$this->data[$this->alias]['date_modified'] = time();
if (isset($this->data[$this->alias]['password'])) {
$this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['password']);
}
@ -349,7 +350,7 @@ App::uses('RandomTool', 'Tools');
public function passwordLength($check) {
$length = Configure::read('Security.password_policy_length');
if (empty($length) || $length < 0) $length = 6;
if (empty($length) || $length < 0) $length = 12;
$value = array_values($check);
$value = $value[0];
if (strlen($value) < $length) return false;
@ -367,7 +368,7 @@ App::uses('RandomTool', 'Tools');
*/
public function complexPassword($check) {
$regex = Configure::read('Security.password_policy_complexity');
if (empty($regex) || @preg_match($regex, 'test') === false) $regex = '/((?=.*\d)|(?=.*\W+))(?![\n])(?=.*[A-Z])(?=.*[a-z]).*$/';
if (empty($regex) || @preg_match($regex, 'test') === false) $regex = '/^((?=.*\d)|(?=.*\W+))(?![\n])(?=.*[A-Z])(?=.*[a-z]).*$|.{16,}/';
$value = array_values($check);
$value = $value[0];
return preg_match($regex, $value);
@ -636,7 +637,6 @@ App::uses('RandomTool', 'Tools');
$conditions['AND']['OR'][] = array('role_id' => $roleIDs);
}
$conditions['AND'][] = $userConditions;
$users = $this->find('all', array(
'conditions' => $conditions,
'recursive' => -1,

View File

@ -285,7 +285,7 @@ class Warninglist extends AppModel{
}
public function fetchTLDLists() {
$tldLists = $this->find('list', array('conditions' => array('Warninglist.name' => $this->__tlds, 'Warninglist.enabled' => 1), 'recursive' => -1, 'fields' => array('Warninglist.id', 'Warninglist.name')));
$tldLists = $this->find('list', array('conditions' => array('Warninglist.name' => $this->__tlds), 'recursive' => -1, 'fields' => array('Warninglist.id', 'Warninglist.name')));
$tlds = array();
if (!empty($tldLists)) {
$tldLists = array_keys($tldLists);

View File

@ -85,6 +85,7 @@ class Whitelist extends AppModel {
}
}
}
$data = array_values($data);
} else {
// if !$isAttributeArray, we know that we have an array of events that we need to parse through
foreach ($data as $ke => $event) {
@ -98,6 +99,7 @@ class Whitelist extends AppModel {
}
}
}
$data[$ke]['Attribute'] = array_values($data[$ke]['Attribute']);
}
}
}
@ -117,6 +119,7 @@ class Whitelist extends AppModel {
}
}
}
$data = array_values($data);
}
return $data;
}

View File

@ -1,6 +1,6 @@
<div class="attributes <?php if (!isset($ajax) || !$ajax) echo 'form';?>">
<?php
echo $this->Form->create('Attribute', array('id'));
echo $this->Form->create('Attribute', array('id', 'url' => '/attributes/add/' . $event_id));
?>
<fieldset>
<legend><?php echo __('Add Attribute'); ?></legend>
@ -81,13 +81,13 @@
<table>
<tr>
<td style="vertical-align:bottom">
<span id="submitButton" class="btn btn-primary" onClick="submitPopoverForm('<?php echo $event_id;?>', 'add')">Submit</span>
<span id="submitButton" class="btn btn-primary" title="Submit" role="button" tabindex="0" aria-label="Submit" onClick="submitPopoverForm('<?php echo $event_id;?>', 'add')">Submit</span>
</td>
<td style="width:540px;margin-bottom:0px;">
<p style="color:red;font-weight:bold;display:none;text-align:center;margin-bottom:0px;" id="warning-message">Warning: You are about to share data that is of a classified nature. Make sure that you are authorised to share this.</p>
</td>
<td style="vertical-align:bottom;">
<span class="btn btn-inverse" id="cancel_attribute_add">Cancel</span>
<span class="btn btn-inverse" title="Cancel" role="button" tabindex="0" aria-label="Cancel" id="cancel_attribute_add">Cancel</span>
</td>
</tr>
</table>
@ -101,11 +101,10 @@
endif;
echo $this->Form->end();
?>
<div id="confirmation_box" class="confirmation_box"></div>
</div>
<?php
if (!$ajax) {
$event['Event']['id'] = $this->request->data['Attribute']['event_id'];
$event['Event']['id'] = $event_id;
$event['Event']['published'] = $published;
echo $this->element('side_menu', array('menuList' => 'event', 'menuItem' => 'addAttribute', 'event' => $event));
}

View File

@ -71,7 +71,6 @@
echo $this->Form->button('Upload', array('class' => 'btn btn-primary'));
echo $this->Form->end();
?>
<div id="confirmation_box" class="confirmation_box"></div>
</div>
<?php
$event['Event']['id'] = $this->request->data['Attribute']['event_id'];
@ -85,7 +84,7 @@ echo $this->Form->end();
foreach ($formInfoTypes as $formInfoType => $humanisedName) {
echo 'var ' . $formInfoType . 'FormInfoValues = {' . PHP_EOL;
foreach ($info[$formInfoType] as $key => $formInfoData) {
echo '"' . $key . '": "<span class=\"blue bold\">' . h($formInfoData['key']) . '</span>: ' . h($formInfoData['desc']) . '<br />",' . PHP_EOL;
echo '"' . $key . '": "<span class=\"blue bold\">' . h($formInfoData['key']) . '</span>: ' . h($formInfoData['desc']) . '<br />",' . PHP_EOL;
}
echo '}' . PHP_EOL;
}

View File

@ -18,7 +18,6 @@
echo $this->Form->button('Upload', array('class' => 'btn btn-primary'));
echo $this->Form->end();
?>
<div id="confirmation_box" class="confirmation_box"></div>
</div>
<?php
$event['Event']['id'] = $this->request->data['Attribute']['event_id'];

View File

@ -9,12 +9,12 @@
<table>
<tr>
<td style="vertical-align:top">
<span id="PromptYesButton" class="btn btn-primary" onClick="submitDeletion(<?php echo $event_id; ?>, 'delete', 'attributes', '<?php echo $id . $hard;?>')">Yes</span>
<span id="PromptYesButton" title="Delete" role="button" tabindex="0" aria-label="Delete" class="btn btn-primary" onClick="submitDeletion(<?php echo $event_id; ?>, 'delete', 'attributes', '<?php echo $id . $hard;?>')">Yes</span>
</td>
<td style="width:540px;">
</td>
<td style="vertical-align:top;">
<span class="btn btn-inverse" id="PromptNoButton" onClick="cancelPrompt();">No</span>
<span class="btn btn-inverse" title="Cancel" role="button" tabindex="0" aria-label="Cancel" id="PromptNoButton" onClick="cancelPrompt();">No</span>
</td>
</tr>
</table>

View File

@ -2,8 +2,8 @@
echo $this->Form->create('Attribute', array('class' => 'inline-form inline-field-form', 'id' => 'Attribute_' . $object['id'] . '_category_form', 'url' => '/attributes/editField/' . $object['id']));
?>
<div class='inline-input inline-input-container'>
<div class="inline-input-accept inline-input-button inline-input-passive"><span class = "icon-ok"></span></div>
<div class="inline-input-decline inline-input-button inline-input-passive"><span class = "icon-remove"></span></div>
<div class="inline-input-accept inline-input-button inline-input-passive"><span class = "icon-ok" role="button" tabindex="0" aria-label="Accept change"></span></div>
<div class="inline-input-decline inline-input-button inline-input-passive"><span class = "icon-remove" role="button" tabindex="0" aria-label="Discard change"></span></div>
<?php
echo $this->Form->input('category', array(
'options' => array(array_combine($typeCategory[$object['type']], $typeCategory[$object['type']])),

View File

@ -2,8 +2,8 @@
echo $this->Form->create('Attribute', array('class' => 'inline-form inline-field-form', 'id' => 'Attribute_' . $object['id'] . '_comment_form', 'url' => '/attributes/editField/' . $object['id']));
?>
<div class='inline-input inline-input-container'>
<div class="inline-input-accept inline-input-button inline-input-passive"><span class = "icon-ok"></span></div>
<div class="inline-input-decline inline-input-button inline-input-passive"><span class = "icon-remove"></span></div>
<div class="inline-input-accept inline-input-button inline-input-passive"><span class = "icon-ok" role="button" tabindex="0" aria-label="Accept change"></span></div>
<div class="inline-input-decline inline-input-button inline-input-passive"><span class = "icon-remove" role="button" tabindex="0" aria-label="Discard change"></span></div>
<?php
echo $this->Form->input('comment', array(
'type' => 'textarea',

View File

@ -2,8 +2,8 @@
echo $this->Form->create('Attribute', array('class' => 'inline-form inline-field-form', 'id' => 'Attribute_' . $object['id'] . '_distribution_form', 'url' => '/attributes/editField/' . $object['id']));
?>
<div class='inline-input inline-input-container'>
<div class="inline-input-accept inline-input-button inline-input-passive"><span class = "icon-ok"></span></div>
<div class="inline-input-decline inline-input-button inline-input-passive"><span class = "icon-remove"></span></div>
<div class="inline-input-accept inline-input-button inline-input-passive"><span class = "icon-ok" role="button" tabindex="0" aria-label="Accept change"></span></div>
<div class="inline-input-decline inline-input-button inline-input-passive"><span class = "icon-remove" role="button" tabindex="0" aria-label="Discard change"></span></div>
<?php
echo $this->Form->input('distribution', array(
'options' => array($distributionLevels),

View File

@ -18,10 +18,12 @@
?>
<div id="SGContainer" style="display:none;">
<?php
echo $this->Form->input('sharing_group_id', array(
'options' => array($sgs),
'label' => 'Sharing Group',
));
if (!empty($sgs)) {
echo $this->Form->input('sharing_group_id', array(
'options' => array($sgs),
'label' => 'Sharing Group',
));
}
?>
</div>
<?php
@ -53,11 +55,11 @@
<table>
<tr>
<td style="vertical-align:top">
<span id="submitButton" class="btn btn-primary" onClick="submitPopoverForm('<?php echo $id;?>', 'massEdit')">Submit</span>
<span id="submitButton" class="btn btn-primary" title="Submit" role="button" tabindex="0" aria-label="Submit" onClick="submitPopoverForm('<?php echo $id;?>', 'massEdit')">Submit</span>
</td>
<td style="width:540px;">&nbsp;</td>
<td style="vertical-align:top;">
<span class="btn btn-inverse" id="cancel_attribute_add">Cancel</span>
<span class="btn btn-inverse" title="Cancel" role="button" tabindex="0" aria-label="Cancel" id="cancel_attribute_add">Cancel</span>
</td>
</tr>
</table>

View File

@ -2,8 +2,8 @@
echo $this->Form->create('Attribute', array('class' => 'inline-form inline-field-form', 'id' => 'Attribute' . '_' . $object['id'] . '_to_ids_form', 'url' => '/attributes/editField/' . $object['id']));
?>
<div class='inline-input inline-input-container'>
<div class="inline-input-accept inline-input-button inline-input-passive"><span class = "icon-ok"></span></div>
<div class="inline-input-decline inline-input-button inline-input-passive"><span class = "icon-remove"></span></div>
<div class="inline-input-accept inline-input-button inline-input-passive"><span class = "icon-ok" role="button" tabindex="0" aria-label="Accept change"></span></div>
<div class="inline-input-decline inline-input-button inline-input-passive"><span class = "icon-remove" role="button" tabindex="0" aria-label="Discard change"></span></div>
<?php
$current = 0;
if ($object['to_ids']) $current = 1;

View File

@ -2,8 +2,8 @@
echo $this->Form->create('Attribute', array('class' => 'inline-form inline-field-form', 'id' => 'Attribute_' . $object['id'] . '_type_form', 'url' => '/attributes/editField/' . $object['id']));
?>
<div class='inline-input inline-input-container'>
<div class="inline-input-accept inline-input-button inline-input-passive"><span class = "icon-ok"></span></div>
<div class="inline-input-decline inline-input-button inline-input-passive"><span class = "icon-remove"></span></div>
<div class="inline-input-accept inline-input-button inline-input-passive"><span class = "icon-ok" role="button" tabindex="0" aria-label="Accept change"></span></div>
<div class="inline-input-decline inline-input-button inline-input-passive"><span class = "icon-remove" role="button" tabindex="0" aria-label="Discard change"></span></div>
<?php
echo $this->Form->input('type', array(
'options' => array(array_combine($categoryDefinitions[$object['category']]['types'], $categoryDefinitions[$object['category']]['types'])),

View File

@ -3,8 +3,8 @@
echo $this->Form->create('Attribute', array('class' => 'inline-form inline-field-form', 'url' => '/attributes/editField/' . $object['id'], 'id' => 'Attribute_' . $object['id'] . '_value_form', 'default' => false));
?>
<div class='inline-input inline-input-container'>
<div class="inline-input-accept inline-input-button inline-input-passive"><span class = "icon-ok"></span></div>
<div class="inline-input-decline inline-input-button inline-input-passive"><span class = "icon-remove"></span></div>
<div class="inline-input-accept inline-input-button inline-input-passive"><span class = "icon-ok" role="button" tabindex="0" aria-label="Accept change"></span></div>
<div class="inline-input-decline inline-input-button inline-input-passive"><span class = "icon-remove" role="button" tabindex="0" aria-label="Discard change"></span></div>
<?php
echo $this->Form->input('value', array(
'type' => 'textarea',

View File

@ -8,12 +8,12 @@
<table>
<tr>
<td style="vertical-align:top">
<span id="PromptYesButton" class="btn btn-primary" onClick="submitDeletion(<?php echo $event_id; ?>, 'restore', 'attributes', <?php echo $id;?>)">Yes</span>
<span id="PromptYesButton" class="btn btn-primary" title="Submit" role="button" tabindex="0" aria-label="Submit" onClick="submitDeletion(<?php echo $event_id; ?>, 'restore', 'attributes', <?php echo $id;?>)">Yes</span>
</td>
<td style="width:540px;">
</td>
<td style="vertical-align:top;">
<span class="btn btn-inverse" id="PromptNoButton" onClick="cancelPrompt();">No</span>
<span class="btn btn-inverse" id="PromptNoButton" title="Cancel" role="button" tabindex="0" aria-label="Cancel" onClick="cancelPrompt();">No</span>
</td>
</tr>
</table>

View File

@ -9,12 +9,12 @@
<table>
<tr>
<td style="vertical-align:top">
<span id="PromptYesButton" class="btn btn-primary" onClick="<?php echo $action; ?>">Yes</span>
<span id="PromptYesButton" class="btn btn-primary" title="Remove" role="button" tabindex="0" aria-label="Remove" onClick="<?php echo $action; ?>">Yes</span>
</td>
<td style="width:540px;">
</td>
<td style="vertical-align:top;">
<span class="btn btn-inverse" id="PromptNoButton" onClick="cancelPrompt();">No</span>
<span class="btn btn-inverse" id="PromptNoButton" title="Cancel" role="button" tabindex="0" aria-label="Cancel" onClick="cancelPrompt();">No</span>
</td>
</tr>
</table>

View File

@ -17,12 +17,12 @@
<table>
<tr>
<td style="vertical-align:top">
<span id="PromptYesButton" class="btn btn-primary" onClick="submitPublish();">Yes</span>
<span id="PromptYesButton" title="Toggle correlation for attribute" role="button" tabindex="0" aria-label="Toggle correlation for attribute" class="btn btn-primary" onClick="toggleCorrelation(<?php echo h($attribute['Attribute']['id']); ?>);">Yes</span>
</td>
<td style="width:540px;">
</td>
<td style="vertical-align:top;">
<span class="btn btn-inverse" id="PromptNoButton" onClick="cancelPrompt();">No</span>
<span class="btn btn-inverse" title="Cancel" role="button" tabindex="0" aria-label="Cancel" id="PromptNoButton" onClick="cancelPrompt();">No</span>
</td>
</tr>
</table>

View File

@ -35,13 +35,13 @@ echo $this->Form->create('Attribute', array('id', 'url' => '/attributes/attribut
<table>
<tr>
<td style="vertical-align:top">
<span id="submitButton" class="btn btn-primary" onClick="submitPopoverForm('<?php echo $event_id;?>', 'replaceAttributes')">Submit</span>
<span id="submitButton" class="btn btn-primary" title="Replace attributes" role="button" tabindex="0" aria-label="Replaceattributes" onClick="submitPopoverForm('<?php echo $event_id;?>', 'replaceAttributes')">Submit</span>
</td>
<td style="width:540px;">
<p style="color:red;font-weight:bold;display:none;text-align:center" id="warning-message">Warning: You are about to share data that is of a classified nature (Attribution / targeting data). Make sure that you are authorised to share this.</p>
</td>
<td style="vertical-align:top;">
<span class="btn btn-inverse" id="cancel_attribute_add">Cancel</span>
<span class="btn btn-inverse" id="cancel_attribute_add" title="Cancel" role="button" tabindex="0" aria-label="Cancel">Cancel</span>
</td>
</tr>
</table>

View File

@ -115,7 +115,7 @@ foreach ($attributes as $attribute):
else $tagText = h($tag['Tag']['name']);
}
?>
<span class="tag useCursorPointer" style="margin-bottom:3px;background-color:<?php echo h($tag['Tag']['colour']);?>;color:<?php echo $this->TextColour->getTextColour($tag['Tag']['colour']);?>;" title="<?php echo h($tag['Tag']['name']); ?>" onClick="document.location.href='<?php echo $baseurl; ?>/attributes/search/attributetag:<?php echo h($tag['Tag']['id']);?>';"><?php echo $tagText; ?></span>
<span class="tag useCursorPointer" style="margin-bottom:3px;background-color:<?php echo h($tag['Tag']['colour']);?>;color:<?php echo $this->TextColour->getTextColour($tag['Tag']['colour']);?>;" title="<?php echo h($tag['Tag']['name']); ?>" role="button" tabindex="0" aria-label="Search events tagged <?php echo h($tag['Tag']['name'])?>" onClick="document.location.href='<?php echo $baseurl; ?>/attributes/search/attributetag:<?php echo h($tag['Tag']['id']);?>';"><?php echo $tagText; ?></span>
<?php endforeach; ?>
</td>
<td ondblclick="document.location ='document.location ='<?php echo $baseurl;?>/events/view/<?php echo $attribute['Event']['id'];?>';">

View File

@ -14,6 +14,7 @@
<th><?php echo $this->Paginator->sort('nids_sid');?></th>
<th><?php echo $this->Paginator->sort('termsaccepted');?></th>
<th><?php echo $this->Paginator->sort('current_login', 'Last login');?></th>
<th><?php echo $this->Paginator->sort('date_created', 'Created');?></th>
<?php
if (Configure::read('Plugin.CustomAuth_enable') && !Configure::read('Plugin.CustomAuth_required')):
?>
@ -65,6 +66,9 @@
<td class="short" ondblclick="document.location ='<?php echo $this->Html->url(array('admin' => true, 'action' => 'view', $user['User']['id']), true);?>';" title="<?php echo !$user['User']['current_login'] ? 'N/A' : h(date("Y-m-d H:i:s",$user['User']['current_login']));?>">
<?php echo !$user['User']['current_login'] ? 'N/A' : h(date("Y-m-d",$user['User']['current_login'])); ?>&nbsp;
</td>
<td class="short" ondblclick="document.location ='<?php echo $this->Html->url(array('admin' => true, 'action' => 'view', $user['User']['id']), true);?>';" title="<?php echo !$user['User']['current_login'] ? 'N/A' : h(date("Y-m-d H:i:s",$user['User']['current_login']));?>">
<?php echo !$user['User']['date_created'] ? 'N/A' : h(date("Y-m-d",$user['User']['date_created'])); ?>&nbsp;
</td>
<?php
if (Configure::read('Plugin.CustomAuth_enable') && !Configure::read('Plugin.CustomAuth_required')):
?>
@ -81,7 +85,7 @@
<?php
if (($isAclAdmin && (($user['User']['org_id'] == $me['org_id'])) || ('1' == $me['id'])) || ($isSiteAdmin)):
?>
<span class="icon-refresh useCursorPointer" onClick="initiatePasswordReset('<?php echo $user['User']['id']; ?>');" title="Inform user"></span>
<span role="button" tabindex="0" aria-label="Initiate password refresh" title="Initiate password refresh" class="icon-refresh useCursorPointer" onClick="initiatePasswordReset('<?php echo $user['User']['id']; ?>');" title="Create new credentials and inform user" role="button" tabindex="0" aria-label="Create new credentials and inform user"></span>
<?php
echo $this->Html->link('', array('admin' => true, 'action' => 'edit', $user['User']['id']), array('class' => 'icon-edit', 'title' => 'Edit'));
echo $this->Form->postLink('', array('admin' => true, 'action' => 'delete', $user['User']['id']), array('class' => 'icon-trash', 'title' => 'Delete'), __('Are you sure you want to delete # %s? It is highly recommended to never delete users but to disable them instead.', $user['User']['id']));

View File

@ -7,7 +7,7 @@
<div style="padding:1px; overflow:hidden; white-space:nowrap; display:flex; float:left; margin-right:2px;">
<a href="<?php echo $baseurl;?>/attributes/search/attributetag:<?php echo h($tag['Tag']['id']); ?>" class="<?php echo $tagClass; ?>" style="display:inline-block; background-color:<?php echo h($tag['Tag']['colour']);?>;color:<?php echo $this->TextColour->getTextColour($tag['Tag']['colour']);?>"><?php echo h($tag['Tag']['name']); ?></a>
<?php if ($full): ?>
<div class="tagSecondHalf useCursorPointer noPrint" onClick="removeObjectTagPopup('attribute', '<?php echo h($attributeId); ?>', '<?php echo h($tag['Tag']['id']); ?>');">x</div>
<div class="tagSecondHalf useCursorPointer noPrint" title="Remove tag" role="button" tabindex="0" aria-label="Remove tag" onClick="removeObjectTagPopup('attribute', '<?php echo h($attributeId); ?>', '<?php echo h($tag['Tag']['id']); ?>');">x</div>
<?php endif;?>
</div>
<?php

View File

@ -7,7 +7,7 @@
<div style="padding:1px; overflow:hidden; white-space:nowrap; display:flex; float:left; margin-right:2px;">
<a href="<?php echo $baseurl;?>/events/index/searchtag:<?php echo h($tag['Tag']['id']); ?>" class="<?php echo $tagClass; ?>" style="display:inline-block; background-color:<?php echo h($tag['Tag']['colour']);?>;color:<?php echo $this->TextColour->getTextColour($tag['Tag']['colour']);?>"><?php echo h($tag['Tag']['name']); ?></a>
<?php if ($full): ?>
<div class="tagSecondHalf useCursorPointer noPrint" onClick="removeObjectTagPopup('event', '<?php echo h($event['Event']['id']); ?>', '<?php echo h($tag['Tag']['id']); ?>');">x</div>
<div class="tagSecondHalf useCursorPointer noPrint" title="Remove tag" role="button" tabindex="0" aria-label="Remove tag <?php echo h($tag['Tag']['name']); ?>" onClick="removeObjectTagPopup('event', '<?php echo h($event['Event']['id']); ?>', '<?php echo h($tag['Tag']['id']); ?>');">x</div>
<?php endif;?>
</div>
<?php
@ -15,7 +15,7 @@
?>
<div style="float:left">
<?php if ($full): ?>
<button id="addTagButton" class="btn btn-inverse noPrint" style="line-height:10px; padding: 4px 4px;" onClick="getPopup('<?php echo h($event['Event']['id']); ?>', 'tags', 'selectTaxonomy');">+</button>
<button id="addTagButton" title="Add a tag" role="button" tabindex="0" aria-label="Add a tag" class="btn btn-inverse noPrint" style="line-height:10px; padding: 4px 4px;" onClick="getPopup('<?php echo h($event['Event']['id']); ?>', 'tags', 'selectTaxonomy');">+</button>
<?php else:?>
&nbsp;
<?php endif; ?>

View File

@ -7,7 +7,7 @@
</td>
<?php if ($editable == 'yes'): ?>
<td style="padding-left:0px;padding-right:5px;">
<span class="tagSecondHalf useCursorPointer" onClick="removeTemplateTag('<?php echo h($tag['Tag']['id']); ?>', '<?php echo h($tag['Tag']['name']); ?>');">x</span>
<span class="tagSecondHalf useCursorPointer" title="Remove tag" role="button" tabindex="0" aria-label="Remove tag" onClick="removeTemplateTag('<?php echo h($tag['Tag']['id']); ?>', '<?php echo h($tag['Tag']['name']); ?>');">x</span>
</td>
<?php endif; ?>
</tr>

View File

@ -96,44 +96,44 @@
</div>
<div id="attributeList" class="attributeListContainer">
<div class="tabMenu tabMenuEditBlock noPrint">
<span id="create-button" title="Add attribute" class="icon-plus useCursorPointer" onClick="clickCreateButton(<?php echo $event['Event']['id']; ?>, '<?php echo $possibleAction; ?>');"></span>
<span id="multi-edit-button" title="Edit selected Attributes" class="hidden icon-edit mass-select useCursorPointer" onClick="editSelectedAttributes(<?php echo $event['Event']['id']; ?>);"></span>
<span id="multi-tag-button" title="Tag selected Attributes" class="hidden icon-tag mass-select useCursorPointer" onClick="getPopup('selected/true', 'tags', 'selectTaxonomy');"></span>
<span id="multi-delete-button" title="Delete selected Attributes" class="hidden icon-trash mass-select useCursorPointer" onClick="multiSelectAction(<?php echo $event['Event']['id']; ?>, 'deleteAttributes');"></span>
<span id="multi-accept-button" title="Accept selected Proposals" class="hidden icon-ok mass-proposal-select useCursorPointer" onClick="multiSelectAction(<?php echo $event['Event']['id']; ?>, 'acceptProposals');"></span>
<span id="multi-discard-button" title="Discard selected Proposals" class="hidden icon-remove mass-proposal-select useCursorPointer" onClick="multiSelectAction(<?php echo $event['Event']['id']; ?>, 'discardProposals');"></span>
<span id="create-button" title="Add attribute" role="button" tabindex="0" aria-label="Add attribute" class="icon-plus useCursorPointer" onClick="clickCreateButton(<?php echo $event['Event']['id']; ?>, '<?php echo $possibleAction; ?>');"></span>
<span id="multi-edit-button" title="Edit selected Attributes" role="button" tabindex="0" aria-label="Edit selected Attributes" class="hidden icon-edit mass-select useCursorPointer" onClick="editSelectedAttributes(<?php echo $event['Event']['id']; ?>);"></span>
<span id="multi-tag-button" title="Tag selected Attributes" role="button" tabindex="0" aria-label="Tag selected Attributes" class="hidden icon-tag mass-select useCursorPointer" onClick="getPopup('selected/true', 'tags', 'selectTaxonomy');"></span>
<span id="multi-delete-button" title="Delete selected Attributes" role="button" tabindex="0" aria-label="Delete selected Attributes" class="hidden icon-trash mass-select useCursorPointer" onClick="multiSelectAction(<?php echo $event['Event']['id']; ?>, 'deleteAttributes');"></span>
<span id="multi-accept-button" title="Accept selected Proposals" role="button" tabindex="0" aria-label="Accept selected Proposals" class="hidden icon-ok mass-proposal-select useCursorPointer" onClick="multiSelectAction(<?php echo $event['Event']['id']; ?>, 'acceptProposals');"></span>
<span id="multi-discard-button" title="Discard selected Proposals" role="button" tabindex="0" aria-label="Discard selected Proposals" class="hidden icon-remove mass-proposal-select useCursorPointer" onClick="multiSelectAction(<?php echo $event['Event']['id']; ?>, 'discardProposals');"></span>
<?php if (Configure::read('Plugin.Sightings_enable')): ?>
<span id="multi-sighting-button" title="Sightings display for selected attributes" class="hidden icon-wrench mass-select useCursorPointer sightings_advanced_add" data-object-id="selected" data-object-context="attribute"></span>
<span id="multi-sighting-button" title="Sightings display for selected attributes" role="button" tabindex="0" aria-label="Sightings display for selected attributes" class="hidden icon-wrench mass-select useCursorPointer sightings_advanced_add" data-object-id="selected" data-object-context="attribute"></span>
<?php endif; ?>
</div>
<div class="tabMenu tabMenuToolsBlock noPrint">
<?php if ($mayModify): ?>
<span id="create-button" title="Populate using a template" class="icon-list-alt useCursorPointer" onClick="getPopup(<?php echo $event['Event']['id']; ?>, 'templates', 'templateChoices');"></span>
<span id="create-button" title="Populate using a template" role="button" tabindex="0" aria-label="Populate using a template" class="icon-list-alt useCursorPointer" onClick="getPopup(<?php echo $event['Event']['id']; ?>, 'templates', 'templateChoices');"></span>
<?php endif; ?>
<span id="freetext-button" title="Populate using the freetext import tool" class="icon-exclamation-sign icon-inverse useCursorPointer" onClick="getPopup(<?php echo $event['Event']['id']; ?>, 'events', 'freeTextImport');"></span>
<span id="freetext-button" title="Populate using the freetext import tool" role="button" tabindex="0" aria-label="Populate using the freetext import tool" class="icon-exclamation-sign icon-inverse useCursorPointer" onClick="getPopup(<?php echo $event['Event']['id']; ?>, 'events', 'freeTextImport');"></span>
<?php if ($mayModify): ?>
<span id="attribute-replace-button" title="Replace all attributes of a category/type combination within the event" class="icon-random useCursorPointer" onClick="getPopup(<?php echo $event['Event']['id']; ?>, 'attributes', 'attributeReplace');"></span>
<span id="attribute-replace-button" title="Replace all attributes of a category/type combination within the event" role="button" tabindex="0" aria-label="Replace all attributes of a category/type combination within the event" class="icon-random useCursorPointer" onClick="getPopup(<?php echo $event['Event']['id']; ?>, 'attributes', 'attributeReplace');"></span>
<?php endif; ?>
</div>
<div class="tabMenu tabMenuFiltersBlock noPrint" style="padding-right:0px !important;">
<span id="filter_header" class="attribute_filter_header">Filters: </span>
<div id="filter_all" title="Show all attributes" class="attribute_filter_text<?php if ($attributeFilter == 'all') echo '_active'; ?>" onClick="filterAttributes('all', '<?php echo h($event['Event']['id']); ?>');">All</div>
<div id="filter_all" title="Show all attributes" role="button" tabindex="0" aria-label="Sow all attributes" class="attribute_filter_text<?php if ($attributeFilter == 'all') echo '_active'; ?>" onClick="filterAttributes('all', '<?php echo h($event['Event']['id']); ?>');">All</div>
<?php foreach ($typeGroups as $group): ?>
<div id="filter_<?php echo $group; ?>" title="Only show <?php echo $group; ?> related attributes" class="attribute_filter_text<?php if ($attributeFilter == $group) echo '_active'; ?>" onClick="filterAttributes('<?php echo $group; ?>', '<?php echo h($event['Event']['id']); ?>');"><?php echo ucfirst($group); ?></div>
<div id="filter_<?php echo h($group); ?>" title="Only show <?php echo $group; ?> related attributes" role="button" tabindex="0" aria-label="Only show <?php echo h($group); ?> related attributes" class="attribute_filter_text<?php if ($attributeFilter == $group) echo '_active'; ?>" onClick="filterAttributes('<?php echo $group; ?>', '<?php echo h($event['Event']['id']); ?>');"><?php echo ucfirst($group); ?></div>
<?php endforeach; ?>
<div id="filter_proposal" title="Only show proposals" class="attribute_filter_text<?php if ($attributeFilter == 'proposal') echo '_active'; ?>" onClick="filterAttributes('proposal', '<?php echo h($event['Event']['id']); ?>');">Proposal</div>
<div id="filter_correlation" title="Only show correlating attributes" class="attribute_filter_text<?php if ($attributeFilter == 'correlation') echo '_active'; ?>" onClick="filterAttributes('correlation', '<?php echo h($event['Event']['id']); ?>');">Correlation</div>
<div id="filter_warning" title="Only show potentially false positive attributes" class="attribute_filter_text<?php if ($attributeFilter == 'warning') echo '_active'; ?>" onClick="filterAttributes('warning', '<?php echo h($event['Event']['id']); ?>');">Warnings</div>
<div id="filter_proposal" title="Only show proposals" role="button" tabindex="0" aria-label="Only show proposals" class="attribute_filter_text<?php if ($attributeFilter == 'proposal') echo '_active'; ?>" onClick="filterAttributes('proposal', '<?php echo h($event['Event']['id']); ?>');">Proposal</div>
<div id="filter_correlation" title="Only show correlating attributes" role="button" tabindex="0" aria-label="Only show correlating attributes" class="attribute_filter_text<?php if ($attributeFilter == 'correlation') echo '_active'; ?>" onClick="filterAttributes('correlation', '<?php echo h($event['Event']['id']); ?>');">Correlation</div>
<div id="filter_warning" title="Only show potentially false positive attributes" role="button" tabindex="0" aria-label="Only show potentially false positive attributes" class="attribute_filter_text<?php if ($attributeFilter == 'warning') echo '_active'; ?>" onClick="filterAttributes('warning', '<?php echo h($event['Event']['id']); ?>');">Warnings</div>
<?php if ($me['Role']['perm_sync'] || $event['Orgc']['id'] == $me['org_id']): ?>
<div id="filter_deleted" title="Include deleted attributes" class="attribute_filter_text<?php if ($deleted) echo '_active'; ?>" onClick="toggleDeletedAttributes('<?php echo Router::url( $this->here, true );?>');">Include deleted attributes</div>
<div id="filter_deleted" title="Include deleted attributes" role="button" tabindex="0" aria-label="Include deleted attributes" class="attribute_filter_text<?php if ($deleted) echo '_active'; ?>" onClick="toggleDeletedAttributes('<?php echo Router::url( $this->here, true );?>');">Include deleted attributes</div>
<?php endif; ?>
<div id="show_context" title="Show attribute context fields" class="attribute_filter_text" onClick="toggleContextFields();">Show context fields</div>
<div id="show_context" title="Show attribute context fields" role="button" tabindex="0" aria-label="Show attribute context fields" class="attribute_filter_text" onClick="toggleContextFields();">Show context fields</div>
</div>
<table class="table table-striped table-condensed">
<tr>
<?php if ($mayModify && !empty($event['objects'])): ?>
<th><input class="select_all" type="checkbox" onClick="toggleAllAttributeCheckboxes();" /></th>
<th><input class="select_all" type="checkbox" title="Select all" role="button" tabindex="0" aria-label="Select all attributes/proposals on current page" onClick="toggleAllAttributeCheckboxes();" /></th>
<?php endif;?>
<th class="context hidden"><?php echo $this->Paginator->sort('id');?></th>
<th class="context hidden">UUID</th>
@ -308,6 +308,9 @@
$sigDisplay = str_replace(" ", '&nbsp;', $sigDisplay);
echo nl2br($sigDisplay);
}
} else if ('hex' == $object['type']) {
$sigDisplay = str_replace("\r", '', $sigDisplay);
echo '<span class="hex-value" title="Hexadecimal representation">' . nl2br(h($sigDisplay)) . '</span>&nbsp;<span role="button" tabindex="0" aria-label="Switch to binary representation" class="icon-repeat hex-value-convert useCursorPointer" title="Switch to binary representation"></span>';
} else {
$sigDisplay = str_replace("\r", '', $sigDisplay);
echo nl2br(h($sigDisplay));
@ -356,7 +359,7 @@
if ($object['objectType'] == 0):
?>
<td class="short <?php echo $extra; ?>" style="padding-top:3px;">
<input class="correlation-toggle" type="checkbox" data-attribute-id="<?php echo h($object['id']); ?>" <?php echo $object['disable_correlation'] ? '' : 'checked'; ?>>
<input id="correlation_toggle_<?php echo h($object['id']); ?>" class="correlation-toggle" type="checkbox" data-attribute-id="<?php echo h($object['id']); ?>" <?php echo $object['disable_correlation'] ? '' : 'checked'; ?>>
</td>
<?php
else:
@ -446,9 +449,9 @@
$temp = $sightingsData['csv'][$object['id']];
}
?>
<span class="icon-thumbs-up useCursorPointer" onClick="addSighting('0', '<?php echo h($object['id']); ?>', '<?php echo h($event['Event']['id']);?>', '<?php echo h($page); ?>');">&nbsp;</span>
<span class="icon-thumbs-down useCursorPointer" onClick="addSighting('1', '<?php echo h($object['id']); ?>', '<?php echo h($event['Event']['id']);?>', '<?php echo h($page); ?>');">&nbsp;</span>
<span class="icon-wrench useCursorPointer sightings_advanced_add" data-object-id="<?php echo h($object['id']); ?>" data-object-context="attribute">&nbsp;</span>
<span class="icon-thumbs-up useCursorPointer" title="Add sighting" role="button" tabindex="0" aria-label="Add sighting" onClick="addSighting('0', '<?php echo h($object['id']); ?>', '<?php echo h($event['Event']['id']);?>', '<?php echo h($page); ?>');">&nbsp;</span>
<span class="icon-thumbs-down useCursorPointer" title="Mark as false-positive" role="button" tabindex="0" aria-label="Mark as false-positive" onClick="addSighting('1', '<?php echo h($object['id']); ?>', '<?php echo h($event['Event']['id']);?>', '<?php echo h($page); ?>');">&nbsp;</span>
<span class="icon-wrench useCursorPointer sightings_advanced_add" title="Advanced sightings" role="button" tabindex="0" aria-label="Advanced sightings" data-object-id="<?php echo h($object['id']); ?>" data-object-context="attribute">&nbsp;</span>
<span id="sightingCount_<?php echo h($object['id']); ?>" class="bold sightingsCounter_<?php echo h($object['id']); ?>" data-placement="top" data-toggle="popover" data-trigger="hover" data-content="<?php echo isset($sightingsData['data'][$object['id']]['html']) ? $sightingsData['data'][$object['id']]['html'] : ''; ?>">
<?php
$s = (!empty($sightingsData['data'][$object['id']]['sighting']['count']) ? $sightingsData['data'][$object['id']]['sighting']['count'] : 0);
@ -479,20 +482,20 @@
if ($object['deleted']):
if ($isSiteAdmin || $mayModify):
?>
<span class="icon-repeat useCursorPointer" onClick="deleteObject('attributes', 'restore', '<?php echo h($object['id']); ?>', '<?php echo h($event['Event']['id']); ?>');"></span>
<span class="icon-trash useCursorPointer" onClick="deleteObject('attributes', 'delete', '<?php echo h($object['id']) . '/true'; ?>', '<?php echo h($event['Event']['id']); ?>');"></span>
<span class="icon-repeat useCursorPointer" title="Restore attribute" role="button" tabindex="0" aria-label="Restore attribute" onClick="deleteObject('attributes', 'restore', '<?php echo h($object['id']); ?>', '<?php echo h($event['Event']['id']); ?>');"></span>
<span class="icon-trash useCursorPointer" title="Delete attribute" role="button" tabindex="0" aria-label="Permanently delete attribute" onClick="deleteObject('attributes', 'delete', '<?php echo h($object['id']) . '/true'; ?>', '<?php echo h($event['Event']['id']); ?>');"></span>
<?php
endif;
else:
if ($isSiteAdmin || !$mayModify):
if (isset($modules) && isset($modules['types'][$object['type']])):
?>
<span class="icon-asterisk useCursorPointer" onClick="simplePopup('<?php echo $baseurl;?>/events/queryEnrichment/<?php echo h($object['id']);?>/ShadowAttribute');" title="Propose enrichment">&nbsp;</span>
<span class="icon-asterisk useCursorPointer" title="Query enrichment" role="button" tabindex="0" aria-label="Query enrichment" onClick="simplePopup('<?php echo $baseurl;?>/events/queryEnrichment/<?php echo h($object['id']);?>/ShadowAttribute');" title="Propose enrichment">&nbsp;</span>
<?php
endif;
?>
<a href="<?php echo $baseurl;?>/shadow_attributes/edit/<?php echo $object['id']; ?>" title="Propose Edit" class="icon-share useCursorPointer"></a>
<span class="icon-trash useCursorPointer" title="Propose Deletion" onClick="deleteObject('shadow_attributes', 'delete', '<?php echo h($object['id']); ?>', '<?php echo h($event['Event']['id']); ?>');"></span>
<span class="icon-trash useCursorPointer" title="Propose Deletion" role="button" tabindex="0" aria-label="Propose deletion" onClick="deleteObject('shadow_attributes', 'delete', '<?php echo h($object['id']); ?>', '<?php echo h($event['Event']['id']); ?>');"></span>
<?php
if ($isSiteAdmin):
?>
@ -502,12 +505,12 @@
if ($isSiteAdmin || $mayModify) {
if (isset($modules) && isset($modules['types'][$object['type']])):
?>
<span class="icon-asterisk useCursorPointer" onClick="simplePopup('<?php echo $baseurl;?>/events/queryEnrichment/<?php echo h($object['id']);?>/Attribute');" title="Add enrichment">&nbsp;</span>
<span class="icon-asterisk useCursorPointer" onClick="simplePopup('<?php echo $baseurl;?>/events/queryEnrichment/<?php echo h($object['id']);?>/Attribute');" title="Add enrichment" role="button" tabindex="0" aria-label="Add enrichment">&nbsp;</span>
<?php
endif;
?>
<a href="<?php echo $baseurl;?>/attributes/edit/<?php echo $object['id']; ?>" title="Edit" class="icon-edit useCursorPointer"></a>
<span class="icon-trash useCursorPointer" onClick="deleteObject('attributes', 'delete', '<?php echo h($object['id']); ?>', '<?php echo h($event['Event']['id']); ?>');"></span>
<span class="icon-trash useCursorPointer" title="Delete attribute" role="button" tabindex="0" aria-label="Delete attribute" onClick="deleteObject('attributes', 'delete', '<?php echo h($object['id']); ?>', '<?php echo h($event['Event']['id']); ?>');"></span>
<?php
}
endif;
@ -516,12 +519,12 @@
echo $this->Form->create('Shadow_Attribute', array('id' => 'ShadowAttribute_' . $object['id'] . '_accept', 'url' => '/shadow_attributes/accept/' . $object['id'], 'style' => 'display:none;'));
echo $this->Form->end();
?>
<span class="icon-ok useCursorPointer" onClick="acceptObject('shadow_attributes', '<?php echo $object['id']; ?>', '<?php echo $event['Event']['id']; ?>');"></span>
<span class="icon-ok useCursorPointer" title="Accept Proposal" role="button" tabindex="0" aria-label="Accept proposal" onClick="acceptObject('shadow_attributes', '<?php echo $object['id']; ?>', '<?php echo $event['Event']['id']; ?>');"></span>
<?php
}
if (($event['Orgc']['id'] == $me['org_id'] && $mayModify) || $isSiteAdmin || ($object['org_id'] == $me['org_id'])) {
?>
<span class="icon-trash useCursorPointer" onClick="deleteObject('shadow_attributes', 'discard' ,'<?php echo $object['id']; ?>', '<?php echo $event['Event']['id']; ?>');"></span>
<span class="icon-trash useCursorPointer" title="Discard proposal" role="button" tabindex="0" aria-label="Discard proposal" onClick="deleteObject('shadow_attributes', 'discard' ,'<?php echo $object['id']; ?>', '<?php echo $event['Event']['id']; ?>');"></span>
<?php
}
}
@ -582,7 +585,7 @@ attributes or the appropriate distribution level. If you think there is a mistak
var timer;
var lastSelected = false;
var deleted = <?php echo (isset($deleted) && $deleted) ? 'true' : 'false';?>;
$(document).ready(function(){
$(document).ready(function() {
setContextFields();
popoverStartup();
$('.select_attribute').removeAttr('checked');
@ -633,6 +636,32 @@ attributes or the appropriate distribution level. If you think there is a mistak
genericPopup(url, '#screenshot_box');
});
});
$('.hex-value-convert').click(function() {
var val = $(this).parent().children(':first-child').text();
if ($(this).parent().children(':first-child').attr('data-original-title') == 'Hexadecimal representation') {
var bin = [];
var temp;
val.split('').forEach(function(entry) {
temp = parseInt(entry, 16).toString(2);
bin.push(Array(5 - (temp.length)).join('0') + temp);
});
bin = bin.join(' ');
$(this).parent().children(':first-child').text(bin);
$(this).parent().children(':first-child').attr('data-original-title', 'Binary representation');
$(this).parent().children(':nth-child(2)').attr('data-original-title', 'Switch to hexadecimal representation');
$(this).parent().children(':nth-child(2)').attr('aria-label', 'Switch to hexadecimal representation');
} else {
val = val.split(' ');
hex = '';
val.forEach(function(entry) {
hex += parseInt(entry , 2).toString(16).toUpperCase();
});
$(this).parent().children(':first-child').text(hex);
$(this).parent().children(':first-child').attr('data-original-title', 'Hexadecimal representation');
$(this).parent().children(':nth-child(2)').attr('data-original-title', 'Switch to binary representation');
$(this).parent().children(':nth-child(2)').attr('aria-label', 'Switch to binary representation');
}
});
</script>
<?php
echo $this->Js->writeBuffer();

View File

@ -59,8 +59,8 @@
<li><a href="<?php echo $baseurl;?>/galaxies/index">List Galaxies</a></li>
</ul>
</li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
Input Filters
@ -149,12 +149,12 @@
<li class="divider"></li>
<li><a href="<?php echo $baseurl;?>/tasks">Scheduled Tasks</a></li>
<?php endif; ?>
<?php if (Configure::read('MISP.enableEventBlacklisting') && $isSiteAdmin): ?>
<?php if (Configure::read('MISP.enableEventBlacklisting') !== false && $isSiteAdmin): ?>
<li class="divider"></li>
<li><a href="<?php echo $baseurl;?>/eventBlacklists/add">Blacklist Event</a></li>
<li><a href="<?php echo $baseurl;?>/eventBlacklists">Manage Event Blacklists</a></li>
<?php endif; ?>
<?php if (Configure::read('MISP.enableEventBlacklisting') && $isSiteAdmin): ?>
<?php if (Configure::read('MISP.enableEventBlacklisting') !== false && $isSiteAdmin): ?>
<li class="divider"></li>
<li><a href="<?php echo $baseurl;?>/orgBlacklists/add">Blacklist Organisation</a></li>
<li><a href="<?php echo $baseurl;?>/orgBlacklists">Manage Org Blacklists</a></li>
@ -190,7 +190,7 @@
</li>
<li>
<a href="<?php echo $baseurl;?>/users/dashboard" style="padding-left:0px;padding-right:0px;">
<span class="notification-<?php echo ($notifications['total'] > 0) ? 'active' : 'passive';?>"><span style="float:left;margin-top:3px;margin-right:3px;margin-left:3px;" class="icon-envelope icon-white"></span></span>
<span class="notification-<?php echo ($notifications['total'] > 0) ? 'active' : 'passive';?>"><span style="float:left;margin-top:3px;margin-right:3px;margin-left:3px;" class="icon-envelope icon-white" title="Dashboard" role="button" tabindex="0" aria-label="Dashboard"></span></span>
</a>
</li>
<?php if (!$externalAuthUser || !Configure::read('Plugin.CustomAuth_disable_logout')): ?>

View File

@ -7,8 +7,8 @@
endif;
?>
<h3>MISP version</h3>
<p>Since version 2.3.14, every version of MISP includes a json file with the current version. This is checked against the latest tag on github, if there is a version mismatch the tool will warn you about it. Make sure that you update MISP regularly.</p>
<div style="background-color:#f7f7f9;width:400px;">
<p>Every version of MISP includes a json file with the current version. This is checked against the latest tag on github, if there is a version mismatch the tool will warn you about it. Make sure that you update MISP regularly.</p>
<div style="background-color:#f7f7f9;width:100%;">
<span>Currently installed version.....
<?php
@ -32,14 +32,14 @@
?>
<span style="color:<?php echo $fontColour; ?>;">
<?php
echo $version['current'];
echo $version['current'] . ' (' . h($commit) . ')';
?>
</span>
</span><br />
<span>Latest available version.....
<span style="color:<?php echo $fontColour; ?>;">
<?php
echo $version['newest'];
echo $version['newest'] . ' (' . $latestCommit . ')';
?>
</span>
</span><br />
@ -49,7 +49,19 @@
echo $versionText;
?>
</span>
</span>
</span><br />
<span>Current branch.....
<?php
$branchColour = $branch == '2.4' ? 'green' : 'red bold';
?>
<span class="<?php echo h($branchColour); ?>">
<?php
echo h($branch);
?>
</span>
</span><br />
<pre class="hidden red" id="gitResult"></pre>
<button title="Pull the latest MISP version from github" class="btn btn-inverse" style="padding-top:1px;padding-bottom:1px;" onClick = "updateMISP();">Update MISP</button>
</div>
<h3>Writeable Directories and files</h3>
<p>The following directories and files have to be writeable for MISP to function properly. Make sure that the apache user has write privileges for the directories below.</p>
@ -230,9 +242,9 @@
?>
</div>
<div>
<span class="btn btn-inverse" style="padding-top:1px;padding-bottom:1px;" onClick = "zeroMQServerAction('start')">Start / Restart</span>
<span class="btn btn-inverse" style="padding-top:1px;padding-bottom:1px;" onClick = "zeroMQServerAction('stop')">Stop</span>
<span class="btn btn-inverse" style="padding-top:1px;padding-bottom:1px;" onClick = "zeroMQServerAction('status')">Status</span>
<span class="btn btn-inverse" role="button" tabindex="0" aria-label="Start or restart ZMQ service" title="Start or restart ZeroMQ service" style="padding-top:1px;padding-bottom:1px;" onClick = "zeroMQServerAction('start')">Start / Restart</span>
<span class="btn btn-inverse" role="button" tabindex="0" aria-label="Stop ZeroMQ service" title="Stop ZeroMQ service" style="padding-top:1px;padding-bottom:1px;" onClick = "zeroMQServerAction('stop')">Stop</span>
<span class="btn btn-inverse" role="button" tabindex="0" aria-label="Check ZeroMQ service status" title="Check ZeroMQ service status" style="padding-top:1px;padding-bottom:1px;" onClick = "zeroMQServerAction('status')">Status</span>
</div>
<h3>
Proxy
@ -304,8 +316,13 @@
<div style="background-color:#f7f7f9;width:400px;">
Orphaned attributes....<span id="orphanedAttributeCount"><span style="color:orange;">Run the test below</span></span>
</div><br />
<span class="btn btn-inverse" style="padding-top:1px;padding-bottom:1px;" onClick="checkOrphanedAttributes();">Check for orphaned attributes</span><br /><br />
<span class="btn btn-inverse" role="button" tabindex="0" aria-label="Check for orphaned attribute" title="Check for orphaned attributes" style="padding-top:1px;padding-bottom:1px;" onClick="checkOrphanedAttributes();">Check for orphaned attributes</span><br /><br />
<?php echo $this->Form->postButton('Remove orphaned attributes', $baseurl . '/attributes/pruneOrphanedAttributes', $options = array('class' => 'btn btn-primary', 'style' => 'padding-top:1px;padding-bottom:1px;')); ?>
<h3>
Verify PGP keys
</h3>
<p>Run a full validation of all PGP keys within this instance's userbase. The script will try to identify possible issues with each key and report back on the results.</p>
<span class="btn btn-inverse" onClick="location.href='<?php echo $baseurl;?>/users/verifyGPG';">Verify GPG keys</span> (Check whether every user's GPG key is usable)</li>
<h3>
Database cleanup scripts
</h3>

View File

@ -6,7 +6,7 @@
<table class="table table-hover table-condensed" style="border:1px solid #dddddd; margin-top:1px; margin-bottom:0px; width:100%; padding:10px">
<?php if ($subGroup != 'general'): ?>
<tr>
<th class="useCursorPointer" style="border-right: 1px solid #dddddd;color: #0088cc;" onClick="toggleSettingSubGroup('<?php echo h($subGroup);?>')"><?php echo h($subGroup);?></th>
<th class="useCursorPointer" role="button" tabindex="0" aria-label="Toggle subgroup <?php echo h($subGroup); ?>" title="Toggle subgroup" style="border-right: 1px solid #dddddd;color: #0088cc;" onClick="toggleSettingSubGroup('<?php echo h($subGroup);?>')"><?php echo h($subGroup);?></th>
</tr>
<?php endif;?>
<tr class="subGroup_<?php echo h($subGroup);?> hidden">

View File

@ -45,6 +45,6 @@
<a href="<?php echo $baseurl;?>/servers/serverSettings/files" id="download-button" title="Manage files" class="discrete">Manage files</a>
</span>
<span class="tabMenuFixed tabMenuFixedCenter tabMenuSides" style="margin-left:10px;">
<a href="<?php echo $baseurl;?>/servers/serverSettings/download" id="download-button" title="Download report" class="useCursorPointer discrete icon-download-alt"></a>
<a href="<?php echo $baseurl;?>/servers/serverSettings/download" id="download-button" title="Download report" role="button" tabindex="0" aria-label="Download report" class="useCursorPointer discrete icon-download-alt"></a>
</span>
</div>

View File

@ -12,7 +12,7 @@
?>
<div class="attributehistogram-legend-line">
<div class="attributehistogram-legend-box" style="display: block;float: left;margin: 4px 6px 0 0;background-color:<?php echo $colour; ?>">&nbsp;</div>
<div style="display: inline-block;cursor: pointer;<?php if (in_array($type, $selectedTypes)) echo 'font-weight:bold';?>" onClick='toggleHistogramType("<?php echo $type; ?>", [<?php foreach ($selectedTypes as $t) echo '"' . $t . '", ' ?>]);'><?php echo $type;?></div>
<div style="display: inline-block;cursor: pointer;<?php if (in_array($type, $selectedTypes)) echo 'font-weight:bold';?>" role="button" tabindex="0" aria-label="Toggle histogram" tite="Toggle histogram" onClick='toggleHistogramType("<?php echo $type; ?>", [<?php foreach ($selectedTypes as $t) echo '"' . $t . '", ' ?>]);'><?php echo $type;?></div>
</div>
<?php
if ($cnt % 12 == 11):

View File

@ -14,7 +14,7 @@
<?php
echo $this->Form->create('Server', array('id' => 'removeTag_' . h($tag['Tag']['id']), 'url' => '/servers/removeTag/' . h($server['Server']['id']) . '/' . h($tag['Tag']['id']), 'style' => 'margin:0px;'));
?>
<div class="tagSecondHalf useCursorPointer noPrint" onClick="removeServerTag('<?php echo h($server['Server']['id']); ?>', '<?php echo h($tag['Tag']['id']); ?>');">x</div>
<div title="Remove tag" role="button" tabindex="0" aria-label="Remove tag" class="tagSecondHalf useCursorPointer noPrint" onClick="removeServerTag('<?php echo h($server['Server']['id']); ?>', '<?php echo h($tag['Tag']['id']); ?>');">x</div>
<?php
echo $this->Form->end();
?>
@ -28,7 +28,7 @@
?>
<div style="float:left">
<?php if ($isSiteAdmin): ?>
<button id="addTagButton" class="btn btn-inverse noPrint" style="line-height:10px; padding: 4px 4px;" onClick="getPopup('<?php echo h($server['Server']['id']); ?>', 'tags', 'selectTaxonomy');">+</button>
<button title="Add a tag" id="addTagButton" class="btn btn-inverse noPrint" style="line-height:10px; padding: 4px 4px;" onClick="getPopup('<?php echo h($server['Server']['id']); ?>', 'tags', 'selectTaxonomy');">+</button>
<?php else:?>
&nbsp;
<?php endif; ?>

View File

@ -6,49 +6,52 @@
<table>
<tr>
<td style="width:120px;">
<p style="color:green;font-weight:bold;">Allowed Tags</p>
<p style="color:green;font-weight:bold;">Allowed Tags (OR)</p>
<select id="tagspullLeftValues" size="5" multiple style="width:185px;">
</select>
</td>
<td style="width:50px;text-align:center;">
<span class="btn btn-inverse" id="tagspullLeftLeft" style="padding:2px;" onClick="serverRuleMoveFilter('pull', 'tags', 'Middle', 'Left');">&lt;&lt;</span>
<span class="btn btn-inverse" id="tagspullLeftRight" style="padding:2px;" onClick="serverRuleMoveFilter('pull', 'tags', 'Left', 'Middle');">&gt;&gt;</span>
<span title="Move tag to the list of tags to allow" role="button" tabindex="0" aria-label="Move tag to the list of tags to allow" class="btn btn-inverse" id="tagspullLeftLeft" style="padding:2px;" onClick="serverRuleMoveFilter('pull', 'tags', 'Middle', 'Left');">&lt;&lt;</span>
<span title="Remove tag from the list of tags to allow" role="button" tabindex="0" aria-label="Remove tag from the list of tags to allow" class="btn btn-inverse" id="tagspullLeftRight" style="padding:2px;" onClick="serverRuleMoveFilter('pull', 'tags', 'Left', 'Middle');">&gt;&gt;</span>
</td>
<td style="width:120px;">
<input id="tagspullNewValue" style="width:180px;"></input>
</td>
<td style="width:50px;text-align:center;">
<span class="btn btn-inverse" id="tagspullRightLeft" style="padding:2px;" onClick="serverRuleMoveFilter('pull', 'tags', 'Right', 'Middle');">&lt;&lt;</span>
<span class="btn btn-inverse" id="tagspullRightRight" style="padding:2px;" onClick="serverRuleMoveFilter('pull', 'tags', 'Middle', 'Right');">&gt;&gt;</span>
<span title="Remove tag from the list of tags to block" role="button" tabindex="0" aria-label="Remove tag from the list of tags to block" class="btn btn-inverse" id="tagspullRightLeft" style="padding:2px;" onClick="serverRuleMoveFilter('pull', 'tags', 'Right', 'Middle');">&lt;&lt;</span>
<span title="Move tag to the list of tags to block" role="button" tabindex="0" aria-label="Move tag to the list of tags to block" class="btn btn-inverse" id="tagspullRightRight" style="padding:2px;" onClick="serverRuleMoveFilter('pull', 'tags', 'Middle', 'Right');">&gt;&gt;</span>
</td>
<td style="width:120px;">
<p style="color:red;font-weight:bold;">Blocked Tags</p>
<p style="color:red;font-weight:bold;">Blocked Tags (AND NOT)</p>
<select id="tagspullRightValues" size="5" multiple style="width:185px;"></select>
</td>
</tr>
</table>
</div>
<div style="padding:10px;">
<table>
<tr>
<td class="bold green center" style="padding-bottom:15px;padding-top:15px;">AND</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td class="bold red center" style="padding-bottom:15px;padding-top:15px;">AND NOT</td>
</tr>
<tr>
<td style="width:120px;">
<p style="color:green;font-weight:bold;">Allowed Organisations</p>
<p style="color:green;font-weight:bold;">Allowed Orgs (OR)</p>
<select id="orgspullLeftValues" size="5" multiple style="width:185px;">
</select>
</td>
<td style="width:50px;text-align:center;">
<span class="btn btn-inverse" id="orgspullLeftLeft" style="padding:2px;" onClick="serverRuleMoveFilter('pull', 'orgs', 'Middle', 'Left');">&lt;&lt;</span>
<span class="btn btn-inverse" id="orgspullLeftRight" style="padding:2px;" onClick="serverRuleMoveFilter('pull', 'orgs', 'Left', 'Middle');">&gt;&gt;</span>
<span title="Move organisation to the list of tags to allow" role="button" tabindex="0" aria-label="Move organisation to the list of organisations to allow" class="btn btn-inverse" id="orgspullLeftLeft" style="padding:2px;" onClick="serverRuleMoveFilter('pull', 'orgs', 'Middle', 'Left');">&lt;&lt;</span>
<span title="Remove organisation to the list of tags to allow" role="button" tabindex="0" aria-label="Remove organisation form the list of organisations to allow" class="btn btn-inverse" id="orgspullLeftRight" style="padding:2px;" onClick="serverRuleMoveFilter('pull', 'orgs', 'Left', 'Middle');">&gt;&gt;</span>
</td>
<td style="width:120px;">
<input id="orgspullNewValue" style="width:180px;"></input>
</td>
<td style="width:50px;text-align:center;">
<span class="btn btn-inverse" id="orgspullRightLeft" style="padding:2px;" onClick="serverRuleMoveFilter('pull', 'orgs', 'Right', 'Middle');">&lt;&lt;</span>
<span class="btn btn-inverse" id="orgspullRightRight" style="padding:2px;" onClick="serverRuleMoveFilter('pull', 'orgs', 'Middle', 'Right');">&gt;&gt;</span>
<span title="Remove organisation from the list of tags to allow" role="button" tabindex="0" aria-label="Remove organisation from the list of organisations to block" class="btn btn-inverse" id="orgspullRightLeft" style="padding:2px;" onClick="serverRuleMoveFilter('pull', 'orgs', 'Right', 'Middle');">&lt;&lt;</span>
<span title="Move organisation to the list of tags to block" role="button" tabindex="0" aria-label="Move organisation to the list of organisations to block" class="btn btn-inverse" id="orgspullRightRight" style="padding:2px;" onClick="serverRuleMoveFilter('pull', 'orgs', 'Middle', 'Right');">&gt;&gt;</span>
</td>
<td style="width:120px;">
<p style="color:red;font-weight:bold;">Blocked Organisations</p>
<p style="color:red;font-weight:bold;">Blocked Orgs (AND NOT)</p>
<select id="orgspullRightValues" size="5" multiple style="width:185px;"></select>
</td>
</tr>
@ -59,12 +62,12 @@
<table>
<tr>
<td style="vertical-align:top">
<span id="PromptYesButton" class="btn btn-primary" onClick="submitServerRulePopulateTagPicklistValues('pull');">Update</span>
<span title="Accept changes" role="button" tabindex="0" aria-label="Accept changes" id="PromptYesButton" class="btn btn-primary" onClick="submitServerRulePopulateTagPicklistValues('pull');">Update</span>
</td>
<td style="width:540px;">
</td>
<td style="vertical-align:top;">
<span class="btn btn-inverse" id="PromptNoButton" onClick="serverRuleCancel();">Cancel</span>
<span title="Cancel" role="button" tabindex="0" aria-label="Cancel" class="btn btn-inverse" id="PromptNoButton" onClick="serverRuleCancel();">Cancel</span>
</td>
</tr>
</table>

View File

@ -6,13 +6,13 @@
<table>
<tr>
<td style="width:120px;">
<p style="color:green;font-weight:bold;">Allowed Tags</p>
<p style="color:green;font-weight:bold;">Allowed Tags (OR)</p>
<select id="tagspushLeftValues" size="5" multiple style="width:185px;">
</select>
</td>
<td style="width:50px;text-align:center;">
<span class="btn btn-inverse" id="tagspushLeftLeft" onClick="serverRuleMoveFilter('push', 'tags', 'Middle', 'Left');" style="padding:2px;">&lt;&lt;</span>
<span class="btn btn-inverse" id="tagspushLeftRight" onClick="serverRuleMoveFilter('push', 'tags', 'Left', 'Middle');" style="padding:2px;">&gt;&gt;</span>
<span title="Move tag to the list of tags to allow" role="button" tabindex="0" aria-label="Move tag to the list of tags to allow" class="btn btn-inverse" id="tagspushLeftLeft" onClick="serverRuleMoveFilter('push', 'tags', 'Middle', 'Left');" style="padding:2px;">&lt;&lt;</span>
<span title="Remove tag from the list of tags to allow" role="button" tabindex="0" aria-label="Remove tag from the list of tags to allow"class="btn btn-inverse" id="tagspushLeftRight" onClick="serverRuleMoveFilter('push', 'tags', 'Left', 'Middle');" style="padding:2px;">&gt;&gt;</span>
</td>
<td style="width:120px;">
<p style="font-weight:bold;">Available Tags</p>
@ -20,27 +20,30 @@
</select>
</td>
<td style="width:50px;text-align:center;">
<span class="btn btn-inverse" id="tagspushRightLeft" onClick="serverRuleMoveFilter('push', 'tags', 'Right', 'Middle');" style="padding:2px;">&lt;&lt;</span>
<span class="btn btn-inverse" id="tagspushRightRight" onClick="serverRuleMoveFilter('push', 'tags', 'Middle', 'Right');" style="padding:2px;">&gt;&gt;</span>
<span title="Remove tag from the list of tags to block" role="button" tabindex="0" aria-label="Remove tag from the list of tags to block" class="btn btn-inverse" id="tagspushRightLeft" style="padding:2px;" onClick="serverRuleMoveFilter('push', 'tags', 'Right', 'Middle');">&lt;&lt;</span>
<span title="Move tag to the list of tags to block" role="button" tabindex="0" aria-label="Move tag to the list of tags to block" class="btn btn-inverse" id="tagspushRightRight" style="padding:2px;" onClick="serverRuleMoveFilter('push', 'tags', 'Middle', 'Right');">&gt;&gt;</span>
</td>
<td style="width:120px;">
<p style="color:red;font-weight:bold;">Blocked Tags</p>
<p style="color:red;font-weight:bold;">Blocked Tags (AND NOT)</p>
<select id="tagspushRightValues" size="5" multiple style="width:185px;"></select>
</td>
</tr>
</table>
</div>
<div style="padding:10px;">
<table>
<tr>
<td class="bold green center" style="padding-bottom:15px;padding-top:15px;">AND</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td class="bold red center" style="padding-bottom:15px;padding-top:15px;">AND NOT</td>
</tr>
<tr>
<td style="width:120px;">
<p style="color:green;font-weight:bold;">Allowed Organisations</p>
<p style="color:green;font-weight:bold;">Allowed Orgs (OR)</p>
<select id="orgspushLeftValues" size="5" multiple style="width:185px;">
</select>
</td>
<td style="width:50px;text-align:center;">
<span class="btn btn-inverse" id="orgspushLeftLeft" onClick="serverRuleMoveFilter('push', 'orgs', 'Middle', 'Left');" style="padding:2px;">&lt;&lt;</span>
<span class="btn btn-inverse" id="orgspushLeftRight" onClick="serverRuleMoveFilter('push', 'orgs', 'Left', 'Middle');" style="padding:2px;">&gt;&gt;</span>
<span title="Move organisation to the list of organisations to allow" role="button" tabindex="0" aria-label="Move organisation to the list of organisations to allow" class="btn btn-inverse" id="orgspushLeftLeft" onClick="serverRuleMoveFilter('push', 'orgs', 'Middle', 'Left');" style="padding:2px;">&lt;&lt;</span>
<span title="Remove organisation from the list of organisations to allow" role="button" tabindex="0" aria-label="Remove organisation from the list of organisations to allow" class="btn btn-inverse" id="orgspushLeftRight" onClick="serverRuleMoveFilter('push', 'orgs', 'Left', 'Middle');" style="padding:2px;">&gt;&gt;</span>
</td>
<td style="width:120px;">
<p style="font-weight:bold;">Available Organisations</p>
@ -48,18 +51,16 @@
</select>
</td>
<td style="width:50px;text-align:center;">
<span class="btn btn-inverse" id="orgspushRightLeft" onClick="serverRuleMoveFilter('push', 'orgs', 'Right', 'Middle');" style="padding:2px;">&lt;&lt;</span>
<span class="btn btn-inverse" id="orgspushRightRight" onClick="serverRuleMoveFilter('push', 'orgs', 'Middle', 'Right');" style="padding:2px;">&gt;&gt;</span>
<span title="Remove organisation from the list of organisations to block" role="button" tabindex="0" aria-label="Remove organisation from the list of organisations to block" class="btn btn-inverse" id="orgspushRightLeft" onClick="serverRuleMoveFilter('push', 'orgs', 'Right', 'Middle');" style="padding:2px;">&lt;&lt;</span>
<span title="Move organisation to the list of organisations to block" role="button" tabindex="0" aria-label="Move organisation to the list of organisations to block"class="btn btn-inverse" id="orgspushRightRight" onClick="serverRuleMoveFilter('push', 'orgs', 'Middle', 'Right');" style="padding:2px;">&gt;&gt;</span>
</td>
<td style="width:120px;">
<p style="color:red;font-weight:bold;">Blocked Organisations</p>
<p style="color:red;font-weight:bold;">Blocked Orgs (AND NOT)</p>
<select id="orgspushRightValues" size="5" multiple style="width:185px;"></select>
</td>
</tr>
</table>
</div>
<table>
<tr>
<td style="vertical-align:top">

View File

@ -224,11 +224,11 @@
<li class="divider"></li>
<li id='litasks'><a href="<?php echo $baseurl;?>/tasks">Scheduled Tasks</a></li>
<?php endif;
if (Configure::read('MISP.enableEventBlacklisting')): ?>
if (Configure::read('MISP.enableEventBlacklisting') !== false): ?>
<li <?php if ($menuItem === 'eventBlacklistsAdd') echo 'class="active"';?>><a href="<?php echo $baseurl;?>/eventBlacklists/add">Blacklists Event</a></li>
<li <?php if ($menuItem === 'eventBlacklists') echo 'class="active"';?>><a href="<?php echo $baseurl;?>/eventBlacklists">Manage Event Blacklists</a></li>
<?php endif;
if (Configure::read('MISP.enableOrgBlacklisting')): ?>
if (!Configure::check('MISP.enableOrgBlacklisting') || Configure::read('MISP.enableOrgBlacklisting') !== false): ?>
<li <?php if ($menuItem === 'orgBlacklistsAdd') echo 'class="active"';?>><a href="<?php echo $baseurl;?>/orgBlacklists/add">Blacklists Organisation</a></li>
<li <?php if ($menuItem === 'orgBlacklists') echo 'class="active"';?>><a href="<?php echo $baseurl;?>/orgBlacklists">Manage Org Blacklists</a></li>
<?php endif;

View File

@ -98,11 +98,11 @@
if ($mayModify) {
echo $this->Form->create('TemplateElement', array('class' => 'inline-delete', 'style' => 'display:inline-block;', 'id' => 'TemplateElement_' . h($element_id) . '_delete', 'url' => array('action' => 'delete')));
?>
<span class="icon-trash useCursorPointer" onClick="deleteObject('template_elements', 'delete' ,'<?php echo h($element_id); ?>', '<?php echo h($element['TemplateElement']['template_id']); ?>');"></span>
<span class="icon-trash useCursorPointer" title="Delete template element" role="button" tabindex="0" aria-label="Delete template element" onClick="deleteObject('template_elements', 'delete' ,'<?php echo h($element_id); ?>', '<?php echo h($element['TemplateElement']['template_id']); ?>');"></span>
<?php
echo $this->Form->end();
?>
<span class="icon-edit useCursorPointer" onClick="editTemplateElement('attribute' ,'<?php echo h($element_id); ?>');"></span>
<span class="icon-edit useCursorPointer" title="Edit template element" role="button" tabindex="0" aria-label="Edit template element" onClick="editTemplateElement('attribute' ,'<?php echo h($element_id); ?>');"></span>
<?php
} else {
echo '&nbsp;';

View File

@ -75,11 +75,11 @@
if ($mayModify) {
echo $this->Form->create('TemplateElement', array('class' => 'inline-delete', 'style' => 'display:inline-block;', 'id' => 'TemplateElement_' . h($element_id) . '_delete', 'url' => array('action' => 'delete')));
?>
<span class="icon-trash useCursorPointer" onClick="deleteObject('template_elements', 'delete' ,'<?php echo h($element_id); ?>', '<?php echo h($element['TemplateElement']['template_id']); ?>');"></span>
<span class="icon-trash useCursorPointer" title="Delete template element" role="button" tabindex="0" aria-label="Delete template element" onClick="deleteObject('template_elements', 'delete' ,'<?php echo h($element_id); ?>', '<?php echo h($element['TemplateElement']['template_id']); ?>');"></span>
<?php
echo $this->Form->end();
?>
<span class="icon-edit useCursorPointer" onClick="editTemplateElement('file' ,'<?php echo h($element_id); ?>');"></span>
<span class="icon-edit useCursorPointer" title="Edit template element" role="button" tabindex="0" aria-label="Edit template element" onClick="editTemplateElement('file' ,'<?php echo h($element_id); ?>');"></span>
<?php
} else {
echo '&nbsp;';

View File

@ -32,11 +32,11 @@
if ($mayModify) {
echo $this->Form->create('TemplateElement', array('class' => 'inline-delete', 'style' => 'display:inline-block;', 'id' => 'TemplateElement_' . h($element_id) . '_delete', 'url' => array('action' => 'delete')));
?>
<span class="icon-trash useCursorPointer" onClick="deleteObject('template_elements', 'delete' ,'<?php echo h($element_id); ?>', '<?php echo h($element['TemplateElement']['template_id']); ?>');"></span>
<span class="icon-trash useCursorPointer" title="Delete template element" role="button" tabindex="0" aria-label="Delete template element" onClick="deleteObject('template_elements', 'delete' ,'<?php echo h($element_id); ?>', '<?php echo h($element['TemplateElement']['template_id']); ?>');"></span>
<?php
echo $this->Form->end();
?>
<span class="icon-edit useCursorPointer" onClick="editTemplateElement('text' ,'<?php echo h($element_id); ?>');"></span>
<span class="icon-edit useCursorPointer" title="Edit template element" role="button" tabindex="0" aria-label="Edit template element" onClick="editTemplateElement('text' ,'<?php echo h($element_id); ?>');"></span>
<?php
} else {
echo '&nbsp;';

View File

@ -1,28 +1,26 @@
<?php
/**
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package Cake.View.Errors
* @package app.View.Errors
* @since CakePHP(tm) v 0.10.0.1076
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
?>
<h2><?php echo $name; ?></h2>
<h2><?php echo $message; ?></h2>
<p class="error">
<strong><?php echo __d('cake', 'Error'); ?>: </strong>
<?php echo __d('cake', 'An Internal Error Has Occurred.'); ?>
</p>
<?php
if (Configure::read('debug') > 0 ):
echo $this->element('exception_stack_trace');
echo $this->element('exception_stack_trace');
endif;
?>

View File

@ -35,7 +35,7 @@ foreach ($response as $item): ?>
<td class="short"><?php echo (isset($item['EventBlacklist']['event_info']) ? h($item['EventBlacklist']['event_info']) : '&nbsp;'); ?></td>
<td class="short"><?php echo (isset($item['EventBlacklist']['comment']) ? h($item['EventBlacklist']['comment']) : '&nbsp;'); ?></td>
<td class="short action-links">
<a href="<?php echo $baseurl;?>/eventBlacklists/edit/<?php echo h($item['EventBlacklist']['id']); ?>"><span class="icon-edit" title="edit">&nbsp;</span></a>
<a href="<?php echo $baseurl;?>/eventBlacklists/edit/<?php echo h($item['EventBlacklist']['id']); ?>"><span class="icon-edit" title="edit" role="button" tabindex="0" aria-label="Edit blacklist entry">&nbsp;</span></a>
<?php echo $this->Form->postLink('', array('action' => 'delete', h($item['EventBlacklist']['id'])), array('class' => 'icon-trash', 'title' => 'Delete'), __('Are you sure you want to delete the blacklist entry for the event UUID %s?', h($item['EventBlacklist']['event_uuid']))); ?>
</td>
</tr><?php

View File

@ -1,7 +1,7 @@
<div class="confirmation">
<div class="legend">Accept Delegation Request</div>
<div style="padding-left:5px;padding-right:5px;padding-bottom:5px;">
<p>Are you sure you would like to accept the request by <?php echo h($delegationRequest['Org']['name']); ?> to take ownership of Event #<?php echo h($delegationRequest['Event']['id']);?>?</p>
<p>Are you sure you would like to accept the request by <?php echo h($delegationRequest['RequesterOrg']['name']); ?> to take ownership of Event #<?php echo h($delegationRequest['Event']['id']);?>?</p>
<table>
<tr>
<td style="vertical-align:top">
@ -14,7 +14,7 @@
<td style="width:540px;">
</td>
<td style="vertical-align:top;">
<span class="btn btn-inverse" id="PromptNoButton" onClick="cancelPrompt();">No</span>
<span title="Cancel" role="button" tabindex="0" aria-label="Cancel" class="btn btn-inverse" id="PromptNoButton" onClick="cancelPrompt();">No</span>
</td>
</tr>
</table>

View File

@ -34,7 +34,7 @@
));
echo $this->Form->submit('Yes', array('div' => false, 'class' => 'btn btn-primary'));
?>
<span class="btn btn-inverse" id="PromptNoButton" onClick="cancelPopoverForm();" style="float:right;">No</span>
<span role="button" tabindex="0" aria-label="Cancel" title="Cancel" class="btn btn-inverse" id="PromptNoButton" onClick="cancelPopoverForm();" style="float:right;">No</span>
<?php
echo $this->Form->end();
?>

View File

@ -1,7 +1,7 @@
<div class="confirmation">
<div class="legend">Delete Delegation Request</div>
<div style="padding-left:5px;padding-right:5px;padding-bottom:5px;">
<p>Are you sure you would like to discard the request by <?php echo h($delegationRequest['Org']['name']); ?> to take owenership of Event #<?php echo h($delegationRequest['Event']['id']);?>?</p>
<p>Are you sure you would like to discard the request by <?php echo h($delegationRequest['RequesterOrg']['name']); ?> to take owenership of Event #<?php echo h($delegationRequest['Event']['id']);?>?</p>
<table>
<tr>
<td style="vertical-align:top">
@ -14,7 +14,7 @@
<td style="width:540px;">
</td>
<td style="vertical-align:top;">
<span class="btn btn-inverse" id="PromptNoButton" onClick="cancelPrompt();">No</span>
<span role="button" tabindex="0" aria-label="Cancel" title="Cancel" class="btn btn-inverse" id="PromptNoButton" onClick="cancelPrompt();">No</span>
</td>
</tr>
</table>

View File

@ -18,9 +18,9 @@ $requester = $me['org_id'] == $delegation['RequesterOrg']['id'] ? 'Your organisa
<p><b>Message from requester</b><br /><?php echo h($delegation['EventDelegation']['message']); ?></p>
<div class="row-fluid">
<?php if ($isSiteAdmin || $me['org_id'] == $delegation['Org']['id']):?>
<span class="btn btn-primary" onClick="genericPopup('<?php echo $baseurl?>/event_delegations/acceptDelegation/<?php echo h($delegation['EventDelegation']['id']); ?>', '#confirmation_box');">Accept</span>
<span role="button" tabindex="0" aria-label="Accept delegation request" title="Accept delegation request" class="btn btn-primary" onClick="genericPopup('<?php echo $baseurl?>/event_delegations/acceptDelegation/<?php echo h($delegation['EventDelegation']['id']); ?>', '#confirmation_box');">Accept</span>
<?php endif;?>
<span class="btn btn-inverse" onClick="genericPopup('<?php echo $baseurl?>/event_delegations/deleteDelegation/<?php echo h($delegation['EventDelegation']['id']); ?>', '#confirmation_box');">Discard</span>
<span class="btn btn-inverse" style="float:right;" id="PromptNoButton" onClick="cancelPrompt();">Cancel</span>
<span role="button" tabindex="0" aria-label="Decline and remove delegation request" title="Decline and remove delegation request" class="btn btn-inverse" onClick="genericPopup('<?php echo $baseurl?>/event_delegations/deleteDelegation/<?php echo h($delegation['EventDelegation']['id']); ?>', '#confirmation_box');">Discard</span>
<span role="button" tabindex="0" aria-label="Cancel" title="Cancel" class="btn btn-inverse" style="float:right;" id="PromptNoButton" onClick="cancelPrompt();">Cancel</span>
</div>
</div>

View File

@ -13,7 +13,6 @@ echo $this->Form->input('Event.submittedioc', array(
echo $this->Form->button('Upload', array('class' => 'btn btn-primary'));
echo $this->Form->end();
?>
<div id="confirmation_box" class="confirmation_box"></div>
</div>
<?php
$event['Event']['id'] = $id;

View File

@ -3,11 +3,11 @@
<div class="popover_choice_main" id ="popover_choice_main">
<div style="width:100%;">
<?php foreach ($modules as $k => $module): ?>
<div style="border-bottom:1px solid black; text-align:center;width:100%;" class="templateChoiceButton useCursorPointer" onClick="window.location='<?php echo $baseurl;?>/events/queryEnrichment/<?php echo implode('/', array(h($attribute_id), h($module['name'])));?>';" title="<?php echo h($module['description']);?>"><?php echo h($module['name']);?></div>
<div style="border-bottom:1px solid black; text-align:center;width:100%;" class="templateChoiceButton useCursorPointer" onClick="window.location='<?php echo $baseurl;?>/events/queryEnrichment/<?php echo implode('/', array(h($attribute_id), h($module['name'])));?>';" title="<?php echo h($module['description']);?>" role="button" tabindex="0" aria-label="Enrich using the <?php echo h($module['name']); ?> module"><?php echo h($module['name']);?></div>
<?php endforeach; ?>
</div>
</div>
<div class="templateChoiceButton templateChoiceButtonLast" onClick="cancelPopoverForm();">Cancel</div>
<div role="button" tabindex="0" aria-label="Cancel" title="Cancel" class="templateChoiceButton templateChoiceButtonLast" onClick="cancelPopoverForm();">Cancel</div>
</div>
<script type="text/javascript">
$(document).ready(function() {

View File

@ -20,12 +20,12 @@
<table>
<tr>
<td style="vertical-align:top">
<span id="PromptYesButton" class="btn btn-primary" onClick="submitPublish()">Yes</span>
<span role="button" tabindex="0" aria-label="Publish" title="Publish" id="PromptYesButton" class="btn btn-primary" onClick="submitPublish()">Yes</span>
</td>
<td style="width:540px;">
</td>
<td style="vertical-align:top;">
<span class="btn btn-inverse" id="PromptNoButton" onClick="cancelPrompt();">No</span>
<span role="button" tabindex="0" aria-label="Cancel" title="Cancel" class="btn btn-inverse" id="PromptNoButton" onClick="cancelPrompt();">No</span>
</td>
</tr>
</table>

View File

@ -4,12 +4,12 @@
<table style="width:100%;">
<?php foreach ($exports as $k => $export): ?>
<tr style="border-bottom:1px solid black;" class="templateChoiceButton">
<td style="padding-left:10px; text-align:left;width:50%;" onClick="exportChoiceSelect('<?php echo h($export['url']); ?>', '<?php echo h($k); ?>', '<?php echo h($export['checkbox']); ?>')"><?php echo h($export['text']); ?></td>
<td role="button" tabindex="0" aria-label="Export as <?php echo h($export['text']); ?>" title="Export as <?php echo h($export['text']); ?>" style="padding-left:10px; text-align:left;width:50%;" onClick="exportChoiceSelect('<?php echo h($export['url']); ?>', '<?php echo h($k); ?>', '<?php echo h($export['checkbox']); ?>')"><?php echo h($export['text']); ?></td>
<td style="padding-right:10px; width:50%;text-align:right;">
<?php if ($export['checkbox']):
echo h($export['checkbox_text']);
?>
<input id = "<?php echo h($k) . '_toggle';?>" type="checkbox" style="align;vertical-align:top;margin-top:8px;" <?php if (isset($export['checkbox_default'])) echo 'checked';?>>
<input title="<?php h($export['checkbox_text']); ?>" id = "<?php echo h($k) . '_toggle';?>" type="checkbox" style="align;vertical-align:top;margin-top:8px;" <?php if (isset($export['checkbox_default'])) echo 'checked';?>>
<span id ="<?php echo h($k);?>_set" style="display:none;"><?php if (isset($export['checkbox_set'])) echo h($export['checkbox_set']); ?></span>
<?php else: ?>
&nbsp;
@ -19,7 +19,7 @@
<?php endforeach; ?>
</table>
</div>
<div class="templateChoiceButton templateChoiceButtonLast" onClick="cancelPopoverForm();">Cancel</div>
<div role="button" tabindex="0" aria-label="Cancel" title="Cancel" class="templateChoiceButton templateChoiceButtonLast" onClick="cancelPopoverForm();">Cancel</div>
</div>
<script type="text/javascript">
$(document).ready(function() {

View File

@ -14,12 +14,12 @@
<table>
<tr>
<td style="vertical-align:top">
<span id="PromptYesButton" class="btn btn-primary" onClick="multiSelectAction('<?php echo h($id); ?>', '<?php echo h($action); ?>');">Yes</span>
<span role="button" tabindex="0" aria-label="Yes" title="Yes" id="PromptYesButton" class="btn btn-primary" onClick="multiSelectAction('<?php echo h($id); ?>', '<?php echo h($action); ?>');">Yes</span>
</td>
<td style="width:540px;">
</td>
<td style="vertical-align:top;">
<span class="btn btn-inverse" id="PromptNoButton" onClick="cancelPrompt();">No</span>
<span class="btn btn-inverse" id="PromptNoButton" role="button" tabindex="0" aria-label="No" title="No" onClick="cancelPrompt();">No</span>
</td>
</tr>
</table>

View File

@ -4,12 +4,12 @@
<table style="width:100%;">
<?php foreach ($imports as $k => $import): ?>
<tr style="border-bottom:1px solid black;" class="templateChoiceButton">
<td style="padding-left:10px; text-align:center;width:100%;" onClick="importChoiceSelect('<?php echo h($import['url']); ?>', '<?php echo h($k); ?>', '<?php echo $import['ajax'] ? h($import['target']) : "false"; ?>')"><?php echo h($import['text']); ?></td>
<td role="button" tabindex="0" aria-label="Import <?php echo h($import['text']); ?>" style="padding-left:10px; text-align:center;width:100%;" onClick="importChoiceSelect('<?php echo h($import['url']); ?>', '<?php echo h($k); ?>', '<?php echo $import['ajax'] ? h($import['target']) : "false"; ?>')"><?php echo h($import['text']); ?></td>
</tr>
<?php endforeach; ?>
</table>
</div>
<div class="templateChoiceButton templateChoiceButtonLast" onClick="cancelPopoverForm();">Cancel</div>
<div role="button" tabindex="0" aria-label="Cancel" title="Cancel" class="templateChoiceButton templateChoiceButtonLast" onClick="cancelPopoverForm();">Cancel</div>
</div>
<script type="text/javascript">
$(document).ready(function() {

View File

@ -2,8 +2,8 @@
echo $this->Form->create('Event', array('class' => 'inline-form inline-field-form', 'url' => '/events/quickEdit/' . $event['Event']['id'] . '/' . $field));
?>
<div class='inline-input inline-input-container'>
<div class="inline-input-accept inline-input-button inline-input-passive"><span class = "icon-ok"></span></div>
<div class="inline-input-decline inline-input-button inline-input-passive"><span class = "icon-remove"></span></div>
<div class="inline-input-accept inline-input-button inline-input-passive"><span class = "icon-ok" title="Accept" role="button" tabindex="0" aria-label="Accept"></span></div>
<div class="inline-input-decline inline-input-button inline-input-passive"><span class = "icon-remove" title="Cancel" role="button" tabindex="0" aria-label="Cancel"></span></div>
<?php
echo $this->Form->input('category', array(
'options' => array(array_combine($typeCategory[$object['type']], $typeCategory[$object['type']])),

View File

@ -17,12 +17,12 @@
<table>
<tr>
<td style="vertical-align:top">
<span id="PromptYesButton" class="btn btn-primary" onClick="submitPublish();">Yes</span>
<span role="button" tabindex="0" aria-label="Toggle correlation" title="Toggle correlation" id="PromptYesButton" class="btn btn-primary" onClick="submitPublish();">Yes</span>
</td>
<td style="width:540px;">
</td>
<td style="vertical-align:top;">
<span class="btn btn-inverse" id="PromptNoButton" onClick="cancelPrompt();">No</span>
<span class="btn btn-inverse" role="button" tabindex="0" aria-label="Cancel" title="Cancel" id="PromptNoButton" onClick="cancelPrompt();">No</span>
</td>
</tr>
</table>

View File

@ -76,7 +76,7 @@ Use semicolons instead (the search will automatically search for colons instead)
<pre><?php echo $baseurl;?>/events/nids/suricata/download
<?php echo $baseurl;?>/events/nids/snort/download</pre>
<p>The full API syntax is as follows:</p>
<pre><?php echo $baseurl;?>/events/nids/[format]/download/[eventid]/[frame]/[tags]/[from]/[to]/[last]/[type]/[enforceWarninglist]</pre>
<pre><?php echo $baseurl;?>/events/nids/[format]/download/[eventid]/[frame]/[tags]/[from]/[to]/[last]/[type]/[enforceWarninglist]/[includeAllTags]</pre>
<p>
<b>format</b>: The export format, can be "suricata" or "snort"<br />
<b>eventid</b>: Restrict the download to a single event<br />
@ -90,6 +90,7 @@ Use semicolons instead (the search will automatically search for colons instead)
<b>last</b>: Events published within the last x amount of time, where x can be defined in days, hours, minutes (for example 6d or 12h or 30m). This filter will use the published timestamp of the event.<br />
<b>type</b>: Restrict the export to only use the given types.<br />
<b>enforceWarninglist</b>: All attributes that have a hit on a warninglist will be excluded.<br />
<b>includeAllTags</b>: All tags will be included even if not exportable.<br />
<p>The keywords false or null should be used for optional empty parameters in the URL.</p>
<p>An example for a suricata export for all events excluding those tagged tag1, without all of the commented information at the start of the file would look like this:</p>
<pre><?php echo $baseurl;?>/events/nids/suricata/download/null/true/!tag1</pre>
@ -287,24 +288,27 @@ Use semicolons instead (the search will automatically search for colons instead)
?>
</pre>
<h3>RESTful searches with XML result export</h3>
<h3>Searches with JSON/XML/OpenIOC results</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>
<p>To return an event or a list of events in a desired format, use the following syntax:</p>
<pre>
<?php
echo $baseurl.'/events/restSearch/download/[value]/[type]/[category]/[org]/[tag]/[quickfilter]/[from]/[to]/[last]/[event_id]/[withAttachments]/[metadata]/[uuid]/[publish_timestamp]/[timestamp]/[published]/[enforceWarninglist]';
echo $baseurl.'/events/restSearch/[format]/[value]/[type]/[category]/[org]/[tag]/[quickfilter]/[from]/[to]/[last]/[event_id]/[withAttachments]/[metadata]/[uuid]/[publish_timestamp]/[timestamp]/[published]/[enforceWarninglist]';
?>
</pre>
<b>format</b>: Set the return format of the search (Currently supported: json, xml, openioc - more formats coming soon).<br />
<b>value</b>: Search for the given value in the attributes' value field.<br />
<b>type</b>: The attribute type, any valid MISP attribute type is accepted.<br />
<b>category</b>: The attribute category, any valid MISP attribute category is accepted.<br />
<b>org</b>: Search by the creator organisation by supplying the organisation idenfitier. <br />
<b>tags</b>: To include a tag in the results just write its names into this parameter. To exclude a tag prepend it with a '!'.
To filter on several values for the same parameter, simply use arrays, such as in the following example: <br />
<code>{"value":["tag1", "tag2", "!tag3"]}</code><br />
You can also chain several tag commands together with the '&amp;&amp;' operator. Please be aware the colons (:) cannot be used in the tag search.
Use semicolons instead (the search will automatically search for colons instead). For example, to include tag1 and tag2 but exclude tag3 you would use:<br />
<pre>
<?php
echo $baseurl.'/events/restSearch/download/null/null/null/null/tag1&amp;&amp;tag2&amp;&amp;!tag3';
echo $baseurl.'/events/restSearch/json/null/null/null/null/tag1&amp;&amp;tag2&amp;&amp;!tag3';
?>
</pre>
<b>quickfilter</b>: Enabling this (by passing "1" as the argument) will make the search ignore all of the other arguments, except for the auth key and value. MISP will return an xml / json (depending on the header sent) of all events that have a sub-string match on value in the event info, event orgc, or any of the attribute value1 / value2 fields, or in the attribute comment. <br />
@ -320,11 +324,11 @@ Use semicolons instead (the search will automatically search for colons instead)
<b>published</b>: Set whether published or unpublished events should be returned. Do not set the parameter if you want both.<br />
<b>enforceWarninglist</b>: Remove any attributes from the result that would cause a hit on a warninglist entry.<br />
<p>The keywords false or null should be used for optional empty parameters in the URL.</p>
<p>For example, to find any event with the term "red october" mentioned, use the following syntax (the example is shown as a POST request instead of a GET, which is highly recommended):</p>
<p>For example, to find any event with the term "red october" mentioned, use the following syntax (the example is shown as a POST request instead of a GET, which is highly recommended. GET requests are problematic and deprecated.):</p>
<p>POST to:</p>
<pre>
<?php
echo $baseurl.'/events/restSearch/download';
echo $baseurl.'/events/restSearch/json';
?>
</pre>
<p>POST message payload (XML):</p>
@ -349,10 +353,10 @@ Use semicolons instead (the search will automatically search for colons instead)
<b>published</b>: Set whether published or unpublished events should be returned. Do not set the parameter if you want both.<br />
<b>timestamp</b>: Restrict the results by the timestamp (of the attribute). Any attributes with a timestamp newer than the given timestamp will be returned.<br />
<b>enforceWarninglist</b>: Remove any attributes from the result that would cause a hit on a warninglist entry.<br /><br />
<p>The keywords false or null should be used for optional empty parameters in the URL.</p>
<p>The keywords false or null should be used for optional empty parameters in the URL. Keep in mind, this is only needed if you use the deprecated URL parameters.</p>
<pre>
<?php
echo $baseurl.'/attributes/restSearch/download/[value]/[type]/[category]/[org]/[tag]/[from]/[to]/[last]/[eventid]/[withAttachments]';
echo $baseurl.'/attributes/restSearch/json/[value]/[type]/[category]/[org]/[tag]/[from]/[to]/[last]/[eventid]/[withAttachments]';
?>
</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 '&amp;&amp;' operator. It is also possible to negate a term with the '!' operator. Please be aware the colons (:) cannot be used in the tag search. Use semicolons instead (the search will automatically search for colons instead).
@ -361,14 +365,14 @@ For example, in order to search for all attributes created by your organisation
<p>You can also use search for IP addresses using CIDR. Make sure that you use '|' (pipe) instead of '/' (slashes). Please be aware the colons (:) cannot be used in the tag search. Use semicolons instead (the search will automatically search for colons instead). See below for an example: </p>
<pre>
<?php
echo $baseurl.'/attributes/restSearch/download/192.168.1.1|16/ip-src/null/' . $me['Organisation']['name'];
echo $baseurl.'/attributes/restSearch/openioc/192.168.1.1|16/ip-src/null/' . $me['Organisation']['name'];
?>
</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 $baseurl.'/attributes/returnAttributes/download/[id]/[type]/[sigOnly]';
echo $baseurl.'/attributes/returnAttributes/json/[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.

View File

@ -31,7 +31,6 @@ $mayPublish = ($isAclPublish && $this->request->data['Event']['orgc_id'] == $me[
?>
</div>
</fieldset>
<div id="confirmation_box" class="confirmation_box"></div>
</div>
<?php
$event = $this->data;

View File

@ -53,7 +53,6 @@ $mayPublish = ($isAclPublish && $event['Event']['orgc_id'] == $me['org_id']);
echo $this->Form->button('Submit', array('class' => 'btn btn-primary'));
echo $this->Form->end();
?>
<div id="confirmation_box" class="confirmation_box"></div>
</div>
<?php
echo $this->element('side_menu', array('menuList' => 'event', 'menuItem' => 'editEvent', 'mayModify' => $mayModify, 'mayPublish' => $mayPublish));
@ -66,7 +65,7 @@ echo $this->Form->end();
foreach ($formInfoTypes as $formInfoType => $humanisedName) {
echo 'var ' . $formInfoType . 'FormInfoValues = {' . PHP_EOL;
foreach ($info[$formInfoType] as $key => $formInfoData) {
echo '"' . $key . '": "<span class=\"blue bold\">' . h($formInfoData['key']) . '</span>: ' . h($formInfoData['desc']) . '<br />",' . PHP_EOL;
echo '"' . $key . '": "<span class=\"blue bold\">' . h($formInfoData['key']) . '</span>: ' . h($formInfoData['desc']) . '<br />",' . PHP_EOL;
}
echo '}' . PHP_EOL;
}
@ -74,16 +73,16 @@ echo $this->Form->end();
$(document).ready(function() {
if ($('#EventDistribution').val() == 4) $('#SGContainer').show();
else $('#SGContainer').hide();
$('#EventDistribution').change(function() {
if ($('#EventDistribution').val() == 4) $('#SGContainer').show();
else $('#SGContainer').hide();
});
$("#EventDistribution, #EventAnalysis, #EventThreatLevelId").change(function() {
initPopoverContent('Event');
});
$(document).ready(function() {
if ($('#EventDistribution').val() == 4) $('#SGContainer').show();
else $('#SGContainer').hide();

View File

@ -135,7 +135,7 @@
<tr id="row_<?php echo $field; ?>" class="hidden filterTableRow">
<td id="key_<?php echo $field;?>" style="border:1px solid #cccccc;font-weight:bold;"><?php echo ucfirst($field); ?></td>
<td id="value_<?php echo $field;?>" style="border:1px solid #cccccc;border-right:0px;"></td>
<td id="delete_<?php echo $field;?>" style="border:1px solid #cccccc;border-left:0px;"><span class="icon-trash" onClick="indexFilterClearRow('<?php echo $field;?>')"></span></td>
<td id="delete_<?php echo $field;?>" style="border:1px solid #cccccc;border-left:0px;"><span class="icon-trash" title="Delete filter" role="button" tabindex="0" aria-label="Delete filter" onClick="indexFilterClearRow('<?php echo $field;?>')"></span></td>
</tr>
<?php
endforeach;
@ -160,8 +160,8 @@
</fieldset>
<div id = "generatedURL" style="word-wrap: break-word;"><br />Save this URL if you would like to use the same filter settings again<br /><div style="background-color:#f5f5f5;border: 1px solid #e3e3e3; border-radius:4px;padding:3px;background-color:white;"><span id="generatedURLContent"></span></div></div>
<br />
<span class="btn btn-primary" onClick="indexApplyFilters();">Apply</span>
<span class="btn btn-inverse" onClick="cancelPopoverForm();" style="float:right;">Cancel</span>
<span role="button" tabindex="0" aria-label="Apply" title="Apply" class="btn btn-primary" onClick="indexApplyFilters();">Apply</span>
<span role="button" tabindex="0" aria-label="Cancel" title="Cancel" class="btn btn-inverse" onClick="cancelPopoverForm();" style="float:right;">Cancel</span>
</div>
</div>
<script type="text/javascript">

View File

@ -27,9 +27,9 @@
?>
<div class="tabMenuFixedContainer" style="display:inline-block;">
<span class="tabMenuFixed tabMenuFixed<?php echo $tab; ?> tabMenuSides">
<span id="create-button" title="Modify filters" class="icon-search useCursorPointer" onClick="getPopup('<?php echo h($urlparams);?>', 'events', 'filterEventIndex');"></span>
<span role="button" tabindex="0" aria-label="Modify filters" id="create-button" title="Modify filters" class="icon-search useCursorPointer" title="Filter events" role="button" tabindex="0" aria-label="Filter events" onClick="getPopup('<?php echo h($urlparams);?>', 'events', 'filterEventIndex');"></span>
</span>
<?php
<?php
if ($filtered):
foreach ($passedArgsArray as $k => $v):?>
<span class="tabMenuFixed tabMenuFixedElement">
@ -40,7 +40,7 @@
<?php echo $this->Html->link('', array('controller' => 'events', 'action' => 'index'), array('class' => 'icon-remove', 'title' => 'Remove filters'));?>
</span>
<?php endif;?>
<span id="quickFilterButton" class="tabMenuFilterFieldButton useCursorPointer" onClick='quickFilter(<?php echo h($passedArgs);?>, "/events/index");'>Filter</span>
<span role="button" tabindex="0" aria-label="Quickfilter" title="Quickfilter" id="quickFilterButton" class="tabMenuFilterFieldButton useCursorPointer" onClick='quickFilter(<?php echo h($passedArgs);?>, "/events/index");'>Filter</span>
<input class="tabMenuFilterField" type="text" id="quickFilterField"></input>
<?php
$tempArgs = json_decode($passedArgs, true);
@ -54,7 +54,7 @@
$tempArgs = json_encode($tempArgs);
?>
<span class="tabMenuFixed tabMenuFixedLeft tabMenuSides useCursorPointer <?php echo $tabBackground; ?>" style="margin-left:50px;">
<span id="myOrgButton" title="Modify filters" onClick="executeFilter(<?php echo h($tempArgs);?>, '<?php echo $baseurl;?>/events/index');">My Events</span>
<span role="button" tabindex="0" aria-label="My events only" title="My events only" id="myOrgButton" title="Modify filters" onClick="executeFilter(<?php echo h($tempArgs);?>, '<?php echo $baseurl;?>/events/index');">My Events</span>
</span>
<?php
$tempArgs = json_decode($passedArgs, true);
@ -68,11 +68,11 @@
$tempArgs = json_encode($tempArgs);
?>
<span class="tabMenuFixed tabMenuFixedRight tabMenuSides useCursorPointer <?php echo $tabBackground; ?>">
<span id="myOrgButton" title="Modify filters" onClick="executeFilter(<?php echo h($tempArgs);?>, '<?php echo $baseurl;?>/events/index');">Org Events</span>
<span role="button" tabindex="0" aria-label="My organisation's events only" id="myOrgButton" title="My organisation's events only" onClick="executeFilter(<?php echo h($tempArgs);?>, '<?php echo $baseurl;?>/events/index');">Org Events</span>
</span>
</div>
<?php
endif;
<?php
endif;
echo $this->element('Events/eventIndexTable');
?>
<p>

Some files were not shown because too many files have changed in this diff Show More