mirror of https://github.com/MISP/MISP
Merge branch '2.4' of github.com:MISP/MISP into chrisr3d_restSearch_tests
commit
09a138fd38
|
@ -16,6 +16,17 @@ class AttributesController extends AppController
|
|||
|
||||
public $helpers = array('Js' => array('Jquery'));
|
||||
|
||||
public $validFormats = array(
|
||||
'openioc' => array('xml', 'OpeniocExport'),
|
||||
'json' => array('json', 'JsonExport'),
|
||||
'xml' => array('xml', 'XmlExport'),
|
||||
'suricata' => array('txt', 'NidsSuricataExport'),
|
||||
'snort' => array('txt', 'NidsSnortExport'),
|
||||
'text' => array('txt', 'TextExport'),
|
||||
'rpz' => array('rpz', 'RPZExport'),
|
||||
'csv' => array('csv', 'CsvExport')
|
||||
);
|
||||
|
||||
public function beforeFilter()
|
||||
{
|
||||
parent::beforeFilter();
|
||||
|
@ -118,7 +129,7 @@ class AttributesController extends AppController
|
|||
foreach ($attribute['AttributeTag'] as $kat => $at) {
|
||||
foreach ($tags as $ktag => $tag) {
|
||||
if ($tag['Tag']['id'] == $at['tag_id']) {
|
||||
$attributes[$k]['AttributeTag'][$kat]['Tag'] = $tag['Tag'];
|
||||
$attributes[$k]['AttributeTag'][$kat]['Tag'] = $tag['Tag'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1565,453 +1576,85 @@ class AttributesController extends AppController
|
|||
}
|
||||
}
|
||||
|
||||
public function search()
|
||||
public function search($continue = false)
|
||||
{
|
||||
$this->set('attrDescriptions', $this->Attribute->fieldDescriptions);
|
||||
$this->set('typeDefinitions', $this->Attribute->typeDefinitions);
|
||||
$this->set('categoryDefinitions', $this->Attribute->categoryDefinitions);
|
||||
|
||||
$fullAddress = '/attributes/search';
|
||||
// if no search is given, show the search form
|
||||
if ($this->request->here == $fullAddress && !$this->request->is('post')) {
|
||||
// adding filtering by category and type
|
||||
// combobox for types
|
||||
$types = array('' => array('ALL' => 'ALL'), 'types' => array());
|
||||
$types['types'] = array_merge($types['types'], $this->_arrayToValuesIndexArray(array_keys($this->Attribute->typeDefinitions)));
|
||||
ksort($types['types']);
|
||||
$this->set('types', $types);
|
||||
// combobox for categories
|
||||
$categories['categories'] = array_merge(array('ALL' => 'ALL'), $this->_arrayToValuesIndexArray(array_keys($this->Attribute->categoryDefinitions)));
|
||||
$this->set('categories', $categories);
|
||||
} else {
|
||||
$this->set('isSearch', 1);
|
||||
|
||||
$attributeTagQuery = '/attributetag';
|
||||
// check if the request is a GET request for attributes with a specific tag (usually after clicking on an attributetag)
|
||||
if (substr($this->request->here, strlen($fullAddress), strlen($attributeTagQuery)) == $attributeTagQuery) {
|
||||
$attributeTagId = substr($this->request->here, (strlen($fullAddress) + strlen($attributeTagQuery) + 1));
|
||||
if (!is_numeric($attributeTagId)) {
|
||||
// either pagination active or no correct id
|
||||
unset($attributeTagId);
|
||||
}
|
||||
}
|
||||
|
||||
// if this is no new search, get parameters from session
|
||||
if ($this->request->here != $fullAddress && !isset($attributeTagId)) {
|
||||
$keyword = $this->Session->read('paginate_conditions_keyword');
|
||||
$keyword2 = $this->Session->read('paginate_conditions_keyword2');
|
||||
$attributeTags = $this->Session->read('paginate_conditions_attributetags');
|
||||
$org = $this->Session->read('paginate_conditions_org');
|
||||
$type = $this->Session->read('paginate_conditions_type');
|
||||
$category = $this->Session->read('paginate_conditions_category');
|
||||
$tags = $this->Session->read('paginate_conditions_tags');
|
||||
$this->set('keywordSearch', $keyword);
|
||||
$this->set('keywordSearch2', $keyword2);
|
||||
$this->set('attributeTags', $attributeTags);
|
||||
$this->set('orgSearch', $org);
|
||||
$this->set('typeSearch', $type);
|
||||
$this->set('tags', $tags);
|
||||
$this->set('categorySearch', $category);
|
||||
$this->Attribute->contain(array('AttributeTag' => array('Tag')));
|
||||
|
||||
// re-get pagination
|
||||
$this->Attribute->recursive = 0;
|
||||
$this->paginate = $this->Session->read('paginate_conditions');
|
||||
$attributes = $this->paginate();
|
||||
foreach ($attributes as $k => $attribute) {
|
||||
if (empty($attribute['Event']['id'])) {
|
||||
unset($attribute[$k]);
|
||||
}
|
||||
}
|
||||
$this->set('attributes', $attributes);
|
||||
|
||||
// set the same view as the index page
|
||||
$this->render('index');
|
||||
} else {
|
||||
// reset the paginate_conditions
|
||||
$this->Session->write('paginate_conditions', array());
|
||||
$conditions = array();
|
||||
$alternateSearch = false;
|
||||
|
||||
if (isset($attributeTagId)) {
|
||||
$this->loadModel('Tag');
|
||||
$this->Tag->id = $attributeTagId;
|
||||
if (!$this->Tag->exists()) {
|
||||
throw new NotFoundException(__('Invalid tag'));
|
||||
}
|
||||
|
||||
$attributeTags = $this->Tag->find('first', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array(
|
||||
'id' => $attributeTagId
|
||||
)
|
||||
));
|
||||
$attributeTags = $attributeTags['Tag']['name'];
|
||||
$conditions['AND'][] = array('OR' => array('Attribute.id' => $this->Tag->findAttributeIdsByAttributeTagNames(array($attributeTags))));
|
||||
|
||||
$keyword = null;
|
||||
$keyword2 = null;
|
||||
$org = null;
|
||||
$type = 'ALL';
|
||||
$tags = null;
|
||||
$category = 'ALL';
|
||||
$ioc = false;
|
||||
|
||||
$this->set('keywordSearch', $keyword);
|
||||
$this->set('keywordSearch2', $keyword2);
|
||||
}
|
||||
|
||||
if ($this->request->is('post')) {
|
||||
$keyword = $this->request->data['Attribute']['keyword'];
|
||||
$keyword2 = $this->request->data['Attribute']['keyword2'];
|
||||
$attributeTags = $this->request->data['Attribute']['attributetags'];
|
||||
$tags = $this->request->data['Attribute']['tags'];
|
||||
$org = $this->request->data['Attribute']['org'];
|
||||
$type = $this->request->data['Attribute']['type'];
|
||||
$ioc = $this->request->data['Attribute']['ioc'];
|
||||
$this->set('ioc', $ioc);
|
||||
$category = $this->request->data['Attribute']['category'];
|
||||
|
||||
$keyWordText = null;
|
||||
$keyWordText2 = null;
|
||||
$keyWordText3 = null;
|
||||
|
||||
// search the db
|
||||
if ($ioc) {
|
||||
$conditions['AND'][] = array('Attribute.to_ids =' => 1);
|
||||
$conditions['AND'][] = array('Event.published =' => 1);
|
||||
}
|
||||
// search on the value field
|
||||
if (isset($keyword)) {
|
||||
$keywordArray = explode("\n", $keyword);
|
||||
$this->set('keywordArray', $keywordArray);
|
||||
$i = 1;
|
||||
$temp = array();
|
||||
$temp2 = array();
|
||||
foreach ($keywordArray as $keywordArrayElement) {
|
||||
$saveWord = trim(strtolower($keywordArrayElement));
|
||||
if ($saveWord != '') {
|
||||
$toInclude = true;
|
||||
if ($saveWord[0] == '!') {
|
||||
$toInclude = false;
|
||||
$saveWord = substr($saveWord, 1);
|
||||
}
|
||||
|
||||
// check for an IPv4 address and subnet in CIDR notation (e.g. 127.0.0.1/8)
|
||||
if ($this->Cidr->checkCIDR($saveWord, 4)) {
|
||||
$cidrresults = $this->Cidr->CIDR($saveWord);
|
||||
foreach ($cidrresults as $result) {
|
||||
$result = strtolower($result);
|
||||
if (strpos($result, '|')) {
|
||||
$resultParts = explode('|', $result);
|
||||
if (!$toInclude) {
|
||||
$temp2[] = array(
|
||||
'AND' => array(
|
||||
'LOWER(Attribute.value1) NOT LIKE' => $resultParts[0],
|
||||
'LOWER(Attribute.value2) NOT LIKE' => $resultParts[1],
|
||||
));
|
||||
} else {
|
||||
$temp[] = array(
|
||||
'AND' => array(
|
||||
'LOWER(Attribute.value1)' => $resultParts[0],
|
||||
'LOWER(Attribute.value2)' => $resultParts[1],
|
||||
));
|
||||
}
|
||||
} else {
|
||||
if (!$toInclude) {
|
||||
array_push($temp2, array('LOWER(Attribute.value1) NOT LIKE' => $result));
|
||||
array_push($temp2, array('LOWER(Attribute.value2) NOT LIKE' => $result));
|
||||
} else {
|
||||
array_push($temp, array('LOWER(Attribute.value1) LIKE' => $result));
|
||||
array_push($temp, array('LOWER(Attribute.value2) LIKE' => $result));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (strpos($saveWord, '|')) {
|
||||
$resultParts = explode('|', $saveWord);
|
||||
if (!$toInclude) {
|
||||
$temp2[] = array(
|
||||
'AND' => array(
|
||||
'LOWER(Attribute.value1) NOT LIKE' => $resultParts[0],
|
||||
'LOWER(Attribute.value2) NOT LIKE' => $resultParts[1],
|
||||
));
|
||||
} else {
|
||||
$temp2[] = array(
|
||||
'AND' => array(
|
||||
'LOWER(Attribute.value1)' => $resultParts[0],
|
||||
'LOWER(Attribute.value2)' => $resultParts[1],
|
||||
));
|
||||
}
|
||||
} else {
|
||||
if (!$toInclude) {
|
||||
array_push($temp2, array('LOWER(Attribute.value1) NOT LIKE' => $saveWord));
|
||||
array_push($temp2, array('LOWER(Attribute.value2) NOT LIKE' => $saveWord));
|
||||
} else {
|
||||
array_push($temp, array('LOWER(Attribute.value1) LIKE' => $saveWord));
|
||||
array_push($temp, array('LOWER(Attribute.value2) LIKE' => $saveWord));
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($toInclude) {
|
||||
array_push($temp, array('LOWER(Attribute.comment) LIKE' => $saveWord));
|
||||
} else {
|
||||
array_push($temp2, array('LOWER(Attribute.comment) NOT LIKE' => $saveWord));
|
||||
}
|
||||
}
|
||||
if ($i == 1 && $saveWord != '') {
|
||||
$keyWordText = $saveWord;
|
||||
} elseif (($i > 1 && $i < 10) && $saveWord != '') {
|
||||
$keyWordText = $keyWordText . ', ' . $saveWord;
|
||||
} elseif ($i == 10 && $saveWord != '') {
|
||||
$keyWordText = $keyWordText . ' and several other keywords';
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
$this->set('keywordSearch', $keyWordText);
|
||||
if (!empty($temp)) {
|
||||
$conditions['AND']['OR'] = $temp;
|
||||
}
|
||||
if (!empty($temp2)) {
|
||||
$conditions['AND'][] = $temp2;
|
||||
}
|
||||
}
|
||||
|
||||
// event IDs to be excluded
|
||||
if (isset($keyword2)) {
|
||||
$keywordArray2 = explode("\n", $keyword2);
|
||||
$i = 1;
|
||||
$temp = array();
|
||||
foreach ($keywordArray2 as $keywordArrayElement) {
|
||||
$saveWord = trim($keywordArrayElement);
|
||||
if (empty($saveWord)) {
|
||||
continue;
|
||||
}
|
||||
if ($saveWord[0] == '!') {
|
||||
if (strlen(substr($saveWord, 1)) == 36) {
|
||||
$temp[] = array('Event.uuid !=' => substr($saveWord, 1));
|
||||
$temp[] = array('Attribute.uuid !=' => substr($saveWord, 1));
|
||||
} else {
|
||||
$temp[] = array('Attribute.event_id !=' => substr($saveWord, 1));
|
||||
}
|
||||
} else {
|
||||
if (strlen($saveWord) == 36) {
|
||||
$temp['OR'][] = array('Event.uuid =' => $saveWord);
|
||||
$temp['OR'][] = array('Attribute.uuid' => $saveWord);
|
||||
} else {
|
||||
$temp['OR'][] = array('Attribute.event_id =' => $saveWord);
|
||||
}
|
||||
}
|
||||
if ($i == 1 && $saveWord != '') {
|
||||
$keyWordText2 = $saveWord;
|
||||
} elseif (($i > 1 && $i < 10) && $saveWord != '') {
|
||||
$keyWordText2 = $keyWordText2 . ', ' . $saveWord;
|
||||
} elseif ($i == 10 && $saveWord != '') {
|
||||
$keyWordText2 = $keyWordText2 . ' and several other events';
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
$this->set('keywordSearch2', $keyWordText2);
|
||||
if (!empty($temp)) {
|
||||
$conditions['AND'][] = $temp;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($attributeTags) || !empty($tags)) {
|
||||
$this->loadModel('Tag');
|
||||
}
|
||||
|
||||
if (!empty($attributeTags)) {
|
||||
$includeAttributeTags = array();
|
||||
$excludeAttributeTags = array();
|
||||
$attributeTagsKeywordArray = explode("\n", $attributeTags);
|
||||
foreach ($attributeTagsKeywordArray as $tagName) {
|
||||
$tagName = trim($tagName);
|
||||
if (empty($tagName)) {
|
||||
continue;
|
||||
}
|
||||
if (substr($tagName, 0, 1) === '!') {
|
||||
$excludeAttributeTags[] = substr($tagName, 1);
|
||||
} else {
|
||||
$includeAttributeTags[] = $tagName;
|
||||
}
|
||||
}
|
||||
if (!empty($includeAttributeTags)) {
|
||||
$conditions['AND'][] = array('OR' => array('Attribute.id' => $this->Tag->findAttributeIdsByAttributeTagNames($includeAttributeTags)));
|
||||
}
|
||||
if (!empty($excludeAttributeTags)) {
|
||||
$conditions['AND'][] = array('Attribute.id !=' => $this->Tag->findAttributeIdsByAttributeTagNames($excludeAttributeTags));
|
||||
}
|
||||
}
|
||||
if (!empty($tags)) {
|
||||
$include = array();
|
||||
$exclude = array();
|
||||
$keywordArray = explode("\n", $tags);
|
||||
foreach ($keywordArray as $tagname) {
|
||||
$tagname = trim($tagname);
|
||||
if (empty($tagname)) {
|
||||
continue;
|
||||
}
|
||||
if (substr($tagname, 0, 1) === '!') {
|
||||
$exclude[] = substr($tagname, 1);
|
||||
} else {
|
||||
$include[] = $tagname;
|
||||
}
|
||||
}
|
||||
if (!empty($include)) {
|
||||
$conditions['AND'][] = array('OR' => array('Attribute.event_id' => $this->Tag->findEventIdsByTagNames($include)));
|
||||
}
|
||||
if (!empty($exclude)) {
|
||||
$conditions['AND'][] = array('Attribute.event_id !=' => $this->Tag->findEventIdsByTagNames($exclude));
|
||||
}
|
||||
}
|
||||
if ($type != 'ALL') {
|
||||
$conditions['Attribute.type ='] = $type;
|
||||
}
|
||||
if ($category != 'ALL') {
|
||||
$conditions['Attribute.category ='] = $category;
|
||||
}
|
||||
// organisation search field
|
||||
if (isset($org)) {
|
||||
$temp = array();
|
||||
$this->loadModel('Organisation');
|
||||
$orgArray = explode("\n", $org);
|
||||
foreach ($orgArray as $i => $orgArrayElement) {
|
||||
$saveWord = trim($orgArrayElement);
|
||||
if (empty($saveWord)) {
|
||||
continue;
|
||||
}
|
||||
if ($saveWord[0] == '!') {
|
||||
$org_names = $this->Organisation->find('all', array(
|
||||
'fields' => array('id', 'name'),
|
||||
'conditions' => array('lower(name) LIKE' => strtolower(substr($saveWord, 1))),
|
||||
));
|
||||
foreach ($org_names as $org_name) {
|
||||
$temp['AND'][] = array('Event.orgc_id !=' => $org_name['Organisation']['id']);
|
||||
}
|
||||
} else {
|
||||
$org_names = $this->Organisation->find('all', array(
|
||||
'fields' => array('id', 'name'),
|
||||
'conditions' => array('lower(name) LIKE' => strtolower($saveWord)),
|
||||
));
|
||||
if (empty($org_names)) {
|
||||
$conditions['AND'][] = array('Event.orgc_id' => -1);
|
||||
}
|
||||
foreach ($org_names as $org_name) {
|
||||
$temp['OR'][] = array('Event.orgc_id' => $org_name['Organisation']['id']);
|
||||
}
|
||||
}
|
||||
if ($i == 0 && $saveWord != '') {
|
||||
$keyWordText3 = $saveWord;
|
||||
} elseif (($i > 0 && $i < 9) && $saveWord != '') {
|
||||
$keyWordText3 = $keyWordText3 . ', ' . $saveWord;
|
||||
} elseif ($i == 9 && $saveWord != '') {
|
||||
$keyWordText3 = $keyWordText3 . ' and several other organisations';
|
||||
}
|
||||
}
|
||||
$this->set('orgSearch', $keyWordText3);
|
||||
if (!empty($temp)) {
|
||||
$conditions['AND'][] = $temp;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->request->data['Attribute']['alternate']) {
|
||||
$alternateSearch = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($attributeTags)) {
|
||||
$this->set('attributeTags', $attributeTags);
|
||||
}
|
||||
$this->set('tags', $tags);
|
||||
$this->set('typeSearch', $type);
|
||||
$this->set('categorySearch', $category);
|
||||
|
||||
$conditions['AND'][] = array('Attribute.deleted' => 0);
|
||||
if ($alternateSearch) {
|
||||
$events = $this->searchAlternate($conditions);
|
||||
$this->set('events', $events);
|
||||
$this->render('alternate_search_result');
|
||||
} else {
|
||||
$this->Attribute->recursive = 0;
|
||||
$this->paginate = array(
|
||||
'limit' => 60,
|
||||
'maxLimit' => 9999, // LATER we will bump here on a problem once we have more than 9999 attributes?
|
||||
'conditions' => $conditions,
|
||||
'contain' => array(
|
||||
'Event' => array(
|
||||
'fields' => array(
|
||||
'orgc_id', 'id', 'org_id', 'user_id', 'info'
|
||||
),
|
||||
'Orgc' => array('fields' => array('Orgc.name', 'Orgc.id'))
|
||||
),
|
||||
'Object' => array(
|
||||
'fields' => array(
|
||||
'id'
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
$this->Attribute->contain(array('AttributeTag' => array('Tag')));
|
||||
if (!$this->_isSiteAdmin()) {
|
||||
// merge in private conditions
|
||||
$this->paginate['conditions'] = array('AND' => array($conditions, $this->Attribute->buildConditions($this->Auth->user())));
|
||||
}
|
||||
$idList = array();
|
||||
$attributeIdList = array();
|
||||
$attributes = $this->paginate();
|
||||
$org_ids = array();
|
||||
foreach ($attributes as $k => $attribute) {
|
||||
if (empty($attribute['Event']['id'])) {
|
||||
unset($attribute[$k]);
|
||||
continue;
|
||||
}
|
||||
if ($attribute['Attribute']['type'] == 'attachment' && preg_match('/.*\.(jpg|png|jpeg|gif)$/i', $attribute['Attribute']['value'])) {
|
||||
$attributes[$k]['Attribute']['image'] = $this->Attribute->base64EncodeAttachment($attribute['Attribute']);
|
||||
}
|
||||
$org_ids[$attribute['Event']['org_id']] = false;
|
||||
$org_ids[$attribute['Event']['orgc_id']] = false;
|
||||
}
|
||||
$orgs = $this->Attribute->Event->Orgc->find('list', array(
|
||||
'conditions' => array('Orgc.id' => array_keys($org_ids)),
|
||||
'fields' => array('Orgc.id', 'Orgc.name')
|
||||
));
|
||||
$this->set('orgs', $orgs);
|
||||
$this->set('attributes', $attributes);
|
||||
|
||||
// if we searched for IOCs only, apply the whitelist to the search result!
|
||||
if ($ioc) {
|
||||
$this->loadModel('Whitelist');
|
||||
$attributes = $this->Whitelist->removeWhitelistedFromArray($attributes, true);
|
||||
}
|
||||
|
||||
foreach ($attributes as $attribute) {
|
||||
$attributeIdList[] = $attribute['Attribute']['id'];
|
||||
if (!in_array($attribute['Attribute']['event_id'], $idList)) {
|
||||
$idList[] = $attribute['Attribute']['event_id'];
|
||||
}
|
||||
}
|
||||
$this->set('attributes', $attributes);
|
||||
|
||||
// and store into session
|
||||
$this->Session->write('paginate_conditions', $this->paginate);
|
||||
$this->Session->write('paginate_conditions_keyword', $keyword);
|
||||
$this->Session->write('paginate_conditions_keyword2', $keyword2);
|
||||
if (isset($attributeTags)) {
|
||||
$this->Session->write('paginate_conditions_attributetags', $attributeTags);
|
||||
}
|
||||
$this->Session->write('paginate_conditions_org', $org);
|
||||
$this->Session->write('paginate_conditions_type', $type);
|
||||
$this->Session->write('paginate_conditions_ioc', $ioc);
|
||||
$this->Session->write('paginate_conditions_tags', $tags);
|
||||
$this->Session->write('paginate_conditions_category', $category);
|
||||
$this->Session->write('search_find_idlist', $idList);
|
||||
$this->Session->write('search_find_attributeidlist', $attributeIdList);
|
||||
|
||||
// set the same view as the index page
|
||||
$this->render('index');
|
||||
}
|
||||
}
|
||||
$this->set('attrDescriptions', $this->Attribute->fieldDescriptions);
|
||||
$this->set('typeDefinitions', $this->Attribute->typeDefinitions);
|
||||
$this->set('categoryDefinitions', $this->Attribute->categoryDefinitions);
|
||||
if ($this->request->is('post')) {
|
||||
if (isset($this->request->data['Attribute'])) {
|
||||
$this->request->data = $this->request->data['Attribute'];
|
||||
}
|
||||
$checkForEmpty = array('value', 'tags', 'uuid', 'org', 'type', 'category');
|
||||
foreach ($checkForEmpty as $field) {
|
||||
if (empty($this->request->data[$field]) || $this->request->data[$field] === 'ALL') {
|
||||
unset($this->request->data[$field]);
|
||||
}
|
||||
}
|
||||
if (empty($this->request->data['to_ids'])) {
|
||||
unset($this->request->data['to_ids']);
|
||||
$this->request->data['ignore'] = 1;
|
||||
}
|
||||
$paramArray = array('value' , 'type', 'category', 'org', 'tags', 'from', 'to', 'last', 'eventid', 'withAttachments', 'uuid', 'publish_timestamp', 'timestamp', 'enforceWarninglist', 'to_ids', 'deleted', 'includeEventUuid', 'event_timestamp', 'threat_level_id', 'includeEventTags');
|
||||
$filterData = array(
|
||||
'request' => $this->request,
|
||||
'named_params' => $this->params['named'],
|
||||
'paramArray' => $paramArray,
|
||||
'ordered_url_params' => compact($paramArray)
|
||||
);
|
||||
$exception = false;
|
||||
$filters = $this->_harvestParameters($filterData, $exception);
|
||||
unset($filterData);
|
||||
if ($filters === false) {
|
||||
return $exception;
|
||||
}
|
||||
$this->Session->write('search_attributes_filters', json_encode($filters));
|
||||
} else if ($continue === 'results') {
|
||||
$filters = $this->Session->read('search_attributes_filters');
|
||||
if (empty($filters)) {
|
||||
$filters = array();
|
||||
} else {
|
||||
$filters = json_decode($filters, true);
|
||||
}
|
||||
} else {
|
||||
$types = array('' => array('ALL' => 'ALL'), 'types' => array());
|
||||
$types['types'] = array_merge($types['types'], $this->_arrayToValuesIndexArray(array_keys($this->Attribute->typeDefinitions)));
|
||||
ksort($types['types']);
|
||||
$this->set('types', $types);
|
||||
// combobox for categories
|
||||
$categories['categories'] = array_merge(array('ALL' => 'ALL'), $this->_arrayToValuesIndexArray(array_keys($this->Attribute->categoryDefinitions)));
|
||||
$this->set('categories', $categories);
|
||||
$this->Session->write('search_attributes_filters', null);
|
||||
}
|
||||
if (isset($filters)) {
|
||||
$params = $this->Attribute->restSearch($this->Auth->user(), 'json', $filters, true);
|
||||
$this->paginate = $params;
|
||||
if (empty($this->paginate['limit'])) {
|
||||
$this->paginate['limit'] = 60;
|
||||
}
|
||||
if (empty($this->paginate['page'])) {
|
||||
$this->paginate['page'] = 1;
|
||||
}
|
||||
$this->paginate['recursive'] = -1;
|
||||
$this->paginate['contain'] = array(
|
||||
'Event' => array(
|
||||
'fields' => array('Event.id', 'Event.orgc_id', 'Event.org_id', 'Event.info', 'Event.user_id'),
|
||||
'Orgc' => array('fields' => array('Orgc.id', 'Orgc.name')),
|
||||
'Org' => array('fields' => array('Org.id', 'Org.name'))
|
||||
),
|
||||
'AttributeTag' => array('Tag'),
|
||||
'Object' => array(
|
||||
'fields' => array('Object.id', 'Object.distribution', 'Object.sharing_group_id')
|
||||
)
|
||||
);
|
||||
$attributes = $this->paginate();
|
||||
$this->set('filters', $filters);
|
||||
$this->set('attributes', $attributes);
|
||||
$this->set('isSearch', 1);
|
||||
$this->render('index');
|
||||
}
|
||||
if (isset($attributeTags)) {
|
||||
$this->set('attributeTags', $attributeTags);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2090,15 +1733,7 @@ class AttributesController extends AppController
|
|||
'paramArray' => $paramArray,
|
||||
'ordered_url_params' => compact($paramArray)
|
||||
);
|
||||
$validFormats = array(
|
||||
'openioc' => array('xml', 'OpeniocExport'),
|
||||
'json' => array('json', 'JsonExport'),
|
||||
'xml' => array('xml', 'XmlExport'),
|
||||
'suricata' => array('txt', 'NidsSuricataExport'),
|
||||
'snort' => array('txt', 'NidsSnortExport'),
|
||||
'text' => array('txt', 'TextExport'),
|
||||
'rpz' => array('rpz', 'RPZExport')
|
||||
);
|
||||
$validFormats = $this->validFormats;
|
||||
$exception = false;
|
||||
$filters = $this->_harvestParameters($filterData, $exception);
|
||||
unset($filterData);
|
||||
|
@ -2116,109 +1751,11 @@ class AttributesController extends AppController
|
|||
if ($returnFormat === 'download') {
|
||||
$returnFormat = 'json';
|
||||
}
|
||||
if (!isset($validFormats[$returnFormat][1])) {
|
||||
throw new NotFoundException('Invalid output format.');
|
||||
}
|
||||
App::uses($validFormats[$returnFormat][1], 'Export');
|
||||
$exportTool = new $validFormats[$returnFormat][1]();
|
||||
if (empty($exportTool->non_restrictive_export)) {
|
||||
if (!isset($filters['to_ids'])) {
|
||||
$filters['to_ids'] = 1;
|
||||
}
|
||||
if (!isset($filters['published'])) {
|
||||
$filters['published'] = 1;
|
||||
}
|
||||
}
|
||||
$conditions = $this->Attribute->buildFilterConditions($this->Auth->user(), $filters);
|
||||
$params = array(
|
||||
'conditions' => $conditions,
|
||||
'fields' => array('Attribute.*', 'Event.org_id', 'Event.distribution'),
|
||||
'withAttachments' => !empty($filters['withAttachments']) ? $filters['withAttachments'] : 0,
|
||||
'enforceWarninglist' => !empty($filters['enforceWarninglist']) ? $filters['enforceWarninglist'] : 0,
|
||||
'includeAllTags' => true,
|
||||
'flatten' => 1,
|
||||
'includeEventUuid' => !empty($filters['includeEventUuid']) ? $filters['includeEventUuid'] : 0,
|
||||
'includeEventTags' => !empty($filters['includeEventTags']) ? $filters['includeEventTags'] : 0
|
||||
);
|
||||
if (isset($filters['include_event_uuid'])) {
|
||||
$params['includeEventUuid'] = $filters['include_event_uuid'];
|
||||
}
|
||||
if (isset($filters['limit'])) {
|
||||
$params['limit'] = $filters['limit'];
|
||||
}
|
||||
if (isset($filters['page'])) {
|
||||
$params['page'] = $filters['page'];
|
||||
}
|
||||
if (!empty($filtes['deleted'])) {
|
||||
$params['deleted'] = 1;
|
||||
if ($params['deleted'] === 'only') {
|
||||
$params['conditions']['AND'][] = array('Attribute.deleted' => 1);
|
||||
$params['conditions']['AND'][] = array('Object.deleted' => 1);
|
||||
}
|
||||
}
|
||||
if (!isset($validFormats[$returnFormat])) {
|
||||
// this is where the new code path for the export modules will go
|
||||
throw new MethodNotFoundException('Invalid export format.');
|
||||
}
|
||||
$exportToolParams = array(
|
||||
'user' => $this->Auth->user(),
|
||||
'params' => $params,
|
||||
'returnFormat' => $returnFormat,
|
||||
'scope' => 'Attribute',
|
||||
'filters' => $filters
|
||||
);
|
||||
if (!empty($exportTool->additional_params)) {
|
||||
$params = array_merge($params, $exportTool->additional_params);
|
||||
}
|
||||
$tmpfile = tmpfile();
|
||||
fwrite($tmpfile, $exportTool->header($exportToolParams));
|
||||
$loop = false;
|
||||
if (empty($params['limit'])) {
|
||||
$memory_in_mb = $this->Attribute->convert_to_memory_limit_to_mb(ini_get('memory_limit'));
|
||||
$memory_scaling_factor = isset($exportTool->memory_scaling_factor) ? $exportTool->memory_scaling_factor : 100;
|
||||
$params['limit'] = $memory_in_mb * $memory_scaling_factor;
|
||||
$loop = true;
|
||||
$params['page'] = 1;
|
||||
}
|
||||
$this->__iteratedFetch($params, $loop, $tmpfile, $exportTool, $exportToolParams);
|
||||
fwrite($tmpfile, $exportTool->footer($exportToolParams));
|
||||
fseek($tmpfile, 0);
|
||||
$final = fread($tmpfile, fstat($tmpfile)['size']);
|
||||
fclose($tmpfile);
|
||||
$final = $this->Attribute->restSearch($user, $returnFormat, $filters);
|
||||
$responseType = $validFormats[$returnFormat][0];
|
||||
return $this->RestResponse->viewData($final, $responseType, false, true);
|
||||
}
|
||||
|
||||
private function __iteratedFetch(&$params, &$loop, &$tmpfile, $exportTool, $exportToolParams) {
|
||||
$continue = true;
|
||||
while ($continue) {
|
||||
$this->loadModel('Whitelist');
|
||||
$results = $this->Attribute->fetchAttributes($this->Auth->user(), $params, $continue);
|
||||
$params['page'] += 1;
|
||||
$results = $this->Whitelist->removeWhitelistedFromArray($results, true);
|
||||
$results = array_values($results);
|
||||
$i = 0;
|
||||
$temp = '';
|
||||
foreach ($results as $attribute) {
|
||||
$temp .= $exportTool->handler($attribute, $exportToolParams);
|
||||
if ($temp !== '') {
|
||||
if ($i != count($results) -1) {
|
||||
$temp .= $exportTool->separator($exportToolParams);
|
||||
}
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
if (!$loop) {
|
||||
$continue = false;
|
||||
}
|
||||
if ($continue) {
|
||||
$temp .= $exportTool->separator($exportToolParams);
|
||||
}
|
||||
fwrite($tmpfile, $temp);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// returns an XML with attributes that belong to an event. The type of attributes to be returned can be restricted by type using the 3rd parameter.
|
||||
// Similar to the restSearch, this parameter can be chained with '&&' and negations are accepted too. For example filename&&!filename|md5 would return all filenames that don't have an md5
|
||||
// The usage of returnAttributes is the following: [MISP-url]/attributes/returnAttributes/<API-key>/<type>/<signature flag>
|
||||
|
@ -3498,4 +3035,20 @@ class AttributesController extends AppController
|
|||
}
|
||||
return new CakeResponse(array('body'=>$counter, 'status'=>200));
|
||||
}
|
||||
|
||||
public function exportSearch($type = false)
|
||||
{
|
||||
if (empty($type)) {
|
||||
$exports = array_keys($this->validFormats);
|
||||
$this->set('exports', $exports);
|
||||
$this->render('ajax/exportSearch');
|
||||
} else {
|
||||
$filters = $this->Session->read('search_attributes_filters');
|
||||
$filters = json_decode($filters, true);
|
||||
$final = $this->Attribute->restSearch($this->Auth->user(), $type, $filters);
|
||||
$responseType = $this->validFormats[$type][0];
|
||||
return $this->RestResponse->viewData($final, $responseType, false, true, 'search.' . $type . '.' . $responseType);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1147,6 +1147,7 @@ class EventsController extends AppController
|
|||
}
|
||||
$this->set('sightingTypes', $this->Sighting->type);
|
||||
$this->set('currentUri', $this->params->here);
|
||||
$this->layout = false;
|
||||
$this->render('/Elements/eventattribute');
|
||||
}
|
||||
|
||||
|
@ -2682,7 +2683,7 @@ class EventsController extends AppController
|
|||
return new CakeResponse(array('body'=> implode(PHP_EOL, $rules), 'status' => 200, 'type' => 'txt'));
|
||||
}
|
||||
|
||||
// csv function
|
||||
// csv function ***DEPRECATED***
|
||||
// Usage: csv($key, $eventid) - key can be a valid auth key or the string 'download'. Download requires the user to be logged in interactively and will generate a .csv file
|
||||
// $eventid can be one of 3 options: left empty it will get all the visible to_ids attributes,
|
||||
// $ignore is a flag that allows the export tool to ignore the ids flag. 0 = only IDS signatures, 1 = everything.
|
||||
|
@ -2696,8 +2697,8 @@ class EventsController extends AppController
|
|||
'ordered_url_params' => compact($paramArray)
|
||||
);
|
||||
$exception = false;
|
||||
$params = $this->_harvestParameters($filterData, $exception);
|
||||
if ($params === false) {
|
||||
$filters = $this->_harvestParameters($filterData, $exception);
|
||||
if ($filters === false) {
|
||||
return $exception;
|
||||
}
|
||||
$list = array();
|
||||
|
@ -2705,6 +2706,7 @@ class EventsController extends AppController
|
|||
if ($user === false) {
|
||||
return $exception;
|
||||
}
|
||||
$final = $this->Event->restSearch($user, 'csv', $filters);
|
||||
// if it's a search, grab the attributeIDList from the session and get the IDs from it. Use those as the condition
|
||||
// We don't need to look out for permissions since that's filtered by the search itself
|
||||
// We just want all the attributes found by the search
|
||||
|
@ -2733,75 +2735,8 @@ class EventsController extends AppController
|
|||
$list[] = $attribute['Attribute']['id'];
|
||||
}
|
||||
}
|
||||
$final = array();
|
||||
$requested_attributes = array('uuid', 'event_id', 'category', 'type',
|
||||
'value', 'comment', 'to_ids', 'timestamp', 'object_relation');
|
||||
$requested_obj_attributes = array('uuid', 'name', 'meta-category');
|
||||
if ($includeContext) {
|
||||
$requested_attributes[] = 'attribute_tag';
|
||||
}
|
||||
if (isset($this->params['url']['attributes'])) {
|
||||
if (!isset($this->params['url']['obj_attributes'])) {
|
||||
$requested_obj_attributes = array();
|
||||
}
|
||||
$requested_attributes = explode(',', $this->params['url']['attributes']);
|
||||
}
|
||||
if (isset($this->params['url']['obj_attributes'])) {
|
||||
$requested_obj_attributes = explode(',', $this->params['url']['obj_attributes']);
|
||||
}
|
||||
if (isset($data['request']['attributes'])) {
|
||||
if (!isset($data['request']['obj_attributes'])) {
|
||||
$requested_obj_attributes = array();
|
||||
}
|
||||
$requested_attributes = $data['request']['attributes'];
|
||||
}
|
||||
if (isset($data['request']['obj_attributes'])) {
|
||||
$requested_obj_attributes = $data['request']['obj_attributes'];
|
||||
}
|
||||
$possibleParams = array(
|
||||
'ignore', 'list', 'category', 'type', 'includeContext',
|
||||
'enforceWarninglist', 'value', 'timestamp', 'tags',
|
||||
'last', 'from', 'to'
|
||||
);
|
||||
if (isset($params['eventid']) && $params['eventid'] == 'all') {
|
||||
unset($params['eventid']);
|
||||
}
|
||||
foreach ($possibleParams as $possibleParam) {
|
||||
if (isset($params[$possibleParam])) {
|
||||
$params[$possibleParam] = $params[$possibleParam];
|
||||
}
|
||||
}
|
||||
$params['limit'] = 1000;
|
||||
$params['page'] = 1;
|
||||
$i = 0;
|
||||
$continue = true;
|
||||
$params = array_merge($params, array(
|
||||
'requested_obj_attributes' => $requested_obj_attributes,
|
||||
'requested_attributes' => $requested_attributes,
|
||||
'includeContext' => $includeContext
|
||||
));
|
||||
App::uses('CsvExport', 'Export');
|
||||
$export = new CsvExport();
|
||||
$final = $export->header($params);
|
||||
while ($continue) {
|
||||
$attributes = $this->Event->csv($user, $params, false, $continue);
|
||||
$params['page'] += 1;
|
||||
$final .= $export->handler($attributes, $params);
|
||||
$final .= $export->separator($attributes);
|
||||
}
|
||||
$export->footer();
|
||||
$this->response->type('csv'); // set the content type
|
||||
if (empty($params['eventid'])) {
|
||||
$filename = "misp.filtered_attributes.csv";
|
||||
} elseif ($params['eventid'] === 'search') {
|
||||
$filename = "misp.search_result.csv";
|
||||
} else {
|
||||
if (is_array($params['eventid'])) {
|
||||
$params['eventid'] = 'list';
|
||||
}
|
||||
$filename = "misp.event_" . $params['eventid'] . ".csv";
|
||||
}
|
||||
return $this->RestResponse->viewData($final, 'csv', false, true, $filename);
|
||||
$responseType = 'csv';
|
||||
return $this->RestResponse->viewData($final, $responseType, false, true, 'download.csv');
|
||||
}
|
||||
|
||||
public function _addIOCFile($id)
|
||||
|
@ -3006,43 +2941,6 @@ class EventsController extends AppController
|
|||
return $this->response;
|
||||
}
|
||||
|
||||
/*
|
||||
* Receive a list of eventids in the id=>count format
|
||||
* Chunk them by the attribute count to fit the memory limits
|
||||
*
|
||||
*/
|
||||
private function __clusterEventIds($exportTool, $eventIds) {
|
||||
$memory_in_mb = $this->Event->Attribute->convert_to_memory_limit_to_mb(ini_get('memory_limit'));
|
||||
$memory_scaling_factor = isset($exportTool->memory_scaling_factor) ? $exportTool->memory_scaling_factor : 100;
|
||||
$limit = $memory_in_mb * $memory_scaling_factor;
|
||||
$eventIdList = array();
|
||||
$continue = true;
|
||||
$i = 0;
|
||||
$current_chunk_size = 0;
|
||||
while (!empty($eventIds)) {
|
||||
foreach ($eventIds as $id => $count) {
|
||||
if ($current_chunk_size == 0 && $count > $limit) {
|
||||
$eventIdList[$i][] = $id;
|
||||
$current_chunk_size = $count;
|
||||
unset($eventIds[$id]);
|
||||
$i++;
|
||||
break;
|
||||
} else {
|
||||
if (($current_chunk_size + $count) > $limit) {
|
||||
$i++;
|
||||
$current_chunk_size = 0;
|
||||
break;
|
||||
} else {
|
||||
$current_chunk_size += $count;
|
||||
$eventIdList[$i][] = $id;
|
||||
unset($eventIds[$id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $eventIdList;
|
||||
}
|
||||
|
||||
// Use the REST interface to search for attributes or events. Usage:
|
||||
// MISP-base-url/events/restSearch/[api-key]/[value]/[type]/[category]/[orgc]
|
||||
// value, type, category, orgc are optional
|
||||
|
@ -3059,6 +2957,7 @@ class EventsController extends AppController
|
|||
'paramArray' => $paramArray,
|
||||
'ordered_url_params' => compact($paramArray)
|
||||
);
|
||||
<<<<<<< HEAD
|
||||
$validFormats = array(
|
||||
'openioc' => array('xml', 'OpeniocExport'),
|
||||
'json' => array('json', 'JsonExport'),
|
||||
|
@ -3070,6 +2969,8 @@ class EventsController extends AppController
|
|||
'stix2' => array('json', 'Stix2Export'),
|
||||
'text' => array('text', 'TextExport')
|
||||
);
|
||||
=======
|
||||
>>>>>>> 92eb8a91ad0c507f97954350535ba87e16d73e23
|
||||
$exception = false;
|
||||
$filters = $this->_harvestParameters($filterData, $exception);
|
||||
unset($filterData);
|
||||
|
@ -3087,6 +2988,7 @@ class EventsController extends AppController
|
|||
if ($returnFormat === 'download') {
|
||||
$returnFormat = 'json';
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
if (!isset($validFormats[$returnFormat][1])) {
|
||||
throw new NotFoundException('Invalid output format.');
|
||||
}
|
||||
|
@ -3174,6 +3076,10 @@ class EventsController extends AppController
|
|||
$final = fread($tmpfile, fstat($tmpfile)['size']);
|
||||
fclose($tmpfile);
|
||||
$responseType = $validFormats[$returnFormat][0];
|
||||
=======
|
||||
$final = $this->Event->restSearch($user, $returnFormat, $filters);
|
||||
$responseType = $this->Event->validFormats[$returnFormat][0];
|
||||
>>>>>>> 92eb8a91ad0c507f97954350535ba87e16d73e23
|
||||
return $this->RestResponse->viewData($final, $responseType, false, true);
|
||||
}
|
||||
|
||||
|
|
|
@ -1651,6 +1651,7 @@ class ServersController extends AppController
|
|||
if (!empty($request['skip_ssl_validation'])) {
|
||||
$params['ssl_verify_peer'] = false;
|
||||
}
|
||||
$params['timeout'] = 300;
|
||||
App::uses('HttpSocket', 'Network/Http');
|
||||
$HttpSocket = new HttpSocket($params);
|
||||
$view_data = array();
|
||||
|
|
|
@ -2,66 +2,194 @@
|
|||
|
||||
class CsvExport
|
||||
{
|
||||
public $event_context_fields = array('event_info', 'event_member_org', 'event_source_org', 'event_distribution', 'event_threat_level_id', 'event_analysis', 'event_date', 'event_tag');
|
||||
public $default_fields = array('uuid', 'event_id', 'category', 'type', 'value', 'comment', 'to_ids', 'timestamp', 'object_relation', 'attribute_tag');
|
||||
public $default_obj_fields = array('object_uuid', 'object_name', 'object_meta-category');
|
||||
public $requested_fields = array();
|
||||
|
||||
public $csv_event_context_fields_to_fetch = array(
|
||||
'event_info' => array('object' => false, 'var' => 'info'),
|
||||
'event_member_org' => array('object' => 'Org', 'var' => 'name'),
|
||||
'event_source_org' => array('object' => 'Orgc', 'var' => 'name'),
|
||||
'event_distribution' => array('object' => false, 'var' => 'distribution'),
|
||||
'event_threat_level_id' => array('object' => 'ThreatLevel', 'var' => 'name'),
|
||||
'event_analysis' => array('object' => false, 'var' => 'analysis'),
|
||||
'event_date' => array('object' => false, 'var' => 'date'),
|
||||
'event_tag' => array('object' => 'Tag', 'var' => 'name')
|
||||
);
|
||||
|
||||
public function handler($attributes, $options = array())
|
||||
public function handler($data, $options = array())
|
||||
{
|
||||
$result = array();
|
||||
foreach ($attributes as $attribute) {
|
||||
$line1 = '';
|
||||
$line2 = '';
|
||||
foreach ($options['requested_attributes'] as $requested_attribute) {
|
||||
$line1 .= $attribute['Attribute'][$requested_attribute] . ',';
|
||||
}
|
||||
$line1 = rtrim($line1, ",");
|
||||
foreach ($options['requested_obj_attributes'] as $requested_obj_attribute) {
|
||||
$line2 .= $attribute['Object'][$requested_obj_attribute] . ',';
|
||||
}
|
||||
$line2 = rtrim($line2, ",");
|
||||
$line = $line1 . ',' . $line2;
|
||||
$line = rtrim($line, ",");
|
||||
if (!empty($options['includeContext'])) {
|
||||
foreach ($this->Event->csv_event_context_fields_to_fetch as $header => $field) {
|
||||
if ($field['object']) {
|
||||
$line .= ',' . $attribute['Event'][$field['object']][$field['var']];
|
||||
} else {
|
||||
$line .= ',' . str_replace(array("\n","\t","\r"), " ", $attribute['Event'][$field['var']]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$result[] = $line;
|
||||
}
|
||||
$result = implode(PHP_EOL, $result);
|
||||
return $result;
|
||||
if ($options['scope'] === 'Attribute') {
|
||||
$lines = $this->__attributesHandler($data, $options);
|
||||
} else if($options['scope'] === 'Event') {
|
||||
$lines = $this->__eventsHandler($data, $options);
|
||||
}
|
||||
return $lines;
|
||||
}
|
||||
|
||||
public function header($options = array())
|
||||
public function modify_params($user, $params)
|
||||
{
|
||||
if (empty($params['contain'])) {
|
||||
$params['contain'] = array();
|
||||
}
|
||||
$params['contain'] = array_merge($params['contain'], array(
|
||||
'Object' => array('fields' => array('Object.uuid', 'Object.name', 'Object.meta-category')),
|
||||
'AttributeTag' => array('Tag'),
|
||||
'Event' => array('fields' => array('Event.*'), 'EventTag' => 'Tag', 'Org.name', 'Orgc.name', 'ThreatLevel')
|
||||
));
|
||||
unset($params['fields']);
|
||||
$params['includeEventUuid'] = 0;
|
||||
$params['includeEventTags'] = 0;
|
||||
$params['withAttachments'] = 0;
|
||||
return $params;
|
||||
}
|
||||
|
||||
private function __attributesHandler($attribute, $options)
|
||||
{
|
||||
$attribute = $this->__addMetadataToAttributeAtomic($attribute);
|
||||
if (!empty($attribute['Object']['uuid'])) {
|
||||
$attribute['object_uuid'] = $attribute['Object']['uuid'];
|
||||
$attribute['object_name'] = $attribute['Object']['name'];
|
||||
$attribute['object_meta-category'] = $attribute['Object']['meta-category'];
|
||||
}
|
||||
return $this->__addLine($attribute, $options);
|
||||
}
|
||||
|
||||
private function __eventsHandler($event, $options)
|
||||
{
|
||||
$lines = '';
|
||||
if (!empty($event['Attribute'])) {
|
||||
foreach ($event['Attribute'] as $k => $attribute) {
|
||||
$attribute = $this->__addMetadataToAttribute($event, $attribute);
|
||||
$lines .= $this->__addLine($attribute, $options);
|
||||
}
|
||||
}
|
||||
if (!empty($event['Object'])) {
|
||||
foreach ($event['Object'] as $k => $object) {
|
||||
if (!empty($object['Attribute'])) {
|
||||
foreach ($object['Attribute'] as $attribute) {
|
||||
$attribute = $this->__addMetadataToAttribute($event, $attribute);
|
||||
$attribute['object_uuid'] = $object['uuid'];
|
||||
$attribute['object_name'] = $object['name'];
|
||||
$attribute['object_meta-category'] = $object['meta-category'];
|
||||
$lines .= $this->__addLine($attribute, $options);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $lines;
|
||||
}
|
||||
|
||||
private function __addLine($attribute, $options = array()) {
|
||||
$line = '';
|
||||
foreach ($this->requested_fields as $req_att) {
|
||||
if (empty($line)) {
|
||||
$line = $this->__escapeCSVField($attribute[$req_att]);
|
||||
} else {
|
||||
$line .= ',' . $this->__escapeCSVField($attribute[$req_att]);
|
||||
}
|
||||
}
|
||||
return $line . PHP_EOL;
|
||||
}
|
||||
|
||||
private function __escapeCSVField(&$field)
|
||||
{
|
||||
if (is_bool($field)) {
|
||||
return ($field ? 'true' : 'false');
|
||||
}
|
||||
if (is_numeric($field)) {
|
||||
return $field;
|
||||
}
|
||||
$field = str_replace(array('"'), '""', $field);
|
||||
$field = '"' . $field . '"';
|
||||
return $field;
|
||||
}
|
||||
|
||||
private function __addMetadataToAttributeAtomic($attribute_raw) {
|
||||
$attribute = $attribute_raw['Attribute'];
|
||||
if (!empty($attribute_raw['AttributeTag'])) {
|
||||
$tags = array();
|
||||
foreach ($attribute_raw['AttributeTag'] as $at) {
|
||||
$tags[] = $at['Tag']['name'];
|
||||
}
|
||||
$tags = implode(',', $tags);
|
||||
$attribute['attribute_tag'] = $tags;
|
||||
}
|
||||
$attribute['event_info'] = $attribute_raw['Event']['info'];
|
||||
$attribute['event_member_org'] = $attribute_raw['Event']['Org']['name'];
|
||||
$attribute['event_source_org'] = $attribute_raw['Event']['Orgc']['name'];
|
||||
$attribute['event_distribution'] = $attribute_raw['Event']['distribution'];
|
||||
$attribute['event_threat_level_id'] = $attribute_raw['Event']['ThreatLevel']['name'];
|
||||
$attribute['event_analysis'] = $attribute_raw['Event']['analysis'];
|
||||
$attribute['event_date'] = $attribute_raw['Event']['date'];
|
||||
if (!empty($attribute_raw['EventTag'])) {
|
||||
$tags = array();
|
||||
foreach ($attribute_raw['EventTag'] as $et) {
|
||||
$tags[] = $et['Tag']['name'];
|
||||
}
|
||||
$tags = implode(',', $tags);
|
||||
$attribute['event_tag'] = $tags;
|
||||
}
|
||||
return $attribute;
|
||||
}
|
||||
|
||||
private function __addMetadataToAttribute($event, $attribute) {
|
||||
if (!empty($attribute['AttributeTag'])) {
|
||||
$tags = array();
|
||||
foreach ($attribute['AttributeTag'] as $at) {
|
||||
$tags[] = $at['Tag']['name'];
|
||||
}
|
||||
$tags = implode(',', $tags);
|
||||
$attribute['attribute_tag'] = $tags;
|
||||
}
|
||||
$attribute['event_info'] = $event['Event']['info'];
|
||||
$attribute['event_member_org'] = $event['Org']['name'];
|
||||
$attribute['event_source_org'] = $event['Orgc']['name'];
|
||||
$attribute['event_distribution'] = $event['Event']['distribution'];
|
||||
$attribute['event_threat_level_id'] = $event['ThreatLevel']['name'];
|
||||
$attribute['event_analysis'] = $event['Event']['analysis'];
|
||||
$attribute['event_date'] = $event['Event']['date'];
|
||||
if (!empty($event['EventTag'])) {
|
||||
$tags = array();
|
||||
foreach ($event['EventTag'] as $et) {
|
||||
$tags[] = $et['Tag']['name'];
|
||||
}
|
||||
$tags = implode(',', $tags);
|
||||
$attribute['event_tag'] = $tags;
|
||||
}
|
||||
return $attribute;
|
||||
}
|
||||
|
||||
public function header(&$options)
|
||||
{
|
||||
if (!empty($options['requested_obj_attributes'])) {
|
||||
array_walk($options['requested_obj_attributes'], function (&$value, $key) {
|
||||
$value = 'object-'.$value;
|
||||
});
|
||||
}
|
||||
$headers = array_merge($options['requested_attributes'], $options['requested_obj_attributes']);
|
||||
if (!empty($options['includeContext'])) {
|
||||
$headers = array_merge($headers, array_keys($this->csv_event_context_fields_to_fetch));
|
||||
}
|
||||
foreach ($headers as $k => $v) {
|
||||
if (isset($options['filters']['requested_attributes'])) {
|
||||
$this->requested_fields = $options['filters']['requested_attributes'];
|
||||
} else {
|
||||
$this->requested_fields = $this->default_fields;
|
||||
}
|
||||
if (isset($options['filters']['requested_obj_attributes'])) {
|
||||
$requested_obj_attributes = array();
|
||||
foreach ($options['filters']['requested_obj_attributes'] as $roa) {
|
||||
$requested_obj_attributes[] = 'object_' . $roa;
|
||||
}
|
||||
} else {
|
||||
if (isset($options['filters']['requested_attributes'])) {
|
||||
$requested_obj_attributes = array();
|
||||
} else {
|
||||
$requested_obj_attributes = $this->default_obj_fields;
|
||||
}
|
||||
}
|
||||
foreach ($requested_obj_attributes as $obj_att) {
|
||||
$this->requested_fields[] = $obj_att;
|
||||
}
|
||||
if (isset($options['filters']['includeContext'])) {
|
||||
foreach ($this->event_context_fields as $event_context_field) {
|
||||
$this->requested_fields[] = $event_context_field;
|
||||
}
|
||||
}
|
||||
$object_level_search = false;
|
||||
foreach ($this->requested_fields as $k => $v) {
|
||||
if (in_array($v, $this->default_obj_fields)) {
|
||||
$object_level_search = true;
|
||||
}
|
||||
$headers[$k] = str_replace('-', '_', $v);
|
||||
if ($v == 'timestamp') {
|
||||
$headers[$k] = 'date';
|
||||
}
|
||||
}
|
||||
if (!$object_level_search) {
|
||||
$options['flatten'] = 1;
|
||||
}
|
||||
$headers = implode(',', $headers) . PHP_EOL;
|
||||
return $headers;
|
||||
}
|
||||
|
@ -73,7 +201,7 @@ class CsvExport
|
|||
|
||||
public function separator()
|
||||
{
|
||||
return PHP_EOL;
|
||||
return '';
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -117,6 +117,17 @@ class Attribute extends AppModel
|
|||
),
|
||||
);
|
||||
|
||||
public $validFormats = array(
|
||||
'openioc' => array('xml', 'OpeniocExport'),
|
||||
'json' => array('json', 'JsonExport'),
|
||||
'xml' => array('xml', 'XmlExport'),
|
||||
'suricata' => array('txt', 'NidsSuricataExport'),
|
||||
'snort' => array('txt', 'NidsSnortExport'),
|
||||
'text' => array('txt', 'TextExport'),
|
||||
'rpz' => array('rpz', 'RPZExport'),
|
||||
'csv' => array('csv', 'CsvExport')
|
||||
);
|
||||
|
||||
public $typeDefinitions = array(
|
||||
'md5' => array('desc' => 'A checksum in md5 format', 'formdesc' => "You are encouraged to use filename|md5 instead. A checksum in md5 format, only use this if you don't know the correct filename", 'default_category' => 'Payload delivery', 'to_ids' => 1),
|
||||
'sha1' => array('desc' => 'A checksum in sha1 format', 'formdesc' => "You are encouraged to use filename|sha1 instead. A checksum in sha1 format, only use this if you don't know the correct filename", 'default_category' => 'Payload delivery', 'to_ids' => 1),
|
||||
|
@ -3166,7 +3177,7 @@ class Attribute extends AppModel
|
|||
|
||||
public function convertToOpenIOC($user, $attributes)
|
||||
{
|
||||
return $this->IOCExport->buildAll($this->Auth->user(), $event);
|
||||
return $this->IOCExport->buildAll($user, $event);
|
||||
}
|
||||
|
||||
private function __createTagSubQuery($tag_id, $blocked = false, $scope = 'Event', $limitAttributeHitsTo = 'event')
|
||||
|
@ -3708,4 +3719,114 @@ class Attribute extends AppModel
|
|||
}
|
||||
return $conditions;
|
||||
}
|
||||
|
||||
public function restSearch($user, $returnFormat, $filters, $paramsOnly = false)
|
||||
{
|
||||
if (!isset($this->validFormats[$returnFormat][1])) {
|
||||
throw new NotFoundException('Invalid output format.');
|
||||
}
|
||||
App::uses($this->validFormats[$returnFormat][1], 'Export');
|
||||
$exportTool = new $this->validFormats[$returnFormat][1]();
|
||||
if (empty($exportTool->non_restrictive_export)) {
|
||||
if (!isset($filters['to_ids'])) {
|
||||
$filters['to_ids'] = 1;
|
||||
}
|
||||
if (!isset($filters['published'])) {
|
||||
$filters['published'] = 1;
|
||||
}
|
||||
}
|
||||
$conditions = $this->buildFilterConditions($user, $filters);
|
||||
$params = array(
|
||||
'conditions' => $conditions,
|
||||
'fields' => array('Attribute.*', 'Event.org_id', 'Event.distribution'),
|
||||
'withAttachments' => !empty($filters['withAttachments']) ? $filters['withAttachments'] : 0,
|
||||
'enforceWarninglist' => !empty($filters['enforceWarninglist']) ? $filters['enforceWarninglist'] : 0,
|
||||
'includeAllTags' => true,
|
||||
'flatten' => 1,
|
||||
'includeEventUuid' => !empty($filters['includeEventUuid']) ? $filters['includeEventUuid'] : 0,
|
||||
'includeEventTags' => !empty($filters['includeEventTags']) ? $filters['includeEventTags'] : 0
|
||||
);
|
||||
if (isset($filters['include_event_uuid'])) {
|
||||
$params['includeEventUuid'] = $filters['include_event_uuid'];
|
||||
}
|
||||
if (isset($filters['limit'])) {
|
||||
$params['limit'] = $filters['limit'];
|
||||
}
|
||||
if (isset($filters['page'])) {
|
||||
$params['page'] = $filters['page'];
|
||||
}
|
||||
if (!empty($filtes['deleted'])) {
|
||||
$params['deleted'] = 1;
|
||||
if ($params['deleted'] === 'only') {
|
||||
$params['conditions']['AND'][] = array('Attribute.deleted' => 1);
|
||||
$params['conditions']['AND'][] = array('Object.deleted' => 1);
|
||||
}
|
||||
}
|
||||
if ($paramsOnly) {
|
||||
return $params;
|
||||
}
|
||||
if (!isset($this->validFormats[$returnFormat])) {
|
||||
// this is where the new code path for the export modules will go
|
||||
throw new MethodNotFoundException('Invalid export format.');
|
||||
}
|
||||
if (method_exists($exportTool, 'modify_params')) {
|
||||
$params = $exportTool->modify_params($user, $params);
|
||||
}
|
||||
$exportToolParams = array(
|
||||
'user' => $user,
|
||||
'params' => $params,
|
||||
'returnFormat' => $returnFormat,
|
||||
'scope' => 'Attribute',
|
||||
'filters' => $filters
|
||||
);
|
||||
if (!empty($exportTool->additional_params)) {
|
||||
$params = array_merge($params, $exportTool->additional_params);
|
||||
}
|
||||
$tmpfile = tmpfile();
|
||||
fwrite($tmpfile, $exportTool->header($exportToolParams));
|
||||
$loop = false;
|
||||
if (empty($params['limit'])) {
|
||||
$memory_in_mb = $this->convert_to_memory_limit_to_mb(ini_get('memory_limit'));
|
||||
$memory_scaling_factor = isset($exportTool->memory_scaling_factor) ? $exportTool->memory_scaling_factor : 100;
|
||||
$params['limit'] = $memory_in_mb * $memory_scaling_factor;
|
||||
$loop = true;
|
||||
$params['page'] = 1;
|
||||
}
|
||||
$this->__iteratedFetch($user, $params, $loop, $tmpfile, $exportTool, $exportToolParams);
|
||||
fwrite($tmpfile, $exportTool->footer($exportToolParams));
|
||||
fseek($tmpfile, 0);
|
||||
$final = fread($tmpfile, fstat($tmpfile)['size']);
|
||||
fclose($tmpfile);
|
||||
return $final;
|
||||
}
|
||||
|
||||
private function __iteratedFetch($user, &$params, &$loop, &$tmpfile, $exportTool, $exportToolParams) {
|
||||
$continue = true;
|
||||
while ($continue) {
|
||||
$this->Whitelist = ClassRegistry::init('Whitelist');
|
||||
$results = $this->fetchAttributes($user, $params, $continue);
|
||||
$params['page'] += 1;
|
||||
$results = $this->Whitelist->removeWhitelistedFromArray($results, true);
|
||||
$results = array_values($results);
|
||||
$i = 0;
|
||||
$temp = '';
|
||||
foreach ($results as $attribute) {
|
||||
$temp .= $exportTool->handler($attribute, $exportToolParams);
|
||||
if ($temp !== '') {
|
||||
if ($i != count($results) -1) {
|
||||
$temp .= $exportTool->separator($exportToolParams);
|
||||
}
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
if (!$loop) {
|
||||
$continue = false;
|
||||
}
|
||||
if ($continue) {
|
||||
$temp .= $exportTool->separator($exportToolParams);
|
||||
}
|
||||
fwrite($tmpfile, $temp);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -152,6 +152,17 @@ class Event extends AppModel
|
|||
),
|
||||
);
|
||||
|
||||
public $validFormats = array(
|
||||
'openioc' => array('xml', 'OpeniocExport', 'ioc'),
|
||||
'json' => array('json', 'JsonExport', 'json'),
|
||||
'xml' => array('xml', 'XmlExport', 'xml'),
|
||||
'suricata' => array('txt', 'NidsSuricataExport', 'rules'),
|
||||
'snort' => array('txt', 'NidsSnortExport', 'rules'),
|
||||
'rpz' => array('rpz', 'RPZExport', 'rpz'),
|
||||
'text' => array('text', 'TextExport', 'txt'),
|
||||
'csv' => array('csv', 'CsvExport', 'csv')
|
||||
);
|
||||
|
||||
public $csv_event_context_fields_to_fetch = array(
|
||||
'event_info' => array('object' => false, 'var' => 'info'),
|
||||
'event_member_org' => array('object' => 'Org', 'var' => 'name'),
|
||||
|
@ -5256,4 +5267,135 @@ class Event extends AppModel
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function restSearch($user, $returnFormat, $filters)
|
||||
{
|
||||
if (!isset($this->validFormats[$returnFormat][1])) {
|
||||
throw new NotFoundException('Invalid output format.');
|
||||
}
|
||||
App::uses($this->validFormats[$returnFormat][1], 'Export');
|
||||
$exportTool = new $this->validFormats[$returnFormat][1]();
|
||||
|
||||
if (empty($exportTool->non_restrictive_export)) {
|
||||
if (!isset($filters['to_ids'])) {
|
||||
$filters['to_ids'] = 1;
|
||||
}
|
||||
if (!isset($filters['published'])) {
|
||||
$filters['published'] = 1;
|
||||
}
|
||||
}
|
||||
if (isset($filters['ignore'])) {
|
||||
$filters['to_ids'] = array(0, 1);
|
||||
$filters['published'] = array(0, 1);
|
||||
}
|
||||
if (isset($filters['searchall'])) {
|
||||
$filters['tags'] = $filters['searchall'];
|
||||
$filters['eventinfo'] = $filters['searchall'];
|
||||
$filters['value'] = $filters['searchall'];
|
||||
$filters['comment'] = $filters['searchall'];
|
||||
}
|
||||
if (!empty($filters['quickfilter']) && !empty($filters['value'])) {
|
||||
$filters['tags'] = $filters['value'];
|
||||
$filters['eventinfo'] = $filters['value'];
|
||||
$filters['comment'] = $filters['value'];
|
||||
}
|
||||
$filters['include_attribute_count'] = 1;
|
||||
$eventid = $this->filterEventIds($user, $filters);
|
||||
$eventids_chunked = $this->__clusterEventIds($exportTool, $eventid);
|
||||
if (!empty($exportTool->additional_params)) {
|
||||
$filters = array_merge($filters, $exportTool->additional_params);
|
||||
}
|
||||
$exportToolParams = array(
|
||||
'user' => $user,
|
||||
'params' => array(),
|
||||
'returnFormat' => $returnFormat,
|
||||
'scope' => 'Event',
|
||||
'filters' => $filters
|
||||
);
|
||||
if (empty($exportTool->non_restrictive_export)) {
|
||||
if (!isset($filters['to_ids'])) {
|
||||
$filters['to_ids'] = 1;
|
||||
}
|
||||
if (!isset($filters['published'])) {
|
||||
$filters['published'] = 1;
|
||||
}
|
||||
}
|
||||
$tmpfile = tmpfile();
|
||||
fwrite($tmpfile, $exportTool->header($exportToolParams));
|
||||
$eventCount = count($eventid);
|
||||
$i = 0;
|
||||
if (!empty($filters['withAttachments'])) {
|
||||
$filters['includeAttachments'] = 1;
|
||||
}
|
||||
$this->Whitelist = ClassRegistry::init('Whitelist');
|
||||
foreach ($eventids_chunked as $chunk_index => $chunk) {
|
||||
$filters['eventid'] = $chunk;
|
||||
if (!empty($filters['tags']['NOT'])) {
|
||||
$filters['blockedAttributeTags'] = $filters['tags']['NOT'];
|
||||
}
|
||||
$result = $this->fetchEvent(
|
||||
$user,
|
||||
$filters,
|
||||
true
|
||||
);
|
||||
if (!empty($result)) {
|
||||
foreach ($result as $event) {
|
||||
$result = $this->Whitelist->removeWhitelistedFromArray($result, false);
|
||||
$temp = $exportTool->handler($event, $exportToolParams);
|
||||
if ($temp !== '') {
|
||||
if ($i !== 0) {
|
||||
$temp = $exportTool->separator($exportToolParams) . $temp;
|
||||
}
|
||||
fwrite($tmpfile, $temp);
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($result);
|
||||
unset($temp);
|
||||
fwrite($tmpfile, $exportTool->footer($exportToolParams));
|
||||
fseek($tmpfile, 0);
|
||||
$final = fread($tmpfile, fstat($tmpfile)['size']);
|
||||
fclose($tmpfile);
|
||||
return $final;
|
||||
}
|
||||
|
||||
/*
|
||||
* Receive a list of eventids in the id=>count format
|
||||
* Chunk them by the attribute count to fit the memory limits
|
||||
*
|
||||
*/
|
||||
private function __clusterEventIds($exportTool, $eventIds)
|
||||
{
|
||||
$memory_in_mb = $this->Attribute->convert_to_memory_limit_to_mb(ini_get('memory_limit'));
|
||||
$memory_scaling_factor = isset($exportTool->memory_scaling_factor) ? $exportTool->memory_scaling_factor : 100;
|
||||
$limit = $memory_in_mb * $memory_scaling_factor;
|
||||
$eventIdList = array();
|
||||
$continue = true;
|
||||
$i = 0;
|
||||
$current_chunk_size = 0;
|
||||
while (!empty($eventIds)) {
|
||||
foreach ($eventIds as $id => $count) {
|
||||
if ($current_chunk_size == 0 && $count > $limit) {
|
||||
$eventIdList[$i][] = $id;
|
||||
$current_chunk_size = $count;
|
||||
unset($eventIds[$id]);
|
||||
$i++;
|
||||
break;
|
||||
} else {
|
||||
if (($current_chunk_size + $count) > $limit) {
|
||||
$i++;
|
||||
$current_chunk_size = 0;
|
||||
break;
|
||||
} else {
|
||||
$current_chunk_size += $count;
|
||||
$eventIdList[$i][] = $id;
|
||||
unset($eventIds[$id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $eventIdList;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -865,14 +865,16 @@ class Feed extends AppModel
|
|||
}
|
||||
$temp = $this->getFreetextFeed($this->data, $HttpSocket, $this->data['Feed']['source_format'], 'all');
|
||||
$data = array();
|
||||
foreach ($temp as $key => $value) {
|
||||
$data[] = array(
|
||||
'category' => $value['category'],
|
||||
'type' => $value['default_type'],
|
||||
'value' => $value['value'],
|
||||
'to_ids' => $value['to_ids']
|
||||
);
|
||||
}
|
||||
if (!empty($temp)) {
|
||||
foreach ($temp as $key => $value) {
|
||||
$data[] = array(
|
||||
'category' => $value['category'],
|
||||
'type' => $value['default_type'],
|
||||
'value' => $value['value'],
|
||||
'to_ids' => $value['to_ids']
|
||||
);
|
||||
}
|
||||
}
|
||||
if ($jobId) {
|
||||
$job->saveField('progress', 50);
|
||||
$job->saveField('message', 'Saving data.');
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
<div class="popover_choice">
|
||||
<legend><?php echo __('Choose the format that you wish to download the search results in'); ?></legend>
|
||||
<div class="popover_choice_main" id ="popover_choice_main">
|
||||
<table style="width:100%;">
|
||||
<?php
|
||||
foreach ($exports as $k => $export) {
|
||||
$tr = 'style="border-bottom:1px solid black;" class="templateChoiceButton"';
|
||||
$td = sprintf(
|
||||
'class="" tabindex="0" title="%s" style="%s" data-type="%s"',
|
||||
__('Export as %s', h($export)),
|
||||
'padding-left:10px; text-align:center;width:100%;',
|
||||
h($export)
|
||||
);
|
||||
$div = '<div style="height:100%;width:100%;">' . h($export) . '</div>';
|
||||
$a = sprintf(
|
||||
'<a href="%s" style="%s" download>%s</a>',
|
||||
$baseurl . '/attributes/exportSearch/' . h($export),
|
||||
'color: black; text-decoration: none;',
|
||||
$div
|
||||
);
|
||||
$td = sprintf(
|
||||
'<td class="export_choice_button" tabindex="0" title="%s", style="%s">%s</td>',
|
||||
__('Export as %s', h($export)),
|
||||
'padding-left:10px; text-align:center;width:100%;',
|
||||
$a
|
||||
);
|
||||
echo sprintf('<tr %s>%s</tr>', $tr, $td);
|
||||
}
|
||||
?>
|
||||
</table>
|
||||
</div>
|
||||
<div role="button" tabindex="0" aria-label="<?php echo __('Cancel');?>" title="<?php echo __('Cancel');?>" class="templateChoiceButton templateChoiceButtonLast" onClick="cancelPopoverForm();"><?php echo __('Cancel');?></div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
resizePopoverBody();
|
||||
});
|
||||
|
||||
$(window).resize(function() {
|
||||
resizePopoverBody();
|
||||
});
|
||||
</script>
|
|
@ -4,15 +4,22 @@
|
|||
if ($isSearch == 1) {
|
||||
// The following block should serve as an example and food
|
||||
// for thought on how to optimize i18n & l10n (especially for languages that are not SOV)
|
||||
echo "<h4>" . __("Results for all attributes");
|
||||
if ($keywordSearch != null) echo __(" with the value containing "). "\"<b>" . h($keywordSearch) . "</b>\"";
|
||||
if ($attributeTags != null) echo __(" being tagged with ") ."\"<b>" . h($attributeTags) . "</b>\"";
|
||||
if ($keywordSearch2 != null) echo __(" from the events ") . "\"<b>" . h($keywordSearch2) . "</b>\"";
|
||||
if ($tags != null) echo " from events tagged \"<b>" . h($tags) . "</b>\"";
|
||||
if ($categorySearch != "ALL") echo __(" of category ") . "\"<b>" . h($categorySearch) . "</b>\"";
|
||||
if ($typeSearch != "ALL") echo __(" of type ") . "\"<b>" . h($typeSearch) . "</b>\"";
|
||||
if (isset($orgSearch) && $orgSearch != '' && $orgSearch != null) echo __(" created by the organisation ") . "\"<b>" . h($orgSearch) . "</b>\"";
|
||||
echo ":</h4>";
|
||||
$filterOptions = array(
|
||||
'value' => __(" with the value containing "),
|
||||
'tags' => __(" being tagged with "),
|
||||
'id' => __(" from the events "),
|
||||
'tag' => __(" carrying the tag(s) "),
|
||||
'type' => __(" of type "),
|
||||
'category' => __(" of category "),
|
||||
'org' => __(" created by organisation ")
|
||||
);
|
||||
$temp = '';
|
||||
foreach ($filterOptions as $fo => $text) {
|
||||
if (!empty($filters[$fo])) {
|
||||
$temp .= sprintf('%s <b>%s</b>', $text, h($filters[$fo]));
|
||||
}
|
||||
}
|
||||
echo sprintf("<h4>%s%s</h4>", __("Results for all attributes"), $temp);
|
||||
}
|
||||
?>
|
||||
<div class="pagination">
|
||||
|
@ -32,10 +39,10 @@
|
|||
</ul>
|
||||
</div>
|
||||
<table class="table table-striped table-hover table-condensed">
|
||||
<tr>
|
||||
<tr>
|
||||
<th><?php echo $this->Paginator->sort('event_id');?></th>
|
||||
<?php if (Configure::read('MISP.showorg') || $isAdmin): ?>
|
||||
<th><?php echo $this->Paginator->sort('org_id', 'Org');?></th>
|
||||
<th><?php echo $this->Paginator->sort('Event.orgc_id', 'Org');?></th>
|
||||
<?php endif; ?>
|
||||
<th><?php echo $this->Paginator->sort('category');?></th>
|
||||
<th><?php echo $this->Paginator->sort('type');?></th>
|
||||
|
@ -45,19 +52,20 @@
|
|||
<th<?php echo ' title="' . $attrDescriptions['signature']['desc'] . '"';?>>
|
||||
<?php echo $this->Paginator->sort('IDS');?></th>
|
||||
<th class="actions">Actions</th>
|
||||
</tr>
|
||||
</tr>
|
||||
<?php
|
||||
$currentCount = 0;
|
||||
if ($isSearch == 1) {
|
||||
|
||||
// sanitize data
|
||||
if (isset($keywordArray)) {
|
||||
foreach ($keywordArray as &$keywordArrayElement) {
|
||||
$keywordArrayElement = h($keywordArrayElement);
|
||||
}
|
||||
$toHighlight = array('value', 'comment');
|
||||
$keywordArray = array();
|
||||
foreach ($toHighlight as $highlightedElement) {
|
||||
if (!empty($filters[$highlightedElement])) {
|
||||
$keywordArray[] = $filters[$highlightedElement];
|
||||
}
|
||||
}
|
||||
// build the $replacePairs variable used to highlight the keywords
|
||||
$replacePairs = $this->Highlight->build_replace_pairs($keywordArray);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($attributes as $attribute):
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class="attributes form">
|
||||
<?php echo $this->Form->create('Attribute');?>
|
||||
<?php echo $this->Form->create('Attribute', array('url' => array('controller' => 'attributes', 'action' => 'search', 'results')));?>
|
||||
<fieldset>
|
||||
<legend><?php echo __('Search Attribute'); ?></legend>
|
||||
<?php echo __('You can search for attributes based on contained expression within the value, event ID, submitting organisation, category and type. <br />For the value, event ID and organisation, you can enter several search terms by entering each term as a new line. To exclude things from a result, use the NOT operator (!) in front of the term.'); ?>
|
||||
|
@ -7,43 +7,36 @@
|
|||
<?php echo __('For string searches (such as searching for an expression, tags, etc) - lookups are simple string matches. If you want a substring match encapsulate the lookup string between "%" characters.'); ?>
|
||||
<br /><br />
|
||||
<?php
|
||||
echo $this->Form->input('keyword', array('type' => 'textarea', 'rows' => 2, 'label' => __('Containing the following expressions'), 'div' => 'clear', 'class' => 'input-xxlarge'));
|
||||
echo $this->Form->input('attributetags', array('type' => 'textarea', 'rows' => 2, 'label' => __('Being an attribute matching the following tags'), 'div' => 'clear', 'class' => 'input-xxlarge'));
|
||||
echo $this->Form->input('keyword2', array('type' => 'textarea', 'rows' => 2, 'label' => __('Being attributes of the following event IDs, event UUIDs or attribute UUIDs'), 'div' => 'clear', 'class' => 'input-xxlarge'));
|
||||
echo $this->Form->input('tags', array('type' => 'textarea', 'rows' => 2, 'label' => __('Being an attribute of an event matching the following tags'), 'div' => 'clear', 'class' => 'input-xxlarge'));
|
||||
|
||||
?>
|
||||
<?php
|
||||
if (Configure::read('MISP.showorg') || $isAdmin)
|
||||
echo $this->Form->input('org', array(
|
||||
'type' => 'textarea',
|
||||
'label' => __('From the following organisation(s)'),
|
||||
'div' => 'input clear',
|
||||
'rows' => 2,
|
||||
'class' => 'input-xxlarge'));
|
||||
?>
|
||||
<?php
|
||||
echo $this->Form->input('type', array(
|
||||
echo $this->Form->input('value', array('type' => 'textarea', 'rows' => 2, 'label' => __('Containing the following expressions'), 'div' => 'clear', 'class' => 'input-xxlarge', 'required' => false));
|
||||
echo $this->Form->input('tags', array('type' => 'textarea', 'rows' => 2, 'label' => __('Having tag or being an attribute of an event having the tag'), 'div' => 'clear', 'class' => 'input-xxlarge', 'required' => false));
|
||||
echo $this->Form->input('uuid', array('type' => 'textarea', 'rows' => 2, 'maxlength' => false, 'label' => __('Being attributes of the following event IDs, event UUIDs or attribute UUIDs'), 'div' => 'clear', 'class' => 'input-xxlarge', 'required' => false));
|
||||
echo $this->Form->input('org', array(
|
||||
'type' => 'textarea',
|
||||
'label' => __('From the following organisation(s)'),
|
||||
'div' => 'input clear',
|
||||
));
|
||||
echo $this->Form->input('category', array(
|
||||
));
|
||||
'rows' => 2,
|
||||
'class' => 'input-xxlarge'));
|
||||
echo $this->Form->input('type', array(
|
||||
'div' => 'input clear',
|
||||
'required' => false
|
||||
));
|
||||
echo $this->Form->input('category', array('required' => false));
|
||||
?>
|
||||
<div class="input clear"></div>
|
||||
<?php
|
||||
echo $this->Form->input('ioc', array(
|
||||
echo $this->Form->input('to_ids', array(
|
||||
'type' => 'checkbox',
|
||||
'label' => __('Only find IOCs to use in IDS'),
|
||||
'label' => __('Only find IOCs flagged as to_ids')
|
||||
));
|
||||
echo $this->Form->input('alternate', array(
|
||||
'type' => 'checkbox',
|
||||
'label' => __('Alternate Search Result (Events)'),
|
||||
'label' => __('Alternate Search Result (Events)')
|
||||
));
|
||||
?>
|
||||
</fieldset>
|
||||
<?php
|
||||
echo $this->Form->button('Search', array('class' => 'btn btn-primary'));
|
||||
echo $this->Form->end();
|
||||
echo $this->Form->button('Search', array('class' => 'btn btn-primary'));
|
||||
echo $this->Form->end();
|
||||
?>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
|
@ -208,5 +201,5 @@ $('.input-xxlarge').keydown(function (e) {
|
|||
</script>
|
||||
<?php
|
||||
echo $this->element('side_menu', array('menuList' => 'event-collection', 'menuItem' => 'searchAttributes'));
|
||||
echo $this->Js->writeBuffer();
|
||||
?>
|
||||
<?php echo $this->Js->writeBuffer(); // Write cached scripts ?>
|
||||
|
|
|
@ -219,18 +219,13 @@
|
|||
));
|
||||
if ($menuItem == 'searchAttributes2') {
|
||||
echo $this->element('/side_menu_divider');
|
||||
echo $this->element('/side_menu_link', array(
|
||||
'url' => '/events/downloadSearchResult.json',
|
||||
'text' => __('Download results as JSON')
|
||||
));
|
||||
echo $this->element('/side_menu_link', array(
|
||||
'url' => '/events/downloadSearchResult.xml',
|
||||
'text' => __('Download results as XML')
|
||||
));
|
||||
echo $this->element('/side_menu_link', array(
|
||||
'url' => '/events/csv/download/search',
|
||||
'text' => __('Download results as CSV')
|
||||
));
|
||||
echo $this->element('/side_menu_link', array(
|
||||
'onClick' => array(
|
||||
'function' => 'getPopup',
|
||||
'params' => array(0, 'attributes', 'exportSearch')
|
||||
),
|
||||
'text' => __('Download as...')
|
||||
));
|
||||
}
|
||||
echo $this->element('/side_menu_divider');
|
||||
echo $this->element('/side_menu_link', array(
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 2402c7d98f0ab23f065ae00d3d34ab6610e9a3e9
|
||||
Subproject commit ecba2dbdbf233d330c2bba7fecd569d31a3ca576
|
Loading…
Reference in New Issue