diff --git a/app/Controller/EventsController.php b/app/Controller/EventsController.php index c65a98721..466c767ae 100644 --- a/app/Controller/EventsController.php +++ b/app/Controller/EventsController.php @@ -2408,14 +2408,14 @@ class EventsController extends AppController } if (isset($this->params['named']['distribution'])) { $distribution = intval($this->params['named']['distribution']); - if (array_key_exists($distribution, $distributionLevels)) { - $initialDistribution = $distribution; - } else { + if (!array_key_exists($distribution, $distributionLevels)) { throw new MethodNotAllowedException(__('Wrong distribution level')); } + } else { + $distribution = $initialDistribution; } $sharingGroupId = null; - if ($initialDistribution == 4) { + if ($distribution == 4) { if (!isset($this->params['named']['sharing_group_id'])) { throw new MethodNotAllowedException(__('The sharing group id is needed when the distribution is set to 4 ("Sharing group").')); } @@ -2424,8 +2424,25 @@ class EventsController extends AppController throw new MethodNotAllowedException(__('Please select a valid sharing group id.')); } } + $clusterDistribution = $initialDistribution; + $clusterSharingGroupId = null; if (isset($this->params['named']['galaxies_as_tags'])) { $galaxies_as_tags = $this->params['named']['galaxies_as_tags']; + if (isset($this->params['name']['cluster_distribution'])) { + $clusterDistribution = intval($this->params['named']['cluster_distribution']); + if (!array_key_exists($clusterDistribution, $distributionLevels)) { + throw new MethodNotAllowedException(__('Wrong cluster distribution level')); + } + if ($clusterDistribution == 4) { + if (!isset($this->params['named']['cluster_sharing_group_id'])) { + throw new MethodNotAllowedException(__('The cluster sharing group id is needed when the cluster distribution is set to 4 ("Sharing group").')); + } + $clusterSharingGroupId = intval($this->params['named']['cluster_sharing_group_id']); + if (!array_key_exists($clusterSharingGroupId, $sgs)) { + throw new MethodNotAllowedException(__('Please select a valid cluster sharing group id.')); + } + } + } } if (isset($this->params['named']['debugging'])) { $debug = $this->params['named']['debugging']; @@ -2437,9 +2454,11 @@ class EventsController extends AppController $stix_version, 'uploaded_stix_file.' . ($stix_version == '1' ? 'xml' : 'json'), $publish, - $initialDistribution, + $distribution, $sharingGroupId, $galaxies_as_tags, + $clusterDistribution, + $clusterSharingGroupId, $debug ); if (is_numeric($result)) { @@ -2471,6 +2490,8 @@ class EventsController extends AppController $this->data['Event']['distribution'], $this->data['Event']['sharing_group_id'] ?? null, $this->data['Event']['galaxies_handling'], + $this->data['Event']['cluster_distribution'], + $this->data['Event']['cluster_sharing_group_id'] ?? null, $debug ); if (is_numeric($result)) { diff --git a/app/Model/Event.php b/app/Model/Event.php index 834db06b0..342337a45 100755 --- a/app/Model/Event.php +++ b/app/Model/Event.php @@ -5995,15 +5995,17 @@ class Event extends AppModel * @param int $distribution * @param int|null $sharingGroupId * @param bool $galaxiesAsTags + * @param int $clusterDistribution + * @param int|null $clusterSharingGroupId * @param bool $debug * @return int|string|array * @throws JsonException * @throws InvalidArgumentException * @throws Exception */ - public function upload_stix(array $user, $file, $stixVersion, $originalFile, $publish, $distribution, $sharingGroupId, $galaxiesAsTags, $debug = false) + public function upload_stix(array $user, $file, $stixVersion, $originalFile, $publish, $distribution, $sharingGroupId, $galaxiesAsTags, $clusterDistribution, $clusterSharingGroupId, $debug = false) { - $decoded = $this->convertStixToMisp($stixVersion, $file, $distribution, $sharingGroupId, $galaxiesAsTags, $debug); + $decoded = $this->convertStixToMisp($stixVersion, $file, $distribution, $sharingGroupId, $galaxiesAsTags, $clusterDistribution, $clusterSharingGroupId, $user['Organisation']['uuid'], $debug); if (!empty($decoded['success'])) { $data = JsonTool::decodeArray($decoded['converted']); @@ -6067,11 +6069,14 @@ class Event extends AppModel * @param int $distribution * @param int|null $sharingGroupId * @param bool $galaxiesAsTags + * @param int $clusterDistribution + * @param int|null $clusterSharingGroupId + * @param string $orgUuid * @param bool $debug * @return array * @throws Exception */ - private function convertStixToMisp($stixVersion, $file, $distribution, $sharingGroupId, $galaxiesAsTags, $debug) + private function convertStixToMisp($stixVersion, $file, $distribution, $sharingGroupId, $galaxiesAsTags, $clusterDistribution, $clusterSharingGroupId, $orgUuid, $debug) { $scriptDir = APP . 'files' . DS . 'scripts'; if ($stixVersion === '2' || $stixVersion === '2.0' || $stixVersion === '2.1') { @@ -6082,12 +6087,18 @@ class Event extends AppModel $scriptFile, '-i', $file, '--distribution', $distribution, + '--org_uuid', $orgUuid ]; if ($distribution == 4) { array_push($shellCommand, '--sharing_group_id', $sharingGroupId); } if ($galaxiesAsTags) { $shellCommand[] = '--galaxies_as_tags'; + } else { + array_push($shell_command, '--cluster_distribution', $clusterDistribution); + if ($clusterDistribution == 4) { + array_push($shell_command, '--cluster_sharing_group_id', $clusterSharingGroupId); + } } if ($debug) { $shellCommand[] = '--debug'; diff --git a/app/View/Events/upload_stix.ctp b/app/View/Events/upload_stix.ctp index 84ee2c1de..7e6bf1b53 100644 --- a/app/View/Events/upload_stix.ctp +++ b/app/View/Events/upload_stix.ctp @@ -28,10 +28,13 @@ 'selected' => $initialDistribution, )); if (!empty($sharingGroups)) { - echo $this->Form->input('sharing_group_id', array( - 'options' => array($sharingGroups), - 'label' => __('Sharing Group'), - )); + $SGContainer = $this->Form->input( + 'sharing_group_id', array( + 'options' => array($sharingGroups), + 'label' => __('Sharing Group'), + ) + ); + echo ''; } ?>
@@ -64,6 +67,36 @@ 'label' => __('How to handle Galaxies and Clusters') . $galaxiesFormInfo, 'selected' => 0 )); +?> +
+element( + 'genericElements/Form/formInfo', + [ + 'field' => [ + 'field' => 'cluster_distribution' + ], + 'modelForForm' => 'Event', + 'fieldDesc' => $fieldDesc['distribution'], + ] + ); + $clusterDistribution = $this->Form->input( + 'cluster_distribution', array( + 'options' => $distributionLevels, + 'label' => __('Cluster distribution ') . $clusterDistributionFormInfo, + 'selected' => $initialDistribution, + ) + ); + echo ''; + if (!empty($sharingGroups)) { + $clusterSGContainer = $this->Form->input( + 'cluster_sharing_group_id', array( + 'options' => array($sharingGroups), + 'label' => __('Cluster Sharing Group'), + ) + ); + echo ''; + } } if ($me['Role']['perm_site_admin'] && Configure::read('debug') > 0) { $debugFormInfo = $this->element( @@ -101,4 +134,26 @@ $(function(){ }); checkSharingGroup('Event'); }); +$(function(){ + $('#EventGalaxiesHandling').change(function() { + if ($(this).val() == 0) { + $('#ClusterDistribution').show(); + if ($('#EventClusterDistribution').val() == 4) { + $('#ClusterSGContainer').show(); + } + } else { + $('#ClusterDistribution').hide(); + $('#ClusterSGContainer').hide(); + } + }).change(); +}); +$(function(){ + $('#EventClusterDistribution').change(function() { + if ($(this).val() == 4 && $('#EventGalaxiesHandling').val() == 0) { + $('#ClusterSGContainer').show(); + } else { + $('#ClusterSGContainer').hide(); + } + }).change(); +}); \ No newline at end of file diff --git a/app/files/scripts/misp-stix b/app/files/scripts/misp-stix index b8b8b7445..dd3037ee7 160000 --- a/app/files/scripts/misp-stix +++ b/app/files/scripts/misp-stix @@ -1 +1 @@ -Subproject commit b8b8b7445754ea3cbc84e2d0b434ecd08740ef95 +Subproject commit dd3037ee7f31c1f43a3ad3aaaa6cccfa232dc530 diff --git a/app/files/scripts/stix2/stix2misp.py b/app/files/scripts/stix2/stix2misp.py index ae5b40c08..6fdad7073 100644 --- a/app/files/scripts/stix2/stix2misp.py +++ b/app/files/scripts/stix2/stix2misp.py @@ -29,10 +29,26 @@ sys.path.insert(2, str(_scripts_path / 'python-cybox')) sys.path.insert(3, str(_scripts_path / 'mixbox')) sys.path.insert(4, str(_scripts_path / 'misp-stix')) from misp_stix_converter import ( - ExternalSTIX2toMISPParser, InternalSTIX2toMISPParser, _from_misp) + ExternalSTIX2toMISPParser, InternalSTIX2toMISPParser, + MISP_org_uuid, _from_misp) from stix2.parsing import parse as stix2_parser +def _get_stix_parser(from_misp, args): + arguments = { + 'distribution': args.distribution, + 'galaxies_as_tags': args.galaxies_as_tags + } + if args.distribution == 4 and args.sharing_group_id is not None: + arguments['sharing_group_id'] = args.sharing_group_id + if from_misp: + return 'InternalSTIX2toMISPParser', arguments + arguments['cluster_distribution'] = args.cluster_distribution + if args.cluster_distribution == 4 and args.cluster_sharing_group_id is not None: + arguments['cluster_sharing_group_id'] = args.cluster_sharing_group_id + return 'ExternalSTIX2toMISPParser', arguments + + def _handle_return_message(traceback): if isinstance(traceback, dict): messages = [] @@ -51,14 +67,8 @@ def _process_stix_file(args: argparse.Namespace): f.read(), allow_custom=True, interoperability=True ) stix_version = getattr(bundle, 'version', '2.1') - to_call = 'Internal' if _from_misp(bundle.objects) else 'External' - arguments = { - 'distribution': args.distribution, - 'galaxies_as_tags': args.galaxies_as_tags - } - if args.distribution == 4 and args.sharing_group_id is not None: - arguments['sharing_group_id'] = args.sharing_group_id - parser = globals()[f'{to_call}STIX2toMISPParser'](**arguments) + to_call, arguments = _get_stix_parser(_from_misp(bundle.objects), args) + parser = globals()[to_call](**arguments) parser.load_stix_bundle(bundle) parser.parse_stix_bundle(single_event=True) with open(f'{args.input}.out', 'wt', encoding='utf-8') as f: @@ -94,6 +104,10 @@ if __name__ == '__main__': '-i', '--input', required=True, type=Path, help='Input file containing STIX 2 content.' ) + argparser.add_argument( + '--org_uuid', default=MISP_org_uuid, + help='Organisation UUID to use when creating custom Galaxy clusters.' + ) argparser.add_argument( '--distribution', type=int, default=0, help='Distribution level for the resulting MISP Event.' @@ -110,6 +124,14 @@ if __name__ == '__main__': '--galaxies_as_tags', action='store_true', help='Import MISP Galaxies as tag names.' ) + argparser.add_argument( + '--cluster_distribution', type=int, default=0, + help='Cluster distribution level for clusters generated from STIX 2.x objects' + ) + argparser.add_argument( + '--cluster_sharing_group_id', type=int, + help='Cluster sharing group id when the cluster distribution level is 4.' + ) try: args = argparser.parse_args() except SystemExit as e: