Merge branch '2.4' of github.com:MISP/MISP into zoidberg-final

Not a simple merge. Needed to fix forms and simplified how
form_seen_input works
pull/5462/head
mokaddem 2019-12-16 13:36:01 +01:00
commit 7797aeed94
No known key found for this signature in database
GPG Key ID: 164C473F627A06FA
35 changed files with 664 additions and 577 deletions

2
PyMISP

@ -1 +1 @@
Subproject commit 36cc79ffb686430e02b382dfef85c29a5e27c39d
Subproject commit 637a9668c0fe6a668fc92011d949a7049c588388

View File

@ -221,7 +221,7 @@ class ServerShell extends AppShell
$data = array(
'worker' => 'default',
'job_type' => 'cache_servers',
'job_input' => 'Server: ' . $id,
'job_input' => 'Server: ' . $scopeid,
'status' => 0,
'retries' => 0,
'org' => $user['Organisation']['name'],

View File

@ -239,13 +239,8 @@ class AttributesController extends AppController
$failed = 1;
$message = sprintf('Attributes saved, however, %s attributes could not be saved. Click %s for more info', count($fails), '$flashErrorMessage');
} else {
if (!empty($fails["attribute_0"])) {
$failed = 1;
$message = '0: ' . $v[0];
} else {
$failed = 1;
$message = 'Attribute could not be saved.';
}
$failed = 1;
$message = 'Attribute could not be saved.';
}
}
if (!empty($failKeys)) {
@ -267,8 +262,14 @@ class AttributesController extends AppController
$flashErrorMessage = implode('<br />', $flashErrorMessage);
$this->Session->write('flashErrorMessage', $flashErrorMessage);
}
if (empty($failed)) {
$this->Flash->success($message);
} else {
$this->Flash->error($message);
}
if ($this->request->is('ajax')) {
$this->autoRender = false;
$this->layout = false;
$errors = ($attributeCount > 1) ? $message : $this->Attribute->validationErrors;
if (!empty($successes)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => $message)),'status' => 200, 'type' => 'json'));
@ -276,11 +277,6 @@ class AttributesController extends AppController
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => $errors)),'status' => 200, 'type' => 'json'));
}
} else {
if (empty($failed)) {
$this->Flash->success($message);
} else {
$this->Flash->error($message);
}
if ($successes > 0) {
$this->redirect(array('controller' => 'events', 'action' => 'view', $eventId));
}
@ -311,25 +307,31 @@ class AttributesController extends AppController
$this->loadModel('SharingGroup');
$sgs = $this->SharingGroup->fetchAllAuthorised($this->Auth->user(), 'name', 1);
$this->set('sharingGroups', $sgs);
$info = array();
$initialDistribution = 5;
$configuredDistribution = Configure::check('MISP.default_attribute_distribution');
if ($configuredDistribution != null && $configuredDistribution != 'event') {
$initialDistribution = $configuredDistribution;
}
$this->set('initialDistribution', $initialDistribution);
$fieldDesc = array();
$distributionLevels = $this->Attribute->distributionLevels;
if (empty($sgs)) {
unset($distributionLevels[4]);
}
$this->set('distributionLevels', $distributionLevels);
foreach ($distributionLevels as $key => $value) {
$fieldDesc['distribution'][$key] = $this->Attribute->distributionDescriptions[$key]['formdesc'];
}
foreach ($this->Attribute->categoryDefinitions as $key => $value) {
$info['category'][$key] = array('key' => $key, 'desc' => isset($value['formdesc'])? $value['formdesc'] : $value['desc']);
$fieldDesc['category'][$key] = isset($value['formdesc']) ? $value['formdesc'] : $value['desc'];
}
foreach ($this->Attribute->typeDefinitions as $key => $value) {
$info['type'][$key] = array('key' => $key, 'desc' => isset($value['formdesc'])? $value['formdesc'] : $value['desc']);
}
foreach ($distributionLevels as $key => $value) {
$info['distribution'][$key] = array('key' => $value, 'desc' => $this->Attribute->distributionDescriptions[$key]['formdesc']);
$fieldDesc['type'][$key] = isset($value['formdesc']) ? $value['formdesc'] : $value['desc'];
}
$this->loadModel('Noticelist');
$notice_list_triggers = $this->Noticelist->getTriggerData();
$this->set('notice_list_triggers', json_encode($notice_list_triggers, true));
$this->set('info', $info);
$this->set('fieldDesc', $fieldDesc);
$this->set('typeDefinitions', $this->Attribute->typeDefinitions);
$this->set('categoryDefinitions', $this->Attribute->categoryDefinitions);
$this->set('published', $events['Event']['published']);

View File

@ -591,7 +591,8 @@ class DecayingModelController extends AppController
$filters['uuid'] = $filters['id'];
} else {
$attributes = $this->User->Event->Attribute->fetchAttributes($this->Auth->user(), array(
'conditions' => array('Attribute.id' => $filters['id'])
'conditions' => array('Attribute.id' => $filters['id']),
'flatten' => 1
));
if (!empty($attributes)) {
$filters['uuid'] = $attributes[0]['Attribute']['uuid'];

View File

@ -2082,7 +2082,6 @@ class EventsController extends AppController
if (isset($this->params['named']['extends'])) {
$this->set('extends_uuid', $this->params['named']['extends']);
}
$this->set('action', 'add');
}
public function addIOC($id)
@ -2420,11 +2419,9 @@ class EventsController extends AppController
$fieldDesc['analysis'][$key] = $this->Event->analysisDescriptions[$key]['formdesc'];
}
$this->set('analysisLevels', $analysisLevels);
$this->set('fieldDesc', $fieldDesc);
$this->set('eventDescriptions', $this->Event->fieldDescriptions);
$this->set('event', $this->Event->data);
$this->set('action', 'edit');
$this->render('add');
}

View File

@ -96,7 +96,7 @@ class ShadowAttributesController extends AppController
$this->Attribute->delete($activeAttribute['Attribute']['id']);
} else {
// Update the live attribute with the shadow data
$fieldsToUpdate = array('value1', 'value2', 'value', 'type', 'category', 'comment', 'to_ids');
$fieldsToUpdate = array('value1', 'value2', 'value', 'type', 'category', 'comment', 'to_ids', 'first_seen', 'last_seen');
foreach ($fieldsToUpdate as $f) {
$activeAttribute['Attribute'][$f] = $shadow[$f];
}

View File

@ -886,9 +886,9 @@ class UsersController extends AppController
continue;
}
if ($field != 'confirm_password') {
array_push($fieldsOldValues, $this->User->field($field));
$fieldsOldValues[$field] = $this->User->field($field);
} else {
array_push($fieldsOldValues, $this->User->field('password'));
$fieldsOldValues[$field] = $this->User->field('password');
}
}
if (
@ -929,31 +929,28 @@ class UsersController extends AppController
}
$cP++;
}
array_push($fieldsNewValues, $newValueStr);
$fieldsNewValues[$field] = $newValueStr;
} else {
array_push($fieldsNewValues, $newValue);
$fieldsNewValues[$field] = $newValue;
}
} else {
array_push($fieldsNewValues, $this->data['User']['password']);
$fieldsNewValues[$field] = $this->data['User']['password'];
}
}
// compare
$fieldsResultStr = '';
$c = 0;
$fieldsResult = array();
foreach ($fields as $field) {
if (isset($fieldsOldValues[$c]) && $fieldsOldValues[$c] != $fieldsNewValues[$c]) {
if (isset($fieldsOldValues[$field]) && $fieldsOldValues[$field] != $fieldsNewValues[$field]) {
if ($field != 'confirm_password' && $field != 'enable_password') {
$fieldsResultStr = $fieldsResultStr . ', ' . $field . ' (' . $fieldsOldValues[$c] . ') => (' . $fieldsNewValues[$c] . ')';
$fieldsResult[$field] = array($fieldsOldValues[$field], $fieldsNewValues[$field]);
}
}
$c++;
}
$fieldsResultStr = substr($fieldsResultStr, 2);
$user = $this->User->find('first', array(
'recursive' => -1,
'conditions' => array('User.id' => $this->User->id)
));
$this->User->extralog($this->Auth->user(), "edit", "user", $fieldsResultStr, $user);
$this->User->extralog($this->Auth->user(), "edit", "user", $fieldsResult, $user);
if ($this->_isRest()) {
$user['User']['password'] = '******';
return $this->RestResponse->viewData($user, $this->response->type());

View File

@ -3346,6 +3346,8 @@ class Attribute extends AppModel
if (empty($at['Tag'])) {
unset($results[$k]['AttributeTag'][$k2]);
$tagCulled = true;
} else {
$results[$k]['AttributeTag'][$k2]['Tag']['local'] = $results[$k]['AttributeTag'][$k2]['local'];
}
}
if ($tagCulled) {
@ -3355,6 +3357,7 @@ class Attribute extends AppModel
if (isset($result['Event']['EventTag'])) {
$results[$k]['Event']['Tag'] = array();
foreach ($result['Event']['EventTag'] as $et) {
$et['Tag']['local'] = $et['local'];
$results[$k]['Event']['Tag'][] = $et['Tag'];
}
unset($results[$k]['Event']['EventTag']);

View File

@ -5851,6 +5851,7 @@ class Event extends AppModel
unset($data[$dataType . 'Tag'][$k]);
continue;
}
$dataTag['Tag']['local'] = $dataTag['local'];
if (!isset($excludeGalaxy) || !$excludeGalaxy) {
if (substr($dataTag['Tag']['name'], 0, strlen('misp-galaxy:')) === 'misp-galaxy:') {
$cluster = $this->GalaxyCluster->getCluster($dataTag['Tag']['name']);

View File

@ -189,6 +189,7 @@ class Log extends AppModel
* @param int $modelId
* @param string $title
* @param string|array $change
* @return array
* @throws Exception
*/
public function createLogEntry($user, $action, $model, $modelId = 0, $title = '', $change = '')
@ -227,6 +228,8 @@ class Log extends AppModel
if (!$result) {
throw new Exception("Cannot save log because of validation errors: " . json_encode($this->validationErrors));
}
return $result;
}
// to combat a certain bug that causes the upgrade scripts to loop without being able to set the correct version

View File

@ -413,11 +413,28 @@ class Tag extends AppModel
return ($this->saveAll($tags));
}
public function getTagsByName($tag_names, $containTagConnectors = true)
{
$contain = array('EventTag', 'AttributeTag');
$tag_params = array(
'recursive' => -1,
'conditions' => array('name' => $tag_names)
);
if ($containTagConnectors) {
$tag_params['contain'] = $contain;
}
$tags_temp = $this->find('all', $tag_params);
$tags = array();
foreach ($tags_temp as $temp) {
$tags[strtoupper($temp['Tag']['name'])] = $temp;
}
return $tags;
}
public function getTagsForNamespace($namespace, $containTagConnectors = true)
{
$contain = array('EventTag');
$contain[] = 'AttributeTag';
$contain = array('EventTag', 'AttributeTag');
$tag_params = array(
'recursive' => -1,
'conditions' => array('UPPER(name) LIKE' => strtoupper($namespace) . '%'),

View File

@ -283,7 +283,8 @@ class Taxonomy extends AppModel
if (empty($taxonomy)) {
return false;
}
$tags = $this->Tag->getTagsForNamespace($taxonomy['Taxonomy']['namespace'], false);
$tag_names = Hash::extract($taxonomy, 'entries.{n}.tag');
$tags = $this->Tag->getTagsByName($tag_names, false);
if (isset($taxonomy['entries'])) {
foreach ($taxonomy['entries'] as $key => $temp) {
$taxonomy['entries'][$key]['existing_tag'] = isset($tags[strtoupper($temp['tag'])]) ? $tags[strtoupper($temp['tag'])] : false;

View File

@ -3,6 +3,9 @@ App::uses('AppModel', 'Model');
App::uses('AuthComponent', 'Controller/Component');
App::uses('RandomTool', 'Tools');
/**
* @property Log $Log
*/
class User extends AppModel
{
public $displayField = 'email';
@ -1419,20 +1422,12 @@ class User extends AppModel
// query
$this->Log = ClassRegistry::init('Log');
$this->Log->create();
$this->Log->save(array(
'org' => $user['Organisation']['name'],
'model' => $model,
'model_id' => $modelId,
'email' => $user['email'],
'action' => $action,
'title' => $description,
'change' => isset($fieldsResult) ? $fieldsResult : ''));
$result = $this->Log->createLogEntry($user, $action, $model, $modelId, $description, $fieldsResult);
// write to syslogd as well
App::import('Lib', 'SysLog.SysLog');
$syslog = new SysLog();
$syslog->write('notice', $description . ' -- ' . $action . (empty($fieldResult) ? '' : '-- ' . $fieldResult));
$syslog->write('notice', "$description -- $action" . (empty($fieldResult) ? '' : ' -- ' . $result['Log']['change']));
}
/**
@ -1500,7 +1495,7 @@ class User extends AppModel
$endDate = time();
}
$dates = array();
for ($d=$startDate; $d < $endDate; $d=$d+3600*24) {
for ($d=$startDate; $d < $endDate; $d=$d+3600*24) {
$dates[] = date('Y-m-d', $d);
}
$csv = 'Date,Close\n';

View File

@ -1,167 +1,131 @@
<div class="attributes <?php if (!isset($ajax) || !$ajax) echo 'form';?>">
<?php
$url_params = $action == 'add' ? 'add/' . $event_id : 'edit/' . $attribute['Attribute']['id'];
echo $this->Form->create('Attribute', array('id'=>'AttributeForm', 'url' => '/attributes/' . $url_params));
?>
<fieldset>
<legend><?php echo $action == 'add' ? __('Add Attribute') : __('Edit Attribute'); ?></legend>
<div id="formWarning" class="message ajaxMessage"></div>
<div id="compositeWarning" class="message <?php echo !empty($ajax) ? 'ajaxMessage' : '';?>" style="display:none;">Did you consider adding an object instead of a composite attribute?</div>
<div class="add_attribute_fields">
<?php
echo $this->Form->hidden('event_id');
echo $this->Form->input('category', array(
'empty' => __('(choose one)'),
'label' => __('Category ') . $this->element('formInfo', array('type' => 'category')),
));
echo $this->Form->input('type', array(
'empty' => __('(first choose category)'),
'label' => __('Type ') . $this->element('formInfo', array('type' => 'type')),
));
$initialDistribution = 5;
if (Configure::read('MISP.default_attribute_distribution') != null) {
if (Configure::read('MISP.default_attribute_distribution') === 'event') {
$initialDistribution = 5;
} else {
$initialDistribution = Configure::read('MISP.default_attribute_distribution');
}
}
?>
<div class="input clear"></div>
<?php
$distArray = array(
'options' => array($distributionLevels),
'label' => __('Distribution ') . $this->element('formInfo', array('type' => 'distribution')),
);
if ($action == 'add') {
$distArray['selected'] = $initialDistribution;
}
echo $this->Form->input('distribution', $distArray);
?>
<div id="SGContainer" style="display:none;">
<?php
if (!empty($sharingGroups)) {
echo $this->Form->input('sharing_group_id', array(
'options' => array($sharingGroups),
'label' => __('Sharing Group'),
));
}
?>
</div>
<?php
echo $this->Form->input('value', array(
'type' => 'textarea',
'error' => array('escape' => false),
'div' => 'input clear',
'class' => 'input-xxlarge'
));
?>
<div class="input clear"></div>
<?php
echo $this->Form->input('comment', array(
$modelForForm = 'Attribute';
echo $this->element('genericElements/Form/genericForm', array(
'form' => $this->Form,
'data' => array(
'title' => $action === 'add' ? __('Add Attribute') : __('Edit Attribute'),
'model' => $modelForForm,
'fields' => array(
array(
'field' => 'event_id',
'class' => 'org-id-picker-hidden-field',
'type' => 'text',
'label' => __('Contextual Comment'),
'error' => array('escape' => false),
'hidden' => true
),
array(
'field' => 'category',
'class' => 'input',
'empty' => __('(choose one)'),
'options' => $categories,
'stayInLine' => 1
),
array(
'field' => 'type',
'class' => 'input',
'empty' => __('(choose category first)'),
'options' => $types
),
array(
'field' => 'distribution',
'class' => 'input',
'options' => $distributionLevels,
'default' => isset($attribute['Attribute']['distribution']) ? $attribute['Attribute']['distribution'] : $initialDistribution,
'stayInLine' => 1
),
array(
'field' => 'sharing_group_id',
'class' => 'input',
'options' => $sharingGroups,
'label' => __("Sharing Group")
),
array(
'field'=> 'value',
'type' => 'textarea',
'class' => 'input span6',
'div' => 'input clear'
),
array(
'field' => 'comment',
'type' => 'text',
'class' => 'input span6',
'div' => 'input clear',
'class' => 'input-xxlarge'
));
?>
<div class="input clear"></div>
<?php
echo $this->Form->input('to_ids', array(
'label' => __('for Intrusion Detection System'),
'type' => 'checkbox'
));
echo $this->Form->input('batch_import', array(
'label' => __("Contextual Comment")
),
array(
'field' => 'to_ids',
'type' => 'checkbox',
'label' => __("for Intrusion Detection System"),
//'stayInLine' => 1
),
array(
'field' => 'batch_import',
'type' => 'checkbox'
));
echo $this->element('form_seen_input');
echo '<div class="input clear"></div>';
echo $this->Form->input('disable_correlation', array(
),
array(
'field' => 'disable_correlation',
'type' => 'checkbox'
));
?>
</div>
</fieldset>
<p id="notice_message" style="display:none;"></p>
<?php if ($ajax): ?>
<div class="overlay_spacing">
<span id="submitButton" class="btn btn-primary" style="margin-bottom:5px;float:left;" title="<?php echo __('Submit'); ?>" role="button" tabindex="0" aria-label="<?php echo __('Submit'); ?>" onClick="submitPopoverForm('<?php echo $action == 'add' ? $event_id : $attribute['Attribute']['id'];?>', '<?php echo $action; ?>')"><?php echo __('Submit'); ?></span>
<span class="btn btn-inverse" style="float:right;" title="<?php echo __('Cancel'); ?>" role="button" tabindex="0" aria-label="<?php echo __('Cancel'); ?>" id="cancel_attribute_add"><?php echo __('Cancel'); ?></span>
</div>
<?php
else:
?>
<?php
echo $this->Form->button('Submit', array('class' => 'btn btn-primary'));
endif;
echo $this->Form->end();
?>
</div>
<?php
),
array(
'field' => 'first_seen',
'type' => 'text',
'stayInLine' => 1,
'hidden' => true
),
array(
'field' => 'last_seen',
'type' => 'text',
'hidden' => true
),
'<div id="extended_event_preview" style="width:446px;"></div>'
),
'submit' => array(
'action' => $action,
'ajaxSubmit' => sprintf(
'submitPopoverForm(%s, %s, 0, 1)',
"'" . ($action == 'add' ? h($event_id) : h($attribute['Attribute']['id'])) . "'",
"'" . h($action) . "'"
)
),
'metaFields' => array(
'<div id="bothSeenSliderContainer"></div>'
)
)
));
if (!$ajax) {
$event['Event']['id'] = $event_id;
$event['Event']['published'] = $published;
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'event', 'menuItem' => 'addAttribute', 'event' => $event));
}
?>
<script type="text/javascript">
var notice_list_triggers = <?php echo $notice_list_triggers; ?>;
var fieldsArray = new Array('AttributeCategory', 'AttributeType', 'AttributeValue', 'AttributeDistribution', 'AttributeComment', 'AttributeToIds', 'AttributeBatchImport', 'AttributeSharingGroupId');
<?php
$formInfoTypes = array('distribution' => 'Distribution', 'category' => 'Category', 'type' => 'Type');
echo 'var formInfoFields = ' . json_encode($formInfoTypes) . PHP_EOL;
foreach ($formInfoTypes as $formInfoType => $humanisedName) {
echo 'var ' . $formInfoType . 'FormInfoValues = {' . PHP_EOL;
foreach ($info[$formInfoType] as $key => $formInfoData) {
echo '"' . $key . '": "<span class=\"blue bold\">' . h($formInfoData['key']) . '</span>: ' . h($formInfoData['desc']) . '<br />",' . PHP_EOL;
}
echo '}' . PHP_EOL;
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'event-collection', 'menuItem' => $this->action === 'add' ? 'add' : 'editEvent'));
}
?>
//
//Generate Category / Type filtering array
//
var category_type_mapping = new Array();
<?php
<script type="text/javascript">
var notice_list_triggers = <?php echo $notice_list_triggers; ?>;
var composite_types = <?php echo json_encode($compositeTypes); ?>;
var category_type_mapping = new Array();
<?php
foreach ($categoryDefinitions as $category => $def) {
echo "category_type_mapping['" . addslashes($category) . "'] = {";
$first = true;
foreach ($def['types'] as $type) {
if ($first) $first = false;
else echo ', ';
if ($first) {
$first = false;
} else {
echo ', ';
}
echo "'" . addslashes($type) . "' : '" . addslashes($type) . "'";
}
echo "}; \n";
}
?>
var composite_types = <?php echo json_encode($compositeTypes); ?>;
$(document).ready(function() {
<?php
if ($action == 'edit'):
?>
checkNoticeList('attribute');
<?php
endif;
?>
initPopoverContent('Attribute');
$('#AttributeDistribution').change(function() {
if ($('#AttributeDistribution').val() == 4) $('#SGContainer').show();
else $('#SGContainer').hide();
checkSharingGroup('Attribute');
});
$("#AttributeCategory").on('change', function(e) {
$('#AttributeCategory').change(function() {
formCategoryChanged('Attribute');
if ($(this).val() === 'Internal reference') {
$("#AttributeDistribution").val('0');
$('#SGContainer').hide();
checkSharingGroup('Attribute');
}
});
@ -169,22 +133,16 @@ $(document).ready(function() {
checkNoticeList('attribute');
});
$("#AttributeCategory, #AttributeType, #AttributeDistribution").change(function() {
var start = $("#AttributeType").val();
initPopoverContent('Attribute');
$("#AttributeType").val(start);
if ($.inArray(start, composite_types) > -1) {
$('#compositeWarning').show();
} else {
$('#compositeWarning').hide();
}
$(document).ready(function() {
<?php
if ($action == 'edit'):
?>
checkNoticeList('attribute');
<?php
endif;
?>
checkSharingGroup('Attribute');
});
<?php if ($ajax): ?>
$('#cancel_attribute_add').click(function() {
cancelPopoverForm();
});
<?php endif; ?>
});
</script>
<?php echo $this->element('form_seen_input'); ?>
<?php echo $this->Js->writeBuffer(); // Write cached scripts

View File

@ -32,18 +32,27 @@
'type' => 'checkbox',
'label' => __('Alternate Search Result (Events)')
));
echo $this->Form->input('first_seen', array(
'type' => 'text',
'div' => 'input hidden',
'required' => false,
));
echo $this->Form->input('last_seen', array(
'type' => 'text',
'div' => 'input hidden',
'required' => false,
));
?>
<div class="clear">
<h3><?php echo __('First seen and Last seen.'); ?></h3>
<p><?php echo __('Attributes not having first seen or last seen set might not appear in the search'); ?></p>
</div>
<?php echo $this->element('form_seen_input'); ?>
</fieldset>
<?php
echo $this->Form->button(__('Search'), array('class' => 'btn btn-primary'));
echo $this->Form->end();
?>
<?php echo $this->Form->end(); ?>
<div id="bothSeenSliderContainer"></div>
<button onclick="$('#AttributeSearchForm').submit();" class="btn btn-primary">Submit</button>
</div>
<?php echo $this->element('form_seen_input'); ?>
<script type="text/javascript">
//
// Generate Category / Type filtering array

View File

@ -1,5 +1,4 @@
<?php
if ($object['value'] == 'MERGE') debug($object);
$tr_class = '';
$linkClass = 'blue';
$otherColour = 'blue';

View File

@ -1,5 +1,4 @@
<?php
if ($object['value'] == 'MERGE') debug($object);
$tr_class = '';
$linkClass = 'blue';
$otherColour = 'blue';

View File

@ -49,10 +49,11 @@
'children' => array(
array(
'id' => 'create-button',
'title' => __('Add attribute'),
'title' => $possibleAction === 'attribute' ? __('Add attribute') : __('Add proposal'),
'fa-icon' => 'plus',
'onClick' => 'clickCreateButton',
'onClickParams' => array($event['Event']['id'], $possibleAction)
//'onClick' => 'clickCreateButton',
'onClick' => 'openGenericModal',
'onClickParams' => array('/' . $possibleAction . 's/add/' . h($event['Event']['id']))
),
array(
'id' => 'multi-edit-button',

View File

@ -1,23 +1,5 @@
<?php echo $this->Html->script('moment-with-locales'); ?>
<div class="input-group">
<?php
echo $this->Form->input('first_seen', array(
'type' => 'text',
'div' => 'input hidden',
'required' => false,
));
echo $this->Form->input('last_seen', array(
'type' => 'text',
'div' => 'input hidden',
'required' => false,
));
?>
</div>
<div class="input clear"></div>
<script>
<?php
$temp = explode('_', $this->params->controller);
@ -304,27 +286,7 @@ function reflect_change_on_form() {
}
$(document).ready(function() {
<?php if ($this->params->controller === 'attributes'): ?>
<?php if ($this->params->action === 'add'): ?>
var sliders_container = "<?php echo '#AttributeForm fieldset'; ?>"
<?php elseif ($this->params->action === 'search'): ?>
var sliders_container = "<?php echo '#AttributeSearchForm fieldset'; ?>"
<?php else: ?>
var sliders_container = "<?php echo '#AttributeForm fieldset'; ?>"
<?php endif; ?>
<?php elseif ($this->params->controller === 'shadow_attributes'): ?>
<?php if ($this->params->action === 'add'): ?>
var sliders_container = "<?php echo '#ShadowAttributeAddForm fieldset'; ?>"
<?php elseif ($this->params->action === 'edit'): ?>
var sliders_container = "<?php echo '#ShadowAttributeEditForm fieldset'; ?>"
<?php else: ?>
var sliders_container = "<?php echo '#ShadowAttributeAddForm fieldset'; ?>"
<?php endif; ?>
<?php else: ?>
var sliders_container = "<?php echo '#meta-div'; ?>"
<?php endif; ?>
var sliders_container = "#bothSeenSliderContainer"
var inputs_container = $('<div class="input-group input-daterange"></div>');
// create separate date and time input
var date_div_fs = $('<div class="input clear larger-input-field" style="margin-left: 10px;"></div>').append(
@ -448,7 +410,7 @@ $(document).ready(function() {
event.preventDefault();
});
$('#date_fs').closest('form').submit(function( event ) {
$('#'+controller+'FirstSeen').closest('form').submit(function( event ) {
reflect_change_on_form();
});

View File

@ -16,8 +16,9 @@
h($data['model']);
$fieldsString = '';
$simpleFieldWhitelist = array(
'default', 'type', 'options', 'placeholder', 'label'
'default', 'type', 'options', 'placeholder', 'label', 'empty'
);
$fieldsArrayForPersistence = array();
$formCreate = $this->Form->create($modelForForm);
if (!empty($data['fields'])) {
foreach ($data['fields'] as $fieldData) {
@ -51,6 +52,7 @@
}
}
$temp = $this->Form->input($fieldData['field'], $params);
$fieldsArrayForPersistence []= $modelForForm . Inflector::camelize($fieldData['field']);
if (!empty($fieldData['hidden'])) {
$temp = '<span class="hidden">' . $temp . '</span>';
}
@ -73,18 +75,55 @@
if (!empty($data['submit'])) {
$submitButtonData = array_merge($submitButtonData, $data['submit']);
}
if (!empty($data['ajaxSubmit'])) {
$submitButtonData['ajaxSubmit'] = $ajaxSubmit;
}
$ajaxFlashMessage = '';
if ($ajax) {
$ajaxFlashMessage = sprintf(
'<div id="flashContainer"><div id="main-view-container">%s</div></div>',
$this->Flash->render()
);
}
$formEnd = $this->Form->end();
echo sprintf(
'<div class="form">%s<fieldset><legend>%s</legend>%s</fieldset>%s%s%s</div>',
$formCreate,
empty($data['title']) ? h(Inflector::humanize($this->request->params['action'])) . ' ' . $modelForForm : h($data['title']),
$fieldsString,
$formEnd,
$metaFieldString,
$this->element('genericElements/Form/submitButton', $submitButtonData)
);
if (!empty($ajax)) {
echo sprintf(
'<div id="genericModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="genericModalLabel" aria-hidden="true">%s%s%s</div>',
sprintf(
'<div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button><h3 id="genericModalLabel">%s</h3></div>',
empty($data['title']) ? h(Inflector::humanize($this->request->params['action'])) . ' ' . $modelForForm : h($data['title'])
),
sprintf(
'<div class="modal-body modal-body-long">%s</div>',
sprintf(
'%s<fieldset>%s%s</fieldset>%s%s',
$formCreate,
$ajaxFlashMessage,
$fieldsString,
$formEnd,
$metaFieldString
)
),
sprintf(
'<div class="modal-footer">%s</div>',
$this->element('genericElements/Form/submitButton', $submitButtonData)
)
);
} else {
echo sprintf(
'<div class="form">%s<fieldset><legend>%s</legend>%s%s</fieldset>%s%s%s</div>',
$formCreate,
empty($data['title']) ? h(Inflector::humanize($this->request->params['action'])) . ' ' . $modelForForm : h($data['title']),
$ajaxFlashMessage,
$fieldsString,
$formEnd,
$metaFieldString,
$this->element('genericElements/Form/submitButton', $submitButtonData)
);
}
?>
<script type="text/javascript">
var fieldsArray = <?php echo json_encode($fieldsArrayForPersistence); ?>;
$(document).ready(function() {
popoverStartup();
});

View File

@ -1,12 +1,28 @@
<?php
echo sprintf(
'<button onClick="%s" class="btn btn-%s">%s</button>',
sprintf(
"$('#%s%sForm').submit();",
h($model),
h(Inflector::classify($action))
),
empty($type) ? 'primary' : h($type),
empty($text) ? __('Submit') : h($text)
);
if ($ajax) {
echo sprintf(
'%s%s',
sprintf(
'<button id="submitButton" class="btn btn-primary" onClick="%s">%s</button>',
$ajaxSubmit,
__('Submit')
),
sprintf(
'<button class="btn" data-dismiss="modal" aria-hidden="true" onClick="%s">%s</button>',
'cancelPopoverForm();',
__('Cancel')
)
);
} else {
echo sprintf(
'<button onClick="%s" class="btn btn-%s">%s</button>',
sprintf(
"$('#%s%sForm').submit();",
h($model),
h(Inflector::classify($action))
),
empty($type) ? 'primary' : h($type),
empty($text) ? __('Submit') : h($text)
);
}
?>

View File

@ -1,5 +1,6 @@
<?php
$modelForForm = 'Event';
$action = $this->request->params['action'];
echo $this->element('genericElements/Form/genericForm', array(
'form' => $this->Form,
'data' => array(
@ -60,11 +61,11 @@
'<div id="extended_event_preview" style="width:446px;"></div>'
),
'submit' => array(
'action' => $this->request->params['action']
'action' => $action
)
)
));
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'event-collection', 'menuItem' => $this->action === 'add' ? 'add' : 'editEvent'));
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'event-collection', 'menuItem' => $action === 'add' ? 'add' : 'editEvent'));
?>
<script type="text/javascript">

View File

@ -78,8 +78,18 @@
?>
</dd>
<?php
echo $this->element('form_seen_input');
echo $this->Form->input('first_seen', array(
'type' => 'text',
'div' => 'input hidden',
'required' => false,
));
echo $this->Form->input('last_seen', array(
'type' => 'text',
'div' => 'input hidden',
'required' => false,
));
?>
<div id="bothSeenSliderContainer"></div>
</dl>
</div>
<?php
@ -312,6 +322,7 @@
<?php
echo $this->element('form_seen_input');
if (!$ajax) {
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'event', 'menuItem' => 'addObject', 'event' => $event));
}

View File

@ -40,8 +40,18 @@
echo $this->Form->input('batch_import', array(
'type' => 'checkbox',
));
echo $this->element('form_seen_input');
echo $this->Form->input('first_seen', array(
'type' => 'text',
'div' => 'input hidden',
'required' => false,
));
echo $this->Form->input('last_seen', array(
'type' => 'text',
'div' => 'input hidden',
'required' => false,
));
?>
<div id="bothSeenSliderContainer"></div>
</div>
</fieldset>
<p style="color:red;font-weight:bold;display:none;<?php if ($ajax) echo 'text-align:center;'; ?>" id="warning-message"><?php echo __('Warning: You are about to share data that is of a classified nature (Attribution / targeting data). Make sure that you are authorised to share this.');?></p>
@ -73,6 +83,8 @@
if (!$ajax) {
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'event', 'menuItem' => 'proposeAttribute', 'event' => $event));
}
echo $this->element('form_seen_input');
?>
<script type="text/javascript">
<?php

View File

@ -40,8 +40,18 @@
echo $this->Form->input('to_ids', array(
'label' => __('IDS Signature?'),
));
echo $this->element('form_seen_input');
echo $this->Form->input('first_seen', array(
'type' => 'text',
'div' => 'input hidden',
'required' => false,
));
echo $this->Form->input('last_seen', array(
'type' => 'text',
'div' => 'input hidden',
'required' => false,
));
?>
<div id="bothSeenSliderContainer"></div>
</fieldset>
<p style="color:red;font-weight:bold;display:none;<?php if (isset($ajax) && $ajax) echo "text-align:center;"?>" id="warning-message"><?php echo __('Warning: You are about to share data that is of a sensitive nature (Attribution / targeting data). Make sure that you are authorised to share this.');?></p>
<?php if (isset($ajax) && $ajax): ?>
@ -70,6 +80,8 @@
<?php
$event['Event']['id'] = $this->request->data['ShadowAttribute']['event_id'];
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'event', 'menuItem' => 'proposeAttribute', 'event' => $event));
echo $this->element('form_seen_input');
?>
<script type="text/javascript">

@ -1 +1 @@
Subproject commit e88b1e07ead796ef3cece3e28dfe9c3e4e04598c
Subproject commit c5a2d74ed6a7835d0b7e43fb6c3ee69bd8bcfa80

@ -1 +1 @@
Subproject commit 54da7b5cc30aea83905bb23e94a25b75c055f022
Subproject commit 33a7d6b574b7354ba8243ba461bfb30db0528023

View File

@ -89,44 +89,44 @@ class StixBuilder(object):
idgen.set_id_namespace(Namespace(self.baseurl, self.orgname, "MISP"))
self.namespace_prefix = idgen.get_id_namespace_alias()
## MAPPING FOR ATTRIBUTES
self.simple_type_to_method = {"port": self.generate_port_observable, "domain|ip": self.generate_domain_ip_observable,
"named pipe": self.generate_pipe_observable}
self.simple_type_to_method.update(dict.fromkeys(list(hash_type_attributes["single"]) + list(hash_type_attributes["composite"]) + ["filename"], self.resolve_file_observable))
self.simple_type_to_method.update(dict.fromkeys(["ip-src", "ip-dst"], self.generate_ip_observable))
self.simple_type_to_method.update(dict.fromkeys(["ip-src|port", "ip-dst|port", "hostname|port"], self.generate_socket_address_observable))
self.simple_type_to_method.update(dict.fromkeys(["regkey", "regkey|value"], self.generate_regkey_observable))
self.simple_type_to_method.update(dict.fromkeys(["hostname", "domain", "url", "AS", "mutex", "named pipe", "link", "windows-service-name"], self.generate_simple_observable))
self.simple_type_to_method.update(dict.fromkeys(["email-src", "email-dst", "email-subject", "email-reply-to"], self.resolve_email_observable))
self.simple_type_to_method.update(dict.fromkeys(["http-method", "user-agent"], self.resolve_http_observable))
self.simple_type_to_method.update(dict.fromkeys(["pattern-in-file", "pattern-in-traffic", "pattern-in-memory"], self.resolve_pattern_observable))
self.simple_type_to_method.update(dict.fromkeys(["mac-address"], self.resolve_system_observable))
self.simple_type_to_method.update(dict.fromkeys(["attachment"], self.resolve_attachment))
self.simple_type_to_method.update(dict.fromkeys(["email-attachment"], self.generate_email_attachment_observable))
self.simple_type_to_method.update(dict.fromkeys(["malware-sample"], self.resolve_malware_sample))
self.simple_type_to_method = {"port": 'generate_port_observable', "domain|ip": 'generate_domain_ip_observable',
"named pipe": 'generate_pipe_observable'}
self.simple_type_to_method.update(dict.fromkeys(list(hash_type_attributes["single"]) + list(hash_type_attributes["composite"]) + ["filename"], 'resolve_file_observable'))
self.simple_type_to_method.update(dict.fromkeys(["ip-src", "ip-dst"], 'generate_ip_observable'))
self.simple_type_to_method.update(dict.fromkeys(["ip-src|port", "ip-dst|port", "hostname|port"], 'generate_socket_address_observable'))
self.simple_type_to_method.update(dict.fromkeys(["regkey", "regkey|value"], 'generate_regkey_observable'))
self.simple_type_to_method.update(dict.fromkeys(["hostname", "domain", "url", "AS", "mutex", "named pipe", "link", "windows-service-name"], 'generate_simple_observable'))
self.simple_type_to_method.update(dict.fromkeys(["email-src", "email-dst", "email-subject", "email-reply-to"], 'resolve_email_observable'))
self.simple_type_to_method.update(dict.fromkeys(["http-method", "user-agent"], 'resolve_http_observable'))
self.simple_type_to_method.update(dict.fromkeys(["pattern-in-file", "pattern-in-traffic", "pattern-in-memory"], 'resolve_pattern_observable'))
self.simple_type_to_method.update(dict.fromkeys(["mac-address"], 'resolve_system_observable'))
self.simple_type_to_method.update(dict.fromkeys(["attachment"], 'resolve_attachment'))
self.simple_type_to_method.update(dict.fromkeys(["email-attachment"], 'generate_email_attachment_observable'))
self.simple_type_to_method.update(dict.fromkeys(["malware-sample"], 'resolve_malware_sample'))
## MAPPING FOR OBJECTS
self.ttp_names = {'attack-pattern': self.parse_attack_pattern,
'course-of-action': self.parse_course_of_action,
'vulnerability': self.parse_vulnerability,
'weakness': self.parse_weakness}
self.ttp_names = {'attack-pattern': 'parse_attack_pattern',
'course-of-action': 'parse_course_of_action',
'vulnerability': 'parse_vulnerability',
'weakness': 'parse_weakness'}
self.types_mapping = {CourseOfAction: 'add_course_of_action',
ThreatActor: 'add_threat_actor',
TTP: 'add_ttp'}
self.objects_mapping = {"asn": self.parse_asn_object,
"credential": self.parse_credential_object,
"domain-ip": self.parse_domain_ip_object,
"email": self.parse_email_object,
"file": self.parse_file_object,
"ip-port": self.parse_ip_port_object,
"network-connection": self.parse_network_connection_object,
"network-socket": self.parse_network_socket_object,
"pe": self.store_pe,
"pe-section": self.store_pe,
"process": self.parse_process_object,
"registry-key": self.parse_regkey_object,
"url": self.parse_url_object,
"user-account": self.parse_user_account_object,
"whois": self.parse_whois,
"x509": self.parse_x509_object}
self.objects_mapping = {"asn": 'parse_asn_object',
"credential": 'parse_credential_object',
"domain-ip": 'parse_domain_ip_object',
"email": 'parse_email_object',
"file": 'parse_file_object',
"ip-port": 'parse_ip_port_object',
"network-connection": 'parse_network_connection_object',
"network-socket": 'parse_network_socket_object',
"pe": 'store_pe',
"pe-section": 'store_pe',
"process": 'parse_process_object',
"registry-key": 'parse_regkey_object',
"url": 'parse_url_object',
"user-account": 'parse_user_account_object',
"whois": 'parse_whois',
"x509": 'parse_x509_object'}
def loadEvent(self):
pathname = os.path.dirname(self.args[0])
@ -274,11 +274,11 @@ class StixBuilder(object):
if name == 'original-imported-file':
continue
if name in self.ttp_names:
self.ttp_names[name](misp_object)
getattr(self, self.ttp_names[name])(misp_object)
else:
category = misp_object.get('meta-category')
try:
to_ids, observable = self.objects_mapping[name](misp_object)
to_ids, observable = getattr(self, self.objects_mapping[name])(misp_object)
except KeyError:
to_ids, observable = self.create_custom_observable(name, misp_object['Attribute'], misp_object['uuid'])
except TypeError:
@ -525,7 +525,7 @@ class StixBuilder(object):
attribute_type = attribute['type']
attribute_uuid = attribute['uuid']
try:
observable_property = self.simple_type_to_method[attribute_type](attribute)
observable_property = getattr(self, self.simple_type_to_method[attribute_type])(attribute)
except KeyError:
return False
if isinstance(observable_property, Observable):

View File

@ -189,43 +189,43 @@ class StixBuilder():
def load_objects_mapping(self):
self.objects_mapping = {
'asn': {'observable': self.resolve_asn_observable,
'pattern': self.resolve_asn_pattern},
'credential': {'observable': self.resolve_credential_observable,
'pattern': self.resolve_credential_pattern},
'domain-ip': {'observable': self.resolve_domain_ip_observable,
'pattern': self.resolve_domain_ip_pattern},
'email': {'observable': self.resolve_email_object_observable,
'pattern': self.resolve_email_object_pattern},
'file': {'observable': self.resolve_file_observable,
'pattern': self.resolve_file_pattern},
'ip-port': {'observable': self.resolve_ip_port_observable,
'pattern': self.resolve_ip_port_pattern},
'network-connection': {'observable': self.resolve_network_connection_observable,
'pattern': self.resolve_network_connection_pattern},
'network-socket': {'observable': self.resolve_network_socket_observable,
'pattern': self.resolve_network_socket_pattern},
'process': {'observable': self.resolve_process_observable,
'pattern': self.resolve_process_pattern},
'registry-key': {'observable': self.resolve_regkey_observable,
'pattern': self.resolve_regkey_pattern},
'stix2-pattern': {'pattern': self.resolve_stix2_pattern},
'url': {'observable': self.resolve_url_observable,
'pattern': self.resolve_url_pattern},
'user-account': {'observable': self.resolve_user_account_observable,
'pattern': self.resolve_user_account_pattern},
'x509': {'observable': self.resolve_x509_observable,
'pattern': self.resolve_x509_pattern}
'asn': {'observable': 'resolve_asn_observable',
'pattern': 'resolve_asn_pattern'},
'credential': {'observable': 'resolve_credential_observable',
'pattern': 'resolve_credential_pattern'},
'domain-ip': {'observable': 'resolve_domain_ip_observable',
'pattern': 'resolve_domain_ip_pattern'},
'email': {'observable': 'resolve_email_object_observable',
'pattern': 'resolve_email_object_pattern'},
'file': {'observable': 'resolve_file_observable',
'pattern': 'resolve_file_pattern'},
'ip-port': {'observable': 'resolve_ip_port_observable',
'pattern': 'resolve_ip_port_pattern'},
'network-connection': {'observable': 'resolve_network_connection_observable',
'pattern': 'resolve_network_connection_pattern'},
'network-socket': {'observable': 'resolve_network_socket_observable',
'pattern': 'resolve_network_socket_pattern'},
'process': {'observable': 'resolve_process_observable',
'pattern': 'resolve_process_pattern'},
'registry-key': {'observable': 'resolve_regkey_observable',
'pattern': 'resolve_regkey_pattern'},
'stix2-pattern': {'pattern': 'resolve_stix2_pattern'},
'url': {'observable': 'resolve_url_observable',
'pattern': 'resolve_url_pattern'},
'user-account': {'observable': 'resolve_user_account_observable',
'pattern': 'resolve_user_account_pattern'},
'x509': {'observable': 'resolve_x509_observable',
'pattern': 'resolve_x509_pattern'}
}
def load_galaxy_mapping(self):
self.galaxies_mapping = {'branded-vulnerability': ['vulnerability', self.add_vulnerability_from_galaxy]}
self.galaxies_mapping.update(dict.fromkeys(attack_pattern_galaxies_list, ['attack-pattern', self.add_attack_pattern]))
self.galaxies_mapping.update(dict.fromkeys(course_of_action_galaxies_list, ['course-of-action', self.add_course_of_action]))
self.galaxies_mapping.update(dict.fromkeys(intrusion_set_galaxies_list, ['intrusion-set', self.add_intrusion_set]))
self.galaxies_mapping.update(dict.fromkeys(malware_galaxies_list, ['malware', self.add_malware]))
self.galaxies_mapping.update(dict.fromkeys(threat_actor_galaxies_list, ['threat-actor', self.add_threat_actor]))
self.galaxies_mapping.update(dict.fromkeys(tool_galaxies_list, ['tool', self.add_tool]))
self.galaxies_mapping = {'branded-vulnerability': ['vulnerability', 'add_vulnerability_from_galaxy']}
self.galaxies_mapping.update(dict.fromkeys(attack_pattern_galaxies_list, ['attack-pattern', 'add_attack_pattern']))
self.galaxies_mapping.update(dict.fromkeys(course_of_action_galaxies_list, ['course-of-action', 'add_course_of_action']))
self.galaxies_mapping.update(dict.fromkeys(intrusion_set_galaxies_list, ['intrusion-set', 'add_intrusion_set']))
self.galaxies_mapping.update(dict.fromkeys(malware_galaxies_list, ['malware', 'add_malware']))
self.galaxies_mapping.update(dict.fromkeys(threat_actor_galaxies_list, ['threat-actor', 'add_threat_actor']))
self.galaxies_mapping.update(dict.fromkeys(tool_galaxies_list, ['tool', 'add_tool']))
def get_object_by_uuid(self, uuid):
for _object in self.misp_event['Object']:
@ -373,7 +373,7 @@ class StixBuilder():
except Exception:
return
if galaxy_uuid not in self.galaxies:
to_call(galaxy)
getattr(self, to_call)(galaxy)
self.galaxies.append(galaxy_uuid)
self.relationships['defined'][source_id].append("{}--{}".format(stix_type, galaxy_uuid))
@ -619,7 +619,7 @@ class StixBuilder():
pattern = pattern_arg
else:
name = misp_object['name']
pattern = self.objects_mapping[name]['pattern'](misp_object['Attribute'], indicator_id)
pattern = getattr(self, self.objects_mapping[name]['pattern'])(misp_object['Attribute'], indicator_id)
category = misp_object.get('meta-category')
killchain = self.create_killchain(category)
labels = self.create_object_labels(name, category, True)
@ -638,7 +638,7 @@ class StixBuilder():
observable_objects = observable_arg
else:
name = misp_object['name']
observable_objects = self.objects_mapping[name]['observable'](misp_object['Attribute'], observed_data_id)
observable_objects = getattr(self, self.objects_mapping[name]['observable'])(misp_object['Attribute'], observed_data_id)
category = misp_object.get('meta-category')
labels = self.create_object_labels(name, category, False)
timestamp = self.get_datetime_from_timestamp(misp_object['timestamp'])

View File

@ -49,13 +49,14 @@ class StixParser():
self.filename = filename
self.stix_version = version
self.event = defaultdict(dict)
self.relationship = defaultdict(list)
self.event['relationship'] = defaultdict(list)
mapping = {'custom_object': self.__load_custom,
'marking-definition': self.__load_marking,
'relationship': self.__load_relationship,
'report': self.__load_report}
mapping.update({object_type: self.__load_usual_object for object_type in ('indicator', 'observed-data', 'vulnerability', 'course-of-action')})
mapping.update({galaxy_type: self.__load_galaxy for galaxy_type in galaxy_types})
mapping = {'custom_object': '_load_custom',
'marking-definition': '_load_marking',
'relationship': '_load_relationship',
'report': '_load_report'}
mapping.update({object_type: '_load_usual_object' for object_type in ('indicator', 'observed-data', 'vulnerability', 'course-of-action')})
mapping.update({galaxy_type: '_load_galaxy' for galaxy_type in galaxy_types})
for parsed_object in event.objects:
try:
object_type = parsed_object._type
@ -64,9 +65,9 @@ class StixParser():
if object_type.startswith('x-misp-object'):
object_type = 'custom_object'
try:
mapping[object_type](parsed_object)
getattr(self, mapping[object_type])(parsed_object)
except KeyError:
self.__load_usual_object(parsed_object)
self._load_usual_object(parsed_object)
try:
event_distribution = args[0]
if not isinstance(event_distribution, int):
@ -84,35 +85,31 @@ class StixParser():
self.misp_event.distribution = event_distribution
self._attribute_distribution = attribute_distribution
def __load_custom(self, parsed_object):
def _load_custom(self, parsed_object):
self.event['custom_object'][parsed_object['id'].split('--')[1]] = parsed_object
def __load_galaxy(self, parsed_object):
def _load_galaxy(self, parsed_object):
try:
self.galaxy[parsed_object['id'].split('--')[1]] = {'object': parsed_object, 'used': False}
except AttributeError:
self.galaxy = {parsed_object['id'].split('--')[1]: {'object': parsed_object, 'used': False}}
def __load_marking(self, parsed_object):
def _load_marking(self, parsed_object):
try:
self.marking_definition[parsed_object['id'].split('--')[1]] = {'object': parsed_object, 'used': False}
except AttributeError:
self.marking_definition = {parsed_object['id'].split('--')[1]: {'object': parsed_object, 'used': False}}
def __load_relationship(self, parsed_object):
try:
self.relationship[parsed_object.source_ref.split('--')[1]].append(parsed_object)
except AttributeError:
self.relationship = defaultdict(list)
self.relationship[parsed_object.source_ref.split('--')[1]].append(parsed_object)
def _load_relationship(self, parsed_object):
self.relationship[parsed_object.source_ref.split('--')[1]].append(parsed_object)
def __load_report(self, parsed_object):
def _load_report(self, parsed_object):
try:
self.report[parsed_object['id'].split('--')[1]] = parsed_object
except AttributeError:
self.report = {parsed_object['id'].split('--')[1]: parsed_object}
def __load_usual_object(self, parsed_object):
def _load_usual_object(self, parsed_object):
self.event[parsed_object._type][parsed_object['id'].split('--')[1]] = parsed_object
def general_handler(self):
@ -558,34 +555,34 @@ class StixParser():
class StixFromMISPParser(StixParser):
def __init__(self):
super(StixFromMISPParser, self).__init__()
self.objects_mapping = {'asn': {'observable': self.attributes_from_asn_observable, 'pattern': self.pattern_asn},
'credential': {'observable': self.observable_credential, 'pattern': self.pattern_credential},
'domain-ip': {'observable': self.attributes_from_domain_ip_observable, 'pattern': self.pattern_domain_ip},
'email': {'observable': self.observable_email, 'pattern': self.pattern_email},
'file': {'observable': self.observable_file, 'pattern': self.pattern_file},
'ip-port': {'observable': self.observable_ip_port, 'pattern': self.pattern_ip_port},
'network-connection': {'observable': self.observable_connection, 'pattern': self.pattern_connection},
'network-socket': {'observable': self.observable_socket, 'pattern': self.pattern_socket},
'process': {'observable': self.attributes_from_process_observable, 'pattern': self.pattern_process},
'registry-key': {'observable': self.attributes_from_regkey_observable, 'pattern': self.pattern_regkey},
'url': {'observable': self.attributes_from_url_observable, 'pattern': self.pattern_url},
'user-account': {'observable': self.attributes_from_user_account_observable,
'pattern': self.attributes_from_user_account_pattern},
'WindowsPEBinaryFile': {'observable': self.observable_pe, 'pattern': self.pattern_pe},
'x509': {'observable': self.attributes_from_x509_observable, 'pattern': self.pattern_x509}}
self.object_from_refs = {'course-of-action': self.parse_MISP_course_of_action, 'vulnerability': self.parse_vulnerability,
'custom_object': self.parse_custom}
self.object_from_refs.update(dict.fromkeys(['indicator', 'observed-data'], self.parse_usual_object))
self.attributes_fetcher_mapping = {'indicator': self.fetch_attributes_from_indicator,
'observed-data': self.fetch_attributes_from_observable,
'vulnerability': self.fetch_attributes_from_vulnerability}
self.objects_mapping = {'asn': {'observable': 'attributes_from_asn_observable', 'pattern': 'pattern_asn'},
'credential': {'observable': 'observable_credential', 'pattern': 'pattern_credential'},
'domain-ip': {'observable': 'attributes_from_domain_ip_observable', 'pattern': 'pattern_domain_ip'},
'email': {'observable': 'observable_email', 'pattern': 'pattern_email'},
'file': {'observable': 'observable_file', 'pattern': 'pattern_file'},
'ip-port': {'observable': 'observable_ip_port', 'pattern': 'pattern_ip_port'},
'network-connection': {'observable': 'observable_connection', 'pattern': 'pattern_connection'},
'network-socket': {'observable': 'observable_socket', 'pattern': 'pattern_socket'},
'process': {'observable': 'attributes_from_process_observable', 'pattern': 'pattern_process'},
'registry-key': {'observable': 'attributes_from_regkey_observable', 'pattern': 'pattern_regkey'},
'url': {'observable': 'attributes_from_url_observable', 'pattern': 'pattern_url'},
'user-account': {'observable': 'attributes_from_user_account_observable',
'pattern': 'attributes_from_user_account_pattern'},
'WindowsPEBinaryFile': {'observable': 'observable_pe', 'pattern': 'pattern_pe'},
'x509': {'observable': 'attributes_from_x509_observable', 'pattern': 'pattern_x509'}}
self.object_from_refs = {'course-of-action': 'parse_MISP_course_of_action', 'vulnerability': 'parse_vulnerability',
'custom_object': 'parse_custom'}
self.object_from_refs.update(dict.fromkeys(['indicator', 'observed-data'], 'parse_usual_object'))
self.attributes_fetcher_mapping = {'indicator': 'fetch_attributes_from_indicator',
'observed-data': 'fetch_attributes_from_observable',
'vulnerability': 'fetch_attributes_from_vulnerability'}
def handler(self):
self.general_handler()
def parsing_process(self, object2parse, object_type):
labels = object2parse.get('labels')
self.object_from_refs[object_type](object2parse, labels)
getattr(self, self.object_from_refs[object_type])(object2parse, labels)
################################################################################
## PARSING FUNCTIONS. ##
@ -665,7 +662,7 @@ class StixFromMISPParser(StixParser):
misp_object.uuid = uuid
misp_object['meta-category'] = object_category
try:
attributes = self.attributes_fetcher_mapping[stix_type](o, object_type)
attributes = getattr(self, self.attributes_fetcher_mapping[stix_type])(o, object_type)
except KeyError:
print("Unable to map {} object:\n{}".format(stix_type, o), file=sys.stderr)
return
@ -683,11 +680,11 @@ class StixFromMISPParser(StixParser):
pattern = indicator.pattern.replace('\\\\', '\\').split(' AND ')
pattern[0] = pattern[0][1:]
pattern[-1] = pattern[-1][:-1]
return self.objects_mapping[object_type]['pattern'](pattern)
return getattr(self, self.objects_mapping[object_type]['pattern'])(pattern)
def fetch_attributes_from_observable(self, observable, object_type):
observable = observable.objects
return self.objects_mapping[object_type]['observable'](observable)
return getattr(self, self.objects_mapping[object_type]['observable'])(observable)
def fetch_attributes_from_vulnerability(self, vulnerability, _):
attributes = []
@ -1102,52 +1099,52 @@ class StixFromMISPParser(StixParser):
class ExternalStixParser(StixParser):
def __init__(self):
super(ExternalStixParser, self).__init__()
self.object_from_refs = {'course-of-action': self.parse_course_of_action, 'vulnerability': self.parse_external_vulnerability,
'indicator': self.parse_external_indicator, 'observed-data': self.parse_external_observable}
self.observable_mapping = {('artifact', 'file'): self.parse_file_object_observable,
('autonomous-system',): self.parse_asn_observable,
('autonomous-system', 'ipv4-addr'): self.parse_asn_observable,
('autonomous-system', 'ipv6-addr'): self.parse_asn_observable,
('autonomous-system', 'ipv4-addr', 'ipv6-addr'): self.parse_asn_observable,
('domain-name',): self.parse_domain_ip_observable,
('domain-name', 'ipv4-addr'): self.parse_domain_ip_observable,
('domain-name', 'ipv6-addr'): self.parse_domain_ip_observable,
('domain-name', 'ipv4-addr', 'network-traffic'): self.parse_ip_port_or_network_socket_observable,
('domain-name', 'ipv6-addr', 'network-traffic'): self.parse_ip_port_or_network_socket_observable,
('domain-name', 'ipv4-addr', 'ipv6-addr', 'network-traffic'): self.parse_ip_port_or_network_socket_observable,
('domain-name', 'network-traffic'): self.parse_network_socket_observable,
('domain-name', 'network-traffic', 'url'): self.parse_url_object_observable,
('email-addr',): self.parse_email_address_observable,
('email-addr', 'email-message'): self.parse_email_observable,
('email-addr', 'email-message', 'file'): self.parse_email_observable,
('email-message',): self.parse_email_observable,
('file',): self.parse_file_observable,
('ipv4-addr',): self.parse_ip_address_observable,
('ipv6-addr',): self.parse_ip_address_observable,
('ipv4-addr', 'network-traffic'): self.parse_ip_network_traffic_observable,
('ipv6-addr', 'network-traffic'): self.parse_ip_network_traffic_observable,
('mac-addr',): self.parse_mac_address_observable,
('mutex',): self.parse_mutex_observable,
('process',): self.parse_process_observable,
('x509-certificate',): self.parse_x509_observable,
('url',): self.parse_url_observable,
('user-account',): self.parse_user_account_observable,
('windows-registry-key',): self.parse_regkey_observable}
self.pattern_mapping = {('directory',): self.parse_file_pattern,
('directory', 'file'): self.parse_file_pattern,
('domain-name',): self.parse_domain_ip_port_pattern,
('domain-name', 'ipv4-addr', 'url'): self.parse_domain_ip_port_pattern,
('domain-name', 'ipv6-addr', 'url'): self.parse_domain_ip_port_pattern,
('email-addr',): self.parse_email_address_pattern,
('file',): self.parse_file_pattern,
('ipv4-addr',): self.parse_ip_address_pattern,
('ipv6-addr',): self.parse_ip_address_pattern,
('network-traffic',): self.parse_network_traffic_pattern,
('process',): self.parse_process_pattern,
('url',): self.parse_url_pattern,
('user-account',): self.parse_user_account_pattern,
('windows-registry-key',): self.parse_regkey_pattern,
('x509-certificate',): self.parse_x509_pattern}
self.object_from_refs = {'course-of-action': 'parse_course_of_action', 'vulnerability': 'parse_external_vulnerability',
'indicator': 'parse_external_indicator', 'observed-data': 'parse_external_observable'}
self.observable_mapping = {('artifact', 'file'): 'parse_file_object_observable',
('autonomous-system',): 'parse_asn_observable',
('autonomous-system', 'ipv4-addr'): 'parse_asn_observable',
('autonomous-system', 'ipv6-addr'): 'parse_asn_observable',
('autonomous-system', 'ipv4-addr', 'ipv6-addr'): 'parse_asn_observable',
('domain-name',): 'parse_domain_ip_observable',
('domain-name', 'ipv4-addr'): 'parse_domain_ip_observable',
('domain-name', 'ipv6-addr'): 'parse_domain_ip_observable',
('domain-name', 'ipv4-addr', 'network-traffic'): 'parse_ip_port_or_network_socket_observable',
('domain-name', 'ipv6-addr', 'network-traffic'): 'parse_ip_port_or_network_socket_observable',
('domain-name', 'ipv4-addr', 'ipv6-addr', 'network-traffic'): 'parse_ip_port_or_network_socket_observable',
('domain-name', 'network-traffic'): 'parse_network_socket_observable',
('domain-name', 'network-traffic', 'url'): 'parse_url_object_observable',
('email-addr',): 'parse_email_address_observable',
('email-addr', 'email-message'): 'parse_email_observable',
('email-addr', 'email-message', 'file'): 'parse_email_observable',
('email-message',): 'parse_email_observable',
('file',): 'parse_file_observable',
('ipv4-addr',): 'parse_ip_address_observable',
('ipv6-addr',): 'parse_ip_address_observable',
('ipv4-addr', 'network-traffic'): 'parse_ip_network_traffic_observable',
('ipv6-addr', 'network-traffic'): 'parse_ip_network_traffic_observable',
('mac-addr',): 'parse_mac_address_observable',
('mutex',): 'parse_mutex_observable',
('process',): 'parse_process_observable',
('x509-certificate',): 'parse_x509_observable',
('url',): 'parse_url_observable',
('user-account',): 'parse_user_account_observable',
('windows-registry-key',): 'parse_regkey_observable'}
self.pattern_mapping = {('directory',): 'parse_file_pattern',
('directory', 'file'): 'parse_file_pattern',
('domain-name',): 'parse_domain_ip_port_pattern',
('domain-name', 'ipv4-addr', 'url'): 'parse_domain_ip_port_pattern',
('domain-name', 'ipv6-addr', 'url'): 'parse_domain_ip_port_pattern',
('email-addr',): 'parse_email_address_pattern',
('file',): 'parse_file_pattern',
('ipv4-addr',): 'parse_ip_address_pattern',
('ipv6-addr',): 'parse_ip_address_pattern',
('network-traffic',): 'parse_network_traffic_pattern',
('process',): 'parse_process_pattern',
('url',): 'parse_url_pattern',
('user-account',): 'parse_user_account_pattern',
('windows-registry-key',): 'parse_regkey_pattern',
('x509-certificate',): 'parse_x509_pattern'}
self.pattern_forbidden_relations = (' LIKE ', ' FOLLOWEDBY ', ' MATCHES ', ' ISSUBSET ', ' ISSUPERSET ', ' REPEATS ')
self.single_attribute_fields = ('type', 'value', 'to_ids')
@ -1157,7 +1154,7 @@ class ExternalStixParser(StixParser):
def parsing_process(self, object2parse, object_type):
try:
self.object_from_refs[object_type](object2parse)
getattr(self, self.object_from_refs[object_type])(object2parse)
except KeyError:
print("Unknown {} type: {}".format(self.stix_version, object_type), file=sys.stderr)
@ -1198,9 +1195,9 @@ class ExternalStixParser(StixParser):
to_call = self.observable_mapping[types]
observable_id = observable.id.split('--')[1]
if hasattr(observable, 'object_marking_refs'):
to_call(objects, observable_id, marking=observable.object_marking_refs)
getattr(self, to_call)(objects, observable_id, marking=observable.object_marking_refs)
else:
to_call(objects, observable_id)
getattr(self, to_call)(objects, observable_id)
except KeyError:
print('{} not parsed at the moment'.format(types), file=sys.stderr)
# deeper analyse to come, as well as for indicators
@ -1222,7 +1219,7 @@ class ExternalStixParser(StixParser):
for p in pattern:
type_ = tuple([p.split(' = ')[0].split(':')[0]])
try:
self.pattern_mapping[type_]([p.strip()], marking)
getattr(self, self.pattern_mapping[type_])([p.strip()], marking)
except KeyError:
print('{} not parsed at the moment'.format(type_), file=sys.stderr)
raise Exception
@ -1230,7 +1227,7 @@ class ExternalStixParser(StixParser):
pattern = [p.strip() for p in pattern.split(' AND ')]
types = self.parse_external_pattern_types(pattern)
try:
self.pattern_mapping[types](pattern, marking, uuid=uuid)
getattr(self, self.pattern_mapping[types])(pattern, marking, uuid=uuid)
except KeyError:
print('{} not parsed at the moment'.format(types), file=sys.stderr)
raise Exception
@ -1268,7 +1265,7 @@ class ExternalStixParser(StixParser):
## PARSING FUNCTIONS. ##
################################################################################
def add_attributes_from_observable(self, objects, attribute_type, identifier, marking, uuid):
def add_attributes_from_observable(self, objects, attribute_type, identifier, uuid, marking):
attribute = {'to_ids': False}
if len(objects) == 1:
attribute['uuid'] = uuid
@ -1321,11 +1318,11 @@ class ExternalStixParser(StixParser):
file_object.add_reference(pe_uuid, 'includes')
self.misp_event.add_object(**file_object)
def parse_asn_observable(self, objects, marking, uuid):
def parse_asn_observable(self, objects, uuid, marking=None):
attributes = self.attributes_from_asn_observable(objects)
self.handle_import_case(attributes, 'asn', marking, uuid)
def parse_domain_ip_observable(self, objects, marking, uuid):
def parse_domain_ip_observable(self, objects, uuid, marking=None):
attributes = self.attributes_from_domain_ip_observable(objects)
self.handle_import_case(attributes, 'domain-ip', marking, uuid)
@ -1337,7 +1334,7 @@ class ExternalStixParser(StixParser):
attributes = self.attributes_from_dict(values, domain_ip_mapping, True)
self.handle_import_case(attributes, 'domain-ip', marking, uuid)
def parse_email_observable(self, objects, marking, uuid):
def parse_email_observable(self, objects, uuid, marking=None):
to_ids = False
attributes, message = self.parse_complex_fields_observable_email(objects, to_ids)
for m_key, m_value in message.items():
@ -1345,7 +1342,7 @@ class ExternalStixParser(StixParser):
attributes.append(self.append_email_attribute(m_key, m_value, to_ids))
self.handle_import_case(attributes, 'email', marking, uuid)
def parse_email_address_observable(self, objects, marking, uuid):
def parse_email_address_observable(self, objects, uuid, marking=None):
mapping = to_attribute_mapping
attributes = [{'type': 'email-dst', 'object_relation': 'to', 'to_ids': True, 'value': _object.value} for _object in objects.values()]
self.handle_import_case(attributes, 'email', marking, uuid)
@ -1355,7 +1352,7 @@ class ExternalStixParser(StixParser):
attributes = self.fill_pattern_attributes(pattern_types, pattern_values, email_mapping)
self.handle_import_case(attributes, 'email', marking, uuid)
def parse_file_observable(self, objects, marking, uuid):
def parse_file_observable(self, objects, uuid, marking=None):
file, directory = self.split_file_observable(objects)
attributes = self.attributes_from_file_observable(file)
if directory is not None and directory.path:
@ -1375,7 +1372,7 @@ class ExternalStixParser(StixParser):
else:
self.handle_import_case(attributes, 'file', marking, uuid)
def parse_file_object_observable(self, objects, marking, uuid):
def parse_file_object_observable(self, objects, uuid, marking=None):
file, data = self.split_file_observable(objects)
attributes = self.attributes_from_file_observable(file, data)
if hasattr(file, 'extensions') and 'windows-pebinary-ext' in file.extensions:
@ -1383,27 +1380,27 @@ class ExternalStixParser(StixParser):
else:
self.handle_import_case(attributes, file._type, marking, uuid)
def parse_ip_address_observable(self, objects, marking, uuid):
self.add_attributes_from_observable(objects, 'ip-dst', 'value', marking, uuid)
def parse_ip_address_observable(self, objects, uuid, marking=None):
self.add_attributes_from_observable(objects, 'ip-dst', 'value', uuid, marking)
def parse_ip_address_pattern(self, pattern, marking=None, uuid=None):
self.add_attributes_from_pattern('ip-dst', pattern, marking, uuid)
def parse_ip_network_traffic_observable(self, objects, marking, uuid):
def parse_ip_network_traffic_observable(self, objects, uuid, marking=None):
attributes, name = self.attributes_from_network_traffic(objects)
self.handle_import_case(attributes, name, marking, uuid)
def parse_ip_port_or_network_socket_observable(self, objects, marking, uuid):
def parse_ip_port_or_network_socket_observable(self, objects, uuid, marking=None):
attributes, name = self.attributes_from_network_traffic(objects)
self.handle_import_case(attributes, name, marking, uuid)
def parse_mac_address_observable(self, objects, marking, uuid):
self.add_attributes_from_observable(objects, 'mac-address', 'value', marking, uuid)
def parse_mac_address_observable(self, objects, uuid, marking=None):
self.add_attributes_from_observable(objects, 'mac-address', 'value', uuid, marking)
def parse_mutex_observable(self, objects, marking, uuid):
self.add_attributes_from_observable(objects, 'mutex', 'name', marking, uuid)
def parse_mutex_observable(self, objects, uuid, marking=None):
self.add_attributes_from_observable(objects, 'mutex', 'name', uuid, marking)
def parse_network_socket_observable(self, objects, marking, uuid):
def parse_network_socket_observable(self, objects, uuid, marking=None):
attributes, name = self.attributes_from_network_traffic(objects)
self.handle_import_case(attributes, name, marking, uuid)
@ -1412,7 +1409,7 @@ class ExternalStixParser(StixParser):
attributes = self.fill_pattern_attributes(pattern_types, pattern_values, network_traffic_mapping)
self.handle_import_case(attributes, 'ip-port', marking, uuid)
def parse_process_observable(self, objects, marking, uuid):
def parse_process_observable(self, objects, uuid, marking=None):
attributes = self.attributes_from_process_observable(objects)
self.handle_import_case(attributes, 'process', marking, uuid)
@ -1421,7 +1418,7 @@ class ExternalStixParser(StixParser):
attributes = self.fill_pattern_attributes(pattern_types, pattern_values, process_mapping)
self.handle_import_case(attributes, 'process', marking, uuid)
def parse_regkey_observable(self, objects, marking, uuid):
def parse_regkey_observable(self, objects, uuid, marking=None):
_object = objects['0']
attributes = self.attributes_from_regkey_observable(_object)
self.handle_import_case(attributes, 'registry-key', marking, uuid)
@ -1431,17 +1428,17 @@ class ExternalStixParser(StixParser):
attributes = self.fill_pattern_attributes(pattern_types, pattern_values, regkey_mapping)
self.handle_import_case(attributes, 'registry-key', marking, uuid)
def parse_url_observable(self, objects, marking, uuid):
self.add_attributes_from_observable(objects, 'url', 'value', marking, uuid)
def parse_url_observable(self, objects, uuid, marking=None):
self.add_attributes_from_observable(objects, 'url', 'value', uuid, marking)
def parse_url_pattern(self, pattern, marking=None, uuid=None):
self.add_attributes_from_pattern('url', pattern, marking, uuid)
def parse_url_object_observable(self, objects, marking, uuid):
def parse_url_object_observable(self, objects, uuid, marking=None):
attributes = self.attributes_from_url_observable(objects)
self.handle_import_case(attributes, 'url', marking, uuid)
def parse_user_account_observable(self, observable, marking, uuid):
def parse_user_account_observable(self, observable, uuid, marking=None):
attributes = self.attributes_from_user_account_observable(observable)
name = self.__define_user_account_name(attributes)
self.handle_import_case(attributes, name, marking, uuid)
@ -1451,7 +1448,7 @@ class ExternalStixParser(StixParser):
name = self.__define_user_account_name(attributes)
self.handle_import_case(attributes, name, marking, uuid)
def parse_x509_observable(self, objects, marking, uuid):
def parse_x509_observable(self, objects, uuid, marking=None):
attributes = self.attributes_from_x509_observable(objects)
self.handle_import_case(attributes, 'x509', marking, uuid)
@ -1533,7 +1530,7 @@ class ExternalStixParser(StixParser):
values.append(value.strip().strip('\''))
return types, values
def handle_import_case(self, attributes, name, marking=None, uuid=None):
def handle_import_case(self, attributes, name, marking, uuid):
if len(attributes) == 1:
attribute = attributes[0]
attribute = {field: attribute[field] for field in self.single_attribute_fields if attribute.get(field)}

View File

@ -100,42 +100,42 @@ class StixParser():
# Load the mapping dictionary for STIX object types
def load_mapping(self):
self.attribute_types_mapping = {
"AccountObjectType": self.handle_credential,
'AddressObjectType': self.handle_address,
"ArtifactObjectType": self.handle_attachment,
"ASObjectType": self.handle_as,
"CustomObjectType": self.handle_custom,
"DNSRecordObjectType": self.handle_dns,
'DomainNameObjectType': self.handle_domain_or_url,
'EmailMessageObjectType': self.handle_email_attribute,
'FileObjectType': self.handle_file,
'HostnameObjectType': self.handle_hostname,
'HTTPSessionObjectType': self.handle_http,
'LinkObjectType': self.handle_link,
'MutexObjectType': self.handle_mutex,
'NetworkConnectionObjectType': self.handle_network_connection,
'NetworkSocketObjectType': self.handle_network_socket,
'PDFFileObjectType': self.handle_file,
'PipeObjectType': self.handle_pipe,
'PortObjectType': self.handle_port,
'ProcessObjectType': self.handle_process,
'SocketAddressObjectType': self.handle_socket_address,
'SystemObjectType': self.handle_system,
'UnixUserAccountObjectType': self.handle_unix_user,
'URIObjectType': self.handle_domain_or_url,
'UserAccountObjectType': self.handle_user,
"WhoisObjectType": self.handle_whois,
"WindowsFileObjectType": self.handle_file,
'WindowsRegistryKeyObjectType': self.handle_regkey,
"WindowsExecutableFileObjectType": self.handle_pe,
"WindowsServiceObjectType": self.handle_windows_service,
'WindowsUserAccountObjectType': self.handle_windows_user,
"X509CertificateObjectType": self.handle_x509
"AccountObjectType": 'handle_credential',
'AddressObjectType': 'handle_address',
"ArtifactObjectType": 'handle_attachment',
"ASObjectType": 'handle_as',
"CustomObjectType": 'handle_custom',
"DNSRecordObjectType": 'handle_dns',
'DomainNameObjectType': 'handle_domain_or_url',
'EmailMessageObjectType': 'handle_email_attribute',
'FileObjectType': 'handle_file',
'HostnameObjectType': 'handle_hostname',
'HTTPSessionObjectType': 'handle_http',
'LinkObjectType': 'handle_link',
'MutexObjectType': 'handle_mutex',
'NetworkConnectionObjectType': 'handle_network_connection',
'NetworkSocketObjectType': 'handle_network_socket',
'PDFFileObjectType': 'handle_file',
'PipeObjectType': 'handle_pipe',
'PortObjectType': 'handle_port',
'ProcessObjectType': 'handle_process',
'SocketAddressObjectType': 'handle_socket_address',
'SystemObjectType': 'handle_system',
'UnixUserAccountObjectType': 'handle_unix_user',
'URIObjectType': 'handle_domain_or_url',
'UserAccountObjectType': 'handle_user',
"WhoisObjectType": 'handle_whois',
"WindowsFileObjectType": 'handle_file',
'WindowsRegistryKeyObjectType': 'handle_regkey',
"WindowsExecutableFileObjectType": 'handle_pe',
"WindowsServiceObjectType": 'handle_windows_service',
'WindowsUserAccountObjectType': 'handle_windows_user',
"X509CertificateObjectType": 'handle_x509'
}
self.marking_mapping = {
'AIS:AISMarkingStructure': self.parse_AIS_marking,
'tlpMarking:TLPMarkingStructureType': self.parse_TLP_marking
'AIS:AISMarkingStructure': 'parse_AIS_marking',
'tlpMarking:TLPMarkingStructureType': 'parse_TLP_marking'
}
def parse_marking(self, handling):
@ -143,7 +143,7 @@ class StixParser():
if hasattr(handling, 'marking_structures') and handling.marking_structures:
for marking in handling.marking_structures:
try:
tags.extend(self.marking_mapping[marking._XSI_TYPE](marking))
tags.extend(getattr(self, self.marking_mapping[marking._XSI_TYPE])(marking))
except KeyError:
print(marking._XSI_TYPE, file=sys.stderr)
continue
@ -226,7 +226,7 @@ class StixParser():
args.append(is_object)
elif xsi_type == "ArtifactObjectType":
args.append(title)
return self.attribute_types_mapping[xsi_type](*args)
return getattr(self, self.attribute_types_mapping[xsi_type])(*args)
# except AttributeError:
# # ATM USED TO TEST TYPES
# print("Unparsed type: {}".format(xsi_type))

@ -1 +1 @@
Subproject commit d7e067bf5b2889c43699c86f66c56b4139ac42dc
Subproject commit 6179f6bb4adb02c99c9a0b133d2b0756758d0585

@ -1 +1 @@
Subproject commit baa25888c98a44b96cf50716e5bc51219e57b33a
Subproject commit 260171d89b494f4e8c84fa80ac263d296b43a2f9

View File

@ -931,6 +931,10 @@ a.proposal_link_red:hover {
float: left;
}
.modal-body-long {
max-height: 600px;
}
.ajax_popover_form {
display:none;
width: 700px;
@ -993,7 +997,7 @@ a.proposal_link_red:hover {
border-radius: 10px 10px 0px 0px;
padding-left:10px;
margin-bottom:0px;
width:690px;
width:calc(100% - 10px);
background-color:black;
color:white;
font-size: 21px;
@ -1027,8 +1031,9 @@ a.proposal_link_red:hover {
height:120px !important;
}
.ajax_popover_form .add_attribute_fields {
.ajax_fieldset, .ajax_popover_form .add_attribute_fields {
padding-left:10px;
padding-right:10px;
}
.hover_enrichment_text {
@ -2509,4 +2514,4 @@ table tr:hover .down-expand-button {
background-color: #3b3b3b;
color: white;
border-radius: 3px;
}
}

View File

@ -1170,62 +1170,56 @@ function clickCreateButton(event, type) {
simplePopup("/" + destination + "/add/" + event);
}
function submitPopoverForm(context_id, referer, update_context_id, popover_dissmis_id_to_close) {
function openGenericModal(url) {
$.ajax({
type: "get",
url: url,
success: function (data) {
$('#genericModal').remove();
$('body').append(data);
$('#genericModal').modal();
},
error: function (data, textStatus, errorThrown) {
showMessage('fail', textStatus + ": " + errorThrown);
}
});
}
// function submitPopoverForm(context_id, referer, update_context_id, popover_dissmis_id_to_close) {
function submitPopoverForm(context_id, referer, update_context_id, modal) {
var url = null;
var context = 'event';
var contextNamingConvention = 'Attribute';
var closePopover = true;
switch (referer) {
case 'add':
url = "/attributes/add/" + context_id;
break;
case 'edit':
url = "/attributes/edit/" + context_id;
break;
case 'propose':
url = "/shadow_attributes/add/" + context_id;
break;
case 'massEdit':
url = "/attributes/editSelected/" + context_id;
break;
case 'addTextElement':
url = "/templateElements/add/text/" + context_id;
context = 'template';
contextNamingConvention = 'TemplateElementText';
break;
case 'editTextElement':
url = "/templateElements/edit/text/" + context_id;
context = 'template';
context_id = update_context_id;
contextNamingConvention = 'TemplateElementText';
break;
case 'addAttributeElement':
url = "/templateElements/add/attribute/" + context_id;
context = 'template';
contextNamingConvention = 'TemplateElementAttribute';
break;
case 'editAttributeElement':
url = "/templateElements/edit/attribute/" + context_id;
context = 'template';
context_id = update_context_id;
contextNamingConvention = 'TemplateElementAttribute';
break;
case 'addFileElement':
url = "/templateElements/add/file/" + context_id;
context = 'template';
contextNamingConvention = 'TemplateElementFile';
break;
case 'editFileElement':
url = "/templateElements/edit/file/" + context_id;
context = 'template';
context_id = update_context_id;
contextNamingConvention = 'TemplateElementFile';
break;
case 'replaceAttributes':
url = "/attributes/attributeReplace/" + context_id;
break;
case 'addSighting':
url = "/sightings/add/" + context_id;
closePopover = false;
break;
case 'addObjectReference':
@ -1235,44 +1229,101 @@ function submitPopoverForm(context_id, referer, update_context_id, popover_dissm
url = "/objects/quickAddAttributeForm/" + context_id;
break;
}
if (url !== null) {
url = baseurl + url;
$.ajax({
beforeSend: function (XMLHttpRequest) {
$(".loading").show();
if ($("#submitButton").parent().hasClass('modal-footer')) {
var $form = $("#submitButton").parent().parent().find('.modal-body form');
url = baseurl + $form.attr('action');
} else {
var $form = $("#submitButton").closest("form");
url = baseurl + $form.attr('action');
}
$.ajax({
beforeSend: function (XMLHttpRequest) {
if (modal) {
if (closePopover) {
$('#genericModal').modal('hide');
}
} else {
if (closePopover) {
$("#gray_out").fadeOut();
$("#popover_form").fadeOut();
if (popover_dissmis_id_to_close !== undefined) {
$('[data-dismissid="' + popover_dissmis_id_to_close + '"]').popover('destroy');
}
// if (popover_dissmis_id_to_close !== undefined) {
// $('[data-dismissid="' + popover_dissmis_id_to_close + '"]').popover('destroy');
// }
$(".loading").show();
}
},
data: $("#submitButton").closest("form").serialize(),
success:function (data, textStatus) {
var result;
if (closePopover) {
}
},
data: $form.serialize(),
success:function (data, textStatus) {
var result;
if (closePopover) {
if (modal) {
result = handleAjaxModalResponse(data, context_id, url, referer, context, contextNamingConvention);
} else {
result = handleAjaxPopoverResponse(data, context_id, url, referer, context, contextNamingConvention);
}
if (referer == 'addSighting') {
updateIndex(update_context_id, 'event');
$.get( "/sightings/listSightings/" + id + "/attribute", function(data) {
$("#sightingsData").html(data);
});
$('.sightingsToggle').removeClass('btn-primary');
$('.sightingsToggle').addClass('btn-inverse');
$('#sightingsListAllToggle').removeClass('btn-inverse');
$('#sightingsListAllToggle').addClass('btn-primary');
}
if (
(
context == 'event' &&
(referer == 'add' || referer == 'massEdit' || referer == 'replaceAttributes' || referer == 'addObjectReference')
) ||
referer == 'quickAddAttributeForm'
){
eventUnpublish();
}
if (referer == 'addSighting') {
updateIndex(update_context_id, 'event');
$.get( "/sightings/listSightings/" + id + "/attribute", function(data) {
$("#sightingsData").html(data);
});
$('.sightingsToggle').removeClass('btn-primary');
$('.sightingsToggle').addClass('btn-inverse');
$('#sightingsListAllToggle').removeClass('btn-inverse');
$('#sightingsListAllToggle').addClass('btn-primary');
}
if (
(
context == 'event' &&
(referer == 'add' || referer == 'massEdit' || referer == 'replaceAttributes' || referer == 'addObjectReference')
) ||
referer == 'quickAddAttributeForm' // FIXME: Why no inline with the others?
){
eventUnpublish();
}
},
error: function (jqXHR, textStatus, errorThrown) {
showMessage('fail', textStatus + ": " + errorThrown);
},
complete: function () {
$(".loading").hide();
},
type: "post",
url: url,
});
return false;
};
function handleAjaxModalResponse(response, context_id, url, referer, context, contextNamingConvention) {
responseArray = response;
var message = null;
var result = "fail";
if (responseArray.saved) {
updateIndex(context_id, context);
if (responseArray.success) {
showMessage("success", responseArray.success);
result = "success";
}
if (responseArray.errors) {
showMessage("fail", responseArray.errors);
}
} else {
var savedArray = saveValuesForPersistance();
$.ajax({
async:true,
dataType:"html",
success:function (data, textStatus) {
$('#genericModal').remove();
$('body').append(data);
$('#genericModal').modal();
var error_context = context.charAt(0).toUpperCase() + context.slice(1);
handleValidationErrors(responseArray.errors, context, contextNamingConvention);
result = "success";
if (!$.isEmptyObject(responseArray)) {
result = "fail";
}
recoverValuesFromPersistance(savedArray);
},
error: function (jqXHR, textStatus, errorThrown) {
showMessage('fail', textStatus + ": " + errorThrown);
@ -1280,13 +1331,11 @@ function submitPopoverForm(context_id, referer, update_context_id, popover_dissm
complete: function () {
$(".loading").hide();
},
type: "post",
url: url,
url:url
});
}
return false;
};
return result;
}
function handleAjaxPopoverResponse(response, context_id, url, referer, context, contextNamingConvention) {
responseArray = response;