mirror of https://github.com/MISP/MISP
new: Added first iteration of new add attachment functionality
- still WIPpull/2489/head
parent
78f49e5e62
commit
c8b0be9431
|
@ -345,7 +345,6 @@ class AttributesController extends AppController {
|
|||
$success = 0;
|
||||
|
||||
foreach ($this->request->data['Attribute']['values'] as $k => $value) {
|
||||
|
||||
// Check if there were problems with the file upload
|
||||
// only keep the last part of the filename, this should prevent directory attacks
|
||||
$filename = basename($value['name']);
|
||||
|
@ -361,36 +360,34 @@ class AttributesController extends AppController {
|
|||
}
|
||||
|
||||
if ($this->request->data['Attribute']['malware']) {
|
||||
$result = $this->Event->Attribute->handleMaliciousBase64($this->request->data['Attribute']['event_id'], $filename, base64_encode($tmpfile->read()), array_keys($hashes));
|
||||
if (!$result['success']) {
|
||||
$this->Session->setFlash(__('There was a problem to upload the file.', true), 'default', array(), 'error');
|
||||
$this->redirect(array('controller' => 'events', 'action' => 'view', $this->request->data['Attribute']['event_id']));
|
||||
}
|
||||
foreach ($hashes as $hash => $typeName) {
|
||||
if (!$result[$hash]) continue;
|
||||
$attribute = array(
|
||||
'Attribute' => array(
|
||||
'value' => $filename . '|' . $result[$hash],
|
||||
'category' => $this->request->data['Attribute']['category'],
|
||||
'type' => $typeName,
|
||||
'event_id' => $this->request->data['Attribute']['event_id'],
|
||||
'comment' => $this->request->data['Attribute']['comment'],
|
||||
'to_ids' => 1,
|
||||
'distribution' => $this->request->data['Attribute']['distribution'],
|
||||
'sharing_group_id' => isset($this->request->data['Attribute']['sharing_group_id']) ? $this->request->data['Attribute']['sharing_group_id'] : 0,
|
||||
)
|
||||
);
|
||||
if ($hash == 'md5') $attribute['Attribute']['data'] = $result['data'];
|
||||
$this->Attribute->create();
|
||||
$r = $this->Attribute->save($attribute);
|
||||
if ($r == false) {
|
||||
if ($hash == 'md5') {
|
||||
$fails[] = $filename;
|
||||
} else {
|
||||
$partialFails[] = '[' . $typeName . ']' . $filename;
|
||||
if ($this->request->data['Attribute']['advanced']) {
|
||||
$execRetval = '';
|
||||
$execOutput = array();
|
||||
$result = shell_exec('python ' . APP . 'files/scripts/generate_file_objects.py -p ' . $tmpfile->path);
|
||||
if (!empty($result)) {
|
||||
$result = json_decode($result, true);
|
||||
if (isset($result['objects'])) {
|
||||
$result['Object'] = $result['objects'];
|
||||
unset($result['objects']);
|
||||
}
|
||||
} else {
|
||||
if ($hash == 'md5') $success++;
|
||||
}
|
||||
} else {
|
||||
$result = $this->Attribute->simpleAddMalwareSample(
|
||||
$eventId,
|
||||
$this->request->data['Attribute']['category'],
|
||||
$this->request->data['Attribute']['distribution'],
|
||||
$this->request->data['Attribute']['distribution'] == 4 ? $this->request->data['Attribute']['sharing_group_id'] : 0,
|
||||
$this->request->data['Attribute']['comment'],
|
||||
$filename,
|
||||
$tmpfile
|
||||
);
|
||||
}
|
||||
if (!empty($result)) {
|
||||
foreach ($result['Object'] as $object) {
|
||||
foreach ($object['Attribute'] as $k => $attribute) {
|
||||
if ($attribute['value'] == $tmpfile->name) $object['Attribute'][$k]['value'] = $value['name'];
|
||||
}
|
||||
$result = $this->Attribute->Object->captureObject($eventId, array('Object' => $object), $this->Auth->user());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -413,9 +410,9 @@ class AttributesController extends AppController {
|
|||
else $success++;
|
||||
}
|
||||
}
|
||||
|
||||
throw new Exception();
|
||||
$message = 'The attachment(s) have been uploaded.';
|
||||
if (!empty($partialFails)) $message .= ' Some of the hashes however could not be generated.';
|
||||
if (!empty($partialFails)) $message .= ' Some of the attributes however could not be created.';
|
||||
if (!empty($fails)) $message = 'Some of the attachments failed to upload. The failed files were: ' . implode(', ', $fails) . ' - This can be caused by the attachments already existing in the event.';
|
||||
if (empty($success)) {
|
||||
if (empty($fails)) $message = 'The attachment(s) could not be saved. please contact your administrator.';
|
||||
|
|
|
@ -487,6 +487,10 @@ class Attribute extends AppModel {
|
|||
'SharingGroup' => array(
|
||||
'className' => 'SharingGroup',
|
||||
'foreignKey' => 'sharing_group_id'
|
||||
),
|
||||
'Object' => array(
|
||||
'className' => 'MispObject',
|
||||
'foreignKey' => 'object_id'
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -2466,7 +2470,7 @@ class Attribute extends AppModel {
|
|||
return true;
|
||||
}
|
||||
|
||||
public function saveAndEncryptAttribute($attribute, $user) {
|
||||
public function saveAndEncryptAttribute($attribute, $user = false) {
|
||||
$hashes = array('md5' => 'malware-sample', 'sha1' => 'filename|sha1', 'sha256' => 'filename|sha256');
|
||||
if ($attribute['encrypt']) {
|
||||
$result = $this->handleMaliciousBase64($attribute['event_id'], $attribute['value'], $attribute['data'], array_keys($hashes));
|
||||
|
@ -2662,4 +2666,77 @@ class Attribute extends AppModel {
|
|||
}
|
||||
return array('sgs' => $sgs, 'levels' => $distributionLevels, 'initial' => $initialDistribution);
|
||||
}
|
||||
|
||||
public function simpleAddMalwareSample($event_id, $category, $distribution, $sharing_group_id, $comment, $filename, $tmpfile) {
|
||||
$attributes = array(
|
||||
'malware-sample' => array('type' => 'malware-sample', 'data' => 1, 'category' => '', 'to_ids' => 1, 'disable_correlation' => 0),
|
||||
'filename' => array('type' => 'filename', 'category' => '', 'to_ids' => 0, 'disable_correlation' => 0),
|
||||
'md5' => array('type' => 'md5', 'category' => '', 'to_ids' => 1, 'disable_correlation' => 0),
|
||||
'sha1' => array('type' => 'sha1', 'category' => '', 'to_ids' => 1, 'disable_correlation' => 0),
|
||||
'sha256' => array('type' => 'sha256', 'category' => '', 'to_ids' => 1, 'disable_correlation' => 0),
|
||||
'size-in-bytes' => array('type' => 'size-in-bytes', 'category' => '', 'to_ids' => 0, 'disable_correlation' => 1)
|
||||
);
|
||||
$hashes = array('md5', 'sha1', 'sha256');
|
||||
$this->Object = ClassRegistry::init('Object');
|
||||
$this->ObjectTemplate = ClassRegistry::init('ObjectTemplate');
|
||||
$object_template = $this->ObjectTemplate->find('first', array(
|
||||
'conditions' => array(
|
||||
'ObjectTemplate.uuid' => '688c46fb-5edb-40a3-8273-1af7923e2215'
|
||||
),
|
||||
'recursive' => -1
|
||||
));
|
||||
if (empty($object_template)) {
|
||||
$object_template = array(
|
||||
'ObjectTemplate' => array(
|
||||
'meta-category' => 'file',
|
||||
'name' => 'file',
|
||||
'template_uuid' => '688c46fb-5edb-40a3-8273-1af7923e2215',
|
||||
'version' => 1,
|
||||
'description' => 'File object describing a file with meta-information'
|
||||
)
|
||||
);
|
||||
}
|
||||
$object = array(
|
||||
'distribution' => $distribution,
|
||||
'sharing_group_id' => $sharing_group_id,
|
||||
'meta-category' => $object_template['ObjectTemplate']['meta-category'],
|
||||
'name' => $object_template['ObjectTemplate']['name'],
|
||||
'template_version' => $object_template['ObjectTemplate']['version'],
|
||||
'description' => $object_template['ObjectTemplate']['description'],
|
||||
'template_uuid' => $object_template['ObjectTemplate']['uuid'],
|
||||
'event_id' => $event_id,
|
||||
'comment' => $comment
|
||||
);
|
||||
foreach ($attributes as $k => $v) {
|
||||
$result = $this->Event->Attribute->handleMaliciousBase64($event_id, $filename, base64_encode($tmpfile->read()), $hashes);
|
||||
$attribute = array(
|
||||
'distribution' => 5,
|
||||
'category' => $category,
|
||||
'type' => $v['type'],
|
||||
'to_ids' => $v['to_ids'],
|
||||
'disable_correlation' => $v['disable_correlation'],
|
||||
'object_id' => $this->Object->id,
|
||||
'event_id' => $event_id
|
||||
);
|
||||
if (isset($v['data'])) {
|
||||
$attribute['data'] = $result['data'];
|
||||
}
|
||||
if ($k == 'malware-sample') {
|
||||
$attribute['value'] = $filename . '|' . $result['md5'];
|
||||
} else if ($k == 'size-in-bytes') {
|
||||
$attribute['value'] = 0;
|
||||
} else if ($k == 'filename') {
|
||||
$attribute['value'] = $filename;
|
||||
} else {
|
||||
$attribute['value'] = $result[$v['type']];
|
||||
}
|
||||
$object['Attribute'][] = $attribute;
|
||||
}
|
||||
return array('Object' => $object);
|
||||
}
|
||||
|
||||
public function advancedAddMalwareSample() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -51,20 +51,23 @@ class MispObject extends AppModel {
|
|||
|
||||
public function beforeValidate($options = array()) {
|
||||
parent::beforeValidate();
|
||||
if (empty($this->data['Object']['comment'])) {
|
||||
$this->data['Object']['comment'] = "";
|
||||
if (empty($this->data[$this->alias]['comment'])) {
|
||||
$this->data[$this->alias]['comment'] = "";
|
||||
}
|
||||
// generate UUID if it doesn't exist
|
||||
if (empty($this->data['Object']['uuid'])) {
|
||||
$this->data['Object']['uuid'] = CakeText::uuid();
|
||||
if (empty($this->data[$this->alias]['uuid'])) {
|
||||
$this->data[$this->alias]['uuid'] = CakeText::uuid();
|
||||
}
|
||||
// generate timestamp if it doesn't exist
|
||||
if (empty($this->data['Object']['timestamp'])) {
|
||||
if (empty($this->data[$this->alias]['timestamp'])) {
|
||||
$date = new DateTime();
|
||||
$this->data['Object']['timestamp'] = $date->getTimestamp();
|
||||
$this->data[$this->alias]['timestamp'] = $date->getTimestamp();
|
||||
}
|
||||
if (!isset($this->data['Object']['distribution']) || $this->data['Object']['distribution'] != 4) $this->data['Object']['sharing_group_id'] = 0;
|
||||
if (!isset($this->data['Object']['distribution'])) $this->data['Object']['distribution'] = 5;
|
||||
if (empty($this->data[$this->alias]['template_version'])) {
|
||||
$this->data[$this->alias]['template_version'] = 1;
|
||||
}
|
||||
if (!isset($this->data[$this->alias]['distribution']) || $this->data['Object']['distribution'] != 4) $this->data['Object']['sharing_group_id'] = 0;
|
||||
if (!isset($this->data[$this->alias]['distribution'])) $this->data['Object']['distribution'] = 5;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -369,4 +372,30 @@ class MispObject extends AppModel {
|
|||
$this->Event->Attribute->save($originalAttribute);
|
||||
}
|
||||
}
|
||||
|
||||
public function captureObject($eventId, $object, $user) {
|
||||
$this->create();
|
||||
$object['Object']['event_id'] = $eventId;
|
||||
if ($this->save($object)) {
|
||||
$objectId = $this->id;
|
||||
$partialFails = array();
|
||||
foreach ($object['Object']['Attribute'] as $attribute) {
|
||||
if (isset($attribute['encrypt'])) {
|
||||
$result = $this->Attribute->handleMaliciousBase64($eventId, $attribute['value'], $attribute['data'], array('md5'));
|
||||
$attribute['data'] = $result['data'];
|
||||
$attribute['value'] = $attribute['value'] . '|' . $result['md5'];
|
||||
}
|
||||
$attribute['event_id'] = $eventId;
|
||||
$attribute['object_id'] = $objectId;
|
||||
$this->Attribute->create();
|
||||
$result = $this->Attribute->save(array('Attribute' => $attribute));
|
||||
if (!$result) {
|
||||
$partialFails[] = $attribute['type'];
|
||||
}
|
||||
}
|
||||
if (!empty($partialFails)) return $partialFails;
|
||||
return true;
|
||||
}
|
||||
return 'fail';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,4 +63,46 @@ class ObjectReference extends AppModel {
|
|||
return $this->validationErrors;
|
||||
}
|
||||
}
|
||||
|
||||
public function smartSave($objectReference, $eventId) {
|
||||
$sides = array('source', 'referenced');
|
||||
foreach ($sides as $side) {
|
||||
$data[$side] = $this->Object->find('first', array(
|
||||
'conditions' => array(
|
||||
'Object.uuid' => $objectReference[$side . '_uuid'],
|
||||
'Object.event_id' => $eventId
|
||||
),
|
||||
'recursive' => -1,
|
||||
'fields' => array('Object.id')
|
||||
));
|
||||
if (empty($data[$side]) && $side == 'referenced') {
|
||||
$data[$side] = $this->Attribute->find('first', array(
|
||||
'conditions' => array(
|
||||
'Attribute.uuid' => $objectReference[$side . '_uuid'],
|
||||
'Attribute.event_id' => $eventId
|
||||
),
|
||||
'recursive' => -1,
|
||||
'fields' => array('Attribute.id')
|
||||
));
|
||||
$referenced_id = $data[$side]['Attribute']['id'];
|
||||
$referenced_type = 0;
|
||||
} else if (!empty($data[$side]) && $side == 'referenced') {
|
||||
$referenced_id = $data[$side]['Object']['id'];
|
||||
$referenced_type = 1;
|
||||
} else if (!empty($data[$side]) && $side = 'source') {
|
||||
$object_id = $data[$side]['Object']['id'];
|
||||
} else {
|
||||
return 'Invalid ' . $side . ' uuid';
|
||||
}
|
||||
}
|
||||
$this->create();
|
||||
$objectReference['referenced_type'] = $referenced_type;
|
||||
$objectReference['referenced_id'] = $referenced_id;
|
||||
$objectReference['object_id'] = $object_id;
|
||||
$result = $this->save(array('ObjectReference' => $ojectReference));
|
||||
if (!$result) {
|
||||
return $this->validationErrors;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,9 +61,16 @@
|
|||
'type' => 'checkbox',
|
||||
'checked' => false,
|
||||
'data-content' => isset($attrDescriptions['signature']['formdesc']) ? $attrDescriptions['signature']['formdesc'] : $attrDescriptions['signature']['desc'],
|
||||
'label' => 'IDS (encrypt and hash)',
|
||||
// 'after' => $this->Html->div('forminfo', 'Tick this box to neutralize the sample. Every malware sample will be zipped with the password "infected"', ''),
|
||||
//'after' => '<br>Tick this box to neutralize the sample. Every malware sample will be zipped with the password "infected"',
|
||||
'label' => 'IDS (encrypt and hash)'
|
||||
));
|
||||
?>
|
||||
<div class="input clear"></div>
|
||||
<?php
|
||||
echo $this->Form->input('advanced', array(
|
||||
'type' => 'checkbox',
|
||||
'checked' => false,
|
||||
'data-content' => isset($attrDescriptions['signature']['formdesc']) ? $attrDescriptions['signature']['formdesc'] : $attrDescriptions['signature']['desc'],
|
||||
'label' => 'Advanced extraction (if installed)',
|
||||
));
|
||||
?>
|
||||
</fieldset>
|
||||
|
|
|
@ -53,6 +53,14 @@
|
|||
</div>
|
||||
</td>
|
||||
<td class="short">
|
||||
<?php
|
||||
if (isset($object['object_relation'])):
|
||||
?>
|
||||
<div class="bold"><?php echo h($object['object_relation']); ?>:</div>
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
<div></div>
|
||||
<div id = "Attribute_<?php echo $object['id']; ?>_type_placeholder" class = "inline-field-placeholder"></div>
|
||||
<div id = "Attribute_<?php echo $object['id']; ?>_type_solid" class="inline-field-solid" ondblclick="activateField('Attribute', '<?php echo $object['id']; ?>', 'type', <?php echo $event['Event']['id'];?>);">
|
||||
<?php echo h($object['type']); ?>
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import argparse
|
||||
import json
|
||||
|
||||
try:
|
||||
from pymisp import MISPEncode
|
||||
from pymisp.tools import make_binary_objects
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
def check():
|
||||
missing_dependencies = {'pydeep': False, 'lief': False, 'magic': False, 'pymisp': False}
|
||||
try:
|
||||
import pymisp # noqa
|
||||
except ImportError:
|
||||
missing_dependencies['pymisp'] = 'Please install pydeep: pip install pymisp'
|
||||
try:
|
||||
import pydeep # noqa
|
||||
except ImportError:
|
||||
missing_dependencies['pydeep'] = 'Please install pydeep: pip install git+https://github.com/kbandla/pydeep.git'
|
||||
#try:
|
||||
import lief # noqa
|
||||
#except ImportError:
|
||||
# missing_dependencies['lief'] = 'Please install lief, documentation here: https://github.com/lief-project/LIEF'
|
||||
try:
|
||||
import magic # noqa
|
||||
except ImportError:
|
||||
missing_dependencies['magic'] = 'Please install python-magic: pip install python-magic.'
|
||||
return json.dumps(missing_dependencies)
|
||||
|
||||
|
||||
def make_objects(path):
|
||||
to_return = {'objects': [], 'references': []}
|
||||
fo, peo, seos = make_binary_objects(path)
|
||||
|
||||
if seos:
|
||||
for s in seos:
|
||||
to_return['objects'].append(s)
|
||||
if s.references:
|
||||
to_return['references'] += s.references
|
||||
|
||||
if peo:
|
||||
to_return['objects'].append(peo)
|
||||
if peo.references:
|
||||
to_return['references'] += peo.references
|
||||
|
||||
if fo:
|
||||
to_return['objects'].append(fo)
|
||||
if fo.references:
|
||||
to_return['references'] += fo.references
|
||||
return json.dumps(to_return, cls=MISPEncode)
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description='Extract indicators out of binaries and returns MISP objects.')
|
||||
group = parser.add_mutually_exclusive_group()
|
||||
group.add_argument("-p", "--path", help="Path to process.")
|
||||
group.add_argument("-c", "--check", action='store_true', help="Check the dependencies.")
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.check:
|
||||
print(check())
|
||||
if args.path:
|
||||
obj = make_objects(args.path)
|
||||
print(obj)
|
Loading…
Reference in New Issue