mirror of https://github.com/MISP/MISP
chg: Further work on the objects
- view events with objects via the API - Further improvements to adding objectspull/2489/head
parent
d2e1a8e259
commit
df5daae664
|
@ -71,7 +71,19 @@ class ObjectsController extends AppController {
|
|||
if (empty($error)) {
|
||||
$error = $this->Object->ObjectTemplate->checkTemplateConformity($template, $object);
|
||||
if ($error === true) {
|
||||
$this->Object->saveObject($object, $eventId, $template, $this->Auth->user(), $errorBehaviour = 'halt');
|
||||
$result = $this->Object->saveObject($object, $eventId, $template, $this->Auth->user(), $errorBehaviour = 'halt');
|
||||
}
|
||||
if ($this->_isRest()) {
|
||||
if (is_numeric($result)) {
|
||||
$object = $this->Object->find('first', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array('Object.id' => $result),
|
||||
'contain' => array('Attribute')
|
||||
));
|
||||
return $this->RestResponse->viewData($object, $this->response->type());
|
||||
} else {
|
||||
return $this->RestResponse->saveFailResponse('Attributes', 'add', false, $result, $this->response->type());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ class JSONConverterTool {
|
|||
}
|
||||
|
||||
public function convert($event, $isSiteAdmin=false) {
|
||||
$toRearrange = array('Org', 'Orgc', 'SharingGroup', 'Attribute', 'ShadowAttribute', 'RelatedAttribute', 'RelatedEvent', 'Galaxy');
|
||||
$toRearrange = array('Org', 'Orgc', 'SharingGroup', 'Attribute', 'ShadowAttribute', 'RelatedAttribute', 'RelatedEvent', 'Galaxy', 'Object');
|
||||
foreach ($toRearrange as $object) {
|
||||
if (isset($event[$object])) {
|
||||
$event['Event'][$object] = $event[$object];
|
||||
|
@ -49,29 +49,12 @@ class JSONConverterTool {
|
|||
}
|
||||
|
||||
if (isset($event['Event']['Attribute'])) {
|
||||
// remove value1 and value2 from the output and remove invalid utf8 characters for the xml parser
|
||||
foreach ($event['Event']['Attribute'] as $key => $value) {
|
||||
if (isset($value['SharingGroup']) && empty($value['SharingGroup'])) {
|
||||
unset($event['Event']['Attribute'][$key]['SharingGroup']);
|
||||
}
|
||||
unset($event['Event']['Attribute'][$key]['value1']);
|
||||
unset($event['Event']['Attribute'][$key]['value2']);
|
||||
unset($event['Event']['Attribute'][$key]['category_order']);
|
||||
if (isset($event['RelatedAttribute'][$value['id']])) {
|
||||
$event['Event']['Attribute'][$key]['RelatedAttribute'] = $event['Event']['RelatedAttribute'][$value['id']];
|
||||
foreach ($event['Event']['Attribute'][$key]['RelatedAttribute'] as &$ra) {
|
||||
$ra = array('Attribute' => $ra);
|
||||
}
|
||||
}
|
||||
if (isset($event['Event']['Attribute'][$key]['AttributeTag'])) {
|
||||
foreach ($event['Event']['Attribute'][$key]['AttributeTag'] as $atk => $tag) {
|
||||
unset($tag['Tag']['org_id']);
|
||||
$event['Event']['Attribute'][$key]['Tag'][$atk] = $tag['Tag'];
|
||||
}
|
||||
unset($event['Event']['Attribute'][$key]['AttributeTag']);
|
||||
}
|
||||
}
|
||||
$event['Event']['Attribute'] = $this->__cleanAttributes($event['Event']['Attribute']);
|
||||
}
|
||||
if (isset($event['Event']['Object'])) {
|
||||
$event['Event']['Object'] = $this->__cleanObjects($event['Event']['Object']);
|
||||
}
|
||||
|
||||
unset($event['Event']['RelatedAttribute']);
|
||||
if (isset($event['Event']['RelatedEvent'])) {
|
||||
foreach ($event['Event']['RelatedEvent'] as $key => $value) {
|
||||
|
@ -87,6 +70,44 @@ class JSONConverterTool {
|
|||
return json_encode($result, JSON_PRETTY_PRINT);
|
||||
}
|
||||
|
||||
private function __cleanAttributes($attributes) {
|
||||
// remove value1 and value2 from the output and remove invalid utf8 characters for the xml parser
|
||||
foreach ($attributes as $key => $value) {
|
||||
if (isset($value['SharingGroup']) && empty($value['SharingGroup'])) {
|
||||
unset($attributes[$key]['SharingGroup']);
|
||||
}
|
||||
unset($attributes[$key]['value1']);
|
||||
unset($attributes[$key]['value2']);
|
||||
unset($attributes[$key]['category_order']);
|
||||
if (isset($event['RelatedAttribute'][$value['id']])) {
|
||||
$attributes[$key]['RelatedAttribute'] = $event['Event']['RelatedAttribute'][$value['id']];
|
||||
foreach ($attributes[$key]['RelatedAttribute'] as &$ra) {
|
||||
$ra = array('Attribute' => $ra);
|
||||
}
|
||||
}
|
||||
if (isset($attributes[$key]['AttributeTag'])) {
|
||||
foreach ($attributes[$key]['AttributeTag'] as $atk => $tag) {
|
||||
unset($tag['Tag']['org_id']);
|
||||
$attributes[$key]['Tag'][$atk] = $tag['Tag'];
|
||||
}
|
||||
unset($attributes[$key]['AttributeTag']);
|
||||
}
|
||||
}
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
private function __cleanObjects($objects) {
|
||||
foreach ($objects as $k => $object) {
|
||||
if (!empty($object['Attribute'])) {
|
||||
$objects[$k]['Attribute'] = $this->__cleanAttributes($object['Attribute']);
|
||||
} else {
|
||||
unset($objects[$k]);
|
||||
}
|
||||
}
|
||||
$objects = array_values($objects);
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function arrayPrinter($array, $root = true) {
|
||||
if (is_array($array)) {
|
||||
$resultArray = array();
|
||||
|
|
|
@ -2364,6 +2364,20 @@ class Attribute extends AppModel {
|
|||
else return 'Could not save changes.';
|
||||
}
|
||||
|
||||
public function saveAttributes($attributes) {
|
||||
foreach ($attributes as $k => $attribute) {
|
||||
if (!empty($attribute['encrypt']) && $attribute['encrypt']) {
|
||||
$result = $this->handleMaliciousBase64($attribute['event_id'], $attribute['value'], $attribute['data'], array('md5'));
|
||||
$attribute['data'] = $result['data'];
|
||||
$attribute['value'] = $attribute['value'] . '|' . $result['md5'];
|
||||
}
|
||||
unset($attribute['Attachment']);
|
||||
$this->create();
|
||||
$this->save($attribute);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function saveAndEncryptAttribute($attribute, $user) {
|
||||
$hashes = array('md5' => 'malware-sample', 'sha1' => 'filename|sha1', 'sha256' => 'filename|sha256');
|
||||
if ($attribute['encrypt']) {
|
||||
|
|
|
@ -311,6 +311,19 @@ class Event extends AppModel {
|
|||
'finderQuery' => '',
|
||||
'counterQuery' => ''
|
||||
),
|
||||
'Object' => array(
|
||||
'className' => 'Object',
|
||||
'foreignKey' => 'event_id',
|
||||
'dependent' => true,
|
||||
'conditions' => '',
|
||||
'fields' => '',
|
||||
'order' => false,
|
||||
'limit' => '',
|
||||
'offset' => '',
|
||||
'exclusive' => '',
|
||||
'finderQuery' => '',
|
||||
'counterQuery' => ''
|
||||
),
|
||||
'EventTag' => array(
|
||||
'className' => 'EventTag',
|
||||
'dependent' => true,
|
||||
|
@ -1247,6 +1260,13 @@ class Event extends AppModel {
|
|||
$isSiteAdmin = $user['Role']['perm_site_admin'];
|
||||
if (isset($options['disableSiteAdmin']) && $options['disableSiteAdmin']) $isSiteAdmin = false;
|
||||
$conditionsAttributes = array();
|
||||
$conditionsObjects = array();
|
||||
|
||||
if (isset($options['flattenObjects']) && $options['flattenObjects']) {
|
||||
$flattenObjects = true;
|
||||
} else {
|
||||
$flattenObjects = false;
|
||||
}
|
||||
|
||||
// restricting to non-private or same org if the user is not a site-admin.
|
||||
if (!$isSiteAdmin) {
|
||||
|
@ -1290,14 +1310,28 @@ class Event extends AppModel {
|
|||
)),
|
||||
'(SELECT events.org_id FROM events WHERE events.id = Attribute.event_id)' => $user['org_id']
|
||||
);
|
||||
|
||||
$conditionsObjects['AND'][0]['OR'] = array(
|
||||
array('AND' => array(
|
||||
'Object.distribution >' => 0,
|
||||
'Object.distribution !=' => 4,
|
||||
)),
|
||||
array('AND' => array(
|
||||
'Object.distribution' => 4,
|
||||
'Object.sharing_group_id' => $sgids,
|
||||
)),
|
||||
'(SELECT events.org_id FROM events WHERE events.id = Object.event_id)' => $user['org_id']
|
||||
);
|
||||
}
|
||||
if ($options['distribution']) {
|
||||
$conditions['AND'][] = array('Event.distribution' => $options['distribution']);
|
||||
$conditionsAttributes['AND'][] = array('Attribute.distribution' => $options['distribution']);
|
||||
$conditionsObjects['AND'][] = array('Object.distribution' => $options['distribution']);
|
||||
}
|
||||
if ($options['sharing_group_id']) {
|
||||
$conditions['AND'][] = array('Event.sharing_group_id' => $options['sharing_group_id']);
|
||||
$conditionsAttributes['AND'][] = array('Attribute.sharing_group_id' => $options['sharing_group_id']);
|
||||
$conditionsObject['AND'][] = array('Object.sharing_group_id' => $options['sharing_group_id']);
|
||||
}
|
||||
if ($options['from']) $conditions['AND'][] = array('Event.date >=' => $options['from']);
|
||||
if ($options['to']) $conditions['AND'][] = array('Event.date <=' => $options['to']);
|
||||
|
@ -1311,8 +1345,17 @@ class Event extends AppModel {
|
|||
'Attribute.deleted' => 0
|
||||
)
|
||||
);
|
||||
$conditionsObjects['AND'][] = array(
|
||||
'OR' => array(
|
||||
'(SELECT events.org_id FROM events WHERE events.id = Object.event_id)' => $user['org_id'],
|
||||
'Object.deleted' => 0
|
||||
)
|
||||
);
|
||||
}
|
||||
} else $conditionsAttributes['AND']['Attribute.deleted'] = 0;
|
||||
} else {
|
||||
$conditionsAttributes['AND']['Attribute.deleted'] = 0;
|
||||
$conditionsObject['AND']['Object.deleted'] = 0;
|
||||
}
|
||||
|
||||
if ($options['idList'] && !$options['tags']) {
|
||||
$conditions['AND'][] = array('Event.id' => $options['idList']);
|
||||
|
@ -1346,7 +1389,8 @@ class Event extends AppModel {
|
|||
|
||||
// do not expose all the data ...
|
||||
$fields = array('Event.id', 'Event.orgc_id', 'Event.org_id', 'Event.date', 'Event.threat_level_id', 'Event.info', 'Event.published', 'Event.uuid', 'Event.attribute_count', 'Event.analysis', 'Event.timestamp', 'Event.distribution', 'Event.proposal_email_lock', 'Event.user_id', 'Event.locked', 'Event.publish_timestamp', 'Event.sharing_group_id', 'Event.disable_correlation');
|
||||
$fieldsAtt = array('Attribute.id', 'Attribute.type', 'Attribute.category', 'Attribute.value', 'Attribute.to_ids', 'Attribute.uuid', 'Attribute.event_id', 'Attribute.distribution', 'Attribute.timestamp', 'Attribute.comment', 'Attribute.sharing_group_id', 'Attribute.deleted', 'Attribute.disable_correlation');
|
||||
$fieldsAtt = array('Attribute.id', 'Attribute.type', 'Attribute.category', 'Attribute.value', 'Attribute.to_ids', 'Attribute.uuid', 'Attribute.event_id', 'Attribute.distribution', 'Attribute.timestamp', 'Attribute.comment', 'Attribute.sharing_group_id', 'Attribute.deleted', 'Attribute.disable_correlation', 'Attribute.object_id', 'Attribute.object_relation');
|
||||
$fieldsObj = array('*');
|
||||
$fieldsShadowAtt = array('ShadowAttribute.id', 'ShadowAttribute.type', 'ShadowAttribute.category', 'ShadowAttribute.value', 'ShadowAttribute.to_ids', 'ShadowAttribute.uuid', 'ShadowAttribute.event_uuid', 'ShadowAttribute.event_id', 'ShadowAttribute.old_id', 'ShadowAttribute.comment', 'ShadowAttribute.org_id', 'ShadowAttribute.proposal_to_delete', 'ShadowAttribute.timestamp');
|
||||
$fieldsOrg = array('id', 'name', 'uuid');
|
||||
$fieldsServer = array('id', 'url', 'name');
|
||||
|
@ -1373,7 +1417,6 @@ class Event extends AppModel {
|
|||
foreach ($sharingGroupDataTemp as $k => $v) {
|
||||
$sharingGroupData[$v['SharingGroup']['id']] = $v;
|
||||
}
|
||||
|
||||
$params = array(
|
||||
'conditions' => $conditions,
|
||||
'recursive' => 0,
|
||||
|
@ -1393,6 +1436,11 @@ class Event extends AppModel {
|
|||
'order' => false
|
||||
),
|
||||
),
|
||||
'Object' => array(
|
||||
'fields' => $fieldsObj,
|
||||
'conditions' => $conditionsObjects,
|
||||
'order' => false
|
||||
),
|
||||
'ShadowAttribute' => array(
|
||||
'fields' => $fieldsShadowAtt,
|
||||
'conditions' => array('deleted' => 0),
|
||||
|
@ -1405,6 +1453,9 @@ class Event extends AppModel {
|
|||
)
|
||||
)
|
||||
);
|
||||
if ($flattenObjects) {
|
||||
unset($params['contain']['Object']);
|
||||
}
|
||||
if ($options['metadata']) {
|
||||
unset($params['contain']['Attribute']);
|
||||
unset($params['contain']['ShadowAttribute']);
|
||||
|
@ -1547,6 +1598,16 @@ class Event extends AppModel {
|
|||
}
|
||||
|
||||
}
|
||||
if ($event['Attribute'][$key]['object_id'] != 0) {
|
||||
if (!empty($event['Object'])) {
|
||||
foreach ($event['Object'] as $objectKey => $objectValue) {
|
||||
if ($event['Attribute'][$key]['object_id'] == $objectValue['id']) {
|
||||
$event['Object'][$objectKey]['Attribute'][] = $event['Attribute'][$key];
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($event['Attribute'][$key]);
|
||||
}
|
||||
}
|
||||
$event['Attribute'] = array_values($event['Attribute']);
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ class Object extends AppModel {
|
|||
'conditions' => array('Object.template_uuid' => 'ObjectTemplate.uuid')
|
||||
)
|
||||
);
|
||||
|
||||
public $hasMany = array(
|
||||
'Attribute' => array(
|
||||
'className' => 'Attribute',
|
||||
|
@ -42,9 +43,28 @@ class Object extends AppModel {
|
|||
public $validate = array(
|
||||
);
|
||||
|
||||
public function beforeValidate($options = array()) {
|
||||
parent::beforeValidate();
|
||||
|
||||
if (empty($this->data['Object']['comment'])) {
|
||||
$this->data['Object']['comment'] = "";
|
||||
}
|
||||
// generate UUID if it doesn't exist
|
||||
if (empty($this->data['Object']['uuid'])) {
|
||||
$this->data['Object']['uuid'] = CakeText::uuid();
|
||||
}
|
||||
// generate timestamp if it doesn't exist
|
||||
if (empty($this->data['Object']['timestamp'])) {
|
||||
$date = new DateTime();
|
||||
$this->data['Object']['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;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function saveObject($object, $eventId, $template, $user, $errorBehaviour = 'drop') {
|
||||
$this->create();
|
||||
//id name meta-category description template_uuid template_version event_id uuid timestamp distribution sharing_group_id comment
|
||||
$templateFields = array(
|
||||
'name' => 'name',
|
||||
'meta-category' => 'meta-category',
|
||||
|
@ -56,11 +76,17 @@ class Object extends AppModel {
|
|||
$object['Object'][$k] = $template['ObjectTemplate'][$v];
|
||||
}
|
||||
$object['Object']['event_id'] = $eventId;
|
||||
debug($template);
|
||||
debug($object);
|
||||
throw new Exception();
|
||||
$this->save($object);
|
||||
return $this->Attribute->saveAttributes($attributes, $eventId, $objectId = 0, $errorBehaviour);
|
||||
$result = false;
|
||||
if ($this->save($object)) {
|
||||
$id = $this->id;
|
||||
foreach ($object['Attribute'] as $k => $attribute) {
|
||||
$object['Attribute'][$k]['object_id'] = $id;
|
||||
}
|
||||
$result = $this->Attribute->saveAttributes($object['Attribute']);
|
||||
} else {
|
||||
$result = $this->validationErrors;
|
||||
}
|
||||
return $id;
|
||||
}
|
||||
|
||||
public function buildEventConditions($user, $sgids = false) {
|
||||
|
@ -262,11 +288,31 @@ class Object extends AppModel {
|
|||
if ($attribute['value_select'] !== 'Enter value manually') {
|
||||
$attributes['Attribute'][$k]['value'] = $attribute['value_select'];
|
||||
}
|
||||
unset($attribute['value_select']);
|
||||
unset($attributes['Attribute'][$k]['value_select']);
|
||||
}
|
||||
unset($attribute['save']);
|
||||
if (isset($attribute['Attachment'])) {
|
||||
// Check if there were problems with the file upload
|
||||
// only keep the last part of the filename, this should prevent directory attacks
|
||||
$filename = basename($attribute['Attachment']['name']);
|
||||
$tmpfile = new File($attribute['Attachment']['tmp_name']);
|
||||
if ((isset($attribute['Attachment']['error']) && $attribute['Attachment']['error'] == 0) ||
|
||||
(!empty($attribute['Attachment']['tmp_name']) && $attribute['Attachment']['tmp_name'] != 'none')
|
||||
) {
|
||||
if (!is_uploaded_file($tmpfile->path))
|
||||
throw new InternalErrorException('PHP says file was not uploaded. Are you attacking me?');
|
||||
} else {
|
||||
return 'Issues with the file attachment for the ' . $attribute['object_relation'] . ' attribute. The error code returned is ' . $attribute['Attachment']['error'];
|
||||
}
|
||||
$attributes['Attribute'][$k]['value'] = $attribute['Attachment']['name'];
|
||||
unset($attributes['Attribute'][$k]['Attachment']);
|
||||
$attributes['Attribute'][$k]['encrypt'] = $attribute['type'] == 'malware-sample' ? 1 : 0;
|
||||
$attributes['Attribute'][$k]['data'] = base64_encode($tmpfile->read());
|
||||
$tmpfile->delete();
|
||||
$tmpfile->close();
|
||||
}
|
||||
unset($attributes['Attribute'][$k]['save']);
|
||||
if ($attribute['distribution'] != 4) {
|
||||
$attribute['sharing_group_id'] = 0;
|
||||
$attributes['Attribute'][$k]['sharing_group_id'] = 0;
|
||||
}
|
||||
}
|
||||
return $attributes;
|
||||
|
|
Loading…
Reference in New Issue