mirror of https://github.com/MISP/MISP
Merge branch 'attribute_merge' into 2.4
commit
d45d66a3bc
|
@ -116,6 +116,7 @@ class ACLComponent extends Component {
|
|||
'viewEventAttributes' => array('*'),
|
||||
'viewGraph' => array('*'),
|
||||
'xml' => array('*'),
|
||||
'merge' => array('perm_modify'),
|
||||
'importChoice' => array('*'),
|
||||
'importModule' => array('*'),
|
||||
'exportModule' => array('*')
|
||||
|
|
|
@ -1167,6 +1167,78 @@ class EventsController extends AppController {
|
|||
}
|
||||
}
|
||||
|
||||
public function merge($target_id = null) {
|
||||
$this->Event->id = $target_id;
|
||||
$eIds = $this->Event->fetchEventIds($this->Auth->user(), false, false, false, true);
|
||||
// check if event exists and is readable for the current user
|
||||
if (!$this->Event->exists() || !in_array($target_id, $eIds)) {
|
||||
throw new NotFoundException(__('Invalid event'));
|
||||
}
|
||||
$this->Event->read(null, $target_id);
|
||||
// check if private and user not authorised to edit
|
||||
if (!$this->_isSiteAdmin() && ($this->Event->data['Event']['orgc_id'] != $this->_checkOrg() || !($this->userRole['perm_modify']))) {
|
||||
$this->Session->setFlash(__('You are not authorised to do that. Please consider using the \'propose attribute\' feature.'));
|
||||
$this->redirect(array('action' => 'view', $target_id));
|
||||
}
|
||||
if ($this->request->is('post')) {
|
||||
$source_id = $this->request->data['Event']['source_id'];
|
||||
$to_ids = $this->request->data['Event']['to_ids'];
|
||||
if (!is_numeric($source_id)) {
|
||||
$this->Session->setFlash(__('Invalid event ID entered.'));
|
||||
return;
|
||||
}
|
||||
$this->Event->read(null, $source_id);
|
||||
if (!$this->_isSiteAdmin() && !in_array($source_id, $eIds)) {
|
||||
$this->Session->setFlash(__('You are not authorised to read the selected event.'));
|
||||
return;
|
||||
}
|
||||
$r = array('results' => []);
|
||||
foreach ($this->Event->data['Attribute'] as $a) {
|
||||
if ($to_ids && !$a['to_ids']) {
|
||||
continue;
|
||||
}
|
||||
$tmp = array();
|
||||
$tmp['values'] = $a['value'];
|
||||
$tmp['categories'] = $a['category'];
|
||||
$tmp['types'] = $a['type'];
|
||||
$tmp['to_ids'] = $a['to_ids'];
|
||||
$tmp['comment'] = $a['comment'];
|
||||
if ($this->Event->Attribute->typeIsAttachment($a['type'])) {
|
||||
$encodedFile = $this->Event->Attribute->base64EncodeAttachment($a);
|
||||
$tmp['data'] = $encodedFile;
|
||||
$tmp['data_is_handled'] = true;
|
||||
}
|
||||
$r['results'][] = $tmp;
|
||||
}
|
||||
$resultArray = $this->Event->handleModuleResult($r, $target_id);
|
||||
$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' => $target_id)));
|
||||
$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', 'Merge Results');
|
||||
$this->set('importComment', 'Merged from event ' . $source_id);
|
||||
$this->render('resolved_attributes');
|
||||
} else {
|
||||
// set the target event id in the form
|
||||
$this->request->data['Event']['target_id'] = $target_id;
|
||||
}
|
||||
}
|
||||
|
||||
public function edit($id = null) {
|
||||
$this->Event->id = $id;
|
||||
if (!$this->Event->exists()) {
|
||||
|
@ -2871,29 +2943,31 @@ class EventsController extends AppController {
|
|||
if ($attribute['type'] == 'ip-src/ip-dst') {
|
||||
$types = array('ip-src', 'ip-dst');
|
||||
} else if ($attribute['type'] == 'malware-sample') {
|
||||
App::uses('FileAccessTool', 'Tools');
|
||||
$tmpdir = Configure::read('MISP.tmpdir') ? Configure::read('MISP.tmpdir') : '/tmp';
|
||||
$tempFile = explode('|', $attribute['data']);
|
||||
if (!$this->Event->checkFilename($tempFile[0])) {
|
||||
throw new Exception('Invalid filename.');
|
||||
}
|
||||
$attribute['data'] = (new FileAccessTool())->readFromFile($tmpdir . '/' . $tempFile[0], $tempFile[1]);
|
||||
unlink($tmpdir . '/' . $tempFile[0]);
|
||||
$result = $this->Event->Attribute->handleMaliciousBase64($id, $attribute['value'], $attribute['data'], array('md5', 'sha1', 'sha256'), $objectType == 'ShadowAttribute' ? true : false);
|
||||
if (!$result['success']) {
|
||||
$failed++;
|
||||
continue;
|
||||
}
|
||||
$attribute['data'] = $result['data'];
|
||||
$shortValue = $attribute['value'];
|
||||
$attribute['value'] = $shortValue . '|' . $result['md5'];
|
||||
$additionalHashes = array('sha1', 'sha256');
|
||||
foreach ($additionalHashes as $hash) {
|
||||
$temp = $attribute;
|
||||
$temp['type'] = 'filename|' . $hash;
|
||||
$temp['value'] = $shortValue . '|' . $result[$hash];
|
||||
unset($temp['data']);
|
||||
$ontheflyattributes[] = $temp;
|
||||
if (!isset($attribute['data_is_handled']) || !$attribute['data_is_handled']) {
|
||||
App::uses('FileAccessTool', 'Tools');
|
||||
$tmpdir = Configure::read('MISP.tmpdir') ? Configure::read('MISP.tmpdir') : '/tmp';
|
||||
$tempFile = explode('|', $attribute['data']);
|
||||
if (!$this->Event->checkFilename($tempFile[0])) {
|
||||
throw new Exception('Invalid filename.');
|
||||
}
|
||||
$attribute['data'] = (new FileAccessTool())->readFromFile($tmpdir . '/' . $tempFile[0], $tempFile[1]);
|
||||
unlink($tmpdir . '/' . $tempFile[0]);
|
||||
$result = $this->Event->Attribute->handleMaliciousBase64($id, $attribute['value'], $attribute['data'], array('md5', 'sha1', 'sha256'), $objectType == 'ShadowAttribute' ? true : false);
|
||||
if (!$result['success']) {
|
||||
$failed++;
|
||||
continue;
|
||||
}
|
||||
$attribute['data'] = $result['data'];
|
||||
$shortValue = $attribute['value'];
|
||||
$attribute['value'] = $shortValue . '|' . $result['md5'];
|
||||
$additionalHashes = array('sha1', 'sha256');
|
||||
foreach ($additionalHashes as $hash) {
|
||||
$temp = $attribute;
|
||||
$temp['type'] = 'filename|' . $hash;
|
||||
$temp['value'] = $shortValue . '|' . $result[$hash];
|
||||
unset($temp['data']);
|
||||
$ontheflyattributes[] = $temp;
|
||||
}
|
||||
}
|
||||
$types = array($attribute['type']);
|
||||
} else {
|
||||
|
@ -3735,7 +3809,6 @@ class EventsController extends AppController {
|
|||
$resultArray[$key]['data'] = basename($tempFile) . '|' . filesize($tempFile);
|
||||
}
|
||||
}
|
||||
|
||||
$this->set('event', array('Event' => $attribute[0]['Event']));
|
||||
$this->set('resultArray', $resultArray);
|
||||
$this->set('typeList', array_keys($this->Event->Attribute->typeDefinitions));
|
||||
|
|
|
@ -2829,6 +2829,9 @@ class Event extends AppModel {
|
|||
$temp['default_category'] = $r['categories'][0];
|
||||
}
|
||||
if (isset($r['data'])) $temp['data'] = $r['data'];
|
||||
// if data_is_handled is set then MISP assumes that the sample is already zipped and encrypted
|
||||
// in this case it will not try to do this by itself - however it also won't create additional hashes
|
||||
if (isset($r['data_is_handled'])) $temp['data_is_handled'] = $r['data_is_handled'];
|
||||
$resultArray[] = $temp;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
<?php if ($menuItem === 'populateFromtemplate'): ?>
|
||||
<li class="active"><a href="<?php echo $baseurl;?>/templates/populateEventFromTemplate/<?php echo $template_id . '/' . h($event['Event']['id']); ?>">Populate From Template</a></li>
|
||||
<?php endif; ?>
|
||||
<li id='merge'><a href="<?php echo $baseurl;?>/events/merge/<?php echo h($event['Event']['id']);?>">Merge attributes from...</a></li>
|
||||
<?php endif; ?>
|
||||
<?php if (($isSiteAdmin && (!isset($mayModify) || !$mayModify)) || (!isset($mayModify) || !$mayModify)): ?>
|
||||
<li id='liproposeAttribute'><a href="<?php echo $baseurl;?>/shadow_attributes/add/<?php echo h($event['Event']['id']);?>">Propose Attribute</a></li>
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
<div class="eventmerge form">
|
||||
<?php echo $this->Form->create('Event', array('enctype' => 'multipart/form-data'));?>
|
||||
<fieldset>
|
||||
<legend><?php echo __('Merge events'); ?></legend>
|
||||
<?php
|
||||
echo $this->Form->hidden('target_id');
|
||||
echo $this->Form->input('source_id', array(
|
||||
'type' => 'text',
|
||||
'label' => 'Event id to copy the attributes from',
|
||||
'error' => array('escape' => false),
|
||||
'div' => 'input clear',
|
||||
'class' => 'input'
|
||||
));
|
||||
?>
|
||||
<div class="input clear"></div>
|
||||
<?php
|
||||
echo $this->Form->input('to_ids', array(
|
||||
'type' => 'checkbox',
|
||||
'checked' => false,
|
||||
'label' => 'copy only IDS attributes',
|
||||
));
|
||||
?>
|
||||
|
||||
</fieldset>
|
||||
<?php
|
||||
echo $this->Form->button('Merge', array('class' => 'btn btn-primary'));
|
||||
echo $this->Form->end();
|
||||
?>
|
||||
<div id="confirmation_box" class="confirmation_box"></div>
|
||||
</div>
|
||||
<?php
|
||||
$event['Event']['id'] = $this->request->data['Event']['target_id'];
|
||||
echo $this->element('side_menu', array('menuList' => 'event', 'menuItem' => 'merge', 'event' => $event));
|
||||
?>
|
|
@ -49,6 +49,11 @@
|
|||
'type' => 'hidden',
|
||||
'value' => isset($item['data']) ? h($item['data']) : false,
|
||||
));
|
||||
echo $this->Form->input('Attribute' . $k . 'DataIsHandled', array(
|
||||
'label' => false,
|
||||
'type' => 'hidden',
|
||||
'value' => isset($item['data_is_handled']) ? h($item['data_is_handled']) : false,
|
||||
));
|
||||
?>
|
||||
<td>
|
||||
<?php
|
||||
|
|
|
@ -1702,7 +1702,8 @@ function freetextImportResultsSubmit(id, count) {
|
|||
type:$('#Attribute' + i + 'Type').val(),
|
||||
to_ids:$('#Attribute' + i + 'To_ids')[0].checked,
|
||||
comment:$('#Attribute' + i + 'Comment').val(),
|
||||
data:$('#Attribute' + i + 'Data').val()
|
||||
data:$('#Attribute' + i + 'Data').val(),
|
||||
data_is_handled:$('#Attribute' + i + 'DataIsHandled').val()
|
||||
}
|
||||
attributeArray[attributeArray.length] = temp;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue