mirror of https://github.com/MISP/MISP
Merge branch 'feature/api_rework2' into 2.4
commit
5f1edc9bad
|
@ -52,6 +52,7 @@ class AppController extends Controller
|
|||
public $phprec = '7.0.16';
|
||||
|
||||
public $baseurl = '';
|
||||
public $sql_dump = false;
|
||||
|
||||
// Used for _isAutomation(), a check that returns true if the controller & action combo matches an action that is a non-xml and non-json automation method
|
||||
// This is used to allow authentication via headers for methods not covered by _isRest() - as that only checks for JSON and XML formats
|
||||
|
@ -101,6 +102,9 @@ class AppController extends Controller
|
|||
|
||||
public function beforeFilter()
|
||||
{
|
||||
if (!empty($this->params['named']['sql'])) {
|
||||
$this->sql_dump = 1;
|
||||
}
|
||||
// check for a supported datasource configuration
|
||||
$dataSourceConfig = ConnectionManager::getDataSource('default')->config;
|
||||
if (!isset($dataSourceConfig['encoding'])) {
|
||||
|
@ -435,6 +439,14 @@ class AppController extends Controller
|
|||
$this->ACL->checkAccess($this->Auth->user(), Inflector::variable($this->request->params['controller']), $this->action);
|
||||
}
|
||||
|
||||
public function afterFilter()
|
||||
{
|
||||
if (Configure::read('debug') > 1 && !empty($this->sql_dump) && $this->_isRest()) {
|
||||
$this->Log = ClassRegistry::init('Log');
|
||||
echo json_encode($this->Log->getDataSource()->getLog(false, false), JSON_PRETTY_PRINT);
|
||||
}
|
||||
}
|
||||
|
||||
public function queryACL($debugType='findMissingFunctionNames', $content = false)
|
||||
{
|
||||
$this->autoRender = false;
|
||||
|
|
|
@ -118,7 +118,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'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -775,7 +775,7 @@ class AttributesController extends AppController
|
|||
// 1/ iterate over all the sources, unique
|
||||
// 2/ add uniques as 'Internal reference'
|
||||
// 3/ if url format -> 'link'
|
||||
// else 'comment'
|
||||
// else 'comment'
|
||||
$references = array();
|
||||
foreach ($entries as $entry) {
|
||||
if (empty($entry['Source'])) {
|
||||
|
@ -2083,101 +2083,92 @@ class AttributesController extends AppController
|
|||
}
|
||||
|
||||
public function restSearch($returnFormat = 'json', $value = false, $type = false, $category = false, $org = false, $tags = false, $from = false, $to = false, $last = false, $eventid = false, $withAttachments = false, $uuid = false, $publish_timestamp = false, $published = false, $timestamp = false, $enforceWarninglist = false, $to_ids = false, $deleted = false, $includeEventUuid = false, $event_timestamp = false, $threat_level_id = false) {
|
||||
$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');
|
||||
$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) {
|
||||
$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');
|
||||
$filterData = array(
|
||||
'request' => $this->request,
|
||||
'named_params' => $this->params['named'],
|
||||
'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')
|
||||
);
|
||||
$exception = false;
|
||||
$filters = $this->_harvestParameters($filterData, $exception);
|
||||
unset($filterData);
|
||||
if ($filters === false) {
|
||||
return $exception;
|
||||
}
|
||||
$list = array();
|
||||
$user = $this->_getApiAuthUser($returnFormat, $exception);
|
||||
if ($user === false) {
|
||||
}
|
||||
$list = array();
|
||||
$user = $this->_getApiAuthUser($returnFormat, $exception);
|
||||
if ($user === false) {
|
||||
return $exception;
|
||||
}
|
||||
if (isset($filters['returnFormat'])) {
|
||||
}
|
||||
if (isset($filters['returnFormat'])) {
|
||||
$returnFormat = $filters['returnFormat'];
|
||||
} else {
|
||||
$returnFormat = 'json';
|
||||
}
|
||||
$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,
|
||||
);
|
||||
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);
|
||||
}
|
||||
}
|
||||
$results = $this->Attribute->fetchAttributes($this->Auth->user(), $params);
|
||||
$this->loadModel('Whitelist');
|
||||
$results = $this->Whitelist->removeWhitelistedFromArray($results, true);
|
||||
$validFormats = array(
|
||||
'openioc' => 'OpeniocExport',
|
||||
'json' => 'AttributeExport',
|
||||
'xml' => 'AttributeExport'
|
||||
);
|
||||
$final = '';
|
||||
App::uses($validFormats[$returnFormat], 'Export');
|
||||
$exportTool = new $validFormats[$returnFormat]();
|
||||
$exportToolParams = array(
|
||||
'user' => $this->Auth->user(),
|
||||
'params' => $params,
|
||||
'returnFormat' => $returnFormat
|
||||
);
|
||||
$final .= $exportTool->header($exportToolParams);
|
||||
$results = array_values($results);
|
||||
foreach ($results as $k => $attribute) {
|
||||
$final .= $exportTool->handler($attribute, $exportToolParams);
|
||||
if ($k <= count($results)) {
|
||||
$final .= $exportTool->separator($exportToolParams);
|
||||
}
|
||||
$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,
|
||||
);
|
||||
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);
|
||||
}
|
||||
}
|
||||
App::uses($validFormats[$returnFormat][1], 'Export');
|
||||
$exportTool = new $validFormats[$returnFormat][1]();
|
||||
$exportToolParams = array(
|
||||
'user' => $this->Auth->user(),
|
||||
'params' => $params,
|
||||
'returnFormat' => $returnFormat,
|
||||
'scope' => 'Attribute'
|
||||
);
|
||||
if (!empty($exportTool->additional_params)) {
|
||||
$params = array_merge($params, $exportTool->additional_params);
|
||||
}
|
||||
}
|
||||
$final .= $exportTool->footer($exportToolParams);
|
||||
/*
|
||||
if ($returnFormat == 'openioc') {
|
||||
App::uses('IOCExportTool', 'Tools');
|
||||
$this->IOCExport = new IOCExportTool();
|
||||
$results = $this->IOCExport->buildAll($this->Auth->user(), $results, 'attribute');
|
||||
} else {
|
||||
if (!empty($results)) {
|
||||
$results = array('response' => array('Attribute' => $results));
|
||||
foreach ($results['response']['Attribute'] as $k => $v) {
|
||||
if (isset($results['response']['Attribute'][$k]['AttributeTag'])) {
|
||||
foreach ($results['response']['Attribute'][$k]['AttributeTag'] as $tk => $tag) {
|
||||
$results['response']['Attribute'][$k]['Attribute']['Tag'][$tk] = $tag['Tag'];
|
||||
}
|
||||
}
|
||||
$results['response']['Attribute'][$k] = $results['response']['Attribute'][$k]['Attribute'];
|
||||
unset(
|
||||
$results['response']['Attribute'][$k]['value1'],
|
||||
$results['response']['Attribute'][$k]['value2']
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$results = array('response' => array('Attribute' => array()));
|
||||
}
|
||||
}
|
||||
*/
|
||||
$responseType = $this->response->type();
|
||||
if ($returnFormat == 'openioc') {
|
||||
$responseType = 'openioc';
|
||||
}
|
||||
return $this->RestResponse->viewData($final, $responseType, false, true);
|
||||
$final = '';
|
||||
$final .= $exportTool->header($exportToolParams);
|
||||
$continue = false;
|
||||
if (empty($params['limit'])) {
|
||||
$params['limit'] = 10000;
|
||||
$continue = true;
|
||||
$params['page'] = 1;
|
||||
}
|
||||
$this->loadModel('Whitelist');
|
||||
while ($continue) {
|
||||
$results = $this->Attribute->fetchAttributes($this->Auth->user(), $params, $continue);
|
||||
$params['page'] += 1;
|
||||
$results = $this->Whitelist->removeWhitelistedFromArray($results, true);
|
||||
$results = array_values($results);
|
||||
$i = 0;
|
||||
foreach ($results as $attribute) {
|
||||
$temp = $exportTool->handler($attribute, $exportToolParams);
|
||||
if ($temp !== '') {
|
||||
$final .= $temp;
|
||||
if ($i != count($results) -1) {
|
||||
$final .= $exportTool->separator($exportToolParams);
|
||||
}
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
$final .= $exportTool->footer($exportToolParams);
|
||||
$responseType = $validFormats[$returnFormat][0];
|
||||
return $this->RestResponse->viewData($final, $responseType, false, 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.
|
||||
|
@ -2229,7 +2220,7 @@ class AttributesController extends AppController
|
|||
throw new UnauthorizedException(__('You don\'t have access to that event.'));
|
||||
}
|
||||
}
|
||||
$this->response->type('xml'); // set the content type
|
||||
$this->response->type('xml'); // set the content type
|
||||
$this->layout = 'xml/default';
|
||||
$this->header('Content-Disposition: download; filename="misp.search.attribute.results.xml"');
|
||||
// check if user can see the event!
|
||||
|
@ -2364,7 +2355,7 @@ class AttributesController extends AppController
|
|||
throw new UnauthorizedException(__('You have to be logged in to do that.'));
|
||||
}
|
||||
}
|
||||
$this->response->type('txt'); // set the content type
|
||||
$this->response->type('txt'); // set the content type
|
||||
$this->header('Content-Disposition: download; filename="misp.' . (is_array($type) ? 'multi' : $type) . '.txt"');
|
||||
$this->layout = 'text/default';
|
||||
$attributes = $this->Attribute->text($this->Auth->user(), $type, $tags, $eventId, $allowNonIDS, $from, $to, $last, $enforceWarninglist, $allowNotPublished);
|
||||
|
@ -2458,7 +2449,7 @@ class AttributesController extends AppController
|
|||
foreach ($eventIds as $k => $eventId) {
|
||||
$values = array_merge_recursive($values, $this->Attribute->rpz($this->Auth->user(), $tags, $eventId, $from, $to, $enforceWarninglist));
|
||||
}
|
||||
$this->response->type('txt'); // set the content type
|
||||
$this->response->type('txt'); // set the content type
|
||||
$file = '';
|
||||
if ($tags) {
|
||||
$file = 'filtered.';
|
||||
|
|
|
@ -1635,15 +1635,9 @@ class ServersController extends AppController
|
|||
private function __doRestQuery($request)
|
||||
{
|
||||
App::uses('SyncTool', 'Tools');
|
||||
$params = array(
|
||||
|
||||
);
|
||||
$params = array();
|
||||
if (!empty($request['url'])) {
|
||||
$path = parse_url($request['url'], PHP_URL_PATH);
|
||||
$query = parse_url($request['url'], PHP_URL_QUERY);
|
||||
if (!empty($query)) {
|
||||
$path .= '?' . $query;
|
||||
}
|
||||
$path = preg_replace('#^(://|[^/?])+#', '', $request['url']);
|
||||
$url = Configure::read('MISP.baseurl') . '/' . $path;
|
||||
} else {
|
||||
throw new InvalidArgumentException('Url not set.');
|
||||
|
|
|
@ -1,10 +1,23 @@
|
|||
<?php
|
||||
|
||||
class AttributeExport
|
||||
class JsonExport
|
||||
{
|
||||
|
||||
public function handler($attribute, $options = array())
|
||||
public function handler($data, $options = array())
|
||||
{
|
||||
if ($options['scope'] === 'Attribute') {
|
||||
return $this->__attributeHandler($data, $options);
|
||||
} else {
|
||||
return $this->__eventHandler($data, $options);
|
||||
}
|
||||
}
|
||||
|
||||
private function __attributeHandler($attribute, $options = array())
|
||||
{
|
||||
$attribute = array_merge($attribute['Attribute'], $attribute);
|
||||
unset($attribute['Attribute']);
|
||||
if (isset($attribute['Object']) && empty($attribute['Object']['id'])) {
|
||||
unset($attribute['Object']);
|
||||
}
|
||||
if (isset($attribute['AttributeTag'])) {
|
||||
$attributeTags = array();
|
||||
foreach ($attribute['AttributeTag'] as $tk => $tag) {
|
||||
|
@ -15,7 +28,7 @@ class AttributeExport
|
|||
unset($attribute['value2']);
|
||||
}
|
||||
return json_encode($attribute);
|
||||
}
|
||||
}
|
||||
|
||||
public function header($options = array())
|
||||
{
|
||||
|
@ -29,7 +42,7 @@ class AttributeExport
|
|||
|
||||
public function separator()
|
||||
{
|
||||
return ',' . PHP_EOL;
|
||||
return ',';
|
||||
}
|
||||
|
||||
}
|
|
@ -8,6 +8,49 @@ class NidsExport
|
|||
|
||||
public $format = ""; // suricata (default), snort
|
||||
|
||||
public $checkWhitelist = true;
|
||||
|
||||
public $additional_params = array(
|
||||
'contain' => array(
|
||||
'Event' => array(
|
||||
'fields' => array('threat_level_id')
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
public function handler($data, $options = array())
|
||||
{
|
||||
$continue = true;
|
||||
$this->checkWhitelist = false;
|
||||
if (empty($this->rules)) {
|
||||
$continue = false;
|
||||
}
|
||||
if ($options['scope'] === 'Attribute') {
|
||||
$this->export(
|
||||
array($data),
|
||||
$options['user']['nids_sid'],
|
||||
$options['returnFormat'],
|
||||
$continue
|
||||
);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
public function header($options = array())
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function footer()
|
||||
{
|
||||
return implode ("\n", $this->rules);
|
||||
}
|
||||
|
||||
public function separator()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function explain()
|
||||
{
|
||||
$this->rules[] = '# MISP export of IDS rules - optimized for '.$this->format;
|
||||
|
@ -28,8 +71,10 @@ class NidsExport
|
|||
public function export($items, $startSid, $format="suricata", $continue = false)
|
||||
{
|
||||
$this->format = $format;
|
||||
$this->Whitelist = ClassRegistry::init('Whitelist');
|
||||
$this->whitelist = $this->Whitelist->getBlockedValues();
|
||||
if ($this->checkWhitelist && !isset($this->Whitelist)) {
|
||||
$this->Whitelist = ClassRegistry::init('Whitelist');
|
||||
$this->whitelist = $this->Whitelist->getBlockedValues();
|
||||
}
|
||||
|
||||
// output a short explanation
|
||||
if (!$continue) {
|
||||
|
@ -105,7 +150,7 @@ class NidsExport
|
|||
}
|
||||
return $this->rules;
|
||||
}
|
||||
|
||||
|
||||
public function domainIpRule($ruleFormat, $attribute, &$sid)
|
||||
{
|
||||
$values = explode('|', $attribute['value']);
|
||||
|
@ -558,11 +603,13 @@ class NidsExport
|
|||
|
||||
public function checkWhitelist($value)
|
||||
{
|
||||
foreach ($this->whitelist as $wlitem) {
|
||||
if (preg_match($wlitem, $value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if ($this->checkWhitelist) {
|
||||
foreach ($this->whitelist as $wlitem) {
|
||||
if (preg_match($wlitem, $value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
class TextExport
|
||||
{
|
||||
public function handler($data, $options = array())
|
||||
{
|
||||
if ($options['scope'] === 'Attribute') {
|
||||
return $data['Attribute']['value'];
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
public function header($options = array())
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function footer()
|
||||
{
|
||||
return "\n";
|
||||
}
|
||||
|
||||
public function separator()
|
||||
{
|
||||
return "\n";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
class XmlExport
|
||||
{
|
||||
public function handler($data, $options = array())
|
||||
{
|
||||
if ($options['scope'] === 'Attribute') {
|
||||
return $this->__attributeHandler($data, $options);
|
||||
} else {
|
||||
return $this->__eventHandler($data, $options);
|
||||
}
|
||||
}
|
||||
|
||||
private function __attributeHandler($attribute, $options = array())
|
||||
{
|
||||
$attribute = array_merge($attribute['Attribute'], $attribute);
|
||||
unset($attribute['Event']);
|
||||
unset($attribute['Attribute']);
|
||||
if (isset($attribute['Object']) && empty($attribute['Object']['id'])) {
|
||||
unset($attribute['Object']);
|
||||
}
|
||||
if (isset($attribute['AttributeTag'])) {
|
||||
$attributeTags = array();
|
||||
foreach ($attribute['AttributeTag'] as $tk => $tag) {
|
||||
$attribute['Tag'][$tk] = $attribute['AttributeTag'][$tk]['Tag'];
|
||||
}
|
||||
unset($attribute['AttributeTag']);
|
||||
unset($attribute['value1']);
|
||||
unset($attribute['value2']);
|
||||
}
|
||||
$xmlObject = Xml::fromArray(array('Attribute' => $attribute), array('format' => 'tags'));
|
||||
$xmlString = $xmlObject->asXML();
|
||||
return substr($xmlString, strpos($xmlString, "\n") + 1);
|
||||
}
|
||||
|
||||
public function header($options = array())
|
||||
{
|
||||
return '<?xml version="1.0" encoding="UTF-8"?>' . PHP_EOL . '<response>';
|
||||
}
|
||||
|
||||
public function footer()
|
||||
{
|
||||
return '</response>' . PHP_EOL;
|
||||
}
|
||||
|
||||
public function separator()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
class XMLConverterTool
|
||||
{
|
||||
private $__toEscape = array("&", "<", ">", "\"", "'");
|
||||
|
|
|
@ -2784,8 +2784,6 @@ class Attribute extends AppModel
|
|||
}
|
||||
if (isset($options['limit'])) {
|
||||
$params['limit'] = $options['limit'];
|
||||
} else {
|
||||
$option['contain']['Event']['fields'] = array('id', 'info', 'org_id', 'orgc_id');
|
||||
}
|
||||
if (Configure::read('MISP.proposals_block_attributes') && isset($options['conditions']['AND']['Attribute.to_ids']) && $options['conditions']['AND']['Attribute.to_ids'] == 1) {
|
||||
$this->bindModel(array('hasMany' => array('ShadowAttribute' => array('foreignKey' => 'old_id'))));
|
||||
|
|
|
@ -17,6 +17,8 @@ class Whitelist extends AppModel
|
|||
),
|
||||
);
|
||||
|
||||
public $whitelistedItems = false;
|
||||
|
||||
public $validate = array(
|
||||
'name' => array(
|
||||
'valueNotEmpty' => array(
|
||||
|
@ -66,12 +68,14 @@ class Whitelist extends AppModel
|
|||
|
||||
public function getBlockedValues()
|
||||
{
|
||||
$Whitelists = $this->find('all', array('fields' => array('name')));
|
||||
$toReturn = array();
|
||||
foreach ($Whitelists as $item) {
|
||||
$toReturn[] = $item['Whitelist']['name'];
|
||||
}
|
||||
return $toReturn;
|
||||
if ($this->whitelistedItems !== false) {
|
||||
$Whitelists = $this->find('all', array('fields' => array('name')));
|
||||
$this->whitelistedItems = array();
|
||||
foreach ($Whitelists as $item) {
|
||||
$this->whitelistedItems[] = $item['Whitelist']['name'];
|
||||
}
|
||||
}
|
||||
return $this->whitelistedItems;
|
||||
}
|
||||
|
||||
public function removeWhitelistedFromArray($data, $isAttributeArray)
|
||||
|
|
Loading…
Reference in New Issue