mirror of https://github.com/MISP/MISP
Merge branch 'quick-fix-metacategory-graph' into ref_graph
commit
921224ed40
|
@ -14,7 +14,7 @@ and how important these are to the users.
|
|||
|
||||
## Reporting security vulnerabilities
|
||||
|
||||
Reporting security vulnerabilities is of great importance for us, as MISP is used in multiple critical infrastructures. In the case of a security vulnerability report, we ask the reporter to directly report to [CIRCL](https://www.circl.lu/contact/), encrypting the report with the PGP key: CA57 2205 C002 4E06 BA70 BE89 EAAD CFFC 22BD 4CD5. We usually fix reported and confirmed security vulnerabilities in less than 48 hours, followed by a software release containing the fixes within the following days. If you report security vulnerabilities, don't forget to tell us if and how you want to be acknowledged and if you already requested CVE(s). If not, we will request the CVE directly.
|
||||
Reporting security vulnerabilities is of great importance for us, as MISP is used in multiple critical infrastructures. In the case of a security vulnerability report, we ask the reporter to directly report to [CIRCL](https://www.circl.lu/contact/), encrypting the report with the GnuPG key: CA57 2205 C002 4E06 BA70 BE89 EAAD CFFC 22BD 4CD5. We usually fix reported and confirmed security vulnerabilities in less than 48 hours, followed by a software release containing the fixes within the following days. If you report security vulnerabilities, don't forget to tell us if and how you want to be acknowledged and if you already requested CVE(s). If not, we will request the CVE directly.
|
||||
|
||||
As one of the critical user-bases of MISP consists of the CSIRT community, it is our duty to clearly state which bug could be potentially abused and could have a security impact on a deployed MISP instance. CVE assignment is performed even for minor bugs having some possible security impact. This allows users using MISP instances in their environment to understand which bugs could have an impact on their security. We firmly believe that, even though unfortunately it is often not regarded as common practice in our industry, being as transparent as possible about vulnerabilities, no matter how minor, is of absolute crucial importance. At MISP-project, we care about the security of our users and prefer to have a high number of published CVEs than to a few swept under the rug.
|
||||
|
||||
|
@ -26,7 +26,7 @@ If you want to contribute to the [MISP core](https://github.com/MISP/MISP) proje
|
|||
- Branch off from 2.4 (2.4 branch is the main branch of development in MISP) `git checkout 2.4`
|
||||
- Then create a branch for your own contribution (bug fixes, enhancement, new features) by typing `git checkout -b fix-glossy-user-interface`
|
||||
- Work on your fix or feature (only work on that, avoid committing any debug functionalities, testing or unused code)
|
||||
- Commit your fix or feature (and sign it with PGP - if you have a PGP key) with a meaningful commit message as recommended in [A Note About Git Commit Messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
|
||||
- Commit your fix or feature (and sign it with GnuPG - if you have a GnuPG key) with a meaningful commit message as recommended in [A Note About Git Commit Messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
|
||||
- MISP uses [gitchangelog](https://github.com/vaab/gitchangelog/blob/master/src/gitchangelog/gitchangelog.rc.reference) to generate changelog, so it's recommended to use `new:` for new features, `fix:` when it's a bug-fix or `chg` when it's re-factoring or clean-up..
|
||||
- Push and then open a pull-request via the GitHub interface.
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ systemctl enable rh-redis32-redis.service
|
|||
scl enable rh-mariadb102 rh-php71 rh-redis32 bash
|
||||
|
||||
2.08/ Secure the MariaDB installation, run the following command and follow the prompts
|
||||
mysqld_secure_installation
|
||||
mysql_secure_installation
|
||||
|
||||
2.10/ Update the PHP extension repository and install required package
|
||||
pear channel-update pear.php.net
|
||||
|
@ -156,9 +156,9 @@ php composer.phar install
|
|||
|
||||
4.03/ Install and configure php redis connector through pecl
|
||||
pecl install redis
|
||||
echo "extension=redis.so" > /etc/opt/rh/rh-php56/php-fpm.d/redis.ini
|
||||
ln -s ../php-fpm.d/redis.ini /etc/opt/rh/rh-php56/php.d/99-redis.ini
|
||||
systemctl restart rh-php56-php-fpm.service
|
||||
echo "extension=redis.so" > /etc/opt/rh/rh-php71/php-fpm.d/redis.ini
|
||||
ln -s ../php-fpm.d/redis.ini /etc/opt/rh/rh-php71/php.d/99-redis.ini
|
||||
systemctl restart rh-php71-php-fpm.service
|
||||
|
||||
4.04/ Set a timezone in php.ini
|
||||
echo 'date.timezone = "Australia/Sydney"' > /etc/opt/rh/rh-php71/php-fpm.d/timezone.ini
|
||||
|
@ -382,7 +382,7 @@ export LIEF_TMP=/tmp/LIEF
|
|||
export LIEF_INSTALL=/tmp/LIEF_INSTALL
|
||||
export LIEF_BRANCH=master
|
||||
cd $LIEF_TMP
|
||||
git clone --depth 3 --branch $LIEF_BRANCH --single-branch https://github.com/lief-project/LIEF.git LIEF
|
||||
git clone --branch $LIEF_BRANCH --single-branch https://github.com/lief-project/LIEF.git LIEF
|
||||
|
||||
11.04/ Compile lief and install
|
||||
cd $LIEF_TMP/LIEF
|
||||
|
|
|
@ -66,7 +66,7 @@ sudo -u www-data git checkout tags/$(git describe --tags `git rev-list --tags --
|
|||
sudo -u www-data git config core.filemode false
|
||||
|
||||
# install Mitre's STIX and its dependencies by running the following commands:
|
||||
sudo apt-get install python-dev python-pip libxml2-dev libxslt1-dev zlib1g-dev python-setuptools
|
||||
sudo apt-get install python-dev python-pip python3-pip libxml2-dev libxslt1-dev zlib1g-dev python-setuptools
|
||||
cd /var/www/MISP/app/files/scripts
|
||||
sudo -u www-data git clone https://github.com/CybOXProject/python-cybox.git
|
||||
sudo -u www-data git clone https://github.com/STIXProject/python-stix.git
|
||||
|
|
2
PyMISP
2
PyMISP
|
@ -1 +1 @@
|
|||
Subproject commit 62fb26fafdb751baa666ca7aa0e90d23656b1afe
|
||||
Subproject commit f805171c51d778d334a8c555fb50718dc3ad1c2b
|
|
@ -55,7 +55,7 @@ MISP, Malware Information Sharing Platform and Threat Sharing, core functionalit
|
|||
- **Expansion modules in Python** to expand MISP with your own services or activate already available [misp-modules](https://github.com/MISP/misp-modules).
|
||||
- **Sighting support** to get observations from organizations concerning shared indicators and attributes. Sighting [can be contributed](https://www.circl.lu/doc/misp/automation/index.html#sightings-api) via MISP user-interface, API as MISP document or STIX sighting documents.
|
||||
- **STIX support**: export data in the STIX format (XML and JSON). Additional STIX import and export is supported by [MISP-STIX-Converter](https://github.com/MISP/MISP-STIX-Converter) or [MISP-Taxii-Server](https://github.com/MISP/MISP-Taxii-Server).
|
||||
- **Integrated encryption and signing of the notifications** via PGP and/or S/MIME depending of the user preferences.
|
||||
- **Integrated encryption and signing of the notifications** via GnuPG and/or S/MIME depending of the user preferences.
|
||||
|
||||
Exchanging info results in *faster detection* of targeted attacks and improves the detection ratio while reducing the false positives. We also avoid reversing similar malware as we know very fast that others team or organizations who already analyzed a specific malware.
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"major":2, "minor":4, "hotfix":88}
|
||||
{"major":2, "minor":4, "hotfix":89}
|
||||
|
|
|
@ -58,4 +58,30 @@ class AdminShell extends AppShell
|
|||
$this->Job->saveField('message', 'Job done.');
|
||||
$this->Job->saveField('status', 4);
|
||||
}
|
||||
|
||||
public function getSetting() {
|
||||
$param = empty($this->args[0]) ? 'all' : $this->args[0];
|
||||
$settings = $this->Server->serverSettingsRead();
|
||||
$result = $settings;
|
||||
if (!empty($param)) {
|
||||
$result = 'No valid setting found for ' . $param;
|
||||
foreach ($settings as $setting) {
|
||||
if ($setting['setting'] == $param) {
|
||||
$result = $setting;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
echo json_encode($result, JSON_PRETTY_PRINT) . PHP_EOL;
|
||||
}
|
||||
|
||||
public function setSetting() {
|
||||
$setting = empty($this->args[0]) ? null : $this->args[0];
|
||||
$value = empty($this->args[1]) ? null : $this->args[1];
|
||||
if (empty($setting) || $value === null) {
|
||||
echo 'Invalid parameters. Usage: ' . APP . 'Console/cake Admin setSetting [setting_name] [setting_value]';
|
||||
} else {
|
||||
$this->Server->serverSettingsSaveValue($setting, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -476,7 +476,7 @@ class EventShell extends AppShell
|
|||
$this->Job->save($job);
|
||||
$log = ClassRegistry::init('Log');
|
||||
$log->create();
|
||||
$log->createLogEntry($user, 'publish', 'Event', $id, 'Event (' . $id . '): published.', 'publised () => (1)');
|
||||
$log->createLogEntry($user, 'publish', 'Event', $id, 'Event (' . $id . '): published.', 'published () => (1)');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
|
||||
// TODO GPG encryption has issues when keys are expired
|
||||
// TODO GnuPG encryption has issues when keys are expired
|
||||
|
||||
App::uses('ConnectionManager', 'Model');
|
||||
App::uses('Controller', 'Controller');
|
||||
|
@ -46,8 +46,8 @@ class AppController extends Controller {
|
|||
|
||||
public $helpers = array('Utility', 'OrgImg');
|
||||
|
||||
private $__queryVersion = '31';
|
||||
public $pyMispVersion = '2.4.87';
|
||||
private $__queryVersion = '33';
|
||||
public $pyMispVersion = '2.4.89';
|
||||
public $phpmin = '5.6.5';
|
||||
public $phprec = '7.0.16';
|
||||
|
||||
|
@ -282,6 +282,18 @@ class AppController extends Controller {
|
|||
$this->redirect(array('controller' => 'users', 'action' => 'login', 'admin' => false));
|
||||
}
|
||||
}
|
||||
$this->set('default_memory_limit', ini_get('memory_limit'));
|
||||
if (isset($this->Auth->user('Role')['memory_limit'])) {
|
||||
if ($this->Auth->user('Role')['memory_limit'] !== '') {
|
||||
ini_set('memory_limit', $this->Auth->user('Role')['memory_limit']);
|
||||
}
|
||||
}
|
||||
$this->set('default_max_execution_time', ini_get('max_execution_time'));
|
||||
if (isset($this->Auth->user('Role')['max_execution_time'])) {
|
||||
if ($this->Auth->user('Role')['max_execution_time'] !== '') {
|
||||
ini_set('max_execution_time', $this->Auth->user('Role')['max_execution_time']);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!($this->params['controller'] === 'users' && $this->params['action'] === 'login')) $this->redirect(array('controller' => 'users', 'action' => 'login', 'admin' => false));
|
||||
}
|
||||
|
|
|
@ -125,7 +125,11 @@ class AttributesController extends AppController {
|
|||
$this->set('categoryDefinitions', $this->Attribute->categoryDefinitions);
|
||||
}
|
||||
|
||||
public function add($eventId) {
|
||||
public function add($eventId = false) {
|
||||
if ($this->request->is('get') && $this->_isRest()) {
|
||||
return $this->RestResponse->describe('Attributes', 'add', false, $this->response->type());
|
||||
}
|
||||
if ($eventId === false) throw new MethodNotAllowedException('No event ID set.');
|
||||
if (!$this->userRole['perm_add']) {
|
||||
throw new MethodNotAllowedException('You don\'t have permissions to create attributes');
|
||||
}
|
||||
|
@ -742,6 +746,9 @@ class AttributesController extends AppController {
|
|||
|
||||
|
||||
public function edit($id = null) {
|
||||
if ($this->request->is('get') && $this->_isRest()) {
|
||||
return $this->RestResponse->describe('Attributes', 'edit', false, $this->response->type());
|
||||
}
|
||||
if (Validation::uuid($id)) {
|
||||
$this->Attribute->recursive = -1;
|
||||
$temp = $this->Attribute->findByUuid($id);
|
||||
|
|
|
@ -193,6 +193,7 @@ class ACLComponent extends Component {
|
|||
'event_index' => array('*'),
|
||||
'maxDateActivity' => array('*'),
|
||||
'returnDates' => array('*'),
|
||||
'testForStolenAttributes' => array(),
|
||||
'pruneUpdateLogs' => array()
|
||||
),
|
||||
'modules' => array(
|
||||
|
|
|
@ -13,6 +13,18 @@ class RestResponseComponent extends Component {
|
|||
|
||||
private $__descriptions = array(
|
||||
'Attribute' => array(
|
||||
'add' => array(
|
||||
'description' => "POST a MISP Attribute JSON to this API to create an Attribute.",
|
||||
'mandatory' => array('value', 'type'),
|
||||
'optional' => array('category', 'to_ids', 'uuid', 'distribution', 'sharing_group_id', 'timestamp', 'comment'),
|
||||
'params' => array('event_id')
|
||||
),
|
||||
'edit' => array(
|
||||
'description' => "POST a MISP Attribute JSON to this API to update an Attribute. If the timestamp is set, it has to be newer than the existing Attribute.",
|
||||
'mandatory' => array(),
|
||||
'optional' => array('value', 'type', 'category', 'to_ids', 'uuid', 'distribution', 'sharing_group_id', 'timestamp', 'comment'),
|
||||
'params' => array('event_id')
|
||||
),
|
||||
'deleteSelected' => array(
|
||||
'description' => "POST a list of attribute IDs in JSON format to this API
|
||||
to delete the given attributes. This API also expects an event ID passed via
|
||||
|
@ -25,6 +37,20 @@ class RestResponseComponent extends Component {
|
|||
'params' => array('event_id')
|
||||
)
|
||||
),
|
||||
'Event' => array(
|
||||
'add' => array(
|
||||
'description' => "POST a MISP Event JSON to this API to create an Event. Contained objects can also be included (such as attributes, objects, tags, etc).",
|
||||
'mandatory' => array('info'),
|
||||
'optional' => array('threat_level_id', 'analysis', 'distribution', 'sharing_group_id', 'uuid', 'published', 'timestamp', 'date', 'Attribute', 'Object', 'Shadow_Attribute', 'EventTag'),
|
||||
'params' => array()
|
||||
),
|
||||
'edit' => array(
|
||||
'description' => "POST a MISP Event JSON to this API to update an Event. Contained objects can also be included (such as attributes, objects, tags, etc). If the timestamp is set, it has to be newer than the existing Attribute.",
|
||||
'mandatory' => array(),
|
||||
'optional' => array('info', 'threat_level_id', 'analysis', 'distribution', 'sharing_group_id', 'uuid', 'published', 'timestamp', 'date', 'Attribute', 'Object', 'Shadow_Attribute', 'EventTag'),
|
||||
'params' => array('event_id')
|
||||
)
|
||||
),
|
||||
'Organisation' => array(
|
||||
'admin_add' => array(
|
||||
'description' => "POST an Organisation object in JSON format to this API to create a new organsiation.",
|
||||
|
|
|
@ -259,7 +259,7 @@ class EventsController extends AppController {
|
|||
// list the events
|
||||
$passedArgsArray = array();
|
||||
$urlparams = "";
|
||||
$overrideAbleParams = array('all', 'attribute', 'published', 'eventid', 'Datefrom', 'Dateuntil', 'org', 'eventinfo', 'tag', 'distribution', 'sharinggroup', 'analysis', 'threatlevel', 'email', 'hasproposal', 'timestamp', 'publishtimestamp', 'publish_timestamp', 'minimal');
|
||||
$overrideAbleParams = array('all', 'attribute', 'published', 'eventid', 'Datefrom', 'Dateuntil', 'org', 'eventinfo', 'tag', 'tags', 'distribution', 'sharinggroup', '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'];
|
||||
|
@ -328,15 +328,19 @@ class EventsController extends AppController {
|
|||
break;
|
||||
case 'timestamp':
|
||||
if ($v == "") continue 2;
|
||||
if (preg_match('/^[0-9]+[mhdw]$/i', $v)) $v = $this->Event->resolveTimeDelta($v);
|
||||
$this->paginate['conditions']['AND'][] = array('Event.timestamp >=' => $v);
|
||||
break;
|
||||
case 'publish_timestamp':
|
||||
case 'publishtimestamp':
|
||||
if ($v == "") continue 2;
|
||||
if (is_array($v) && isset($v[0]) && isset($v[1])) {
|
||||
if (preg_match('/^[0-9]+[mhdw]$/i', $v[0])) $v[0] = $this->Event->resolveTimeDelta($v[0]);
|
||||
if (preg_match('/^[0-9]+[mhdw]$/i', $v[1])) $v[1] = $this->Event->resolveTimeDelta($v[1]);
|
||||
$this->paginate['conditions']['AND'][] = array('Event.publish_timestamp >=' => $v[0]);
|
||||
$this->paginate['conditions']['AND'][] = array('Event.publish_timestamp <=' => $v[1]);
|
||||
} else {
|
||||
if (preg_match('/^[0-9]+[mhdw]$/i', $v)) $v = $this->Event->resolveTimeDelta($v);
|
||||
$this->paginate['conditions']['AND'][] = array('Event.publish_timestamp >=' => $v);
|
||||
}
|
||||
break;
|
||||
|
@ -403,7 +407,8 @@ class EventsController extends AppController {
|
|||
}
|
||||
$this->paginate['conditions']['AND'][] = $test;
|
||||
break;
|
||||
case 'tag' :
|
||||
case 'tag':
|
||||
case 'tags':
|
||||
if (!$v || !Configure::read('MISP.tagging') || $v === 0) continue 2;
|
||||
$pieces = explode('|', $v);
|
||||
$filterString = "";
|
||||
|
@ -668,20 +673,20 @@ class EventsController extends AppController {
|
|||
}
|
||||
|
||||
if (!$this->Event->User->getPGP($this->Auth->user('id')) && Configure::read('GnuPG.onlyencrypted')) {
|
||||
// No GPG
|
||||
// No GnuPG
|
||||
if (Configure::read('SMIME.enabled') && !$this->Event->User->getCertificate($this->Auth->user('id'))) {
|
||||
// No GPG and No SMIME
|
||||
$this->Session->setFlash(__('No x509 certificate or GPG key set in your profile. To receive emails, submit your public certificate or GPG key in your profile.'));
|
||||
// No GnuPG and No SMIME
|
||||
$this->Session->setFlash(__('No x509 certificate or GnuPG key set in your profile. To receive emails, submit your public certificate or GnuPG key in your profile.'));
|
||||
} else if (!Configure::read('SMIME.enabled')) {
|
||||
$this->Session->setFlash(__('No GPG key set in your profile. To receive emails, submit your public key in your profile.'));
|
||||
$this->Session->setFlash(__('No GnuPG key set in your profile. To receive emails, submit your public key in your profile.'));
|
||||
}
|
||||
} else if ($this->Auth->user('autoalert') && !$this->Event->User->getPGP($this->Auth->user('id')) && Configure::read('GnuPG.bodyonlyencrypted')) {
|
||||
// No GPG & autoalert
|
||||
// No GnuPG & autoalert
|
||||
if ($this->Auth->user('autoalert') && Configure::read('SMIME.enabled') && !$this->Event->User->getCertificate($this->Auth->user('id'))) {
|
||||
// No GPG and No SMIME & autoalert
|
||||
$this->Session->setFlash(__('No x509 certificate or GPG key set in your profile. To receive attributes in emails, submit your public certificate or GPG key in your profile.'));
|
||||
// No GnuPG and No SMIME & autoalert
|
||||
$this->Session->setFlash(__('No x509 certificate or GnuPG key set in your profile. To receive attributes in emails, submit your public certificate or GnuPG key in your profile.'));
|
||||
} else if (!Configure::read('SMIME.enabled')) {
|
||||
$this->Session->setFlash(__('No GPG key set in your profile. To receive attributes in emails, submit your public key in your profile.'));
|
||||
$this->Session->setFlash(__('No GnuPG key set in your profile. To receive attributes in emails, submit your public key in your profile.'));
|
||||
}
|
||||
}
|
||||
$this->set('eventDescriptions', $this->Event->fieldDescriptions);
|
||||
|
@ -1026,7 +1031,7 @@ class EventsController extends AppController {
|
|||
if (!empty($event['RelatedAttribute'])) {
|
||||
foreach ($event['RelatedAttribute'] as $key => $relatedAttribute) {
|
||||
foreach ($relatedAttribute as $key2 => $relation) {
|
||||
$event['RelatedAttribute'][$key][$key2]['date'] = $relatedDates[$relation['id']];
|
||||
if (!empty($relatedDates[$relation['id']])) $event['RelatedAttribute'][$key][$key2]['date'] = $relatedDates[$relation['id']];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1275,6 +1280,7 @@ class EventsController extends AppController {
|
|||
}
|
||||
// rearrange the response if the event came from an export
|
||||
if (isset($this->request->data['response'])) $this->request->data = $this->request->data['response'];
|
||||
if (!isset($this->request->data['Event'])) $this->request->data['Event'] = $this->request->data;
|
||||
|
||||
// Distribution, reporter for the events pushed will be the owner of the authentication key
|
||||
$this->request->data['Event']['user_id'] = $this->Auth->user('id');
|
||||
|
@ -1386,6 +1392,8 @@ class EventsController extends AppController {
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if ($this->_isRest()) {
|
||||
return $this->RestResponse->describe('Events', 'add', false, $this->response->type());
|
||||
}
|
||||
|
||||
$this->request->data['Event']['date'] = date('Y-m-d');
|
||||
|
@ -1478,7 +1486,7 @@ class EventsController extends AppController {
|
|||
}
|
||||
}
|
||||
|
||||
public function upload_stix() {
|
||||
public function upload_stix($stix_version = '1') {
|
||||
if (!$this->userRole['perm_modify']) {
|
||||
throw new UnauthorizedException('You do not have permission to do that.');
|
||||
}
|
||||
|
@ -1489,7 +1497,7 @@ class EventsController extends AppController {
|
|||
$tempFile = new File($tmpDir . DS . $randomFileName, true, 0644);
|
||||
$tempFile->write($this->request->input());
|
||||
$tempFile->close();
|
||||
$result = $this->Event->upload_stix($this->Auth->user(), $randomFileName);
|
||||
$result = $this->Event->upload_stix($this->Auth->user(), $randomFileName, $stix_version);
|
||||
if (is_array($result)) {
|
||||
return $this->RestResponse->saveSuccessResponse('Events', 'upload_stix', false, $this->response->type(), 'STIX document imported, event\'s created: ' . implode(', ', $result) . '.');
|
||||
} else if (is_numeric($result)) {
|
||||
|
@ -1507,7 +1515,7 @@ class EventsController extends AppController {
|
|||
$randomFileName = $this->Event->generateRandomFileName();
|
||||
$tmpDir = APP . "files" . DS . "scripts" . DS . "tmp";
|
||||
move_uploaded_file($this->data['Event']['stix']['tmp_name'], $tmpDir . DS . $randomFileName);
|
||||
$result = $this->Event->upload_stix($this->Auth->user(), $randomFileName);
|
||||
$result = $this->Event->upload_stix($this->Auth->user(), $randomFileName, $stix_version);
|
||||
if (is_array($result)) {
|
||||
$this->Session->setFlash(__('STIX document imported, event\'s created: ' . implode(', ', $result) . '.'));
|
||||
$this->redirect(array('action' => 'index'));
|
||||
|
@ -1524,37 +1532,14 @@ class EventsController extends AppController {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public function upload_stix2() {
|
||||
if (!$this->userRole['perm_modify']) {
|
||||
throw new UnauthorizedException('You do not have permission to do that.');
|
||||
}
|
||||
if ($this->request->is('post')) {
|
||||
|
||||
if ($this->_isRest()) {
|
||||
$randomFileName = $this->Event->generateRandomFileName();
|
||||
$tmpDir = APP . "files" . DS . "scripts" . DS . "tmp";
|
||||
$tempFile = new File($tmpDir . DS . $randomFileName, true, 0644);
|
||||
$tempFile->write($this->request->input());
|
||||
$tempFile->close();
|
||||
$result = $this->Event->upload_stix2($this->Auth->user(), $randomFileName);
|
||||
} else {
|
||||
if (isset($this->data['Event']['stix']) && $this->data['Event']['stix']['size'] > 0 && is_uploaded_file($this->data['Event']['stix']['tmp_name'])) {
|
||||
$randomFileName = $this->Event->generateRandomFileName();
|
||||
$tmpDir = APP . "files" . DS . "scripts" . DS . "tmp";
|
||||
move_uploaded_file($this->data['Event']['stix']['tmp_name'], $tmpDir . DS . $randomFileName);
|
||||
$result = $this->Event->upload_stix($this->Auth->user(), $randomFileName);
|
||||
} else {
|
||||
$max_size = intval(ini_get('post_max_size'));
|
||||
if (intval(ini_get('upload_max_filesize')) < $max_size) $max_size = intval(ini_get('upload_max_filesize'));
|
||||
throw new UnauthorizedException('File upload failed. Make sure that you select a stix file to be uploaded and that the file doesn\'t exceed the maximum file size of ' . $max_size . '.');
|
||||
}
|
||||
}
|
||||
if ($stix_version == 2) {
|
||||
$stix_version = '2.x JSON';
|
||||
} else {
|
||||
$stix_version = '1.x XML';
|
||||
}
|
||||
$this->set('stix_version', $stix_version);
|
||||
}
|
||||
*/
|
||||
|
||||
public function merge($target_id = null) {
|
||||
$this->Event->id = $target_id;
|
||||
|
@ -1629,6 +1614,9 @@ class EventsController extends AppController {
|
|||
}
|
||||
|
||||
public function edit($id = null) {
|
||||
if ($this->request->is('get') && $this->_isRest()) {
|
||||
return $this->RestResponse->describe('Events', 'edit', false, $this->response->type());
|
||||
}
|
||||
if (Validation::uuid($id)) {
|
||||
$temp = $this->Event->find('first', array('recursive' => -1, 'fields' => array('Event.id'), 'conditions' => array('Event.uuid' => $id)));
|
||||
if (empty($temp)) throw new NotFoundException('Invalid event');
|
||||
|
@ -1650,12 +1638,10 @@ class EventsController extends AppController {
|
|||
}
|
||||
if ($this->request->is('post') || $this->request->is('put')) {
|
||||
if ($this->_isRest()) {
|
||||
if ($this->_isRest()) {
|
||||
if (isset($this->request->data['response'])) {
|
||||
$this->request->data = $this->Event->updateXMLArray($this->request->data, true);
|
||||
} else {
|
||||
$this->request->data = $this->Event->updateXMLArray($this->request->data, false);
|
||||
}
|
||||
if (isset($this->request->data['response'])) {
|
||||
$this->request->data = $this->Event->updateXMLArray($this->request->data, true);
|
||||
} else {
|
||||
$this->request->data = $this->Event->updateXMLArray($this->request->data, false);
|
||||
}
|
||||
// Workaround for different structure in XML/array than what CakePHP expects
|
||||
if (isset($this->request->data['response'])) $this->request->data = $this->request->data['response'];
|
||||
|
@ -1895,7 +1881,7 @@ class EventsController extends AppController {
|
|||
}
|
||||
|
||||
// Send out an alert email to all the users that wanted to be notified.
|
||||
// Users with a GPG key will get the mail encrypted, other users will get the mail unencrypted
|
||||
// Users with a GnuPG key will get the mail encrypted, other users will get the mail unencrypted
|
||||
public function alert($id = null) {
|
||||
$this->Event->id = $id;
|
||||
$this->Event->recursive = 0;
|
||||
|
@ -1971,7 +1957,7 @@ class EventsController extends AppController {
|
|||
}
|
||||
|
||||
// Send out an contact email to the person who posted the event.
|
||||
// Users with a GPG key will get the mail encrypted, other users will get the mail unencrypted
|
||||
// Users with a GnuPG key will get the mail encrypted, other users will get the mail unencrypted
|
||||
public function contact($id = null) {
|
||||
$this->Event->id = $id;
|
||||
if (!$this->Event->exists()) {
|
||||
|
@ -3055,7 +3041,6 @@ class EventsController extends AppController {
|
|||
$eventCount = count($eventIds);
|
||||
$i = 0;
|
||||
foreach ($eventIds as $k => $currentEventId) {
|
||||
$i++;
|
||||
$result = $this->Event->fetchEvent(
|
||||
$this->Auth->user(),
|
||||
array(
|
||||
|
@ -3070,12 +3055,14 @@ class EventsController extends AppController {
|
|||
);
|
||||
if (!empty($result)) {
|
||||
$result = $this->Whitelist->removeWhitelistedFromArray($result, false);
|
||||
$final .= $converter->convert($result[0]);
|
||||
if ($i < $eventCount) {
|
||||
if ($i != 0) {
|
||||
$final .= ',' . PHP_EOL;
|
||||
}
|
||||
$final .= $converter->convert($result[0]);
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
if ($i > 0) $final .= PHP_EOL;
|
||||
$final .= $converter->generateBottom($responseType, $final);
|
||||
$extension = $responseType;
|
||||
if ($key == 'openioc') {
|
||||
|
@ -3689,7 +3676,7 @@ class EventsController extends AppController {
|
|||
}
|
||||
if ($failed > 0) {
|
||||
if ($failed == 1) {
|
||||
$flashMessage = $saved . ' ' . $messageScope . ' created' . $emailResult . '. ' . $failed . ' ' . $messageScope . ' could not be saved. Reason for the failure: ' . $this->Event->objectType->validationErrors;
|
||||
$flashMessage = $saved . ' ' . $messageScope . ' created' . $emailResult . '. ' . $failed . ' ' . $messageScope . ' could not be saved. Reason for the failure: ' . json_encode($this->Event->$objectType->validationErrors);
|
||||
} else {
|
||||
$flashMessage = $saved . ' ' . $messageScope . ' created' . $emailResult . '. ' . $failed . ' ' . $messageScope . ' could not be saved. This may be due to attributes with similar values already existing.';
|
||||
}
|
||||
|
@ -4066,12 +4053,18 @@ class EventsController extends AppController {
|
|||
$imports = array(
|
||||
'MISP' => array(
|
||||
'url' => '/events/add_misp_export',
|
||||
'text' => 'MISP standard (recommended exchange format)',
|
||||
'text' => 'MISP standard (recommended exchange format - lossless)',
|
||||
'ajax' => false,
|
||||
'bold' => true
|
||||
),
|
||||
'STIX' => array(
|
||||
'url' => '/events/upload_stix',
|
||||
'text' => 'STIX 1.1.1 format',
|
||||
'text' => 'STIX 1.1.1 format (lossy)',
|
||||
'ajax' => false,
|
||||
),
|
||||
'STIX2' => array(
|
||||
'url' => '/events/upload_stix/2',
|
||||
'text' => 'STIX 2.0 format (lossy)',
|
||||
'ajax' => false,
|
||||
)
|
||||
);
|
||||
|
@ -4305,7 +4298,6 @@ class EventsController extends AppController {
|
|||
$data = $this->request->is('post') ? $this->request->data : array();
|
||||
$grapher->construct($this->Event, $this->Taxonomy, $this->GalaxyCluster, $this->Auth->user(), $data);
|
||||
$json = $grapher->buildGraphJson($id, $type);
|
||||
|
||||
array_walk_recursive($json, function(&$item, $key){
|
||||
if(!mb_detect_encoding($item, 'utf-8', true)){
|
||||
$item = utf8_encode($item);
|
||||
|
@ -4452,7 +4444,7 @@ class EventsController extends AppController {
|
|||
}
|
||||
}
|
||||
}
|
||||
$data = array('module' => $module, $attribute[0]['Attribute']['type'] => $attribute[0]['Attribute']['value'], 'event_id' => $attribute[0]['Attribute']['event_id']);
|
||||
$data = array('module' => $module, $attribute[0]['Attribute']['type'] => $attribute[0]['Attribute']['value'], 'event_id' => $attribute[0]['Attribute']['event_id'], 'attribute_uuid' => $attribute[0]['Attribute']['uuid']);
|
||||
if ($this->Event->Attribute->typeIsAttachment($attribute[0]['Attribute']['type'])) {
|
||||
$data['data'] = $this->Event->Attribute->base64EncodeAttachment($attribute[0]['Attribute']);
|
||||
}
|
||||
|
|
|
@ -31,7 +31,10 @@ class FeedsController extends AppController {
|
|||
if ($scope !== 'all') {
|
||||
if ($scope == 'enabled') {
|
||||
$this->paginate['conditions'][] = array(
|
||||
'Feed.enabled' => 1
|
||||
'OR' => array(
|
||||
'Feed.enabled' => 1,
|
||||
'Feed.caching_enabled' => 1
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->paginate['conditions'][] = array(
|
||||
|
@ -210,7 +213,7 @@ class FeedsController extends AppController {
|
|||
$this->request->data['Feed']['settings']['delimiter'] = ',';
|
||||
}
|
||||
$this->request->data['Feed']['settings'] = json_encode($this->request->data['Feed']['settings']);
|
||||
$fields = array('id', 'name', 'provider', 'enabled', 'rules', 'url', 'distribution', 'sharing_group_id', 'tag_id', 'fixed_event', 'event_id', 'publish', 'delta_merge', 'source_format', 'override_ids', 'settings', 'input_source', 'delete_local_file', 'lookup_visible', 'headers');
|
||||
$fields = array('id', 'name', 'provider', 'enabled', 'caching_enabled','rules', 'url', 'distribution', 'sharing_group_id', 'tag_id', 'fixed_event', 'event_id', 'publish', 'delta_merge', 'source_format', 'override_ids', 'settings', 'input_source', 'delete_local_file', 'lookup_visible', 'headers');
|
||||
$feed = array();
|
||||
foreach ($fields as $field) {
|
||||
if (isset($this->request->data['Feed'][$field])) {
|
||||
|
@ -686,7 +689,8 @@ class FeedsController extends AppController {
|
|||
}
|
||||
}
|
||||
|
||||
public function toggleSelected($enable = false, $feedList = false) {
|
||||
public function toggleSelected($enable = false, $cache = false, $feedList = false) {
|
||||
$field = $cache ? 'caching_enabled' : 'enabled';
|
||||
if (!empty($enable)) $enable = 1;
|
||||
else $enable = 0;
|
||||
try {
|
||||
|
@ -702,8 +706,8 @@ class FeedsController extends AppController {
|
|||
));
|
||||
$count = 0;
|
||||
foreach ($feeds as $feed) {
|
||||
if ($feed['Feed']['enabled'] != $enable) {
|
||||
$feed['Feed']['enabled'] = $enable;
|
||||
if ($feed['Feed'][$field] != $enable) {
|
||||
$feed['Feed'][$field] = $enable;
|
||||
$this->Feed->save($feed);
|
||||
$count++;
|
||||
}
|
||||
|
|
|
@ -346,4 +346,31 @@ class LogsController extends AppController {
|
|||
}
|
||||
$this->redirect($this->referer());
|
||||
}
|
||||
|
||||
public function testForStolenAttributes() {
|
||||
$logs = $this->Log->find('list', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array(
|
||||
'Log.model' => 'Attribute',
|
||||
'Log.action' => 'edit'
|
||||
),
|
||||
'fields' => array('Log.title')
|
||||
));
|
||||
$ids = array();
|
||||
foreach ($logs as $log) {
|
||||
preg_match('/Attribute \(([0-9]+?)\)/', $log, $attribute_id);
|
||||
preg_match('/Event \(([0-9]+?)\)/', $log, $event_id);
|
||||
if (!isset($attribute_id[1])) continue;
|
||||
if (empty($ids[$attribute_id[1]]) || !in_array($event_id[1], $ids[$attribute_id[1]])) {
|
||||
$ids[$attribute_id[1]][] = $event_id[1];
|
||||
}
|
||||
}
|
||||
$issues = array();
|
||||
foreach ($ids as $aid => $eids) {
|
||||
if (count($eids) > 1) {
|
||||
$issues[$aid] = $eids;
|
||||
}
|
||||
}
|
||||
$this->set('issues', $issues);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -708,7 +708,7 @@ class ServersController extends AppController {
|
|||
);
|
||||
$writeableErrors = array(0 => 'OK', 1 => 'not found', 2 => 'is not writeable');
|
||||
$readableErrors = array(0 => 'OK', 1 => 'not readable');
|
||||
$gpgErrors = array(0 => 'OK', 1 => 'FAIL: settings not set', 2 => 'FAIL: Failed to load GPG', 3 => 'FAIL: Issues with the key/passphrase', 4 => 'FAIL: encrypt failed');
|
||||
$gpgErrors = array(0 => 'OK', 1 => 'FAIL: settings not set', 2 => 'FAIL: Failed to load GnuPG', 3 => 'FAIL: Issues with the key/passphrase', 4 => 'FAIL: encrypt failed');
|
||||
$proxyErrors = array(0 => 'OK', 1 => 'not configured (so not tested)', 2 => 'Getting URL via proxy failed');
|
||||
$zmqErrors = array(0 => 'OK', 1 => 'not enabled (so not tested)', 2 => 'Python ZeroMQ library not installed correctly.', 3 => 'ZeroMQ script not running.');
|
||||
$stixOperational = array(0 => 'STIX or CyBox or mixbox library not installed correctly', 1 => 'OK');
|
||||
|
@ -821,7 +821,7 @@ class ServersController extends AppController {
|
|||
// check if the STIX and Cybox libraries are working and the correct version using the test script stixtest.py
|
||||
$stix = $this->Server->stixDiagnostics($diagnostic_errors, $stixVersion, $cyboxVersion, $mixboxVersion);
|
||||
|
||||
// if GPG is set up in the settings, try to encrypt a test message
|
||||
// if GnuPG is set up in the settings, try to encrypt a test message
|
||||
$gpgStatus = $this->Server->gpgDiagnostics($diagnostic_errors);
|
||||
|
||||
// if the message queue pub/sub is enabled, check whether the extension works
|
||||
|
|
|
@ -490,7 +490,12 @@ class UsersController extends AppController {
|
|||
$this->loadModel('Role');
|
||||
$this->Role->recursive = -1;
|
||||
$chosenRole = $this->Role->findById($this->request->data['User']['role_id']);
|
||||
if ($chosenRole['Role']['perm_site_admin'] == 1 || $chosenRole['Role']['perm_regexp_access'] == 1 || $chosenRole['Role']['perm_sync'] == 1) {
|
||||
if (
|
||||
$chosenRole['Role']['perm_site_admin'] == 1 ||
|
||||
$chosenRole['Role']['perm_regexp_access'] == 1 ||
|
||||
$chosenRole['Role']['perm_sync'] == 1 ||
|
||||
$chosenRole['Role']['restricted_to_site_admin'] == 1
|
||||
) {
|
||||
throw new Exception('You are not authorised to assign that role to a user.');
|
||||
}
|
||||
}
|
||||
|
@ -617,7 +622,7 @@ class UsersController extends AppController {
|
|||
$params = array('conditions' => array(
|
||||
'OR' => array(
|
||||
'AND' => array(
|
||||
'perm_site_admin' => 0, 'perm_sync' => 0, 'perm_regexp_access' => 0
|
||||
'perm_site_admin' => 0, 'perm_sync' => 0, 'perm_regexp_access' => 0, 'restricted_to_site_admin' => 0
|
||||
),
|
||||
'id' => $allowedRole,
|
||||
)
|
||||
|
|
|
@ -192,67 +192,111 @@ class ComplexTypeTool {
|
|||
128 => array('single' => array('sha512'), 'composite' => array('filename|sha512'))
|
||||
);
|
||||
|
||||
private function __resolveType($input) {
|
||||
$input = trim($input);
|
||||
if (strpos($input, '|')) {
|
||||
$compositeParts = explode('|', $input);
|
||||
if (count($compositeParts) == 2) {
|
||||
if ($this->__resolveFilename($compositeParts[0])) {
|
||||
foreach ($this->__hexHashTypes as $k => $v) {
|
||||
if (strlen($compositeParts[1]) == $k && preg_match("#[0-9a-f]{" . $k . "}$#i", $compositeParts[1])) return array('types' => $v['composite'], 'to_ids' => true, 'default_type' => $v['composite'][0], 'value' => $input);
|
||||
}
|
||||
if (preg_match('#^[0-9]+:[0-9a-zA-Z\/\+]+:[0-9a-zA-Z\/\+]+$#', $compositeParts[1]) && !preg_match('#^[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}$#', $compositeParts[1])) {
|
||||
return array('types' => array('filename|ssdeep'), 'to_ids' => true, 'default_type' => 'filename|ssdeep', 'value' => $input);
|
||||
// algorithms to run through in order
|
||||
private $__checks = array('Hashes', 'Email', 'IP', 'DomainOrFilename', 'SimpleRegex');
|
||||
|
||||
private function __resolveType($raw_input) {
|
||||
$input = array(
|
||||
'raw' => trim($raw_input)
|
||||
);
|
||||
$input = $this->__refangInput($input);
|
||||
$input = $this->__extractPort($input);
|
||||
|
||||
foreach ($this->__checks as $check) {
|
||||
$result = $this->{'__checkFor' . $check}($input);
|
||||
if ($result) return $result;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function __checkForEmail($input) {
|
||||
// quick filter for an @ to see if we should validate a potential e-mail address
|
||||
if (strpos($input['refanged'], '@') !== false) {
|
||||
if (filter_var($input['refanged'], FILTER_VALIDATE_EMAIL)) return array('types' => array('email-src', 'email-dst', 'target-email', 'whois-registrant-email'), 'to_ids' => true, 'default_type' => 'email-src', 'value' => $input['refanged']);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function __checkForHashes($input) {
|
||||
// handle prepared composite values with the filename|hash format
|
||||
if (strpos($input['raw'], '|')) {
|
||||
$compositeParts = explode('|', $input['raw']);
|
||||
if (count($compositeParts) == 2) {
|
||||
if ($this->__resolveFilename($compositeParts[0])) {
|
||||
foreach ($this->__hexHashTypes as $k => $v) {
|
||||
if (strlen($compositeParts[1]) == $k && preg_match("#[0-9a-f]{" . $k . "}$#i", $compositeParts[1])) return array('types' => $v['composite'], 'to_ids' => true, 'default_type' => $v['composite'][0], 'value' => $input['raw']);
|
||||
}
|
||||
if (preg_match('#^[0-9]+:[0-9a-zA-Z\/\+]+:[0-9a-zA-Z\/\+]+$#', $compositeParts[1]) && !preg_match('#^[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}$#', $compositeParts[1])) {
|
||||
return array('types' => array('filename|ssdeep'), 'to_ids' => true, 'default_type' => 'filename|ssdeep', 'value' => $input['raw']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check for hashes
|
||||
foreach ($this->__hexHashTypes as $k => $v) {
|
||||
if (strlen($input) == $k && preg_match("#[0-9a-f]{" . $k . "}$#i", $input)) return array('types' => $v['single'], 'to_ids' => true, 'default_type' => $v['single'][0], 'value' => $input);
|
||||
}
|
||||
if (preg_match('#^[0-9]+:[0-9a-zA-Z\/\+]+:[0-9a-zA-Z\/\+]+$#', $input) && !preg_match('#^[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}$#', $input)) return array('types' => array('ssdeep'), 'to_ids' => true, 'default_type' => 'ssdeep', 'value' => $input);
|
||||
$inputRefanged = $input;
|
||||
foreach ($this->__refangRegexTable as $regex => $replacement) {
|
||||
$inputRefanged = preg_replace($regex, $replacement , $inputRefanged);
|
||||
}
|
||||
$inputRefanged = rtrim($inputRefanged, ".");
|
||||
if (strpos($inputRefanged, '@') !== false) {
|
||||
if (filter_var($inputRefanged, FILTER_VALIDATE_EMAIL)) return array('types' => array('email-src', 'email-dst', 'target-email', 'whois-registrant-email'), 'to_ids' => true, 'default_type' => 'email-src', 'value' => $inputRefanged);
|
||||
}
|
||||
// check for hashes
|
||||
foreach ($this->__hexHashTypes as $k => $v) {
|
||||
if (strlen($input['raw']) == $k && preg_match("#[0-9a-f]{" . $k . "}$#i", $input['raw'])) return array('types' => $v['single'], 'to_ids' => true, 'default_type' => $v['single'][0], 'value' => $input['raw']);
|
||||
}
|
||||
// ssdeep has a different pattern
|
||||
if (preg_match('#^[0-9]+:[0-9a-zA-Z\/\+]+:[0-9a-zA-Z\/\+]+$#', $input['raw']) && !preg_match('#^[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}$#', $input['raw'])) return array('types' => array('ssdeep'), 'to_ids' => true, 'default_type' => 'ssdeep', 'value' => $input['raw']);
|
||||
return false;
|
||||
}
|
||||
|
||||
private function __extractPort($input) {
|
||||
// note down and remove the port if it's a url / domain name / hostname / ip
|
||||
// input2 from here on is the variable containing the original input with the port removed. It is only used by url / domain name / hostname / ip
|
||||
$comment = false;
|
||||
if (preg_match('/(:[0-9]{2,5})$/', $inputRefanged, $port)) {
|
||||
$comment = 'On port ' . substr($port[0], 1);
|
||||
$inputRefangedNoPort = str_replace($port[0], '', $inputRefanged);
|
||||
$port = substr($port[0], 1);
|
||||
$input['comment'] = false;
|
||||
if (preg_match('/(:[0-9]{2,5})$/', $input['refanged'], $input['port'])) {
|
||||
$input['comment'] = 'On port ' . substr($input['port'][0], 1);
|
||||
$input['refanged_no_port'] = str_replace($input['port'][0], '', $input['refanged']);
|
||||
$input['port'] = substr($input['port'][0], 1);
|
||||
} else {
|
||||
unset($port);
|
||||
$inputRefangedNoPort = $inputRefanged;
|
||||
unset($input['port']);
|
||||
$input['refanged_no_port'] = $input['refanged'];
|
||||
}
|
||||
// check for IP
|
||||
if (filter_var($inputRefangedNoPort, FILTER_VALIDATE_IP)) {
|
||||
if (isset($port)) {
|
||||
return array('types' => array('ip-dst|port', 'ip-src|port', 'ip-src|port/ip-dst|port'), 'to_ids' => true, 'default_type' => 'ip-dst|port', 'comment' => $comment, 'value' => $inputRefangedNoPort . '|' . $port);
|
||||
return $input;
|
||||
}
|
||||
|
||||
private function __refangInput($input) {
|
||||
$input['refanged'] = $input['raw'];
|
||||
foreach ($this->__refangRegexTable as $regex => $replacement) {
|
||||
$input['refanged'] = preg_replace($regex, $replacement , $input['refanged']);
|
||||
}
|
||||
$input['refanged'] = rtrim($input['refanged'], ".");
|
||||
return $input;
|
||||
}
|
||||
|
||||
private function __checkForSimpleRegex($input) {
|
||||
// CVE numbers
|
||||
if (preg_match("#^cve-[0-9]{4}-[0-9]{4,9}$#i", $input['raw'])) return array('types' => array('vulnerability'), 'categories' => array('External analysis'), 'to_ids' => false, 'default_type' => 'vulnerability', 'value' => $input['raw']);
|
||||
// Phone numbers
|
||||
if (preg_match("#^(\+)?([0-9]{1,3}(\(0\))?)?[0-9\/\-]{5,}[0-9]$#i", $input['raw'])) return array('types' => array('phone-number', 'prtn', 'whois-registrant-phone'), 'categories' => array('Other'), 'to_ids' => false, 'default_type' => 'phone-number', 'value' => $input['raw']);
|
||||
}
|
||||
|
||||
private function __checkForIP($input) {
|
||||
if (filter_var($input['refanged_no_port'], FILTER_VALIDATE_IP)) {
|
||||
if (isset($input['port'])) {
|
||||
return array('types' => array('ip-dst|port', 'ip-src|port', 'ip-src|port/ip-dst|port'), 'to_ids' => true, 'default_type' => 'ip-dst|port', 'comment' => $input['comment'], 'value' => $input['refanged_no_port'] . '|' . $input['port']);
|
||||
} else {
|
||||
return array('types' => array('ip-dst', 'ip-src', 'ip-src/ip-dst'), 'to_ids' => true, 'default_type' => 'ip-dst', 'comment' => $comment, 'value' => $inputRefangedNoPort);
|
||||
return array('types' => array('ip-dst', 'ip-src', 'ip-src/ip-dst'), 'to_ids' => true, 'default_type' => 'ip-dst', 'comment' => $input['comment'], 'value' => $input['refanged_no_port']);
|
||||
}
|
||||
}
|
||||
if (strpos($inputRefangedNoPort, '/')) {
|
||||
$temp = explode('/', $inputRefangedNoPort);
|
||||
// it could still be a CIDR block
|
||||
if (strpos($input['refanged_no_port'], '/')) {
|
||||
$temp = explode('/', $input['refanged_no_port']);
|
||||
if (count($temp) == 2) {
|
||||
if (filter_var($temp[0], FILTER_VALIDATE_IP) && is_numeric($temp[1])) return array('types' => array('ip-dst', 'ip-src', 'ip-src/ip-dst'), 'to_ids' => true, 'default_type' => 'ip-dst', 'comment' => $comment, 'value' => $inputRefangedNoPort);
|
||||
if (filter_var($temp[0], FILTER_VALIDATE_IP) && is_numeric($temp[1])) return array('types' => array('ip-dst', 'ip-src', 'ip-src/ip-dst'), 'to_ids' => true, 'default_type' => 'ip-dst', 'comment' => $input['comment'], 'value' => $input['refanged_no_port']);
|
||||
}
|
||||
}
|
||||
// check for domain name, hostname, filename
|
||||
if (strpos($inputRefanged, '.') !== false) {
|
||||
$temp = explode('.', $inputRefanged);
|
||||
}
|
||||
|
||||
private function __checkForDomainOrFilename($input) {
|
||||
if (strpos($input['refanged'], '.') !== false) {
|
||||
$temp = explode('.', $input['refanged']);
|
||||
// TODO: use a more flexible matching approach, like the one below (that still doesn't support non-ASCII domains)
|
||||
//if (filter_var($input, FILTER_VALIDATE_URL)) {
|
||||
$domainDetection = true;
|
||||
if (preg_match('/^([-\pL\pN]+\.)+[a-z]+(:[0-9]{2,5})?$/iu', $inputRefanged)) {
|
||||
if (preg_match('/^([-\pL\pN]+\.)+[a-z]+(:[0-9]{2,5})?$/iu', $input['refanged'])) {
|
||||
if (empty($this->__tlds) || count($this->__tlds) == 1) {
|
||||
$this->__generateTLDList();
|
||||
}
|
||||
|
@ -265,42 +309,37 @@ class ComplexTypeTool {
|
|||
}
|
||||
if ($domainDetection) {
|
||||
if (count($temp) > 2) {
|
||||
return array('types' => array('hostname', 'domain', 'url'), 'to_ids' => true, 'default_type' => 'hostname', 'comment' => $comment, 'value' => $inputRefangedNoPort);
|
||||
return array('types' => array('hostname', 'domain', 'url'), 'to_ids' => true, 'default_type' => 'hostname', 'comment' => $input['comment'], 'value' => $input['refanged_no_port']);
|
||||
} else {
|
||||
return array('types' => array('domain'), 'to_ids' => true, 'default_type' => 'domain', 'comment' => $comment, 'value' => $inputRefangedNoPort);
|
||||
return array('types' => array('domain'), 'to_ids' => true, 'default_type' => 'domain', 'comment' => $input['comment'], 'value' => $input['refanged_no_port']);
|
||||
}
|
||||
} else {
|
||||
// check if it is a URL
|
||||
// Adding http:// infront of the input in case it was left off. github.com/MISP/MISP should still be counted as a valid link
|
||||
if (count($temp) > 1 && (filter_var($inputRefangedNoPort, FILTER_VALIDATE_URL) || filter_var('http://' . $inputRefangedNoPort, FILTER_VALIDATE_URL))) {
|
||||
// TODO: add comment explaining why there is a check for a specific domain
|
||||
if (preg_match('/^https:\/\/(www.)?virustotal.com\//i', $inputRefangedNoPort)) return array('types' => array('link'), 'to_ids' => false, 'default_type' => 'link', 'comment' => $comment, 'value' => $inputRefangedNoPort);
|
||||
if (preg_match('/^https:\/\/www\.hybrid-analysis\.com\//i', $inputRefangedNoPort)) return array('types' => array('link'), 'categories' => array('External analysis'), 'to_ids' => false, 'default_type' => 'link', 'comment' => $comment, 'value' => $inputRefangedNoPort);
|
||||
if (strpos($inputRefangedNoPort, '/')) return array('types' => array('url'), 'to_ids' => true, 'default_type' => 'url', 'comment' => $comment, 'value' => $inputRefangedNoPort);
|
||||
if (count($temp) > 1 && (filter_var($input['refanged_no_port'], FILTER_VALIDATE_URL) || filter_var('http://' . $input['refanged_no_port'], FILTER_VALIDATE_URL))) {
|
||||
// Even though some domains are valid, we want to exclude them as they are known security vendors / etc
|
||||
// TODO, replace that with the appropriate warninglist.
|
||||
if (preg_match('/^https:\/\/(www.)?virustotal.com\//i', $input['refanged_no_port'])) return array('types' => array('link'), 'to_ids' => false, 'default_type' => 'link', 'comment' => $input['comment'], 'value' => $input['refanged_no_port']);
|
||||
if (preg_match('/^https:\/\/www\.hybrid-analysis\.com\//i', $input['refanged_no_port'])) return array('types' => array('link'), 'categories' => array('External analysis'), 'to_ids' => false, 'default_type' => 'link', 'comment' => $input['comment'], 'value' => $input['refanged_no_port']);
|
||||
if (strpos($input['refanged_no_port'], '/')) return array('types' => array('url'), 'to_ids' => true, 'default_type' => 'url', 'comment' => $input['comment'], 'value' => $input['refanged_no_port']);
|
||||
}
|
||||
if ($this->__resolveFilename($input)) return array('types' => array('filename'), 'to_ids' => true, 'default_type' => 'filename', 'value' => $input);
|
||||
if ($this->__resolveFilename($input['raw'])) return array('types' => array('filename'), 'to_ids' => true, 'default_type' => 'filename', 'value' => $input['raw']);
|
||||
}
|
||||
}
|
||||
|
||||
if (strpos($input, '\\') !== false) {
|
||||
$temp = explode('\\', $input);
|
||||
if (strpos($input['raw'], '\\') !== false) {
|
||||
$temp = explode('\\', $input['raw']);
|
||||
if (strpos($temp[count($temp)-1], '.') || preg_match('/^.:/i', $temp[0])) {
|
||||
if ($this->__resolveFilename($temp[count($temp)-1])) return array('types' => array('filename'), 'categories' => array('Payload installation'), 'to_ids' => true, 'default_type' => 'filename', 'value' => $input);
|
||||
if ($this->__resolveFilename($temp[count($temp)-1])) return array('types' => array('filename'), 'categories' => array('Payload installation'), 'to_ids' => true, 'default_type' => 'filename', 'value' => $input['raw']);
|
||||
} else {
|
||||
return array('types' => array('regkey'), 'to_ids' => false, 'default_type' => 'regkey', 'value' => $input);
|
||||
return array('types' => array('regkey'), 'to_ids' => false, 'default_type' => 'regkey', 'value' => $input['raw']);
|
||||
}
|
||||
}
|
||||
|
||||
// check for CVE
|
||||
if (preg_match("#^cve-[0-9]{4}-[0-9]{4,9}$#i", $input)) return array('types' => array('vulnerability'), 'categories' => array('External analysis'), 'to_ids' => false, 'default_type' => 'vulnerability', 'value' => $input);
|
||||
if (preg_match("#^(\+)?([0-9]{1,3}(\(0\))?)?[0-9\/\-]{5,}[0-9]$#i", $input)) return array('types' => array('phone-number', 'prtn', 'whois-registrant-phone'), 'categories' => array('Other'), 'to_ids' => false, 'default_type' => 'phone-number', 'value' => $input);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function __resolveFilename($input) {
|
||||
if ((preg_match('/^.:/', $input) || strpos($input, '.') !=0)) {
|
||||
$parts = explode('.', $input);
|
||||
private function __resolveFilename($param) {
|
||||
if ((preg_match('/^.:/', $param) || strpos($param, '.') !=0)) {
|
||||
$parts = explode('.', $param);
|
||||
if (!is_numeric($parts[count($parts)-1]) && ctype_alnum($parts[count($parts)-1])) return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -89,19 +89,19 @@ msgid "Event Blacklisting is not currently enabled on this instance."
|
|||
msgstr ""
|
||||
|
||||
#: Controller/EventsController.php:610
|
||||
msgid "No x509 certificate or GPG key set in your profile. To receive emails, submit your public certificate or GPG key in your profile."
|
||||
msgid "No x509 certificate or GnuPG key set in your profile. To receive emails, submit your public certificate or GnuPG key in your profile."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/EventsController.php:612
|
||||
msgid "No GPG key set in your profile. To receive emails, submit your public key in your profile."
|
||||
msgid "No GnuPG key set in your profile. To receive emails, submit your public key in your profile."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/EventsController.php:618
|
||||
msgid "No x509 certificate or GPG key set in your profile. To receive attributes in emails, submit your public certificate or GPG key in your profile."
|
||||
msgid "No x509 certificate or GnuPG key set in your profile. To receive attributes in emails, submit your public certificate or GnuPG key in your profile."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/EventsController.php:620
|
||||
msgid "No GPG key set in your profile. To receive attributes in emails, submit your public key in your profile."
|
||||
msgid "No GnuPG key set in your profile. To receive attributes in emails, submit your public key in your profile."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/EventsController.php:1052
|
||||
|
@ -2649,16 +2649,16 @@ msgstr ""
|
|||
|
||||
#: View/Elements/healthElements/diagnostics.ctp:324;326
|
||||
#: View/Pages/administration.ctp:17
|
||||
msgid "Verify PGP keys"
|
||||
msgid "Verify GnuPG keys"
|
||||
msgstr ""
|
||||
|
||||
#: View/Elements/healthElements/diagnostics.ctp:325
|
||||
msgid "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."
|
||||
msgid "Run a full validation of all GnuPG keys within this instance's userbase. The script will try to identify possible issues with each key and report back on the results."
|
||||
msgstr ""
|
||||
|
||||
#: View/Elements/healthElements/diagnostics.ctp:326
|
||||
#: View/Pages/administration.ctp:17
|
||||
msgid "Check whether every user's PGP key is usable"
|
||||
msgid "Check whether every user's GnuPG key is usable"
|
||||
msgstr ""
|
||||
|
||||
#: View/Elements/healthElements/diagnostics.ctp:327
|
||||
|
@ -6111,7 +6111,7 @@ msgid "GnuPG settings"
|
|||
msgstr ""
|
||||
|
||||
#: View/Pages/doc/administration.ctp:34
|
||||
msgid "GPG related settings."
|
||||
msgid "GnuPG related settings."
|
||||
msgstr ""
|
||||
|
||||
#: View/Pages/doc/administration.ctp:35
|
||||
|
@ -6139,7 +6139,7 @@ msgid "Diagnostics"
|
|||
msgstr ""
|
||||
|
||||
#: View/Pages/doc/administration.ctp:38
|
||||
msgid "The diagnostics tool checks if all directories that MISP uses to store data are writeable by the apache user. Also, the tool checks whether the STIX libraries and GPG are working as intended."
|
||||
msgid "The diagnostics tool checks if all directories that MISP uses to store data are writeable by the apache user. Also, the tool checks whether the STIX libraries and GnuPG are working as intended."
|
||||
msgstr ""
|
||||
|
||||
#: View/Pages/doc/administration.ctp:39
|
||||
|
@ -6393,7 +6393,7 @@ msgid "Nids ID, not yet implemented."
|
|||
msgstr ""
|
||||
|
||||
#: View/Pages/doc/administration.ctp:96;127
|
||||
msgid "Gpgkey"
|
||||
msgid "GnuPGkey"
|
||||
msgstr ""
|
||||
|
||||
#: View/Pages/doc/administration.ctp:96;127
|
||||
|
@ -6443,7 +6443,7 @@ msgid "Shows whether the user has the subscription to contact reporter e-mails d
|
|||
msgstr ""
|
||||
|
||||
#: View/Pages/doc/administration.ctp:107
|
||||
msgid "Shows whether the user has entered a Gpgkey yet."
|
||||
msgid "Shows whether the user has entered a GnuPG key yet."
|
||||
msgstr ""
|
||||
|
||||
#: View/Pages/doc/administration.ctp:108
|
||||
|
@ -6510,7 +6510,7 @@ msgid "Contacting a user"
|
|||
msgstr ""
|
||||
|
||||
#: View/Pages/doc/administration.ctp:130
|
||||
msgid "Site admins can use the \"Contact users\" feature to send all or an individual user an e-mail. Users that have a PGP key set will receive their e-mails encrypted. When clicking this button on the left, you'll be presented with a form that allows you to specify the type of the e-mail, who it should reach and what the content is using the following options"
|
||||
msgid "Site admins can use the \"Contact users\" feature to send all or an individual user an e-mail. Users that have a GnuPG key set will receive their e-mails encrypted. When clicking this button on the left, you'll be presented with a form that allows you to specify the type of the e-mail, who it should reach and what the content is using the following options"
|
||||
msgstr ""
|
||||
|
||||
#: View/Pages/doc/administration.ctp:131
|
||||
|
@ -6536,7 +6536,7 @@ msgid "Recipient"
|
|||
msgstr ""
|
||||
|
||||
#: View/Pages/doc/administration.ctp:134
|
||||
msgid "The recipient toggle lets you contact all your users, a single user (which creates a second drop-down list with all the e-mail addresses of the users) and potential future users (which opens up a text field for the e-mail address and a text area field for a PGP public key)."
|
||||
msgid "The recipient toggle lets you contact all your users, a single user (which creates a second drop-down list with all the e-mail addresses of the users) and potential future users (which opens up a text field for the e-mail address and a text area field for a GnuPG public key)."
|
||||
msgstr ""
|
||||
|
||||
#: View/Pages/doc/administration.ctp:135;136
|
||||
|
@ -6558,7 +6558,7 @@ msgid "This is available for password resets, you can either write your own mess
|
|||
msgstr ""
|
||||
|
||||
#: View/Pages/doc/administration.ctp:139
|
||||
msgid "Keep in mind that all e-mails sent through this system will, in addition to your own message, will be signed in the name of the instance's host organisation's support team, will include the e-mail address of the instance's support (if the contact field is set in the bootstrap file), and will include the instance's PGP signature for users that have a PGP key set (and thus are eligible for an encrypted e-mail)."
|
||||
msgid "Keep in mind that all e-mails sent through this system will, in addition to your own message, will be signed in the name of the instance's host organisation's support team, will include the e-mail address of the instance's support (if the contact field is set in the bootstrap file), and will include the instance's GnuPG signature for users that have a GnuPG key set (and thus are eligible for an encrypted e-mail)."
|
||||
msgstr ""
|
||||
|
||||
#: View/Pages/doc/administration.ctp:141
|
||||
|
@ -7468,11 +7468,11 @@ msgid "After accepting the ToU, you'll be prompted to change your password, but
|
|||
msgstr ""
|
||||
|
||||
#: View/Pages/doc/user_management.ctp:27;44
|
||||
msgid "Setting up the GPG Key"
|
||||
msgid "Setting up the GnuPG Key"
|
||||
msgstr ""
|
||||
|
||||
#: View/Pages/doc/user_management.ctp:27
|
||||
msgid "In order for the system to be able to encrypt the messages that you send through it, it needs to know your GPG key. Navigate to the Edit profile view (My Profile on the left -> Edit profile in the top right corner). Paste the key into the Gpgkey field and click submit."
|
||||
msgid "In order for the system to be able to encrypt the messages that you send through it, it needs to know your GnuPG key. Navigate to the Edit profile view (My Profile on the left -> Edit profile in the top right corner). Paste the key into the GnuPG key field and click submit."
|
||||
msgstr ""
|
||||
|
||||
#: View/Pages/doc/user_management.ctp:28;42
|
||||
|
@ -7536,7 +7536,7 @@ msgid "Turning this feature on will allow you to receive e-mails addressed to yo
|
|||
msgstr ""
|
||||
|
||||
#: View/Pages/doc/user_management.ctp:44
|
||||
msgid "In order for the system to be able to encrypt the messages that you send through it, it needs to know your GPG key. You can acquire this by clicking on the PGP/GPG key link at the bottom left of the screen. Copy the entirety of the key and navigate to the Edit profile view (My Profile on the left -> Edit profile in the top right corner). Paste the key into the Gpgkey field and click submit."
|
||||
msgid "In order for the system to be able to encrypt the messages that you send through it, it needs to know your GnuPG key. You can acquire this by clicking on the GnuPG key link at the bottom left of the screen. Copy the entirety of the key and navigate to the Edit profile view (My Profile on the left -> Edit profile in the top right corner). Paste the key into the GnuPG key field and click submit."
|
||||
msgstr ""
|
||||
|
||||
#: View/Pages/doc/user_management.ctp:45
|
||||
|
@ -10157,23 +10157,23 @@ msgstr ""
|
|||
|
||||
#: View/Users/admin_add.ctp:70
|
||||
#: View/Users/admin_edit.ctp:64
|
||||
msgid "GPG key"
|
||||
msgid "GnuPG key"
|
||||
msgstr ""
|
||||
|
||||
#: View/Users/admin_add.ctp:70
|
||||
#: View/Users/admin_edit.ctp:64
|
||||
msgid "Paste the user's PGP key here or try to retrieve it from the MIT key server by clicking on \"Fetch GPG key\" below."
|
||||
msgid "Paste the user's GnuPG key here or try to retrieve it from the MIT key server by clicking on \"Fetch GnuPG key\" below."
|
||||
msgstr ""
|
||||
|
||||
#: View/Users/admin_add.ctp:72
|
||||
#: View/Users/admin_edit.ctp:66
|
||||
msgid "Fetch the user's PGP key"
|
||||
msgid "Fetch the user's GnuPG key"
|
||||
msgstr ""
|
||||
|
||||
#: View/Users/admin_add.ctp:72
|
||||
#: View/Users/admin_edit.ctp:66
|
||||
#: View/Users/edit.ctp:25
|
||||
msgid "Fetch GPG key"
|
||||
msgid "Fetch GnuPG key"
|
||||
msgstr ""
|
||||
|
||||
#: View/Users/admin_add.ctp:74
|
||||
|
@ -10238,7 +10238,7 @@ msgid "You can then specify (if eligible) what the e-mail address of the target
|
|||
msgstr ""
|
||||
|
||||
#: View/Users/admin_email.ctp:12
|
||||
msgid "In the case of a new user, you can specify the future user's gpg key, to send his/her new key in an encrypted e-mail."
|
||||
msgid "In the case of a new user, you can specify the future user's GnuPG key, to send his/her new key in an encrypted e-mail."
|
||||
msgstr ""
|
||||
|
||||
#: View/Users/admin_email.ctp:13
|
||||
|
@ -10328,17 +10328,17 @@ msgstr ""
|
|||
|
||||
#: View/Users/admin_view.ctp:67
|
||||
#: View/Users/view.ctp:60
|
||||
msgid "PGP key"
|
||||
msgid "GnuPG key"
|
||||
msgstr ""
|
||||
|
||||
#: View/Users/admin_view.ctp:74
|
||||
#: View/Users/view.ctp:67
|
||||
msgid "PGP fingerprint"
|
||||
msgid "GnuPG fingerprint"
|
||||
msgstr ""
|
||||
|
||||
#: View/Users/admin_view.ctp:80
|
||||
#: View/Users/view.ctp:73
|
||||
msgid "PGP status"
|
||||
msgid "GnuPG status"
|
||||
msgstr ""
|
||||
|
||||
#: View/Users/admin_view.ctp:90
|
||||
|
@ -10355,7 +10355,7 @@ msgid "Password change"
|
|||
msgstr ""
|
||||
|
||||
#: View/Users/check_and_correct_pgps.ctp:2
|
||||
msgid "Failed GPGs?"
|
||||
msgid "Failed GnuPGs?"
|
||||
msgstr ""
|
||||
|
||||
#: View/Users/check_and_correct_pgps.ctp:4
|
||||
|
@ -10363,7 +10363,7 @@ msgid "No failed composites"
|
|||
msgstr ""
|
||||
|
||||
#: View/Users/edit.ctp:25
|
||||
msgid "Fetch PGP key"
|
||||
msgid "Fetch GnuPG key"
|
||||
msgstr ""
|
||||
|
||||
#: View/Users/edit.ctp:27
|
||||
|
@ -10481,7 +10481,7 @@ msgid "Certificates validation"
|
|||
msgstr ""
|
||||
|
||||
#: View/Users/verify_g_p_g.ctp:2
|
||||
msgid "GPG key validation"
|
||||
msgid "GnuPG key validation"
|
||||
msgstr ""
|
||||
|
||||
#: View/Users/view.ctp:45
|
||||
|
@ -10509,7 +10509,7 @@ msgid "Associated E-mail addresses"
|
|||
msgstr ""
|
||||
|
||||
#: View/Users/ajax/fetchpgpkey.ctp:12
|
||||
msgid "Select pgp key"
|
||||
msgid "Select GnuPG key"
|
||||
msgstr ""
|
||||
|
||||
#: View/Users/ajax/passwordResetConfirmationForm.ctp:3
|
||||
|
|
|
@ -60,7 +60,7 @@ class AppModel extends Model {
|
|||
);
|
||||
|
||||
public $db_changes = array(
|
||||
1 => false, 2 => false, 3 => false
|
||||
1 => false, 2 => false, 3 => false, 4 => true, 5 => false
|
||||
);
|
||||
|
||||
function afterSave($created, $options = array()) {
|
||||
|
@ -134,6 +134,11 @@ class AppModel extends Model {
|
|||
$this->MispObject->removeOrphanedObjects();
|
||||
$this->updateDatabase($command);
|
||||
break;
|
||||
case 5:
|
||||
$this->updateDatabase($command);
|
||||
$this->Feed = Classregistry::init('Feed');
|
||||
$this->Feed->setEnableFeedCachingDefaults();
|
||||
break;
|
||||
default:
|
||||
$this->updateDatabase($command);
|
||||
break;
|
||||
|
@ -862,7 +867,6 @@ class AppModel extends Model {
|
|||
$indexArray[] = array('attributes', 'deleted');
|
||||
break;
|
||||
case '2.4.86':
|
||||
|
||||
break;
|
||||
case '2.4.87':
|
||||
$sqlArray[] = "ALTER TABLE `feeds` ADD `headers` TEXT COLLATE utf8_bin;";
|
||||
|
@ -886,6 +890,14 @@ class AppModel extends Model {
|
|||
$this->__addIndex('fuzzy_correlate_ssdeep', 'chunk');
|
||||
$this->__addIndex('fuzzy_correlate_ssdeep', 'attribute_id');
|
||||
break;
|
||||
case 4:
|
||||
$sqlArray[] = 'ALTER TABLE `roles` ADD `memory_limit` VARCHAR(255) COLLATE utf8_bin DEFAULT "";';
|
||||
$sqlArray[] = 'ALTER TABLE `roles` ADD `max_execution_time` VARCHAR(255) COLLATE utf8_bin DEFAULT "";';
|
||||
$sqlArray[] = "ALTER TABLE `roles` ADD `restricted_to_site_admin` tinyint(1) NOT NULL DEFAULT 0;";
|
||||
break;
|
||||
case 5:
|
||||
$sqlArray[] = "ALTER TABLE `feeds` ADD `caching_enabled` BOOLEAN NOT NULL DEFAULT 0;";
|
||||
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;';
|
||||
|
|
|
@ -118,7 +118,7 @@ class Attribute extends AppModel {
|
|||
'email-attachment' => array('desc' => "File name of the email attachment.", 'default_category' => 'Payload delivery', 'to_ids' => 1),
|
||||
'email-body' => array('desc' => 'Email body', 'default_category' => 'Payload delivery', 'to_ids' => 0),
|
||||
'float' => array('desc' => "A floating point value.", 'default_category' => 'Other', 'to_ids' => 0),
|
||||
'url' => array('desc' => 'url', 'default_category' => 'External analysis', 'to_ids' => 1),
|
||||
'url' => array('desc' => 'url', 'default_category' => 'Network activity', '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),
|
||||
'regkey' => array('desc' => "Registry key or value", 'default_category' => 'Persistence mechanism', 'to_ids' => 1),
|
||||
|
@ -386,6 +386,8 @@ class Attribute extends AppModel {
|
|||
'financial' => array('btc', 'iban', 'bic', 'bank-account-nr', 'aba-rtn', 'bin', 'cc-number', 'prtn', 'phone-number')
|
||||
);
|
||||
|
||||
private $__fTool = false;
|
||||
|
||||
public $order = array("Attribute.event_id" => "DESC");
|
||||
|
||||
public $validate = array(
|
||||
|
@ -1213,7 +1215,6 @@ class Attribute extends AppModel {
|
|||
case 'sha512':
|
||||
case 'sha512/224':
|
||||
case 'sha512/256':
|
||||
case 'domain':
|
||||
case 'hostname':
|
||||
case 'pehash':
|
||||
case 'authentihash':
|
||||
|
@ -1225,8 +1226,14 @@ class Attribute extends AppModel {
|
|||
case 'whois-registrant-email':
|
||||
$value = strtolower($value);
|
||||
break;
|
||||
case 'domain':
|
||||
$value = strtolower($value);
|
||||
$value = trim($value, '.');
|
||||
break;
|
||||
case 'domain|ip':
|
||||
$value = strtolower($value);
|
||||
$parts = explode('|', $value);
|
||||
$parts[0] = trim($parts[0], '.');
|
||||
if (filter_var($parts[1], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
|
||||
// convert IPv6 address to compressed format
|
||||
$parts[1] = inet_ntop(inet_pton($value));
|
||||
|
@ -3128,6 +3135,7 @@ class Attribute extends AppModel {
|
|||
$attribute['data'] = $result['data'];
|
||||
$attribute['value'] = $attribute['value'] . '|' . $result['md5'];
|
||||
}
|
||||
unset($attribute['id']);
|
||||
if (isset($attribute['uuid'])) {
|
||||
$existingAttribute = $this->find('first', array(
|
||||
'conditions' => array('Attribute.uuid' => $attribute['uuid']),
|
||||
|
@ -3262,4 +3270,13 @@ class Attribute extends AppModel {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
public function attachValidationWarnings($adata) {
|
||||
if (!$this->__fTool) {
|
||||
$this->__fTool = new FinancialTool();
|
||||
}
|
||||
if (!$this->__fTool->validateRouter($adata['type'], $adata['value'])) {
|
||||
$adata['validationIssue'] = true;
|
||||
}
|
||||
return $adata;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1701,6 +1701,9 @@ class Event extends AppModel {
|
|||
unset($event['Attribute'][$key]);
|
||||
continue;
|
||||
}
|
||||
if ($event['Attribute'][$key]['category'] === 'Financial fraud') {
|
||||
$event['Attribute'][$key] = $this->Attribute->attachValidationWarnings($event['Attribute'][$key]);
|
||||
}
|
||||
if (isset($options['includeAttachments']) && $options['includeAttachments']) {
|
||||
if ($this->Attribute->typeIsAttachment($attribute['type'])) {
|
||||
$encodedFile = $this->Attribute->base64EncodeAttachment($attribute);
|
||||
|
@ -1742,6 +1745,11 @@ class Event extends AppModel {
|
|||
foreach ($event['Object'] as $objectKey => $objectValue) {
|
||||
if (!empty($event['Object'][$objectKey]['Attribute'])) {
|
||||
$event['Object'][$objectKey]['Attribute'] = $this->__attachSharingGroups(!$options['sgReferenceOnly'], $event['Object'][$objectKey]['Attribute'], $sharingGroupData);
|
||||
foreach ($event['Object'][$objectKey]['Attribute'] as $akey => $adata) {
|
||||
if ($adata['category'] === 'Financial fraud') {
|
||||
$event['Object'][$objectKey]['Attribute'][$akey] = $this->Attribute->attachValidationWarnings($adata);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($event['Attribute'][$key]['object_id'] == $objectValue['id']) {
|
||||
$event['Object'][$objectKey]['Attribute'][] = $event['Attribute'][$key];
|
||||
|
@ -2243,7 +2251,7 @@ class Event extends AppModel {
|
|||
$body .= "\n";
|
||||
$body .= "You can reach him at " . $user['User']['email'] . "\n";
|
||||
if (!$user['User']['gpgkey'])
|
||||
$body .= "His GPG/PGP key is added as attachment to this email. \n";
|
||||
$body .= "His GnuPG key is added as attachment to this email. \n";
|
||||
if (!$user['User']['certif_public'])
|
||||
$body .= "His Public certificate is added as attachment to this email. \n";
|
||||
$body .= "\n";
|
||||
|
@ -4064,17 +4072,28 @@ class Event extends AppModel {
|
|||
return $this->save($event);
|
||||
}
|
||||
|
||||
public function upload_stix($user, $filename) {
|
||||
public function upload_stix($user, $filename, $stix_version) {
|
||||
App::uses('Folder', 'Utility');
|
||||
App::uses('File', 'Utility');
|
||||
$scriptFile = APP . 'files/scripts/stix2misp.py';
|
||||
$tempFilePath = APP . 'files/scripts/tmp/' . $filename;
|
||||
$result = shell_exec('python3 ' . $scriptFile . ' ' . $filename . ' 2>' . APP . 'tmp/logs/exec-errors.log');
|
||||
if ($stix_version == '2') {
|
||||
$scriptFile = APP . 'files/scripts/stix2/stix2misp.py';
|
||||
$tempFilePath = APP . 'files/scripts/tmp/' . $filename;
|
||||
$shell_command = 'python3 ' . $scriptFile . ' ' . $tempFilePath . ' 2>' . APP . 'tmp/logs/exec-errors.log';
|
||||
$output_path = $tempFilePath . '.stix2';
|
||||
} else if ($stix_version == '1' || $stix_version == '1.1' || $stix_version == '1.2') {
|
||||
$scriptFile = APP . 'files/scripts/stix2misp.py';
|
||||
$tempFilePath = APP . 'files/scripts/tmp/' . $filename;
|
||||
$shell_command = 'python3 ' . $scriptFile . ' ' . $filename . ' 2>' . APP . 'tmp/logs/exec-errors.log';
|
||||
$output_path = $tempFilePath . '.json';
|
||||
} else {
|
||||
throw new MethodNotAllowedException('Invalid STIX version');
|
||||
}
|
||||
$result = shell_exec($shell_command);
|
||||
unlink($tempFilePath);
|
||||
if (trim($result) == '1') {
|
||||
$data = file_get_contents($tempFilePath . '.json');
|
||||
$data = file_get_contents($output_path);
|
||||
$data = json_decode($data, true);
|
||||
unlink($tempFilePath . '.json');
|
||||
unlink($output_path);
|
||||
$created_id = false;
|
||||
$validationIssues = false;
|
||||
$result = $this->_add($data, true, $user, '', null, false, null, $created_id, $validationIssues);
|
||||
|
|
|
@ -714,6 +714,7 @@ class Feed extends AppModel {
|
|||
'provider' => $newFeed['provider'],
|
||||
'url' => $newFeed['url'],
|
||||
'enabled' => $newFeed['enabled'],
|
||||
'caching_enabled' => !empty($newFeed['caching_enabled']) ? $newFeed['caching_enabled'] : 0,
|
||||
'distribution' => 3,
|
||||
'sharing_group_id' => 0,
|
||||
'tag_id' => 0,
|
||||
|
@ -912,7 +913,7 @@ class Feed extends AppModel {
|
|||
|
||||
public function cacheFeedInitiator($user, $jobId = false, $scope = 'freetext') {
|
||||
$params = array(
|
||||
'conditions' => array('enabled' => 1),
|
||||
'conditions' => array('caching_enabled' => 1),
|
||||
'recursive' => -1,
|
||||
'fields' => array('source_format', 'input_source', 'url', 'id', 'settings')
|
||||
);
|
||||
|
@ -1179,4 +1180,19 @@ class Feed extends AppModel {
|
|||
$this->importFeeds($json, $user, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function setEnableFeedCachingDefaults() {
|
||||
$feeds = $this->find('all', array(
|
||||
'conditions' => array(
|
||||
'Feed.enabled' => 1
|
||||
),
|
||||
'recursive' => -1
|
||||
));
|
||||
if (empty($feeds)) return true;
|
||||
foreach ($feeds as $feed) {
|
||||
$feed['Feed']['caching_enabled'] = 1;
|
||||
$this->save($feed);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -160,6 +160,11 @@ class Module extends AppModel {
|
|||
'Content-Type' => 'application/json',
|
||||
)
|
||||
);
|
||||
if ($moduleFamily == 'Cortex') {
|
||||
if (!empty(Configure::read('Plugin.' . $moduleFamily . '_authkey'))) {
|
||||
$request['header']['Authorization'] = 'bearer ' . Configure::read('Plugin.' . $moduleFamily . '_authkey');
|
||||
}
|
||||
}
|
||||
try {
|
||||
if ($post) $response = $httpSocket->post($url . $uri, $post, $request);
|
||||
else $response = $httpSocket->get($url . $uri);
|
||||
|
|
|
@ -55,19 +55,84 @@ 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' => 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),
|
||||
'perm_tagger' => array('id' => 'RolePermTagger', 'text' => 'Tagger', 'readonlyenabled' => false),
|
||||
'perm_tag_editor' => array('id' => 'RolePermTagEditor', 'text' => 'Tag Editor', 'readonlyenabled' => false),
|
||||
'perm_template' => array('id' => 'RolePermTemplate', 'text' => 'Template Editor', 'readonlyenabled' => false),
|
||||
'perm_sharing_group' => array('id' => 'RolePermSharingGroup', 'text' => 'Sharing Group Editor', 'readonlyenabled' => false),
|
||||
'perm_delegate' => array('id' => 'RolePermDelegate', 'text' => 'Delegations Access', 'readonlyenabled' => false),
|
||||
'perm_sighting' => array('id' => 'RolePermSighting', 'text' => 'Sighting Creator', 'readonlyenabled' => true),
|
||||
'perm_object_template' => array('id' => 'RolePermObjectTemplate', 'text' => 'Object Template Editor', 'readonlyenabled' => false),
|
||||
'perm_site_admin' => array(
|
||||
'id' => 'RolePermSiteAdmin',
|
||||
'text' => 'Site Admin',
|
||||
'readonlyenabled' => false,
|
||||
'title' => 'Unrestricted access to any data and functionality on this instance.'
|
||||
),
|
||||
'perm_admin' => array(
|
||||
'id' => 'RolePermAdmin',
|
||||
'text' => 'Org Admin',
|
||||
'readonlyenabled' => false,
|
||||
'title' => 'Limited organisation admin - create, manage users of their own organisation'
|
||||
),
|
||||
'perm_sync' => array(
|
||||
'id' => 'RolePermSync',
|
||||
'text' => 'Sync Actions',
|
||||
'readonlyenabled' => true,
|
||||
'title' => 'Synchronisation permission, can be used to connect two MISP instances create data on behalf of other users. Make sure that the role with this permission has also access to tagging and tag editing rights.'
|
||||
),
|
||||
'perm_audit' => array(
|
||||
'id' => 'RolePermAudit',
|
||||
'text' => 'Audit Actions',
|
||||
'readonlyenabled' => true,
|
||||
'title' => 'Access to the audit logs of the user\'s organisation.'
|
||||
),
|
||||
'perm_auth' => array(
|
||||
'id' => 'RolePermAuth',
|
||||
'text' => 'Auth key access',
|
||||
'readonlyenabled' => true,
|
||||
'title' => 'Users with this permission have access to authenticating via their Auth keys, granting them access to the API.'
|
||||
),
|
||||
'perm_regexp_access' => array(
|
||||
'id' => 'RolePermRegexpAccess',
|
||||
'text' => 'Regex Actions',
|
||||
'readonlyenabled' => false,
|
||||
'title' => 'Users with this role can modify the regex rules affecting how data is fed into MISP. Make sure that caution is advised with handing out roles that include this permission, user controlled executed regexes are dangerous.'
|
||||
),
|
||||
'perm_tagger' => array(
|
||||
'id' => 'RolePermTagger',
|
||||
'text' => 'Tagger',
|
||||
'readonlyenabled' => false,
|
||||
'title' => 'Users with roles that include this permission can attach or detach existing tags to and from events/attributes.'
|
||||
),
|
||||
'perm_tag_editor' => array(
|
||||
'id' => 'RolePermTagEditor',
|
||||
'text' => 'Tag Editor',
|
||||
'readonlyenabled' => false,
|
||||
'title' => 'This permission gives users the ability to create, modify or remove tags.'
|
||||
),
|
||||
'perm_template' => array(
|
||||
'id' => 'RolePermTemplate',
|
||||
'text' => 'Template Editor',
|
||||
'readonlyenabled' => false,
|
||||
'title' => 'Create or modify templates, to be used when populating events.'
|
||||
),
|
||||
'perm_sharing_group' => array(
|
||||
'id' => 'RolePermSharingGroup',
|
||||
'text' => 'Sharing Group Editor',
|
||||
'readonlyenabled' => false,
|
||||
'title' => 'Permission to create or modify sharing groups.'
|
||||
),
|
||||
'perm_delegate' => array(
|
||||
'id' => 'RolePermDelegate',
|
||||
'text' => 'Delegations Access',
|
||||
'readonlyenabled' => false,
|
||||
'title' => 'Allow users to create delegation requests for their own org only events to trusted third parties.'
|
||||
),
|
||||
'perm_sighting' => array(
|
||||
'id' => 'RolePermSighting',
|
||||
'text' => 'Sighting Creator',
|
||||
'readonlyenabled' => true,
|
||||
'title' => 'Permits the user to push feedback on attributes into MISP by providing sightings.'
|
||||
),
|
||||
'perm_object_template' => array(
|
||||
'id' => 'RolePermObjectTemplate',
|
||||
'text' => 'Object Template Editor',
|
||||
'readonlyenabled' => false,
|
||||
'title' => 'Create or modify MISP Object templates'
|
||||
)
|
||||
);
|
||||
|
||||
public $premissionLevelName = array('Read Only', 'Manage Own Events', 'Manage Organisation Events', 'Manage and Publish Organisation Events');
|
||||
|
@ -119,6 +184,20 @@ class Role extends AppModel {
|
|||
$this->data['Role'][$permFlag] = 0;
|
||||
}
|
||||
}
|
||||
if (!isset($this->data['Role']['max_execution_time'])) {
|
||||
$this->data['Role']['max_execution_time'] = '';
|
||||
} else if ($this->data['Role']['max_execution_time'] !== '') {
|
||||
$this->data['Role']['max_execution_time'] = intval($this->data['Role']['max_execution_time']);
|
||||
}
|
||||
if (!isset($this->data['Role']['memory_limit'])) {
|
||||
$this->data['Role']['memory_limit'] = '';
|
||||
} else if (
|
||||
$this->data['Role']['memory_limit'] !== '' &&
|
||||
!preg_match('/^[0-9]+[MG]$/i', $this->data['Role']['memory_limit']) &&
|
||||
$this->data['Role']['memory_limit'] != -1
|
||||
) {
|
||||
$this->data['Role']['memory_limit'] = '';
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -433,7 +433,7 @@ class Server extends AppModel {
|
|||
),
|
||||
'extended_alert_subject' => array(
|
||||
'level' => 1,
|
||||
'description' => 'enabling this flag will allow the event description to be transmitted in the alert e-mail\'s subject. Be aware that this is not encrypted by PGP, so only enable it if you accept that part of the event description will be sent out in clear-text.',
|
||||
'description' => 'enabling this flag will allow the event description to be transmitted in the alert e-mail\'s subject. Be aware that this is not encrypted by GnuPG, so only enable it if you accept that part of the event description will be sent out in clear-text.',
|
||||
'value' => false,
|
||||
'errorMessage' => '',
|
||||
'test' => 'testBool',
|
||||
|
@ -804,7 +804,7 @@ class Server extends AppModel {
|
|||
'branch' => 1,
|
||||
'binary' => array(
|
||||
'level' => 2,
|
||||
'description' => 'The location of the GPG executable. If you would like to use a different gpg executable than /usr/bin/gpg, you can set it here. If the default is fine, just keep the setting suggested by MISP.',
|
||||
'description' => 'The location of the GnuPG executable. If you would like to use a different GnuPG executable than /usr/bin/gpg, you can set it here. If the default is fine, just keep the setting suggested by MISP.',
|
||||
'value' => '/usr/bin/gpg',
|
||||
'errorMessage' => '',
|
||||
'test' => 'testForGPGBinary',
|
||||
|
@ -812,7 +812,7 @@ class Server extends AppModel {
|
|||
),
|
||||
'onlyencrypted' => array(
|
||||
'level' => 0,
|
||||
'description' => 'Allow (false) unencrypted e-mails to be sent to users that don\'t have a PGP key.',
|
||||
'description' => 'Allow (false) unencrypted e-mails to be sent to users that don\'t have a GnuPG key.',
|
||||
'value' => '',
|
||||
'errorMessage' => '',
|
||||
'test' => 'testBool',
|
||||
|
@ -828,7 +828,7 @@ class Server extends AppModel {
|
|||
),
|
||||
'sign' => array(
|
||||
'level' => 2,
|
||||
'description' => 'Enable the signing of GPG emails. By default, GPG emails are signed',
|
||||
'description' => 'Enable the signing of GnuPG emails. By default, GnuPG emails are signed',
|
||||
'value' => 'true',
|
||||
'errorMessage' => '',
|
||||
'test' => 'testBool',
|
||||
|
@ -836,7 +836,7 @@ class Server extends AppModel {
|
|||
),
|
||||
'email' => array(
|
||||
'level' => 0,
|
||||
'description' => 'The e-mail address that the instance\'s PGP key is tied to.',
|
||||
'description' => 'The e-mail address that the instance\'s GnuPG key is tied to.',
|
||||
'value' => '',
|
||||
'errorMessage' => '',
|
||||
'test' => 'testForEmpty',
|
||||
|
@ -844,7 +844,7 @@ class Server extends AppModel {
|
|||
),
|
||||
'password' => array(
|
||||
'level' => 1,
|
||||
'description' => 'The password (if it is set) of the PGP key of the instance.',
|
||||
'description' => 'The password (if it is set) of the GnuPG key of the instance.',
|
||||
'value' => '',
|
||||
'errorMessage' => '',
|
||||
'test' => 'testForEmpty',
|
||||
|
@ -853,7 +853,7 @@ class Server extends AppModel {
|
|||
),
|
||||
'homedir' => array(
|
||||
'level' => 0,
|
||||
'description' => 'The location of the GPG homedir.',
|
||||
'description' => 'The location of the GnuPG homedir.',
|
||||
'value' => '',
|
||||
'errorMessage' => '',
|
||||
'test' => 'testForEmpty',
|
||||
|
@ -1517,6 +1517,15 @@ class Server extends AppModel {
|
|||
'test' => 'testBool',
|
||||
'type' => 'boolean'
|
||||
),
|
||||
'Cortex_authkey' => array(
|
||||
'level' => 1,
|
||||
'description' => 'Set an authentication key to be passed to Cortex',
|
||||
'value' => '',
|
||||
'errorMessage' => '',
|
||||
'test' => 'testForEmpty',
|
||||
'type' => 'string',
|
||||
'null' => true
|
||||
),
|
||||
'Cortex_timeout' => array(
|
||||
'level' => 1,
|
||||
'description' => 'Set a timeout for the import services',
|
||||
|
@ -2390,6 +2399,8 @@ class Server extends AppModel {
|
|||
}
|
||||
|
||||
public function testBaseURL($value) {
|
||||
// only run this check via the GUI, via the CLI it won't work
|
||||
if (php_sapi_name() == 'cli') return true;
|
||||
if ($this->testForEmpty($value) !== true) return $this->testForEmpty($value);
|
||||
if ($value != strtolower($this->getProto()) . '://' . $this->getHost()) return false;
|
||||
return true;
|
||||
|
@ -2481,7 +2492,7 @@ class Server extends AppModel {
|
|||
public function testForGPGBinary($value) {
|
||||
if (empty($value)) $value = $this->serverSettings['GnuPG']['binary']['value'];
|
||||
if (file_exists($value)) return true;
|
||||
return 'Could not find the gnupg executable at the defined location.';
|
||||
return 'Could not find the GnuPG executable at the defined location.';
|
||||
}
|
||||
|
||||
public function testForRPZDuration($value) {
|
||||
|
|
|
@ -123,7 +123,7 @@ class User extends AppModel {
|
|||
'gpgkey' => array(
|
||||
'gpgvalidation' => array(
|
||||
'rule' => array('validateGpgkey'),
|
||||
'message' => 'GPG key not valid, please enter a valid key.',
|
||||
'message' => 'GnuPG key not valid, please enter a valid key.',
|
||||
),
|
||||
),
|
||||
'certif_public' => array(
|
||||
|
@ -290,7 +290,7 @@ class User extends AppModel {
|
|||
return true;
|
||||
}
|
||||
|
||||
// Checks if the GPG key is a valid key, but also import it in the keychain.
|
||||
// Checks if the GnuPG key is a valid key, but also import it in the keychain.
|
||||
// TODO: this will NOT fail on keys that can only be used for signing but not encryption!
|
||||
// the method in verifyUsers will fail in that case.
|
||||
public function validateGpgkey($check) {
|
||||
|
@ -499,7 +499,7 @@ class User extends AppModel {
|
|||
$sortedKeys['valid']++;
|
||||
}
|
||||
if (!$sortedKeys['valid']) {
|
||||
$result[2] = 'The user\'s PGP key does not include a valid subkey that could be used for encryption.';
|
||||
$result[2] = 'The user\'s GnuPG key does not include a valid subkey that could be used for encryption.';
|
||||
if ($sortedKeys['expired']) $result[2] .= ' Found ' . $sortedKeys['expired'] . ' subkey(s) that have expired.';
|
||||
if ($sortedKeys['noEncrypt']) $result[2] .= ' Found ' . $sortedKeys['noEncrypt'] . ' subkey(s) that are sign only.';
|
||||
$result[0] = true;
|
||||
|
@ -765,8 +765,8 @@ class User extends AppModel {
|
|||
$failureReason = " the message could not be encrypted because the provided key is either expired or cannot be used for encryption.";
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// despite the user having a PGP key and the signing already succeeding earlier, we get an exception. This must mean that there is an issue with the user's key.
|
||||
$failureReason = " the message could not be encrypted because there was an issue with the user's PGP key. The following error message was returned by gpg: " . $e->getMessage();
|
||||
// despite the user having a GnuPG key and the signing already succeeding earlier, we get an exception. This must mean that there is an issue with the user's key.
|
||||
$failureReason = " the message could not be encrypted because there was an issue with the user's GnuPG key. The following error message was returned by gpg: " . $e->getMessage();
|
||||
$this->log($e->getMessage());
|
||||
$failed = true;
|
||||
}
|
||||
|
|
|
@ -69,7 +69,6 @@
|
|||
<div class="input clear"></div>
|
||||
<?php
|
||||
echo $this->Form->input('to_ids', array(
|
||||
'checked' => false,
|
||||
'label' => __('for Intrusion Detection System'),
|
||||
));
|
||||
echo $this->Form->input('batch_import', array(
|
||||
|
|
|
@ -89,7 +89,7 @@
|
|||
foreach ($object['warnings'][$component] as $warning) $temp .= '<span class=\'bold\'>' . h($valueParts[$valuePart]) . '</span>: <span class=\'red\'>' . h($warning) . '</span><br />';
|
||||
}
|
||||
}
|
||||
echo ' <span class="icon-warning-sign" data-placement="right" data-toggle="popover" data-content="' . h($temp) . '" data-trigger="hover"> </span>';
|
||||
echo ' <span class="icon-warning-sign" data-placement="right" data-toggle="popover" data-content="' . h($temp) . '" data-trigger="hover" data-placement="right"> </span>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
|
|
@ -82,11 +82,11 @@
|
|||
if ($mayModify && empty($object['deleted'])):
|
||||
?>
|
||||
<a href="<?php echo $baseurl;?>/objects/edit/<?php echo $object['id']; ?>" title="Edit" class="icon-edit icon-white useCursorPointer"></a>
|
||||
<span class="icon-trash icon-white useCursorPointer" title="<?php echo __('Permanently delete object');?>" role="button" tabindex="0" aria-label="<?php echo __('Permanently delete object');?>" onClick="deleteObject('objects', 'delete', '<?php echo h($object['id']); ?>', '<?php echo h($event['Event']['id']); ?>');"></span>
|
||||
<span class="icon-trash icon-white useCursorPointer" title="<?php echo __('Soft delete object');?>" role="button" tabindex="0" aria-label="<?php echo __('Soft delete object');?>" onClick="deleteObject('objects', 'delete', '<?php echo h($object['id']); ?>', '<?php echo h($event['Event']['id']); ?>');"></span>
|
||||
<?php
|
||||
elseif ($mayModify):
|
||||
?>
|
||||
<span class="icon-trash icon-white useCursorPointer" title="<?php echo __('Soft delete object');?>" role="button" tabindex="0" aria-label="<?php echo __('Soft delete attribute');?>" onClick="deleteObject('objects', 'delete', '<?php echo h($object['id']) . '/true'; ?>', '<?php echo h($event['Event']['id']); ?>');"></span>
|
||||
<span class="icon-trash icon-white useCursorPointer" title="<?php echo __('Permanently delete object');?>" role="button" tabindex="0" aria-label="<?php echo __('Permanently delete attribute');?>" onClick="deleteObject('objects', 'delete', '<?php echo h($object['id']) . '/true'; ?>', '<?php echo h($event['Event']['id']); ?>');"></span>
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<span class="bold"><?php echo __('References: ');?></span>
|
||||
<?php
|
||||
$refCount = count($object['ObjectReference']);
|
||||
$refCount = empty($object['ObjectReference']) ? 0 : count($object['ObjectReference']);
|
||||
echo $refCount . ' ';
|
||||
if (!empty($object['ObjectReference'])):
|
||||
?>
|
||||
|
@ -10,25 +10,25 @@
|
|||
?>
|
||||
<div id="Object_<?php echo $object['uuid']; ?>_references_collapsible" class="collapse">
|
||||
<?php
|
||||
foreach ($object['ObjectReference'] as $reference):
|
||||
if (!empty($reference['Object'])) {
|
||||
$uuid = $reference['Object']['uuid'];
|
||||
$output = ' (' . $reference['Object']['name'] . ': ' . $reference['Object']['name'] . ')';
|
||||
$objectType = 'Object';
|
||||
} else {
|
||||
$uuid = $reference['Attribute']['uuid'];
|
||||
$output = ' (' . $reference['Attribute']['category'] . '/' . $reference['Attribute']['type'] . ': "' . $reference['Attribute']['value'] . '")';
|
||||
$objectType = 'Attribute';
|
||||
}
|
||||
$uuid = empty($reference['Object']) ? $reference['Attribute']['uuid'] : $reference['Object']['uuid'];
|
||||
$idref = $reference['uuid'];
|
||||
if (!empty($object['ObjectReference'])):
|
||||
foreach ($object['ObjectReference'] as $reference):
|
||||
if (!empty($reference['Object'])) {
|
||||
$uuid = $reference['Object']['uuid'];
|
||||
$output = ' (' . $reference['Object']['name'] . ': ' . $reference['Object']['name'] . ')';
|
||||
$objectType = 'Object';
|
||||
} else {
|
||||
$uuid = $reference['referenced_uuid'];
|
||||
$output = '';
|
||||
$objectType = 'Attribute';
|
||||
}
|
||||
$uuid = $reference['referenced_uuid'];
|
||||
$idref = $reference['uuid'];
|
||||
?>
|
||||
|
||||
<div class="bold white useCursorPointer">
|
||||
<?php echo h($reference['relationship_type']) . ' ' . $objectType . ' ' . $reference['referenced_uuid'] . h($output);?>
|
||||
</div>
|
||||
<br />
|
||||
<div class="bold white useCursorPointer">
|
||||
<?php echo h($reference['relationship_type']) . ' ' . $objectType . ' ' . $reference['referenced_uuid'] . h($output);?>
|
||||
</div>
|
||||
<?php
|
||||
endforeach;
|
||||
endforeach;
|
||||
endif;
|
||||
?>
|
||||
</div>
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
echo $refCount;
|
||||
if (!empty($object['referenced_by'])):
|
||||
?>
|
||||
<span class="fa fa-expand useCursorPointer" title="<?php echo __('Expand or Collapse');?>" role="button" tabindex="0" aria-label="<?php echo __('Expand or Collapse');?>" data-toggle="collapse" data-target="#Object_<?php echo h($object['id']); ?>_referenced_by_collapsible"></span>
|
||||
<span class="fa fa-expand useCursorPointer" title="<?php echo __('Expand or Collapse');?>" role="button" tabindex="0" aria-label="<?php echo __('Expand or Collapse');?>" data-toggle="collapse" data-target="#Object_<?php echo h($object['uuid']); ?>_referenced_by_collapsible"></span>
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
<div id="Object_<?php echo $object['id']; ?>_referenced_by_collapsible" class="collapse">
|
||||
<div id="Object_<?php echo $object['uuid']; ?>_referenced_by_collapsible" class="collapse">
|
||||
<?php
|
||||
foreach ($object['referenced_by'] as $type => $reference):
|
||||
foreach ($reference as $ref):
|
||||
|
@ -21,9 +21,9 @@
|
|||
}
|
||||
?>
|
||||
|
||||
<a class="bold white useCursorPointer" onClick="pivotObjectReferences('<?php echo h($currentUri); ?>', '<?php echo $uuid; ?>')">
|
||||
<?php echo h($ref['relationship_type']) . ' ' . ucfirst($type) . ' ' . h($ref['id']) . h($output);?>
|
||||
</a>
|
||||
<span class="bold white useCursorPointer">
|
||||
<?php echo h($ref['relationship_type']) . ' ' . ucfirst($type) . ' ' . h($output);?>
|
||||
</span>
|
||||
<br />
|
||||
<?php
|
||||
endforeach;
|
||||
|
|
|
@ -39,13 +39,22 @@
|
|||
?>
|
||||
<div class="value_select_with_manual_entry">
|
||||
<?php
|
||||
$choice = '';
|
||||
if (!empty($element['value'])) {
|
||||
if (in_array($element['value'], $list)) {
|
||||
$choice = $element['value'];
|
||||
} else {
|
||||
$choice = 'Enter value manually';
|
||||
}
|
||||
}
|
||||
|
||||
echo $this->Form->input('Attribute.' . $k . '.value_select', array(
|
||||
'class' => 'Attribute_value_select',
|
||||
'style' => 'width:414px;margin-bottom:0px;',
|
||||
'options' => array_combine($list, $list),
|
||||
'label' => false,
|
||||
'div' => false,
|
||||
'value' => empty($element['value']) ? '' : $element['value']
|
||||
'value' => $choice
|
||||
));
|
||||
?>
|
||||
<br />
|
||||
|
@ -55,7 +64,7 @@
|
|||
'type' => 'textarea',
|
||||
'required' => false,
|
||||
'allowEmpty' => true,
|
||||
'style' => 'height:20px;width:400px;display:none;',
|
||||
'style' => 'height:20px;width:400px;' . (($choice == 'Enter value manually') ? '' : 'display:none;'),
|
||||
'label' => false,
|
||||
'div' => false,
|
||||
'value' => empty($element['value']) ? '' : $element['value']
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class="footer <?php echo $debugMode;?>">
|
||||
<div id="shortcutsListContainer">
|
||||
<div id="shortcutsListContainer" class="<?php echo $debugMode ? 'hidden': ''; ?>">
|
||||
<div id="triangle"></div>
|
||||
<div id="shortcutsList">
|
||||
<span> <?php echo __('Keyboard shortcuts for this page'); ?>:</span><br />
|
||||
|
@ -12,9 +12,9 @@
|
|||
<?php
|
||||
$gpgpath = ROOT.DS.APP_DIR.DS.WEBROOT_DIR.DS.'gpg.asc';
|
||||
if (file_exists($gpgpath) && is_file($gpgpath)){ ?>
|
||||
<span>Download: <?php echo $this->Html->link('PGP/GPG key', $this->webroot.'gpg.asc');?></span>
|
||||
<span>Download: <?php echo $this->Html->link('GnuPG key', $this->webroot.'gpg.asc');?></span>
|
||||
<?php } else { ?>
|
||||
<span>Could not locate the PGP/GPG public key.</span>
|
||||
<span>Could not locate the GnuPG public key.</span>
|
||||
<?php }
|
||||
if (Configure::read('SMIME.enabled')):
|
||||
$smimepath = ROOT.DS.APP_DIR.DS.WEBROOT_DIR.DS.'public_certificate.pem';
|
||||
|
|
|
@ -324,9 +324,9 @@
|
|||
</div><br />
|
||||
<span class="btn btn-inverse" role="button" tabindex="0" aria-label="<?php echo __('Check for orphaned attribute');?>" title="<?php echo __('Check for orphaned attributes');?>" style="padding-top:1px;padding-bottom:1px;" onClick="checkOrphanedAttributes();"><?php echo __('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><?php echo __('Verify PGP keys');?></h3>
|
||||
<p><?php echo __('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';"><?php echo __('Verify PGP keys');?></span> (<?php echo __('Check whether every user\'s PGP key is usable');?>)</li>
|
||||
<h3><?php echo __('Verify GnuPG keys');?></h3>
|
||||
<p><?php echo __('Run a full validation of all GnuPG 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';"><?php echo __('Verify GnuPG keys');?></span> (<?php echo __('Check whether every user\'s GnuPG key is usable');?>)</li>
|
||||
<h3><?php echo __('Database cleanup scripts');?></h3>
|
||||
<p><?php echo __('If you run into an issue with an infinite upgrade loop (when upgrading from version ~2.4.50) that ends up filling your database with upgrade script log messages, run the following script.');?></p>
|
||||
<?php echo $this->Form->postButton(__('Prune upgrade logs'), $baseurl . '/logs/pruneUpdateLogs', $options = array('class' => 'btn btn-primary', 'style' => 'padding-top:1px;padding-bottom:1px;')); ?>
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
if (isset($errors[$element_id])) $error = $errors[$element_id];
|
||||
if ($element['batch']) {
|
||||
if ($element['complex']) {
|
||||
$placeholder = __('Describe the %s using one or several (separated by a line-break) of the following types: %s' , h($element['name'], $types));
|
||||
$placeholder = __('Describe the %s using one or several (separated by a line-break) of the following types: %s' , h($element['name']), $types);
|
||||
} else {
|
||||
$placeholder = __('Describe the %s using one or several %s\s (separated by a line-break) ' , h($element['name']) , h($element['type']));
|
||||
}
|
||||
|
|
|
@ -25,5 +25,5 @@
|
|||
<script type="text/javascript">
|
||||
var i_<?php echo h($element_id); ?> = 0;
|
||||
var element_id_<?php echo h($element_id); ?> = <?php echo h($element_id); ?>;
|
||||
var batch_<?php echo h($element_id); ?> = "<?php echo ($element['batch'] ? '<?php echo __('yes');?>' : '<?php echo __('no');?>'); ?>";
|
||||
var batch_<?php echo h($element_id); ?> = "<?php echo ($element['batch'] ? 'yes': 'no'); ?>";
|
||||
</script>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<table style="width:100%;">
|
||||
<?php foreach ($imports as $k => $import): ?>
|
||||
<tr style="border-bottom:1px solid black;" class="templateChoiceButton">
|
||||
<td role="button" tabindex="0" aria-label="<?php echo __('Import %s', 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>
|
||||
<td class="<?php echo !empty($import['bold']) ? 'bold' : ''; ?>" role="button" tabindex="0" aria-label="<?php echo __('Import %s', 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>
|
||||
|
|
|
@ -143,8 +143,8 @@
|
|||
<?php
|
||||
if (!empty($item['types'])) {
|
||||
foreach ($item['types'] as $type) {
|
||||
echo '<option value="' . $type . '" ';
|
||||
echo ($type == $item['default_type'] ? 'selected="selected"' : '') . '>' . $type . '</option>';
|
||||
echo '<option value="' . h($type) . '" ';
|
||||
echo ($type == $item['default_type'] ? 'selected="selected"' : '') . '>' . h($type) . '</option>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
@ -167,17 +167,17 @@
|
|||
<select id = "<?php echo 'Attribute' . $k . 'SharingGroupId'; ?>" class='sgToggle' style='padding:0px;height:20px;margin-top:3px;margin-bottom:0px;'>
|
||||
<?php
|
||||
foreach ($sgs as $sgKey => $sgValue) {
|
||||
echo '<option value="' . $sgKey . '">' . $sgValue . '</option>';
|
||||
echo '<option value="' . h($sgKey) . '">' . h($sgValue) . '</option>';
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</div>
|
||||
</td>
|
||||
<td class="short">
|
||||
<input type="text" class="freetextCommentField" id="<?php echo 'Attribute' . $k . 'Comment'; ?>" style="padding:0px;height:20px;margin-bottom:0px;" placeholder="<?php echo h($importComment); ?>" <?php if (isset($item['comment']) && $item['comment'] !== false) echo 'value="' . $item['comment'] . '"'?>/>
|
||||
<input type="text" class="freetextCommentField" id="<?php echo 'Attribute' . $k . 'Comment'; ?>" style="padding:0px;height:20px;margin-bottom:0px;" placeholder="<?php echo h($importComment); ?>" <?php if (isset($item['comment']) && $item['comment'] !== false) echo 'value="' . h($item['comment']) . '"'?>/>
|
||||
</td>
|
||||
<td class="short">
|
||||
<input type="text" class="freetextTagField" id="<?php echo 'Attribute' . $k . 'Tags'; ?>" style="padding:0px;height:20px;margin-bottom:0px;"<?php if (isset($item['tags']) && $item['tags'] !== false) echo 'value="' . htmlspecialchars(implode(",",$item['tags'])) . '"'?>/>
|
||||
<input type="text" class="freetextTagField" id="<?php echo 'Attribute' . $k . 'Tags'; ?>" style="padding:0px;height:20px;margin-bottom:0px;"<?php if (isset($item['tags']) && $item['tags'] !== false) echo 'value="' . h(implode(",",$item['tags'])) . '"'?>/>
|
||||
</td>
|
||||
<td class="action short">
|
||||
<span class="icon-remove pointer" title="<?php echo __('Remove resolved attribute');?>" role="button" tabindex="0" aria-label="<?php echo __('Remove resolved attribute');?>" onClick="freetextRemoveRow('<?php echo $k; ?>', '<?php echo $event['Event']['id']; ?>');"></span>
|
||||
|
@ -206,7 +206,7 @@
|
|||
<?php
|
||||
foreach (array_keys($optionsRearranged) as $fromElement):
|
||||
?>
|
||||
<option><?php echo $fromElement; ?></option>
|
||||
<option><?php echo h($fromElement); ?></option>
|
||||
<?php
|
||||
endforeach;
|
||||
?>
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
<div class="events form">
|
||||
<?php
|
||||
echo $this->Form->create('Event', array('type' => 'file'));
|
||||
$stixVersion = 'STIX 1.1.1 XML';
|
||||
?>
|
||||
<fieldset>
|
||||
<legend><?php echo __('Import %s file', $stixVersion); ?></legend>
|
||||
<legend><?php echo __('Import %s file', $stix_version); ?></legend>
|
||||
<?php
|
||||
echo $this->Form->input('Event.stix', array(
|
||||
'label' => '<b>' . __('%s file', $stixVersion) . '</b>',
|
||||
'label' => '<b>' . __('%s file', $stix_version) . '</b>',
|
||||
'type' => 'file',
|
||||
));
|
||||
?>
|
||||
|
|
|
@ -164,6 +164,11 @@
|
|||
<dd class="green bold published <?php echo ($event['Event']['published'] == 0) ? 'hidden' : ''; ?>"><?php echo __('Yes');?></dd>
|
||||
<dt><?php echo __('#Attributes');?></dt>
|
||||
<dd><?php echo h($attribute_count);?></dd>
|
||||
<dt><?php echo __('Last change');?></dt>
|
||||
<dd>
|
||||
<?php echo date('Y/m/d h:i:s', $event['Event']['timestamp']);; ?>
|
||||
|
||||
</dd>
|
||||
<dt><?php echo __('Sightings');?></dt>
|
||||
<dd style="word-wrap: break-word;">
|
||||
<span id="eventSightingCount" class="bold sightingsCounter" data-toggle="popover" data-trigger="hover" data-content="<?php echo $sightingPopover; ?>"><?php echo count($event['Sighting']); ?></span>
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
<p><?php echo __('Add a new MISP feed source.');?></p>
|
||||
<?php
|
||||
echo $this->Form->input('enabled', array());
|
||||
echo $this->Form->input('caching_enabled', array());
|
||||
?>
|
||||
<div class="input clear"></div>
|
||||
<?php
|
||||
|
|
|
@ -5,70 +5,78 @@
|
|||
?>
|
||||
<div class="feed index">
|
||||
<h2><?php echo __('Feed overlap analysis matrix');?></h2>
|
||||
<div>
|
||||
<table class="table table-striped table-hover table-condensed" style="width:100px;">
|
||||
<tr>
|
||||
<th> </th>
|
||||
<?php
|
||||
<?php
|
||||
if (count($feeds) > 2):
|
||||
?>
|
||||
<div>
|
||||
<table class="table table-striped table-hover table-condensed" style="width:100px;">
|
||||
<tr>
|
||||
<th> </th>
|
||||
<?php
|
||||
foreach ($feeds as $item):
|
||||
$popover = '';
|
||||
foreach ($feedTemplate as $element):
|
||||
$popover .= '<span class=\'bold\'>' . Inflector::humanize($element) . '</span>: <span class=\'bold blue\'>' . h($item['Feed'][$element]) . '</span><br />';
|
||||
endforeach;
|
||||
?>
|
||||
<th>
|
||||
<div data-toggle="popover" data-content="<?php echo $popover; ?>" data-trigger="hover">
|
||||
<?php echo h($item['Feed']['id']); ?>
|
||||
</div>
|
||||
</th>
|
||||
<?php
|
||||
endforeach;
|
||||
?>
|
||||
</tr>
|
||||
<?php
|
||||
foreach ($feeds as $item):
|
||||
$popover = '';
|
||||
foreach ($feedTemplate as $element):
|
||||
$popover .= '<span class=\'bold\'>' . Inflector::humanize($element) . '</span>: <span class=\'bold blue\'>' . h($item['Feed'][$element]) . '</span><br />';
|
||||
endforeach;
|
||||
?>
|
||||
<th>
|
||||
<div data-toggle="popover" data-content="<?php echo $popover; ?>" data-trigger="hover">
|
||||
<?php echo h($item['Feed']['id']); ?>
|
||||
</div>
|
||||
</th>
|
||||
<tr>
|
||||
<td class="short">
|
||||
<div data-toggle="popover" data-content="<?php echo $popover;?>" data-trigger="hover">
|
||||
<?php echo h($item['Feed']['id']) . ' ' . h($item['Feed']['name']); ?>
|
||||
</div>
|
||||
</td>
|
||||
<?php
|
||||
foreach ($feeds as $item2):
|
||||
$percentage = -1;
|
||||
$class = 'bold';
|
||||
foreach ($item['Feed']['ComparedFeed'] as $k => $v):
|
||||
if ($item2['Feed']['id'] == $v['id']):
|
||||
$percentage = $v['overlap_percentage'];
|
||||
if ($percentage <= 5) $class .= ' green';
|
||||
else if ($percentage <= 50) $class .= ' orange';
|
||||
else $class .= ' red';
|
||||
break;
|
||||
endif;
|
||||
endforeach;
|
||||
$title = '';
|
||||
if ($percentage == 0) $popover = __('None or less than 1% of the data of %s is contained in %s (%s matching values)', $item['Feed']['name'], $item2['Feed']['name'], $v['overlap_count']);
|
||||
else if ($percentage > 0) $popover = __('%s\% of the data of %s is contained in %s (%s matching values)',$percentage, $item['Feed']['name'], $item2['Feed']['name'], $v['overlap_count'])
|
||||
?>
|
||||
<td class="<?php echo h($class); ?>">
|
||||
<div data-toggle="popover" data-content="<?php echo h($popover);?>" data-trigger="hover">
|
||||
<?php echo (($percentage == -1) ? '-' : h($percentage) . '%');?>
|
||||
</div>
|
||||
</td>
|
||||
<?php
|
||||
endforeach;
|
||||
?>
|
||||
</tr>
|
||||
<?php
|
||||
endforeach;
|
||||
?>
|
||||
</tr>
|
||||
<?php
|
||||
foreach ($feeds as $item):
|
||||
$popover = '';
|
||||
foreach ($feedTemplate as $element):
|
||||
$popover .= '<span class=\'bold\'>' . Inflector::humanize($element) . '</span>: <span class=\'bold blue\'>' . h($item['Feed'][$element]) . '</span><br />';
|
||||
endforeach;
|
||||
?>
|
||||
<tr>
|
||||
<td class="short">
|
||||
<div data-toggle="popover" data-content="<?php echo $popover;?>" data-trigger="hover">
|
||||
<?php echo h($item['Feed']['id']) . ' ' . h($item['Feed']['name']); ?>
|
||||
</div>
|
||||
</td>
|
||||
<?php
|
||||
foreach ($feeds as $item2):
|
||||
$percentage = -1;
|
||||
$class = 'bold';
|
||||
foreach ($item['Feed']['ComparedFeed'] as $k => $v):
|
||||
if ($item2['Feed']['id'] == $v['id']):
|
||||
$percentage = $v['overlap_percentage'];
|
||||
if ($percentage <= 5) $class .= ' green';
|
||||
else if ($percentage <= 50) $class .= ' orange';
|
||||
else $class .= ' red';
|
||||
break;
|
||||
endif;
|
||||
endforeach;
|
||||
$title = '';
|
||||
if ($percentage == 0) $popover = __('None or less than 1% of the data of %s is contained in %s (%s matching values)', $item['Feed']['name'], $item2['Feed']['name'], $v['overlap_count']);
|
||||
else if ($percentage > 0) $popover = __('%s\% of the data of %s is contained in %s (%s matching values)',$percentage, $item['Feed']['name'], $item2['Feed']['name'], $v['overlap_count'])
|
||||
?>
|
||||
<td class="<?php echo h($class); ?>">
|
||||
<div data-toggle="popover" data-content="<?php echo h($popover);?>" data-trigger="hover">
|
||||
<?php echo (($percentage == -1) ? '-' : h($percentage) . '%');?>
|
||||
</div>
|
||||
</td>
|
||||
<?php
|
||||
endforeach;
|
||||
?>
|
||||
</tr>
|
||||
<?php
|
||||
endforeach;
|
||||
?>
|
||||
</table>
|
||||
</div>
|
||||
</table>
|
||||
</div>
|
||||
<?php
|
||||
else:
|
||||
echo '<p class="red bold">Not enough feeds cached. Make sure you have at least 2 feeds that are cached and available.</p>';
|
||||
endif;
|
||||
?>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
<p><?php echo __('Edit a new MISP feed source.');?></p>
|
||||
<?php
|
||||
echo $this->Form->input('enabled', array());
|
||||
echo $this->Form->input('caching_enabled', array());
|
||||
?>
|
||||
<div class="input clear"></div>
|
||||
<?php
|
||||
|
|
|
@ -24,9 +24,10 @@
|
|||
</ul>
|
||||
</div>
|
||||
<div class="tabMenuFixedContainer" style="display:inline-block;">
|
||||
<span id="multi-delete-button" role="button" tabindex="0" aria-label="<?php echo __('Default feeds filter');?>" title="<?php echo __('Default feeds');?>" class=" hidden tabMenuFixed mass-select tabMenuFixedCenter tabMenuSides useCursorPointer <?php echo $scope == 'default' ? 'tabMenuActive' : ''; ?>" onClick="multiSelectToggleFeeds(1);"><?php echo __('Enable Selected');?></span>
|
||||
<span id="multi-delete-button" role="button" tabindex="0" aria-label="<?php echo __('Default feeds filter');?>" title="<?php echo __('Default feeds');?>" class=" hidden tabMenuFixed mass-select tabMenuFixedCenter tabMenuSides useCursorPointer <?php echo $scope == 'default' ? 'tabMenuActive' : ''; ?>" onClick="multiSelectToggleFeeds(0);"><?php echo __('Disable Selected');?></span>
|
||||
<span role="button" tabindex="0" aria-label="<?php echo __('Default feeds filter');?>" title="<?php echo __('Default feeds');?>" class="tabMenuFixed tabMenuFixedCenter tabMenuSides useCursorPointer <?php echo $scope == 'default' ? 'tabMenuActive' : ''; ?>" onclick="window.location='/feeds/index/scope:default'"><?php echo __('Default feeds');?></span>
|
||||
<span id="multi-delete-button" role="button" tabindex="0" aria-label="<?php echo __('Enable selected');?>" title="<?php echo __('Enable selected');?>" class=" hidden tabMenuFixed mass-select tabMenuFixedCenter tabMenuSides useCursorPointer <?php echo $scope == 'default' ? 'tabMenuActive' : ''; ?>" onClick="multiSelectToggleFeeds(1, 0);"><?php echo __('Enable Selected');?></span>
|
||||
<span id="multi-delete-button" role="button" tabindex="0" aria-label="<?php echo __('Disable selected');?>" title="<?php echo __('Disable selected');?>" class=" hidden tabMenuFixed mass-select tabMenuFixedCenter tabMenuSides useCursorPointer <?php echo $scope == 'default' ? 'tabMenuActive' : ''; ?>" onClick="multiSelectToggleFeeds(0, 0);"><?php echo __('Disable Selected');?></span>
|
||||
<span id="multi-delete-button" role="button" tabindex="0" aria-label="<?php echo __('Enable caching for selected');?>" title="<?php echo __('Enable caching for selected');?>" class=" hidden tabMenuFixed mass-select tabMenuFixedCenter tabMenuSides useCursorPointer <?php echo $scope == 'default' ? 'tabMenuActive' : ''; ?>" onClick="multiSelectToggleFeeds(1, 1);"><?php echo __('Enable Caching for Selected');?></span>
|
||||
<span id="multi-delete-button" role="button" tabindex="0" aria-label="<?php echo __('Disable caching for selected');?>" title="<?php echo __('Disable caching for selected');?>" class=" hidden tabMenuFixed mass-select tabMenuFixedCenter tabMenuSides useCursorPointer <?php echo $scope == 'default' ? 'tabMenuActive' : ''; ?>" onClick="multiSelectToggleFeeds(0, 1);"><?php echo __('Disable Caching for Selected');?></span> <span role="button" tabindex="0" aria-label="<?php echo __('Default feeds filter');?>" title="<?php echo __('Default feeds');?>" class="tabMenuFixed tabMenuFixedCenter tabMenuSides useCursorPointer <?php echo $scope == 'default' ? 'tabMenuActive' : ''; ?>" onclick="window.location='/feeds/index/scope:default'"><?php echo __('Default feeds');?></span>
|
||||
<span role="button" tabindex="0" aria-label="<?php echo __('Custom feeds filter');?>" title="<?php echo __('Custom feeds');?>" class="tabMenuFixed tabMenuFixedCenter tabMenuSides useCursorPointer <?php echo $scope == 'custom' ? 'tabMenuActive' : ''; ?> " onclick="window.location='/feeds/index/scope:custom'"><?php echo __('Custom Feeds');?></span>
|
||||
<span role="button" tabindex="0" aria-label="<?php echo __('All feeds');?>" title="<?php echo __('All feeds');?>" class="tabMenuFixed tabMenuFixedCenter tabMenuSides useCursorPointer <?php echo $scope == 'all' ? 'tabMenuActive' : ''; ?> " onclick="window.location='/feeds/index/scope:all'"><?php echo __('All Feeds');?></span>
|
||||
<span role="button" tabindex="0" aria-label="<?php echo __('Enabled feeds');?>" title="<?php echo __('Enabled feeds');?>" class="tabMenuFixed tabMenuFixedCenter tabMenuSides useCursorPointer <?php echo $scope == 'enabled' ? 'tabMenuActive' : ''; ?> " onclick="window.location='/feeds/index/scope:enabled'"><?php echo __('Enabled Feeds');?></span>
|
||||
|
@ -42,6 +43,7 @@
|
|||
<?php endif;?>
|
||||
<th><?php echo $this->Paginator->sort('id');?></th>
|
||||
<th><?php echo $this->Paginator->sort('enabled');?></th>
|
||||
<th><?php echo $this->Paginator->sort('caching_enabled');?></th>
|
||||
<th><?php echo $this->Paginator->sort('name');?></th>
|
||||
<th><?php echo $this->Paginator->sort('source_format', __('Feed Format'));?></th>
|
||||
<th><?php echo $this->Paginator->sort('provider');?></th>
|
||||
|
@ -105,6 +107,10 @@ foreach ($feeds as $item):
|
|||
>
|
||||
(<?php echo __('Rules');?>)
|
||||
</span>
|
||||
</td>
|
||||
<td class="short">
|
||||
<span class="<?php echo ($item['Feed']['caching_enabled'] ? 'icon-ok' : 'icon-remove'); ?>"></span>
|
||||
</td>
|
||||
<td>
|
||||
<?php
|
||||
echo h($item['Feed']['name']);
|
||||
|
@ -190,7 +196,7 @@ foreach ($feeds as $item):
|
|||
else:
|
||||
echo __('Not cached');
|
||||
endif;
|
||||
if ($item['Feed']['enabled']):
|
||||
if ($item['Feed']['caching_enabled']):
|
||||
?>
|
||||
<a href="<?php echo $baseurl;?>/feeds/cacheFeeds/<?php echo h($item['Feed']['id']); ?>" title="Cache feed"><span class="icon-download-alt"></span></a>
|
||||
<?php
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<?php echo $this->Html->charset(); ?>
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>
|
||||
<?php echo $title_for_layout, ' - '. h(Configure::read('MISP.title_text') ? Configure::read('MISP.title_text') : 'MISP'); ?>
|
||||
</title>
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
<div class="index">
|
||||
<h3><?php echo __('Stolen attribute validation');?></h3>
|
||||
<ul>
|
||||
<?php
|
||||
if (empty($issues)) {
|
||||
echo '<span class="blue bold">' . __('Nothing to see here, move along.') . '</span>';
|
||||
} else {
|
||||
foreach ($issues as $aid => $eids) {
|
||||
echo '<div>' . __('Attribute (%s) associated to events: %s', $aid, implode(', ', $eids)) . '</div>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
echo $this->element('side_menu', array('menuList' => 'admin', 'menuItem' => 'adminTools'));
|
||||
?>
|
|
@ -67,8 +67,7 @@
|
|||
'required' => false,
|
||||
'allowEmpty' => true,
|
||||
'label' => false,
|
||||
'div' => false,
|
||||
'value' => empty($template['Object']['comment']) ? '' : $template['Object']['comment']
|
||||
'div' => false
|
||||
));
|
||||
?>
|
||||
</dd>
|
||||
|
|
|
@ -14,7 +14,7 @@ if (!$isSiteAdmin) exit();
|
|||
<li><?php echo $this->Form->postLink(__('Reset the attribute counts'), $baseurl . '/events/generateCount');?> (<?php echo __('Events need to have no validation issues');?>)</li>
|
||||
<li><?php echo $this->Form->postLink('Recorrelate attributes', $baseurl . '/attributes/generateCorrelation');?></li>
|
||||
<li><?php echo $this->Form->postLink('Recorrelate proposals', $baseurl . '/shadow_attributes/generateCorrelation');?></li>
|
||||
<li><a href="<?php echo $baseurl;?>/users/verifyGPG"><?php echo __('Verify PGP keys');?></a> (<?php echo __('Check whether every user\'s PGP key is usable');?>)</li>
|
||||
<li><a href="<?php echo $baseurl;?>/users/verifyGPG"><?php echo __('Verify GnuPG keys');?></a> (<?php echo __('Check whether every user\'s GnuPG key is usable');?>)</li>
|
||||
<li><a href="<?php echo $baseurl;?>/users/verifyCertificate"><?php echo __('Verify Certificates');?></a> (<?php echo __('Check whether every user\'s certificate is usable');?>)</li>
|
||||
<li><?php echo $this->Form->postLink(__('Extend Organization length'), $baseurl . '/servers/updateDatabase/extendServerOrganizationLength');?> (<?php echo __('Hotfix 2.3.57: Increase the max length of the organization field when adding a new server connection.');?>)</li>
|
||||
<li><?php echo $this->Form->postLink('Convert log fields to text', $baseurl . '/servers/updateDatabase/convertLogFieldsToText');?> (<?php echo __('Hotfix 2.3.78: Some of the log fields that were varchar(255) ended up truncating the data. This function will change them to "text"');?>)</li>
|
||||
|
|
|
@ -31,11 +31,11 @@
|
|||
<ul>
|
||||
<li><b><?php echo __('Overview');?></b>: <?php echo __('General overview of the current state of your MISP installation');?></li>
|
||||
<li><b><?php echo __('MISP settings');?></b>: <?php echo __('Basic MISP settings. This includes the way MISP handles the default settings for distribution settings, whether background jobs are enabled, etc');?></li>
|
||||
<li><b><?php echo __('GnuPG settings');?></b>: <?php echo __('GPG related settings.');?></li>
|
||||
<li><b><?php echo __('GnuPG settings');?></b>: <?php echo __('GnuPG related settings.');?></li>
|
||||
<li><b><?php echo __('Proxy settings');?></b>: <?php echo __('HTTP proxy related settings.');?></li>
|
||||
<li><b><?php echo __('Security settings');?></b>: <?php echo __('Settings controlling the brute-force protection and the application\'s salt key.');?></li>
|
||||
<li><b><?php echo __('Misc settings');?></b>: <?php echo __('You change the debug options here, but make sure that debug is always disabled on a production system.');?></li>
|
||||
<li><b><?php echo __('Diagnostics');?></b>: <?php echo __('The diagnostics tool checks if all directories that MISP uses to store data are writeable by the apache user. Also, the tool checks whether the STIX libraries and GPG are working as intended.');?></li>
|
||||
<li><b><?php echo __('Diagnostics');?></b>: <?php echo __('The diagnostics tool checks if all directories that MISP uses to store data are writeable by the apache user. Also, the tool checks whether the STIX libraries and GnuPG are working as intended.');?></li>
|
||||
<li><b><?php echo __('Workers');?></b>: <?php echo __('Shows the background workers (if enabled) and shows a warning if they are not running. Admins can also restart the workers here.');?></li>
|
||||
<li><b><?php echo __('Download report');?></b>: <?php echo __('Download a report in JSON format, compiled of all of the settings visible in the tool.');?></li>
|
||||
</ul>
|
||||
|
@ -93,7 +93,7 @@
|
|||
<li><b><?php echo __('Receive alerts from "contact reporter" requests');?>:</b> <?php echo __('This option will subscribe the new user to e-mails that are generated when another user tries to get in touch with an event\'s reporting organisation that matches that of the new user.');?><br /></li>
|
||||
<li><b><?php echo __('Authkey');?>:</b> <?php echo __('This is assigned automatically and is the unique authentication key of the user (he/she will be able to reset this and receive a new key). It is used for exports and for connecting one server to another, but it requires the user to be assigned to a role that has auth permission enabled.');?><br /></li>
|
||||
<li><b><?php echo __('NIDS Sid');?>:</b> <?php echo __('Nids ID, not yet implemented.');?><br /></li>
|
||||
<li><b><?php echo __('Gpgkey');?>:</b> <?php echo __('The key used for encrypting e-mails sent through the system.');?> <br /></li>
|
||||
<li><b><?php echo __('GnuPGkey');?>:</b> <?php echo __('The key used for encrypting e-mails sent through the system.');?> <br /></li>
|
||||
</ul>
|
||||
<h3><?php echo __('Listing all users');?>:</h3>
|
||||
<?php echo __('To list all current users of the system, just click on List Users under the administration menu to the left. A view will be loaded with a list of all users and the following columns of information');?>:<br />
|
||||
|
@ -103,8 +103,8 @@
|
|||
<li><b>Org:</b> <?php echo __('The organisation that the user belongs to.');?><br /></li>
|
||||
<li><b><?php echo __('Email');?>:</b> <?php echo __('The e-mail address (and login name) of the user.');?><br /></li>
|
||||
<li><b><?php echo __('Autoalert');?>:</b> <?php echo __('Shows whether the user has subscribed to auto-alerts and is always receiving the mass-emails regarding newly published events that he/she is eligible for.');?><br /></li>
|
||||
<li><b>ontactalert:</b> <?php echo __('Shows whether the user has the subscription to contact reporter e-mails directed at his/her organisation turned on or off.');?><br /></li>
|
||||
<li><b>Gpgkey:</b> <?php echo __('Shows whether the user has entered a Gpgkey yet.');?><br /></li>
|
||||
<li><b>Contactalert:</b> <?php echo __('Shows whether the user has the subscription to contact reporter e-mails directed at his/her organisation turned on or off.');?><br /></li>
|
||||
<li><b>GnuPGkey:</b> <?php echo __('Shows whether the user has entered a GnuPGkey yet.');?><br /></li>
|
||||
<li><b>Nids Sid:</b> <?php echo __('Shows the currently assigned NIDS ID.');?><br /></li>
|
||||
<li><b><?php echo __('Termsaccepted');?>:</b> <?php echo __('This flag indicates whether the user has accepted the terms of use or not.');?><br /></li>
|
||||
<li><b><?php echo __('Newsread');?>:</b> <?php echo __('The last point in time when the user has looked at the news section of the system.');?><br /></li>
|
||||
|
@ -124,19 +124,19 @@
|
|||
<li><b><?php echo __('NIDS Sid');?>:</b> <?php echo __('Nids ID, not yet implemented.');?><br /></li>
|
||||
<li><b><?php echo __('Termsaccepted');?>:</b> <?php echo __('Indicates whether the user has accepted the terms of use already or not.');?><br /></li>
|
||||
<li><b><?php echo __('Change Password');?>:</b> <?php echo __('Setting this flag will require the user to change password after the next login.');?><br /></li>
|
||||
<li><b><?php echo __('Gpgkey');?>:</b> <?php echo __('The key used for encrypting e-mails sent through the system.');?> <br /></li>
|
||||
<li><b><?php echo __('GnuPGkey');?>:</b> <?php echo __('The key used for encrypting e-mails sent through the system.');?> <br /></li>
|
||||
</ul>
|
||||
<h3><?php echo __('Contacting a user');?>:</h3>
|
||||
<?php echo __('Site admins can use the "Contact users" feature to send all or an individual user an e-mail. Users that have a PGP key set will receive their e-mails encrypted. When clicking this button on the left, you\'ll be presented with a form that allows you to specify the type of the e-mail, who it should reach and what the content is using the following options');?>:<br />
|
||||
<?php echo __('Site admins can use the "Contact users" feature to send all or an individual user an e-mail. Users that have a GnuPG key set will receive their e-mails encrypted. When clicking this button on the left, you\'ll be presented with a form that allows you to specify the type of the e-mail, who it should reach and what the content is using the following options');?>:<br />
|
||||
<img src="<?php echo $baseurl;?>/img/doc/contact.png" alt = "<?php echo __('Contact');?>" title = "<?php echo __('Contact your users here.');?>"/><br />
|
||||
<ul>
|
||||
<li><b><?php echo __('Action');?>:</b> <?php echo __('This defines the type of the e-mail, which can be a custom message or a password reset. Password resets automatically include a new temporary password at the bottom of the message and will automatically change the user\'s password accordingly.');?><br /></li>
|
||||
<li><b><?php echo __('Recipient');?>:</b> <?php echo __('The recipient toggle lets you contact all your users, a single user (which creates a second drop-down list with all the e-mail addresses of the users) and potential future users (which opens up a text field for the e-mail address and a text area field for a PGP public key).');?><br /></li>
|
||||
<li><b><?php echo __('Recipient');?>:</b> <?php echo __('The recipient toggle lets you contact all your users, a single user (which creates a second drop-down list with all the e-mail addresses of the users) and potential future users (which opens up a text field for the e-mail address and a text area field for a GnuPG public key).');?><br /></li>
|
||||
<li><b><?php echo __('Subject');?>:</b> <?php echo __('In the case of a custom e-mail, you can enter a subject line here.');?><br /></li>
|
||||
<li><b><?php echo __('Subject');?>:</b> <?php echo __('In the case of a custom e-mail, you can enter a subject line here.');?><br /></li>
|
||||
<li><b><?php echo __('Custom message checkbox');?>:</b> <?php echo __('This is available for password resets, you can either write your own message (which will be appended with a temporary key and the signature), or let the system generate one automatically.');?><br /></li>
|
||||
</ul>
|
||||
<?php echo __('Keep in mind that all e-mails sent through this system will, in addition to your own message, will be signed in the name of the instance\'s host organisation\'s support team, will include the e-mail address of the instance\'s support (if the contact field is set in the bootstrap file), and will include the instance\'s PGP signature for users that have a PGP key set (and thus are eligible for an encrypted e-mail).');?>
|
||||
<?php echo __('Keep in mind that all e-mails sent through this system will, in addition to your own message, will be signed in the name of the instance\'s host organisation\'s support team, will include the e-mail address of the instance\'s support (if the contact field is set in the bootstrap file), and will include the instance\'s GnuPG signature for users that have a GnuPG key set (and thus are eligible for an encrypted e-mail).');?>
|
||||
<hr />
|
||||
<h2><a id="roles"></a><?php echo __('Managing the roles');?></h2>
|
||||
<?php echo __('Privileges are assigned to users by assigning them to rule groups, which use one of four options determining what they can do with events and four additional privilege elevating settings. The four options for event manipulation are: Read Only, Manage My Own Events, Manage Organisation Events, Manage & Publish Organisation Events. The extra privileges are admin, sync, authentication key usage and audit permission');?><br />
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
<li><b><?php echo __('Accepting the Terms of use');?>:</b> <?php echo __('The terms of use are shown immediately after logging in for the first time, make sure to read through this page before clicking "Accept Terms" at the bottom of the page.');?><br /><br /></li>
|
||||
<li><b><?php echo __('Changing the password');?>:</b> <?php echo __('After accepting the ToU, you\'ll be prompted to change your password, but keep in mind that it has to be at least 6 characters long, it has to include at least one upper-case and one lower-case character in addition to a digit or a special character. Enter the same password into the confirm password field, before clicking submit to finalise the change.');?><br /><br />
|
||||
<p><img src="<?php echo $baseurl;?>/img/doc/password.png" alt = "" title="<?php echo __('Changing the password');?>"></p><br /></li>
|
||||
<li><b><?php echo __('Setting up the GPG Key');?>:</b> <?php echo __('In order for the system to be able to encrypt the messages that you send through it, it needs to know your GPG key. Navigate to the Edit profile view (My Profile on the left -> Edit profile in the top right corner). Paste the key into the Gpgkey field and click submit.');?><br /><br /></li>
|
||||
<li><b><?php echo __('Setting up the GnuPG Key');?>:</b> <?php echo __('In order for the system to be able to encrypt the messages that you send through it, it needs to know your GnuPG key. Navigate to the Edit profile view (My Profile on the left -> Edit profile in the top right corner). Paste the key into the GnuPG field and click submit.');?><br /><br /></li>
|
||||
<li><b><?php echo __('Subscribing to Auto-alerts');?>:</b> <?php echo __('Turning auto-alerts on will allow the system to send you e-mail notifications about any new public events entered into the system by other users and private events added by members of your organisation. To turn this on, navigate to the Edit profile view (My profile on the left navigation menu -> Edit profile in the top right corner). Tick the auto-alert checkbox and click submit to enable this feature.');?><br /><br />
|
||||
<p><img src="<?php echo $baseurl;?>/img/doc/alerts.png" alt = "" title="<?php echo __('Use these checkboxes to subscribe to auto-alerts and contact reporter e-mails.');?>"></p><br /></li>
|
||||
<li><b><?php echo __('Subscribing to e-mails sent via the "Contact Reporter" functionality');?>:</b> <?php echo __('This feature is turned on right below the autoalerts and will allow you to receive e-mails addressed to your organisation whenever a user tries to ask about an event that was posted by a user of your organisation. Keep in mind that you can still be addressed by such a request even when this setting is turned off, if someone tries to contact you as the event creator directly or your organisation for an event that you personally have created then you will be notified.');?><br /><br />
|
||||
|
@ -41,7 +41,7 @@
|
|||
<li><b><?php echo __('Changing the password');?>:</b> <?php echo __('As a next step, change the password provided by your administrator to something of your own choosing. Click on My profile on the left navigation menu, under Global Actions, which will bring up the User view. Click on Edit User on the left navigation menu or Edit Profile in the top right corner. This next screen, allows you to edit your details, including your password, by filling out the password field. Keep in mind that the password has to be at least 6 characters long, has to include at least one upper-case and one lower-case character in addition to a digit or a special character. Enter the same password into the confirm password field, before clicking submit to finalise the change.');?><br /><br /></li>
|
||||
<li><b><?php echo __('Subscribing to Auto-alerts');?>:</b> <?php echo __('Turning auto-alerts on will allow the system to send you e-mail notifications about any new public events entered into the system by other users and private events added by members of your organisation. To turn this on, navigate to the Edit profile view (My profile on the left navigation menu -> Edit profile in the top right corner). Tick the auto-alert checkbox and click submit to enable this feature.');?><br /><br /></li>
|
||||
<li><b><?php echo __('Subscribing to e-mails sent via the "Contact Reporter" functionality');?>:</b> <?php echo __('Turning this feature on will allow you to receive e-mails addressed to your organisation whenever a user tries to ask about an event that was posted by a user of your organisation. Keep in mind that you can still be addressed by such a request even when this setting is turned off, if someone tries to contact the person that reported an event that you yourself have created.');?><br /><br /></li>
|
||||
<li><b><?php echo __('Setting up the GPG Key');?>:</b> <?php echo __('In order for the system to be able to encrypt the messages that you send through it, it needs to know your GPG key. You can acquire this by clicking on the PGP/GPG key link at the bottom left of the screen. Copy the entirety of the key and navigate to the Edit profile view (My Profile on the left -> Edit profile in the top right corner). Paste the key into the Gpgkey field and click submit.');?><br /><br /></li>
|
||||
<li><b><?php echo __('Setting up the GnuPG Key');?>:</b> <?php echo __('In order for the system to be able to encrypt the messages that you send through it, it needs to know your GnuPG key. You can acquire this by clicking on the GnuPG key link at the bottom left of the screen. Copy the entirety of the key and navigate to the Edit profile view (My Profile on the left -> Edit profile in the top right corner). Paste the key into the GnuPG field and click submit.');?><br /><br /></li>
|
||||
<li><b><?php echo __('Requesting a new authentication key');?>:</b> <?php echo __('It is possible to make the system generate a new authentication key for you (for example if your previous one gets compromised. This can be accessed by clicking on the My Profile button and then clicking the reset key next to the currently active authentication code. The old key will become invalid when the new one is generated.');?><br /><br />
|
||||
<p><img src="<?php echo $baseurl;?>/img/doc/reset.png" alt = "" title="<?php echo __('Clicking on reset will generate a new key for you and invalidate the old one, blocking it from being used.');?>"></p></li></ul>
|
||||
<hr />
|
||||
|
|
|
@ -2,9 +2,23 @@
|
|||
<?php echo $this->Form->create('Role'); ?>
|
||||
<fieldset>
|
||||
<legend><?php echo __('Add Role');?></legend>
|
||||
<?php
|
||||
echo $this->Form->input('name');?>
|
||||
<?php echo $this->Form->input('permission', array('type' => 'select', 'options' => $options), array('value' => '3'));?>
|
||||
<?php
|
||||
echo $this->Form->input('restricted_to_site_admin', array(
|
||||
'type' => 'checkbox',
|
||||
'class' => 'checkbox readonlyenabled',
|
||||
'label' => __('Restrict to site admins')
|
||||
));
|
||||
?>
|
||||
<div class = 'input clear'></div>
|
||||
<?php
|
||||
echo $this->Form->input('name');
|
||||
echo $this->Form->input('permission', array('type' => 'select', 'options' => $options), array('value' => '3'));
|
||||
?>
|
||||
<div class = 'input clear'></div>
|
||||
<?php
|
||||
echo $this->Form->input('memory_limit', array('label' => __('Memory limit') . ' (' . h($default_memory_limit) . ')'));
|
||||
echo $this->Form->input('max_execution_time', array('label' => __('Maximum execution time') . ' (' . h($default_max_execution_time) . ')'));
|
||||
?>
|
||||
<div class = 'input clear'></div>
|
||||
<?php
|
||||
$counter = 1;
|
||||
|
|
|
@ -2,10 +2,23 @@
|
|||
<?php echo $this->Form->create('Role');?>
|
||||
<fieldset>
|
||||
<legend><?php echo __('Edit Role'); ?></legend>
|
||||
<?php
|
||||
echo $this->Form->input('restricted_to_site_admin', array(
|
||||
'type' => 'checkbox',
|
||||
'class' => 'checkbox readonlyenabled',
|
||||
'label' => __('Restrict to site admins')
|
||||
));
|
||||
?>
|
||||
<div class = 'input clear'></div>
|
||||
<?php
|
||||
echo $this->Form->input('name');?>
|
||||
<?php echo $this->Form->input('permission', array('label' => __('Permissions'), 'type' => 'select', 'options' => $options), array('value' => '3'));?>
|
||||
<div class = 'input clear'></div>
|
||||
<?php
|
||||
echo $this->Form->input('memory_limit', array('label' => __('Memory limit') . ' (' . h($default_memory_limit) . ')'));
|
||||
echo $this->Form->input('max_execution_time', array('label' => __('Maximum execution time') . ' (' . h($default_max_execution_time) . ')'));
|
||||
?>
|
||||
<div class = 'input clear'></div>
|
||||
<?php
|
||||
$counter = 1;
|
||||
foreach ($permFlags as $k => $flag):
|
||||
|
|
|
@ -21,14 +21,17 @@
|
|||
<th><?php echo $this->Paginator->sort('id');?></th>
|
||||
<th><?php echo __('Default');?></th>
|
||||
<th><?php echo $this->Paginator->sort('name');?></th>
|
||||
<th><?php echo $this->Paginator->sort('restricted_to_site_admin');?></th>
|
||||
<th><?php echo $this->Paginator->sort('permission', 'Permission');?></th>
|
||||
<?php
|
||||
foreach ($permFlags as $k => $flags):
|
||||
?>
|
||||
<th><?php echo $this->Paginator->sort($k, $flags['text']);?></th>
|
||||
<th title="<?php echo h($flags['title']); ?>"><?php echo $this->Paginator->sort($k, $flags['text']);?></th>
|
||||
<?php
|
||||
endforeach;
|
||||
?>
|
||||
<th><?php echo $this->Paginator->sort('memory_limit');?></th>
|
||||
<th><?php echo $this->Paginator->sort('max_execution_time');?></th>
|
||||
<th class="actions"><?php echo __('Actions');?></th>
|
||||
</tr><?php
|
||||
foreach ($list as $item): ?>
|
||||
|
@ -36,10 +39,29 @@ foreach ($list as $item): ?>
|
|||
<td><?php echo $this->Html->link(h($item['Role']['id']), array('admin' => true, 'action' => 'edit', $item['Role']['id'])); ?> </td>
|
||||
<td class="short" style="text-align:center;width:20px;"><input class="servers_default_role_checkbox" type="checkbox" data-id="<?php echo h($item['Role']['id']); ?>" <?php if ($default_role_id && $default_role_id == $item['Role']['id']) echo 'checked'; ?>></td>
|
||||
<td><?php echo h($item['Role']['name']); ?> </td>
|
||||
<td class="short"><span class="<?php if ($item['Role']['restricted_to_site_admin']) echo 'icon-ok'; ?>"></span> </td>
|
||||
<td><?php echo h($options[$item['Role']['permission']]); ?> </td>
|
||||
<?php foreach ($permFlags as $k => $flags): ?>
|
||||
<td class="short"><span class="<?php if ($item['Role'][$k]) echo 'icon-ok'; ?>"></span> </td>
|
||||
<?php endforeach; ?>
|
||||
<td class="short">
|
||||
<?php
|
||||
if (empty($item['Role']['memory_limit'])) {
|
||||
echo h($default_memory_limit);
|
||||
} else {
|
||||
echo h($item['Role']['memory_limit']);
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
<td class="short">
|
||||
<?php
|
||||
if (empty($item['Role']['max_execution_time'])) {
|
||||
echo h($default_max_execution_time);
|
||||
} else {
|
||||
echo h($item['Role']['max_execution_time']);
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
<td class="short action-links">
|
||||
<?php echo $this->Html->link('', array('admin' => true, 'action' => 'edit', $item['Role']['id']), array('class' => 'icon-edit', 'title' => 'Edit')); ?>
|
||||
<?php echo $this->Form->postLink('', array('admin' => true, 'action' => 'delete', $item['Role']['id']), array('class' => 'icon-trash', 'title' => __('Delete')), __('Are you sure you want to delete %s?', $item['Role']['name'])); ?>
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
<?php
|
||||
foreach ($permFlags as $k => $flags):
|
||||
?>
|
||||
<th><?php echo $this->Paginator->sort($k, $flags['text']);?></th>
|
||||
<th title="<?php echo h($flags['title']); ?>"><?php echo $this->Paginator->sort($k, $flags['text']);?></th>
|
||||
<?php
|
||||
endforeach;
|
||||
?>
|
||||
|
|
|
@ -67,9 +67,9 @@
|
|||
?>
|
||||
</div>
|
||||
<?php
|
||||
echo $this->Form->input('gpgkey', array('label' => __('GPG key'), 'div' => 'clear', 'class' => 'input-xxlarge', 'placeholder' => __('Paste the user\'s PGP key here or try to retrieve it from the MIT key server by clicking on "Fetch GPG key" below.')));
|
||||
echo $this->Form->input('gpgkey', array('label' => __('GnuPG key'), 'div' => 'clear', 'class' => 'input-xxlarge', 'placeholder' => __('Paste the user\'s GnuPG key here or try to retrieve it from the MIT key server by clicking on "Fetch GnuPG key" below.')));
|
||||
?>
|
||||
<div class="clear"><span role="button" tabindex="0" aria-label="<?php echo __('Fetch the user\'s PGP key');?>" onClick="lookupPGPKey('UserEmail');" class="btn btn-inverse" style="margin-bottom:10px;"><?php echo __('Fetch GPG key');?></span></div>
|
||||
<div class="clear"><span role="button" tabindex="0" aria-label="<?php echo __('Fetch the user\'s GnuPG key');?>" onClick="lookupPGPKey('UserEmail');" class="btn btn-inverse" style="margin-bottom:10px;"><?php echo __('Fetch GnuPG key');?></span></div>
|
||||
<?php
|
||||
if (Configure::read('SMIME.enabled')) echo $this->Form->input('certif_public', array('label' => __('SMIME key'), 'div' => 'clear', 'class' => 'input-xxlarge', 'placeholder' => __('Paste the user\'s SMIME public key in PEM format here.')));
|
||||
echo $this->Form->input('autoalert', array('label' => __('Receive alerts when events are published'), 'type' => 'checkbox', 'checked' => true));
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
$passwordPopover = '<span class=\"blue bold\">Length</span>: ' . h($length) . '<br />';
|
||||
$passwordPopover .= '<span class=\"blue bold\">Complexity</span>: ' . h($complexity);
|
||||
echo $this->Form->input('password', array(
|
||||
'label' => __('Password') . '<span id = "PasswordPopover" class="icon-info-sign" ></span>'
|
||||
'label' => __('Password') . ' <span id = "PasswordPopover" class="icon-info-sign" ></span>'
|
||||
));
|
||||
echo $this->Form->input('confirm_password', array('type' => 'password', 'div' => array('class' => 'input password required')));
|
||||
?>
|
||||
|
@ -61,9 +61,9 @@
|
|||
?>
|
||||
</div>
|
||||
<?php
|
||||
echo $this->Form->input('gpgkey', array('label' => __('GPG key'), 'div' => 'clear', 'class' => 'input-xxlarge', 'placeholder' => __('Paste the user\'s PGP key here or try to retrieve it from the MIT key server by clicking on "Fetch GPG key" below.')));
|
||||
echo $this->Form->input('gpgkey', array('label' => __('GnuPG key'), 'div' => 'clear', 'class' => 'input-xxlarge', 'placeholder' => __('Paste the user\'s GnuPG key here or try to retrieve it from the MIT key server by clicking on "Fetch GnuPG key" below.')));
|
||||
?>
|
||||
<div class="clear"><span role="button" tabindex="0" aria-label="<?php echo __('Fetch the user\'s PGP key');?>" onClick="lookupPGPKey('UserEmail');" class="btn btn-inverse" style="margin-bottom:10px;"><?php echo __('Fetch GPG key');?></span></div>
|
||||
<div class="clear"><span role="button" tabindex="0" aria-label="<?php echo __('Fetch the user\'s GnuPG key');?>" onClick="lookupPGPKey('UserEmail');" class="btn btn-inverse" style="margin-bottom:10px;"><?php echo __('Fetch GnuPG key');?></span></div>
|
||||
<?php
|
||||
if (Configure::read('SMIME.enabled')) echo $this->Form->input('certif_public', array('label' => __('SMIME key'), 'div' => 'clear', 'class' => 'input-xxlarge', 'placeholder' => __('Paste the user\'s SMIME public key in PEM format here.')));
|
||||
echo $this->Form->input('termsaccepted', array('label' => __('Terms accepted')));
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<li><?php echo __('When adding a new user to the system, or when you want to manually reset the password for a user, just use the "Send temporary password" setting.');?></li>
|
||||
<li><?php echo __('After selecting the action, choose who the target of the e-mails should be (all users, a single user or a user not yet in the system).');?></li>
|
||||
<li><?php echo __('You can then specify (if eligible) what the e-mail address of the target is (for existing users you can choose from a dropdown menu).');?></li>
|
||||
<li><?php echo __('In the case of a new user, you can specify the future user\'s gpg key, to send his/her new key in an encrypted e-mail.');?></li>
|
||||
<li><?php echo __('In the case of a new user, you can specify the future user\'s GnuPG key, to send his/her new key in an encrypted e-mail.');?></li>
|
||||
<li><?php echo __('The system will automatically generate a message for you, but it is also possible to write a custom message if you tick the check-box,
|
||||
but don\'t worry about assigning a temporary password manually, the system will do that for you, right after your custom message.');?></li>
|
||||
</ul>
|
||||
|
|
|
@ -64,20 +64,20 @@ $buttonModifyStatus = $mayModify ? 'button_on':'button_off';
|
|||
?>
|
||||
|
||||
</dd>
|
||||
<dt><?php echo __('PGP key'); ?></dt>
|
||||
<dt><?php echo __('GnuPG key'); ?></dt>
|
||||
<dd class="quickSelect <?php echo $user['User']['gpgkey'] ? 'green' : 'bold red'; ?>">
|
||||
<?php echo $user['User']['gpgkey'] ? nl2br(h($user['User']['gpgkey'])) : "N/A"; ?>
|
||||
</dd>
|
||||
<?php
|
||||
if (!empty($user['User']['gpgkey'])):
|
||||
?>
|
||||
<dt><?php echo __('PGP fingerprint');?></dt>
|
||||
<dt><?php echo __('GnuPG fingerprint');?></dt>
|
||||
<dd class="quickSelect bold <?php echo $user['User']['fingerprint'] ? 'green': 'red'; ?>">
|
||||
<?php
|
||||
echo $user['User']['fingerprint'] ? chunk_split(h($user['User']['fingerprint']), 4, ' ') : 'N/A';
|
||||
?>
|
||||
</dd>
|
||||
<dt><?php echo __('PGP status');?></dt>
|
||||
<dt><?php echo __('GnuPG status');?></dt>
|
||||
<dd class="bold <?php echo (empty($user['User']['pgp_status']) || $user['User']['pgp_status'] != __('OK')) ? 'red': 'green'; ?>">
|
||||
<?php
|
||||
echo !empty($user['User']['pgp_status']) ? h($user['User']['pgp_status']) : __('N/A');
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
</tr>
|
||||
<?php foreach ($keys as $k => $key): ?>
|
||||
<tr style="border-bottom:1px solid black;" class="templateChoiceButton">
|
||||
<td role="button" tabindex="0" aria-label="<?php echo __('Select pgp key');?>" style="padding-left:10px; text-align:left;width:20%;" title="<?php echo h($key['fingerprint']); ?>" onClick="pgpChoiceSelect('<?php echo h($key['uri']); ?>')"><?php echo h($key['key_id']); ?></td>
|
||||
<td role="button" tabindex="0" aria-label="<?php echo __('Select GnuPG key');?>" style="padding-left:10px; text-align:left;width:20%;" title="<?php echo h($key['fingerprint']); ?>" onClick="pgpChoiceSelect('<?php echo h($key['uri']); ?>')"><?php echo h($key['key_id']); ?></td>
|
||||
<td style="text-align:left;width:20%;" title="<?php echo h($key['fingerprint']); ?>" onClick="pgpChoiceSelect('<?php echo h($key['uri']); ?>')"><?php echo h($key['date']); ?></td>
|
||||
<td style="padding-right:10px; text-align:left;width:60%;" title="<?php echo h($key['fingerprint']); ?>" onClick="pgpChoiceSelect('<?php echo h($key['uri']); ?>')">
|
||||
<span class="bold">
|
||||
|
|
|
@ -24,6 +24,16 @@ echo $this->Form->button(__('Submit'), array('class' => 'btn btn-primary'));
|
|||
echo $this->Form->end();
|
||||
?>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$('#PasswordPopover').popover("destroy").popover({
|
||||
placement: 'right',
|
||||
html: 'true',
|
||||
trigger: 'hover',
|
||||
content: '<?php echo $passwordPopover; ?>'
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
echo $this->element('side_menu', array('menuList' => 'globalActions', 'menuItem' => 'news'));
|
||||
?>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class="composites index">
|
||||
<h2><?php echo __('Failed GPGs?');?></h2><?php
|
||||
<h2><?php echo __('Failed GnuPGs?');?></h2><?php
|
||||
if (0 == count($fails)):?>
|
||||
<p><?php echo __('No failed composites');?></p>
|
||||
<?php else:?>
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
?>
|
||||
<div class="input clear"></div>
|
||||
<?php
|
||||
echo $this->Form->input('gpgkey', array('label' => 'GPG key', 'div' => 'clear', 'class' => 'input-xxlarge'));
|
||||
echo $this->Form->input('gpgkey', array('label' => 'GnuPG key', 'div' => 'clear', 'class' => 'input-xxlarge'));
|
||||
?>
|
||||
<div class="clear"><span role="button" tabindex="0" aria-label="<?php echo __('Fetch PGP key');?>" onClick="lookupPGPKey('UserEmail');" class="btn btn-inverse" style="margin-bottom:10px;"><?php echo __('Fetch GPG key');?></span></div>
|
||||
<div class="clear"><span role="button" tabindex="0" aria-label="<?php echo __('Fetch GnuPG key');?>" onClick="lookupPGPKey('UserEmail');" class="btn btn-inverse" style="margin-bottom:10px;"><?php echo __('Fetch GnuPG key');?></span></div>
|
||||
<?php
|
||||
if (Configure::read('SMIME.enabled')) echo $this->Form->input('certif_public', array('label' => __('SMIME Public certificate (PEM format)'), 'div' => 'clear', 'class' => 'input-xxlarge'));
|
||||
echo $this->Form->input('autoalert', array('label' => __('Receive alerts when events are published'), 'type' => 'checkbox'));
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class="index">
|
||||
<h3><?php echo __('GPG key validation');?></h3>
|
||||
<h3><?php echo __('GnuPG key validation');?></h3>
|
||||
<ul>
|
||||
<?php foreach ($users as $k => $user) {
|
||||
echo '<a href="'.$baseurl.'/admin/users/view/' . $k . '">' . $k . ' (' . h($user[1]) . ')</a>:';
|
||||
|
|
|
@ -57,20 +57,20 @@
|
|||
<?php echo h((0 == $user['User']['termsaccepted'])? __('No') : __('Yes')); ?>
|
||||
|
||||
</dd>
|
||||
<dt><?php echo __('PGP key'); ?></dt>
|
||||
<dt><?php echo __('GnuPG key'); ?></dt>
|
||||
<dd class="quickSelect <?php echo $user['User']['gpgkey'] ? 'green' : 'bold red'; ?>">
|
||||
<?php echo $user['User']['gpgkey'] ? nl2br(h($user['User']['gpgkey'])) : __("N/A"); ?>
|
||||
</dd>
|
||||
<?php
|
||||
if (!empty($user['User']['gpgkey'])):
|
||||
?>
|
||||
<dt><?php echo __('PGP fingerprint');?></dt>
|
||||
<dt><?php echo __('GnuPG fingerprint');?></dt>
|
||||
<dd class="quickSelect bold <?php echo $user['User']['fingerprint'] ? 'green': 'red'; ?>">
|
||||
<?php
|
||||
echo $user['User']['fingerprint'] ? chunk_split(h($user['User']['fingerprint']), 4, ' ') : 'N/A';
|
||||
?>
|
||||
</dd>
|
||||
<dt><?php echo __('PGP status');?></dt>
|
||||
<dt><?php echo __('GnuPG status');?></dt>
|
||||
<dd class="bold <?php echo (empty($user['User']['pgp_status']) || $user['User']['pgp_status'] != 'OK') ? 'red': 'green'; ?>">
|
||||
<?php
|
||||
echo !empty($user['User']['pgp_status']) ? h($user['User']['pgp_status']) : 'N/A';
|
||||
|
|
|
@ -181,40 +181,7 @@
|
|||
"hide_tag": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"Feed": {
|
||||
"id": "6",
|
||||
"name": "Binary Defense Systems Artillery Threat Intelligence Feed and Banlist Feed",
|
||||
"provider": "Binary Defense Systems",
|
||||
"url": "https://www.trustedsec.com/banlist.txt",
|
||||
"rules": "{\"tags\":{\"OR\":[],\"NOT\":[]},\"orgs\":{\"OR\":[],\"NOT\":[]}}",
|
||||
"enabled": true,
|
||||
"distribution": "0",
|
||||
"sharing_group_id": "0",
|
||||
"tag_id": "615",
|
||||
"default": false,
|
||||
"source_format": "csv",
|
||||
"fixed_event": true,
|
||||
"delta_merge": true,
|
||||
"event_id": "5153",
|
||||
"publish": false,
|
||||
"override_ids": true,
|
||||
"settings": "{\"csv\":{\"value\":\"1\"}}",
|
||||
"input_source": "network",
|
||||
"delete_local_file": false,
|
||||
"lookup_visible": false,
|
||||
"cache_timestamp": "1495871960"
|
||||
},
|
||||
"Tag": {
|
||||
"id": "615",
|
||||
"name": "osint:source-type=\"block-or-filter-list\"",
|
||||
"colour": "#004f89",
|
||||
"exportable": true,
|
||||
"org_id": "0",
|
||||
"hide_tag": false
|
||||
}
|
||||
},
|
||||
{
|
||||
{
|
||||
"Feed": {
|
||||
"id": "7",
|
||||
"name": "malwaredomainlist",
|
||||
|
@ -569,39 +536,6 @@
|
|||
"hide_tag": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"Feed": {
|
||||
"id": "25",
|
||||
"name": "openbl.org base",
|
||||
"provider": "openbl.org",
|
||||
"url": "http://www.openbl.org/lists/base.txt",
|
||||
"rules": "{\"tags\":{\"OR\":[],\"NOT\":[]},\"orgs\":{\"OR\":[],\"NOT\":[]}}",
|
||||
"enabled": true,
|
||||
"distribution": "0",
|
||||
"sharing_group_id": "0",
|
||||
"tag_id": "615",
|
||||
"default": false,
|
||||
"source_format": "freetext",
|
||||
"fixed_event": true,
|
||||
"delta_merge": true,
|
||||
"event_id": "6293",
|
||||
"publish": true,
|
||||
"override_ids": false,
|
||||
"settings": "{\"csv\":{\"value\":\"\",\"delimiter\":\",\"},\"common\":{\"excluderegex\":\"\"}}",
|
||||
"input_source": "network",
|
||||
"delete_local_file": false,
|
||||
"lookup_visible": true,
|
||||
"cache_timestamp": "1495871996"
|
||||
},
|
||||
"Tag": {
|
||||
"id": "615",
|
||||
"name": "osint:source-type=\"block-or-filter-list\"",
|
||||
"colour": "#004f89",
|
||||
"exportable": true,
|
||||
"org_id": "0",
|
||||
"hide_tag": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"Feed": {
|
||||
"id": "27",
|
||||
|
@ -1455,5 +1389,38 @@
|
|||
"lookup_visible": true,
|
||||
"headers": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Feed": {
|
||||
"id": "69",
|
||||
"name": "URLHaus Malware URLs",
|
||||
"provider": "Abuse.ch",
|
||||
"url": "https:\/\/urlhaus.abuse.ch\/downloads\/csv\/",
|
||||
"rules": "{\"tags\":{\"OR\":[],\"NOT\":[]},\"orgs\":{\"OR\":[],\"NOT\":[]}}",
|
||||
"enabled": true,
|
||||
"distribution": "3",
|
||||
"sharing_group_id": "0",
|
||||
"tag_id": "615",
|
||||
"default": false,
|
||||
"source_format": "csv",
|
||||
"fixed_event": false,
|
||||
"delta_merge": false,
|
||||
"event_id": "0",
|
||||
"publish": false,
|
||||
"override_ids": false,
|
||||
"settings": "{\"csv\":{\"value\":\"3\",\"delimiter\":\",\"},\"common\":{\"excluderegex\":\"\"}}",
|
||||
"input_source": "network",
|
||||
"delete_local_file": false,
|
||||
"lookup_visible": true,
|
||||
"headers": ""
|
||||
},
|
||||
"Tag": {
|
||||
"id": "615",
|
||||
"name": "osint:source-type=\"block-or-filter-list\"",
|
||||
"colour": "#004f89",
|
||||
"exportable": true,
|
||||
"org_id": "0",
|
||||
"hide_tag": false
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 9fa4d37803de84fbb708ab1ce78b18f423eaa15f
|
||||
Subproject commit f4d7fe01666607c5606ab11da81a8054974e886a
|
|
@ -1 +1 @@
|
|||
Subproject commit cee578dce19f5b4f87af3272e40772d752836c3d
|
||||
Subproject commit c92ee2e46179f2b30ff1011950f16af38e0f94fc
|
|
@ -22,8 +22,6 @@ from misp2stix2_dictionaries import *
|
|||
from copy import deepcopy
|
||||
from collections import defaultdict
|
||||
|
||||
namespace = ['https://github.com/MISP/MISP', 'MISP']
|
||||
|
||||
not_implemented_attributes = ['yara', 'pattern-in-traffic', 'pattern-in-memory']
|
||||
|
||||
non_indicator_attributes = ['text', 'comment', 'other', 'link', 'target-user', 'target-email',
|
||||
|
@ -770,11 +768,6 @@ def generateEventPackage(event, SDOs):
|
|||
|
||||
def main(args):
|
||||
pathname = os.path.dirname(args[0])
|
||||
if len(sys.argv) > 3:
|
||||
namespace[0] = sys.argv[3]
|
||||
if len(sys.argv) > 4:
|
||||
namespace[1] = sys.argv[4].replace(" ", "_")
|
||||
namespace[1] = re.sub('[\W]+', '', namespace[1])
|
||||
misp = pymisp.MISPEvent(None, False)
|
||||
misp.load_file(os.path.join(pathname, args[1]))
|
||||
if 'Attribute' not in dir(misp):
|
||||
|
|
|
@ -31,14 +31,16 @@ def loadEvent(args, pathname):
|
|||
|
||||
def fillReportInfo(mispDict, report):
|
||||
mispDict['info'] = report.get('name')
|
||||
mispDict['publish_timestamp'] = getTimestampfromDate(report.get('published'))
|
||||
if report.get('published'):
|
||||
mispDict['publish_timestamp'] = getTimestampfromDate(report.get('published'))
|
||||
labels = report.get('labels')
|
||||
Tag = []
|
||||
for l in labels:
|
||||
label = {'exportable': True, 'hide_tag': False}
|
||||
label['name'] = l
|
||||
Tag.append(label)
|
||||
mispDict['Tag'] = Tag
|
||||
if labels:
|
||||
Tag = []
|
||||
for l in labels:
|
||||
label = {'exportable': True, 'hide_tag': False}
|
||||
label['name'] = l
|
||||
Tag.append(label)
|
||||
mispDict['Tag'] = Tag
|
||||
|
||||
def buildMispDict(event):
|
||||
mispDict = {}
|
||||
|
@ -148,7 +150,7 @@ def fillAttributes(attr, attrLabels, Attribute):
|
|||
def fillCustom(attr, attrLabels, Attribute):
|
||||
attribute = {}
|
||||
attribute['type'] = attr.get('type').split('x-misp-object-')[1]
|
||||
attribute['timestamp'] = int(time.mktime(time.strptime(attr.get('x_misp_timestamp'), "%Y-%m-%d %H:%M:%S")))
|
||||
attribute['timestamp'] = getTimestampfromDate(attr.get('x_misp_timestamp'))
|
||||
attribute['to_ids'] = bool(attrLabels[1].split('=')[1])
|
||||
attribute['value'] = attr.get('x_misp_value')
|
||||
attribute['category'] = getMispCategory(attrLabels)
|
||||
|
@ -175,6 +177,8 @@ def fillCustomFromObject(attr, attrLabels, Object):
|
|||
def getTimestampfromDate(date):
|
||||
if '.' in date:
|
||||
return int(time.mktime(time.strptime(date.split('.')[0], "%Y-%m-%dT%H:%M:%S")))
|
||||
elif '+' in date:
|
||||
return int(time.mktime(time.strptime(date.split('+')[0], "%Y-%m-%d %H:%M:%S")))
|
||||
else:
|
||||
return int(time.mktime(time.strptime(date, "%Y-%m-%dT%H:%M:%SZ")))
|
||||
|
||||
|
@ -517,7 +521,7 @@ def checkIfFromMISP(stix2Event):
|
|||
return False
|
||||
|
||||
def main(args):
|
||||
pathname = os.path.dirname(sys.argv[0])
|
||||
pathname = os.path.dirname(args[0])
|
||||
stix2Event = loadEvent(args, pathname)
|
||||
stix2Event = stix2Event.get('objects')
|
||||
if checkIfFromMISP(stix2Event):
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2017 CIRCL Computer Incident Response Center Luxembourg (smile gie)
|
||||
# Copyright (C) 2017 Christian Studer
|
||||
# Copyright (C) 2017-2018 CIRCL Computer Incident Response Center Luxembourg (smile gie)
|
||||
# Copyright (C) 2017-2018 Christian Studer
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
|
@ -16,412 +16,561 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import sys, json, os, time
|
||||
import pymisp
|
||||
from pymisp import MISPEvent, MISPObject, MISPAttribute, __path__
|
||||
from stix.core import STIXPackage
|
||||
|
||||
eventTypes = {"ipv4-addr": {"src": "ip-src", "dst": "ip-dst", "value": "address_value", "relation": "ip"},
|
||||
"ipv6-addr": {"src": "ip-src", "dst": "ip-dst", "value": "address_value", "relation": "ip"},
|
||||
"URIObjectType": {"type": "url", "value": "value", "relation": "url"},
|
||||
"FileObjectType": {"type": "filename", "value": "file_name", "relation": "filename"},
|
||||
"DomainNameObjectType": {"type": "domain", "value": "value", "relation": "domain"},
|
||||
"HostnameObjectType": {"type": "hostname", "value": "hostname_value", "relation": "host"},
|
||||
"PortObjectType": {"type": "port", "value": "port_value", "relation": "port"},
|
||||
"HTTPSessionObjectType": {"type": "", "value": "", "relation": ""},
|
||||
"AddressObjectType": {"email": "email-src", "": ""},
|
||||
"to": {"type": "email-dst", "value": "address_value", "relation": "to"},
|
||||
"from": {"type": "email-src", "value": "value", "relation": "from"},
|
||||
"subject": {"type": "email-subject", "value": "value", "relation": "subject"},
|
||||
"email-attachment": {"value": "file_name", "relation": "attachment"},
|
||||
"user_agent": "user-agent"}
|
||||
file_object_type = {"type": "filename", "relation": "filename"}
|
||||
|
||||
descFilename = os.path.join(pymisp.__path__[0], 'data/describeTypes.json')
|
||||
eventTypes = {"ArtifactObjectType": {"type": "attachment", "relation": "attachment"},
|
||||
"DomainNameObjectType": {"type": "domain", "relation": "domain"},
|
||||
"FileObjectType": file_object_type,
|
||||
"HostnameObjectType": {"type": "hostname", "relation": "host"},
|
||||
"MutexObjectType": {"type": "mutex", "relation": "mutex"},
|
||||
"PDFFileObjectType": file_object_type,
|
||||
"PortObjectType": {"type": "port", "relation": "port"},
|
||||
"URIObjectType": {"type": "url", "relation": "url"},
|
||||
"WindowsExecutableFileObjectType": file_object_type,
|
||||
"WindowsRegistryKeyObjectType": {"type": "regkey", "relation": ""}}
|
||||
|
||||
descFilename = os.path.join(__path__[0], 'data/describeTypes.json')
|
||||
with open(descFilename, 'r') as f:
|
||||
categories = json.loads(f.read())['result'].get('categories')
|
||||
|
||||
def loadEvent(args, pathname):
|
||||
try:
|
||||
filename = '{}/tmp/{}'.format(pathname, args[1])
|
||||
tempFile = open(filename, 'r')
|
||||
fromMISP = True
|
||||
stixJson = True
|
||||
class StixParser():
|
||||
def __init__(self):
|
||||
self.misp_event = MISPEvent()
|
||||
|
||||
def loadEvent(self, args, pathname):
|
||||
try:
|
||||
event = json.loads(tempFile.read())
|
||||
isJson = True
|
||||
except:
|
||||
filename = '{}/tmp/{}'.format(pathname, args[1])
|
||||
event = STIXPackage.from_xml(filename)
|
||||
try:
|
||||
event = json.loads(event.to_json())
|
||||
except:
|
||||
stixJson = False
|
||||
if args[1].startswith('misp.'):
|
||||
event = event['related_packages']['related_packages'][0]
|
||||
if "CIRCL:Package" in event.id_ and "CIRCL MISP" in event.stix_header.title:
|
||||
fromMISP = True
|
||||
else:
|
||||
fromMISP = False
|
||||
isJson = False
|
||||
return event, isJson, fromMISP, stixJson
|
||||
except:
|
||||
print(json.dumps({'success': 0, 'message': 'The temporary STIX export file could not be read'}))
|
||||
sys.exit(0)
|
||||
|
||||
def getTimestampfromDate(date):
|
||||
try:
|
||||
try:
|
||||
dt = date.split('+')[0]
|
||||
d = int(time.mktime(time.strptime(dt, "%Y-%m-%dT%H:%M:%S")))
|
||||
except:
|
||||
dt = date.split('.')[0]
|
||||
d = int(time.mktime(time.strptime(dt, "%Y-%m-%dT%H:%M:%S")))
|
||||
except AttributeError:
|
||||
d = int(time.mktime(date.timetuple()))
|
||||
return d
|
||||
|
||||
def buildMispDict(stixEvent):
|
||||
mispDict = {}
|
||||
stixTimestamp = stixEvent.get("timestamp")
|
||||
dictTimestampAndDate(mispDict, stixTimestamp)
|
||||
event = stixEvent["incidents"][0]
|
||||
eventInfo(mispDict, event)
|
||||
indicators = event["related_indicators"]["indicators"]
|
||||
mispDict["Attribute"] = []
|
||||
mispDict["Object"] = []
|
||||
for indic in indicators:
|
||||
try:
|
||||
indicator = indic.get("indicator")
|
||||
timestamp = indicator.get("timestamp").split("+")[0]
|
||||
category = indic.get("relationship")
|
||||
observable = indicator["observable"]
|
||||
except:
|
||||
continue
|
||||
try:
|
||||
properties = observable["object"]
|
||||
attribute = {'timestamp': getTimestampfromDate(timestamp)}
|
||||
attrType, attribute['value'], relation = fillMispAttribute(properties, category)
|
||||
attribute['type'] = attrType
|
||||
if category in categories:
|
||||
attribute['category'] = category
|
||||
mispDict["Attribute"].append(attribute)
|
||||
if fromMISP:
|
||||
self.event = event.related_packages.related_package[0].item.incidents[0]
|
||||
else:
|
||||
name = indicator.get('description').split(' ')[0]
|
||||
defineRelation(attribute, attrType, name, relation)
|
||||
obj = {'timestamp': getTimestampfromDate(timestamp), 'meta-category': category,
|
||||
'Attribute': [attribute]}
|
||||
obj['name'] = name
|
||||
mispDict["Object"].append(obj)
|
||||
self.event = event
|
||||
self.fromMISP = fromMISP
|
||||
self.filename = filename
|
||||
self.load_mapping()
|
||||
except:
|
||||
observables = observable['observable_composition'].get('observables')
|
||||
if category in categories:
|
||||
domain = False
|
||||
for obs in observables:
|
||||
properties = obs['object']
|
||||
tmpType, tmpValue, _ = fillMispAttribute(properties, category)
|
||||
if tmpType == 'domain':
|
||||
domainType = tmpType
|
||||
domainVal = tmpValue
|
||||
domain = True
|
||||
elif tmpType in ('filename', 'regkey', 'hostname', 'ip-src', 'ip-dst'):
|
||||
type1 = tmpType
|
||||
value1 = tmpValue
|
||||
else:
|
||||
type2 = tmpType
|
||||
value2 = tmpValue
|
||||
if domain == True:
|
||||
type2 = type1.split('-')[0]
|
||||
type1 = domainType
|
||||
value2 = value1
|
||||
value1 = domainVal
|
||||
attribute = {'timestamp': getTimestampfromDate(timestamp),
|
||||
'type': '{}|{}'.format(type1, type2),
|
||||
'value': '{}|{}'.format(value1, value2)}
|
||||
mispDict['Attribute'].append(attribute)
|
||||
else:
|
||||
attributes = []
|
||||
name = indicator.get('description').split(' ')[0]
|
||||
for obs in observables:
|
||||
properties = obs['object']
|
||||
attribute = {'timestamp': getTimestampfromDate(timestamp)}
|
||||
attrType, attribute['value'], relation = fillMispAttribute(properties, category)
|
||||
if '|' in attrType:
|
||||
attribute['type'] = "malware-sample"
|
||||
attribute['object_relation'] = "malware-sample"
|
||||
else:
|
||||
attribute['type'] = attrType
|
||||
defineRelation(attribute, attrType, name, relation)
|
||||
attributes.append(attribute)
|
||||
obj = {'timestamp': getTimestampfromDate(timestamp), 'meta-category': category,
|
||||
'Attribute': attributes}
|
||||
obj['name'] = name
|
||||
mispDict["Object"].append(obj)
|
||||
return mispDict
|
||||
print(json.dumps({'success': 0, 'message': 'The temporary STIX export file could not be read'}))
|
||||
sys.exit(0)
|
||||
|
||||
def dictTimestampAndDate(mispDict, stixTimestamp):
|
||||
try:
|
||||
date = stixTimestamp.split("T")[0]
|
||||
except AttributeError:
|
||||
date = stixTimestamp
|
||||
mispDict["date"] = date
|
||||
timestamp = getTimestampfromDate(stixTimestamp)
|
||||
mispDict["timestamp"] = timestamp
|
||||
def load_mapping(self):
|
||||
self.attribute_types_mapping = {
|
||||
'AddressObjectType': self.handle_address,
|
||||
"ArtifactObjectType": self.handle_attachment,
|
||||
'DomainNameObjectType': self.handle_domain_or_url,
|
||||
'EmailMessageObjectType': self.handle_email_attribute,
|
||||
'FileObjectType': self.handle_file,
|
||||
'HostnameObjectType': self.handle_hostname,
|
||||
'HTTPSessionObjectType': self.handle_http,
|
||||
'MutexObjectType': self.handle_mutex,
|
||||
'PDFFileObjectType': self.handle_file,
|
||||
'PortObjectType': self.handle_port,
|
||||
'SocketAddressObjectType': self.handle_socket_address,
|
||||
'URIObjectType': self.handle_domain_or_url,
|
||||
"WhoisObjectType": self.handle_whois,
|
||||
'WindowsRegistryKeyObjectType': self.handle_regkey,
|
||||
"WindowsExecutableFileObjectType": self.handle_pe
|
||||
}
|
||||
|
||||
def eventInfo(mispDict, event):
|
||||
try:
|
||||
mispDict["info"] = event["title"]
|
||||
except:
|
||||
mispDict["info"] = "Imported from external STIX event"
|
||||
try:
|
||||
orgSource = event["information_source"]["identity"]["name"]
|
||||
mispDict["Org"] = {}
|
||||
mispDict["Org"]["name"] = orgSource
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
orgReporter = event["reporter"]["identity"]["name"]
|
||||
mispDict["Orgc"] = {}
|
||||
mispDict["Orgc"]["name"] = orgReporter
|
||||
except:
|
||||
pass
|
||||
|
||||
def defineRelation(attribute, attrType, name, relation):
|
||||
if attrType in ('md5', 'sha1', 'sha256') and name == 'x509':
|
||||
attribute['object_relation'] = "x509-fingerprint-{}".format(attrType)
|
||||
else:
|
||||
attribute['object_relation'] = relation
|
||||
|
||||
def buildExternalDict(stixEvent):
|
||||
mispDict = {}
|
||||
stixTimestamp = stixEvent.get("timestamp")
|
||||
dictTimestampAndDate(mispDict, stixTimestamp)
|
||||
header = stixEvent.get('stix_header')
|
||||
eventInfo(mispDict, header)
|
||||
mispDict['Attribute'] = []
|
||||
mispDict['Object'] = []
|
||||
if 'indicators' in stixEvent:
|
||||
indicators = stixEvent.get('indicators')
|
||||
parseAttributes(indicators, mispDict, True)
|
||||
if 'observables' in stixEvent:
|
||||
observables = stixEvent['observables'].get('observables')
|
||||
parseAttributes(observables, mispDict, False)
|
||||
if 'ttps' in stixEvent:
|
||||
ttps = stixEvent['ttps'].get('ttps')
|
||||
parseTTPS(ttps, mispDict)
|
||||
return mispDict
|
||||
|
||||
def buildExternalDict_fromPackage(stixEvent):
|
||||
mispDict = {}
|
||||
dictTimestampAndDate(mispDict, stixEvent.timestamp)
|
||||
eventInfo(mispDict, stixEvent.stix_header)
|
||||
mispDict['Attribute'] = []
|
||||
mispDict['Object'] = []
|
||||
if stixEvent.indicators:
|
||||
parseAttributes(stixEvent.indicators.to_dict(), mispDict, True)
|
||||
if stixEvent.observables:
|
||||
parseAttributes(stixEvent.observables.to_dict()['observables'], mispDict, False)
|
||||
if stixEvent.ttps:
|
||||
parseTTPS(stixEvent.ttps.to_dict()['ttps'], mispDict)
|
||||
return mispDict
|
||||
|
||||
def parseAttributes(attributes, mispDict, indic):
|
||||
for attr in attributes:
|
||||
if 'observable' in attr:
|
||||
observable = attr.get('observable')
|
||||
obj = observable.get('object')
|
||||
def handler(self):
|
||||
self.outputname = '{}.json'.format(self.filename)
|
||||
if self.fromMISP:
|
||||
# STIX format coming from a MISP export
|
||||
self.buildMispDict()
|
||||
else:
|
||||
obj = attr.get('object')
|
||||
try:
|
||||
properties = obj.get('properties')
|
||||
if 'hashes' in properties and len(properties.get('hashes')) > 1:
|
||||
parseFileObject(properties, mispDict)
|
||||
continue
|
||||
elif properties.get('xsi:type') == 'WhoisObjectType':
|
||||
continue
|
||||
except:
|
||||
if 'description' in attr:
|
||||
attribute = {'type': 'text', 'value': attr.get('description')}
|
||||
mispDict['Attribute'].append(attribute)
|
||||
continue
|
||||
try:
|
||||
attrTimestamp = attr['timestamp'].split('+')[0]
|
||||
attribute = {'timestamp': getTimestampfromDate(attrTimestamp)}
|
||||
except:
|
||||
attribute = {}
|
||||
attribute['type'], attribute['value'] = fillExternalAttribute(properties)
|
||||
attribute['to_ids'] = indic
|
||||
mispDict['Attribute'].append(attribute)
|
||||
# external STIX format file
|
||||
self.buildExternalDict()
|
||||
|
||||
def parseFileObject(properties, mispDict):
|
||||
obj = {'name': 'file', 'Attribute': []}
|
||||
if 'file_name' in properties:
|
||||
obj['Attribute'].append({'type': 'filename', 'object_relation': 'filename', 'value': properties.get('file_name')})
|
||||
if 'peak_entropy' in properties:
|
||||
obj['Attribute'].append({'type': 'float', 'object_relation': 'entropy', 'value': properties.get('peak_entropy')})
|
||||
if 'size_in_bytes' in properties:
|
||||
obj['Attribute'].append({'type': 'size-in-bytes', 'object_relation': 'size-in-bytes',
|
||||
'value': properties.get('size_in_bytes')})
|
||||
for h in properties.get('hashes'):
|
||||
h_type = h.get('type').lower()
|
||||
obj['Attribute'].append({'type': h_type, 'object_relation': h_type, 'value': h.get('simple_hash_value')})
|
||||
mispDict['Object'].append(obj)
|
||||
def buildMispDict(self):
|
||||
self.dictTimestampAndDate()
|
||||
self.eventInfo()
|
||||
for indicator in self.event.related_indicators.indicator:
|
||||
self.parse_misp_indicator(indicator)
|
||||
|
||||
def parseTTPS(ttps, mispDict):
|
||||
mispDict['Galaxy'] = []
|
||||
for ttp in ttps:
|
||||
try:
|
||||
behavior = ttp['behavior']
|
||||
except KeyError:
|
||||
continue
|
||||
if 'malware_instances' in behavior:
|
||||
attr = behavior['malware_instances'][0]
|
||||
def buildExternalDict(self):
|
||||
self.dictTimestampAndDate()
|
||||
self.eventInfo()
|
||||
if self.event.indicators:
|
||||
self.parse_external_indicator(self.event.indicators)
|
||||
if self.event.observables:
|
||||
self.parse_external_observable(self.event.observables.observables)
|
||||
# if self.event.ttps:
|
||||
# self.parse_ttps(self.event.ttps.ttps)
|
||||
|
||||
def dictTimestampAndDate(self):
|
||||
if self.event.timestamp:
|
||||
stixTimestamp = self.event.timestamp
|
||||
try:
|
||||
attrType = attr['types'][0].get('value')
|
||||
date = stixTimestamp.split("T")[0]
|
||||
except AttributeError:
|
||||
date = stixTimestamp
|
||||
self.misp_event.date = date
|
||||
self.misp_event.timestamp = self.getTimestampfromDate(stixTimestamp)
|
||||
|
||||
@staticmethod
|
||||
def getTimestampfromDate(date):
|
||||
try:
|
||||
try:
|
||||
dt = date.split('+')[0]
|
||||
d = int(time.mktime(time.strptime(dt, "%Y-%m-%dT%H:%M:%S")))
|
||||
except:
|
||||
dt = date.split('.')[0]
|
||||
d = int(time.mktime(time.strptime(dt, "%Y-%m-%dT%H:%M:%S")))
|
||||
except AttributeError:
|
||||
d = int(time.mktime(date.timetuple()))
|
||||
return d
|
||||
|
||||
def eventInfo(self):
|
||||
try:
|
||||
try:
|
||||
info = self.event.stix_header.title
|
||||
except:
|
||||
info = self.event.title
|
||||
if info:
|
||||
self.misp_event.info = info
|
||||
else:
|
||||
raise Exception("Imported from external STIX event")
|
||||
except Exception as noinfo:
|
||||
self.misp_event.info = str(noinfo)
|
||||
|
||||
def parse_misp_indicator(self, indicator):
|
||||
# define is an indicator will be imported as attribute or object
|
||||
if indicator.relationship in categories:
|
||||
self.parse_misp_attribute(indicator)
|
||||
else:
|
||||
self.parse_misp_object(indicator)
|
||||
|
||||
def parse_misp_attribute(self, indicator):
|
||||
misp_attribute = {'category': str(indicator.relationship)}
|
||||
item = indicator.item
|
||||
misp_attribute['timestamp'] = self.getTimestampfromDate(item.timestamp)
|
||||
if item.observable:
|
||||
observable = item.observable
|
||||
try:
|
||||
properties = observable.object_.properties
|
||||
if properties:
|
||||
attribute_type, attribute_value, _ = self.handle_attribute_type(properties)
|
||||
self.misp_event.add_attribute(attribute_type, attribute_value, **misp_attribute)
|
||||
except AttributeError:
|
||||
attribute_dict = {}
|
||||
for observables in observable.observable_composition.observables:
|
||||
properties = observables.object_.properties
|
||||
attribute_type, attribute_value, _ = self.handle_attribute_type(properties)
|
||||
attribute_dict[attribute_type] = attribute_value
|
||||
attribute_type, attribute_value = self.composite_type(attribute_dict)
|
||||
self.misp_event.add_attribute(attribute_type, attribute_value, **misp_attribute)
|
||||
|
||||
@staticmethod
|
||||
def composite_type(attributes):
|
||||
if "port" in attributes:
|
||||
if "ip-src" in attributes:
|
||||
return "ip-src|port", "{}|{}".format(attributes["ip-src"], attributes["port"])
|
||||
elif "ip-dst" in attributes:
|
||||
return "ip-dst|port", "{}|{}".format(attributes["ip-dst"], attributes["port"])
|
||||
elif "hostname" in attributes:
|
||||
return "hostname|port", "{}|{}".format(attributes["hostname"], attributes["port"])
|
||||
elif "domain" in attributes:
|
||||
if "ip-src" in attributes:
|
||||
ip_value = attributes["ip-src"]
|
||||
elif "ip-dst" in attributes:
|
||||
ip_value = attributes["ip-dst"]
|
||||
return "domain|ip", "{}|{}".format(attributes["domain"], ip_value)
|
||||
|
||||
def handle_attribute_type(self, properties, is_object=False, title=None):
|
||||
xsi_type = properties._XSI_TYPE
|
||||
try:
|
||||
args = [properties]
|
||||
if xsi_type in ("FileObjectType", "PDFFileObjectType"):
|
||||
args.append(is_object)
|
||||
elif xsi_type == "ArtifactObjectType":
|
||||
args.append(title)
|
||||
return self.attribute_types_mapping[xsi_type](*args)
|
||||
except AttributeError:
|
||||
# ATM USED TO TEST TYPES
|
||||
print("Unparsed type: {}".format(xsi_type))
|
||||
sys.exit(1)
|
||||
|
||||
@staticmethod
|
||||
def handle_address(properties):
|
||||
if properties.is_source:
|
||||
ip_type = "ip-src"
|
||||
else:
|
||||
ip_type = "ip-dst"
|
||||
return ip_type, properties.address_value.value, "ip"
|
||||
|
||||
@staticmethod
|
||||
def handle_attachment(properties, title):
|
||||
return eventTypes[properties._XSI_TYPE]['type'], title, properties.raw_artifact.value
|
||||
|
||||
@staticmethod
|
||||
def handle_domain_or_url(properties):
|
||||
event_types = eventTypes[proprties._XSI_TYPE]
|
||||
return event_types['type'], properties.value.value, event_types['relation']
|
||||
|
||||
def handle_email_attribute(self, properties):
|
||||
try:
|
||||
if properties.from_:
|
||||
return "email-src", properties.from_.address_value.value, "from"
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
if properties.to:
|
||||
return "email-dst", properties.to[0].address_value.value, "to"
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
if properties.subject:
|
||||
return "email-subject", properties.subject.value, "subject"
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
if properties.attachments:
|
||||
return self.handle_email_attachment(properties.parent)
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
# ATM USED TO TEST EMAIL PROPERTIES
|
||||
print("Unsupported Email property")
|
||||
sys.exit(1)
|
||||
|
||||
@staticmethod
|
||||
def handle_email_attachment(indicator_object):
|
||||
properties = indicator_object.related_objects[0].properties
|
||||
return "email-attachment", properties.file_name.value, "attachment"
|
||||
|
||||
def handle_file(self, properties, is_object):
|
||||
b_hash, b_file = False, False
|
||||
attributes = []
|
||||
if properties.hashes:
|
||||
b_hash = True
|
||||
for h in properties.hashes:
|
||||
attributes.append(self.handle_hashes_attribute(h))
|
||||
if properties.file_format and properties.file_format.value:
|
||||
attributes.append(["mime-type", properties.file_format.value, "mimetype"])
|
||||
if properties.file_name or properties.file_path:
|
||||
try:
|
||||
value = properties.file_name.value
|
||||
except AttributeError:
|
||||
value = properties.file_path.value
|
||||
if value:
|
||||
b_file = True
|
||||
event_types = eventTypes[properties._XSI_TYPE]
|
||||
attributes.append([event_types['type'], value, event_types['relation']])
|
||||
if properties.byte_runs:
|
||||
attribute_type = "pattern-in-file"
|
||||
attributes.append([attribute_type, properties.byte_runs[0].byte_run_data, attribute_type])
|
||||
if properties.size_in_bytes and properties.size_in_bytes.value:
|
||||
attribute_type = "size-in-bytes"
|
||||
attributes.append([attribute_type, properties.size_in_bytes.value, attribute_type])
|
||||
if properties.peak_entropy and properties.peak_entropy.value:
|
||||
attributes.append(["float", properties.peak_entropy.value, "entropy"])
|
||||
if len(attributes) == 1:
|
||||
return attributes[0]
|
||||
if len(attributes) == 2:
|
||||
if b_hash and b_file:
|
||||
return self.handle_filename_object(attributes, is_object)
|
||||
return "file", self.return_attributes(attributes), ""
|
||||
|
||||
@staticmethod
|
||||
def handle_filename_object(attributes, is_object):
|
||||
for attribute in attributes:
|
||||
attribute_type, attribute_value, _ = attribute
|
||||
if attribute_type == "filename":
|
||||
filename_value = attribute_value
|
||||
else:
|
||||
hash_type, hash_value = attribute_type, attribute_value
|
||||
value = "{}|{}".format(filename_value, hash_value)
|
||||
if is_object:
|
||||
# file object attributes cannot be filename|hash, so it is malware-sample
|
||||
attr_type = "malware-sample"
|
||||
return attr_type, value, attr_type
|
||||
else:
|
||||
# it could be malware-sample as well, but STIX is losing this information
|
||||
return "filename|{}".format(hash_type), value, ""
|
||||
|
||||
@staticmethod
|
||||
def handle_hashes_attribute(properties):
|
||||
hash_type = properties.type_.value.lower()
|
||||
try:
|
||||
hash_value = properties.simple_hash_value.value
|
||||
except AttributeError:
|
||||
hash_value = properties.fuzzy_hash_value.value
|
||||
return hash_type, hash_value, hash_type
|
||||
|
||||
@staticmethod
|
||||
def handle_hostname(properties):
|
||||
event_types = eventTypes[properties._XSI_TYPE]
|
||||
return event_types['type'], properties.hostname_value.value, event_types['relation']
|
||||
|
||||
@staticmethod
|
||||
def handle_http(properties):
|
||||
client_request = properties.http_request_response[0].http_client_request
|
||||
if client_request.http_request_header:
|
||||
request_header = client_request.http_request_header
|
||||
if request_header.parsed_header:
|
||||
value = request_header.parsed_header.user_agent.value
|
||||
return "user-agent", value, "user-agent"
|
||||
elif request_header.raw_header:
|
||||
value = request_header.raw_header.value
|
||||
return "http-method", value, "method"
|
||||
elif client_request.http_request_line:
|
||||
value = client_request.http_request_line.http_method.value
|
||||
return "http-method", value, "method"
|
||||
|
||||
@staticmethod
|
||||
def handle_mutex(properties):
|
||||
event_types = eventTypes[properties._XSI_TYPE]
|
||||
return event_types['type'], properties.name.value, event_types['relation']
|
||||
|
||||
@staticmethod
|
||||
def handle_port(properties):
|
||||
event_types = eventTypes[properties._XSI_TYPE]
|
||||
return event_types['type'], properties.port_value.value, event_types['relation']
|
||||
|
||||
@staticmethod
|
||||
def handle_regkey(properties):
|
||||
event_types = eventTypes[properties._XSI_TYPE]
|
||||
return event_types['type'], properties.key.value, event_types['relation']
|
||||
|
||||
def handle_socket_address(self, properties):
|
||||
if properties.ip_address:
|
||||
type1, value1, _ = self.handle_address(properties.ip_address)
|
||||
elif properties.hostname:
|
||||
type1 = "hostname"
|
||||
value1 = properties.hostname.hostname_value.value
|
||||
return "{}|port".format(type1), "{}|{}".format(value1, properties.port.port_value.value), ""
|
||||
|
||||
def handle_whois(self, properties):
|
||||
required_one_of = False
|
||||
attributes = []
|
||||
if properties.remarks:
|
||||
attribute_type = "text"
|
||||
attributes.append([attribute_type, properties.remarks.value, attribute_type])
|
||||
required_one_of = True
|
||||
if properties.registrar_info:
|
||||
attribute_type = "whois-registrar"
|
||||
attributes.append([attribute_type, properties.registrar_info.value, attribute_type])
|
||||
required_one_of = True
|
||||
if properties.registrants:
|
||||
# ATM: need to see how it looks like in a real example
|
||||
print(dir(properties.registrants))
|
||||
if properties.creation_date:
|
||||
attributes.append(["datetime", properties.creation_date.value, "creation-date"])
|
||||
required_one_of = True
|
||||
if properties.updated_date:
|
||||
attributes.append(["datetime", properties.updated_date.value, "modification-date"])
|
||||
if properties.expiration_date:
|
||||
attributes.append(["datetime", properties.expiration_date.value, "expiration-date"])
|
||||
if properties.nameservers:
|
||||
for nameserver in properties.nameservers:
|
||||
attributes.append(["hostname", nameserver.value.value, "nameserver"])
|
||||
if properties.ip_address:
|
||||
attributes.append(["ip-dst", properties.ip_address.value, "ip-address"])
|
||||
required_one_of = True
|
||||
if properties.domain_name:
|
||||
attribute_type = "domain"
|
||||
attributes.append([attribute_type, properties.domain_name.value, attribute_type])
|
||||
required_one_of = True
|
||||
# Testing if we have the required attribute types for Object whois
|
||||
if required_one_of:
|
||||
# if yes, we return the object type and the attributes
|
||||
return "whois", self.return_attributes(attributes), ""
|
||||
else:
|
||||
# otherwise, attributes are added in the event, and one attribute is returned to not make the function crash
|
||||
if len(attributes) == 1:
|
||||
return attributes[0]
|
||||
last_attribute = attributes.pop(-1)
|
||||
for attribute in attributes:
|
||||
attribute_type, attribute_value, attribute_relation = attribute
|
||||
misp_attributes = {"comment": "Whois {}".format(attribute_relation)}
|
||||
self.misp_event.add_attribute(attribute_type, attribute_value, **misp_attributes)
|
||||
return last_attribute
|
||||
|
||||
def handle_pe(self, properties):
|
||||
pe_uuid = self.parse_pe(properties)
|
||||
file_type, file_value, _ = self.handle_file(properties, False)
|
||||
return file_type, file_value, pe_uuid
|
||||
|
||||
def parse_pe(self, properties):
|
||||
misp_object = MISPObject('pe')
|
||||
filename = properties.file_name.value
|
||||
for attr in ('internal-filename', 'original-filename'):
|
||||
misp_object.add_attribute(**dict(zip(('type', 'value', 'object_relation'),('filename', filename, attr))))
|
||||
if properties.headers:
|
||||
headers = properties.headers
|
||||
header_object = MISPObject('pe-section')
|
||||
if headers.entropy:
|
||||
header_object.add_attribute(**{"type": "float", "object_relation": "entropy",
|
||||
"value": headers.entropy.value.value})
|
||||
file_header = headers.file_header
|
||||
misp_object.add_attribute(**{"type": "counter", "object_relation": "number-sections",
|
||||
"value": file_header.number_of_sections.value})
|
||||
for h in file_header.hashes:
|
||||
hash_type, hash_value, hash_relation = self.handle_hashes_attribute(h)
|
||||
header_object.add_attribute(**{"type": hash_type, "value": hash_value, "object_relation": hash_relation})
|
||||
if file_header.size_of_optional_header:
|
||||
header_object.add_attribute(**{"type": "size-in-bytes", "object_relation": "size-in-bytes",
|
||||
"value": file_header.size_of_optional_header.value})
|
||||
self.misp_event.add_object(**header_object)
|
||||
misp_object.add_reference(header_object.uuid, 'pe-section')
|
||||
if properties.sections:
|
||||
for section in properties.sections:
|
||||
section_uuid = self.parse_pe_section(section)
|
||||
misp_object.add_reference(section_uuid, 'pe-section')
|
||||
self.misp_event.add_object(**misp_object)
|
||||
return {"pe_uuid": misp_object.uuid}
|
||||
|
||||
def parse_pe_section(self, section):
|
||||
section_object = MISPObject('pe-section')
|
||||
header_hashes = section.header_hashes
|
||||
for h in header_hashes:
|
||||
hash_type, hash_value, hash_relation = self.handle_hashes_attribute(h)
|
||||
section_object.add_attribute(**{"type": hash_type, "value": hash_value, "object_relation": hash_relation})
|
||||
if section.entropy:
|
||||
section_object.add_attribute(**{"type": "float", "object_relation": "entropy",
|
||||
"value": section.entropy.value.value})
|
||||
if section.section_header:
|
||||
section_header = section.section_header
|
||||
section_object.add_attribute(**{"type": "text", "object_relation": "name",
|
||||
"value": section_header.name.value})
|
||||
section_object.add_attribute(**{"type": "size-in-bytes", "object_relation": "size-in-bytes",
|
||||
"value": section_header.size_of_raw_data.value})
|
||||
self.misp_event.add_object(**section_object)
|
||||
return section_object.uuid
|
||||
|
||||
def parse_misp_object(self, indicator):
|
||||
object_type = str(indicator.relationship)
|
||||
if object_type == 'file':
|
||||
item = indicator.item
|
||||
self.fill_misp_object(item, object_type)
|
||||
elif object_type == 'network':
|
||||
item = indicator.item
|
||||
name = item.title.split(' ')[0]
|
||||
if name not in ('passive-dns'):
|
||||
self.fill_misp_object(item, name)
|
||||
else:
|
||||
if object_type != "misc":
|
||||
print("Unparsed Object type: {}".format(name))
|
||||
|
||||
def fill_misp_object(self, item, name):
|
||||
misp_object = MISPObject(name)
|
||||
misp_object.timestamp = self.getTimestampfromDate(item.timestamp)
|
||||
try:
|
||||
observables = item.observable.observable_composition.observables
|
||||
for observable in observables:
|
||||
properties = observable.object_.properties
|
||||
self.parse_observable(properties, misp_object)
|
||||
except AttributeError:
|
||||
properties = item.observable.object_.properties
|
||||
self.parse_observable(properties, misp_object)
|
||||
self.misp_event.add_object(**misp_object)
|
||||
|
||||
def parse_observable(self, properties, misp_object):
|
||||
misp_attribute = MISPAttribute()
|
||||
misp_attribute.type, misp_attribute.value, misp_attribute.object_relation = self.handle_attribute_type(properties, is_object=True)
|
||||
misp_object.add_attribute(**misp_attribute)
|
||||
|
||||
def parse_external_indicator(self, indicators):
|
||||
for indicator in indicators:
|
||||
try:
|
||||
properties = indicator.observable.object_.properties
|
||||
except:
|
||||
self.parse_description(indicator)
|
||||
continue
|
||||
attribute = {'type': attrType, 'GalaxyCluster': []}
|
||||
cluster = {'type': attrType}
|
||||
if properties:
|
||||
attribute_type, attribute_value, compl_data = self.handle_attribute_type(properties)
|
||||
if type(attribute_value) is str:
|
||||
# if the returned value is a simple value, we build an attribute
|
||||
attribute = {'to_ids': True}
|
||||
if indicator.timestamp:
|
||||
attribute['timestamp'] = self.getTimestampfromDate(indicator.timestamp)
|
||||
self.handle_attribute_case(attribute_type, attribute_value, compl_data, attribute)
|
||||
else:
|
||||
# otherwise, it is a dictionary of attributes, so we build an object
|
||||
self.handle_object_case(attribute_type, attribute_value, compl_data)
|
||||
|
||||
def parse_external_observable(self, observables):
|
||||
for observable in observables:
|
||||
title = observable.title
|
||||
try:
|
||||
cluster['description'] = attr['short_description']
|
||||
properties = observable.object_.properties
|
||||
except:
|
||||
cluster['description'] = attr.get('description')
|
||||
if 'names' in attr:
|
||||
synonyms = []
|
||||
for name in attr.get('names'):
|
||||
synonyms.append(name)
|
||||
cluster['meta'] = {'synonyms': synonyms}
|
||||
cluster['value'] = ttp.get('title')
|
||||
attribute['GalaxyCluster'].append(cluster)
|
||||
mispDict['Galaxy'].append(attribute)
|
||||
self.parse_description(observable)
|
||||
continue
|
||||
if properties:
|
||||
attribute_type, attribute_value, compl_data = self.handle_attribute_type(properties, title=title)
|
||||
attr_type = type(attribute_value)
|
||||
if attr_type is str or attr_type is int:
|
||||
# if the returned value is a simple value, we build an attribute
|
||||
attribute = {'to_ids': False}
|
||||
self.handle_attribute_case(attribute_type, attribute_value, compl_data, attribute)
|
||||
else:
|
||||
# otherwise, it is a dictionary of attributes, so we build an object
|
||||
self.handle_object_case(attribute_type, attribute_value, compl_data)
|
||||
|
||||
def fillExternalAttribute(properties):
|
||||
if 'hashes' in properties:
|
||||
hashes = properties['hashes'][0]
|
||||
try:
|
||||
typeVal = hashes.get('type').lower()
|
||||
except:
|
||||
typeVal = hashes['type'].get('value').lower()
|
||||
value = hashes.get('simple_hash_value')
|
||||
if type(value) is dict:
|
||||
value = value.get('value')
|
||||
else:
|
||||
attrType = properties.get('xsi:type')
|
||||
if attrType == 'AddressObjectType':
|
||||
if 'email' in properties.get('category'):
|
||||
typeVal = eventTypes[attrType]['email']
|
||||
else:
|
||||
try:
|
||||
if properties.get('is_source') == 'false':
|
||||
typeVal = eventTypes[properties.get('category')].get('dst')
|
||||
else:
|
||||
typeVal = eventTypes[properties.get('category')].get('src')
|
||||
except:
|
||||
typeVal = "ip-src"
|
||||
elif attrType == 'HTTPSessionObjectType':
|
||||
return "http-method", properties['http_request_response'][0]['http_client_request']['http_request_header']['raw_header']
|
||||
else:
|
||||
typeVal = eventTypes[properties.get('xsi:type')].get('type')
|
||||
if 'address_value' in properties:
|
||||
try:
|
||||
value = properties['address_value'].get('value')
|
||||
except:
|
||||
value = properties.get('address_value')
|
||||
else:
|
||||
value = properties.get('value')
|
||||
return typeVal, value
|
||||
def parse_description(self, stix_object):
|
||||
if stix_object.description:
|
||||
misp_attribute = {}
|
||||
if stix_object.timestamp:
|
||||
misp_attribute['timestamp'] = self.getTimestampfromDate(stix_object.timestamp)
|
||||
self.misp_event.add_attribute("text", stix_object.description.value, **misp_attribute)
|
||||
|
||||
def fillMispAttribute(prop, category):
|
||||
properties = prop['properties']
|
||||
try:
|
||||
cat = properties["category"]
|
||||
except:
|
||||
cat = properties["xsi:type"]
|
||||
if 'ip' in cat:
|
||||
if properties.get("is_source"):
|
||||
attr_type = "src"
|
||||
else:
|
||||
attr_type = "dst"
|
||||
typeVal = eventTypes[cat][attr_type]
|
||||
value = eventTypes[cat]["value"]
|
||||
valueVal = properties[value]["value"]
|
||||
relation = 'ip'
|
||||
elif cat == 'EmailMessageObjectType':
|
||||
try:
|
||||
header = properties["header"]
|
||||
emailType = list(header)[0]
|
||||
typeVal = eventTypes[emailType]["type"]
|
||||
value = eventTypes[emailType]["value"]
|
||||
headerVal = header[emailType]
|
||||
if emailType == "to":
|
||||
headerVal = headerVal[0]
|
||||
elif emailType == "from":
|
||||
headerVal = headerVal["address_value"]
|
||||
valueVal = headerVal.get(value)
|
||||
relation = eventTypes[emailType]['relation']
|
||||
except:
|
||||
attachmentProp = prop['related_objects'][0]['properties']
|
||||
if attachmentProp.get('xsi:type') == 'FileObjectType':
|
||||
typeVal = 'email-attachment'
|
||||
propCat = eventTypes[typeVal]['value']
|
||||
valueVal = attachmentProp[propCat].get('value')
|
||||
relation = eventTypes[typeVal]['relation']
|
||||
elif cat == "FileObjectType" and "hashes" in properties:
|
||||
hashes = properties['hashes'][0]
|
||||
if 'file_name' in properties:
|
||||
type2 = hashes["type"].get("value").lower()
|
||||
typeVal = 'filename|{}'.format(type2)
|
||||
value1 = properties['file_name'].get('value')
|
||||
value2 = hashes["simple_hash_value"].get("value")
|
||||
valueVal = '{}|{}'.format(value1, value2)
|
||||
relation = None
|
||||
else:
|
||||
if category == 'Network activity':
|
||||
typeVal = 'x509-fingerprint-sha1'
|
||||
else:
|
||||
typeVal = hashes["type"].get("value").lower()
|
||||
valueVal = hashes["simple_hash_value"].get("value")
|
||||
relation = typeVal
|
||||
elif cat == "HTTPSessionObjectType":
|
||||
http = properties["http_request_response"][0]
|
||||
httpAttr = http["http_client_request"]["http_request_header"]["parsed_header"]
|
||||
attrVal = list(httpAttr)[0]
|
||||
valueVal = httpAttr.get(attrVal)
|
||||
typeVal = eventTypes[attrVal]
|
||||
relation = 'user-agent'
|
||||
elif cat == "WindowsRegistryKeyObjectType":
|
||||
valueVal = ""
|
||||
if properties['hive'].get('value') == "HKEY_LOCAL_MACHINE":
|
||||
valueVal += "HKLM\\"
|
||||
valueVal += properties['key'].get('value')
|
||||
typeVal = "regkey"
|
||||
relation = "key"
|
||||
else:
|
||||
value = eventTypes[cat]["value"]
|
||||
typeVal = eventTypes[cat]["type"]
|
||||
valueVal = properties[value]["value"]
|
||||
relation = eventTypes[cat]["relation"]
|
||||
return typeVal, valueVal, relation
|
||||
def handle_attribute_case(self, attribute_type, attribute_value, data, attribute):
|
||||
if attribute_type == 'attachment':
|
||||
attribute['data'] = data
|
||||
self.misp_event.add_attribute(attribute_type, attribute_value, **attribute)
|
||||
|
||||
def handle_object_case(self, attribute_type, attribute_value, compl_data):
|
||||
misp_object = MISPObject(attribute_type)
|
||||
for attribute in attribute_value:
|
||||
misp_object.add_attribute(**attribute)
|
||||
if type(compl_data) is dict and "pe_uuid" in compl_data:
|
||||
# if some complementary data is a dictionary containing an uuid,
|
||||
# it means we are using it to add an object reference of a pe object
|
||||
# in a file object
|
||||
misp_object.add_reference(compl_data['pe_uuid'], 'pe')
|
||||
self.misp_event.add_object(**misp_object)
|
||||
|
||||
def saveFile(namefile, pathname, misp):
|
||||
filepath = "{}/tmp/{}".format(pathname, namefile)
|
||||
eventDict = misp.to_json()
|
||||
with open(filepath, 'w') as f:
|
||||
f.write(eventDict)
|
||||
def parse_ttps(self, ttps):
|
||||
galaxies = []
|
||||
for ttp in ttps:
|
||||
if ttp.behavior and ttp.behavior.malware_instances:
|
||||
mi = ttp.behavior.malware_instances[0]
|
||||
if mi.types:
|
||||
mi_type = mi.types[0].value
|
||||
galaxy = {'type': mi_type, 'GalaxyCluster': []}
|
||||
cluster = {'type': mi_type}
|
||||
if mi.description:
|
||||
cluster['description'] = mi.description.value
|
||||
cluster['value'] = ttp.title
|
||||
galaxy['GalaxyCluster'].append(cluster)
|
||||
galaxies.append(galaxy)
|
||||
self.misp_event['Galaxy'] = galaxies
|
||||
|
||||
@staticmethod
|
||||
def return_attributes(attributes):
|
||||
return_attributes = []
|
||||
for attribute in attributes:
|
||||
return_attributes.append(dict(zip(('type', 'value', 'object_relation'), attribute)))
|
||||
return return_attributes
|
||||
|
||||
def saveFile(self):
|
||||
eventDict = self.misp_event.to_json()
|
||||
with open(self.outputname, 'w') as f:
|
||||
f.write(eventDict)
|
||||
|
||||
def main(args):
|
||||
pathname = os.path.dirname(args[0])
|
||||
stixEvent, isJson, fromMISP, stixJson = loadEvent(args, pathname)
|
||||
if isJson:
|
||||
namefile = args[1]
|
||||
else:
|
||||
namefile = '{}.json'.format(args[1])
|
||||
if fromMISP:
|
||||
stixEvent = stixEvent["package"]
|
||||
mispDict = buildMispDict(stixEvent)
|
||||
else:
|
||||
if stixJson:
|
||||
mispDict = buildExternalDict(stixEvent)
|
||||
else:
|
||||
mispDict = buildExternalDict_fromPackage(stixEvent)
|
||||
misp = pymisp.MISPEvent(None, False)
|
||||
misp.from_dict(**mispDict)
|
||||
saveFile(namefile, pathname, misp)
|
||||
stix_parser = StixParser()
|
||||
stix_parser.loadEvent(args, pathname)
|
||||
stix_parser.handler()
|
||||
stix_parser.saveFile()
|
||||
print(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 1b4cb19909c32f3c721e48d123e9ffbd43ea4336
|
||||
Subproject commit 4996ebb4a2ebbf70ddb2714b32458d62fcd0d5c1
|
|
@ -1 +1 @@
|
|||
Subproject commit 42c5cf055c26119bc3931399f98a8a3c7bd0253d
|
||||
Subproject commit f54d241f2b159114224db2e8447e2c8bcf36ed8e
|
|
@ -31,7 +31,7 @@ class EventGraph {
|
|||
this.mapping_meta_fa.set('file', {"meta-category": "file","fa_text": "file","fa-hex": "f15b"});
|
||||
this.mapping_meta_fa.set('financial', {"meta-category": "financial","fa_text": "money-bil-alt","fa-hex": "f3d1"});
|
||||
this.mapping_meta_fa.set('network', {"meta-category": "network","fa_text": "server","fa-hex": "f233"});
|
||||
this.mapping_meta_fa.set('misc', {"meta-category": "misc","fa_text": "cube","fa-hex": "f1b2"});
|
||||
this.mapping_meta_fa.set('misc', {"meta-category": "misc","fa_text": "cube","fa-hex": "f1b2"}); // Also considered as default
|
||||
// FIXME
|
||||
this.network_options = network_options;
|
||||
this.globalCounter = 0;
|
||||
|
@ -77,6 +77,11 @@ class EventGraph {
|
|||
get_node_color(uuid) {
|
||||
return this.nodes.get(uuid).icon.color;
|
||||
}
|
||||
get_FA_icon(metaCateg) {
|
||||
var dict = this.mapping_meta_fa.get(metaCateg);
|
||||
dict = dict === undefined ? this.mapping_meta_fa.get('misc') : dict; // if unknown meta-categ, take default
|
||||
return String.fromCharCode(parseInt(dict['fa-hex'], 16))
|
||||
}
|
||||
getUniqId() {
|
||||
this.globalCounter++;
|
||||
return this.globalCounter-1;
|
||||
|
@ -347,7 +352,7 @@ class EventGraph {
|
|||
icon: {
|
||||
color: getRandomColor(),
|
||||
face: 'FontAwesome',
|
||||
code: String.fromCharCode(parseInt(this.mapping_meta_fa.get(node['meta-category'])['fa-hex'], 16)),
|
||||
code: this.get_FA_icon(node['meta-category']),
|
||||
}
|
||||
};
|
||||
dataHandler.mapping_value_to_nodeID.set(striped_value, node.id);
|
||||
|
|
|
@ -639,7 +639,7 @@ function multiSelectDeleteEvents() {
|
|||
});
|
||||
}
|
||||
|
||||
function multiSelectToggleFeeds(on) {
|
||||
function multiSelectToggleFeeds(on, cache) {
|
||||
var selected = [];
|
||||
$(".select").each(function() {
|
||||
if ($(this).is(":checked")) {
|
||||
|
@ -649,7 +649,7 @@ function multiSelectToggleFeeds(on) {
|
|||
}
|
||||
}
|
||||
});
|
||||
$.get("/feeds/toggleSelected/" + on + "/" + JSON.stringify(selected), function(data) {
|
||||
$.get("/feeds/toggleSelected/" + on + "/" + cache + "/" + JSON.stringify(selected), function(data) {
|
||||
$("#confirmation_box").html(data);
|
||||
openPopup("#confirmation_box");
|
||||
});
|
||||
|
@ -1268,7 +1268,7 @@ function simplePopup(url) {
|
|||
error:function() {
|
||||
$(".loading").hide();
|
||||
$("#gray_out").fadeOut();
|
||||
showMessage('fail', 'Could not fetch the given PGP key.');
|
||||
showMessage('fail', 'Could not fetch the given GnuPG key.');
|
||||
},
|
||||
url: url,
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue