Merge branch '2.4' of github.com:MISP/MISP into zoidberg-timeline

pull/4743/head
mokaddem 2019-06-24 09:06:11 +02:00
commit 2ea4916051
44 changed files with 581 additions and 151 deletions

View File

@ -120,9 +120,11 @@ MISPvars () {
# GPG configuration
GPG_REAL_NAME='Autogenerated Key'
# On a REAL install, please do not set a comment, see here for why: https://www.debian-administration.org/users/dkg/weblog/97
GPG_COMMENT='WARNING: MISP AutoGenerated Key consider this Key VOID!'
GPG_EMAIL_ADDRESS='admin@admin.test'
GPG_KEY_LENGTH='2048'
# 3072 bits used as per suggestions here: https://riseup.net/en/security/message-security/openpgp/best-practices
GPG_KEY_LENGTH='3072'
GPG_PASSPHRASE="$(openssl rand -hex 32)"
# debug alias to make sure people are not confused when blindly copy pasting blobs of code
@ -247,7 +249,7 @@ checkCoreOS () {
if [[ -f "/etc/redhat-release" ]]; then
echo "This is some redhat flavour"
REDHAT=1
RHfla=$(cat /etc/redhat-release | cut -f 1 -d\ | tr [A-Z] [a-z])
RHfla=$(cat /etc/redhat-release | cut -f 1 -d\ | tr '[:upper:]' '[:lower:]')
fi
}
@ -259,7 +261,7 @@ checkFlavour () {
sudo apt install lsb-release dialog -y
fi
FLAVOUR=$(lsb_release -s -i |tr [A-Z] [a-z])
FLAVOUR=$(lsb_release -s -i |tr '[:upper:]' '[:lower:]')
if [ FLAVOUR == "ubuntu" ]; then
RELEASE=$(lsb_release -s -r)
debug "We detected the following Linux flavour: ${YELLOW}$(tr '[:lower:]' '[:upper:]' <<< ${FLAVOUR:0:1})${FLAVOUR:1} ${RELEASE}${NC}"
@ -377,6 +379,27 @@ checkFail () {
fi
}
ask_o () {
ANSWER=""
if [ -z "${1}" ]; then
echo "This function needs at least 1 parameter."
exit 1
fi
[ -z "${2}" ] && OPT1="y" || OPT1="${2}"
[ -z "${3}" ] && OPT2="n" || OPT2="${3}"
while true; do
case "${ANSWER}" in "${OPT1}" | "${OPT2}") break ;; esac
echo -e -n "${1} (${OPT1}/${OPT2}) "
read ANSWER
ANSWER=$(echo "${ANSWER}" | tr '[:upper:]' '[:lower:]')
done
}
# Check if misp user is present and if run as root
checkID () {
debug "Checking if run as root and $MISP_USER is present"
@ -387,7 +410,7 @@ checkID () {
if [[ "$UNATTENDED" != "1" ]]; then
echo "There is NO user called '$MISP_USER' create a user '$MISP_USER' (y) or continue as $USER (n)? (y/n) "
read ANSWER
ANSWER=$(echo $ANSWER |tr [A-Z] [a-z])
ANSWER=$(echo $ANSWER |tr '[:upper:]' '[:lower:]')
else
ANSWER="y"
fi
@ -530,7 +553,7 @@ setBaseURL () {
echo "You can now enter your own MISP_BASEURL, if you wish to NOT do that, the MISP_BASEURL will be empty, which will work, but ideally you configure it afterwards."
echo "Do you want to change it now? (y/n) "
read ANSWER
ANSWER=$(echo $ANSWER |tr [A-Z] [a-z])
ANSWER=$(echo $ANSWER |tr '[:upper:]' '[:lower:]')
if [[ "$ANSWER" == "y" ]]; then
if [[ ! -z $IP ]]; then
echo "It seems you have an interface called $IFACE UP with the following IP: $IP - FYI"
@ -854,6 +877,7 @@ genRCLOCAL () {
sed -i -e '$i \echo never > /sys/kernel/mm/transparent_hugepage/enabled\n' /etc/rc.local
sed -i -e '$i \echo 1024 > /proc/sys/net/core/somaxconn\n' /etc/rc.local
sed -i -e '$i \sysctl vm.overcommit_memory=1\n' /etc/rc.local
sed -i -e '$i \[ -f /etc/init.d/firstBoot ] && bash /etc/init.d/firstBoot\n' /etc/rc.local
}
# Run PyMISP tests
@ -943,7 +967,16 @@ aptUpgrade () {
debug "Upgrading system"
checkAptLock
sudo apt-get update
sudo apt-get upgrade -qy
# If we run in non-interactive mode, make sure we do not stop all of a sudden
if [[ "${PACKER}" == "1" || "${UNATTENDED}" == "1" ]]; then
export DEBIAN_FRONTEND=noninteractive
export DEBIAN_PRIORITY=critical
sudo -E apt-get -qy -o "Dpkg::Options::=--force-confdef" -o "Dpkg::Options::=--force-confold" upgrade
sudo -E apt-get -qy autoclean
else
sudo apt-get upgrade -qy
fi
}
# check if sudo is installed
@ -1172,6 +1205,9 @@ installCore () {
# install lief
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install https://github.com/lief-project/packages/raw/lief-master-latest/pylief-0.9.0.dev.zip
# install zmq needed by mispzmq
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install zmq
# install python-magic
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install python-magic
@ -1269,7 +1305,8 @@ coreCAKE () {
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.python_bin" "${PATH_TO_MISP}/venv/bin/python"
# Set default role
$SUDO_WWW $RUN_PHP -- $CAKE setDefaultRole 3
# TESTME: The following seem defunct, please test.
# $SUDO_WWW $RUN_PHP -- $CAKE setDefaultRole 3
# Tune global time outs
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Session.autoRegenerate" 0
@ -2113,6 +2150,12 @@ installMISPonKali () {
# install python-magic
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install python-magic 2> /dev/null > /dev/null
# install plyara
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install plyara 2> /dev/null > /dev/null
# install zmq needed by mispzmq
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install zmq 2> /dev/null > /dev/null
# Install Crypt_GPG and Console_CommandLine
debug "Installing pear Console_CommandLine"
pear install ${PATH_TO_MISP}/INSTALL/dependencies/Console_CommandLine/package.xml
@ -2311,7 +2354,7 @@ fi
# If Ubuntu is detected, figure out which release it is and run the according scripts
if [ "${FLAVOUR}" == "ubuntu" ]; then
RELEASE=$(lsb_release -s -r| tr [A-Z] [a-z])
RELEASE=$(lsb_release -s -r| tr '[:upper:]' '[:lower:]')
if [ "${RELEASE}" == "18.04" ]; then
echo "Install on Ubuntu 18.04 LTS fully supported."
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
@ -2337,7 +2380,7 @@ fi
# If Debian is detected, figure out which release it is and run the according scripts
if [ "${FLAVOUR}" == "debian" ]; then
CODE=$(lsb_release -s -c| tr [A-Z] [a-z])
CODE=$(lsb_release -s -c| tr '[:upper:]' '[:lower:]')
if [ "${CODE}" == "buster" ]; then
echo "Install on Debian testing fully supported."
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
@ -2359,7 +2402,7 @@ fi
# If Tsurugi is detected, figure out which release it is and run the according scripts
if [ "${FLAVOUR}" == "tsurugi" ]; then
CODE=$(lsb_release -s -c| tr [A-Z] [a-z])
CODE=$(lsb_release -s -c| tr '[:upper:]' '[:lower:]')
if [ "${CODE}" == "bamboo" ]; then
echo "Install on Tsurugi Lab partially supported."
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"

View File

@ -1,5 +1,5 @@
; Generated by RHash v1.3.8 on 2019-05-30 at 14:36.25
; Generated by RHash v1.3.8 on 2019-06-20 at 14:00.36
; Written by Kravchenko Aleksey (Akademgorodok) - http://rhash.sf.net/
;
; 93871 14:36.25 2019-05-30 INSTALL.sh
INSTALL.sh DE23B5D224757A8AB2941D8E15D73F10872D5106 ABEE81992478478406197EEC1891FA7CBDC5B32575447DD6865511B1DE48EC6F D7B9CA78779343C0CD47C9184DCA17DEFA24FA1B6BB35441F574AC40ED5A5AD68738BA91676E528AFC2488B44EC935C6 1FFDD293EF9FD53F80813B33839187ECF00B68FDDECA11327508ACABB99B45F45017CFF4AF2B70CF82D27B4AEEB75C34434B3AA00AD52D3AFC8405E77B8CF348
; 95437 14:00.36 2019-06-20 INSTALL.sh
INSTALL.sh 8CFDF8FC14572C9AA51673D7449C354257C6CE67 61B8976709B44B3F2C0491EDB6FA013AC15BA4833F074929810C65C93C274FCB 75D5538717565401F180E7C777BE41A167B2365473806141C9357E75220DD198BE68DC2B59452F39396B42FB50208194 460D731E91EAA0F589B96D13CC451BCB7014C683A357099B13492E7683A459ECB7C2A43AFFB237C966CE67DD06140199686E968B518A33ED73C84135948E0749

View File

@ -1 +1 @@
de23b5d224757a8ab2941d8e15d73f10872d5106 INSTALL.sh
8cfdf8fc14572c9aa51673d7449c354257c6ce67 INSTALL.sh

View File

@ -1 +1 @@
abee81992478478406197eec1891fa7cbdc5b32575447dd6865511b1de48ec6f INSTALL.sh
61b8976709b44b3f2c0491edb6fa013ac15ba4833f074929810c65c93c274fcb INSTALL.sh

View File

@ -1 +1 @@
d7b9ca78779343c0cd47c9184dca17defa24fa1b6bb35441f574ac40ed5a5ad68738ba91676e528afc2488b44ec935c6 INSTALL.sh
75d5538717565401f180e7c777be41a167b2365473806141c9357e75220dd198be68dc2b59452f39396b42fb50208194 INSTALL.sh

View File

@ -1 +1 @@
1ffdd293ef9fd53f80813b33839187ecf00b68fddeca11327508acabb99b45f45017cff4af2b70cf82d27b4aeeb75c34434b3aa00ad52d3afc8405e77b8cf348 INSTALL.sh
460d731e91eaa0f589b96d13cc451bcb7014c683a357099b13492e7683a459ecb7c2a43affb237c966ce67dd06140199686e968b518a33ed73c84135948e0749 INSTALL.sh

View File

@ -465,6 +465,12 @@ installMISPonKali () {
# install python-magic
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install python-magic 2> /dev/null > /dev/null
# install plyara
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install plyara 2> /dev/null > /dev/null
# install zmq needed by mispzmq
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install zmq 2> /dev/null > /dev/null
# Install Crypt_GPG and Console_CommandLine
debug "Installing pear Console_CommandLine"
pear install ${PATH_TO_MISP}/INSTALL/dependencies/Console_CommandLine/package.xml
@ -663,7 +669,7 @@ fi
# If Ubuntu is detected, figure out which release it is and run the according scripts
if [ "${FLAVOUR}" == "ubuntu" ]; then
RELEASE=$(lsb_release -s -r| tr [A-Z] [a-z])
RELEASE=$(lsb_release -s -r| tr '[:upper:]' '[:lower:]')
if [ "${RELEASE}" == "18.04" ]; then
echo "Install on Ubuntu 18.04 LTS fully supported."
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
@ -689,7 +695,7 @@ fi
# If Debian is detected, figure out which release it is and run the according scripts
if [ "${FLAVOUR}" == "debian" ]; then
CODE=$(lsb_release -s -c| tr [A-Z] [a-z])
CODE=$(lsb_release -s -c| tr '[:upper:]' '[:lower:]')
if [ "${CODE}" == "buster" ]; then
echo "Install on Debian testing fully supported."
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
@ -711,7 +717,7 @@ fi
# If Tsurugi is detected, figure out which release it is and run the according scripts
if [ "${FLAVOUR}" == "tsurugi" ]; then
CODE=$(lsb_release -s -c| tr [A-Z] [a-z])
CODE=$(lsb_release -s -c| tr '[:upper:]' '[:lower:]')
if [ "${CODE}" == "bamboo" ]; then
echo "Install on Tsurugi Lab partially supported."
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"

View File

@ -1 +1 @@
{"major":2, "minor":4, "hotfix":108}
{"major":2, "minor":4, "hotfix":109}

View File

@ -46,7 +46,7 @@ class AppController extends Controller
public $helpers = array('Utility', 'OrgImg', 'FontAwesome');
private $__queryVersion = '75';
private $__queryVersion = '77';
public $pyMispVersion = '2.4.106';
public $phpmin = '7.0';
public $phprec = '7.2';
@ -525,7 +525,7 @@ class AppController extends Controller
private function __convertEmailToName($email)
{
$name = explode('@', $email);
$name = explode('@', (string)$email);
$name = explode('.', $name[0]);
foreach ($name as $key => $value) {
$name[$key] = ucfirst($value);
@ -668,7 +668,7 @@ class AppController extends Controller
foreach ($options['paramArray'] as $p) {
if (
isset($options['ordered_url_params'][$p]) &&
(!in_array(strtolower($options['ordered_url_params'][$p]), array('null', '0', false, 'false', null)))
(!in_array(strtolower((string)$options['ordered_url_params'][$p]), array('null', '0', false, 'false', null)))
) {
$data[$p] = $options['ordered_url_params'][$p];
$data[$p] = str_replace(';', ':', $data[$p]);

View File

@ -75,6 +75,7 @@ class ACLComponent extends Component
'delete' => array(),
'edit' => array(),
'index' => array(),
'massDelete' => array()
),
'eventDelegations' => array(
'acceptDelegation' => array('perm_add'),
@ -348,6 +349,7 @@ class ACLComponent extends Component
'getPyMISPVersion' => array('*'),
'getSubmodulesStatus' => array('perm_site_admin'),
'getSubmoduleQuickUpdateForm' => array('perm_site_admin'),
'getWorkers' => array(),
'getVersion' => array('*'),
'import' => ('perm_site_admin'),
'index' => array('OR' => array('perm_sync', 'perm_admin')),

View File

@ -27,13 +27,25 @@ class EventBlacklistsController extends AppController
public function index()
{
$passedArgsArray = array();
$passedArgs = $this->passedArgs;
$params = array();
$validParams = array('event_uuid', 'comment');
$validParams = array('event_uuid', 'comment', 'event_info', 'event_orgc');
foreach ($validParams as $validParam) {
if (!empty($this->params['named'][$validParam])) {
$params[$validParam] = $this->params['named'][$validParam];
}
}
if (!empty($this->params['named']['searchall'])) {
$params['AND']['OR'] = array(
'event_uuid' => $this->params['named']['searchall'],
'comment' => $this->params['named']['searchall'],
'event_info' => $this->params['named']['searchall'],
'event_orgc' => $this->params['named']['searchall']
);
}
$this->set('passedArgs', json_encode($passedArgs));
$this->set('passedArgsArray', $passedArgsArray);
$this->BlackList->index($this->_isRest(), $params);
}
@ -51,4 +63,39 @@ class EventBlacklistsController extends AppController
{
$this->BlackList->delete($this->_isRest(), $id);
}
public function massDelete()
{
if ($this->request->is('post') || $this->request->is('put')) {
$ids = $this->request->data['EventBlacklist']['ids'];
$event_ids = json_decode($ids, true);
if (empty($event_ids)) {
throw new NotFoundException(__('Invalid event IDs.'));
}
$result = $this->EventBlacklist->deleteAll(array('EventBlacklist.id' => $event_ids));
if ($result) {
if ($this->_isRest()) {
return $this->RestResponse->saveSuccessResponse('EventBlacklist', 'Deleted', $ids, $this->response->type());
} else {
$this->Flash->success('Blacklist entry removed');
$this->redirect(array('controller' => 'eventBlacklists', 'action' => 'index'));
}
} else {
$error = __('Failed to delete Event from EventBlacklist. Error: ') . PHP_EOL . h($result);
if ($this->_isRest()) {
return $this->RestResponse->saveFailResponse('EventBlacklist', 'Deleted', false, $error, $this->response->type());
} else {
$this->Flash->error($error);
$this->redirect(array('controller' => 'eventBlacklists', 'action' => 'index'));
}
}
} else {
$ids = json_decode($this->request->query('ids'), true);
if (empty($ids)) {
throw new NotFoundException(__('Invalid event IDs.'));
}
$this->set('event_ids', $ids);
}
}
}

View File

@ -1292,8 +1292,9 @@ class EventsController extends AppController
'Event' => array('eventDescriptions' => 'fieldDescriptions', 'analysisDescriptions' => 'analysisDescriptions', 'analysisLevels' => 'analysisLevels')
);
// workaround to get the event dates in to the attribute relations
// workaround to get the event dates in to the attribute relations and number of correlation per related event
$relatedDates = array();
$relatedEventCorrelationCount = array();
if (!empty($event['RelatedEvent'])) {
foreach ($event['RelatedEvent'] as $relation) {
$relatedDates[$relation['Event']['id']] = $relation['Event']['date'];
@ -1304,10 +1305,14 @@ class EventsController extends AppController
if (!empty($relatedDates[$relation['id']])) {
$event['RelatedAttribute'][$key][$key2]['date'] = $relatedDates[$relation['id']];
}
$relatedEventCorrelationCount[$relation['id']][$relation['value']] = 1;
}
}
}
}
foreach ($relatedEventCorrelationCount as $key => $relation) {
$relatedEventCorrelationCount[$key] = count($relatedEventCorrelationCount[$key]);
}
foreach ($dataForView as $m => $variables) {
if ($m === 'Event') {
@ -1477,6 +1482,7 @@ class EventsController extends AppController
$orgTable = $this->Event->Orgc->find('list', array(
'fields' => array('Orgc.id', 'Orgc.name')
));
$this->set('relatedEventCorrelationCount', $relatedEventCorrelationCount);
$this->set('oldest_timestamp', $oldest_timestamp);
$this->set('required_taxonomies', $this->Event->getRequiredTaxonomies());
$this->set('orgTable', $orgTable);
@ -1549,6 +1555,8 @@ class EventsController extends AppController
$conditions['includeFeedCorrelations'] = 1;
if (!$this->_isRest()) {
$conditions['includeGranularCorrelations'] = 1;
} else if (!empty($this->params['named']['includeGranularCorrelations'])) {
$conditions['includeGranularCorrelations'] = 1;
}
if (!isset($this->params['named']['includeServerCorrelations'])) {
$conditions['includeServerCorrelations'] = 1;
@ -1559,6 +1567,28 @@ class EventsController extends AppController
$conditions['includeServerCorrelations'] = $this->params['named']['includeServerCorrelations'];
}
$results = $this->Event->fetchEvent($this->Auth->user(), $conditions);
if (!empty($this->params['named']['includeGranularCorrelations'])) {
foreach ($results as $k => $event) {
if (!empty($event['RelatedAttribute'])) {
foreach ($event['RelatedAttribute'] as $attribute_id => $relation) {
foreach ($event['Attribute'] as $k2 => $attribute) {
if ((int)$attribute['id'] == $attribute_id) {
$results[$k]['Attribute'][$k2]['RelatedAttribute'][] = $relation;
break 2;
}
}
foreach ($event['Object'] as $k2 => $object) {
foreach ($object['Attribute'] as $k3 => $attribute) {
if ((int)$attribute['id'] == $attribute_id) {
$results[$k]['Object'][$k2]['Attribute'][$k3]['RelatedAttribute'][] = $relation;
break 3;
}
}
}
}
}
}
}
if (empty($results)) {
throw new NotFoundException(__('Invalid event'));
}
@ -3647,7 +3677,6 @@ class EventsController extends AppController
if (empty($tagCollection)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Invalid Tag Collection.')), 'status'=>200, 'type' => 'json'));
}
$tag_id_list = array();
foreach ($tagCollection[0]['TagCollectionTag'] as $tagCollectionTag) {
$tag_id_list[] = $tagCollectionTag['tag_id'];
}

View File

@ -163,12 +163,22 @@ class ObjectTemplatesController extends AppController
public function index($all = false)
{
$passedArgsArray = array();
$passedArgs = $this->passedArgs;
if (!$all || !$this->_isSiteAdmin()) {
$this->paginate['conditions'][] = array('ObjectTemplate.active' => 1);
$this->set('all', false);
} else {
$this->set('all', true);
}
if (!empty($this->params['named']['searchall'])) {
$this->paginate['conditions']['AND']['OR'] = array(
'ObjectTemplate.uuid LIKE' => '%' . strtolower($this->params['named']['searchall']) . '%',
'LOWER(ObjectTemplate.name) LIKE' => '%' . strtolower($this->params['named']['searchall']) . '%',
'ObjectTemplate.meta-category LIKE' => '%' . strtolower($this->params['named']['searchall']) . '%',
'LOWER(ObjectTemplate.description) LIKE' => '%' . strtolower($this->params['named']['searchall']) . '%'
);
}
if ($this->_isRest()) {
$rules = $this->paginate;
unset($rules['limit']);
@ -180,6 +190,8 @@ class ObjectTemplatesController extends AppController
$objectTemplates = $this->paginate();
$this->set('list', $objectTemplates);
}
$this->set('passedArgs', json_encode($passedArgs));
$this->set('passedArgsArray', $passedArgsArray);
}
public function update($type = false, $force = false)

View File

@ -1103,7 +1103,13 @@ class ServersController extends AppController
} else {
shell_exec($prepend . APP . 'Console' . DS . 'cake CakeResque.CakeResque startscheduler -i 5 > /dev/null 2>&1 &');
}
$this->redirect('/servers/serverSettings/workers');
$message = __('Worker start signal sent');
if ($this->_isRest()) {
return $this->RestResponse->saveSuccessResponse('Servers', 'startWorker', $type, $this->response->type(), $message);
} else {
$this->Flash->info($message);
$this->redirect('/servers/serverSettings/workers');
}
}
public function stopWorker($pid)
@ -1112,7 +1118,20 @@ class ServersController extends AppController
throw new MethodNotAllowedException();
}
$this->Server->killWorker($pid, $this->Auth->user());
$this->redirect('/servers/serverSettings/workers');
$message = __('Worker stop signal sent');
if ($this->_isRest()) {
return $this->RestResponse->saveSuccessResponse('Servers', 'stopWorker', $pid, $this->response->type(), $message);
} else {
$this->Flash->info($message);
$this->redirect('/servers/serverSettings/workers');
}
}
public function getWorkers()
{
$issues = 0;
$worker_array = $this->Server->workerDiagnostics($issues);
return $this->RestResponse->viewData($worker_array);
}
private function __checkVersion()
@ -1168,6 +1187,9 @@ class ServersController extends AppController
}
$setting = $this->Server->getSettingData($setting_name);
if (!empty($setting['cli_only'])) {
throw new MethodNotAllowedException(__('This setting can only be edited via the CLI.'));
}
if ($this->request->is('get')) {
if ($setting != null) {
$value = Configure::read($setting['name']);

View File

@ -1550,9 +1550,6 @@ class Attribute extends AppModel
$value = strtolower($value);
str_replace(':', '|', $value);
break;
case 'float':
$value = floatval($value);
break;
case 'hex':
$value = strtoupper($value);
break;

View File

@ -886,11 +886,10 @@ class MispObject extends AppModel
}
$attribute_types = array_keys($attribute_types);
$potential_templates = $this->ObjectTemplate->find('all', array(
$potential_templates = $this->ObjectTemplate->find('list', array(
'recursive' => -1,
'fields' => array(
'ObjectTemplate.id',
'ObjectTemplate.name',
'COUNT(ObjectTemplateElement.type) as type_count'
),
'conditions' => array(
@ -906,11 +905,11 @@ class MispObject extends AppModel
'conditions' => array('ObjectTemplate.id = ObjectTemplateElement.object_template_id')
)
),
'group' => 'ObjectTemplate.name',
'group' => 'ObjectTemplate.id',
'order' => 'type_count DESC'
));
$potential_template_ids = Hash::extract($potential_templates, '{n}.ObjectTemplate.id');
$potential_template_ids = array_keys($potential_templates);
$templates = $this->ObjectTemplate->find('all', array(
'recursive' => -1,
'conditions' => array('id' => $potential_template_ids),

View File

@ -192,6 +192,15 @@ class Server extends AppModel
'type' => 'boolean',
'null' => true
),
'server_settings_skip_backup_rotate' => array(
'level' => 1,
'description' => __('Enable this setting to directly save the config.php file without first creating a temporary file and moving it to avoid concurency issues. Generally not recommended, but useful when for example other tools modify/maintain the config.php file.'),
'value' => false,
'errorMessage' => '',
'test' => 'testBool',
'type' => 'boolean',
'null' => true
),
'python_bin' => array(
'level' => 1,
'description' => __('It is highly recommended to install all the python dependencies in a virtualenv. The recommended location is: %s/venv', ROOT),
@ -201,6 +210,7 @@ class Server extends AppModel
'test' => 'testForBinExec',
'beforeHook' => 'beforeHookBinExec',
'type' => 'string',
'cli_only' => 1
),
'disable_auto_logout' => array(
'level' => 1,
@ -456,6 +466,7 @@ class Server extends AppModel
'null' => false,
'test' => 'testForWritableDir',
'type' => 'string',
'cli_only' => 1
),
'cached_attachments' => array(
'level' => 1,
@ -847,6 +858,7 @@ class Server extends AppModel
'test' => 'testForPath',
'type' => 'string',
'null' => true,
'cli_only' => 1
),
'custom_css' => array(
'level' => 2,
@ -970,6 +982,7 @@ class Server extends AppModel
'errorMessage' => '',
'test' => 'testForGPGBinary',
'type' => 'string',
'cli_only' => 1
),
'onlyencrypted' => array(
'level' => 0,
@ -3076,6 +3089,9 @@ class Server extends AppModel
public function testForBinExec($value)
{
if (substr($value, 0, 7) === "phar://") {
return 'Phar protocol not allowed.';
}
$finfo = finfo_open(FILEINFO_MIME_TYPE);
if ($value === '') {
return true;
@ -3094,6 +3110,9 @@ class Server extends AppModel
public function testForWritableDir($value)
{
if (substr($value, 0, 7) === "phar://") {
return 'Phar protocol not allowed.';
}
if (!is_dir($value)) {
return 'Not a valid directory.';
}
@ -3724,26 +3743,30 @@ class Server extends AppModel
if (function_exists('opcache_reset')) {
opcache_reset();
}
$randomFilename = $this->generateRandomFileName();
// To protect us from 2 admin users having a concurent file write to the config file, solar flares and the bogeyman
file_put_contents(APP . 'Config' . DS . $randomFilename, $settingsString);
rename(APP . 'Config' . DS . $randomFilename, APP . 'Config' . DS . 'config.php');
$config_saved = file_get_contents(APP . 'Config' . DS . 'config.php');
// if the saved config file is empty, restore the backup.
if (strlen($config_saved) < 20) {
copy(APP . 'Config' . DS . 'config.php.bk', APP . 'Config' . DS . 'config.php');
$this->Log = ClassRegistry::init('Log');
$this->Log->create();
$this->Log->save(array(
'org' => 'SYSTEM',
'model' => 'Server',
'model_id' => $id,
'email' => 'SYSTEM',
'action' => 'error',
'user_id' => 0,
'title' => 'Error: Something went wrong saving the config file, reverted to backup file.',
));
return false;
if (empty(Configure::read('MISP.server_settings_skip_backup_rotate'))) {
$randomFilename = $this->generateRandomFileName();
// To protect us from 2 admin users having a concurent file write to the config file, solar flares and the bogeyman
file_put_contents(APP . 'Config' . DS . $randomFilename, $settingsString);
rename(APP . 'Config' . DS . $randomFilename, APP . 'Config' . DS . 'config.php');
$config_saved = file_get_contents(APP . 'Config' . DS . 'config.php');
// if the saved config file is empty, restore the backup.
if (strlen($config_saved) < 20) {
copy(APP . 'Config' . DS . 'config.php.bk', APP . 'Config' . DS . 'config.php');
$this->Log = ClassRegistry::init('Log');
$this->Log->create();
$this->Log->save(array(
'org' => 'SYSTEM',
'model' => 'Server',
'model_id' => $id,
'email' => 'SYSTEM',
'action' => 'error',
'user_id' => 0,
'title' => 'Error: Something went wrong saving the config file, reverted to backup file.',
));
return false;
}
} else {
file_put_contents(APP . 'Config' . DS . 'config.php', $settingsString);
}
return true;
}

View File

@ -0,0 +1,30 @@
<?php
$href_url = isset($href_url) ? $href_url : $baseurl . '/events';
$hide = isset($hide) ? $hide : false;
?>
<span class="<?php echo $hide ? 'hidden correlation-expanded-area' : '' ?>">
<span style="display: inline-block; border: 1px solid #ddd; border-radius: 5px; padding: 3px;">
<table>
<tbody>
<tr>
<td rowspan="2" style="border-right: 1px solid #ddd; padding-right: 2px">
<?php echo $this->OrgImg->getOrgImg(array('name' => $related['Orgc']['name'], 'id' => $related['Orgc']['id'], 'size' => 24)); ?>
</td>
<td style="line-height: 14px; padding-left: 2px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; max-width: 430px;">
<a title="<?php echo h($related['info']); ?>" href="<?php echo h($href_url) . '/' . $related['id']?>">
<span><?php echo h($related['info']) ?>
</a>
</td>
</tr>
<tr>
<td style="line-height: 14px; padding-left: 2px;">
<i><?php echo h($related['date']); ?></i>
<?php if (isset($relatedEventCorrelationCount[$related['id']])): ?>
<b style="margin-left: 5px; float: right;" title="<?php echo __(sprintf('This related event contains %s unique correlation(s)', h($relatedEventCorrelationCount[$related['id']]))); ?>"> <?php echo h($relatedEventCorrelationCount[$related['id']]) ?></b>
<?php endif; ?>
</td>
</tr>
</tbody>
</table>
</span>
</span>

View File

@ -21,14 +21,24 @@
?>
<span style="display:inline-block;">
<?php
$full = $isAclTagger && $tagAccess;
$full = $isAclTagger && $tagAccess && empty($static_tags_only);
$tagData = "";
foreach ($tags as $tag) {
if (empty($tag['Tag'])) {
$tag['Tag'] = $tag;
}
if (empty($tag['Tag']['colour'])) {
$tag['Tag']['colour'] = '#0088cc';
}
$aStyle = 'display:inline-block; background-color:' . h($tag['Tag']['colour']) . ';color:' . $this->TextColour->getTextColour($tag['Tag']['colour']) . ';';
$aClass = $full ? 'tagFirstHalf' : 'tag';
$aText = h($tag['Tag']['name']);
$aSearchTagUrl = $baseurl . '/events/index/searchtag: ' . h($tag['Tag']['id']);
$span1 = sprintf('<a href="%s" style="%s" class="%s">%s</a>', $aSearchTagUrl, $aStyle, $aClass, $aText);
if (!empty($tag['Tag']['id'])) {
$aSearchTagUrl = $baseurl . '/events/index/searchtag: ' . h($tag['Tag']['id']);
$span1 = sprintf('<a href="%s" style="%s" class="%s">%s</a>', $aSearchTagUrl, $aStyle, $aClass, $aText);
} else {
$span1 = sprintf('<span style="%s" class="%s">%s</span>', $aStyle, $aClass, $aText);
}
$span2 = '';
if ($full) {
$spanClass = "tagSecondHalf useCursorPointer noPrint";

View File

@ -315,6 +315,32 @@ attributes or the appropriate distribution level. If you think there is a mistak
url = "<?php echo $baseurl; ?>" + "/sightings/advanced/" + object_id + "/" + object_context;
genericPopup(url, '#popover_box');
});
$(".eventViewAttributeHover").mouseenter(function() {
$('#' + currentPopover).popover('destroy');
var type = $(this).attr('data-object-type');
var id = $(this).attr('data-object-id');
if (type + "_" + id in ajaxResults["hover"]) {
var element = $('#' + type + '_' + id + '_container');
element.popover({
title: attributeHoverTitle(id, type),
content: ajaxResults["hover"][type + "_" + id],
placement: attributeHoverPlacement(element),
html: true,
trigger: 'manual',
container: 'body'
}).popover('show');
currentPopover = type + '_' + id + '_container';
} else {
timer = setTimeout(function () {
runHoverLookup(type, id)
},
500
);
}
}).mouseout(function() {
clearTimeout(timer);
});
});
$('#attributesFilterField').bind("keydown", function(e) {
var eventid = $('#attributesFilterField').data("eventid");

View File

@ -28,7 +28,7 @@
'value_passive' => array(
'html' => nl2br(h($setting['value'])),
'class' => 'inline-field-solid live_filter_target',
'requirement' => ((isset($setting['editable']) && !$setting['editable'])),
'requirement' => ((isset($setting['editable']) && !$setting['editable']) || !empty($setting['cli_only'])),
'style' => 'width:500px;',
'id' => sprintf(
'setting_%s_%s_passive',
@ -39,7 +39,7 @@
'value_solid' => array(
'html' => nl2br(h($setting['value'])),
'class' => 'inline-field-solid live_filter_target',
'requirement' => ((!isset($setting['editable']) || $setting['editable'])),
'requirement' => ((!isset($setting['editable']) || $setting['editable']) && empty($setting['cli_only'])),
'style' => 'width:500px;',
'id' => sprintf(
'setting_%s_%s_solid',
@ -51,7 +51,7 @@
),
'value_placeholder' => array(
'class' => 'inline-field-placeholder hidden',
'requirement' => ((!isset($setting['editable']) || $setting['editable'])),
'requirement' => ((!isset($setting['editable']) || $setting['editable']) && empty($setting['cli_only'])),
'style' => 'width:500px;',
'id' => sprintf(
'setting_%s_%s_placeholder',
@ -60,7 +60,11 @@
)
),
'description' => array(
'html' => h($setting['description']),
'html' => sprintf(
'%s%s',
!empty($setting['cli_only']) ? sprintf('<span class="bold">[<span class="red">%s</span>]</span> ', __('CLI only')) : '',
h($setting['description'])
),
'class' => 'live_filter_target'
),
'error' => array(

View File

@ -16,8 +16,36 @@
?>
</ul>
</div>
<div>
<?php
$data = array(
'children' => array(
array(
'children' => array(
array(
'class' => 'hidden mass-select',
'fa-icon' => 'trash',
'onClick' => "multiSelectDeleteEventBlacklist",
'onClickParams' => array('1', '0')
)
)
),
array(
'type' => 'search',
'button' => __('Filter'),
'placeholder' => __('Enter value to search'),
'data' => '',
)
)
);
echo $this->element('/genericElements/ListTopBar/scaffold', array('data' => $data));
?>
</div>
<table class="table table-striped table-hover table-condensed">
<tr>
<th>
<input class="select_all select" type="checkbox" title="<?php echo __('Select all');?>" role="button" tabindex="0" aria-label="<?php echo __('Select all events on current page');?>" onClick="toggleAllCheckboxes();" />&nbsp;
</th>
<th><?php echo $this->Paginator->sort('id');?></th>
<th><?php echo $this->Paginator->sort('org');?></th>
<th><?php echo $this->Paginator->sort('event_uuid', __('Event UUID'));?></th>
@ -28,6 +56,9 @@
</tr><?php
foreach ($response as $item): ?>
<tr>
<td style="width:10px;">
<input class="select" type="checkbox" data-id="<?php echo h($item['EventBlacklist']['id']); ?>" aria-label="select <?php echo h($item['EventBlacklist']['id'])?>" />
</td>
<td class="short"><?php echo h($item['EventBlacklist']['id']); ?>&nbsp;</td>
<td class="short"><?php echo (isset($item['EventBlacklist']['event_orgc']) ? h($item['EventBlacklist']['event_orgc']) : '&nbsp;'); ?></td>
<td class="short"><?php echo h($item['EventBlacklist']['event_uuid']); ?>&nbsp;</td>
@ -35,7 +66,7 @@ foreach ($response as $item): ?>
<td class="short"><?php echo (isset($item['EventBlacklist']['event_info']) ? h($item['EventBlacklist']['event_info']) : '&nbsp;'); ?></td>
<td class="short"><?php echo (isset($item['EventBlacklist']['comment']) ? h($item['EventBlacklist']['comment']) : '&nbsp;'); ?></td>
<td class="short action-links">
<a href="<?php echo $baseurl;?>/eventBlacklists/edit/<?php echo h($item['EventBlacklist']['id']); ?>"><span class="fa fa-edit" title=<?php echo __('Edit')?> role="button" tabindex="0" aria-label="Edit blacklist entry">&nbsp;</span></a>
<a href="<?php echo $baseurl;?>/eventBlacklists/edit/<?php echo h($item['EventBlacklist']['id']); ?>"><span class="fa fa-edit black" title=<?php echo __('Edit')?> role="button" tabindex="0" aria-label="Edit blacklist entry">&nbsp;</span></a>
<?php echo $this->Form->postLink('', array('action' => 'delete', h($item['EventBlacklist']['id'])), array('class' => 'fa fa-trash', 'title' => __('Delete'), 'aria-label' => __('Delete')), __('Are you sure you want to delete the blacklist entry for the event UUID %s?', h($item['EventBlacklist']['event_uuid']))); ?>
</td>
</tr><?php
@ -59,6 +90,25 @@ endforeach; ?>
</div>
</div>
<script type="text/javascript">
$(document).ready(function(){
popoverStartup();
$('.select').on('change', function() {
listCheckboxesChecked();
});
$('.select').on('change', function() {
listCheckboxesChecked();
});
$('#quickFilterButton').click(function() {
runIndexQuickFilter();
});
$('#quickFilterField').on('keypress', function (e) {
if(e.which === 13) {
runIndexQuickFilter();
}
});
});
</script>
<?php
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'admin', 'menuItem' => 'eventBlacklists'));
?>

View File

@ -0,0 +1,29 @@
<div class="confirmation">
<?php
echo $this->Form->create('EventBlacklist', array('style' => 'margin:0px;', 'id' => 'PromptForm'));
echo $this->Form->input('ids', array(
'type' => 'hidden',
'div' => 'hidden',
'value' => json_encode($event_ids)
));
?>
<legend><?php echo __('Delete blacklisted events'); ?></legend>
<div style="padding-left:5px;padding-right:5px;padding-bottom:5px;">
<p><?php echo __('Are you sure you want to delete from the blacklist the selected events?'); ?></p>
<table>
<tr>
<td style="vertical-align:top">
<span role="button" tabindex="0" aria-label="Publish" title="Publish" id="PromptYesButton" class="btn btn-primary" onClick="submitPublish()">Yes</span>
</td>
<td style="width:540px;">
</td>
<td style="vertical-align:top;">
<span role="button" tabindex="0" aria-label="Cancel" title="Cancel" class="btn btn-inverse" id="PromptNoButton" onClick="cancelPrompt();">No</span>
</td>
</tr>
</table>
</div>
<?php
echo $this->Form->end();
?>
</div>

View File

@ -329,6 +329,17 @@
echo sprintf('<h3>%s</h3>', $data['title']);
echo sprintf('<p>%s</p>', implode(" ", $data['description']));
echo sprintf("<pre>%s</pre>", implode("\n", $data['url']));
$data = array(
'title' => __('Administering the background workers via the API.'),
'description' => array(
__('You can start/stop and view the bacground workers via the API.'),
sprintf('<br /><span class="bold">%s</span>: <code>%s/servers/%s</code><br />', __('Add worker'), $baseurl, 'startWorker/[queue_name]'),
sprintf('<span class="bold">%s</span>: <code>%s/servers/%s</code><br />', __('Stop worker'), $baseurl, 'stopWorker/[worker_pid]'),
sprintf('<span class="bold">%s</span>: <code>%s/servers/%s</code><br />', __('Get worker info'), $baseurl, 'getWorkers')
)
);
echo sprintf('<h3>%s</h3>', $data['title']);
echo sprintf('<p>%s</p>', implode(" ", $data['description']));
foreach ($command_line_functions as $clusterRef => $cluster) {
echo sprintf('<a id="%s"></a><h3>%s</h3>', $clusterRef, $cluster['header']);
echo sprintf('<p>%s:<br />', $cluster['description']);

View File

@ -337,33 +337,27 @@
<span class="inline">
<?php
$count = 0;
$display_threshold = 10;
$total = count($event['RelatedEvent']);
foreach ($event['RelatedEvent'] as $relatedEvent):
$count++;
$relatedData = array('Orgc' => $relatedEvent['Event']['Orgc']['name'], 'Date' => $relatedEvent['Event']['date'], 'Info' => $relatedEvent['Event']['info']);
$popover = '';
foreach ($relatedData as $k => $v) {
$popover .= '<span class=\'bold\'>' . h($k) . '</span>: <span class="blue">' . h($v) . '</span><br />';
}
if ($count == 11 && $total > 10):
if ($count == $display_threshold+1 && $total > $display_threshold):
?>
<div class="no-side-padding correlation-expand-button useCursorPointer linkButton blue"><?php echo __('Show (%s more)', $total - $count);?></div>
<?php
endif;
?>
<span data-toggle="popover" data-content="<?php echo h($popover); ?>" data-trigger="hover" class="<?php if ($count > 11) echo 'correlation-expanded-area'; ?>" style="white-space: nowrap;<?php echo ($count > 10) ? 'display:none;' : ''; ?>">
<?php
$linkText = $relatedEvent['Event']['date'] . ' (' . $relatedEvent['Event']['id'] . ')';
if ($relatedEvent['Event']['orgc_id'] == $me['org_id']) {
echo $this->Html->link($linkText, array('controller' => 'events', 'action' => 'view', $relatedEvent['Event']['id'], true, $event['Event']['id']), array('style' => 'color:red;'));
} else {
echo $this->Html->link($linkText, array('controller' => 'events', 'action' => 'view', $relatedEvent['Event']['id'], true, $event['Event']['id']));
}
?>
</span>&nbsp;
<?php
echo $this->element('/Events/View/related_event', array(
'related' => $relatedEvent['Event'],
'color_red' => $relatedEvent['Event']['orgc_id'] == $me['org_id'],
'hide' => $count > $display_threshold,
'relatedEventCorrelationCount' => $relatedEventCorrelationCount
));
?>
<?php
endforeach;
if ($total > 10):
if ($total > $display_threshold):
?>
<div class="no-side-padding correlation-collapse-button useCursorPointer linkButton blue" style="display:none;"><?php echo __('Collapse…');?></div>
<?php

View File

@ -12,7 +12,7 @@
<?php
if (!$ajax):
?>
<div class="view">
<div class="graph-view">
<?php endif; ?>
<span id="fullscreen-btn-correlation" class="fullscreen-btn-correlation btn btn-xs btn-primary" data-toggle="tooltip" data-placement="top" data-title="<?php echo __('Toggle fullscreen');?>"><span class="fa fa-desktop"></span></span>
<div id="chart" style="width:100%;height:100%"></div>
@ -30,6 +30,7 @@
<li id="expand"><?php echo __('Expand');?></li>
<li id="context-delete"><?php echo __('Delete');?></li>
</ul>
<button class="correlation-stop-btn btn btn-inverse" onClick="togglePhysics();" title="<?php echo __('Toggle the physics engine on/off.');?> ">Toggle physics</button>
<?php
if (!$ajax):
?>

View File

@ -78,11 +78,8 @@
?>
<?php foreach ($event['RelatedEvent'] as $i => $relatedEvent): ?>
<li class="<?php echo $i > $display_threshold ? 'correlation-expanded-area' : ''; ?>" style="<?php echo $i > $display_threshold ? 'display: none;' : ''; ?>">
<div title="<?php echo h($relatedEvent['Event'][0]['info']); ?>">
<a href = "<?php echo '/feeds/previewEvent/' . $feed['Feed']['id'] . '/' . $relatedEvent['Event'][0]['uuid']; ?>">
<?php echo h($relatedEvent['Event'][0]['date']) . ' (' . h($relatedEvent['Event'][0]['uuid']) . ')'; ?>
</a>
</div></li>
<?php echo $this->element('/Events/View/related_event', array('related' => $relatedEvent['Event'])); ?>
</li>
<?php if ($i == $display_threshold+1 && $total > $display_threshold): ?>
<div class="no-side-padding correlation-expand-button useCursorPointer linkButton blue"><?php echo __('Show (%s more)', $total - $i);?></div>
<?php endif; ?>

View File

@ -41,6 +41,12 @@
'active' => $all
)
)
),
array(
'type' => 'search',
'button' => __('Filter'),
'placeholder' => __('Enter value to search'),
'data' => '',
)
)
);
@ -141,5 +147,17 @@ endforeach; ?>
</ul>
</div>
</div>
<script type="text/javascript">
$(document).ready(function(){
$('#quickFilterButton').click(function() {
runIndexQuickFilter();
});
$('#quickFilterField').on('keypress', function (e) {
if(e.which === 13) {
runIndexQuickFilter();
}
});
});
</script>
<?php
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'objectTemplates', 'menuItem' => 'index'));

View File

@ -102,11 +102,12 @@
if (isset($relatedEvent['Event'][0])) $relatedEvent['Event'] = $relatedEvent['Event'][0];
?>
<li class="<?php echo $i > $display_threshold ? 'correlation-expanded-area' : ''; ?>" style="<?php echo $i > $display_threshold ? 'display: none;' : ''; ?>">
<div title="<?php echo h($relatedEvent['Event']['info']); ?>">
<a href = "<?php echo '/servers/previewEvent/' . $server['Server']['id'] . '/' . $relatedEvent['Event']['id']; ?>">
<?php echo h($relatedEvent['Event']['date']) . ' (' . h($relatedEvent['Event']['id']) . ')'; ?>
</a>
</div></li>
<?php echo $this->element('/Events/View/related_event', array(
'related' => $relatedEvent['Event'],
'relatedEventCorrelationCount' => array(),
'href_url' => $baseurl . '/servers/previewEvent/' . $server['Server']['id']
)); ?>
</li>
<?php if ($i == $display_threshold+1 && $total > $display_threshold): ?>
<div class="no-side-padding correlation-expand-button useCursorPointer linkButton blue"><?php echo __('Show (%s more)', $total - $i);?></div>
<?php endif; ?>

View File

@ -20,7 +20,7 @@
?>
<div class="input clear"></div>
<?php
echo $this->Form->input('gpgkey', array('label' => __('GnuPG key'), 'div' => 'clear', 'class' => 'input-xxlarge'));
echo $this->Form->input('gpgkey', array('label' => __('GnuPG key'), 'div' => 'clear', 'class' => 'input-xxlarge', 'placeholder' => __('Paste the user\'s GnuPG key here or try to retrieve it from the MIT key server by clicking on "Fetch GnuPG key" below.')));
?>
<div class="clear"><span role="button" tabindex="0" aria-label="<?php echo __('Fetch GnuPG key');?>" onClick="lookupPGPKey('UserEmail');" class="btn btn-inverse" style="margin-bottom:10px;"><?php echo __('Fetch GnuPG key');?></span></div>
<?php

@ -1 +1 @@
Subproject commit 8c69da1fd9c0be2ec742370f4918f0f88554644f
Subproject commit 9517c8b8782a9385874940eec6741a78597cad12

View File

@ -27,6 +27,10 @@ from mixbox.namespaces import NamespaceNotFoundError
from operator import attrgetter
from stix.core import STIXPackage
from collections import defaultdict
try:
import stix_edh
except ModuleNotFoundError:
pass
_MISP_dir = "/".join([p for p in os.path.dirname(os.path.realpath(__file__)).split('/')[:-3]])
_PyMISP_dir = '{_MISP_dir}/PyMISP'.format(_MISP_dir=_MISP_dir)
@ -206,11 +210,13 @@ class StixParser():
# Return type & value of an ip address attribute
@staticmethod
def handle_address(properties):
if properties.is_source:
ip_type = "ip-src"
if properties.category == 'e-mail':
attribute_type = 'email-src'
relation = 'from'
else:
ip_type = "ip-dst"
return ip_type, properties.address_value.value, "ip"
attribute_type = "ip-src" if properties.is_source else "ip-dst"
relation = 'ip'
return attribute_type, properties.address_value.value, relation
def handle_as(self, properties):
attributes = self.fetch_attributes_with_partial_key_parsing(properties, stix2misp_mapping._as_mapping)
@ -1099,12 +1105,14 @@ class ExternalStixParser(StixParser):
self.handle_object_case(attribute_type, attribute_value, compl_data, to_ids=True, object_uuid=uuid)
except AttributeError:
self.parse_description(indicator)
elif hasattr(observable, 'observable_composition') and observable.observable_composition:
self.parse_external_observable(observable.observable_composition.observables, to_ids=True)
if hasattr(indicator, 'related_indicators') and indicator.related_indicators:
for related_indicator in indicator.related_indicators:
self.parse_external_single_indicator(related_indicator.item)
# Parse observables of an external STIX document
def parse_external_observable(self, observables):
def parse_external_observable(self, observables, to_ids=False):
for observable in observables:
title = observable.title
observable_object = observable.object_
@ -1122,7 +1130,7 @@ class ExternalStixParser(StixParser):
object_uuid = self.fetch_uuid(observable_object.id_)
if isinstance(attribute_value, (str, int)):
# if the returned value is a simple value, we build an attribute
attribute = {'to_ids': False, 'uuid': object_uuid}
attribute = {'to_ids': to_ids, 'uuid': object_uuid}
if hasattr(observable, 'handling') and observable.handling:
attribute['Tag'] = []
for handling in observable.handling:
@ -1207,7 +1215,9 @@ def _update_namespaces():
# can add additional ones whenever it is needed
ADDITIONAL_NAMESPACES = [
Namespace('http://us-cert.gov/ciscp', 'CISCP',
'http://www.us-cert.gov/sites/default/files/STIX_Namespace/ciscp_vocab_v1.1.1.xsd')
'http://www.us-cert.gov/sites/default/files/STIX_Namespace/ciscp_vocab_v1.1.1.xsd'),
Namespace('http://taxii.mitre.org/messages/taxii_xml_binding-1.1', 'TAXII',
'http://docs.oasis-open.org/cti/taxii/v1.1.1/cs01/schemas/TAXII-XMLMessageBinding-Schema.xsd')
]
for namespace in ADDITIONAL_NAMESPACES:
register_namespace(namespace)
@ -1222,13 +1232,16 @@ def generate_event(filename, tries=0):
sys.exit()
_update_namespaces()
return generate_event(filename, 1)
except NotImplementedError:
print('ERROR - Missing python library: stix_edh', file=sys.stderr)
except Exception:
try:
import maec
print(2)
except ImportError:
print('ERROR - Missing python library: maec', file=sys.stderr)
print(3)
sys.exit(0)
sys.exit(0)
def main(args):
filename = '{}/tmp/{}'.format(os.path.dirname(args[0]), args[1])

@ -1 +1 @@
Subproject commit b82ab8bfd5e3b8e29b7b147053935cfc2d5868bc
Subproject commit 788371461432499007d558fc7acb4477c3d9a898

View File

@ -88,4 +88,15 @@ line.link {
cursor: nesw-resize;
}
.graph-view {
float: right;
width: calc(100% - 216px);
border-left: 1px solid #666;
padding: 0px 10px;
}
.correlation-stop-btn {
position: absolute;
top: 60px;
right:10px;
}

View File

@ -1,13 +1,24 @@
var pinNodes = true;
function togglePhysics() {
d3.selectAll(".node").each(
function(d) {
d.fixed = pinNodes;
}
);
pinNodes = !pinNodes;
}
$(document).ready( function() {
var currentMousePos = { x: -1, y: -1 };
$(document).mousemove(function(event) {
currentMousePos.x = event.pageX;
currentMousePos .x = event.pageX;
currentMousePos.y = event.pageY;
});
var margin = {top: -5, right: -5, bottom: -5, left: -5},
width = $(window).width() - margin.left - margin.right,
height = $(window).height() - 160 - margin.top - margin.bottom;
height = $(window).height() - 115 - margin.top - margin.bottom;
var menu_x_buffer_ = width - 150;
var menu_y_buffer = height - 100;
@ -524,5 +535,6 @@ $(document).ready( function() {
}
}
}
});
});

View File

@ -891,6 +891,22 @@ function multiSelectToggleFeeds(on, cache) {
});
}
function multiSelectDeleteEventBlacklist(on, cache) {
var selected = [];
$(".select").each(function() {
if ($(this).is(":checked")) {
var temp = $(this).data("id");
if (temp != null) {
selected.push(temp);
}
}
});
$.get("/eventBlacklists/massDelete?ids=" + JSON.stringify(selected), function(data) {
$("#confirmation_box").html(data);
openPopup("#confirmation_box");
});
}
function multiSelectAction(event, context) {
var settings = {
deleteAttributes: {
@ -4051,32 +4067,6 @@ $(document).ready(function() {
$('#quickFilterButton').trigger("click");
}
});
$(".eventViewAttributeHover").mouseenter(function() {
$('#' + currentPopover).popover('destroy');
var type = $(this).attr('data-object-type');
var id = $(this).attr('data-object-id');
if (type + "_" + id in ajaxResults["hover"]) {
var element = $('#' + type + '_' + id + '_container');
element.popover({
title: attributeHoverTitle(id, type),
content: ajaxResults["hover"][type + "_" + id],
placement: attributeHoverPlacement(element),
html: true,
trigger: 'manual',
container: 'body'
}).popover('show');
currentPopover = type + '_' + id + '_container';
} else {
timer = setTimeout(function () {
runHoverLookup(type, id)
},
500
);
}
}).mouseout(function() {
clearTimeout(timer);
});
$(".queryPopover").click(function() {
url = $(this).data('url');
id = $(this).data('id');
@ -4184,6 +4174,8 @@ function checkIfLoggedIn() {
if (data.slice(-2) !== 'OK') {
window.location.replace(baseurl + "/users/login");
}
}).fail(function() {
window.location.replace(baseurl + "/users/login");
});
}
setTimeout(function() { checkIfLoggedIn(); }, 5000);

View File

@ -703,7 +703,7 @@ sudo systemctl enable --now misp-workers.service
## 9.07/ misp-modules (WIP!)
```bash
# some misp-modules dependencies
sudo yum install openjpeg-devel gcc-c++ poppler-cpp-devel -y
sudo yum install openjpeg-devel gcc-c++ poppler-cpp-devel pkgconfig python-devel redhat-rpm-config -y
sudo chmod 2777 /usr/local/src
sudo chown root:users /usr/local/src

View File

@ -46,7 +46,16 @@ aptUpgrade () {
debug "Upgrading system"
checkAptLock
sudo apt-get update
sudo apt-get upgrade -qy
# If we run in non-interactive mode, make sure we do not stop all of a sudden
if [[ "${PACKER}" == "1" || "${UNATTENDED}" == "1" ]]; then
export DEBIAN_FRONTEND=noninteractive
export DEBIAN_PRIORITY=critical
sudo -E apt-get -qy -o "Dpkg::Options::=--force-confdef" -o "Dpkg::Options::=--force-confold" upgrade
sudo -E apt-get -qy autoclean
else
sudo apt-get upgrade -qy
fi
}
# <snippet-end 0_apt-upgrade.sh>
```
@ -173,6 +182,9 @@ installCore () {
# install lief
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install https://github.com/lief-project/packages/raw/lief-master-latest/pylief-0.9.0.dev.zip
# install zmq needed by mispzmq
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install zmq
# install python-magic
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install python-magic

View File

@ -57,9 +57,11 @@ MISPvars () {
# GPG configuration
GPG_REAL_NAME='Autogenerated Key'
# On a REAL install, please do not set a comment, see here for why: https://www.debian-administration.org/users/dkg/weblog/97
GPG_COMMENT='WARNING: MISP AutoGenerated Key consider this Key VOID!'
GPG_EMAIL_ADDRESS='admin@admin.test'
GPG_KEY_LENGTH='2048'
# 3072 bits used as per suggestions here: https://riseup.net/en/security/message-security/openpgp/best-practices
GPG_KEY_LENGTH='3072'
GPG_PASSPHRASE="$(openssl rand -hex 32)"
# debug alias to make sure people are not confused when blindly copy pasting blobs of code

View File

@ -95,7 +95,7 @@ checkCoreOS () {
if [[ -f "/etc/redhat-release" ]]; then
echo "This is some redhat flavour"
REDHAT=1
RHfla=$(cat /etc/redhat-release | cut -f 1 -d\ | tr [A-Z] [a-z])
RHfla=$(cat /etc/redhat-release | cut -f 1 -d\ | tr '[:upper:]' '[:lower:]')
fi
}
@ -107,7 +107,7 @@ checkFlavour () {
sudo apt install lsb-release dialog -y
fi
FLAVOUR=$(lsb_release -s -i |tr [A-Z] [a-z])
FLAVOUR=$(lsb_release -s -i |tr '[:upper:]' '[:lower:]')
if [ FLAVOUR == "ubuntu" ]; then
RELEASE=$(lsb_release -s -r)
debug "We detected the following Linux flavour: ${YELLOW}$(tr '[:lower:]' '[:upper:]' <<< ${FLAVOUR:0:1})${FLAVOUR:1} ${RELEASE}${NC}"
@ -225,6 +225,27 @@ checkFail () {
fi
}
ask_o () {
ANSWER=""
if [ -z "${1}" ]; then
echo "This function needs at least 1 parameter."
exit 1
fi
[ -z "${2}" ] && OPT1="y" || OPT1="${2}"
[ -z "${3}" ] && OPT2="n" || OPT2="${3}"
while true; do
case "${ANSWER}" in "${OPT1}" | "${OPT2}") break ;; esac
echo -e -n "${1} (${OPT1}/${OPT2}) "
read ANSWER
ANSWER=$(echo "${ANSWER}" | tr '[:upper:]' '[:lower:]')
done
}
# Check if misp user is present and if run as root
checkID () {
debug "Checking if run as root and $MISP_USER is present"
@ -235,7 +256,7 @@ checkID () {
if [[ "$UNATTENDED" != "1" ]]; then
echo "There is NO user called '$MISP_USER' create a user '$MISP_USER' (y) or continue as $USER (n)? (y/n) "
read ANSWER
ANSWER=$(echo $ANSWER |tr [A-Z] [a-z])
ANSWER=$(echo $ANSWER |tr '[:upper:]' '[:lower:]')
else
ANSWER="y"
fi
@ -378,7 +399,7 @@ setBaseURL () {
echo "You can now enter your own MISP_BASEURL, if you wish to NOT do that, the MISP_BASEURL will be empty, which will work, but ideally you configure it afterwards."
echo "Do you want to change it now? (y/n) "
read ANSWER
ANSWER=$(echo $ANSWER |tr [A-Z] [a-z])
ANSWER=$(echo $ANSWER |tr '[:upper:]' '[:lower:]')
if [[ "$ANSWER" == "y" ]]; then
if [[ ! -z $IP ]]; then
echo "It seems you have an interface called $IFACE UP with the following IP: $IP - FYI"
@ -706,6 +727,7 @@ genRCLOCAL () {
sed -i -e '$i \echo never > /sys/kernel/mm/transparent_hugepage/enabled\n' /etc/rc.local
sed -i -e '$i \echo 1024 > /proc/sys/net/core/somaxconn\n' /etc/rc.local
sed -i -e '$i \sysctl vm.overcommit_memory=1\n' /etc/rc.local
sed -i -e '$i \[ -f /etc/init.d/firstBoot ] && bash /etc/init.d/firstBoot\n' /etc/rc.local
}
# Run PyMISP tests

View File

@ -26,11 +26,14 @@
## vi misp-backup.conf # adjust values
## sudo bash misp-backup.sh 2>&1 | tee misp-backup.log
##
## TODO: Target directory, rudimentary free space check: stat -f --format="%a" OutputDirName
## TODO: Make sure no directories are blank
## TODO: Make sure no directories are blank, $OutputDirName==Done
## TODO: Review how much sense it makes to ask fo MySQL credentials when most of the script does auto detection anyway.
##
# This makes use of the standard variables used by the installer
eval "$(curl -fsSL https://raw.githubusercontent.com/MISP/MISP/2.4/docs/generic/globalVariables.md | grep -v \`\`\`)"
MISPvars > /dev/null 2>&1
# Leave empty for NO debug messages, if run with set -x or bash -x it will enable DEBUG by default
DEBUG=
@ -59,6 +62,10 @@ checkDiskFree () {
if [[ ! -e $1 ]]; then
echo "$1 does not exist, creating"
mkdir -p $1
if [[ $? != 0 ]]; then
echo "Could not create $1, please fix permissions."
exit 126
fi
fi
threshhold=90
free=$(df -l --sync --output=pcent $1 |tail -1|cut -f 1 -d% | tr -d \ )

View File

@ -27,6 +27,10 @@
# TODO: Move DB, check DB?
# TODO: Check db user exists.
# This makes use of the standard variables used by the installer
eval "$(curl -fsSL https://raw.githubusercontent.com/MISP/MISP/2.4/docs/generic/globalVariables.md | grep -v \`\`\`)"
MISPvars > /dev/null 2>&1
# Leave empty for NO debug messages, if run with set -x or bash -x it will enable DEBUG by default
DEBUG=

View File

@ -1 +1 @@
MISPPath=/var/www/MISP
PATH_TO_MISP=/var/www/MISP

View File

@ -25,6 +25,10 @@
## Time to set some variables
##
# This makes use of the standard variables used by the installer
eval "$(curl -fsSL https://raw.githubusercontent.com/MISP/MISP/2.4/docs/generic/globalVariables.md | grep -v \`\`\`)"
MISPvars > /dev/null 2>&1
LUSER_ID="$(id -u)"
if [[ "${LUSER_ID}" > "0" ]]; then
@ -54,17 +58,17 @@ fi
# Fill in any missing values with defaults
# MISP path
MISPPath=${MISPPath:-$(locate MISP/app/webroot/index.php|sed 's/\/app\/webroot\/index\.php//')}
PATH_TO_MISP=${PATH_TO_MISP:-$(locate MISP/app/webroot/index.php|sed 's/\/app\/webroot\/index\.php//')}
# database.php
MySQLUUser=$(grep -o -P "(?<='login' => ').*(?=')" $MISPPath/app/Config/database.php)
MySQLUPass=$(grep -o -P "(?<='password' => ').*(?=')" $MISPPath/app/Config/database.php)
MISPDB=$(grep -o -P "(?<='database' => ').*(?=')" $MISPPath/app/Config/database.php)
DB_Port=$(grep -o -P "(?<='port' => ).*(?=,)" $MISPPath/app/Config/database.php)
MISPDBHost=$(grep -o -P "(?<='host' => ').*(?=')" $MISPPath/app/Config/database.php)
MySQLUUser=$(grep -o -P "(?<='login' => ').*(?=')" $PATH_TO_MISP/app/Config/database.php)
MySQLUPass=$(grep -o -P "(?<='password' => ').*(?=')" $PATH_TO_MISP/app/Config/database.php)
MISPDB=$(grep -o -P "(?<='database' => ').*(?=')" $PATH_TO_MISP/app/Config/database.php)
DB_Port=$(grep -o -P "(?<='port' => ).*(?=,)" $PATH_TO_MISP/app/Config/database.php)
MISPDBHost=$(grep -o -P "(?<='host' => ').*(?=')" $PATH_TO_MISP/app/Config/database.php)
echo "Clearing data model cache files"
rm -f $MISPPath/app/tmp/cache/models/myapp_*
rm -f $MISPPath/app/tmp/cache/persistent/myapp_*
rm -f $PATH_TO_MISP/app/tmp/cache/models/myapp_*
rm -f $PATH_TO_MISP/app/tmp/cache/persistent/myapp_*
echo "Wiping MySQL tables"
echo "Removes all users and organizations, except default (id=1)"
@ -76,7 +80,7 @@ mysql --host $MISPDBHost -u $MySQLRUser -p$MySQLRPass $MISPDB < $SQL
echo "Inserting default values to MySQL tables"
TMP=/tmp/misp-wipe-$$.sql
cd $MISPPath
cd $PATH_TO_MISP
sed -n '/Default values for initial installation/ { s///; :a; n; p; ba; }' INSTALL/MYSQL.sql | egrep -v '(admin_settings|db_version)' > $TMP
mysql --host $MISPDBHost -u $MySQLRUser -p$MySQLRPass $MISPDB < $TMP
rm -f $TMP
@ -88,7 +92,7 @@ git clean -f -d -x app/tmp
git clean -f -d -x app/files
echo "Updating taxonomies"
baseurl=$(grep -o -P "(?<='baseurl' => ').*(?=')" $MISPPath/app/Config/config.php)
baseurl=$(grep -o -P "(?<='baseurl' => ').*(?=')" $PATH_TO_MISP/app/Config/config.php)
AuthKey=$(echo 'select authkey from users where role_id = 1 order by id limit 1;' | mysql -u $MySQLRUser -p$MySQLRPass $MISPDB 2>/dev/null | tail -1)
curl --header "Authorization: $AuthKey" --header "Accept: application/json" --header "Content-Type: application/json" -o /dev/null -s -X POST ${baseurl}/taxonomies/update