Merge branch 'module_rework2' into 2.4

pull/4832/head
iglocska 2019-07-01 09:51:07 +02:00
commit 9293a15e2f
No known key found for this signature in database
GPG Key ID: BEA224F1FEF113AC
9 changed files with 983 additions and 314 deletions

View File

@ -599,4 +599,21 @@ class EventShell extends AppShell
);
return true;
}
public function processmoduleresult()
{
$inputFile = $this->args[0];
$tempDir = new Folder(APP . 'tmp/cache/ingest', true, 0750);
$tempFile = new File(APP . 'tmp/cache/ingest' . DS . $inputFile);
$inputData = json_decode($tempFile->read(), true);
$tempFile->delete();
$this->Event->processModuleResultsData(
$inputData['user'],
$inputData['misp_format'],
$inputData['id'],
$inputData['default_comment'],
$inputData['jobId']
);
return true;
}
}

View File

@ -2922,6 +2922,36 @@ class AttributesController extends AppController
$resultArray[$type][] = array($type => 'Enrichment service not reachable.');
continue;
}
$current_result = array();
if (isset($result['results']['Object'])) {
if (!empty($result['results']['Object'])) {
$objects = array();
foreach($result['results']['Object'] as $object) {
if (isset($object['Attribute']) && !empty($object['Attribute'])) {
$object_attributes = array();
foreach($object['Attribute'] as $object_attribute) {
array_push($object_attributes, array('object_relation' => $object_attribute['object_relation'], 'value' => $object_attribute['value']));
}
array_push($objects, array('name' => $object['name'], 'Attribute' => $object_attributes));
}
}
if (!empty($objects)) {
$current_result['Object'] = $objects;
}
}
unset($result['results']['Object']);
}
if (isset($result['results']['Attribute'])) {
if (!empty($result['results']['Attribute'])) {
$attributes = array();
foreach($result['results']['Attribute'] as $attribute) {
array_push($attributes, array('type' => $attribute['type'], 'value' => $attribute['value']));
}
$current_result['Attribute'] = $attributes;
}
unset($result['results']['Attribute']);
}
$resultArray[$type] = $current_result;
if (!empty($result['results'])) {
foreach ($result['results'] as $r) {
if (is_array($r['values']) && !empty($r['values'])) {

View File

@ -5162,64 +5162,64 @@ class EventsController extends AppController
if (!is_array($result)) {
throw new Exception($result);
}
$defaultDistribution = 5;
if (!empty(Configure::read('MISP.default_attribute_distribution'))) {
$defaultDistribution = Configure::read('MISP.default_attribute_distribution');
if ($defaultDistribution == 'event') {
$defaultDistribution = 5;
}
}
$attributes = array();
$objects = array();
if (isset($result['results']['Attribute']) && !empty($result['results']['Attribute'])) {
foreach ($result['results']['Attribute'] as &$tmp_attribute) {
$tmp_attribute = $this->__fillAttribute($tmp_attribute, $defaultDistribution);
array_push($attributes, $tmp_attribute);
}
unset($result['results']['Attribute']);
}
if (isset($result['results']['Object']) && !empty($result['results']['Object'])) {
foreach ($result['results']['Object'] as $tmp_object) {
foreach ($tmp_object['Attribute'] as &$tmp_attribute) {
$tmp_attribute = $this->__fillAttribute($tmp_attribute, $defaultDistribution);
}
array_push($objects, $tmp_object);
}
unset($result['results']['Object']);
}
if (empty($attributes) && empty($objects)) {
$event = $this->Event->handleMispFormatFromModuleResult($result);
if (empty($event['Attribute']) && empty($event['Object'])) {
$this->__handleSimplifiedFormat($attribute, $module, $options, $result, $type);
} else {
$this->set('attributeValue', $attribute[0]['Attribute']['value']);
$this->set('module', $module);
$event = array('Event' => $attribute[0]['Event']);
$event['Attribute'] = $attributes;
$event['Object'] = $objects;
$this->set('event', $event);
if (!empty($result['results'])) {
$this->__handleSimplifiedFormat($attribute, $module, $options, $result, $type, $event = true, $render_name = 'resolved_misp_format');
} else {
$this->set('menuItem', 'enrichmentResults');
$this->set('title', 'Enrichment Results');
$this->render('resolved_misp_format');
$importComment = !empty($result['comment']) ? $result['comment'] : $attribute[0]['Attribute']['value'] . __(': Enriched via the ') . $module . ($type != 'Enrichment' ? ' ' . $type : '') . ' module';
$this->set('importComment', $importComment);
$event['Event'] = $attribute[0]['Event'];
$org_name = $this->Event->Orgc->find('first', array(
'conditions' => array('Orgc.id' => $event['Event']['orgc_id']),
'fields' => array('Orgc.name')
));
$event['Event']['orgc_name'] = $org_name['Orgc']['name'];
if ($attribute[0]['Object']['id']) {
$object_id = $attribute[0]['Object']['id'];
$initial_object = $this->Event->Object->find('first', array(
'conditions' => array('Object.id' => $object_id,
'Object.event_id' => $event_id,
'Object.deleted' => 0),
'recursive' => -1,
'fields' => array('Object.id', 'Object.uuid', 'Object.name')
));
if (!empty($initial_object)) {
$initial_attributes = $this->Event->Attribute->find('all', array(
'conditions' => array('Attribute.object_id' => $object_id,
'Attribute.deleted' => 0),
'recursive' => -1,
'fields' => array('Attribute.id', 'Attribute.uuid', 'Attribute.type',
'Attribute.object_relation', 'Attribute.value')
));
if (!empty($initial_attributes)) {
$initial_object['Attribute'] = array();
foreach ($initial_attributes as $initial_attribute) {
array_push($initial_object['Attribute'], $initial_attribute['Attribute']);
}
}
$initial_references = $this->Event->Object->ObjectReference->find('all', array(
'conditions' => array('ObjectReference.object_id' => $object_id,
'ObjectReference.event_id' => $event_id,
'ObjectReference.deleted' => 0),
'recursive' => -1,
'fields' => array('ObjectReference.referenced_uuid', 'ObjectReference.relationship_type')
));
if (!empty($initial_references)) {
$initial_object['ObjectReference'] = array();
foreach ($initial_references as $initial_reference) {
array_push($initial_object['ObjectReference'], $initial_reference['ObjectReference']);
}
}
$event['initialObject'] = $initial_object;
}
}
$this->set('event', $event);
$this->set('menuItem', 'enrichmentResults');
$this->set('title', 'Enrichment Results');
$this->render('resolved_misp_format');
}
}
private function __fillAttribute($attribute, $defaultDistribution)
{
if (!isset($attribute['category'])) {
$attribute['category'] = $this->Event->Attribute->typeDefinitions[$attribute['type']]['default_category'];
}
if (!isset($attribute['to_ids'])) {
$attribute['to_ids'] = $this->Event->Attribute->typeDefinitions[$attribute['type']]['to_ids'];
}
if (!isset($attribute['distribution'])) {
$attribute['distribution'] = $defaultDistribution;
}
return $attribute;
}
private function __queryOldEnrichment($attribute, $module, $options, $type)
{
$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']);
@ -5243,10 +5243,10 @@ class EventsController extends AppController
$this->__handleSimplifiedFormat($attribute, $module, $options, $result, $type);
}
private function __handleSimplifiedFormat($attribute, $module, $options, $result, $type, $event = false, $renderName = 'resolved_attributes')
private function __handleSimplifiedFormat($attribute, $module, $options, $result, $type, $event = false)
{
$resultArray = $this->Event->handleModuleResult($result, $attribute[0]['Attribute']['event_id']);
if (isset($result['comment']) && $result['comment'] != "") {
if (!empty($result['comment'])) {
$importComment = $result['comment'];
} else {
$importComment = $attribute[0]['Attribute']['value'] . __(': Enriched via the %s', $module) . ($type != 'Enrichment' ? ' ' . $type : '') . ' module';
@ -5283,10 +5283,10 @@ class EventsController extends AppController
$this->set('typeCategoryMapping', $typeCategoryMapping);
$this->set('title', 'Enrichment Results');
$this->set('importComment', $importComment);
$this->render($renderName);
$this->render('resolved_attributes');
}
public function handleModuleResults($eventId)
public function handleModuleResults($id)
{
if (!$this->userRole['perm_add']) {
throw new MethodNotAllowedException(__('Event not found or you don\'t have permissions to create attributes'));
@ -5295,6 +5295,15 @@ class EventsController extends AppController
if (!$this->Event->checkIfAuthorised($this->Auth->user(), $id)) {
throw new MethodNotAllowedException(__('Invalid event.'));
}
$resolved_data = json_decode($this->request->data['Event']['JsonObject'], true);
$data = json_decode($this->request->data['Event']['data'], true);
if (!empty($data['initialObject'])) {
$resolved_data['initialObject'] = $data['initialObject'];
}
unset($data);
$default_comment = $this->request->data['Event']['default_comment'];
$flashMessage = $this->Event->processModuleResultsDataRouter($this->Auth->user(), $resolved_data, $id, $default_comment);
$this->Flash->info($flashMessage);
$this->redirect(array('controller' => 'events', 'action' => 'view', $id));
} else {
throw new MethodNotAllowedException('This endpoint requires a POST request.');
@ -5400,34 +5409,44 @@ class EventsController extends AppController
if (!is_array($result)) {
throw new Exception($result);
}
$resultArray = $this->Event->handleModuleResult($result, $eventId);
if ($this->_isRest()) {
return $this->__pushFreetext(
$resultArray,
$eventId,
false,
false,
'soft'
);
}
if (isset($result['comment'])) {
$importComment = $result['comment'];
$importComment = !empty($result['comment']) ? $result['comment'] : 'Enriched via the ' . $module['name'] . ' module';
if (isset($module['mispattributes']['format']) && $module['mispattributes']['format'] === 'misp_standard') {
$event = $this->Event->handleMispFormatFromModuleResult($result);
$event['Event'] = array('id' => $eventId);
$this->set('event', $event);
$this->set('menuItem', 'importResults');
$render_name = 'resolved_misp_format';
} else {
$importComment = 'Enriched via the ' . $module['name'] . ' module';
}
$typeCategoryMapping = array();
foreach ($this->Event->Attribute->categoryDefinitions as $k => $cat) {
foreach ($cat['types'] as $type) {
$typeCategoryMapping[$type][$k] = $k;
$resultArray = $this->Event->handleModuleResult($result, $eventId);
if ($this->_isRest()) {
return $this->__pushFreetext(
$resultArray,
$eventId,
false,
false,
'soft'
);
}
}
foreach ($resultArray as $key => $result) {
$options = array(
'conditions' => array('OR' => array('Attribute.value1' => $result['value'], 'Attribute.value2' => $result['value'])),
'fields' => array('Attribute.type', 'Attribute.category', 'Attribute.value', 'Attribute.comment'),
'order' => false
);
$resultArray[$key]['related'] = $this->Event->Attribute->fetchAttributes($this->Auth->user(), $options);
$typeCategoryMapping = array();
foreach ($this->Event->Attribute->categoryDefinitions as $k => $cat) {
foreach ($cat['types'] as $type) {
$typeCategoryMapping[$type][$k] = $k;
}
}
foreach ($resultArray as $key => $result) {
$options = array(
'conditions' => array('OR' => array('Attribute.value1' => $result['value'], 'Attribute.value2' => $result['value'])),
'fields' => array('Attribute.type', 'Attribute.category', 'Attribute.value', 'Attribute.comment'),
'order' => false
);
$resultArray[$key]['related'] = $this->Event->Attribute->fetchAttributes($this->Auth->user(), $options);
}
$this->set('event', array('Event' => array('id' => $eventId)));
$this->set('resultArray', $resultArray);
$this->set('typeList', array_keys($this->Event->Attribute->typeDefinitions));
$this->set('defaultCategories', $this->Event->Attribute->defaultCategories);
$this->set('typeCategoryMapping', $typeCategoryMapping);
$render_name = 'resolved_attributes';
}
$distributions = $this->Event->Attribute->distributionLevels;
$sgs = $this->Event->SharingGroup->fetchAllAuthorised($this->Auth->user(), 'name', 1);
@ -5436,14 +5455,9 @@ class EventsController extends AppController
}
$this->set('distributions', $distributions);
$this->set('sgs', $sgs);
$this->set('event', array('Event' => array('id' => $eventId)));
$this->set('resultArray', $resultArray);
$this->set('typeList', array_keys($this->Event->Attribute->typeDefinitions));
$this->set('defaultCategories', $this->Event->Attribute->defaultCategories);
$this->set('typeCategoryMapping', $typeCategoryMapping);
$this->set('title', 'Import Results');
$this->set('importComment', $importComment);
$this->render('resolved_attributes');
$this->render($render_name);
}
}
$this->Flash->error($fail);

View File

@ -54,34 +54,7 @@ class ObjectReferencesController extends AppController
if (!isset($this->request->data['ObjectReference'])) {
$this->request->data['ObjectReference'] = $this->request->data;
}
$referenced_type = 1;
$target_object = $this->ObjectReference->Object->find('first', array(
'conditions' => array('Object.uuid' => $this->request->data['ObjectReference']['referenced_uuid'], 'Object.deleted' => 0),
'recursive' => -1,
'fields' => array('Object.id', 'Object.uuid', 'Object.event_id')
));
if (!empty($target_object)) {
$referenced_id = $target_object['Object']['id'];
$referenced_uuid = $target_object['Object']['uuid'];
if ($target_object['Object']['event_id'] != $object['Event']['id']) {
throw new NotFoundException('Invalid target. Target has to be within the same event.');
}
} else {
$target_attribute = $this->ObjectReference->Object->Attribute->find('first', array(
'conditions' => array('Attribute.uuid' => $this->request->data['ObjectReference']['referenced_uuid'], 'Attribute.deleted' => 0),
'recursive' => -1,
'fields' => array('Attribute.id', 'Attribute.uuid', 'Attribute.event_id')
));
if (empty($target_attribute)) {
throw new NotFoundException('Invalid target.');
}
if ($target_attribute['Attribute']['event_id'] != $object['Event']['id']) {
throw new NotFoundException('Invalid target. Target has to be within the same event.');
}
$referenced_id = $target_attribute['Attribute']['id'];
$referenced_uuid = $target_attribute['Attribute']['uuid'];
$referenced_type = 0;
}
list($referenced_id, $referenced_uuid, $referenced_type) = $this->ObjectReference->getReferencedInfo($this->request->data['ObjectReference']['referenced_uuid'], $object);
$relationship_type = empty($this->request->data['ObjectReference']['relationship_type']) ? '' : $this->request->data['ObjectReference']['relationship_type'];
if (!empty($this->request->data['ObjectReference']['relationship_type_select']) && $this->request->data['ObjectReference']['relationship_type_select'] !== 'custom') {
$relationship_type = $this->request->data['ObjectReference']['relationship_type_select'];

View File

@ -5270,6 +5270,60 @@ class Event extends AppModel
return $resultArray;
}
public function handleMispFormatFromModuleResult(&$result)
{
$defaultDistribution = 5;
if (!empty(Configure::read('MISP.default_attribute_distribution'))) {
$defaultDistribution = Configure::read('MISP.default_attribute_distribution');
if ($defaultDistribution == 'event') {
$defaultDistribution = 5;
}
}
$event = array();
if (!empty($result['results']['Attribute'])) {
$attributes = array();
foreach ($result['results']['Attribute'] as &$tmp_attribute) {
$tmp_attribute = $this->__fillAttribute($tmp_attribute, $defaultDistribution);
$attributes[] = $tmp_attribute;
}
$event['Attribute'] = $attributes;
}
if (!empty($result['results']['Object'])) {
$object = array();
foreach ($result['results']['Object'] as $tmp_object) {
$tmp_object['distribution'] = (isset($tmp_object['distribution']) ? (int)$tmp_object['distribution'] : $defaultDistribution);
$tmp_object['sharing_group_id'] = (isset($tmp_object['sharing_group_id']) ? (int)$tmp_object['sharing_group_id'] : 0);
if (!empty($tmp_object['Attribute'])) {
foreach ($tmp_object['Attribute'] as &$tmp_attribute) {
$tmp_attribute = $this->__fillAttribute($tmp_attribute, $defaultDistribution);
}
}
$objects[] = $tmp_object;
}
$event['Object'] = $objects;
}
foreach (array('Tag', 'Galaxy') as $field) {
if (!empty($result['results'][$field])) {
$event[$field] = $result['results'][$field];
}
}
return $event;
}
private function __fillAttribute($attribute, $defaultDistribution)
{
if (!isset($attribute['category'])) {
$attribute['category'] = $this->Event->Attribute->typeDefinitions[$attribute['type']]['default_category'];
}
if (!isset($attribute['to_ids'])) {
$attribute['to_ids'] = $this->Event->Attribute->typeDefinitions[$attribute['type']]['to_ids'];
}
$attribute['value'] = $this->Attribute->runRegexp($attribute['type'], $attribute['value']);
$attribute['distribution'] = (isset($attribute['distribution']) ? (int)$attribute['distribution'] : $defaultDistribution);
$attribute['sharing_group_id'] = (isset($attribute['sharing_group_id']) ? (int)$attribute['sharing_group_id'] : 0);
return $attribute;
}
public function export($user = false, $module = false, $options = array())
{
if (empty($user)) {
@ -5990,11 +6044,7 @@ class Event extends AppModel
}
}
}
if ($saved == 1) {
$messageScopeSaved = Inflector::singularize($messageScope);
} else {
$messageScopeSaved = Inflector::pluralize($messageScope);
}
$messageScopeSaved = $this-> __apply_inflector($saved, $messageScope);
if ($failed > 0) {
if ($failed == 1) {
$messageScopeFailed = Inflector::singularize($messageScope);
@ -6014,27 +6064,346 @@ class Event extends AppModel
return $message;
}
public function processModuleResultsData($user, $resolved_data, $id, $default_comment = '', $jobId = false, $adhereToWarninglists = false)
{
if ($jobId) {
$this->Job = ClassRegistry::init('Job');
$this->Job->id = $jobId;
}
$failed_attributes = $failed_objects = $failed_object_attributes = 0;
$saved_attributes = $saved_objects = $saved_object_attributes = 0;
$items_count = 0;
$failed = array();
$recovered_uuids = array();
foreach (array('Attribute', 'Object') as $feature) {
if (isset($resolved_data[$feature])) {
$items_count += count($resolved_data[$feature]);
}
}
if (!empty($resolved_data['Tag'])) {
foreach ($resolved_data['Tag'] as $tag) {
$tag_id = $this->EventTag->Tag->captureTag($tag, $user);
if ($tag_id) {
$this->EventTag->attachTagToEvent($id, $tag_id);
}
}
}
if (!empty($resolved_data['Attribute'])) {
$total_attributes = count($resolved_data['Attribute']);
foreach ($resolved_data['Attribute'] as $a => $attribute) {
$this->Attribute->create();
if (empty($attribute['comment'])) {
$attribute['comment'] = $default_comment;
}
$attribute['event_id'] = $id;
if ($this->Attribute->save($attribute)) {
$saved_attributes++;
if (!empty($attribute['Tag'])) {
foreach ($attribute['Tag'] as $tag) {
$tag_id = $this->Attribute->AttributeTag->Tag->captureTag($tag, $user);
if ($tag_id) {
$this->Attribute->AttributeTag->attachTagToAttribute($this->Attribute->id, $id, $tag_id);
}
}
}
} else {
$failed_attributes++;
$lastAttributeError = $this->Attribute->validationErrors;
$original_uuid = $this->Object->Attribute->find('first', array(
'conditions' => array('Attribute.event_id' => $id, 'Attribute.object_id' => 0, 'Attribute.deleted' => 0,
'Attribute.type' => $attribute['type'], 'Attribute.value' => $attribute['value']),
'recursive' => -1,
'fields' => array('Attribute.uuid')
));
if (!empty($original_uuid)) {
$recovered_uuids[$attribute['uuid']] = $original_uuid['Attribute']['uuid'];
} else {
$failed[] = $attribute['uuid'];
}
}
if ($jobId) {
$current = ($a + 1);
$this->Job->saveField('message', 'Attribute ' . $current . '/' . $total_attributes);
$this->Job->saveField('progress', ($current * 100 / $items_count));
}
}
} else {
$total_attributes = 0;
}
if (!empty($resolved_data['Object'])) {
$initial_object_id = isset($resolved_data['initialObject']) ? $resolved_data['initialObject']['Object']['id'] : "0";
$total_objects = count($resolved_data['Object']);
$references = array();
foreach ($resolved_data['Object'] as $o => $object) {
$object['meta-category'] = $object['meta_category'];
unset($object['meta_category']);
$object['event_id'] = $id;
if (isset($object['id']) && $object['id'] == $initial_object_id) {
$initial_object = $resolved_data['initialObject'];
$recovered_uuids[$object['uuid']] = $initial_object['Object']['uuid'];
if ($object['name'] != $initial_object['Object']['name']) {
throw new NotFoundException(__('Invalid object.'));
}
$initial_attributes = array();
if (!empty($initial_object['Attribute'])) {
foreach ($initial_object['Attribute'] as $initial_attribute) {
$initial_attributes[$initial_attribute['object_relation']][] = $initial_attribute['value'];
}
}
$initial_references = array();
if (!empty($initial_object['ObjectReference'])) {
foreach ($initial_object['ObjectReference'] as $initial_reference) {
$initial_references[$initial_reference['relationship_type']][] = $initial_reference['referenced_uuid'];
}
}
if (!empty($object['Attribute'])) {
foreach ($object['Attribute'] as $object_attribute) {
$object_relation = $object_attribute['object_relation'];
if (isset($initial_attributes[$object_relation]) && in_array($object_attribute['value'], $initial_attributes[$object_relation])) {
continue;
}
if ($this->__saveObjectAttribute($object_attribute, $default_comment, $id, $initial_object_id, $user)) {
$saved_object_attributes++;
} else {
$failed_object_attributes++;
$lastObjectAttributeError = $this->Attribute->validationErrors;
}
}
}
if (!empty($object['ObjectReference'])) {
foreach ($object['ObjectReference'] as $object_reference) {
array_push($references, array('objectId' => $initial_object_id, 'reference' => $object_reference));
}
}
$saved_objects++;
} else {
if (!empty($object['Attribute'])) {
$current_object_id = $this->__findCurrentObjectId($id, $object['Attribute']);
if ($current_object_id) {
$original_uuid = $this->Object->find('first', array(
'conditions' => array('Object.id' => $current_object_id, 'Object.event_id' => $id,
'Object.name' => $object['name'], 'Object.deleted' => 0),
'recursive' => -1,
'fields' => array('Object.uuid')
));
if (!empty($original_uuid)) {
$recovered_uuids[$object['uuid']] = $original_uuid['Object']['uuid'];
}
$object_id = $current_object_id;
} else {
$this->Object->create();
if ($this->Object->save($object)) {
$object_id = $this->Object->id;
foreach ($object['Attribute'] as $object_attribute) {
if ($this->__saveObjectAttribute($object_attribute, $default_comment, $id, $object_id, $user)) {
$saved_object_attributes++;
} else {
$failed_object_attributes++;
$lastObjectAttributeError = $this->Attribute->validationErrors;
}
}
$saved_objects++;
} else {
$failed_objects++;
$lastObjectError = $this->Object->validationErrors;
$failed[] = $object['uuid'];
continue;
}
}
} else {
$this->Object->create();
if ($this->Object->save($object)) {
$object_id = $this->Object->id;
$saved_objects++;
} else {
$failed_objects++;
$lastObjectError = $this->Object->validationErrors;
$failed[] = $object['uuid'];
continue;
}
}
if (!empty($object['ObjectReference'])) {
foreach($object['ObjectReference'] as $object_reference) {
array_push($references, array('objectId' => $object_id, 'reference' => $object_reference));
}
}
}
if ($jobId) {
$current = ($o + 1);
$this->Job->saveField('message', 'Object ' . $current . '/' . $total_objects);
$this->Job->saveField('progress', (($current + $total_attributes) * 100 / $items_count));
}
}
}
if (!empty($references)) {
$reference_errors = array();
foreach($references as $reference) {
$object_id = $reference['objectId'];
$reference = $reference['reference'];
if (in_array($reference['object_uuid'], $failed) || in_array($reference['referenced_uuid'], $failed)) {
continue;
}
if (isset($recovered_uuids[$reference['object_uuid']])) {
$reference['object_uuid'] = $recovered_uuids[$reference['object_uuid']];
}
if (isset($recovered_uuids[$reference['referenced_uuid']])) {
$reference['referenced_uuid'] = $recovered_uuids[$reference['referenced_uuid']];
}
$current_reference = $this->Object->ObjectReference->find('all', array(
'conditions' => array('ObjectReference.object_id' => $object_id,
'ObjectReference.referenced_uuid' => $reference['referenced_uuid'],
'ObjectReference.relationship_type' => $reference['relationship_type'],
'ObjectReference.event_id' => $id, 'ObjectReference.deleted' => 0),
'recursive' => -1,
'fields' => ('ObjectReference.uuid')
));
if (!empty($current_reference)) {
continue;
}
list($referenced_id, $referenced_uuid, $referenced_type) = $this->Object->ObjectReference->getReferencedInfo(
$reference['referenced_uuid'],
array('Event' => array('id' => $id))
);
$reference = array(
'event_id' => $id,
'referenced_id' => $referenced_id,
'referenced_uuid' => $referenced_uuid,
'referenced_type' => $referenced_type,
'object_id' => $object_id,
'object_uuid' => $reference['object_uuid'],
'relationship_type' => $reference['relationship_type']
);
$this->Object->ObjectReference->create();
if (!$this->Object->ObjectReference->save($reference)) {
$reference_errors[] = $this->Object->ObjectReference->validationErrors;
}
}
}
if ($saved_attributes > 0 || $saved_objects > 0) {
$event = $this->find('first', array(
'conditions' => array('Event.id' => $id),
'recursive' => -1
));
if ($event['Event']['published'] == 1) {
$event['Event']['published'] = 0;
}
$date = new DateTime();
$event['Event']['timestamp'] = $date->getTimestamp();
$this->save($event);
}
$message = '';
if ($saved_attributes > 0) {
$message .= $saved_attributes . ' ' . $this->__apply_inflector($saved_attributes, 'attribute') . ' created. ';
}
if ($failed_attributes > 0) {
if ($failed_attributes == 1) {
$reason = ' attribute could not be saved. Reason for the failure: ' . json_encode($lastAttributeError) . ' ';
} else {
$reason = ' attributes could not be saved. This may be due to attributes with similar values already existing. ';
}
$message .= $failed_attributes . $reason;
}
if ($saved_objects > 0) {
$message .= $saved_objects . ' ' . $this->__apply_inflector($saved_objects, 'object') . ' created';
if ($saved_object_attributes > 0) {
$message .= ' (including a total of ' . $saved_object_attributes . ' object ' . $this->__apply_inflector($saved_object_attributes, 'attribute') . '). ';
} else {
$message .= '. ';
}
}
if ($failed_objects > 0) {
if ($failed_objects == 1) {
$reason = ' object could not be saved. Reason for the failure: ';
} else {
$reason = ' objects could not be saved. An example of reason for the failure: ';
}
$message .= $failed_objects . $reason . json_encode($lastObjectError) . ' ';
}
if ($failed_object_attributes > 0) {
if ($failed_object_attributes == 1) {
$reason = 'object attribute could not be saved. Reason for the failure: ';
} else {
$reason = 'object attributes could not be saved. An example of reason for the failure: ';
}
$message .= 'By the way, ' . $failed_object_attributes . $reason . json_encode($lastObjectAttributeError) . '.';
}
if (!empty($reference_errors)) {
$reference_error = sizeof($reference_errors) == 1 ? 'a reference is' : 'some references are';
$message .= ' Also, be aware that ' . $reference_error . ' missing: ';
foreach ($reference_errors as $error) {
$message .= $error;
}
$message .= 'you can have a look at the module results view you just left, to compare.';
}
if ($jobId) {
$this->Job->saveField('message', 'Processing complete. ' . $message);
$this->Job->saveField('progress', 100);
}
return $message;
}
private function __apply_inflector($count, $scope)
{
return ($count == 1 ? Inflector::singularize($scope) : Inflector::pluralize($scope));
}
private function __findCurrentObjectId($event_id, $attributes)
{
$conditions = array();
foreach($attributes as $attribute) {
$conditions[] = array('AND' => array(
'Attribute.object_relation' => $attribute['object_relation'],
'Attribute.value' => $attribute['value'],
'Attribute.type' => $attribute['type']
));
}
$ids = array();
foreach ($this->Object->Attribute->find('all', array(
'conditions' => array(
'Attribute.event_id' => $event_id,
'Attribute.object_id !=' => 0,
'Attribute.deleted' => 0,
'OR' => $conditions
),
'recursive' => -1,
'fields' => array('Attribute.object_id'))) as $found_id) {
$ids[] = $found_id['Attribute']['object_id'];
}
$attributes_count = sizeof($attributes);
foreach (array_count_values($ids) as $id => $count) {
if ($count >= $attributes_count) {
return $id;
}
}
return 0;
}
private function __saveObjectAttribute($attribute, $default_comment, $event_id, $object_id, $user)
{
$attribute['object_id'] = $object_id;
$attribute['event_id'] = $event_id;
if (empty($attribute['comment'])) {
$attribute['comment'] = $default_comment;
}
$this->Attribute->create();
$attribute_save = $this->Attribute->save($attribute);
if ($attribute_save) {
if (!empty($attribute['Tag'])) {
foreach ($attribute['Tag'] as $tag) {
$tag_id = $this->Attribute->AttributeTag->Tag->captureTag($tag, $user);
if ($tag_id) {
$this->Attribute->AttributeTag->attachTagToAttribute($this->Attribute->id, $event_id, $tag_id);
}
}
}
}
return $attribute_save;
}
public function processFreeTextDataRouter($user, $attributes, $id, $default_comment = '', $force = false, $adhereToWarninglists = false)
{
if (Configure::read('MISP.background_jobs')) {
$job = ClassRegistry::init('Job');
$job->create();
$data = array(
'worker' => 'default',
'job_type' => 'process_freetext_data',
'job_input' => 'Event: ' . $id,
'status' => 0,
'retries' => 0,
'org_id' => $user['org_id'],
'org' => $user['Organisation']['name'],
'message' => 'Processing...',
);
$job->save($data);
$randomFileName = $this->generateRandomFileName() . '.json';
App::uses('Folder', 'Utility');
App::uses('File', 'Utility');
$tempdir = new Folder(APP . 'tmp/cache/ingest', true, 0755);
$tempFile = new File(APP . 'tmp/cache/ingest' . DS . $randomFileName, true, 0644);
list($job, $randomFileName, $tempFile) = $this->__initiateProcessJob($user, $id);
$tempData = array(
'user' => $user,
'attributes' => $attributes,
@ -6050,7 +6419,6 @@ class Event extends AppModel
return ($this->processFreeTextData($user, $attributes, $id, $default_comment = '', $force = false, $adhereToWarninglists = false));
}
$tempFile->close();
$jobId = $job->id;
$process_id = CakeResque::enqueue(
'prio',
'EventShell',
@ -6060,10 +6428,61 @@ class Event extends AppModel
$job->saveField('process_id', $process_id);
return 'Freetext ingestion queued for background processing. Attributes will be added to the event as they are being processed.';
} else {
return ($this->processFreeTextData($user, $attributes, $id, $default_comment = '', $force = false, $adhereToWarninglists = false));
return $this->processFreeTextData($user, $resolved_data, $id, $default_comment);
}
}
public function processModuleResultsDataRouter($user, $resolved_data, $id, $default_comment = '', $adhereToWarninglists = false)
{
if (Configure::read('MISP.background_jobs')) {
list($job, $randomFileName, $tempFile) = $this->__initiateProcessJob($user, $id, 'module_results');
$tempData = array(
'user' => $user,
'misp_format' => $resolved_data,
'id' => $id,
'default_comment' => $default_comment,
'jobId' => $job->id
);
$writeResult = $tempFile->write(json_encode($tempData));
if ($writeResult) {
$tempFile->close();
$process_id = CakeResque::enqueue(
'prio',
'EventShell',
array('processmoduleresult', $randomFileName),
true
);
$job->saveField('process_id', $process_id);
return 'Module results ingestion queued for background processing. Related data will be added to the event as it is being processed.';
}
$tempFile->delete();
}
return ($this->processModuleResultsData($user, $attributes, $id, $default_comment = ''));
}
private function __initiateProcessJob($user, $id, $format = 'freetext')
{
$job = ClassRegistry::init('Job');
$job->create();
$data = array(
'worker' => 'default',
'job_type' => __('process_' . $format . '_data'),
'job_input' => 'Event: ' . $id,
'status' => 0,
'retries' => 0,
'org_id' => $user['org_id'],
'org' => $user['Organisation']['name'],
'message' => 'Processing...'
);
$job->save($data);
$randomFileName = $this->generateRandomFileName() . '.json';
App::uses('Folder', 'Utility');
App::uses('File', 'Utility');
$tempdir = new Folder(APP . 'tmp/cache/ingest', true, 0755);
$tempFile = new File(APP . 'tmp/cache/ingest' . DS . $randomFileName, true, 0644);
return array($job, $randomFileName, $tempFile);
}
private function __attachReferences($user, &$event, $sgids, $fields)
{
if (!empty($event['Object'])) {

View File

@ -262,4 +262,37 @@ class ObjectReference extends AppModel
$result = $this->save(array('ObjectReference' => $reference));
return true;
}
public function getReferencedInfo($referencedUuid, $object)
{
$referenced_type = 1;
$target_object = $this->Object->find('first', array(
'conditions' => array('Object.uuid' => $referencedUuid, 'Object.deleted' => 0),
'recursive' => -1,
'fields' => array('Object.id', 'Object.uuid', 'Object.event_id')
));
if (!empty($target_object)) {
$referenced_id = $target_object['Object']['id'];
$referenced_uuid = $target_object['Object']['uuid'];
if ($target_object['Object']['event_id'] != $object['Event']['id']) {
throw new NotFoundException('Invalid target. Target has to be within the same event.');
}
} else {
$target_attribute = $this->Object->Attribute->find('first', array(
'conditions' => array('Attribute.uuid' => $referencedUuid, 'Attribute.deleted' => 0),
'recursive' => -1,
'fields' => array('Attribute.id', 'Attribute.uuid', 'Attribute.event_id')
));
if (empty($target_attribute)) {
throw new NotFoundException('Invalid target.');
}
if ($target_attribute['Attribute']['event_id'] != $object['Event']['id']) {
throw new NotFoundException('Invalid target. Target has to be within the same event.');
}
$referenced_id = $target_attribute['Attribute']['id'];
$referenced_uuid = $target_attribute['Attribute']['uuid'];
$referenced_type = 0;
}
return array($referenced_id, $referenced_uuid, $referenced_type);
}
}

View File

@ -1,8 +1,32 @@
<div style="overflow-y:auto;max-height:75vh">
<?php
foreach ($results as $enrichment_type => $enrichment_values):
echo sprintf('<span class="hover_enrichment_title blue">%s</span>: <br />', Inflector::humanize(h($enrichment_type)));
echo sprintf('<h5><span class="hover_enrichment_title blue">%s</span>:</h5>', Inflector::humanize(h($enrichment_type)));
if (empty($enrichment_values)) {
echo '<div style="padding: 2px;"><span class="empty_results_text red">Empty results</span></div>';
continue;
}
if (!empty($enrichment_values['Object'])) {
echo '<h6><span class="bold blue">Objects</span></h6>';
foreach ($enrichment_values['Object'] as $object) {
echo '<span class="object_name bold blue">' . h($object['name']) . '</span><br />';
foreach ($object['Attribute'] as $object_attribute) {
echo '<div style="padding: 2px;"><pre class="object_attribute">';
echo '<span class="attribute_object_relation bold blue">' . h($object_attribute['object_relation']) . '</span>';
echo ': <span class="attribute_value red">' . h($object_attribute['value']) . '</span></pre></div>';
}
}
unset($enrichment_values['Object']);
}
if (!empty($enrichment_values['Attribute'])) {
echo '<h6><span class="bold blue">Attributes</span><br />';
foreach ($enrichment_values['Attribute'] as $attribute) {
echo '<div style="padding: 2px;"><pre class="attribute">';
echo '<span class="attribute_type bold blue">' . h($attribute['type']) . '</span>';
echo ': <span class="attribute_value red">' . h($attribute['value']) . '</span></pre></div>';
}
unset($enrichment_values['Attribute']);
}
foreach ($enrichment_values as $attributes):
foreach ($attributes as $attribute):
echo '<div style="padding: 2px;">';
@ -12,9 +36,9 @@
echo '<span class="hover_enrichment_text blue">' . h($attribute_name) . ':</span>';
}
echo '<span><pre class="hover_enrichment_text red">' . h($attribute_value) . '</pre></span>';
}
}
} else {
echo '<span><pre class="hover_enrichment_text red ">' . h($attribute) . '</pre></span>';
echo '<span><pre class="hover_enrichment_text red ">' . h($attribute) . '</pre></span>';
}
echo '</div>';
endforeach;

View File

@ -1,103 +1,134 @@
<div class="index">
<h2><?php echo h($title); ?></h2>
<?php
$url = '/events/handleModuleResults/' . $event['Event']['id'];
$event_id = $event['Event']['id'];
$url = '/events/handleModuleResults/' . $event_id;
echo $this->Form->create('Event', array('url' => $url, 'class' => 'mainForm'));
$formSettings = array(
'type' => 'hidden',
'value' => json_encode($event, true)
);
echo $this->Form->input('data', $formSettings);
echo $this->Form->input('JsonObject', array(
'label' => false,
'type' => 'text',
'style' => 'display:none;',
'value' => ''
));
echo $this->Form->input('default_comment', array(
'label' => false,
'type' => 'text',
'style' => 'display:none;',
'value' => $importComment
));
echo $this->Form->end();
$scope = !empty($proposals) ? 'proposals of' : '';
$objects_array = array();
if (isset($event['Attribute'])) {
array_push($objects_array, 'attributes');
foreach (array('Attribute', 'Object') as $field) {
if (!empty($event[$field])) {
$objects_array[] = strtolower($field) . 's';
}
}
if (isset($event['Object'])) {
array_push($objects_array, 'objects');
if (empty($objects_array)) {
echo '<p>Results from the enrichment module for this attribute are empty.</p>';
} else {
$scope = join(' and ', $objects_array);
echo '<p>Below you can see the ' . $scope . ' that are to be created from the results of the enrichment module.</p>';
$table_data = array(array('key' => __('Event ID'), 'value' => $event_id));
$event_metadata = $event['Event'];
if (!empty($event_metadata['uuid'])) {
$table_data[] = array('key' => __('Event UUID'),
'value' => $event_metadata['uuid']);
}
if (!empty($event_metadata['orgc_id']) && !empty($event_metadata['orgc_name'])) {
$table_data[] = array('key' => __('Event creator org'), 'html' => sprintf(
'<a href=%s/organisations/view/%s>%s</a>',
$baseurl,
h($event['Event']['orgc_id']),
h($event['Event']['orgc_name'])
));
}
if (!empty($event_metadata['info'])) {
array('key' => __('Event info'), 'value' => $event['Event']['info']);
}
$attributes_count = isset($event['Attribute']) ? count($event['Attribute']) : 0;
$objects_count = isset($event['Object']) ? count($event['Object']) : 0;
if (!empty($event['Object'])) {
foreach ($event['Object'] as $object) {
if (!empty($object['Attribute'])) {
$attributes_count += count($object['Attribute']);
}
}
}
$objects_string = $objects_count > 1 ? ' Objects)' : 'Object)';
$count = $attributes_count . ' (' . $objects_count . $objects_string;
if (!empty($event['Tag'])) {
$table_data[] = array(
'key' => __('Tags'),
'html' => sprintf(
'<span class="eventTagContainer">%s</span>',
$this->element('ajaxTags', array(
'event' => $event,
'tags' => $event['Tag'],
'tagAccess' => ($isSiteAdmin || $me['org_id'] == $event['Event']['orgc_id']),
'static_tags_only' => 1
))
)
);
}
$table_data[] = array('key' => __('#Resolved Attributes'), 'value' => $count);
echo $this->element('genericElements/viewMetaTable', array('table_data' => $table_data));
}
if (isset($resultArray) && !in_array('attributes', $objects_array, true) && in_array('objects', $objects_array, true)) {
$scope .= __('simplified attributes and');
}
$scope .= !empty($objects_array) ? join(' and ', $objects_array) : 'simplified attributes';
if (!isset($importComment)) {
$importComment = $attributeValue . ': Enriched via the ' . $module . ' module';
}
?>
<p><?php echo __('Below you can see the %s that are to be created, from the results of the enrichment module.', $scope);?></p>
<?php
$attributeFields = array('category', 'type', 'value', 'uuid');
if (isset($event['Object']) && !empty($event['Object'])) {
$header_present = false;
$typesWithData = array('attachment', 'malware-sample');
if (!empty($event['Object'])) {
?>
<div class='MISPObjects' style="margin-bottom:40px;">
<h3><?php echo __('Objects'); ?></h3>
<?php
foreach ($event['Object'] as $o => $object) {
?>
<div class='MISPObject'>
<table style="width:25%;">
<tbody>
<?php if(isset($object['id']) && !empty($object['id'])) { ?>
<tr>
<td class="bold"><?php echo __('ID');?></td>
<td class='ObjectID'><?php echo h($object['id']); ?></td>
</tr>
<?php } ?>
<tr>
<td class="bold"><?php echo __('Name');?></td>
<td class='ObjectName'><?php echo h($object['name']); ?></td>
</tr>
<tr>
<td class="bold"><?php echo __('Meta Category');?></td>
<td class='ObjectMetaCategory'><?php echo h($object['meta-category']); ?></td>
</tr>
<tr>
<td class="bold"><?php echo __('UUID');?></td>
<td class='ObjectUUID' style='height:20px;width:60px;'><?php echo h($object['uuid']); ?></td>
</tr>
<tr>
<td class="bold"><?php echo __('Distribution');?></td>
<td style="width:60px;text-align:center;">
<select class='ObjectDistribution' style='padding:0px;height:20px;margin-bottom:0px;'>
<?php
foreach ($distributions as $distKey => $distValue) {
echo '<option value="' . $distKey . '" ' . ($distKey == $object['distribution'] ? 'selected="selected"' : '') . '>' . $distValue . '</option>';
}
?>
</select>
</td>
<div style="display:none;">
<select class='ObjectSharingGroup' style='padding:0px;height:20px;margin-top:3px;margin-bottom:0px;'>
<?php
foreach ($sgs as $sgKey => $sgValue) {
echo '<option value="' . h($sgKey) . '">' . h($sgValue) . '</option>';
}
?>
</select>
</div>
</tr>
</tbody>
</table>
<?php if (isset($object['ObjectReference']) && !empty($object['ObjectReference'])) { ?>
<table class='table table-striped table-condensed'>
<tbody>
<tr>
<td class="bold"><?php echo __('References:');?></td>
<th><?php echo __('Category');?></th>
<th><?php echo __('Type');?></th>
<th><?php echo __('Value');?></th>
<th><?php echo __('UUID');?></th>
<th><?php echo __('Tags');?></th>
<th><?php echo __('IDS');?></th>
<th><?php echo __('Disable Correlation');?></th>
<th><?php echo __('Comment');?></th>
<th><?php echo __('Distribution');?></th>
</tr>
<table class="ObjectReferences" style="margin-bottom:0px;text-align:left;width:50%;">
<thead>
<th><?php echo __('Relationship'); ?></th>
<th><?php echo __('Referenced name/type'); ?></th>
<th><?php echo __('Referenced uuid'); ?></th>
</thead>
<tbody>
<?php
<?php
$header_present = true;
foreach ($event['Object'] as $o => $object) {
?>
<tbody class='MISPObject'>
<tr class='tableHighlightBorderTop borderBlue blueRow' tabindex='0'>
<td colspan="7">
<?php if(!empty($object['id'])) { ?>
<span class="bold"><?php echo __('ID: ');?></span><span class="ObjectID"><?php echo h($object['id']); ?></span><br />
<?php } ?>
<span class="bold"><?php echo __('Name: ');?></span><span class="ObjectName"><?php echo h($object['name']); ?></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 $o; ?>_collapsible"></span><br />
<div id="Object_<?php echo $o; ?>_collapsible" class="collapse">
<span class="bold"><?php echo __('UUID: ');?></span><span class="ObjectUUID"><?php echo h($object['uuid']); ?></span><br />
<span class="bold"><?php echo __('Meta Category: ');?></span><span class="ObjectMetaCategory"><?php echo h($object['meta-category']); ?></span>
</div>
<span class="bold"><?php echo __('References: ')?></span>
<?php
if (!empty($object['ObjectReference'])) {
echo sizeof($object['ObjectReference']);
?>
<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 $o; ?>_references_collapsible"></span>
<div id="Object_<?php echo $o; ?>_references_collapsible" class="collapse">
<?php
foreach ($object['ObjectReference'] as $reference) {
echo '<tr class="ObjectReference">';
echo '<td class="Relationship">' . h($reference['relationship_type']) . '</td>';
echo '&nbsp;&nbsp;<span class="ObjectReference">';
echo '<span class="Relationship">' . h($reference['relationship_type']) . ' </span>';
$referenced_uuid = $reference['referenced_uuid'];
foreach ($event['Object'] as $object_reference) {
if ($referenced_uuid === $object_reference['uuid']) {
$name = $object_reference['name'];
$category = $object_reference['meta-category'];
$objectType = 'Object';
break;
}
}
@ -105,63 +136,97 @@
foreach ($event['Attribute'] as $attribute_reference) {
if ($referenced_uuid === $attribute_reference['uuid']) {
$name = $attribute_reference['type'];
$category = $attribute_reference['category'];
$objectType = 'Attribute';
break;
}
}
if (!isset($name)) {
$name = '';
$category = '';
$objectType = '';
}
}
echo '<td>' . h($name) . '</td>';
echo $objectType . ' <span class="ReferencedUUID">' . $referenced_uuid . '</span> (' . $name . ': ' . $category . ')</span><br />';
unset($name);
echo '<td class="ReferencedUUID">' . h($referenced_uuid) . '</td>';
echo '</tr>';
}
?>
</tbody>
</table>
<?php } ?>
<table class="ObjectAttributes table table-condensed table-striped" style="text-align:left;margin-bottom:20px;">
<thead>
<th><?php echo __('Attribute');?></th>
<th><?php echo __('Category');?></th>
<th><?php echo __('Type');?></th>
<th><?php echo __('Value');?></th>
<th><?php echo __('UUID');?></th>
<th><?php echo __('IDS');?></th>
<th><?php echo __('Disable Correlation');?></th>
<th><?php echo __('Comment');?></th>
<th><?php echo __('Distribution');?></th>
</thead>
<tbody>
<?php
echo '</div>';
} else {
echo 0;
}
?>
</td>
<td class="ObjectComment shortish"><?php echo (!empty($object['comment']) ? h($object['comment']) : ''); ?></td>
<td style="width:60px;text-align:center;">
<select class="ObjectDistribution" style="padding:0px;height:20px;margin-bottom:0px;">
<?php
foreach ($distributions as $distKey => $distValue) {
echo '<option value="' . h($distKey) . '" ' . ($distKey == $object['distribution'] ? 'selected="selected"' : '') . '>' . h($distValue) . '</option>';
}
?>
</select>
<div style="display:none;">
<select class='ObjectSharingGroup' style='padding:0px;height:20px;margin-top:3px;margin-bottom:0px;'>
<?php
foreach ($sgs as $sgKey => $sgValue) {
echo '<option value="' . h($sgKey) . '" ' . ($sgKey == $object['sharing_group_id'] ? 'selected="selected"' : '') . '>' . h($sgValue) . '</option>';
}
?>
</select>
</div>
</td>
</tr>
<?php
if (!empty($object['Attribute'])) {
$last_attribute = end($object['Attribute']);
foreach ($object['Attribute'] as $a => $attribute) {
echo '<tr class="ObjectAttribute">';
echo '<td class="ObjectRelation">' . h($attribute['object_relation']) . '</td>';
if ($attribute['distribution'] != 4) {
$attribute['distribution'] = $distributions[$attribute['distribution']];
} else {
$attribute['distribution'] = $sgs[$attribute['sharing_group_id']];
}
foreach ($attributeFields as $field) {
echo '<td class="Attribute' . ucfirst($field) . '">' . (isset($attribute[$field]) ? h($attribute[$field]) : '') . '</td>';
}
?>
<td class="short" style="width:40px;text-align:center;">
<input type="checkbox" class="AttributeToIds" <?php if (isset($attribute['to_ids']) && $attribute['to_ids']) echo 'checked'; ?>/>
$border_position = ($attribute == $last_attribute ? 'Bottom' : 'Center');
?>
<tr class="ObjectAttribute tableHighlightBorder<?php echo $border_position; ?> borderBlue">
<td class="ObjectCategory"><?php echo (isset($attribute['category']) ? h($attribute['category']) : ''); ?></td>
<td class="short">
<span class="ObjectRelation bold"><?php echo h($attribute['object_relation']); ?></span>:
<span class="AttributeType"><?php echo h($attribute['type']); ?></span>
</td>
<td class="AttributeValue limitedWidth"><?php echo h($attribute['value']); ?></td>
<?php if (in_array($attribute['type'], $typesWithData) && !empty($attribute['data'])) {?>
<input class='AttributeData' type='hidden' value="<?php echo h($attribute['data']); ?>"/>
<?php } ?>
<td class="AttributeUuid short"><?php echo h($attribute['uuid']); ?></td>
<td style="max-width:150px;width:10px;">
<?php if (!empty($attribute['Tag'])) { ?>
<span class="objectAttributeTagContainer">
<?php
foreach ($attribute['Tag'] as $tag) {
$tagText = explode('=', $tag['name']);
$tagText = trim(end($tagText), "\"");
$color = !empty($tag['colour']) ? $tag['colour'] : '#0088cc';
?>
<span style="display:inline-block;">
<span style="padding:1px;display:flex;white-space:nowrap;margin-right:2px;word-wrap:break-word;">
<span class="objectAttributeTag" style="display:inline-block;background-color:<?php echo h($color); ?>;color:white;" title="<?php echo h($tag['name']); ?>">
<?php echo h($tagText); ?>
</span>
</span>
</span>
<?php } ?>
</span>
<?php } ?>
</td>
<td class="short" style="width:40px;text-align:center;">
<input type="checkbox" class="AttributeDisableCorrelation" <?php if (isset($attribute['disable_correlation']) && $attribute['disable_correlation']) echo 'checked'; ?>/>
<input type="checkbox" class="AttributeToIds" <?php if (!empty($attribute['to_ids'])) echo 'checked'; ?>/>
</td>
<td class="short" style="width:40px;text-align:center;">
<input type="checkbox" class="AttributeDisableCorrelation" <?php if (!empty($attribute['disable_correlation'])) echo 'checked'; ?>/>
</td>
<td class="short">
<input type="text" class="AttributeComment" style="padding:0px;height:20px;margin-bottom:0px;" placeholder="<?php echo h($importComment); ?>" <?php if (isset($attribute['comment']) && $attribute['comment'] !== false) echo 'value="' . h($attribute['comment']) . '"';?>/>
<input type="text" class="AttributeComment" style="padding:0px;height:20px;margin-bottom:0px;" placeholder="<?php echo h($importComment); ?>" <?php if (!empty($attribute['comment'])) echo 'value="' . h($attribute['comment']) . '"';?>/>
</td>
<td class="short" style="width:40px;text-align:center;">
<select class='AttributeDistribution' style='padding:0px;height:20px;margin-bottom:0px;'>
<?php
foreach ($distributions as $distKey => $distValue) {
echo '<option value="' . $distKey . '" ' . ($distKey == $attribute['distribution'] ? 'selected="selected"' : '') . '>' . $distValue . '</option>';
echo '<option value="' . h($distKey) . '" ' . ($distKey == $attribute['distribution'] ? 'selected="selected"' : '') . '>' . h($distValue) . '</option>';
}
?>
</select>
@ -169,7 +234,7 @@
<select class='AttributeSharingGroup' style='padding:0px;height:20px;margin-top:3px;margin-bottom:0px;'>
<?php
foreach ($sgs as $sgKey => $sgValue) {
echo '<option value="' . h($sgKey) . '">' . h($sgValue) . '</option>';
echo '<option value="' . h($sgKey) . '" ' . ($sgKey == $attribute['sharing_group_id'] ? 'selected="selected"' : '') . '>' . h($sgValue) . '</option>';
}
?>
</select>
@ -179,44 +244,74 @@
echo '</tr>';
}
}
echo '<tr><td colspan="9" /></tr>';
?>
</tbody>
</table>
</div>
<?php
</tbody>
<?php
}
}
?>
</div>
<?php
if (isset($event['Attribute']) && !empty($event['Attribute'])) {
?>
<div class='MISPAttributes'>
<h3><?php echo __('Attributes'); ?></h3>
<table class="table table-condensed table-stripped">
<thead>
<th><?php echo __('Category');?></th>
<th><?php echo __('Type');?></th>
<th><?php echo __('Value');?></th>
<th><?php echo __('UUID');?></th>
<th><?php echo __('IDS');?></th>
<th><?php echo __('Disable Correlation');?></th>
<th><?php echo __('Comment');?></th>
<th><?php echo __('Distribution');?></th>
</thead>
<tbody>
if (!empty($event['Attribute'])) {
if (!$header_present) {
?>
<table class='table table-striped table-condensed'>
<tbody>
<tr>
<th><?php echo __('Category');?></th>
<th><?php echo __('Type');?></th>
<th><?php echo __('Value');?></th>
<th><?php echo __('UUID');?></th>
<th><?php echo __('Tags');?></th>
<th><?php echo __('IDS');?></th>
<th><?php echo __('Disable Correlation');?></th>
<th><?php echo __('Comment');?></th>
<th><?php echo __('Distribution');?></th>
</tr>
<?php
}
foreach ($event['Attribute'] as $a => $attribute) {
echo '<tr class="MISPAttribute">';
if ($attribute['distribution'] != 4) {
$attribute['distribution'] = $distributions[$attribute['distribution']];
} else {
$attribute['distribution'] = $sgs[$attribute['sharing_group_id']];
}
foreach ($attributeFields as $field) {
echo '<td class="Attribute' . ucfirst($field) . '">' . (isset($attribute[$field]) ? h($attribute[$field]) : '') . '</td>';
foreach (array('category', 'type') as $field) {
$field_header = 'class="Attribute' . ucfirst($field);
if (isset($attribute[$field])) {
if (is_array($attribute[$field])) {
echo '<td class="short" style="width:40px;text-align:center;"><select ' . $field_header . 'Select" style="padding:0px;height:20px;margin-bottom:0px;">';
foreach ($attribute[$field] as $v => $value) {
echo '<option value="' . h($value) . '" ' . ($v ? '' : 'selected="selected"') . '>' . h($value) . '</option>';
}
echo '</select></td>';
} else {
echo '<td ' . $field_header . '">' . h($attribute[$field]) . '</td>';
}
} else {
echo '<td ' . $field_header . '"></td>';
}
}
?>
<td class="AttributeValue limitedWidth"><?php echo h($attribute['value']); ?></td>
<?php if (in_array($attribute['type'], $typesWithData) && !empty($attribute['data'])) {?>
<input class='AttributeData' type='hidden' value="<?php echo $attribute['data']; ?>"/>
<?php } ?>
<td class="AttributeUuid short"><?php echo h($attribute['uuid']); ?></td>
<td style="max-width:150px;width:10px;">
<?php if (!empty($attribute['Tag'])) { ?>
<span class="attributeTagContainer">
<?php
foreach ($attribute['Tag'] as $tag) {
$tagText = explode('=', $tag['name']);
$tagText = trim(end($tagText), "\"");
$color = !empty($tag['colour']) ? $tag['colour'] : '#0088cc';
?>
<span style="display:inline-block;">
<span style="padding:1px;display:flex;white-space:nowrap;margin-right:2px;word-wrap:break-word;">
<span class="attributeTag" style="display:inline-block;background-color:<?php echo h($color); ?>;color:white;" title="<?php echo h($tag['name']); ?>">
<?php echo h($tagText); ?>
</span>
</span>
</span>
<?php } ?>
</span>
<?php } ?>
</td>
<td class="short" style="width:40px;text-align:center;">
<input type="checkbox" class="AttributeToIds" <?php if (isset($attribute['to_ids']) && $attribute['to_ids']) echo 'checked'; ?>/>
</td>
@ -224,13 +319,13 @@
<input type="checkbox" class="AttributeDisableCorrelation" <?php if (isset($attribute['disable_correlation']) && $attribute['disable_correlation']) echo 'checked'; ?>/>
</td>
<td class="short">
<input type="text" class="AttributeComment" style="padding:0px;height:20px;margin-bottom:0px;" placeholder="<?php echo h($importComment); ?>" <?php if (isset($attribute['comment']) && $attribute['comment'] !== false) echo 'value="' . h($attribute['comment']) . '"';?>/>
<input type="text" class="AttributeComment" style="padding:0px;height:20px;margin-bottom:0px;" placeholder="<?php echo h($importComment); ?>" <?php if (!empty($attribute['comment'])) echo 'value="' . h($attribute['comment']) . '"';?>/>
</td>
<td class="short" style="width:40px;text-align:center;">
<select class='AttributeDistribution' style='padding:0px;height:20px;margin-bottom:0px;'>
<?php
foreach ($distributions as $distKey => $distValue) {
echo '<option value="' . $distKey . '" ' . ($distKey == $attribute['distribution'] ? 'selected="selected"' : '') . '>' . $distValue . '</option>';
echo '<option value="' . h($distKey) . '" ' . ($distKey == $attribute['distribution'] ? 'selected="selected"' : '') . '>' . h($distValue) . '</option>';
}
?>
</select>
@ -238,28 +333,24 @@
<select class='AttributeSharingGroup' style='padding:0px;height:20px;margin-top:3px;margin-bottom:0px;'>
<?php
foreach ($sgs as $sgKey => $sgValue) {
echo '<option value="' . h($sgKey) . '">' . h($sgValue) . '</option>';
echo '<option value="' . h($sgKey) . '" ' . ($sgKey == $attribute['sharing_group_id'] ? 'selected="selected"' : '') . '>' . h($sgValue) . '</option>';
}
?>
</select>
</div>
</td>
<?php
<?php
echo '</tr>';
}
}
?>
</tbody>
</table>
</div>
<button class="btn btn-primary" style="float:left;" onClick="moduleResultsSubmit('<?php echo h($event['Event']['id']); ?>');"><?php echo __('Submit oui'); ?></button>
?>
</tbody>
</table>
<span>
<button class="btn btn-primary" style="float:left;" onClick="moduleResultsSubmit('<?php echo h($event_id); ?>');"><?php echo __('Submit'); ?></button>
<a href="<?php echo $baseurl . '/events/view/' . h($event['Event']['id']); ?>" style="margin-left:10px;" class="btn btn-inverse"><?php echo __('Cancel');?></a>
</span>
</div>
<?php
if (!isset($menuItem)) {
$menuItem = 'freetextResults';
}
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'event', 'menuItem' => $menuItem));
?>
<script type="text/javascript">
$(document).ready(function() {
$('.AttributeDistribution').change(function() {
@ -278,3 +369,9 @@
});
});
</script>
<?php
if (!isset($menuItem)) {
$menuItem = 'freetextResults';
}
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'event', 'menuItem' => $menuItem));
?>

View File

@ -2457,9 +2457,19 @@ function freetextImportResultsSubmit(id, count) {
}
function moduleResultsSubmit(id) {
var typesWithData = ['attachment', 'malware-sample'];
var data_collected = {};
var temp;
if ($('.MISPObjects').length) {
if ($('.meta_table').length) {
var tags = [];
$('.meta_table').find('.tag').each(function() {
tags.push({name: $(this).text()});
});
if (tags.length) {
data_collected['Tag'] = tags;
}
}
if ($('.MISPObject').length) {
var objects = [];
$(".MISPObject").each(function(o) {
var object_uuid = $(this).find('.ObjectUUID').text();
@ -2470,27 +2480,38 @@ function moduleResultsSubmit(id) {
distribution: $(this).find('.ObjectDistribution').val(),
sharing_group_id: $(this).find('.ObjectSharingGroup').val()
}
if (temp['distribution'] != '4') {
temp['sharing_group_id'] = '0';
}
if ($(this).has('.ObjectID').length) {
temp['id'] = $(this).find('.ObjectID').text();
}
if ($(this).has('.ObjectReferences').length) {
if ($(this).has('.TemplateVersion').length) {
temp['template_version'] = $(this).find('.TemplateVersion').text();
}
if ($(this).has('.TemplateUUID').length) {
temp['template_uuid'] = $(this).find('.TemplateUUID').text();
}
if ($(this).has('.ObjectReference').length) {
var references = [];
$(this).find('.ObjectReference').each(function() {
var reference = {
object_uuid: object_uuid,
referenced_uuid: $(this).find('.ReferencedUUID').text(),
relationhip_type: $(this).find('.Relationship').text()
relationship_type: $(this).find('.Relationship').text()
};
references.push(reference);
});
temp['ObjectReference'] = references;
}
if ($(this).find('.ObjectAttributes').length) {
if ($(this).find('.ObjectAttribute').length) {
var object_attributes = [];
$(this).find('.ObjectAttribute').each(function(a) {
var attribute_type = $(this).find('.AttributeType').text();
attribute = {
object_relation: $(this).find('.ObjectRelation').text(),
category: $(this).find('.AttributeCategory').text(),
type: $(this).find('.AttributeType').text(),
type: attribute_type,
value: $(this).find('.AttributeValue').text(),
uuid: $(this).find('.AttributeUuid').text(),
to_ids: $(this).find('.AttributeToIds')[0].checked,
@ -2499,6 +2520,19 @@ function moduleResultsSubmit(id) {
distribution: $(this).find('.AttributeDistribution').val(),
sharing_group_id: $(this).find('.AttributeSharingGroup').val()
}
if (attribute['distribution'] != '4') {
attribute['sharing_group_id'] = '0';
}
if ($(this).find('.objectAttributeTagContainer').length) {
var tags = [];
$(this).find('.objectAttributeTag').each(function() {
tags.push({name: $(this).attr('title')});
});
attribute['Tag'] = tags;
}
if (typesWithData.indexOf(attribute_type) != -1 && $(this).find('.AttributeData').length) {
attribute['data'] = $(this).find('.AttributeData').val();
}
object_attributes.push(attribute);
});
temp['Attribute'] = object_attributes;
@ -2507,12 +2541,24 @@ function moduleResultsSubmit(id) {
});
data_collected['Object'] = objects;
}
if ($('.MISPAttributes').length) {
if ($('.MISPAttribute').length) {
var attributes = [];
$('.MISPAttribute').each(function(a) {
var category_value;
var type_value;
if ($(this).find('.AttributeCategorySelect').length) {
category_value = $(this).find('.AttributeCategorySelect').val();
} else {
category_value = $(this).find('.AttributeCategory').text();
}
if ($(this).find('.AttributeTypeSelect').length) {
type_value = $(this).find('.AttributeTypeSelect').val();
} else {
type_value = $(this).find('.AttributeType').text();
}
temp = {
category: $(this).find('.AttributeCategory').text(),
type: $(this).find('.AttributeType').text(),
category: category_value,
type: type_value,
value: $(this).find('.AttributeValue').text(),
uuid: $(this).find('.AttributeUuid').text(),
to_ids: $(this).find('.AttributeToIds')[0].checked,
@ -2521,14 +2567,30 @@ function moduleResultsSubmit(id) {
distribution: $(this).find('.AttributeDistribution').val(),
sharing_group_id: $(this).find('.AttributeSharingGroup').val()
}
if (temp['distribution'] != '4') {
temp['sharing_group_id'] = '0';
}
if ($(this).find('.attributeTagContainer').length) {
var tags = [];
$(this).find('.attributeTag').each(function() {
tags.push({name: $(this).attr('title')});
});
temp['Tag'] = tags;
}
if (typesWithData.indexOf(type_value) != -1 && $(this).find('.AttributeData').length) {
temp['data'] = $(this).find('.AttributeData').val();
}
attributes.push(temp);
});
data_collected['Attribute'] = attributes;
}
$("#EventJsonObject").val(JSON.stringify(data_collected));
var formData = $('.mainForm').serialize();
$.ajax({
type: "post",
cache: false,
url: "/events/handleModuleResults/" + id,
data: formData,
beforeSend: function (XMLHttpRequest) {
$(".loading").show();
},