mirror of https://github.com/MISP/MISP
Merge branch 'develop' of github.com:MISP/MISP into develop
commit
2e815627db
|
@ -49,14 +49,6 @@ class AppController extends Controller
|
|||
|
||||
public $restResponsePayload = null;
|
||||
|
||||
// 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
|
||||
public $automationArray = array(
|
||||
'events' => array('csv', 'nids', 'hids', 'xml', 'restSearch', 'stix', 'updateGraph', 'downloadOpenIOCEvent'),
|
||||
'attributes' => array('text', 'downloadAttachment', 'returnAttributes', 'restSearch', 'rpz', 'bro'),
|
||||
'objects' => array('restSearch')
|
||||
);
|
||||
|
||||
protected $_legacyParams = array();
|
||||
/** @var array */
|
||||
public $userRole;
|
||||
|
|
|
@ -10,6 +10,14 @@ class IndexFilterComponent extends Component
|
|||
public $Controller;
|
||||
public $isRest = null;
|
||||
|
||||
// Used for isApiFunction(), 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
|
||||
const AUTOMATION_ARRAY = array(
|
||||
'events' => array('csv', 'nids', 'hids', 'xml', 'restSearch', 'stix', 'updateGraph', 'downloadOpenIOCEvent'),
|
||||
'attributes' => array('text', 'downloadAttachment', 'returnAttributes', 'restSearch', 'rpz', 'bro'),
|
||||
'objects' => array('restSearch'),
|
||||
);
|
||||
|
||||
public function initialize(Controller $controller)
|
||||
{
|
||||
$this->Controller = $controller;
|
||||
|
@ -121,6 +129,6 @@ class IndexFilterComponent extends Component
|
|||
*/
|
||||
public function isApiFunction($controller, $action)
|
||||
{
|
||||
return isset($this->Controller->automationArray[$controller]) && in_array($action, $this->Controller->automationArray[$controller], true);
|
||||
return isset(self::AUTOMATION_ARRAY[$controller]) && in_array($action, self::AUTOMATION_ARRAY[$controller], true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
class NidsExport
|
||||
abstract class NidsExport
|
||||
{
|
||||
public $rules = array();
|
||||
|
||||
|
@ -858,15 +858,16 @@ class NidsExport
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $attribute
|
||||
* @return array|string[]
|
||||
*/
|
||||
public static function getIpPort($attribute)
|
||||
{
|
||||
$ipport = array();
|
||||
if (strpos($attribute['type'], 'port') !== false) {
|
||||
$ipport = explode('|', $attribute['value']);
|
||||
return explode('|', $attribute['value']);
|
||||
} else {
|
||||
$ipport[0] = $attribute['value'];
|
||||
$ipport[1] = 'any';
|
||||
return [$attribute['value'], 'any'];
|
||||
}
|
||||
return $ipport;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -635,11 +635,14 @@ class AttributeValidationTool
|
|||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param string $value
|
||||
* @return bool
|
||||
*/
|
||||
private static function isSsdeep($value)
|
||||
{
|
||||
if (strpos($value, "\n") !== false) {
|
||||
return false;
|
||||
}
|
||||
$parts = explode(':', $value);
|
||||
if (count($parts) !== 3) {
|
||||
return false;
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
<?php
|
||||
class ColourPaletteTool
|
||||
{
|
||||
|
||||
// pass the number of distinct colours to receive an array of colours
|
||||
/**
|
||||
* @param int $count Pass the number of distinct colours to receive an array of colours
|
||||
* @return array
|
||||
*/
|
||||
public function createColourPalette($count)
|
||||
{
|
||||
$interval = 1 / $count;
|
||||
|
@ -13,6 +15,10 @@ class ColourPaletteTool
|
|||
return $colours;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $hsv
|
||||
* @return string
|
||||
*/
|
||||
public function HSVtoRGB(array $hsv)
|
||||
{
|
||||
list($H, $S, $V) = $hsv;
|
||||
|
@ -50,12 +56,16 @@ class ColourPaletteTool
|
|||
return $this->convertToHex(array($R, $G, $B));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $channels
|
||||
* @return string
|
||||
*/
|
||||
public function convertToHex($channels)
|
||||
{
|
||||
$colour = '#';
|
||||
foreach ($channels as $channel) {
|
||||
$channel = strval(dechex(round($channel*255)));
|
||||
if (strlen($channel) == 1) {
|
||||
$channel = dechex(round($channel*255));
|
||||
if (strlen($channel) === 1) {
|
||||
$channel = '0' . $channel;
|
||||
}
|
||||
$colour .= $channel;
|
||||
|
|
|
@ -24,7 +24,7 @@ class SendEmailTemplate
|
|||
/**
|
||||
* This value will be used for grouping emails in mail client.
|
||||
* @param string|null $referenceId
|
||||
* @return string
|
||||
* @return string|void
|
||||
*/
|
||||
public function referenceId($referenceId = null)
|
||||
{
|
||||
|
@ -49,7 +49,7 @@ class SendEmailTemplate
|
|||
/**
|
||||
* Get subject from template. Must be called after render method.
|
||||
* @param string|null $subject
|
||||
* @return string
|
||||
* @return string|void
|
||||
*/
|
||||
public function subject($subject = null)
|
||||
{
|
||||
|
@ -84,7 +84,6 @@ class SendEmailTemplate
|
|||
$View->set($this->viewVars);
|
||||
$View->set('hideDetails', $hideDetails);
|
||||
|
||||
$View->viewPath = $View->layoutPath = 'Emails' . DS . 'html';
|
||||
try {
|
||||
$View->viewPath = $View->layoutPath = 'Emails' . DS . 'html' . DS . 'Custom';
|
||||
$html = $View->render($this->viewName); // Attempt to load a custom template if it exists
|
||||
|
@ -93,7 +92,7 @@ class SendEmailTemplate
|
|||
try {
|
||||
$html = $View->render($this->viewName);
|
||||
} catch (MissingViewException $e) {
|
||||
$html = null; // HTMl template is optional
|
||||
$html = null; // HTML template is optional
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ class TrendingTool
|
|||
}
|
||||
$allTags[$tag] = true;
|
||||
$trendAnalysis[$timestamp][$tag] = [
|
||||
'occurence' => round($amount / $eventNumberPerRollingWindow[$timestamp], 2),
|
||||
'occurrence' => round($amount / $eventNumberPerRollingWindow[$timestamp], 2),
|
||||
'raw_change' => $rawChange,
|
||||
'percent_change' => $percentChange,
|
||||
'change_sign' => $rawChange > 0 ? 1 : ($rawChange < 0 ? -1 : 0),
|
||||
|
@ -54,9 +54,9 @@ class TrendingTool
|
|||
foreach (array_keys($trendAnalysis[$timestamp]) as $tag) {
|
||||
if (empty($trendAnalysis[$previousTimestamp][$tag])) {
|
||||
$trendAnalysis[$previousTimestamp][$tag] = [
|
||||
'occurence' => 0,
|
||||
'occurrence' => 0,
|
||||
'raw_change' => -$amount,
|
||||
'percent_change' => 100 * (-$amount / $amount),
|
||||
'percent_change' => round(100 * (-$amount / $amount), 2),
|
||||
'change_sign' => -$amount > 0 ? 1 : (-$amount < 0 ? -1 : 0),
|
||||
];
|
||||
}
|
||||
|
|
|
@ -2622,7 +2622,7 @@ class AppModel extends Model
|
|||
return $remainingTime > 0 || $failThresholdReached;
|
||||
}
|
||||
|
||||
public function getUpdateFailNumber()
|
||||
private function getUpdateFailNumber()
|
||||
{
|
||||
$this->AdminSetting = ClassRegistry::init('AdminSetting');
|
||||
$updateFailNumber = $this->AdminSetting->getSetting('update_fail_number');
|
||||
|
@ -2635,7 +2635,7 @@ class AppModel extends Model
|
|||
$this->AdminSetting->changeSetting('update_fail_number', 0);
|
||||
}
|
||||
|
||||
public function __increaseUpdateFailNumber()
|
||||
private function __increaseUpdateFailNumber()
|
||||
{
|
||||
$this->AdminSetting = ClassRegistry::init('AdminSetting');
|
||||
$updateFailNumber = $this->AdminSetting->getSetting('update_fail_number');
|
||||
|
@ -2737,7 +2737,7 @@ class AppModel extends Model
|
|||
return true;
|
||||
}
|
||||
|
||||
public function removeDuplicatedUUIDs()
|
||||
private function removeDuplicatedUUIDs()
|
||||
{
|
||||
$removedResults = array(
|
||||
'Event' => $this->removeDuplicateEventUUIDs(),
|
||||
|
@ -2782,7 +2782,7 @@ class AppModel extends Model
|
|||
return $counter;
|
||||
}
|
||||
|
||||
public function removeDuplicateAttributeUUIDs()
|
||||
private function removeDuplicateAttributeUUIDs()
|
||||
{
|
||||
$this->Attribute = ClassRegistry::init('Attribute');
|
||||
$this->Log = ClassRegistry::init('Log');
|
||||
|
@ -2836,7 +2836,7 @@ class AppModel extends Model
|
|||
return $counter;
|
||||
}
|
||||
|
||||
public function removeDuplicateEventUUIDs()
|
||||
private function removeDuplicateEventUUIDs()
|
||||
{
|
||||
$this->Event = ClassRegistry::init('Event');
|
||||
$this->Log = ClassRegistry::init('Log');
|
||||
|
|
|
@ -1024,163 +1024,6 @@ class Attribute extends AppModel
|
|||
return $data;
|
||||
}
|
||||
|
||||
public function hids($user, $type, $tags = '', $from = false, $to = false, $last = false, $jobId = false, $enforceWarninglist = false)
|
||||
{
|
||||
if (empty($user)) {
|
||||
throw new MethodNotAllowedException(__('Could not read user.'));
|
||||
}
|
||||
// check if it's a valid type
|
||||
if ($type != 'md5' && $type != 'sha1' && $type != 'sha256') {
|
||||
throw new UnauthorizedException(__('Invalid hash type.'));
|
||||
}
|
||||
$conditions = array();
|
||||
$typeArray = array($type, 'filename|' . $type);
|
||||
if ($type == 'md5') {
|
||||
$typeArray[] = 'malware-sample';
|
||||
}
|
||||
$rules = array();
|
||||
$eventIds = $this->Event->fetchEventIds($user, [
|
||||
'from' => $from,
|
||||
'to' => $to,
|
||||
'last' => $last
|
||||
]);
|
||||
if (!empty($tags)) {
|
||||
$tag = ClassRegistry::init('Tag');
|
||||
$args = $this->dissectArgs($tags);
|
||||
$tagArray = $tag->fetchEventTagIds($args[0], $args[1]);
|
||||
if (!empty($tagArray[0])) {
|
||||
foreach ($eventIds as $k => $v) {
|
||||
if (!in_array($v['Event']['id'], $tagArray[0])) {
|
||||
unset($eventIds[$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($tagArray[1])) {
|
||||
foreach ($eventIds as $k => $v) {
|
||||
if (in_array($v['Event']['id'], $tagArray[1])) {
|
||||
unset($eventIds[$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
App::uses('HidsExport', 'Export');
|
||||
$continue = false;
|
||||
$eventCount = count($eventIds);
|
||||
if ($jobId) {
|
||||
$this->Job = ClassRegistry::init('Job');
|
||||
$this->Job->id = $jobId;
|
||||
if (!$this->Job->exists()) {
|
||||
$jobId = false;
|
||||
}
|
||||
}
|
||||
foreach ($eventIds as $k => $event) {
|
||||
$conditions['AND'] = array('Attribute.to_ids' => 1, 'Event.published' => 1, 'Attribute.type' => $typeArray, 'Attribute.event_id' => $event['Event']['id']);
|
||||
$options = array(
|
||||
'conditions' => $conditions,
|
||||
'group' => array('Attribute.type', 'Attribute.value1'),
|
||||
'enforceWarninglist' => $enforceWarninglist,
|
||||
'flatten' => true
|
||||
);
|
||||
$items = $this->fetchAttributes($user, $options);
|
||||
if (empty($items)) {
|
||||
continue;
|
||||
}
|
||||
$export = new HidsExport();
|
||||
$rules = array_merge($rules, $export->export($items, strtoupper($type), $continue));
|
||||
$continue = true;
|
||||
if ($jobId && ($k % 10 == 0)) {
|
||||
$this->Job->saveField('progress', $k * 80 / $eventCount);
|
||||
}
|
||||
}
|
||||
return $rules;
|
||||
}
|
||||
|
||||
|
||||
public function nids($user, $format, $id = false, $continue = false, $tags = false, $from = false, $to = false, $last = false, $type = false, $enforceWarninglist = false, $includeAllTags = false)
|
||||
{
|
||||
if (empty($user)) {
|
||||
throw new MethodNotAllowedException(__('Could not read user.'));
|
||||
}
|
||||
$eventIds = $this->Event->fetchEventIds($user, [
|
||||
'from' => $from,
|
||||
'to' => $to,
|
||||
'last' => $last
|
||||
]);
|
||||
|
||||
// If we sent any tags along, load the associated tag names for each attribute
|
||||
if ($tags) {
|
||||
$tag = ClassRegistry::init('Tag');
|
||||
$args = $this->dissectArgs($tags);
|
||||
$tagArray = $tag->fetchEventTagIds($args[0], $args[1]);
|
||||
if (!empty($tagArray[0])) {
|
||||
foreach ($eventIds as $k => $v) {
|
||||
if (!in_array($v['Event']['id'], $tagArray[0])) {
|
||||
unset($eventIds[$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($tagArray[1])) {
|
||||
foreach ($eventIds as $k => $v) {
|
||||
if (in_array($v['Event']['id'], $tagArray[1])) {
|
||||
unset($eventIds[$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($id) {
|
||||
foreach ($eventIds as $k => $v) {
|
||||
if ($v['Event']['id'] !== $id) {
|
||||
unset($eventIds[$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($format == 'suricata') {
|
||||
App::uses('NidsSuricataExport', 'Export');
|
||||
} else {
|
||||
App::uses('NidsSnortExport', 'Export');
|
||||
}
|
||||
|
||||
$rules = array();
|
||||
foreach ($eventIds as $event) {
|
||||
$conditions['AND'] = array('Attribute.to_ids' => 1, "Event.published" => 1, 'Attribute.event_id' => $event['Event']['id']);
|
||||
$valid_types = array('ip-dst', 'ip-src', 'ip-dst|port', 'ip-src|port', 'eppn', 'email', 'email-src', 'email-dst', 'email-subject', 'email-attachment', 'domain', 'domain|ip', 'hostname', 'url', 'user-agent', 'snort');
|
||||
$conditions['AND']['Attribute.type'] = $valid_types;
|
||||
if (!empty($type)) {
|
||||
$conditions['AND'][] = array('Attribute.type' => $type);
|
||||
}
|
||||
|
||||
$params = array(
|
||||
'conditions' => $conditions, // array of conditions
|
||||
'recursive' => -1, // int
|
||||
'fields' => array('Attribute.id', 'Attribute.event_id', 'Attribute.type', 'Attribute.value'),
|
||||
'contain' => array('Event'=> array('fields' => array('Event.id', 'Event.threat_level_id'))),
|
||||
'group' => array('Attribute.type', 'Attribute.value1'), // fields to GROUP BY
|
||||
'enforceWarninglist' => $enforceWarninglist,
|
||||
'includeAllTags' => $includeAllTags,
|
||||
'flatten' => true
|
||||
);
|
||||
$items = $this->fetchAttributes($user, $params);
|
||||
if (empty($items)) {
|
||||
continue;
|
||||
}
|
||||
// export depending on the requested type
|
||||
switch ($format) {
|
||||
case 'suricata':
|
||||
$export = new NidsSuricataExport();
|
||||
break;
|
||||
case 'snort':
|
||||
$export = new NidsSnortExport();
|
||||
break;
|
||||
}
|
||||
$rules = array_merge($rules, $export->export($items, $user['nids_sid'], $format, $continue));
|
||||
// Only prepend the comments once
|
||||
$continue = true;
|
||||
}
|
||||
return $rules;
|
||||
}
|
||||
|
||||
public function set_filter_tags(&$params, $conditions, $options)
|
||||
{
|
||||
if (empty($params['tags']) && empty($params['event_tags'])) {
|
||||
|
@ -1315,212 +1158,6 @@ class Attribute extends AppModel
|
|||
return $conditions;
|
||||
}
|
||||
|
||||
public function text($user, $type, $tags = false, $eventId = false, $allowNonIDS = false, $from = false, $to = false, $last = false, $enforceWarninglist = false, $allowNotPublished = false)
|
||||
{
|
||||
//permissions are taken care of in fetchAttributes()
|
||||
$conditions['AND'] = array();
|
||||
if ($allowNonIDS === false) {
|
||||
$conditions['AND']['Attribute.to_ids'] = 1;
|
||||
if ($allowNotPublished === false) {
|
||||
$conditions['AND']['Event.published'] = 1;
|
||||
}
|
||||
}
|
||||
if (!is_array($type) && $type !== 'all') {
|
||||
$conditions['AND']['Attribute.type'] = $type;
|
||||
}
|
||||
if ($from) {
|
||||
$conditions['AND']['Event.date >='] = $from;
|
||||
}
|
||||
if ($to) {
|
||||
$conditions['AND']['Event.date <='] = $to;
|
||||
}
|
||||
if ($last) {
|
||||
$conditions['AND']['Event.publish_timestamp >='] = $last;
|
||||
}
|
||||
|
||||
if ($eventId !== false) {
|
||||
$conditions['AND'][] = array('Event.id' => $eventId);
|
||||
} elseif ($tags !== false) {
|
||||
$passed_param = array('tags' => $tags);
|
||||
$conditions = $this->set_filter_tags($passed_param, $conditions, array('scope' => 'Attribute'));
|
||||
}
|
||||
$attributes = $this->fetchAttributes($user, array(
|
||||
'conditions' => $conditions,
|
||||
'order' => 'Attribute.value1 ASC',
|
||||
'fields' => array('value'),
|
||||
'contain' => array('Event' => array(
|
||||
'fields' => array('Event.id', 'Event.published', 'Event.date', 'Event.publish_timestamp'),
|
||||
)),
|
||||
'enforceWarninglist' => $enforceWarninglist,
|
||||
'flatten' => 1
|
||||
));
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
public function rpz($user, $tags = false, $eventId = false, $from = false, $to = false, $enforceWarninglist = false)
|
||||
{
|
||||
// we can group hostname and domain as well as ip-src and ip-dst in this case
|
||||
$conditions['AND'] = array('Attribute.to_ids' => 1, 'Event.published' => 1);
|
||||
$typesToFetch = array('ip' => array('ip-src', 'ip-dst'), 'domain' => array('domain'), 'hostname' => array('hostname'));
|
||||
if ($from) {
|
||||
$conditions['AND']['Event.date >='] = $from;
|
||||
}
|
||||
if ($to) {
|
||||
$conditions['AND']['Event.date <='] = $to;
|
||||
}
|
||||
if ($eventId !== false) {
|
||||
$conditions['AND'][] = array('Event.id' => $eventId);
|
||||
}
|
||||
if ($tags !== false) {
|
||||
// If we sent any tags along, load the associated tag names for each attribute
|
||||
$tag = ClassRegistry::init('Tag');
|
||||
$args = $this->dissectArgs($tags);
|
||||
$tagArray = $tag->fetchEventTagIds($args[0], $args[1]);
|
||||
$temp = array();
|
||||
foreach ($tagArray[0] as $accepted) {
|
||||
$temp['OR'][] = array('Event.id' => $accepted);
|
||||
}
|
||||
$conditions['AND'][] = $temp;
|
||||
$temp = array();
|
||||
foreach ($tagArray[1] as $rejected) {
|
||||
$temp['AND'][] = array('Event.id !=' => $rejected);
|
||||
}
|
||||
$conditions['AND'][] = $temp;
|
||||
}
|
||||
$values = array();
|
||||
foreach ($typesToFetch as $k => $v) {
|
||||
$tempConditions = $conditions;
|
||||
$tempConditions['type'] = $v;
|
||||
$temp = $this->fetchAttributes(
|
||||
$user,
|
||||
array(
|
||||
'conditions' => $tempConditions,
|
||||
'fields' => array('Attribute.value'), // array of field names
|
||||
'enforceWarninglist' => $enforceWarninglist,
|
||||
'flatten' => 1
|
||||
)
|
||||
);
|
||||
if (empty($temp)) {
|
||||
continue;
|
||||
}
|
||||
if ($k == 'hostname') {
|
||||
foreach ($temp as $value) {
|
||||
$found = false;
|
||||
if (isset($values['domain'])) {
|
||||
foreach ($values['domain'] as $domain) {
|
||||
if (strpos($value['Attribute']['value'], $domain) != 0) {
|
||||
$found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$found) {
|
||||
$values[$k][] = $value['Attribute']['value'];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach ($temp as $value) {
|
||||
$values[$k][] = $value['Attribute']['value'];
|
||||
}
|
||||
}
|
||||
unset($temp);
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
|
||||
public function bro($user, $type, $tags = false, $eventId = false, $from = false, $to = false, $last = false, $enforceWarninglist = false, $skipHeader = false)
|
||||
{
|
||||
App::uses('BroExport', 'Export');
|
||||
$export = new BroExport();
|
||||
if ($type == 'all') {
|
||||
$types = array_keys($export->mispTypes);
|
||||
} else {
|
||||
$types = array($type);
|
||||
}
|
||||
$intel = array();
|
||||
foreach ($types as $type) {
|
||||
//restricting to non-private or same org if the user is not a site-admin.
|
||||
$conditions['AND'] = array('Attribute.to_ids' => 1, 'Event.published' => 1);
|
||||
if ($from) {
|
||||
$conditions['AND']['Event.date >='] = $from;
|
||||
}
|
||||
if ($to) {
|
||||
$conditions['AND']['Event.date <='] = $to;
|
||||
}
|
||||
if ($last) {
|
||||
$conditions['AND']['Event.publish_timestamp >='] = $last;
|
||||
}
|
||||
if ($eventId !== false) {
|
||||
$temp = array();
|
||||
$args = $this->dissectArgs($eventId);
|
||||
foreach ($args[0] as $accepted) {
|
||||
$temp['OR'][] = array('Event.id' => $accepted);
|
||||
}
|
||||
$conditions['AND'][] = $temp;
|
||||
$temp = array();
|
||||
foreach ($args[1] as $rejected) {
|
||||
$temp['AND'][] = array('Event.id !=' => $rejected);
|
||||
}
|
||||
$conditions['AND'][] = $temp;
|
||||
}
|
||||
if ($tags !== false) {
|
||||
// If we sent any tags along, load the associated tag names for each attribute
|
||||
$tag = ClassRegistry::init('Tag');
|
||||
$args = $this->dissectArgs($tags);
|
||||
$tagArray = $tag->fetchEventTagIds($args[0], $args[1]);
|
||||
$temp = array();
|
||||
foreach ($tagArray[0] as $accepted) {
|
||||
$temp['OR'][] = array('Event.id' => $accepted);
|
||||
}
|
||||
$conditions['AND'][] = $temp;
|
||||
$temp = array();
|
||||
foreach ($tagArray[1] as $rejected) {
|
||||
$temp['AND'][] = array('Event.id !=' => $rejected);
|
||||
}
|
||||
$conditions['AND'][] = $temp;
|
||||
}
|
||||
$this->Allowedlist = ClassRegistry::init('Allowedlist');
|
||||
$this->allowedlist = $this->Allowedlist->getBlockedValues();
|
||||
$instanceString = 'MISP';
|
||||
if (Configure::read('MISP.host_org_id') && Configure::read('MISP.host_org_id') > 0) {
|
||||
$this->Event->Orgc->id = Configure::read('MISP.host_org_id');
|
||||
if ($this->Event->Orgc->exists()) {
|
||||
$instanceString = $this->Event->Orgc->field('name') . ' MISP';
|
||||
}
|
||||
}
|
||||
$mispTypes = $export->getMispTypes($type);
|
||||
foreach ($mispTypes as $mispType) {
|
||||
$conditions['AND']['Attribute.type'] = $mispType[0];
|
||||
$intel = array_merge($intel, $this->__bro($user, $conditions, $mispType[1], $export, $this->allowedlist, $instanceString, $enforceWarninglist));
|
||||
}
|
||||
}
|
||||
natsort($intel);
|
||||
$intel = array_unique($intel);
|
||||
if (empty($skipHeader)) {
|
||||
array_unshift($intel, $export->header);
|
||||
}
|
||||
return $intel;
|
||||
}
|
||||
|
||||
private function __bro($user, $conditions, $valueField, $export, $allowedlist, $instanceString, $enforceWarninglist)
|
||||
{
|
||||
$attributes = $this->fetchAttributes(
|
||||
$user,
|
||||
array(
|
||||
'conditions' => $conditions, // array of conditions
|
||||
'order' => 'Attribute.value' . $valueField . ' ASC',
|
||||
'recursive' => -1, // int
|
||||
'fields' => array('Attribute.id', 'Attribute.event_id', 'Attribute.type', 'Attribute.category', 'Attribute.comment', 'Attribute.to_ids', 'Attribute.value', 'Attribute.value' . $valueField),
|
||||
'contain' => array('Event' => array('fields' => array('Event.id', 'Event.threat_level_id', 'Event.orgc_id', 'Event.uuid'))),
|
||||
'enforceWarninglist' => $enforceWarninglist,
|
||||
'flatten' => 1
|
||||
)
|
||||
);
|
||||
$orgs = $this->Event->Orgc->find('list', array(
|
||||
'fields' => array('Orgc.id', 'Orgc.name')
|
||||
));
|
||||
return $export->export($attributes, $orgs, $valueField, $allowedlist, $instanceString);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|false $jobId
|
||||
* @param int|false $eventId
|
||||
|
|
|
@ -1782,25 +1782,25 @@ class User extends AppModel
|
|||
/**
|
||||
* generatePeriodicSummary
|
||||
*
|
||||
* @param int $user_id
|
||||
* @param string $period
|
||||
* @param int $userId
|
||||
* @param string $period Can be 'daily', 'weekly' or 'monthly'
|
||||
* @param bool $rendered When false, instance of SendEmailTemplate will returned
|
||||
* @return string|SendEmailTemplate
|
||||
* @throws NotFoundException
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function generatePeriodicSummary(int $user_id, string $period, $rendered=true)
|
||||
public function generatePeriodicSummary(int $userId, string $period, $rendered=true)
|
||||
{
|
||||
$existingUser = $this->getUserById($user_id);
|
||||
$user = $this->rearrangeToAuthForm($existingUser);
|
||||
$allowed_periods = array_map(function($period) {
|
||||
$allowedPeriods = array_map(function($period) {
|
||||
return substr($period, strlen('notification_'));
|
||||
}, self::PERIODIC_NOTIFICATIONS);
|
||||
if (!in_array($period, $allowed_periods)) {
|
||||
if (!in_array($period, $allowedPeriods, true)) {
|
||||
throw new InvalidArgumentException(__('Invalid period. Must be one of %s', JsonTool::encode(self::PERIODIC_NOTIFICATIONS)));
|
||||
}
|
||||
|
||||
$user = $this->getAuthUser($userId);
|
||||
App::import('Tools', 'SendEmail');
|
||||
$emailTemplate = $this->prepareEmailTemplate($period);
|
||||
$periodicSettings = $this->fetchPeriodicSettingForUser($user_id, true);
|
||||
$periodicSettings = $this->fetchPeriodicSettingForUser($userId, true);
|
||||
$filters = $this->getUsablePeriodicSettingForUser($periodicSettings, $period);
|
||||
$filtersForRestSearch = $filters; // filters for restSearch are slightly different than fetchEvent
|
||||
$filters['last'] = $this->resolveTimeDelta($filters['last']);
|
||||
|
@ -1823,7 +1823,7 @@ class User extends AppModel
|
|||
unset($filtersForRestSearch['tags']);
|
||||
}
|
||||
$finalContext = $this->Event->restSearch($user, 'context', $filtersForRestSearch, false, false, $elementCounter, $renderView);
|
||||
$finalContext = json_decode($finalContext->intoString(), true);
|
||||
$finalContext = JsonTool::decode($finalContext->intoString());
|
||||
$aggregated_context = $this->__renderAggregatedContext($finalContext);
|
||||
|
||||
$rollingWindows = $periodicSettings['trending_period_amount'] ?: 2;
|
||||
|
@ -1835,6 +1835,7 @@ class User extends AppModel
|
|||
];
|
||||
$trending_summary = $this->__renderTrendingSummary($trendData);
|
||||
|
||||
$emailTemplate = $this->prepareEmailTemplate($period);
|
||||
$emailTemplate->set('baseurl', $this->Event->__getAnnounceBaseurl());
|
||||
$emailTemplate->set('events', $events);
|
||||
$emailTemplate->set('filters', $filters);
|
||||
|
@ -1845,9 +1846,9 @@ class User extends AppModel
|
|||
$emailTemplate->set('trending_summary', $trending_summary);
|
||||
$emailTemplate->set('analysisLevels', $this->Event->analysisLevels);
|
||||
$emailTemplate->set('distributionLevels', $this->Event->distributionLevels);
|
||||
if (!empty($rendered)) {
|
||||
if ($rendered) {
|
||||
$summary = $emailTemplate->render();
|
||||
return $summary->format() == 'text' ? $summary->text : $summary->html;
|
||||
return $summary->format() === 'text' ? $summary->text : $summary->html;
|
||||
}
|
||||
return $emailTemplate;
|
||||
}
|
||||
|
@ -1877,23 +1878,21 @@ class User extends AppModel
|
|||
|
||||
private function __genTimerangeFilter(string $period='daily'): string
|
||||
{
|
||||
$timerange = '1d';
|
||||
if ($period == 'weekly') {
|
||||
$timerange = '7d';
|
||||
} else if ($period == 'monthly'){
|
||||
$timerange = '31d';
|
||||
}
|
||||
return $timerange;
|
||||
return $this->periodToDays($period) . 'd';
|
||||
}
|
||||
|
||||
public function periodToDays(string $period='daily'): int
|
||||
private function periodToDays(string $period='daily'): int
|
||||
{
|
||||
return ($period == 'daily' ? 1 : (
|
||||
$period == 'weekly' ? 7 : 31)
|
||||
);
|
||||
if ($period === 'daily') {
|
||||
return 1;
|
||||
} else if ($period === 'weekly') {
|
||||
return 7;
|
||||
} else {
|
||||
return 31;
|
||||
}
|
||||
}
|
||||
|
||||
public function prepareEmailTemplate(string $period='daily'): SendEmailTemplate
|
||||
private function prepareEmailTemplate(string $period = 'daily'): SendEmailTemplate
|
||||
{
|
||||
$subject = sprintf('[%s MISP] %s %s', Configure::read('MISP.org'), Inflector::humanize($period), __('Notification - %s', (new DateTime())->format('Y-m-d')));
|
||||
$template = new SendEmailTemplate("notification_$period");
|
||||
|
|
|
@ -135,6 +135,12 @@ class AttributeValidationToolTest extends TestCase
|
|||
$this->assertEquals('xn--hkyrky-ptac70bc.cz|127.0.0.1', AttributeValidationTool::modifyBeforeValidation('domain|ip', 'HÁČKYČÁRKY.CZ|127.0.0.1'));
|
||||
}
|
||||
|
||||
public function testSssdeep()
|
||||
{
|
||||
$this->shouldBeValid('ssdeep', ["768:+OFu8Q3w6QzfR5Jni6SQD7qSFDs6P93/q0XIc/UB5EPABWX:RFu8QAFzffJui79f13/AnB5EPAkX"]);
|
||||
$this->shouldBeInvalid('ssdeep', ["768:+OFu8Q3w6QzfR5Jni6SQD7qSFDs6P93/q0XIc/UB5EPABWX\n\n:RFu8QAFzffJui79f13/AnB5EPAkX"]);
|
||||
}
|
||||
|
||||
private function shouldBeValid($type, array $values)
|
||||
{
|
||||
foreach ($values as $value) {
|
||||
|
|
|
@ -46,6 +46,7 @@ foreach ($allUniqueTags as $i => $tag) {
|
|||
$chartData[$tag] = array_reverse($chartData[$tag]);
|
||||
$maxValue = max($maxValue, max($chartData[$tag]));
|
||||
}
|
||||
$colorForTags[$tag] = $COLOR_PALETTE[$i];
|
||||
}
|
||||
$canvasWidth = 600;
|
||||
$canvasHeight = 150;
|
||||
|
@ -136,7 +137,7 @@ if (!function_exists('getColorFromYlOrBr')) {
|
|||
<div>
|
||||
<span class="y-axis-label" style="<?= sprintf('left: %spx; top: %spx; transform: translate(-100%%, %s%%)', 0, 0, -25) ?>"><?= h($maxValue) ?></span>
|
||||
<span class="y-axis-label" style="<?= sprintf('left: %spx; top: %spx; transform: translate(-100%%, %s%%)', 0, ($canvasHeight - 20) / 2, 0) ?>"><?= h(round($maxValue / 2, 2)) ?></span>
|
||||
<span class="y-axis-label" style="<?= sprintf('left: %spx; top: %spx; transform: translate(-100%%, %s%%)', 0, ($canvasHeight - 20), 25) ?>"><?= 0 ?></span>
|
||||
<span class="y-axis-label" style="<?= sprintf('left: %spx; top: %spx; transform: translate(-100%%, %s%%)', 0, ($canvasHeight - 20), 25) ?>">0</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="canvas">
|
||||
|
@ -247,7 +248,6 @@ if (!function_exists('getColorFromYlOrBr')) {
|
|||
$colorGradient[] = sprintf('%s %s%%', $color, $length);
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="heatbar" style="background: <?= sprintf('linear-gradient(90deg, %s);', implode(', ', $colorGradient)) ?>;"></div>
|
||||
</td>
|
||||
<?php endforeach; ?>
|
||||
|
|
Loading…
Reference in New Issue