Merge remote-tracking branch 'origin/2.4' into eventTimeline-sightings

pull/5845/head
mokaddem 2020-04-30 08:38:39 +02:00
commit 8525dda7f8
No known key found for this signature in database
GPG Key ID: 164C473F627A06FA
73 changed files with 24226 additions and 12325 deletions

View File

@ -16,6 +16,7 @@
# 0/ Quick MISP Instance on Debian Based Linux - Status | # 0/ Quick MISP Instance on Debian Based Linux - Status |
#-------------------------------------------------------| #-------------------------------------------------------|
# #
# 20200412: Ubuntu 18.04.4 tested and working. -- sCl
# 20190302: Ubuntu 18.04.2 tested and working. -- sCl # 20190302: Ubuntu 18.04.2 tested and working. -- sCl
# 20190208: Kali Linux tested and working. -- sCl # 20190208: Kali Linux tested and working. -- sCl
# #
@ -376,18 +377,19 @@ EOF
checkInstaller () { checkInstaller () {
# Workaround: shasum is not available on RHEL, only checking sha512 # Workaround: shasum is not available on RHEL, only checking sha512
if [[ $FLAVOUR == "rhel" ]] || [[ $FLAVOUR == "centos" ]]; then if [[ $FLAVOUR == "rhel" ]] || [[ $FLAVOUR == "centos" ]]; then
INSTsum=$(sha512sum ${0} | cut -f1 -d\ ) INSTsum=$(sha512sum ${0} | cut -f1 -d\ )
/usr/bin/wget --no-cache -q -O /tmp/INSTALL.sh.sha512 https://raw.githubusercontent.com/MISP/MISP/2.4/INSTALL/INSTALL.sh.sha512 /usr/bin/wget --no-cache -q -O /tmp/INSTALL.sh.sha512 https://raw.githubusercontent.com/MISP/MISP/2.4/INSTALL/INSTALL.sh.sha512
chsum=$(cat /tmp/INSTALL.sh.sha512) chsum=$(cat /tmp/INSTALL.sh.sha512)
if [[ "${chsum}" == "${INSTsum}" ]]; then if [[ "${chsum}" == "${INSTsum}" ]]; then
echo "SHA512 matches" echo "SHA512 matches"
else else
echo "SHA512: ${chsum} does not match the installer sum of: ${INSTsum}" echo "SHA512: ${chsum} does not match the installer sum of: ${INSTsum}"
# exit 1 # uncomment when/if PR is merged # exit 1 # uncomment when/if PR is merged
fi fi
else else
# TODO: Implement $FLAVOUR checks and install depending on the platform we are on # TODO: Implement $FLAVOUR checks and install depending on the platform we are on
if [[ $(which shasum > /dev/null 2>&1 ; echo $?) != 0 ]]; then if [[ $(which shasum > /dev/null 2>&1 ; echo $?) != 0 ]]; then
sudo apt update
sudo apt install libdigest-sha-perl -qyy sudo apt install libdigest-sha-perl -qyy
fi fi
# SHAsums to be computed, not the -- notatiation is for ease of use with rhash # SHAsums to be computed, not the -- notatiation is for ease of use with rhash
@ -700,12 +702,20 @@ setBaseURL () {
MISP_BASEURL="https://misp.local" MISP_BASEURL="https://misp.local"
# Webserver configuration # Webserver configuration
FQDN='misp.local' FQDN='misp.local'
else elif [[ "$(checkManufacturer)" == "innotek GmbH" ]]; then
MISP_BASEURL='https://localhost:8443' MISP_BASEURL='https://localhost:8443'
IP=$(ip addr show | awk '$1 == "inet" {gsub(/\/.*$/, "", $2); print $2}' |grep -v "127.0.0.1" |tail -1) IP=$(ip addr show | awk '$1 == "inet" {gsub(/\/.*$/, "", $2); print $2}' |grep -v "127.0.0.1" |tail -1)
sudo iptables -t nat -A OUTPUT -p tcp --dport 8443 -j DNAT --to ${IP}:443 sudo iptables -t nat -A OUTPUT -p tcp --dport 8443 -j DNAT --to ${IP}:443
# Webserver configuration # Webserver configuration
FQDN='localhost.localdomain' FQDN='localhost.localdomain'
elif [[ "$(checkManufacturer)" == "VMware, Inc." ]]; then
MISP_BASEURL='""'
# Webserver configuration
FQDN='misp.local'
else
MISP_BASEURL='""'
# Webserver configuration
FQDN='misp.local'
fi fi
} }
@ -1136,6 +1146,26 @@ installCoreDeps () {
sudo apt install expect -qy sudo apt install expect -qy
} }
# Install Php 7.4 dependencies
installDepsPhp74 () {
debug "Installing PHP 7.4 dependencies"
PHP_ETC_BASE=/etc/php/7.4
PHP_INI=${PHP_ETC_BASE}/apache2/php.ini
sudo apt update
sudo apt install -qy \
libapache2-mod-php \
php php-cli \
php-dev \
php-json php-xml php-mysql php-opcache php-readline php-mbstring \
php-redis php-gnupg \
php-gd
for key in upload_max_filesize post_max_size max_execution_time max_input_time memory_limit
do
sudo sed -i "s/^\($key\).*/\1 = $(eval echo \${$key})/" $PHP_INI
done
}
# Install Php 7.3 deps # Install Php 7.3 deps
installDepsPhp73 () { installDepsPhp73 () {
debug "Installing PHP 7.3 dependencies" debug "Installing PHP 7.3 dependencies"
@ -1324,7 +1354,7 @@ installCore () {
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install git+https://github.com/kbandla/pydeep.git $SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install git+https://github.com/kbandla/pydeep.git
# install lief # 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 $SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install lief
# install zmq needed by mispzmq # install zmq needed by mispzmq
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install zmq redis $SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install zmq redis
@ -1467,6 +1497,7 @@ coreCAKE () {
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Plugin.Sightings_policy" 0 $SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Plugin.Sightings_policy" 0
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Plugin.Sightings_anonymise" false $SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Plugin.Sightings_anonymise" false
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Plugin.Sightings_range" 365 $SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Plugin.Sightings_range" 365
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Plugin.Sightings_sighting_db_enable" false
# Plugin CustomAuth tuneable # Plugin CustomAuth tuneable
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Plugin.CustomAuth_disable_logout" false $SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Plugin.CustomAuth_disable_logout" false
@ -1509,6 +1540,7 @@ coreCAKE () {
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.block_event_alert_tag" "no-alerts=\"true\"" $SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.block_event_alert_tag" "no-alerts=\"true\""
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.block_old_event_alert" false $SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.block_old_event_alert" false
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.block_old_event_alert_age" "" $SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.block_old_event_alert_age" ""
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.block_old_event_alert_by_date" ""
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.incoming_tags_disabled_by_default" false $SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.incoming_tags_disabled_by_default" false
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.maintenance_message" "Great things are happening! MISP is undergoing maintenance, but will return shortly. You can contact the administration at \$email." $SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.maintenance_message" "Great things are happening! MISP is undergoing maintenance, but will return shortly. You can contact the administration at \$email."
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.footermidleft" "This is an initial install" $SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.footermidleft" "This is an initial install"
@ -1526,6 +1558,10 @@ coreCAKE () {
# Force defaults to make MISP Server Settings less GREEN # Force defaults to make MISP Server Settings less GREEN
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Security.password_policy_length" 12 $SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Security.password_policy_length" 12
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Security.password_policy_complexity" '/^((?=.*\d)|(?=.*\W+))(?![\n])(?=.*[A-Z])(?=.*[a-z]).*$|.{16,}/' $SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Security.password_policy_complexity" '/^((?=.*\d)|(?=.*\W+))(?![\n])(?=.*[A-Z])(?=.*[a-z]).*$|.{16,}/'
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Security.self_registration_message" "If you would like to send us a registration request, please fill out the form below. Make sure you fill out as much information as possible in order to ease the task of the administrators."
# It is possible to updateMISP too, only here for reference how to to that on the CLI.
## $SUDO_WWW $RUN_PHP -- $CAKE Admin updateMISP
# Set MISP Live # Set MISP Live
$SUDO_WWW $RUN_PHP -- $CAKE Live $MISP_LIVE $SUDO_WWW $RUN_PHP -- $CAKE Live $MISP_LIVE
@ -1798,7 +1834,7 @@ mail2misp () {
sudo ldconfig sudo ldconfig
cd ../../mail_to_misp cd ../../mail_to_misp
$SUDO_CMD virtualenv -p python3 venv $SUDO_CMD virtualenv -p python3 venv
$SUDO_CMD ./venv/bin/pip install https://github.com/lief-project/packages/raw/lief-master-latest/pylief-0.9.0.dev.zip $SUDO_CMD ./venv/bin/pip install lief
$SUDO_CMD ./venv/bin/pip install -r requirements.txt $SUDO_CMD ./venv/bin/pip install -r requirements.txt
$SUDO_CMD cp mail_to_misp_config.py-example mail_to_misp_config.py $SUDO_CMD cp mail_to_misp_config.py-example mail_to_misp_config.py
##$SUDO cp mail_to_misp_config.py-example mail_to_misp_config.py ##$SUDO cp mail_to_misp_config.py-example mail_to_misp_config.py
@ -1852,7 +1888,7 @@ viper () {
# TODO: Check for current user install permissions # TODO: Check for current user install permissions
$SUDO_CMD git submodule update --init --recursive $SUDO_CMD git submodule update --init --recursive
echo "pip install deps" echo "pip install deps"
$SUDO_CMD ./venv/bin/pip install pefile olefile jbxapi Crypto pypdns pypssl r2pipe pdftools virustotal-api SQLAlchemy PrettyTable python-magic scrapy https://github.com/lief-project/packages/raw/lief-master-latest/pylief-0.9.0.dev.zip $SUDO_CMD ./venv/bin/pip install pefile olefile jbxapi Crypto pypdns pypssl r2pipe pdftools virustotal-api SQLAlchemy PrettyTable python-magic scrapy lief
$SUDO_CMD ./venv/bin/pip install . $SUDO_CMD ./venv/bin/pip install .
echo 'update-modules' |/usr/local/src/viper/venv/bin/viper echo 'update-modules' |/usr/local/src/viper/venv/bin/viper
cd /usr/local/src/viper-web cd /usr/local/src/viper-web
@ -1977,10 +2013,13 @@ installCoreRHEL () {
$SUDO_WWW git clone --branch master --single-branch https://github.com/lief-project/LIEF.git lief $SUDO_WWW git clone --branch master --single-branch https://github.com/lief-project/LIEF.git lief
$SUDO_WWW git clone https://github.com/CybOXProject/mixbox.git $SUDO_WWW git clone https://github.com/CybOXProject/mixbox.git
cd $PATH_TO_MISP/app/files/scripts/python-cybox
# If you umask is has been changed from the default, it is a good idea to reset it to 0022 before installing python modules # If you umask is has been changed from the default, it is a good idea to reset it to 0022 before installing python modules
UMASK=$(umask) UMASK=$(umask)
umask 0022 umask 0022
cd $PATH_TO_MISP/app/files/scripts/python-cybox
$SUDO_WWW $PATH_TO_MISP/venv/bin/pip install .
cd $PATH_TO_MISP/app/files/scripts/python-stix cd $PATH_TO_MISP/app/files/scripts/python-stix
$SUDO_WWW $PATH_TO_MISP/venv/bin/pip install . $SUDO_WWW $PATH_TO_MISP/venv/bin/pip install .
@ -2005,7 +2044,7 @@ installCoreRHEL () {
$SUDO_WWW $PATH_TO_MISP/venv/bin/pip install -U redis $SUDO_WWW $PATH_TO_MISP/venv/bin/pip install -U redis
# lief needs manual compilation # lief needs manual compilation
sudo yum install devtoolset-7 cmake3 cppcheck -y sudo yum install devtoolset-7 cmake3 cppcheck libcxx-devel -y
cd $PATH_TO_MISP/app/files/scripts/lief cd $PATH_TO_MISP/app/files/scripts/lief
$SUDO_WWW mkdir build $SUDO_WWW mkdir build
@ -2195,6 +2234,7 @@ apacheConfig_RHEL () {
sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/files/scripts/*.py sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/files/scripts/*.py
sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/files/scripts/*/*.py sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/files/scripts/*/*.py
sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/files/scripts/lief/build/api/python/lief.so sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/files/scripts/lief/build/api/python/lief.so
sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/Vendor/pear/crypt_gpg/scripts/crypt-gpg-pinentry
sudo chcon -R -t bin_t $PATH_TO_MISP/venv/bin/* sudo chcon -R -t bin_t $PATH_TO_MISP/venv/bin/*
find $PATH_TO_MISP/venv -type f -name "*.so*" -or -name "*.so.*" | xargs sudo chcon -t lib_t find $PATH_TO_MISP/venv -type f -name "*.so*" -or -name "*.so.*" | xargs sudo chcon -t lib_t
# Only run these if you want to be able to update MISP from the web interface # Only run these if you want to be able to update MISP from the web interface
@ -2391,8 +2431,8 @@ mispmodulesRHEL () {
[Service] [Service]
Type=simple Type=simple
User=apache User=$WWW_USER
Group=apache Group=$WWW_USER
WorkingDirectory=/usr/local/src/misp-modules WorkingDirectory=/usr/local/src/misp-modules
Environment="PATH=/var/www/MISP/venv/bin" Environment="PATH=/var/www/MISP/venv/bin"
ExecStart=\"${PATH_TO_MISP}/venv/bin/misp-modules -l 127.0.0.1 -s\" ExecStart=\"${PATH_TO_MISP}/venv/bin/misp-modules -l 127.0.0.1 -s\"
@ -2487,7 +2527,7 @@ generateInstaller () {
cp ../INSTALL.tpl.sh . cp ../INSTALL.tpl.sh .
# Pull code snippets out of Main Install Documents # Pull code snippets out of Main Install Documents
for f in `echo INSTALL.ubuntu1804.md xINSTALL.debian9.md INSTALL.kali.md xINSTALL.debian10.md xINSTALL.tsurugi.md xINSTALL.debian9-postgresql.md xINSTALL.ubuntu1804.with.webmin.md INSTALL.rhel7.md`; do for f in `echo INSTALL.ubuntu2004.md INSTALL.ubuntu1804.md xINSTALL.debian9.md INSTALL.kali.md xINSTALL.debian10.md xINSTALL.tsurugi.md xINSTALL.debian9-postgresql.md xINSTALL.ubuntu1804.with.webmin.md INSTALL.rhel7.md`; do
xsnippet . ../../docs/${f} xsnippet . ../../docs/${f}
done done
@ -2506,6 +2546,7 @@ generateInstaller () {
perl -pe 's/^## 0_apt-upgrade.sh ##/`cat 0_apt-upgrade.sh`/ge' -i INSTALL.tpl.sh perl -pe 's/^## 0_apt-upgrade.sh ##/`cat 0_apt-upgrade.sh`/ge' -i INSTALL.tpl.sh
perl -pe 's/^## 0_sudoKeeper.sh ##/`cat 0_sudoKeeper.sh`/ge' -i INSTALL.tpl.sh perl -pe 's/^## 0_sudoKeeper.sh ##/`cat 0_sudoKeeper.sh`/ge' -i INSTALL.tpl.sh
perl -pe 's/^## 0_installCoreDeps.sh ##/`cat 0_installCoreDeps.sh`/ge' -i INSTALL.tpl.sh perl -pe 's/^## 0_installCoreDeps.sh ##/`cat 0_installCoreDeps.sh`/ge' -i INSTALL.tpl.sh
perl -pe 's/^## 0_installDepsPhp74.sh ##/`cat 0_installDepsPhp74.sh`/ge' -i INSTALL.tpl.sh
perl -pe 's/^## 0_installDepsPhp73.sh ##/`cat 0_installDepsPhp73.sh`/ge' -i INSTALL.tpl.sh perl -pe 's/^## 0_installDepsPhp73.sh ##/`cat 0_installDepsPhp73.sh`/ge' -i INSTALL.tpl.sh
perl -pe 's/^## 0_installDepsPhp72.sh ##/`cat 0_installDepsPhp72.sh`/ge' -i INSTALL.tpl.sh perl -pe 's/^## 0_installDepsPhp72.sh ##/`cat 0_installDepsPhp72.sh`/ge' -i INSTALL.tpl.sh
perl -pe 's/^## 0_installDepsPhp70.sh ##/`cat 0_installDepsPhp70.sh`/ge' -i INSTALL.tpl.sh perl -pe 's/^## 0_installDepsPhp70.sh ##/`cat 0_installDepsPhp70.sh`/ge' -i INSTALL.tpl.sh
@ -2619,13 +2660,16 @@ installSupported () {
if [[ "$1" =~ ^PHP= ]]; then if [[ "$1" =~ ^PHP= ]]; then
PHP_VER=$(echo $1 |cut -f2 -d=) PHP_VER=$(echo $1 |cut -f2 -d=)
if [[ "$PHP_VER" == "7.2" ]]; then if [[ "$PHP_VER" == 7.2 ]]; then
# Install PHP 7.2 Dependencies - functionLocation('INSTALL.ubuntu1804.md') # Install PHP 7.2 Dependencies - functionLocation('INSTALL.ubuntu1804.md')
[[ -n $CORE ]] || [[ -n $ALL ]] && installDepsPhp72 [[ -n $CORE ]] || [[ -n $ALL ]] && installDepsPhp72
elif [[ "$PHP_VER" == "7.3" ]]; then elif [[ "$PHP_VER" == 7.3 ]]; then
# Install PHP 7.4 Dependencies - functionLocation('INSTALL.ubuntu2004.md')
[[ -n $CORE ]] || [[ -n $ALL ]] && installDepsPhp74
elif [[ "$PHP_VER" == 7.4 ]]; then
# Install PHP 7.3 Dependencies - functionLocation('generic/supportFunctions.md') # Install PHP 7.3 Dependencies - functionLocation('generic/supportFunctions.md')
[[ -n $CORE ]] || [[ -n $ALL ]] && installDepsPhp73 [[ -n $CORE ]] || [[ -n $ALL ]] && installDepsPhp73
elif [[ "$PHP_VER" == "7.0" ]]; then elif [[ "$PHP_VER" == 7.0 ]]; then
# Install PHP 7.0 Dependencies - functionLocation('generic/supportFunctions.md') # Install PHP 7.0 Dependencies - functionLocation('generic/supportFunctions.md')
[[ -n $CORE ]] || [[ -n $ALL ]] && installDepsPhp70 [[ -n $CORE ]] || [[ -n $ALL ]] && installDepsPhp70
fi fi
@ -2723,7 +2767,7 @@ installSupported () {
theEnd theEnd
} }
# Main Kalin Install function # Main Kali Install function
installMISPonKali () { installMISPonKali () {
# Kali might have a bug on installs where libc6 is not up to date, this forces bash and libc to update - functionLocation('') # Kali might have a bug on installs where libc6 is not up to date, this forces bash and libc to update - functionLocation('')
kaliUpgrade 2> /dev/null > /dev/null kaliUpgrade 2> /dev/null > /dev/null
@ -2838,7 +2882,7 @@ installMISPonKali () {
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install git+https://github.com/kbandla/pydeep.git 2> /dev/null > /dev/null $SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install git+https://github.com/kbandla/pydeep.git 2> /dev/null > /dev/null
# install lief # 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 2> /dev/null > /dev/null $SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install lief 2> /dev/null > /dev/null
# install python-magic # install python-magic
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install python-magic 2> /dev/null > /dev/null $SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install python-magic 2> /dev/null > /dev/null
@ -3138,6 +3182,7 @@ x86_64-fedora-30
x86_64-debian-stretch x86_64-debian-stretch
x86_64-debian-buster x86_64-debian-buster
x86_64-ubuntu-bionic x86_64-ubuntu-bionic
x86_64-ubuntu-focal
x86_64-kali-2019.1 x86_64-kali-2019.1
x86_64-kali-2019.2 x86_64-kali-2019.2
x86_64-kali-2019.3 x86_64-kali-2019.3
@ -3152,6 +3197,7 @@ armv7l-debian-jessie
armv7l-debian-stretch armv7l-debian-stretch
armv7l-debian-buster armv7l-debian-buster
armv7l-ubuntu-bionic armv7l-ubuntu-bionic
armv7l-ubuntu-focal
" "
# Check if we actually support this configuration # Check if we actually support this configuration
@ -3173,12 +3219,18 @@ if [ "${FLAVOUR}" == "ubuntu" ]; then
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues" echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
installSupported && exit || exit installSupported && exit || exit
fi fi
if [ "${RELEASE}" == "20.04" ]; then
echo "Install on Ubuntu 20.04 LTS fully supported."
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
installSupported PHP="7.4" && exit || exit
fi
if [ "${RELEASE}" == "18.10" ]; then if [ "${RELEASE}" == "18.10" ]; then
echo "Install on Ubuntu 18.10 partially supported, bye." echo "Install on Ubuntu 18.10 partially supported, bye."
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
installSupported && exit || exit installSupported && exit || exit
fi fi
if [ "${RELEASE}" == "19.04" ]; then if [ "${RELEASE}" == "19.04" ]; then
echo "Install on Ubuntu 19.04 under development." echo "Install on Ubuntu 19.04 partially supported bye."
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues" echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
installSupported && exit || exit installSupported && exit || exit
exit 1 exit 1

View File

@ -1,5 +1,5 @@
; Generated by RHash v1.3.9 on 2020-03-28 at 11:27.22 ; Generated by RHash v1.3.8 on 2020-04-30 at 15:20.13
; Written by Kravchenko Aleksey (Akademgorodok) - http://rhash.sf.net/ ; Written by Kravchenko Aleksey (Akademgorodok) - http://rhash.sf.net/
; ;
; 129017 11:27.22 2020-03-28 INSTALL.sh ; 131010 15:20.13 2020-04-30 INSTALL.sh
INSTALL.sh D13A40A737C9FC7BCB6085F7557EAE47E48AF57A FBD4920A02D7811FF6280306FE1ED0CF6ADDD3707B2E0F9D1FF58F808CC92784 66A1518CCBBAC090C84748D59BE0D45CF9EB4882AF3B65CFA0E0F1CD76CE82D928A5EB16B4927A297C29BBE964B104F9 ED28FA2445A350193E6089E44E1451E34DE3C4A49643B8A8F2690488067AD05E806FA5A169044525F4686D3E5171F6A8EE65415EF5BB3DE6884BA93F9EE7BA05 INSTALL.sh 660E0D51D88B57CE5BE725117482207E39371038 DCF69118CD37B43C308FD25E6BADAF03549BAF0FFA2AC11A1E919005D700F4AC 74E03A8054AF2E4BCB90426A3B813F57BF032734AB7B4E9D4F6F96961D7371FB051180BEE8357642EB9CC58603C13DA3 C4D1D02980808A92E8E11C72A49AA354DDEFA71C6E85FAC739645CEDEB4B36415243F7FB4B8BC75B6AE7B5D9660E0F88A35E884EBD51EA107128B0D7FB20C946

View File

@ -1 +1 @@
d13a40a737c9fc7bcb6085f7557eae47e48af57a INSTALL.sh 660e0d51d88b57ce5be725117482207e39371038 INSTALL.sh

View File

@ -1 +1 @@
fbd4920a02d7811ff6280306fe1ed0cf6addd3707b2e0f9d1ff58f808cc92784 INSTALL.sh dcf69118cd37b43c308fd25e6badaf03549baf0ffa2ac11a1e919005d700f4ac INSTALL.sh

View File

@ -1 +1 @@
66a1518ccbbac090c84748d59be0d45cf9eb4882af3b65cfa0e0f1cd76ce82d928a5eb16b4927a297c29bbe964b104f9 INSTALL.sh 74e03a8054af2e4bcb90426a3b813f57bf032734ab7b4e9d4f6f96961d7371fb051180bee8357642eb9cc58603c13da3 INSTALL.sh

View File

@ -1 +1 @@
ed28fa2445a350193e6089e44e1451e34de3c4a49643b8a8f2690488067ad05e806fa5a169044525f4686d3e5171f6a8ee65415ef5bb3de6884ba93f9ee7ba05 INSTALL.sh c4d1d02980808a92e8e11c72a49aa354ddefa71c6e85fac739645cedeb4b36415243f7fb4b8bc75b6ae7b5d9660e0f88a35e884ebd51ea107128b0d7fb20c946 INSTALL.sh

View File

@ -16,6 +16,7 @@
# 0/ Quick MISP Instance on Debian Based Linux - Status | # 0/ Quick MISP Instance on Debian Based Linux - Status |
#-------------------------------------------------------| #-------------------------------------------------------|
# #
# 20200412: Ubuntu 18.04.4 tested and working. -- sCl
# 20190302: Ubuntu 18.04.2 tested and working. -- sCl # 20190302: Ubuntu 18.04.2 tested and working. -- sCl
# 20190208: Kali Linux tested and working. -- sCl # 20190208: Kali Linux tested and working. -- sCl
# #
@ -70,6 +71,7 @@
## 0_apt-upgrade.sh ## ## 0_apt-upgrade.sh ##
## 0_sudoKeeper.sh ## ## 0_sudoKeeper.sh ##
## 0_installCoreDeps.sh ## ## 0_installCoreDeps.sh ##
## 0_installDepsPhp74.sh ##
## 0_installDepsPhp73.sh ## ## 0_installDepsPhp73.sh ##
## 0_installDepsPhp72.sh ## ## 0_installDepsPhp72.sh ##
## 0_installDepsPhp70.sh ## ## 0_installDepsPhp70.sh ##
@ -143,7 +145,7 @@ generateInstaller () {
cp ../INSTALL.tpl.sh . cp ../INSTALL.tpl.sh .
# Pull code snippets out of Main Install Documents # Pull code snippets out of Main Install Documents
for f in `echo INSTALL.ubuntu1804.md xINSTALL.debian9.md INSTALL.kali.md xINSTALL.debian10.md xINSTALL.tsurugi.md xINSTALL.debian9-postgresql.md xINSTALL.ubuntu1804.with.webmin.md INSTALL.rhel7.md`; do for f in `echo INSTALL.ubuntu2004.md INSTALL.ubuntu1804.md xINSTALL.debian9.md INSTALL.kali.md xINSTALL.debian10.md xINSTALL.tsurugi.md xINSTALL.debian9-postgresql.md xINSTALL.ubuntu1804.with.webmin.md INSTALL.rhel7.md`; do
xsnippet . ../../docs/${f} xsnippet . ../../docs/${f}
done done
@ -162,6 +164,7 @@ generateInstaller () {
perl -pe 's/^## 0_apt-upgrade.sh ##/`cat 0_apt-upgrade.sh`/ge' -i INSTALL.tpl.sh perl -pe 's/^## 0_apt-upgrade.sh ##/`cat 0_apt-upgrade.sh`/ge' -i INSTALL.tpl.sh
perl -pe 's/^## 0_sudoKeeper.sh ##/`cat 0_sudoKeeper.sh`/ge' -i INSTALL.tpl.sh perl -pe 's/^## 0_sudoKeeper.sh ##/`cat 0_sudoKeeper.sh`/ge' -i INSTALL.tpl.sh
perl -pe 's/^## 0_installCoreDeps.sh ##/`cat 0_installCoreDeps.sh`/ge' -i INSTALL.tpl.sh perl -pe 's/^## 0_installCoreDeps.sh ##/`cat 0_installCoreDeps.sh`/ge' -i INSTALL.tpl.sh
perl -pe 's/^## 0_installDepsPhp74.sh ##/`cat 0_installDepsPhp74.sh`/ge' -i INSTALL.tpl.sh
perl -pe 's/^## 0_installDepsPhp73.sh ##/`cat 0_installDepsPhp73.sh`/ge' -i INSTALL.tpl.sh perl -pe 's/^## 0_installDepsPhp73.sh ##/`cat 0_installDepsPhp73.sh`/ge' -i INSTALL.tpl.sh
perl -pe 's/^## 0_installDepsPhp72.sh ##/`cat 0_installDepsPhp72.sh`/ge' -i INSTALL.tpl.sh perl -pe 's/^## 0_installDepsPhp72.sh ##/`cat 0_installDepsPhp72.sh`/ge' -i INSTALL.tpl.sh
perl -pe 's/^## 0_installDepsPhp70.sh ##/`cat 0_installDepsPhp70.sh`/ge' -i INSTALL.tpl.sh perl -pe 's/^## 0_installDepsPhp70.sh ##/`cat 0_installDepsPhp70.sh`/ge' -i INSTALL.tpl.sh
@ -275,13 +278,16 @@ installSupported () {
if [[ "$1" =~ ^PHP= ]]; then if [[ "$1" =~ ^PHP= ]]; then
PHP_VER=$(echo $1 |cut -f2 -d=) PHP_VER=$(echo $1 |cut -f2 -d=)
if [[ "$PHP_VER" == "7.2" ]]; then if [[ "$PHP_VER" == 7.2 ]]; then
# Install PHP 7.2 Dependencies - functionLocation('INSTALL.ubuntu1804.md') # Install PHP 7.2 Dependencies - functionLocation('INSTALL.ubuntu1804.md')
[[ -n $CORE ]] || [[ -n $ALL ]] && installDepsPhp72 [[ -n $CORE ]] || [[ -n $ALL ]] && installDepsPhp72
elif [[ "$PHP_VER" == "7.3" ]]; then elif [[ "$PHP_VER" == 7.3 ]]; then
# Install PHP 7.4 Dependencies - functionLocation('INSTALL.ubuntu2004.md')
[[ -n $CORE ]] || [[ -n $ALL ]] && installDepsPhp74
elif [[ "$PHP_VER" == 7.4 ]]; then
# Install PHP 7.3 Dependencies - functionLocation('generic/supportFunctions.md') # Install PHP 7.3 Dependencies - functionLocation('generic/supportFunctions.md')
[[ -n $CORE ]] || [[ -n $ALL ]] && installDepsPhp73 [[ -n $CORE ]] || [[ -n $ALL ]] && installDepsPhp73
elif [[ "$PHP_VER" == "7.0" ]]; then elif [[ "$PHP_VER" == 7.0 ]]; then
# Install PHP 7.0 Dependencies - functionLocation('generic/supportFunctions.md') # Install PHP 7.0 Dependencies - functionLocation('generic/supportFunctions.md')
[[ -n $CORE ]] || [[ -n $ALL ]] && installDepsPhp70 [[ -n $CORE ]] || [[ -n $ALL ]] && installDepsPhp70
fi fi
@ -379,7 +385,7 @@ installSupported () {
theEnd theEnd
} }
# Main Kalin Install function # Main Kali Install function
installMISPonKali () { installMISPonKali () {
# Kali might have a bug on installs where libc6 is not up to date, this forces bash and libc to update - functionLocation('') # Kali might have a bug on installs where libc6 is not up to date, this forces bash and libc to update - functionLocation('')
kaliUpgrade 2> /dev/null > /dev/null kaliUpgrade 2> /dev/null > /dev/null
@ -494,7 +500,7 @@ installMISPonKali () {
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install git+https://github.com/kbandla/pydeep.git 2> /dev/null > /dev/null $SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install git+https://github.com/kbandla/pydeep.git 2> /dev/null > /dev/null
# install lief # 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 2> /dev/null > /dev/null $SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install lief 2> /dev/null > /dev/null
# install python-magic # install python-magic
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install python-magic 2> /dev/null > /dev/null $SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install python-magic 2> /dev/null > /dev/null
@ -794,6 +800,7 @@ x86_64-fedora-30
x86_64-debian-stretch x86_64-debian-stretch
x86_64-debian-buster x86_64-debian-buster
x86_64-ubuntu-bionic x86_64-ubuntu-bionic
x86_64-ubuntu-focal
x86_64-kali-2019.1 x86_64-kali-2019.1
x86_64-kali-2019.2 x86_64-kali-2019.2
x86_64-kali-2019.3 x86_64-kali-2019.3
@ -808,6 +815,7 @@ armv7l-debian-jessie
armv7l-debian-stretch armv7l-debian-stretch
armv7l-debian-buster armv7l-debian-buster
armv7l-ubuntu-bionic armv7l-ubuntu-bionic
armv7l-ubuntu-focal
" "
# Check if we actually support this configuration # Check if we actually support this configuration
@ -829,12 +837,18 @@ if [ "${FLAVOUR}" == "ubuntu" ]; then
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues" echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
installSupported && exit || exit installSupported && exit || exit
fi fi
if [ "${RELEASE}" == "20.04" ]; then
echo "Install on Ubuntu 20.04 LTS fully supported."
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
installSupported PHP="7.4" && exit || exit
fi
if [ "${RELEASE}" == "18.10" ]; then if [ "${RELEASE}" == "18.10" ]; then
echo "Install on Ubuntu 18.10 partially supported, bye." echo "Install on Ubuntu 18.10 partially supported, bye."
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
installSupported && exit || exit installSupported && exit || exit
fi fi
if [ "${RELEASE}" == "19.04" ]; then if [ "${RELEASE}" == "19.04" ]; then
echo "Install on Ubuntu 19.04 under development." echo "Install on Ubuntu 19.04 partially supported bye."
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues" echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
installSupported && exit || exit installSupported && exit || exit
exit 1 exit 1

View File

@ -916,7 +916,7 @@ CREATE TABLE IF NOT EXISTS `shadow_attribute_correlations` (
-- Table structure for table `sharing_group_orgs` -- Table structure for table `sharing_group_orgs`
-- --
CREATE TABLE `sharing_group_orgs` ( CREATE TABLE IF NOT EXISTS `sharing_group_orgs` (
`id` int(11) NOT NULL AUTO_INCREMENT, `id` int(11) NOT NULL AUTO_INCREMENT,
`sharing_group_id` int(11) NOT NULL, `sharing_group_id` int(11) NOT NULL,
`org_id` int(11) NOT NULL, `org_id` int(11) NOT NULL,
@ -932,7 +932,7 @@ CREATE TABLE `sharing_group_orgs` (
-- Table structure for table `sharing_group_servers` -- Table structure for table `sharing_group_servers`
-- --
CREATE TABLE `sharing_group_servers` ( CREATE TABLE IF NOT EXISTS `sharing_group_servers` (
`id` int(11) NOT NULL AUTO_INCREMENT, `id` int(11) NOT NULL AUTO_INCREMENT,
`sharing_group_id` int(11) NOT NULL, `sharing_group_id` int(11) NOT NULL,
`server_id` int(11) NOT NULL, `server_id` int(11) NOT NULL,
@ -948,7 +948,7 @@ CREATE TABLE `sharing_group_servers` (
-- Table structure for table `sharing_groups` -- Table structure for table `sharing_groups`
-- --
CREATE TABLE `sharing_groups` ( CREATE TABLE IF NOT EXISTS `sharing_groups` (
`id` int(11) NOT NULL AUTO_INCREMENT, `id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`releasability` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, `releasability` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
@ -1355,14 +1355,14 @@ CREATE TABLE IF NOT EXISTS `whitelist` (
-- Default values for initial installation -- Default values for initial installation
-- --
INSERT INTO `admin_settings` (`id`, `setting`, `value`) VALUES INSERT IGNORE INTO `admin_settings` (`id`, `setting`, `value`) VALUES
(1, 'db_version', '40'); (1, 'db_version', '40');
INSERT INTO `feeds` (`id`, `provider`, `name`, `url`, `distribution`, `default`, `enabled`) VALUES INSERT IGNORE INTO `feeds` (`id`, `provider`, `name`, `url`, `distribution`, `default`, `enabled`) VALUES
(1, 'CIRCL', 'CIRCL OSINT Feed', 'https://www.circl.lu/doc/misp/feed-osint', 3, 1, 0), (1, 'CIRCL', 'CIRCL OSINT Feed', 'https://www.circl.lu/doc/misp/feed-osint', 3, 1, 0),
(2, 'Botvrij.eu', 'The Botvrij.eu Data', 'https://www.botvrij.eu/data/feed-osint', 3, 1, 0); (2, 'Botvrij.eu', 'The Botvrij.eu Data', 'https://www.botvrij.eu/data/feed-osint', 3, 1, 0);
INSERT INTO `regexp` (`id`, `regexp`, `replacement`, `type`) VALUES INSERT IGNORE INTO `regexp` (`id`, `regexp`, `replacement`, `type`) VALUES
(1, '/.:.ProgramData./i', '%ALLUSERSPROFILE%\\\\', 'ALL'), (1, '/.:.ProgramData./i', '%ALLUSERSPROFILE%\\\\', 'ALL'),
(2, '/.:.Documents and Settings.All Users./i', '%ALLUSERSPROFILE%\\\\', 'ALL'), (2, '/.:.Documents and Settings.All Users./i', '%ALLUSERSPROFILE%\\\\', 'ALL'),
(3, '/.:.Program Files.Common Files./i', '%COMMONPROGRAMFILES%\\\\', 'ALL'), (3, '/.:.Program Files.Common Files./i', '%COMMONPROGRAMFILES%\\\\', 'ALL'),
@ -1407,22 +1407,22 @@ INSERT INTO `feeds` (`id`, `provider`, `name`, `url`, `distribution`, `default`,
-- 7. Read Only - read -- 7. Read Only - read
-- --
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_publish_zmq`, `perm_publish_kafka`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `perm_object_template`, `perm_decaying`, `default_role`) INSERT IGNORE INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_publish_zmq`, `perm_publish_kafka`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `perm_object_template`, `perm_decaying`, `default_role`)
VALUES (1, 'admin', NOW(), NOW(), 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0); VALUES (1, 'admin', NOW(), NOW(), 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0);
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_publish_zmq`, `perm_publish_kafka`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `perm_object_template`, `perm_decaying`, `default_role`) INSERT IGNORE INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_publish_zmq`, `perm_publish_kafka`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `perm_object_template`, `perm_decaying`, `default_role`)
VALUES (2, 'Org Admin', NOW(), NOW(), 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0); VALUES (2, 'Org Admin', NOW(), NOW(), 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0);
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_publish_zmq`, `perm_publish_kafka`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `perm_object_template`, `perm_decaying`, `default_role`) INSERT IGNORE INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_publish_zmq`, `perm_publish_kafka`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `perm_object_template`, `perm_decaying`, `default_role`)
VALUES (3, 'User', NOW(), NOW(), 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1); VALUES (3, 'User', NOW(), NOW(), 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1);
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_publish_zmq`, `perm_publish_kafka`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `perm_object_template`, `perm_decaying`, `default_role`) INSERT IGNORE INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_publish_zmq`, `perm_publish_kafka`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `perm_object_template`, `perm_decaying`, `default_role`)
VALUES (4, 'Publisher', NOW(), NOW(), 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0); VALUES (4, 'Publisher', NOW(), NOW(), 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0);
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_publish_zmq`, `perm_publish_kafka`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `perm_object_template`, `perm_decaying`, `default_role`) INSERT IGNORE INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_publish_zmq`, `perm_publish_kafka`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `perm_object_template`, `perm_decaying`, `default_role`)
VALUES (5, 'Sync user', NOW(), NOW(), 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0); VALUES (5, 'Sync user', NOW(), NOW(), 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0);
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_publish_zmq`, `perm_publish_kafka`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `perm_object_template`, `perm_decaying`, `default_role`) INSERT IGNORE INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_publish_zmq`, `perm_publish_kafka`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `perm_object_template`, `perm_decaying`, `default_role`)
VALUES (6, 'Read Only', NOW(), NOW(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); VALUES (6, 'Read Only', NOW(), NOW(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-- -------------------------------------------------------- -- --------------------------------------------------------
@ -1431,7 +1431,7 @@ VALUES (6, 'Read Only', NOW(), NOW(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
-- Initial threat levels -- Initial threat levels
-- --
INSERT INTO `threat_levels` (`id`, `name`, `description`, `form_description`) INSERT IGNORE INTO `threat_levels` (`id`, `name`, `description`, `form_description`)
VALUES VALUES
(1, 'High', '*high* means sophisticated APT malware or 0-day attack', 'Sophisticated APT malware or 0-day attack'), (1, 'High', '*high* means sophisticated APT malware or 0-day attack', 'Sophisticated APT malware or 0-day attack'),
(2, 'Medium', '*medium* means APT malware', 'APT malware'), (2, 'Medium', '*medium* means APT malware', 'APT malware'),
@ -1444,13 +1444,13 @@ VALUES
-- Default templates -- Default templates
-- --
INSERT INTO `templates` (`id`, `name`, `description`, `org`, `share`) VALUES INSERT IGNORE INTO `templates` (`id`, `name`, `description`, `org`, `share`) VALUES
(1, 'Phishing E-mail', 'Create a MISP event about a Phishing E-mail.', 'MISP', 1), (1, 'Phishing E-mail', 'Create a MISP event about a Phishing E-mail.', 'MISP', 1),
(2, 'Phishing E-mail with malicious attachment', 'A MISP event based on Spear-phishing containing a malicious attachment. This event can include anything from the description of the e-mail itself, the malicious attachment and its description as well as the results of the analysis done on the malicious f', 'MISP', 1), (2, 'Phishing E-mail with malicious attachment', 'A MISP event based on Spear-phishing containing a malicious attachment. This event can include anything from the description of the e-mail itself, the malicious attachment and its description as well as the results of the analysis done on the malicious f', 'MISP', 1),
(3, 'Malware Report', 'This is a template for a generic malware report. ', 'MISP', 1), (3, 'Malware Report', 'This is a template for a generic malware report. ', 'MISP', 1),
(4, 'Indicator List', 'A simple template for indicator lists.', 'MISP', 1); (4, 'Indicator List', 'A simple template for indicator lists.', 'MISP', 1);
INSERT INTO `template_elements` (`id`, `template_id`, `position`, `element_definition`) VALUES INSERT IGNORE INTO `template_elements` (`id`, `template_id`, `position`, `element_definition`) VALUES
(1, 1, 2, 'attribute'), (1, 1, 2, 'attribute'),
(2, 1, 3, 'attribute'), (2, 1, 3, 'attribute'),
(3, 1, 1, 'text'), (3, 1, 1, 'text'),
@ -1497,7 +1497,7 @@ INSERT INTO `template_elements` (`id`, `template_id`, `position`, `element_defin
(46, 4, 2, 'attribute'), (46, 4, 2, 'attribute'),
(47, 4, 3, 'attribute'); (47, 4, 3, 'attribute');
INSERT INTO `template_element_attributes` (`id`, `template_element_id`, `name`, `description`, `to_ids`, `category`, `complex`, `type`, `mandatory`, `batch`) VALUES INSERT IGNORE INTO `template_element_attributes` (`id`, `template_element_id`, `name`, `description`, `to_ids`, `category`, `complex`, `type`, `mandatory`, `batch`) VALUES
(1, 1, 'From address', 'The source address from which the e-mail was sent.', 1, 'Payload delivery', 0, 'email-src', 1, 1), (1, 1, 'From address', 'The source address from which the e-mail was sent.', 1, 'Payload delivery', 0, 'email-src', 1, 1),
(2, 2, 'Malicious url', 'The malicious url in the e-mail body.', 1, 'Payload delivery', 0, 'url', 1, 1), (2, 2, 'Malicious url', 'The malicious url in the e-mail body.', 1, 'Payload delivery', 0, 'url', 1, 1),
(3, 4, 'E-mail subject', 'The subject line of the e-mail.', 0, 'Payload delivery', 0, 'email-subject', 1, 0), (3, 4, 'E-mail subject', 'The subject line of the e-mail.', 0, 'Payload delivery', 0, 'email-subject', 1, 0),
@ -1529,13 +1529,13 @@ INSERT INTO `template_element_attributes` (`id`, `template_element_id`, `name`,
(29, 46, 'Network Indicators', 'Paste any combination of IP addresses, hostnames, domains or URL', 1, 'Network activity', 1, 'CnC', 0, 1), (29, 46, 'Network Indicators', 'Paste any combination of IP addresses, hostnames, domains or URL', 1, 'Network activity', 1, 'CnC', 0, 1),
(30, 47, 'File Indicators', 'Paste any file hashes that you have (MD5, SHA1, SHA256) or filenames below. You can also add filename and hash pairs by using the following syntax for each applicable column: filename|hash ', 1, 'Payload installation', 1, 'File', 0, 1); (30, 47, 'File Indicators', 'Paste any file hashes that you have (MD5, SHA1, SHA256) or filenames below. You can also add filename and hash pairs by using the following syntax for each applicable column: filename|hash ', 1, 'Payload installation', 1, 'File', 0, 1);
INSERT INTO `template_element_files` (`id`, `template_element_id`, `name`, `description`, `category`, `malware`, `mandatory`, `batch`) VALUES INSERT IGNORE INTO `template_element_files` (`id`, `template_element_id`, `name`, `description`, `category`, `malware`, `mandatory`, `batch`) VALUES
(1, 14, 'Malicious Attachment', 'The file (or files) that was (were) attached to the e-mail itself.', 'Payload delivery', 1, 0, 1), (1, 14, 'Malicious Attachment', 'The file (or files) that was (were) attached to the e-mail itself.', 'Payload delivery', 1, 0, 1),
(2, 21, 'Payload installation', 'Payload installation detected during the analysis', 'Payload installation', 1, 0, 1), (2, 21, 'Payload installation', 'Payload installation detected during the analysis', 'Payload installation', 1, 0, 1),
(3, 30, 'Malware sample', 'The sample that the report is based on', 'Payload delivery', 1, 0, 0), (3, 30, 'Malware sample', 'The sample that the report is based on', 'Payload delivery', 1, 0, 0),
(4, 40, 'Artifacts dropped (Sample)', 'Upload any files that were dropped during the analysis.', 'Artifacts dropped', 1, 0, 1); (4, 40, 'Artifacts dropped (Sample)', 'Upload any files that were dropped during the analysis.', 'Artifacts dropped', 1, 0, 1);
INSERT INTO `template_element_texts` (`id`, `name`, `template_element_id`, `text`) VALUES INSERT IGNORE INTO `template_element_texts` (`id`, `name`, `template_element_id`, `text`) VALUES
(1, 'Required fields', 3, 'The fields below are mandatory.'), (1, 'Required fields', 3, 'The fields below are mandatory.'),
(2, 'Optional information', 5, 'All of the fields below are optional, please fill out anything that''s applicable.'), (2, 'Optional information', 5, 'All of the fields below are optional, please fill out anything that''s applicable.'),
(4, 'Required Fields', 11, 'The following fields are mandatory'), (4, 'Required Fields', 11, 'The following fields are mandatory'),
@ -1548,6 +1548,6 @@ INSERT INTO `template_element_texts` (`id`, `name`, `template_element_id`, `text
(11, 'Persistence mechanism', 41, 'The following fields allow you to describe the persistence mechanism used by the malware'), (11, 'Persistence mechanism', 41, 'The following fields allow you to describe the persistence mechanism used by the malware'),
(12, 'Indicators', 45, 'Just paste your list of indicators based on type into the appropriate field. All of the fields are optional, so inputting a list of IP addresses into the Network indicator field for example is sufficient to complete this template.'); (12, 'Indicators', 45, 'Just paste your list of indicators based on type into the appropriate field. All of the fields are optional, so inputting a list of IP addresses into the Network indicator field for example is sufficient to complete this template.');
INSERT INTO `org_blacklists` (`org_uuid`, `created`, `org_name`, `comment`) VALUES INSERT IGNORE INTO `org_blacklists` (`org_uuid`, `created`, `org_name`, `comment`) VALUES
('58d38339-7b24-4386-b4b4-4c0f950d210f', NOW(), 'Setec Astrononomy', 'default example'), ('58d38339-7b24-4386-b4b4-4c0f950d210f', NOW(), 'Setec Astrononomy', 'default example'),
('58d38326-eda8-443a-9fa8-4e12950d210f', NOW(), 'Acme Finance', 'default example'); ('58d38326-eda8-443a-9fa8-4e12950d210f', NOW(), 'Acme Finance', 'default example');

View File

@ -6,7 +6,6 @@ The text files in this folder are symlink to ../docs - Which is the actual sourc
Currently the following install guides are being tested on a regular basis: Currently the following install guides are being tested on a regular basis:
``` ```
INSTALL.debian9.txt
INSTALL.kali.txt INSTALL.kali.txt
INSTALL.ubuntu1804.txt INSTALL.ubuntu1804.txt
``` ```

2
PyMISP

@ -1 +1 @@
Subproject commit 5e46724646c0aa779b827678333a21a5e9eb2034 Subproject commit 0faa75824f4dbac2b14919bb17e9d0fef79026d7

11
SECURITY.md Normal file
View File

@ -0,0 +1,11 @@
## Reporting security vulnerabilities for MISP or related MISP project repositories
Reporting security vulnerabilities is of great importance for us, as MISP is used in multiple critical infrastructures.
In the case of a security vulnerability report, we ask the reporter to send it directly to [CIRCL](https://www.circl.lu/contact/), if possible encrypted with the following GnuPG key: **CA57 2205 C002 4E06 BA70 BE89 EAAD CFFC 22BD 4CD5**. We usually fix reported and confirmed security vulnerabilities in less than 48 hours, followed by a software release containing the fixes within the following days.
If you report security vulnerabilities, do not forget to **tell us if and how you want to be acknowledged** and if you already requested CVE(s). Otherwise, we will request the CVE(s) directly.
As one of the critical user-bases of MISP consists of the CSIRT community, it is our duty to clearly state which bug could be abused and have a security impact on a MISP instance. CVE assignment is performed even for minor bugs suspected of having a security impact. This allows every user with MISP instances set up in their environments to understand which bugs could impact their security.
We firmly believe that, even though unfortunately it is often not regarded as common practice in our industry, being as transparent as possible about vulnerabilities, no matter how minor, is of crucial importance. At MISP Project, we care about the security of our users and prefer to have a high number of published CVEs rather than sweeping some of them under the rug.

View File

@ -5,6 +5,7 @@ require_once 'AppShell.php';
class ServerShell extends AppShell class ServerShell extends AppShell
{ {
public $uses = array('Server', 'Task', 'Job', 'User', 'Feed'); public $uses = array('Server', 'Task', 'Job', 'User', 'Feed');
public $tasks = array('ConfigLoad');
public function listServers() public function listServers()
{ {

View File

@ -57,6 +57,8 @@ class AppController extends Controller
public $baseurl = ''; public $baseurl = '';
public $sql_dump = false; public $sql_dump = false;
private $isRest = 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 // 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 // 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( public $automationArray = array(
@ -204,7 +206,14 @@ class AppController extends Controller
$this->Security->unlockedActions = array($this->action); $this->Security->unlockedActions = array($this->action);
} }
if (!$userLoggedIn) { if (
!$userLoggedIn &&
(
$this->params['controller'] !== 'users' ||
$this->params['action'] !== 'register' ||
empty(Configure::read('Security.allow_self_registration'))
)
) {
// REST authentication // REST authentication
if ($this->_isRest() || $this->_isAutomation()) { if ($this->_isRest() || $this->_isAutomation()) {
// disable CSRF for REST access // disable CSRF for REST access
@ -354,7 +363,11 @@ class AppController extends Controller
} }
} }
} else { } else {
if ($this->params['controller'] !== 'users' || !in_array($this->params['action'], array('login', 'register'))) { $pre_auth_actions = array('login', 'register');
if (!empty(Configure::read('Security.email_otp_enabled'))) {
$pre_auth_actions[] = 'email_otp';
}
if ($this->params['controller'] !== 'users' || !in_array($this->params['action'], $pre_auth_actions)) {
if (!$this->request->is('ajax')) { if (!$this->request->is('ajax')) {
$this->Session->write('pre_login_requested_url', $this->here); $this->Session->write('pre_login_requested_url', $this->here);
} }
@ -673,6 +686,11 @@ class AppController extends Controller
protected function _isRest() protected function _isRest()
{ {
// This method is surprisingly slow and called many times for one request, so it make sense to cache the result.
if ($this->isRest !== null) {
return $this->isRest;
}
$api = $this->__isApiFunction($this->request->params['controller'], $this->request->params['action']); $api = $this->__isApiFunction($this->request->params['controller'], $this->request->params['action']);
if (isset($this->RequestHandler) && ($api || $this->RequestHandler->isXml() || $this->_isJson() || $this->_isCsv())) { if (isset($this->RequestHandler) && ($api || $this->RequestHandler->isXml() || $this->_isJson() || $this->_isCsv())) {
if ($this->_isJson()) { if ($this->_isJson()) {
@ -680,8 +698,10 @@ class AppController extends Controller
throw new MethodNotAllowedException('Invalid JSON input. Make sure that the JSON input is a correctly formatted JSON string. This request has been blocked to avoid an unfiltered request.'); throw new MethodNotAllowedException('Invalid JSON input. Make sure that the JSON input is a correctly formatted JSON string. This request has been blocked to avoid an unfiltered request.');
} }
} }
$this->isRest = true;
return true; return true;
} else { } else {
$this->isRest = false;
return false; return false;
} }
} }

View File

@ -3,6 +3,9 @@ App::uses('AppController', 'Controller');
App::uses('Folder', 'Utility'); App::uses('Folder', 'Utility');
App::uses('File', 'Utility'); App::uses('File', 'Utility');
/**
* @property Attribute $Attribute
*/
class AttributesController extends AppController class AttributesController extends AppController
{ {
public $components = array('Security', 'RequestHandler', 'Cidr'); public $components = array('Security', 'RequestHandler', 'Cidr');
@ -148,6 +151,12 @@ class AttributesController extends AppController
if (!isset($this->request->data['Attribute'])) { if (!isset($this->request->data['Attribute'])) {
$this->request->data = array('Attribute' => $this->request->data); $this->request->data = array('Attribute' => $this->request->data);
} }
if ($this->request->data['Attribute']['distribution'] == 4) {
$sg = $this->Event->SharingGroup->fetchAllAuthorised($this->Auth->user(), 'name', 1, $this->request->data['Attribute']['sharing_group_id']);
if (empty($sg)) {
throw new MethodNotAllowedException(__('Invalid Sharing Group or not authorised.'));
}
}
// //
// multiple attributes in batch import // multiple attributes in batch import
// //
@ -410,22 +419,19 @@ class AttributesController extends AppController
public function add_attachment($eventId = null) public function add_attachment($eventId = null)
{ {
if ($this->request->is('post')) { if ($this->request->is('post')) {
$hashes = array('md5' => 'malware-sample', 'sha1' => 'filename|sha1', 'sha256' => 'filename|sha256'); $this->Attribute->Event->id = $this->request->data['Attribute']['event_id'];
$this->loadModel('Event'); $this->Attribute->Event->recursive = -1;
$this->Event->id = $this->request->data['Attribute']['event_id']; $event = $this->Attribute->Event->read();
$this->Event->recursive = -1;
$event = $this->Event->read();
if (empty($event)) { if (empty($event)) {
throw new NotFoundException(__('Invalid Event.')); throw new NotFoundException(__('Invalid Event.'));
} }
if (!$this->_isSiteAdmin() && ($this->Event->data['Event']['orgc_id'] != $this->_checkOrg() || !$this->userRole['perm_modify'])) { if (!$this->_isSiteAdmin() && ($this->Attribute->Event->data['Event']['orgc_id'] != $this->_checkOrg() || !$this->userRole['perm_modify'])) {
throw new UnauthorizedException(__('You do not have permission to do that.')); throw new UnauthorizedException(__('You do not have permission to do that.'));
} }
$partialFails = array();
$fails = array(); $fails = array();
$success = 0; $success = 0;
foreach ($this->request->data['Attribute']['values'] as $k => $value) { foreach ($this->request->data['Attribute']['values'] as $value) {
// Check if there were problems with the file upload // Check if there were problems with the file upload
// only keep the last part of the filename, this should prevent directory attacks // only keep the last part of the filename, this should prevent directory attacks
$filename = basename($value['name']); $filename = basename($value['name']);
@ -449,11 +455,6 @@ class AttributesController extends AppController
$filename, $filename,
$tmpfile $tmpfile
); );
if ($result) {
$success++;
} else {
$fails[] = $filename;
}
} else { } else {
$result = $this->Attribute->simpleAddMalwareSample( $result = $this->Attribute->simpleAddMalwareSample(
$eventId, $eventId,
@ -461,15 +462,16 @@ class AttributesController extends AppController
$filename, $filename,
$tmpfile $tmpfile
); );
if ($result) {
$success++;
} else {
$fails[] = $filename;
}
} }
if ($result) {
$success++;
} else {
$fails[] = $filename;
}
if (!empty($result)) { if (!empty($result)) {
foreach ($result['Object'] as $object) { foreach ($result['Object'] as $object) {
$this->loadModel('MispObject');
$object['distribution'] = $this->request->data['Attribute']['distribution']; $object['distribution'] = $this->request->data['Attribute']['distribution'];
if (!empty($this->request->data['sharing_group_id'])) { if (!empty($this->request->data['sharing_group_id'])) {
$object['sharing_group_id'] = $this->request->data['Attribute']['sharing_group_id']; $object['sharing_group_id'] = $this->request->data['Attribute']['sharing_group_id'];
@ -477,11 +479,11 @@ class AttributesController extends AppController
foreach ($object['Attribute'] as $ka => $attribute) { foreach ($object['Attribute'] as $ka => $attribute) {
$object['Attribute'][$ka]['distribution'] = 5; $object['Attribute'][$ka]['distribution'] = 5;
} }
$this->MispObject->captureObject(array('Object' => $object), $eventId, $this->Auth->user()); $this->Attribute->Object->captureObject(array('Object' => $object), $eventId, $this->Auth->user());
} }
if (!empty($result['ObjectReference'])) { if (!empty($result['ObjectReference'])) {
foreach ($result['ObjectReference'] as $reference) { foreach ($result['ObjectReference'] as $reference) {
$this->MispObject->ObjectReference->smartSave($reference, $eventId); $this->Attribute->Object->ObjectReference->smartSave($reference, $eventId);
} }
} }
} }
@ -508,20 +510,17 @@ class AttributesController extends AppController
} }
} }
} }
$message = 'The attachment(s) have been uploaded.'; $message = __('The attachment(s) have been uploaded.');
if (!empty($partialFails)) {
$message .= ' Some of the attributes however could not be created.';
}
if (!empty($fails)) { if (!empty($fails)) {
$message = 'Some of the attachments failed to upload. The failed files were: ' . implode(', ', $fails) . ' - This can be caused by the attachments already existing in the event.'; $message = __('Some of the attachments failed to upload. The failed files were: %s - This can be caused by the attachments already existing in the event.', implode(', ', $fails));
} }
if (empty($success)) { if (empty($success)) {
if (empty($fails)) { if (empty($fails)) {
$message = 'The attachment(s) could not be saved. please contact your administrator.'; $message = __('The attachment(s) could not be saved. Please contact your administrator.');
} }
} else { } else {
$this->Event->id = $this->request->data['Attribute']['event_id']; $this->Attribute->Event->id = $this->request->data['Attribute']['event_id'];
$this->Event->saveField('published', 0); $this->Attribute->Event->saveField('published', 0);
} }
if (empty($success) && !empty($fails)) { if (empty($success) && !empty($fails)) {
$this->Flash->error($message); $this->Flash->error($message);
@ -536,57 +535,43 @@ class AttributesController extends AppController
// set the event_id in the form // set the event_id in the form
$this->request->data['Attribute']['event_id'] = $eventId; $this->request->data['Attribute']['event_id'] = $eventId;
} }
$event = $this->Attribute->Event->findById($eventId);
if (empty($event)) {
throw new NotFoundException(__('Invalid Event.'));
}
if (!$this->_isRest()) { if (!$this->_isRest()) {
$this->Attribute->Event->insertLock($this->Auth->user(), $eventId); $this->Attribute->Event->insertLock($this->Auth->user(), $eventId);
} }
// combobox for categories
$categories = array_keys($this->Attribute->categoryDefinitions); // Filter categories that contains attachment type
// just get them with attachments..
$selectedCategories = array(); $selectedCategories = array();
foreach ($categories as $category) { foreach ($this->Attribute->categoryDefinitions as $category => $values) {
$types = $this->Attribute->categoryDefinitions[$category]['types']; foreach ($values['types'] as $type) {
$alreadySet = false; if ($this->Attribute->typeIsAttachment($type)) {
foreach ($types as $type) {
if ($this->Attribute->typeIsAttachment($type) && !$alreadySet) {
// add to the whole..
$selectedCategories[] = $category; $selectedCategories[] = $category;
$alreadySet = true; continue 2;
continue;
} }
} }
} }
$categories = $this->_arrayToValuesIndexArray($selectedCategories); $categories = $this->_arrayToValuesIndexArray($selectedCategories);
$this->set('categories', $categories); $this->set('categories', $categories);
$this->set('attrDescriptions', $this->Attribute->fieldDescriptions);
$this->set('typeDefinitions', $this->Attribute->typeDefinitions);
$this->set('categoryDefinitions', $this->Attribute->categoryDefinitions); $this->set('categoryDefinitions', $this->Attribute->categoryDefinitions);
$this->set('zippedDefinitions', $this->Attribute->zippedDefinitions); $this->set('zippedDefinitions', $this->Attribute->zippedDefinitions);
$this->set('uploadDefinitions', $this->Attribute->uploadDefinitions); $this->set('advancedExtractionAvailable', $this->Attribute->isAdvancedExtractionAvailable());
// combobox for distribution // combobox for distribution
$this->loadModel('Event'); $this->set('distributionLevels', $this->Attribute->distributionLevels);
$this->set('distributionLevels', $this->Event->Attribute->distributionLevels); $this->set('info', $this->__getInfo());
foreach ($this->Attribute->categoryDefinitions as $key => $value) {
$info['category'][$key] = array('key' => $key, 'desc' => isset($value['formdesc'])? $value['formdesc'] : $value['desc']);
}
foreach ($this->Event->Attribute->distributionLevels as $key => $value) {
$info['distribution'][$key] = array('key' => $value, 'desc' => $this->Attribute->distributionDescriptions[$key]['formdesc']);
}
$this->set('info', $info);
$this->loadModel('SharingGroup'); $this->loadModel('SharingGroup');
$sgs = $this->SharingGroup->fetchAllAuthorised($this->Auth->user(), 'name', 1); $sgs = $this->SharingGroup->fetchAllAuthorised($this->Auth->user(), 'name', 1);
$this->set('sharingGroups', $sgs); $this->set('sharingGroups', $sgs);
$events = $this->Event->findById($eventId); $this->set('currentDist', $event['Event']['distribution']);
if (empty($events)) { $this->set('published', $event['Event']['published']);
throw new NotFoundException(__('Invalid Event.'));
}
$this->set('currentDist', $events['Event']['distribution']);
$this->set('published', $events['Event']['published']);
} }
@ -852,6 +837,12 @@ class AttributesController extends AppController
if (!isset($this->request->data['Attribute'])) { if (!isset($this->request->data['Attribute'])) {
$this->request->data = array('Attribute' => $this->request->data); $this->request->data = array('Attribute' => $this->request->data);
} }
if ($this->request->data['Attribute']['distribution'] == 4) {
$sg = $this->Attribute->Event->SharingGroup->fetchAllAuthorised($this->Auth->user(), 'name', 1, $this->request->data['Attribute']['sharing_group_id']);
if (empty($sg)) {
throw new MethodNotAllowedException(__('Invalid Sharing Group or not authorised.'));
}
}
$existingAttribute = $this->Attribute->findByUuid($this->Attribute->data['Attribute']['uuid']); $existingAttribute = $this->Attribute->findByUuid($this->Attribute->data['Attribute']['uuid']);
// check if the attribute has a timestamp already set (from a previous instance that is trying to edit via synchronisation) // check if the attribute has a timestamp already set (from a previous instance that is trying to edit via synchronisation)
// check which attribute is newer // check which attribute is newer
@ -3250,4 +3241,28 @@ class AttributesController extends AppController
return $this->RestResponse->viewData($final, $responseType, false, true, 'search.' . $type . '.' . $responseType); return $this->RestResponse->viewData($final, $responseType, false, true, 'search.' . $type . '.' . $responseType);
} }
} }
private function __getInfo()
{
$info = array('category' => array(), 'type' => array(), 'distribution' => array());
foreach ($this->Attribute->categoryDefinitions as $key => $value) {
$info['category'][$key] = array(
'key' => $key,
'desc' => isset($value['formdesc']) ? $value['formdesc'] : $value['desc']
);
}
foreach ($this->Attribute->typeDefinitions as $key => $value) {
$info['type'][$key] = array(
'key' => $key,
'desc' => isset($value['formdesc']) ? $value['formdesc'] : $value['desc']
);
}
foreach ($this->Attribute->distributionLevels as $key => $value) {
$info['distribution'][$key] = array(
'key' => $value,
'desc' => $this->Attribute->distributionDescriptions[$key]['formdesc']
);
}
return $info;
}
} }

View File

@ -569,6 +569,7 @@ class ACLComponent extends Component
'discardRegistrations' => array('perm_site_admin'), 'discardRegistrations' => array('perm_site_admin'),
'downloadTerms' => array('*'), 'downloadTerms' => array('*'),
'edit' => array('*'), 'edit' => array('*'),
'email_otp' => array('*'),
'searchGpgKey' => array('*'), 'searchGpgKey' => array('*'),
'fetchGpgKey' => array('*'), 'fetchGpgKey' => array('*'),
'histogram' => array('*'), 'histogram' => array('*'),

View File

@ -1403,12 +1403,8 @@ class EventsController extends AppController
$this->set($alias, $currentModel->{$variable}); $this->set($alias, $currentModel->{$variable});
} }
} }
$cluster_names = $this->GalaxyCluster->find('list', array('fields' => array('GalaxyCluster.tag_name'), 'group' => array('GalaxyCluster.tag_name', 'GalaxyCluster.id')));
foreach ($event['EventTag'] as $k => $eventTag) { $this->Event->removeGalaxyClusterTags($event);
if (in_array($eventTag['Tag']['name'], $cluster_names)) {
unset($event['EventTag'][$k]);
}
}
$tagConflicts = $this->Taxonomy->checkIfTagInconsistencies($event['EventTag']); $tagConflicts = $this->Taxonomy->checkIfTagInconsistencies($event['EventTag']);
foreach ($tagConflicts['global'] as $tagConflict) { foreach ($tagConflicts['global'] as $tagConflict) {
@ -1430,11 +1426,9 @@ class EventsController extends AppController
} }
$modDate = date("Y-m-d", $attribute['timestamp']); $modDate = date("Y-m-d", $attribute['timestamp']);
$modificationMap[$modDate] = empty($modificationMap[$modDate])? 1 : $modificationMap[date("Y-m-d", $attribute['timestamp'])] + 1; $modificationMap[$modDate] = empty($modificationMap[$modDate])? 1 : $modificationMap[date("Y-m-d", $attribute['timestamp'])] + 1;
foreach ($attribute['AttributeTag'] as $k2 => $attributeTag) {
if (in_array($attributeTag['Tag']['name'], $cluster_names)) { $this->Event->Attribute->removeGalaxyClusterTags($event['Attribute'][$k]);
unset($event['Attribute'][$k]['AttributeTag'][$k2]);
}
}
$tagConflicts = $this->Taxonomy->checkIfTagInconsistencies($attribute['AttributeTag']); $tagConflicts = $this->Taxonomy->checkIfTagInconsistencies($attribute['AttributeTag']);
foreach ($tagConflicts['global'] as $tagConflict) { foreach ($tagConflicts['global'] as $tagConflict) {
$warningTagConflicts[$tagConflict['taxonomy']['Taxonomy']['namespace']] = $tagConflict['taxonomy']; $warningTagConflicts[$tagConflict['taxonomy']['Taxonomy']['namespace']] = $tagConflict['taxonomy'];
@ -1463,11 +1457,9 @@ class EventsController extends AppController
} }
$modDate = date("Y-m-d", $attribute['timestamp']); $modDate = date("Y-m-d", $attribute['timestamp']);
$modificationMap[$modDate] = empty($modificationMap[$modDate])? 1 : $modificationMap[date("Y-m-d", $attribute['timestamp'])] + 1; $modificationMap[$modDate] = empty($modificationMap[$modDate])? 1 : $modificationMap[date("Y-m-d", $attribute['timestamp'])] + 1;
foreach ($attribute['AttributeTag'] as $k3 => $attributeTag) {
if (in_array($attributeTag['Tag']['name'], $cluster_names)) { $this->Event->Attribute->removeGalaxyClusterTags($event['Object'][$k]['Attribute'][$k2]);
unset($event['Object'][$k]['Attribute'][$k2]['AttributeTag'][$k3]);
}
}
$tagConflicts = $this->Taxonomy->checkIfTagInconsistencies($attribute['AttributeTag']); $tagConflicts = $this->Taxonomy->checkIfTagInconsistencies($attribute['AttributeTag']);
foreach ($tagConflicts['global'] as $tagConflict) { foreach ($tagConflicts['global'] as $tagConflict) {
$warningTagConflicts[$tagConflict['taxonomy']['Taxonomy']['namespace']] = $tagConflict['taxonomy']; $warningTagConflicts[$tagConflict['taxonomy']['Taxonomy']['namespace']] = $tagConflict['taxonomy'];
@ -1659,7 +1651,7 @@ class EventsController extends AppController
if (!empty($this->params['named']['excludeGalaxy'])) { if (!empty($this->params['named']['excludeGalaxy'])) {
$conditions['excludeGalaxy'] = 1; $conditions['excludeGalaxy'] = 1;
} }
if (!empty($this->params['named']['extended'])) { if (!empty($this->params['named']['extended']) || !empty($this->request->data['extended'])) {
$conditions['extended'] = 1; $conditions['extended'] = 1;
$this->set('extended', 1); $this->set('extended', 1);
} else { } else {
@ -2280,18 +2272,34 @@ class EventsController extends AppController
} }
} }
foreach ($resultArray as $key => $result) { foreach ($resultArray as $key => $result) {
if ($has_pipe = strpos($result['default_type'], '|') !== false || $result['default_type'] === 'malware-sample') {
$pieces = explode('|', $result['value']);
$or = array('Attribute.value1' => $pieces,
'Attribute.value2' => $pieces);
} else {
$or = array('Attribute.value1' => $result['value'], 'Attribute.value2' => $result['value']);
}
$options = array( $options = array(
'conditions' => array('OR' => array('Attribute.value1' => $result['value'], 'Attribute.value2' => $result['value'])), 'conditions' => array('OR' => $or),
'fields' => array('Attribute.type', 'Attribute.category', 'Attribute.value', 'Attribute.comment'), 'fields' => array('Attribute.type', 'Attribute.category', 'Attribute.value', 'Attribute.comment'),
'order' => false 'order' => false
); );
$resultArray[$key]['related'] = $this->Event->Attribute->fetchAttributes($this->Auth->user(), $options); $resultArray[$key]['related'] = $this->Event->Attribute->fetchAttributes($this->Auth->user(), $options);
} }
// combobox for distribution
$distributions = $this->Event->Attribute->distributionLevels;
$sgs = $this->Event->SharingGroup->fetchAllAuthorised($this->Auth->user(), 'name', 1);
if (empty($sgs)) {
unset($distributions[4]);
}
$this->set('event', array('Event' => array('id' => $target_id))); $this->set('event', array('Event' => array('id' => $target_id)));
$this->set('resultArray', $resultArray); $this->set('resultArray', $resultArray);
$this->set('typeList', array_keys($this->Event->Attribute->typeDefinitions)); $this->set('typeList', array_keys($this->Event->Attribute->typeDefinitions));
$this->set('defaultCategories', $this->Event->Attribute->defaultCategories); $this->set('defaultCategories', $this->Event->Attribute->defaultCategories);
$this->set('typeCategoryMapping', $typeCategoryMapping); $this->set('typeCategoryMapping', $typeCategoryMapping);
$this->set('distributions', $distributions);
$this->set('sgs', $sgs);
$this->set('title', 'Merge Results'); $this->set('title', 'Merge Results');
$this->set('importComment', 'Merged from event ' . $source_id); $this->set('importComment', 'Merged from event ' . $source_id);
$this->render('resolved_attributes'); $this->render('resolved_attributes');
@ -3715,8 +3723,15 @@ class EventsController extends AppController
} }
} }
foreach ($resultArray as $key => $result) { foreach ($resultArray as $key => $result) {
if ($has_pipe = strpos($result['default_type'], '|') !== false || $result['default_type'] === 'malware-sample') {
$pieces = explode('|', $result['value']);
$or = array('Attribute.value1' => $pieces,
'Attribute.value2' => $pieces);
} else {
$or = array('Attribute.value1' => $result['value'], 'Attribute.value2' => $result['value']);
}
$options = array( $options = array(
'conditions' => array('OR' => array('Attribute.value1' => $result['value'], 'Attribute.value2' => $result['value'])), 'conditions' => array('OR' => $or),
'fields' => array('Attribute.type', 'Attribute.category', 'Attribute.value', 'Attribute.comment'), 'fields' => array('Attribute.type', 'Attribute.category', 'Attribute.value', 'Attribute.comment'),
'order' => false, 'order' => false,
'flatten' => 1 'flatten' => 1
@ -4987,10 +5002,17 @@ class EventsController extends AppController
} }
} }
foreach ($resultArray as $key => $result) { foreach ($resultArray as $key => $result) {
if ($has_pipe = strpos($result['default_type'], '|') !== false || $result['default_type'] === 'malware-sample') {
$pieces = explode('|', $result['value']);
$or = array('Attribute.value1' => $pieces,
'Attribute.value2' => $pieces);
} else {
$or = array('Attribute.value1' => $result['value'], 'Attribute.value2' => $result['value']);
}
$options = array( $options = array(
'conditions' => array('OR' => array('Attribute.value1' => $result['value'], 'Attribute.value2' => $result['value'])), 'conditions' => array('OR' => $or),
'fields' => array('Attribute.type', 'Attribute.category', 'Attribute.value', 'Attribute.comment'), 'fields' => array('Attribute.type', 'Attribute.category', 'Attribute.value', 'Attribute.comment'),
'order' => false 'order' => false
); );
$resultArray[$key]['related'] = $this->Event->Attribute->fetchAttributes($this->Auth->user(), $options); $resultArray[$key]['related'] = $this->Event->Attribute->fetchAttributes($this->Auth->user(), $options);
if (isset($result['data'])) { if (isset($result['data'])) {
@ -5170,10 +5192,17 @@ class EventsController extends AppController
} }
} }
foreach ($resultArray as $key => $result) { foreach ($resultArray as $key => $result) {
if ($has_pipe = strpos($result['default_type'], '|') !== false || $result['default_type'] === 'malware-sample') {
$pieces = explode('|', $result['value']);
$or = array('Attribute.value1' => $pieces,
'Attribute.value2' => $pieces);
} else {
$or = array('Attribute.value1' => $result['value'], 'Attribute.value2' => $result['value']);
}
$options = array( $options = array(
'conditions' => array('OR' => array('Attribute.value1' => $result['value'], 'Attribute.value2' => $result['value'])), 'conditions' => array('OR' => $or),
'fields' => array('Attribute.type', 'Attribute.category', 'Attribute.value', 'Attribute.comment'), 'fields' => array('Attribute.type', 'Attribute.category', 'Attribute.value', 'Attribute.comment'),
'order' => false 'order' => false
); );
$resultArray[$key]['related'] = $this->Event->Attribute->fetchAttributes($this->Auth->user(), $options); $resultArray[$key]['related'] = $this->Event->Attribute->fetchAttributes($this->Auth->user(), $options);
} }

View File

@ -202,7 +202,7 @@ class FeedsController extends AppController
$tags = $this->Event->EventTag->Tag->find('list', array('fields' => array('Tag.name'), 'order' => array('lower(Tag.name) asc'))); $tags = $this->Event->EventTag->Tag->find('list', array('fields' => array('Tag.name'), 'order' => array('lower(Tag.name) asc')));
$tags[0] = 'None'; $tags[0] = 'None';
$this->set('tags', $tags); $this->set('tags', $tags);
if (empty($this->request->data['Feed']['fixed_event'])) { if (!isset($this->request->data['Feed']['fixed_event'])) {
$this->request->data['Feed']['fixed_event'] = 1; $this->request->data['Feed']['fixed_event'] = 1;
} }
$this->set('orgs', $this->Event->Orgc->find('list', array( $this->set('orgs', $this->Event->Orgc->find('list', array(

View File

@ -992,13 +992,15 @@ class ServersController extends AppController
if ($tab == 'diagnostics' || $tab == 'download' || $this->_isRest()) { if ($tab == 'diagnostics' || $tab == 'download' || $this->_isRest()) {
$php_ini = php_ini_loaded_file(); $php_ini = php_ini_loaded_file();
$this->set('php_ini', $php_ini); $this->set('php_ini', $php_ini);
$advanced_attachments = shell_exec($this->Server->getPythonVersion() . ' ' . APP . 'files/scripts/generate_file_objects.py -c');
$malwareTool = new MalwareTool();
try { try {
$advanced_attachments = json_decode($advanced_attachments, true); $advanced_attachments = $malwareTool->checkAdvancedExtractionStatus($this->Server->getPythonVersion());
} catch (Exception $e) { } catch (Exception $e) {
$this->log($e->getMessage(), LOG_NOTICE);
$advanced_attachments = false; $advanced_attachments = false;
} }
$this->set('advanced_attachments', $advanced_attachments); $this->set('advanced_attachments', $advanced_attachments);
// check if the current version of MISP is outdated or not // check if the current version of MISP is outdated or not
$version = $this->__checkVersion(); $version = $this->__checkVersion();

View File

@ -31,6 +31,9 @@ class UsersController extends AppController
// what pages are allowed for non-logged-in users // what pages are allowed for non-logged-in users
$allowedActions = array('login', 'logout'); $allowedActions = array('login', 'logout');
if(!empty(Configure::read('Security.email_otp_enabled'))) {
$allowedActions[] = 'email_otp';
}
if (!empty(Configure::read('Security.allow_self_registration'))) { if (!empty(Configure::read('Security.allow_self_registration'))) {
$allowedActions[] = 'register'; $allowedActions[] = 'register';
} }
@ -1116,33 +1119,15 @@ class UsersController extends AppController
$this->Auth->constructAuthenticate(); $this->Auth->constructAuthenticate();
} }
} }
if ($this->request->is('post') && Configure::read('Security.email_otp_enabled')) {
$user = $this->Auth->identify($this->request, $this->response);
if ($user) {
$this->Session->write('email_otp_user', $user);
return $this->redirect('email_otp');
}
}
if ($this->Auth->login()) { if ($this->Auth->login()) {
$this->User->extralog($this->Auth->user(), "login"); $this->_postlogin();
$this->User->Behaviors->disable('SysLogLogable.SysLogLogable');
$this->User->id = $this->Auth->user('id');
$user = $this->User->find('first', array(
'conditions' => array(
'User.id' => $this->Auth->user('id')
),
'recursive' => -1
));
$lastUserLogin = $user['User']['last_login'];
unset($user['User']['password']);
$user['User']['action'] = 'login';
$user['User']['last_login'] = $this->Auth->user('current_login');
$user['User']['current_login'] = time();
$this->User->save($user['User'], true, array('id', 'last_login', 'current_login'));
if (empty($this->Auth->authenticate['Form']['passwordHasher']) && !empty($passwordToSave)) {
$this->User->saveField('password', $passwordToSave);
}
$this->User->Behaviors->enable('SysLogLogable.SysLogLogable');
if ($lastUserLogin) {
$readableDatetime = (new DateTime())->setTimestamp($lastUserLogin)->format('D, d M y H:i:s O'); // RFC822
$this->Flash->info(sprintf('Welcome! Last login was on %s', $readableDatetime));
}
// no state changes are ever done via GET requests, so it is safe to return to the original page:
$this->redirect($this->Auth->redirectUrl());
// $this->redirect(array('controller' => 'events', 'action' => 'index'));
} else { } else {
$dataSourceConfig = ConnectionManager::getDataSource('default')->config; $dataSourceConfig = ConnectionManager::getDataSource('default')->config;
$dataSource = $dataSourceConfig['datasource']; $dataSource = $dataSourceConfig['datasource'];
@ -1224,6 +1209,35 @@ class UsersController extends AppController
} }
} }
private function _postlogin()
{
$this->User->extralog($this->Auth->user(), "login");
$this->User->Behaviors->disable('SysLogLogable.SysLogLogable');
$this->User->id = $this->Auth->user('id');
$user = $this->User->find('first', array(
'conditions' => array(
'User.id' => $this->Auth->user('id')
),
'recursive' => -1
));
$lastUserLogin = $user['User']['last_login'];
unset($user['User']['password']);
$user['User']['action'] = 'login';
$user['User']['last_login'] = $this->Auth->user('current_login');
$user['User']['current_login'] = time();
$this->User->save($user['User'], true, array('id', 'last_login', 'current_login'));
if (empty($this->Auth->authenticate['Form']['passwordHasher']) && !empty($passwordToSave)) {
$this->User->saveField('password', $passwordToSave);
}
$this->User->Behaviors->enable('SysLogLogable.SysLogLogable');
if ($lastUserLogin) {
$readableDatetime = (new DateTime())->setTimestamp($lastUserLogin)->format('D, d M y H:i:s O'); // RFC822
$this->Flash->info(__('Welcome! Last login was on %s', $readableDatetime));
}
// no state changes are ever done via GET requests, so it is safe to return to the original page:
$this->redirect($this->Auth->redirectUrl());
}
public function routeafterlogin() public function routeafterlogin()
{ {
// Events list // Events list
@ -1473,7 +1487,7 @@ class UsersController extends AppController
if ($this->_isRest()) { if ($this->_isRest()) {
return $this->RestResponse->saveFailResponse('Users', 'admin_quickEmail', false, $error, $this->response->type()); return $this->RestResponse->saveFailResponse('Users', 'admin_quickEmail', false, $error, $this->response->type());
} else { } else {
$this->Flash->error('Cannot send an e-mail to this user as the account is disabled.'); $this->Flash->error($error);
$this->redirect('/admin/users/view/' . $user_id); $this->redirect('/admin/users/view/' . $user_id);
} }
} }
@ -1656,6 +1670,90 @@ class UsersController extends AppController
} }
} }
public function email_otp()
{
$user = $this->Session->read('email_otp_user');
if(empty($user)) {
$this->redirect('login');
}
$redis = $this->User->setupRedis();
$user_id = $user['id'];
if ($this->request->is('post') && isset($this->request->data['User']['otp'])) {
$stored_otp = $redis->get('misp:otp:'.$user_id);
if (!empty($stored_otp) && $this->request->data['User']['otp'] == $stored_otp) {
// we invalidate the previously generated OTP
$redis->delete('misp:otp:'.$user_id);
// We login the user with CakePHP
$this->Auth->login($user);
$this->_postlogin();
} else {
$this->Flash->error(__("The OTP is incorrect or has expired"));
}
} else {
// GET Request
// We check for exceptions
$exception_list = Configure::read('Security.email_otp_exceptions');
if (!empty($exception_list)) {
$exceptions = explode(",", $exception_list);
foreach ($exceptions as &$exception) {
if ($user['email'] == trim($exception)) {
// We login the user with CakePHP
$this->Auth->login($user);
$this->_postlogin();
}
}
}
$this->loadModel('Server');
// Generating the OTP
$digits = !empty(Configure::read('Security.email_otp_length')) ? Configure::read('Security.email_otp_length') : $this->Server->serverSettings['Security']['email_otp_length']['value'];
$otp = "";
for ($i=0; $i<$digits; $i++) {
$otp.= random_int(0,9);
}
// We use Redis to cache the OTP
$redis->set('misp:otp:'.$user_id, $otp);
$validity = !empty(Configure::read('Security.email_otp_validity')) ? Configure::read('Security.email_otp_validity') : $this->Server->serverSettings['Security']['email_otp_validity']['value'];
$redis->expire('misp:otp:'.$user_id, (int) $validity * 60);
// Email construction
$body = !empty(Configure::read('Security.email_otp_text')) ? Configure::read('Security.email_otp_text') : $this->Server->serverSettings['Security']['email_otp_text']['value'];
$body = str_replace('$misp', Configure::read('MISP.baseurl'), $body);
$body = str_replace('$org', Configure::read('MISP.org'), $body);
$body = str_replace('$contact', Configure::read('MISP.contact'), $body);
$body = str_replace('$validity', $validity, $body);
$body = str_replace('$otp', $otp, $body);
$body = str_replace('$ip', $this->__getClientIP(), $body);
$body = str_replace('$username', $user['email'], $body);
$result = $this->User->sendEmail(array('User' => $user), $body, false, "[MISP] Email OTP");
if ( $result ) {
$this->Flash->success(__("An email containing a OTP has been sent."));
} else {
$this->Flash->error(__("The email couldn't be sent, please reach out to your administrator."));
}
}
}
/**
* Helper function to determine the IP of a client (proxy aware)
*/
private function __getClientIP() {
$x_forwarded = filter_input(INPUT_SERVER, 'HTTP_X_FORWARDED_FOR', FILTER_SANITIZE_STRING);
$client_ip = filter_input(INPUT_SERVER, 'HTTP_CLIENT_IP', FILTER_SANITIZE_STRING);
if (!empty($x_forwarded)) {
$x_forwarded = explode(",", $x_forwarded);
return $x_forwarded[0];
} elseif(!empty($client_ip)){
return $_client_ip;
} else {
return filter_input(INPUT_SERVER, 'REMOTE_ADDR', FILTER_SANITIZE_STRING);
}
}
// shows some statistics about the instance // shows some statistics about the instance
public function statistics($page = 'data') public function statistics($page = 'data')
{ {
@ -2495,6 +2593,14 @@ class UsersController extends AppController
throw new InvalidArgumentException(__('Role ID not provided and no default role exist on the instance')); throw new InvalidArgumentException(__('Role ID not provided and no default role exist on the instance'));
} }
} }
if (!isset($this->request->data['User']['org_id'])) {
throw new InvalidArgumentException(__('No organisation selected. Supply an Organisation ID'));
} else {
if (Validation::uuid($this->request->data['User']['org_id'])) {
$id = $this->Toolbox->findIdByUuid($this->User->Organisation, $this->request->data['User']['org_id']);
$this->request->data['User']['org_id'] = $id;
}
}
foreach ($registrations as $registration) { foreach ($registrations as $registration) {
$result = $this->User->registerUser( $result = $this->User->registerUser(
$this->Auth->user(), $this->Auth->user(),

View File

@ -131,12 +131,12 @@ class NidsSuricataExport extends NidsExport
$data['host'] = NidsExport::replaceIllegalChars($data['host']); $data['host'] = NidsExport::replaceIllegalChars($data['host']);
$tag = 'tag:session,600,seconds;'; $tag = 'tag:session,600,seconds;';
# IP: classic IP rule for HTTPS # IP: classic IP rule for HTTPS
$suricata_protocol = 'tcp'; $suricata_protocol = 'tls';
$suricata_src_ip = '$HOME_NET'; $suricata_src_ip = '$HOME_NET';
$suricata_src_port = 'any'; $suricata_src_port = 'any';
$suricata_dst_ip = $data['host']; $suricata_dst_ip = '$EXTERNAL_NET';
$suricata_dst_port = NidsExport::getProtocolPort($scheme, $data['port']); $suricata_dst_port = NidsExport::getProtocolPort($scheme, $data['port']);
$content = 'flow:to_server; app-layer-protocol:tls;'; $content = 'tls_sni; content:"' . $data['host'] . '";';
break; break;
case "ssh": case "ssh":

View File

@ -0,0 +1,227 @@
<?php
class MalwareTool
{
const ZIP_PASSWORD = 'infected';
const ADVANCED_EXTRACTION_SCRIPT_PATH = APP . 'files/scripts/generate_file_objects.py';
/**
* @param string $originalFilename
* @param string $content
* @param string $md5
* @return string Content of zipped file
* @throws Exception
*/
public function encrypt($originalFilename, $content, $md5)
{
if (method_exists("ZipArchive", "setEncryptionName")) {
// When PHP zip extension is installed and supports creating encrypted archives.
return $this->encryptByExtension($originalFilename, $content, $md5);
} else {
return $this->encryptByCommand($originalFilename, $content, $md5);
}
}
/**
* @param string $originalFilename
* @param string $content
* @param string $md5
* @return string Content of zipped file
* @throws Exception
*/
private function encryptByCommand($originalFilename, $content, $md5)
{
$tempDir = $this->tempDir();
$contentsFile = new File($tempDir . DS . $md5, true);
if (!$contentsFile->write($content)) {
throw new Exception("Could not write content to file '{$contentsFile->path}'.");
}
$contentsFile->close();
$fileNameFile = new File($tempDir . DS . $md5 . '.filename.txt', true);
if (!$fileNameFile->write($originalFilename)) {
throw new Exception("Could not write original file name to file '{$fileNameFile->path}'.");
}
$fileNameFile->close();
$zipFile = new File($tempDir . DS . $md5 . '.zip');
$exec = [
'zip',
'-j', // junk (don't record) directory names
'-P', // use standard encryption
self::ZIP_PASSWORD,
escapeshellarg($zipFile->path),
escapeshellarg($contentsFile->path),
escapeshellarg($fileNameFile->path),
];
try {
$this->execute($exec);
$zipContent = $zipFile->read();
if ($zipContent === false) {
throw new Exception("Could not read content of newly created ZIP file.");
}
return $zipContent;
} catch (Exception $e) {
throw new Exception("Could not create encrypted ZIP file '{$zipFile->path}'.", 0, $e);
} finally {
$fileNameFile->delete();
$contentsFile->delete();
$zipFile->delete();
}
}
/**
* @param string $originalFilename
* @param string $content
* @param string $md5
* @return string Content of zipped file
* @throws Exception
*/
private function encryptByExtension($originalFilename, $content, $md5)
{
$zipFilePath = $this->tempFileName();
$zip = new ZipArchive();
$result = $zip->open($zipFilePath, ZipArchive::CREATE);
if ($result === true) {
$zip->setPassword(self::ZIP_PASSWORD);
$zip->addFromString($md5, $content);
$zip->setEncryptionName($md5, ZipArchive::EM_AES_128);
$zip->addFromString("$md5.filename.txt", $originalFilename);
$zip->setEncryptionName("$md5.filename.txt", ZipArchive::EM_AES_128);
$zip->close();
} else {
throw new Exception("Could not create encrypted ZIP file '$zipFilePath'. Error code: $result");
}
$zipFile = new File($zipFilePath);
$zipContent = $zipFile->read();
if ($zipContent === false) {
throw new Exception("Could not read content of newly created ZIP file.");
}
$zipFile->delete();
return $zipContent;
}
/**
* @param string $content
* @param array $hashTypes
* @return array
* @throws InvalidArgumentException
*/
public function computeHashes($content, array $hashTypes = array())
{
$validHashes = array('md5', 'sha1', 'sha256');
$hashes = [];
foreach ($hashTypes as $hashType) {
if (!in_array($hashType, $validHashes)) {
throw new InvalidArgumentException("Hash type '$hashType' is not valid hash type.");
}
$hashes[$hashType] = hash($hashType, $content);
}
return $hashes;
}
/**
* @param string $pythonBin
* @param string $filePath
* @return array
* @throws Exception
*/
public function advancedExtraction($pythonBin, $filePath)
{
return $this->executeAndParseJsonOutput([
$pythonBin,
self::ADVANCED_EXTRACTION_SCRIPT_PATH,
'-p',
escapeshellarg($filePath),
]);
}
/**
* @param string $pythonBin
* @return array
* @throws Exception
*/
public function checkAdvancedExtractionStatus($pythonBin)
{
return $this->executeAndParseJsonOutput([$pythonBin, self::ADVANCED_EXTRACTION_SCRIPT_PATH, '-c']);
}
private function tempFileName()
{
$randomName = (new RandomTool())->random_str(false, 12);
return $this->tempDir() . DS . $randomName;
}
/**
* @return string
*/
private function tempDir()
{
return Configure::read('MISP.tmpdir') ?: sys_get_temp_dir();
}
/**
* @param array $command
* @return array
* @throws Exception
*/
private function executeAndParseJsonOutput(array $command)
{
$output = $this->execute($command);
$json = json_decode($output, true);
if ($json === null) {
throw new Exception("Command output is not valid JSON: " . json_last_error_msg());
}
return $json;
}
/**
* This method is much more complicated than just `exec`, but it also provide stderr output, so Exceptions
* can be much more specific.
*
* @param array $command
* @return string
* @throws Exception
*/
private function execute(array $command)
{
$descriptorspec = [
1 => ["pipe", "w"], // stdout
2 => ["pipe", "w"], // stderr
];
$command = implode(' ', $command);
$process = proc_open($command, $descriptorspec, $pipes);
if (!$process) {
throw new Exception("Command '$command' could be started.");
}
$stdout = stream_get_contents($pipes[1]);
if ($stdout === false) {
throw new Exception("Could not get STDOUT of command.");
}
fclose($pipes[1]);
$stderr = stream_get_contents($pipes[2]);
fclose($pipes[2]);
$returnCode = proc_close($process);
if ($returnCode !== 0) {
throw new Exception("Command '$command' return error code $returnCode. STDERR: '$stderr', STDOUT: '$stdout'");
}
return $stdout;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: misp\n" "Project-Id-Version: misp\n"
"PO-Revision-Date: 2020-02-27 02:21\n" "PO-Revision-Date: 2020-04-24 01:13\n"
"Last-Translator: NAME <EMAIL@ADDRESS>\n" "Last-Translator: NAME <EMAIL@ADDRESS>\n"
"Language-Team: German\n" "Language-Team: German\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: misp\n" "Project-Id-Version: misp\n"
"PO-Revision-Date: 2020-02-27 02:23\n" "PO-Revision-Date: 2020-04-24 01:14\n"
"Last-Translator: NAME <EMAIL@ADDRESS>\n" "Last-Translator: NAME <EMAIL@ADDRESS>\n"
"Language-Team: Italian\n" "Language-Team: Italian\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@ -82,11 +82,12 @@ msgstr ""
#: Console/Command/AdminShell.php:563 #: Console/Command/AdminShell.php:563
msgid "\n" msgid "\n"
"Error: %s\n" "Error: %s\n"
msgstr "" msgstr "\n"
"Errore: %s\n"
#: Console/Command/AdminShell.php:565 #: Console/Command/AdminShell.php:565
msgid "%s events purged.\n" msgid "%s events purged.\n"
msgstr "" msgstr "%s eventi eliminati.\n"
#: Console/Command/AdminShell.php:587 #: Console/Command/AdminShell.php:587
msgid "> Database schema dumped on disk" msgid "> Database schema dumped on disk"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: misp\n" "Project-Id-Version: misp\n"
"PO-Revision-Date: 2020-02-27 02:23\n" "PO-Revision-Date: 2020-04-24 01:12\n"
"Last-Translator: NAME <EMAIL@ADDRESS>\n" "Last-Translator: NAME <EMAIL@ADDRESS>\n"
"Language-Team: Russian\n" "Language-Team: Russian\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"

View File

@ -1,7 +1,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: misp\n" "Project-Id-Version: misp\n"
"PO-Revision-Date: 2020-02-27 02:20\n" "PO-Revision-Date: 2020-04-24 01:14\n"
"Last-Translator: NAME <EMAIL@ADDRESS>\n" "Last-Translator: NAME <EMAIL@ADDRESS>\n"
"Language-Team: Chinese Simplified\n" "Language-Team: Chinese Simplified\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@ -73,11 +73,11 @@ msgstr ""
#: Console/Command/AdminShell.php:536 #: Console/Command/AdminShell.php:536
#: Controller/UsersController.php:1234 #: Controller/UsersController.php:1234
msgid "Invalid user." msgid "Invalid user."
msgstr "" msgstr "无效用户"
#: Console/Command/AdminShell.php:539 #: Console/Command/AdminShell.php:539
msgid "User has to be a site admin." msgid "User has to be a site admin."
msgstr "" msgstr "用户必须是站点管理员。"
#: Console/Command/AdminShell.php:563 #: Console/Command/AdminShell.php:563
msgid "\n" msgid "\n"
@ -181,7 +181,7 @@ msgstr "未设置事件ID。"
#: Controller/AttributesController.php:112 #: Controller/AttributesController.php:112
msgid "You do not have permissions to create attributes" msgid "You do not have permissions to create attributes"
msgstr "" msgstr "你没有权限创建属性."
#: Controller/AttributesController.php:132;422;602;832;3127;3142 #: Controller/AttributesController.php:132;422;602;832;3127;3142
#: Controller/EventGraphController.php:88 #: Controller/EventGraphController.php:88
@ -350,7 +350,7 @@ msgstr "此功能只能通过AJAX访问。"
#: Controller/AttributesController.php:2241 #: Controller/AttributesController.php:2241
msgid "You do not have permission to do that" msgid "You do not have permission to do that"
msgstr "" msgstr "您无权执行此操作。"
#: Controller/AttributesController.php:2271;2279 #: Controller/AttributesController.php:2271;2279
#: Controller/EventsController.php:3643;3796;4999 #: Controller/EventsController.php:3643;3796;4999
@ -395,7 +395,7 @@ msgstr "无效请求类型。"
#: Controller/AttributesController.php:2823;3030 #: Controller/AttributesController.php:2823;3030
#: Controller/TagCollectionsController.php:254 #: Controller/TagCollectionsController.php:254
msgid "Invalid tag" msgid "Invalid tag"
msgstr "" msgstr "无效标签"
#: Controller/AttributesController.php:3120 #: Controller/AttributesController.php:3120
#: Controller/EventsController.php:5197 #: Controller/EventsController.php:5197
@ -409,11 +409,11 @@ msgstr "无效属性。"
#: Controller/CommunitiesController.php:150 #: Controller/CommunitiesController.php:150
msgid "Request sent." msgid "Request sent."
msgstr "" msgstr "请求已发送"
#: Controller/CommunitiesController.php:150 #: Controller/CommunitiesController.php:150
msgid "Something went wrong and the request could not be sent." msgid "Something went wrong and the request could not be sent."
msgstr "" msgstr "出错了,请求无法发送。"
#: Controller/CommunitiesController.php:166 #: Controller/CommunitiesController.php:166
msgid "The message could not be sent (either because e-mailing is disabled or because encryption is misconfigured), however, you can view the e-mail that would have been sent below. Feel free to send it manually." msgid "The message could not be sent (either because e-mailing is disabled or because encryption is misconfigured), however, you can view the e-mail that would have been sent below. Feel free to send it manually."

View File

@ -78,7 +78,7 @@ class AppModel extends Model
33 => false, 34 => false, 35 => false, 36 => false, 37 => false, 38 => false, 33 => false, 34 => false, 35 => false, 36 => false, 37 => false, 38 => false,
39 => false, 40 => false, 41 => false, 42 => false, 43 => false, 44 => false, 39 => false, 40 => false, 41 => false, 42 => false, 43 => false, 44 => false,
45 => false, 46 => false, 47 => false, 48 => false, 49 => false, 50 => false, 45 => false, 46 => false, 47 => false, 48 => false, 49 => false, 50 => false,
51 => false 51 => false, 52 => false, 53 => false
); );
public $advanced_updates_description = array( public $advanced_updates_description = array(
@ -1268,7 +1268,7 @@ class AppModel extends Model
case 39: case 39:
$sqlArray[] = "CREATE TABLE IF NOT EXISTS user_settings ( $sqlArray[] = "CREATE TABLE IF NOT EXISTS user_settings (
`id` int(11) NOT NULL AUTO_INCREMENT, `id` int(11) NOT NULL AUTO_INCREMENT,
`key` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL, `setting` varchar(255) COLLATE utf8_bin NOT NULL,
`value` text, `value` text,
`user_id` int(11) NOT NULL, `user_id` int(11) NOT NULL,
`timestamp` int(11) NOT NULL, `timestamp` int(11) NOT NULL,
@ -1377,6 +1377,18 @@ class AppModel extends Model
$sqlArray[] = "ALTER TABLE `feeds` ADD `orgc_id` int(11) NOT NULL DEFAULT 0"; $sqlArray[] = "ALTER TABLE `feeds` ADD `orgc_id` int(11) NOT NULL DEFAULT 0";
$this->__addIndex('feeds', 'orgc_id'); $this->__addIndex('feeds', 'orgc_id');
break; break;
case 52:
if (!empty($this->query("SHOW COLUMNS FROM `admin_settings` LIKE 'key';"))) {
$sqlArray[] = "ALTER TABLE admin_settings CHANGE `key` `setting` varchar(255) COLLATE utf8_bin NOT NULL;";
$this->__addIndex('admin_settings', 'setting');
}
break;
case 53:
if (!empty($this->query("SHOW COLUMNS FROM `user_settings` LIKE 'key';"))) {
$sqlArray[] = "ALTER TABLE user_settings CHANGE `key` `setting` varchar(255) COLLATE utf8_bin NOT NULL;";
$this->__addIndex('user_settings', 'setting');
}
break;
case 'fixNonEmptySharingGroupID': case 'fixNonEmptySharingGroupID':
$sqlArray[] = 'UPDATE `events` SET `sharing_group_id` = 0 WHERE `distribution` != 4;'; $sqlArray[] = 'UPDATE `events` SET `sharing_group_id` = 0 WHERE `distribution` != 4;';
$sqlArray[] = 'UPDATE `attributes` SET `sharing_group_id` = 0 WHERE `distribution` != 4;'; $sqlArray[] = 'UPDATE `attributes` SET `sharing_group_id` = 0 WHERE `distribution` != 4;';
@ -2839,12 +2851,34 @@ class AppModel extends Model
*/ */
protected function logException($message, Exception $exception, $type = LOG_ERR) protected function logException($message, Exception $exception, $type = LOG_ERR)
{ {
$message = sprintf("%s\n[%s] %s", $message .= "\n";
$message,
get_class($exception), do {
$exception->getMessage() $message .= sprintf("[%s] %s",
); get_class($exception),
$message .= "\nStack Trace:\n" . $exception->getTraceAsString(); $exception->getMessage()
);
$message .= "\nStack Trace:\n" . $exception->getTraceAsString();
$exception = $exception->getPrevious();
} while ($exception !== null);
return $this->log($message, $type); return $this->log($message, $type);
} }
/**
* Generates random file name in tmp dir.
* @return string
*/
protected function tempFileName()
{
return $this->tempDir() . DS . $this->generateRandomFileName();
}
/**
* @return string
*/
protected function tempDir()
{
return Configure::read('MISP.tmpdir') ?: sys_get_temp_dir();
}
} }

View File

@ -5,6 +5,7 @@ App::uses('Folder', 'Utility');
App::uses('File', 'Utility'); App::uses('File', 'Utility');
App::uses('FinancialTool', 'Tools'); App::uses('FinancialTool', 'Tools');
App::uses('RandomTool', 'Tools'); App::uses('RandomTool', 'Tools');
App::uses('MalwareTool', 'Tools');
class Attribute extends AppModel class Attribute extends AppModel
{ {
@ -698,7 +699,7 @@ class Attribute extends AppModel
* Only recorrelate if: * Only recorrelate if:
* - We are dealing with a new attribute OR * - We are dealing with a new attribute OR
* - The existing attribute's previous state is known AND * - The existing attribute's previous state is known AND
* value, type or disable correlation have changed * value, type, disable correlation or distribution have changed
* This will avoid recorrelations when it's not really needed, such as adding a tag * This will avoid recorrelations when it's not really needed, such as adding a tag
*/ */
if (!$created) { if (!$created) {
@ -706,7 +707,9 @@ class Attribute extends AppModel
empty($this->old) || empty($this->old) ||
$this->data['Attribute']['value'] != $this->old['Attribute']['value'] || $this->data['Attribute']['value'] != $this->old['Attribute']['value'] ||
$this->data['Attribute']['disable_correlation'] != $this->old['Attribute']['disable_correlation'] || $this->data['Attribute']['disable_correlation'] != $this->old['Attribute']['disable_correlation'] ||
$this->data['Attribute']['type'] != $this->old['Attribute']['type'] $this->data['Attribute']['type'] != $this->old['Attribute']['type'] ||
$this->data['Attribute']['distribution'] != $this->old['Attribute']['distribution'] ||
$this->data['Attribute']['sharing_group_id'] != $this->old['Attribute']['sharing_group_id']
) { ) {
$this->__beforeSaveCorrelation($this->data['Attribute']); $this->__beforeSaveCorrelation($this->data['Attribute']);
$this->__afterSaveCorrelation($this->data['Attribute'], false, $passedEvent); $this->__afterSaveCorrelation($this->data['Attribute'], false, $passedEvent);
@ -3348,6 +3351,9 @@ class Attribute extends AppModel
} else { } else {
$options['includeDecayScore'] = true; $options['includeDecayScore'] = true;
} }
if ($options['includeDecayScore']) {
$options['includeEventTags'] = true;
}
if (!$user['Role']['perm_sync'] || !isset($options['deleted']) || !$options['deleted']) { if (!$user['Role']['perm_sync'] || !isset($options['deleted']) || !$options['deleted']) {
$params['conditions']['AND']['(Attribute.deleted + 0)'] = 0; $params['conditions']['AND']['(Attribute.deleted + 0)'] = 0;
} else { } else {
@ -3477,7 +3483,13 @@ class Attribute extends AppModel
if ($options['includeDecayScore']) { if ($options['includeDecayScore']) {
$this->DecayingModel = ClassRegistry::init('DecayingModel'); $this->DecayingModel = ClassRegistry::init('DecayingModel');
$include_full_model = isset($options['includeFullModel']) && $options['includeFullModel'] ? 1 : 0; $include_full_model = isset($options['includeFullModel']) && $options['includeFullModel'] ? 1 : 0;
if (empty($results[$key]['Attribute']['AttributeTag'])) {
$results[$key]['Attribute']['AttributeTag'] = $results[$key]['AttributeTag'];
$results[$key]['Attribute']['EventTag'] = $results[$key]['EventTag'];
}
$results[$key]['Attribute'] = $this->DecayingModel->attachScoresToAttribute($user, $results[$key]['Attribute'], $options['decayingModel'], $options['modelOverrides'], $include_full_model); $results[$key]['Attribute'] = $this->DecayingModel->attachScoresToAttribute($user, $results[$key]['Attribute'], $options['decayingModel'], $options['modelOverrides'], $include_full_model);
unset($results[$key]['Attribute']['AttributeTag']);
unset($results[$key]['Attribute']['EventTag']);
if ($options['excludeDecayed'] && !empty($results[$key]['Attribute']['decay_score'])) { // filter out decayed attribute if ($options['excludeDecayed'] && !empty($results[$key]['Attribute']['decay_score'])) { // filter out decayed attribute
$decayed_flag = true; $decayed_flag = true;
foreach ($results[$key]['Attribute']['decay_score'] as $decayResult) { // remove attribute if ALL score results in a decay foreach ($results[$key]['Attribute']['decay_score'] as $decayResult) { // remove attribute if ALL score results in a decay
@ -3558,63 +3570,40 @@ class Attribute extends AppModel
if (!is_numeric($event_id)) { if (!is_numeric($event_id)) {
throw new Exception(__('Something went wrong. Received a non-numeric event ID while trying to create a zip archive of an uploaded malware sample.')); throw new Exception(__('Something went wrong. Received a non-numeric event ID while trying to create a zip archive of an uploaded malware sample.'));
} }
$attachments_dir = Configure::read('MISP.attachments_dir');
if (empty($attachments_dir)) { $content = base64_decode($base64);
$attachments_dir = $this->getDefaultAttachments_dir();
$malwareTool = new MalwareTool();
$hashes = $malwareTool->computeHashes($content, $hash_types);
try {
$encrypted = $malwareTool->encrypt($original_filename, $content, $hashes['md5']);
} catch (Exception $e) {
$this->logException("Could not create encrypted malware sample.", $e);
return array('success' => false);
} }
// If we've set attachments to S3, we can't write there $result = array_merge(array('data' => base64_encode($encrypted), 'success' => true), $hashes);
if ($this->attachmentDirIsS3()) {
$attachments_dir = Configure::read('MISP.tmpdir');
// Sometimes it's not set?
if (empty($attachments_dir)) {
// Get a default tmpdir
$attachments_dir = $this->getDefaultTmp_dir();
}
}
if ($proposal) {
$dir = new Folder($attachments_dir . DS . $event_id . DS . 'shadow', true);
} else {
$dir = new Folder($attachments_dir . DS . $event_id, true);
}
$tmpFile = new File($dir->path . DS . $this->generateRandomFileName(), true, 0600);
$tmpFile->write(base64_decode($base64));
$hashes = array();
foreach ($hash_types as $hash) {
$hashes[$hash] = $this->__hashRouter($hash, $tmpFile->path);
}
$contentsFile = new File($dir->path . DS . $hashes['md5']);
rename($tmpFile->path, $contentsFile->path);
$fileNameFile = new File($dir->path . DS . $hashes['md5'] . '.filename.txt');
$fileNameFile->write($original_filename);
$fileNameFile->close();
$zipFile = new File($dir->path . DS . $hashes['md5'] . '.zip');
exec('zip -j -P infected ' . escapeshellarg($zipFile->path) . ' ' . escapeshellarg($contentsFile->path) . ' ' . escapeshellarg($fileNameFile->path), $execOutput, $execRetval);
if ($execRetval != 0) {
$result = array('success' => false);
} else {
$result = array_merge(array('data' => base64_encode($zipFile->read()), 'success' => true), $hashes);
}
$fileNameFile->delete();
$zipFile->delete();
$contentsFile->delete();
return $result; return $result;
} }
private function __hashRouter($hashType, $file) /**
* @return bool Return true if at least one advanced extraction tool is available
*/
public function isAdvancedExtractionAvailable()
{ {
$validHashes = array('md5', 'sha1', 'sha256'); $malwareTool = new MalwareTool();
if (!in_array($hashType, $validHashes)) { try {
$types = $malwareTool->checkAdvancedExtractionStatus($this->getPythonVersion());
} catch (Exception $e) {
return false; return false;
} }
switch ($hashType) {
case 'md5': foreach ($types as $type => $missing) {
case 'sha1': if ($missing === false) {
case 'sha256': return true;
return hash_file($hashType, $file); }
break;
} }
return false; return false;
} }
@ -3961,7 +3950,7 @@ class Attribute extends AppModel
'event_id' => $event_id, 'event_id' => $event_id,
'comment' => !empty($attribute_settings['comment']) ? $attribute_settings['comment'] : '' 'comment' => !empty($attribute_settings['comment']) ? $attribute_settings['comment'] : ''
); );
$result = $this->Event->Attribute->handleMaliciousBase64($event_id, $filename, base64_encode($tmpfile->read()), $hashes); $result = $this->handleMaliciousBase64($event_id, $filename, base64_encode($tmpfile->read()), $hashes);
foreach ($attributes as $k => $v) { foreach ($attributes as $k => $v) {
$attribute = array( $attribute = array(
'distribution' => 5, 'distribution' => 5,
@ -3992,33 +3981,34 @@ class Attribute extends AppModel
public function advancedAddMalwareSample($event_id, $attribute_settings, $filename, $tmpfile) public function advancedAddMalwareSample($event_id, $attribute_settings, $filename, $tmpfile)
{ {
$execRetval = ''; $malwareTool = new MalwareTool();
$execOutput = array(); try {
$result = shell_exec($this->getPythonVersion() . ' ' . APP . 'files/scripts/generate_file_objects.py -p ' . $tmpfile->path); $result = $malwareTool->advancedExtraction($this->getPythonVersion(), $tmpfile->path);
if (!empty($result)) { } catch (Exception $e) {
$result = json_decode($result, true); $this->logException("Could not finish advanced extraction", $e);
if (isset($result['objects'])) { return $this->simpleAddMalwareSample($event_id, $attribute_settings, $filename, $tmpfile);
$result['Object'] = $result['objects']; }
unset($result['objects']);
} if (isset($result['objects'])) {
if (isset($result['references'])) { $result['Object'] = $result['objects'];
$result['ObjectReference'] = $result['references']; unset($result['objects']);
unset($result['references']); }
} if (isset($result['references'])) {
foreach ($result['Object'] as $k => $object) { $result['ObjectReference'] = $result['references'];
$result['Object'][$k]['distribution'] = $attribute_settings['distribution']; unset($result['references']);
$result['Object'][$k]['sharing_group_id'] = isset($attribute_settings['distribution']) ? $attribute_settings['distribution'] : 0; }
if (!empty($result['Object'][$k]['Attribute'])) { foreach ($result['Object'] as $k => $object) {
foreach ($result['Object'][$k]['Attribute'] as $k2 => $attribute) { $result['Object'][$k]['distribution'] = $attribute_settings['distribution'];
if ($attribute['value'] == $tmpfile->name) { $result['Object'][$k]['sharing_group_id'] = isset($attribute_settings['distribution']) ? $attribute_settings['distribution'] : 0;
$result['Object'][$k]['Attribute'][$k2]['value'] = $filename; if (!empty($result['Object'][$k]['Attribute'])) {
} foreach ($result['Object'][$k]['Attribute'] as $k2 => $attribute) {
if ($attribute['value'] == $tmpfile->name) {
$result['Object'][$k]['Attribute'][$k2]['value'] = $filename;
} }
} }
} }
} else {
$result = $this->simpleAddMalwareSample($event_id, $attribute_settings, $filename, $tmpfile);
} }
return $result; return $result;
} }
@ -4639,4 +4629,28 @@ class Attribute extends AppModel
} }
return $conditions; return $conditions;
} }
/**
* @param array $attribute
*/
public function removeGalaxyClusterTags(array &$attribute)
{
$galaxyTagIds = array();
foreach ($attribute['Galaxy'] as $galaxy) {
foreach ($galaxy['GalaxyCluster'] as $galaxyCluster) {
$galaxyTagIds[$galaxyCluster['tag_id']] = true;
}
}
if (empty($galaxyTagIds)) {
return;
}
foreach ($attribute['AttributeTag'] as $k => $attributeTag) {
$tagId = $attributeTag['Tag']['id'];
if (isset($galaxyTagIds[$tagId])) {
unset($attribute['AttributeTag'][$k]);
}
}
}
} }

View File

@ -536,7 +536,7 @@ class DecayingModel extends AppModel
'sightings' => $sightings, 'sightings' => $sightings,
'base_score_config' => $base_score_config, 'base_score_config' => $base_score_config,
'last_sighting' => $sightings[count($sightings)-1], 'last_sighting' => $sightings[count($sightings)-1],
'current_score' => $this->Computation->computeCurrentScore($user, $model, $attribute['Attribute'], $base_score, $last_sighting_timestamp), 'current_score' => $this->Computation->computeCurrentScore($user, $model, $attribute['Attribute'], $base_score, $last_sighting_timestamp)['score'],
'Model' => $model['DecayingModel'] 'Model' => $model['DecayingModel']
); );
} }
@ -587,9 +587,10 @@ class DecayingModel extends AppModel
$model = $this->overrideModelParameters($model, $model_overrides); $model = $this->overrideModelParameters($model, $model_overrides);
} }
$score = $this->getScore($attribute, $model, $user); $score = $this->getScore($attribute, $model, $user);
$decayed = $this->isDecayed($attribute, $model, $score); $decayed = $this->isDecayed($attribute, $model, $score['score']);
$to_attach = array( $to_attach = array(
'score' => $score, 'score' => $score['score'],
'base_score' => $score['base_score'],
'decayed' => $decayed, 'decayed' => $decayed,
'DecayingModel' => array( 'DecayingModel' => array(
'id' => $model['DecayingModel']['id'], 'id' => $model['DecayingModel']['id'],
@ -626,7 +627,7 @@ class DecayingModel extends AppModel
public function isDecayed($attribute, $model, $score=false, $user=false) public function isDecayed($attribute, $model, $score=false, $user=false)
{ {
if ($score === false) { if ($score === false) {
$score = $this->getScore($attribute, $model, $user); $score = $this->getScore($attribute, $model, $user)['score'];
} }
$this->Computation = $this->getModelClass($model); $this->Computation = $this->getModelClass($model);
return $this->Computation->isDecayed($model, $attribute, $score); return $this->Computation->isDecayed($model, $attribute, $score);

View File

@ -144,7 +144,11 @@ abstract class DecayingModelBase
$last_sighting_timestamp = $attribute['timestamp']; $last_sighting_timestamp = $attribute['timestamp'];
} }
$timestamp = time(); $timestamp = time();
return $this->computeScore($model, $attribute, $base_score, $timestamp - $last_sighting_timestamp); $scores = array(
'score' => $this->computeScore($model, $attribute, $base_score, $timestamp - $last_sighting_timestamp),
'base_score' => $base_score
);
return $scores;
} }
// Compute the score for the provided attribute according to the elapsed time with the provided model // Compute the score for the provided attribute according to the elapsed time with the provided model

View File

@ -641,6 +641,12 @@ class Event extends AppModel
if (isset($this->data['Event']['info'])) { if (isset($this->data['Event']['info'])) {
$this->Correlation->updateAll(array('Correlation.info' => $db->value($this->data['Event']['info'])), array('Correlation.event_id' => intval($this->data['Event']['id']))); $this->Correlation->updateAll(array('Correlation.info' => $db->value($this->data['Event']['info'])), array('Correlation.event_id' => intval($this->data['Event']['id'])));
} }
if (isset($this->data['Event']['distribution'])) {
$this->Correlation->updateAll(array('Correlation.distribution' => $db->value($this->data['Event']['distribution'])), array('Correlation.event_id' => intval($this->data['Event']['id'])));
}
if (isset($this->data['Event']['sharing_group_id'])) {
$this->Correlation->updateAll(array('Correlation.sharing_group_id' => $db->value($this->data['Event']['sharing_group_id'])), array('Correlation.event_id' => intval($this->data['Event']['id'])));
}
} }
if (empty($this->data['Event']['unpublishAction']) && empty($this->data['Event']['skip_zmq']) && Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_event_notifications_enable')) { if (empty($this->data['Event']['unpublishAction']) && empty($this->data['Event']['skip_zmq']) && Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_event_notifications_enable')) {
$pubSubTool = $this->getPubSubTool(); $pubSubTool = $this->getPubSubTool();
@ -2150,6 +2156,22 @@ class Event extends AppModel
'Object' => array('name', 'meta-category') 'Object' => array('name', 'meta-category')
); );
foreach ($results as $eventKey => &$event) { foreach ($results as $eventKey => &$event) {
if ($event['Event']['distribution'] == 4 && !in_array($event['Event']['sharing_group_id'], $sgids)) {
$this->Log = ClassRegistry::init('Log');
$this->Log->create();
$this->Log->save(array(
'org' => $user['Organisation']['name'],
'model' => 'Event',
'model_id' => $event['Event']['id'],
'email' => $user['email'],
'action' => 'fetchEvent',
'user_id' => $user['id'],
'title' => 'User was able to fetch the event but not the sharing_group it belongs to',
'change' => ''
));
unset($results[$eventKey]); // Current user cannot access sharing_group associated to this event
continue;
}
$this->__attachReferences($user, $event, $sgids, $fields); $this->__attachReferences($user, $event, $sgids, $fields);
$event = $this->Orgc->attachOrgsToEvent($event, $fieldsOrg); $event = $this->Orgc->attachOrgsToEvent($event, $fieldsOrg);
if (!$options['sgReferenceOnly'] && $event['Event']['sharing_group_id']) { if (!$options['sgReferenceOnly'] && $event['Event']['sharing_group_id']) {
@ -2448,7 +2470,11 @@ class Event extends AppModel
} }
foreach ($data as $k => $v) { foreach ($data as $k => $v) {
if ($v['distribution'] == 4) { if ($v['distribution'] == 4) {
$data[$k]['SharingGroup'] = $sharingGroupData[$v['sharing_group_id']]['SharingGroup']; if (isset($sharingGroupData[$v['sharing_group_id']])) {
$data[$k]['SharingGroup'] = $sharingGroupData[$v['sharing_group_id']]['SharingGroup'];
} else {
unset($data[$k]); // current user could not fetch the sharing_group
}
} }
} }
return $data; return $data;
@ -3237,10 +3263,10 @@ class Event extends AppModel
return array($bodyevent, $body); return array($bodyevent, $body);
} }
private function __captureSGForElement($element, $user) private function __captureSGForElement($element, $user, $syncLocal=false)
{ {
if (isset($element['SharingGroup'])) { if (isset($element['SharingGroup'])) {
$sg = $this->SharingGroup->captureSG($element['SharingGroup'], $user); $sg = $this->SharingGroup->captureSG($element['SharingGroup'], $user, $syncLocal);
unset($element['SharingGroup']); unset($element['SharingGroup']);
} elseif (isset($element['sharing_group_id'])) { } elseif (isset($element['sharing_group_id'])) {
$sg = $this->SharingGroup->checkIfAuthorised($user, $element['sharing_group_id']) ? $element['sharing_group_id'] : false; $sg = $this->SharingGroup->checkIfAuthorised($user, $element['sharing_group_id']) ? $element['sharing_group_id'] : false;
@ -3257,17 +3283,17 @@ class Event extends AppModel
// When we receive an event via REST, we might end up with organisations, sharing groups, tags that we do not know // When we receive an event via REST, we might end up with organisations, sharing groups, tags that we do not know
// or which we need to update. All of that is controlled in this method. // or which we need to update. All of that is controlled in this method.
private function __captureObjects($data, $user) private function __captureObjects($data, $user, $syncLocal=false)
{ {
// First we need to check whether the event or any attributes are tied to a sharing group and whether the user is even allowed to create the sharing group / is part of it // First we need to check whether the event or any attributes are tied to a sharing group and whether the user is even allowed to create the sharing group / is part of it
if (isset($data['Event']['distribution']) && $data['Event']['distribution'] == 4) { if (isset($data['Event']['distribution']) && $data['Event']['distribution'] == 4) {
$data['Event'] = $this->__captureSGForElement($data['Event'], $user); $data['Event'] = $this->__captureSGForElement($data['Event'], $user, $syncLocal);
} }
if (!empty($data['Event']['Attribute'])) { if (!empty($data['Event']['Attribute'])) {
foreach ($data['Event']['Attribute'] as $k => $a) { foreach ($data['Event']['Attribute'] as $k => $a) {
unset($data['Event']['Attribute']['id']); unset($data['Event']['Attribute']['id']);
if (isset($a['distribution']) && $a['distribution'] == 4) { if (isset($a['distribution']) && $a['distribution'] == 4) {
$data['Event']['Attribute'][$k] = $this->__captureSGForElement($a, $user); $data['Event']['Attribute'][$k] = $this->__captureSGForElement($a, $user, $syncLocal);
if ($data['Event']['Attribute'][$k] === false) { if ($data['Event']['Attribute'][$k] === false) {
unset($data['Event']['Attribute']); unset($data['Event']['Attribute']);
} }
@ -3277,7 +3303,7 @@ class Event extends AppModel
if (!empty($data['Event']['Object'])) { if (!empty($data['Event']['Object'])) {
foreach ($data['Event']['Object'] as $k => $o) { foreach ($data['Event']['Object'] as $k => $o) {
if (isset($o['distribution']) && $o['distribution'] == 4) { if (isset($o['distribution']) && $o['distribution'] == 4) {
$data['Event']['Object'][$k] = $this->__captureSGForElement($o, $user); $data['Event']['Object'][$k] = $this->__captureSGForElement($o, $user, $syncLocal);
if ($data['Event']['Object'][$k] === false) { if ($data['Event']['Object'][$k] === false) {
unset($data['Event']['Object'][$k]); unset($data['Event']['Object'][$k]);
continue; continue;
@ -3285,7 +3311,7 @@ class Event extends AppModel
} }
foreach ($o['Attribute'] as $k2 => $a) { foreach ($o['Attribute'] as $k2 => $a) {
if (isset($a['distribution']) && $a['distribution'] == 4) { if (isset($a['distribution']) && $a['distribution'] == 4) {
$data['Event']['Object'][$k]['Attribute'][$k2] = $this->__captureSGForElement($a, $user); $data['Event']['Object'][$k]['Attribute'][$k2] = $this->__captureSGForElement($a, $user, $syncLocal);
if ($data['Event']['Object'][$k]['Attribute'][$k2] === false) { if ($data['Event']['Object'][$k]['Attribute'][$k2] === false) {
unset($data['Event']['Object'][$k]['Attribute'][$k2]); unset($data['Event']['Object'][$k]['Attribute'][$k2]);
} }
@ -3453,6 +3479,24 @@ class Event extends AppModel
return 'blocked'; return 'blocked';
} }
} }
if ($passAlong) {
$this->Server = ClassRegistry::init('Server');
$server = $this->Server->find('first', array(
'conditions' => array(
'Server.id' => $passAlong
),
'recursive' => -1,
'fields' => array(
'Server.name',
'Server.id',
'Server.unpublish_event',
'Server.publish_without_email',
'Server.internal'
)
));
} else {
$server['Server']['internal'] = false;
}
if ($fromXml) { if ($fromXml) {
// Workaround for different structure in XML/array than what CakePHP expects // Workaround for different structure in XML/array than what CakePHP expects
$data = $this->cleanupEventArrayFromXML($data); $data = $this->cleanupEventArrayFromXML($data);
@ -3479,7 +3523,7 @@ class Event extends AppModel
return $existingEvent['Event']['id']; return $existingEvent['Event']['id'];
} else { } else {
if ($fromXml) { if ($fromXml) {
$data = $this->__captureObjects($data, $user); $data = $this->__captureObjects($data, $user, $server['Server']['internal']);
} }
if ($data === false) { if ($data === false) {
$failedCapture = true; $failedCapture = true;
@ -3487,7 +3531,7 @@ class Event extends AppModel
} }
} else { } else {
if ($fromXml) { if ($fromXml) {
$data = $this->__captureObjects($data, $user); $data = $this->__captureObjects($data, $user, $server['Server']['internal']);
} }
if ($data === false) { if ($data === false) {
$failedCapture = true; $failedCapture = true;
@ -3548,19 +3592,6 @@ class Event extends AppModel
$this->Log = ClassRegistry::init('Log'); $this->Log = ClassRegistry::init('Log');
if ($saveResult) { if ($saveResult) {
if ($passAlong) { if ($passAlong) {
$this->Server = ClassRegistry::init('Server');
$server = $this->Server->find('first', array(
'conditions' => array(
'Server.id' => $passAlong
),
'recursive' => -1,
'fields' => array(
'Server.name',
'Server.id',
'Server.unpublish_event',
'Server.publish_without_email'
)
));
if ($server['Server']['publish_without_email'] == 0) { if ($server['Server']['publish_without_email'] == 0) {
$st = "enabled"; $st = "enabled";
} else { } else {
@ -3703,6 +3734,23 @@ class Event extends AppModel
} else { } else {
$existingEvent = $this->findById($id); $existingEvent = $this->findById($id);
} }
if ($passAlong) {
$this->Server = ClassRegistry::init('Server');
$server = $this->Server->find('first', array(
'conditions' => array(
'Server.id' => $passAlong
),
'recursive' => -1,
'fields' => array(
'Server.name',
'Server.id',
'Server.unpublish_event',
'Server.publish_without_email'
)
));
} else {
$server['Server']['internal'] = false;
}
// If the event exists... // If the event exists...
$dateObj = new DateTime(); $dateObj = new DateTime();
$date = $dateObj->getTimestamp(); $date = $dateObj->getTimestamp();
@ -3725,7 +3773,7 @@ class Event extends AppModel
return(array('error' => 'Event could not be saved: Invalid sharing group or you don\'t have access to that sharing group.')); return(array('error' => 'Event could not be saved: Invalid sharing group or you don\'t have access to that sharing group.'));
} }
} else { } else {
$data['Event']['sharing_group_id'] = $this->SharingGroup->captureSG($data['Event']['SharingGroup'], $user); $data['Event']['sharing_group_id'] = $this->SharingGroup->captureSG($data['Event']['SharingGroup'], $user, $server['Server']['internal']);
unset($data['Event']['SharingGroup']); unset($data['Event']['SharingGroup']);
if ($data['Event']['sharing_group_id'] === false) { if ($data['Event']['sharing_group_id'] === false) {
return (array('error' => 'Event could not be saved: User not authorised to create the associated sharing group.')); return (array('error' => 'Event could not be saved: User not authorised to create the associated sharing group.'));
@ -3846,19 +3894,6 @@ class Event extends AppModel
if ((!empty($data['Event']['published']) && 1 == $data['Event']['published'])) { if ((!empty($data['Event']['published']) && 1 == $data['Event']['published'])) {
// The edited event is from a remote server ? // The edited event is from a remote server ?
if ($passAlong) { if ($passAlong) {
$this->Server = ClassRegistry::init('Server');
$server = $this->Server->find('first', array(
'conditions' => array(
'Server.id' => $passAlong
),
'recursive' => -1,
'fields' => array(
'Server.name',
'Server.id',
'Server.unpublish_event',
'Server.publish_without_email'
)
));
if ($server['Server']['publish_without_email'] == 0) { if ($server['Server']['publish_without_email'] == 0) {
$st = "enabled"; $st = "enabled";
} else { } else {
@ -6948,4 +6983,27 @@ class Event extends AppModel
} }
return $filters; return $filters;
} }
/**
* @param array $event
*/
public function removeGalaxyClusterTags(array &$event)
{
$galaxyTagIds = array();
foreach ($event['Galaxy'] as $galaxy) {
foreach ($galaxy['GalaxyCluster'] as $galaxyCluster) {
$galaxyTagIds[$galaxyCluster['tag_id']] = true;
}
}
if (empty($galaxyTagIds)) {
return;
}
foreach ($event['EventTag'] as $k => $eventTag) {
if (isset($galaxyTagIds[$eventTag['tag_id']])) {
unset($event['EventTag'][$k]);
}
}
}
} }

View File

@ -247,10 +247,7 @@ class Feed extends AppModel
$data = $this->feedGetUri($feed, $feedUrl, $HttpSocket, true); $data = $this->feedGetUri($feed, $feedUrl, $HttpSocket, true);
if (!$isLocal) { if (!$isLocal) {
$redis = $this->setupRedis(); $redis = $this->setupRedisWithException();
if ($redis === false) {
throw new Exception('Could not reach Redis.');
}
$redis->del('misp:feed_cache:' . $feed['Feed']['id']); $redis->del('misp:feed_cache:' . $feed['Feed']['id']);
file_put_contents($feedCache, $data); file_put_contents($feedCache, $data);
} }
@ -502,12 +499,17 @@ class Feed extends AppModel
$result = array( $result = array(
'header' => array( 'header' => array(
'Accept' => array('application/json', 'text/plain'), 'Accept' => array('application/json', 'text/plain'),
'Content-Type' => 'application/json', 'MISP-version' => $version,
'MISP-version' => $version, 'MISP-uuid' => Configure::read('MISP.uuid'),
'MISP-uuid' => Configure::read('MISP.uuid')
) )
); );
// Enable gzipped responses if PHP has 'gzdecode' method
if (function_exists('gzdecode')) {
$result['header']['Accept-Encoding'] = 'gzip';
}
if ($commit) { if ($commit) {
$result['header']['commit'] = $commit; $result['header']['commit'] = $commit;
} }
@ -1029,14 +1031,14 @@ class Feed extends AppModel
} elseif ($scope == 'freetext' || $scope == 'csv') { } elseif ($scope == 'freetext' || $scope == 'csv') {
$params['conditions']['source_format'] = array('csv', 'freetext'); $params['conditions']['source_format'] = array('csv', 'freetext');
} elseif ($scope == 'misp') { } elseif ($scope == 'misp') {
$redis->del('misp:feed_cache:event_uuid_lookup:'); $redis->del($redis->keys('misp:feed_cache:event_uuid_lookup:*'));
$params['conditions']['source_format'] = 'misp'; $params['conditions']['source_format'] = 'misp';
} else { } else {
throw new InvalidArgumentException("Invalid value for scope, it must be integer or 'freetext', 'csv', 'misp' or 'all' string."); throw new InvalidArgumentException("Invalid value for scope, it must be integer or 'freetext', 'csv', 'misp' or 'all' string.");
} }
} else { } else {
$redis->del('misp:feed_cache:combined'); $redis->del('misp:feed_cache:combined');
$redis->del('misp:feed_cache:event_uuid_lookup:'); $redis->del($redis->keys('misp:feed_cache:event_uuid_lookup:*'));
} }
$feeds = $this->find('all', $params); $feeds = $this->find('all', $params);
$atLeastOneSuccess = false; $atLeastOneSuccess = false;
@ -1590,24 +1592,51 @@ class Feed extends AppModel
if ($data === false) { if ($data === false) {
throw new Exception("Could not read local file '$uri'."); throw new Exception("Could not read local file '$uri'.");
} }
return $data;
} else { } else {
throw new Exception("Local file '$uri' doesn't exists."); throw new Exception("Local file '$uri' doesn't exists.");
} }
}
$request = $this->__createFeedRequest($feed['Feed']['headers']);
if ($followRedirect) {
$response = $this->getFollowRedirect($HttpSocket, $uri, $request);
} else { } else {
$request = $this->__createFeedRequest($feed['Feed']['headers']); $response = $HttpSocket->get($uri, array(), $request);
}
if ($followRedirect) { if ($response === false) {
$response = $this->getFollowRedirect($HttpSocket, $uri, $request); throw new Exception("Could not reach '$uri'.");
} else { } else if ($response->code != 200) { // intentionally !=
$response = $HttpSocket->get($uri, array(), $request); throw new Exception("Fetching the '$uri' failed with HTTP error {$response->code}: {$response->reasonPhrase}");
} }
if ($response === false) { $data = $response->body;
throw new Exception("Could not reach '$uri'.");
} else if ($response->code != 200) { // intentionally != $contentEncoding = $response->getHeader('Content-Encoding');
throw new Exception("Fetching the '$uri' failed with HTTP error {$response->code}: {$response->reasonPhrase}"); if ($contentEncoding === 'gzip') {
$data = gzdecode($data);
if ($data === false) {
throw new Exception("Fetching the '$uri' failed, response should be gzip encoded, but gzip decoding failed.");
}
} else if ($contentEncoding) {
throw new Exception("Fetching the '$uri' failed, because remote server returns unsupported content encoding '$contentEncoding'");
}
$contentType = $response->getHeader('Content-Type');
if ($contentType === 'application/zip') {
$zipFile = new File($this->tempFileName());
$zipFile->write($data);
$zipFile->close();
try {
$data = $this->unzipFirstFile($zipFile);
} catch (Exception $e) {
throw new Exception("Fetching the '$uri' failed: {$e->getMessage()}");
} finally {
$zipFile->delete();
} }
$data = $response->body;
} }
return $data; return $data;
@ -1720,4 +1749,47 @@ class Feed extends AppModel
$this->save($feed); $this->save($feed);
return $count; return $count;
} }
/**
* @param File $zipFile
* @return string Uncompressed data
* @throws Exception
*/
private function unzipFirstFile(File $zipFile)
{
if (!class_exists('ZipArchive')) {
throw new Exception("ZIP archive decompressing is not supported.");
}
$zip = new ZipArchive();
$result = $zip->open($zipFile->pwd());
if ($result !== true) {
throw new Exception("Remote server returns ZIP file, that cannot be open (error $result)");
}
if ($zip->numFiles !== 1) {
throw new Exception("Remote server returns ZIP file, that contains multiple files.");
}
$filename = $zip->getNameIndex(0);
if ($filename === false) {
throw new Exception("Remote server returns ZIP file, but there is a problem with reading filename.");
}
$zip->close();
$destinationFile = $this->tempFileName();
$result = copy("zip://{$zipFile->pwd()}#$filename", $destinationFile);
if ($result === false) {
throw new Exception("Remote server returns ZIP file, that contains '$filename' file, that cannot be extracted.");
}
$unzipped = new File($destinationFile);
$data = $unzipped->read();
if ($data === false) {
throw new Exception("Couldn't read extracted file content.");
}
$unzipped->delete();
return $data;
}
} }

View File

@ -96,18 +96,6 @@ class Log extends AppModel
'email' => array('values' => array('admin_email')) 'email' => array('values' => array('admin_email'))
); );
public function beforeValidete()
{
parent::beforeValidate();
if (!isset($this->data['Log']['org']) || empty($this->data['Log']['org'])) {
$this->data['Log']['org'] = 'SYSTEM';
}
// truncate the description if it would exceed the allowed size in mysql
if (!empty($this->data['Log']['description'] && strlen($this->data['Log']['description']) > 65536)) {
$this->data['Log']['description'] = substr($this->data['Log']['description'], 0, 65535);
}
}
public function beforeSave($options = array()) public function beforeSave($options = array())
{ {
if (!empty(Configure::read('MISP.log_skip_db_logs_completely'))) { if (!empty(Configure::read('MISP.log_skip_db_logs_completely'))) {
@ -125,7 +113,7 @@ class Log extends AppModel
if (!isset($this->data['Log']['created'])) { if (!isset($this->data['Log']['created'])) {
$this->data['Log']['created'] = date('Y-m-d H:i:s'); $this->data['Log']['created'] = date('Y-m-d H:i:s');
} }
if (!isset($this->data['Log']['org'])) { if (!isset($this->data['Log']['org']) || empty($this->data['Log']['org'])) {
$this->data['Log']['org'] = 'SYSTEM'; $this->data['Log']['org'] = 'SYSTEM';
} }
$truncate_fields = array('title', 'change', 'description'); $truncate_fields = array('title', 'change', 'description');

View File

@ -1261,6 +1261,54 @@ class Server extends AppModel
'type' => 'boolean', 'type' => 'boolean',
'null' => true 'null' => true
), ),
'email_otp_enabled' => array(
'level'=> 2,
'description' => __('Enable two step authentication with a OTP sent by email. Requires e-mailing to be enabled. Warning: You cannot use it in combination with external authentication plugins.'),
'value' => false,
'errorMessage' => '',
'test' => 'testBool',
'beforeHook' => 'otpBeforeHook',
'type' => 'boolean',
'null' => true
),
'email_otp_length' => array (
'level' => 2,
'description' => __('Define the length of the OTP code sent by email'),
'value' => '6',
'errorMessage' => '',
'type' => 'numeric',
'test' => 'testForNumeric',
'null' => true,
),
'email_otp_validity' => array (
'level' => 2,
'description' => __('Define the validity (in minutes) of the OTP code sent by email'),
'value' => '5',
'errorMessage' => '',
'type' => 'numeric',
'test' => 'testForNumeric',
'null' => true,
),
'email_otp_text' => array(
'level' => 2,
'bigField' => true,
'description' => __('The message sent to the user when a new OTP is requested. Use \\n for line-breaks. The following variables will be automatically replaced in the text: $otp = the new OTP generated by MISP, $username = the user\'s e-mail address, $org the Organisation managing the instance, $misp = the url of this instance, $contact = the e-mail address used to contact the support team (as set in MISP.contact), $ip the IP used to complete the first step of the login and $validity the validity time in minutes.'),
'value' => 'Dear MISP user,\n\nYou have attempted to login to MISP ($misp) from $ip with username $username.\n\n Use the following OTP to log into MISP: $otp\n This code is valid for the next $validity minutes.\n\nIf you have any questions, don\'t hesitate to contact us at: $contact.\n\nBest regards,\nYour $org MISP support team',
'errorMessage' => '',
'test' => 'testForEmpty',
'type' => 'string',
'null' => true,
),
'email_otp_exceptions' => array(
'level' => 2,
'bigField' => true,
'description' => __('A comma separated list of emails for which the OTP is disabled. Note that if you remove someone from this list, the OTP will only be asked at next login.'),
'value' => '',
'errorMessage' => '',
'test' => 'testForEmpty',
'type' => 'string',
'null' => true,
),
'allow_self_registration' => array( 'allow_self_registration' => array(
'level' => 1, 'level' => 1,
'description' => __('Enabling this setting will allow users to have access to the pre-auth registration form. This will create an inbox entry for administrators to review.'), 'description' => __('Enabling this setting will allow users to have access to the pre-auth registration form. This will create an inbox entry for administrators to review.'),
@ -3113,15 +3161,6 @@ class Server extends AppModel
private function readModuleSettings($serverSettings, $moduleTypes) private function readModuleSettings($serverSettings, $moduleTypes)
{ {
$this->Module = ClassRegistry::init('Module'); $this->Module = ClassRegistry::init('Module');
$orgs = $this->Organisation->find('list', array(
'conditions' => array(
'Organisation.local' => 1
),
'fields' => array(
'Organisation.id', 'Organisation.name'
)
));
$orgs = array_merge(array('Unrestricted'), $orgs);
foreach ($moduleTypes as $moduleType) { foreach ($moduleTypes as $moduleType) {
if (Configure::read('Plugin.' . $moduleType . '_services_enable')) { if (Configure::read('Plugin.' . $moduleType . '_services_enable')) {
$results = $this->Module->getModuleSettings($moduleType); $results = $this->Module->getModuleSettings($moduleType);
@ -3550,7 +3589,7 @@ class Server extends AppModel
if ($errorMessage) { if ($errorMessage) {
return $errorMessage; return $errorMessage;
} }
return 'Value is not a boolean, make sure that you convert \'true\' to true for example.'; return __('Value is not a boolean, make sure that you convert \'true\' to true for example.');
} }
return true; return true;
} }
@ -3740,6 +3779,14 @@ class Server extends AppModel
return true; return true;
} }
public function otpBeforeHook($setting, $value)
{
if ($value && !empty(Configure::read('MISP.disable_emailing'))) {
return __('Emailing is currently disabled. Enabling OTP without e-mailing being configured would lock all users out.');
}
return true;
}
public function testForRPZSerial($value) public function testForRPZSerial($value)
{ {
if ($this->testForEmpty($value) !== true) { if ($this->testForEmpty($value) !== true) {
@ -3901,7 +3948,6 @@ class Server extends AppModel
} else { } else {
$serverSettings = $this->serverSettings; $serverSettings = $this->serverSettings;
} }
$relevantSettings = (array_intersect_key(Configure::read(), $serverSettings));
$setting = false; $setting = false;
foreach ($serverSettings as $k => $s) { foreach ($serverSettings as $k => $s) {
if (isset($s['branch'])) { if (isset($s['branch'])) {
@ -5752,7 +5798,7 @@ class Server extends AppModel
$params['conditions']['Server.id'] = $id; $params['conditions']['Server.id'] = $id;
} else { } else {
$redis->del('misp:server_cache:combined'); $redis->del('misp:server_cache:combined');
$redis->del('misp:server_cache:event_uuid_lookup:'); $redis->del($redis->keys('misp:server_cache:event_uuid_lookup:*'));
} }
$servers = $this->find('all', $params); $servers = $this->find('all', $params);
if ($jobId) { if ($jobId) {

View File

@ -54,6 +54,10 @@ class SharingGroup extends AppModel
); );
private $__sgoCache = array(); private $__sgoCache = array();
private $__sgAuthorisationCache = array(
'save' => array(),
'access' => array()
);
public function beforeValidate($options = array()) public function beforeValidate($options = array())
@ -353,6 +357,9 @@ class SharingGroup extends AppModel
// returns true if the SG exists and the user is allowed to see it // returns true if the SG exists and the user is allowed to see it
public function checkIfAuthorised($user, $id, $adminCheck = true) public function checkIfAuthorised($user, $id, $adminCheck = true)
{ {
if (isset($this->__sgAuthorisationCache['access'][boolval($adminCheck)][$id])) {
return $this->__sgAuthorisationCache['access'][boolval($adminCheck)][$id];
}
if (Validation::uuid($id)) { if (Validation::uuid($id)) {
$sgid = $this->SharingGroup->find('first', array( $sgid = $this->SharingGroup->find('first', array(
'conditions' => array('SharingGroup.uuid' => $id), 'conditions' => array('SharingGroup.uuid' => $id),
@ -372,8 +379,10 @@ class SharingGroup extends AppModel
return false; return false;
} }
if (($adminCheck && $user['Role']['perm_site_admin']) || $this->SharingGroupServer->checkIfAuthorised($id) || $this->SharingGroupOrg->checkIfAuthorised($id, $user['org_id'])) { if (($adminCheck && $user['Role']['perm_site_admin']) || $this->SharingGroupServer->checkIfAuthorised($id) || $this->SharingGroupOrg->checkIfAuthorised($id, $user['org_id'])) {
$this->__sgAuthorisationCache['access'][boolval($adminCheck)][$id] = true;
return true; return true;
} }
$this->__sgAuthorisationCache['access'][boolval($adminCheck)][$id] = false;
return false; return false;
} }
@ -485,7 +494,7 @@ class SharingGroup extends AppModel
return $results; return $results;
} }
public function captureSG($sg, $user) public function captureSG($sg, $user, $syncLocal=false)
{ {
$existingSG = !isset($sg['uuid']) ? null : $this->find('first', array( $existingSG = !isset($sg['uuid']) ? null : $this->find('first', array(
'recursive' => -1, 'recursive' => -1,
@ -501,6 +510,34 @@ class SharingGroup extends AppModel
if (!$user['Role']['perm_sharing_group']) { if (!$user['Role']['perm_sharing_group']) {
return false; return false;
} }
// check if current user is contained in the SG and we are in a local sync setup
if (!empty($sg['uuid'])) {
if (isset($this->__sgAuthorisationCache['save'][boolval($syncLocal)][$sg['uuid']])) {
$authorisedToSave = $this->__sgAuthorisationCache['save'][boolval($syncLocal)][$sg['uuid']];
} else {
$authorisedToSave = $this->checkIfAuthorisedToSave($user, $sg);
$this->__sgAuthorisationCache['save'][boolval($syncLocal)][$sg['uuid']] = $authorisedToSave;
}
} else {
$authorisedToSave = $this->checkIfAuthorisedToSave($user, $sg);
}
if (!$user['Role']['perm_site_admin'] &&
!($user['Role']['perm_sync'] && $syncLocal ) &&
!$authorisedToSave
) {
$this->Log->create();
$entry = array(
'org' => $user['Organisation']['name'],
'model' => 'SharingGroup',
'model_id' => $sg['SharingGroup']['uuid'],
'email' => $user['email'],
'action' => 'error',
'user_id' => $user['id'],
'title' => 'Tried to save a sharing group but the user does not belong to it.'
);
$this->Log->save($entry);
return false;
}
$this->create(); $this->create();
$newSG = array(); $newSG = array();
$attributes = array( $attributes = array(

View File

@ -68,10 +68,10 @@ class SysLog {
} else if (in_array($type, $debugTypes)) { } else if (in_array($type, $debugTypes)) {
$priority = LOG_DEBUG; $priority = LOG_DEBUG;
} }
$output = date('Y-m-d H:i:s') . ' ' . ucfirst($type) . ': ' . $message . "\n";
if (!openlog($this->_ident, LOG_PID | LOG_PERROR, $this->_facility)) { if (!openlog($this->_ident, LOG_PID | LOG_PERROR, $this->_facility)) {
return false; return false;
} }
$output = date('Y-m-d H:i:s') . ' ' . ucfirst($type) . ': ' . $message;
$result = syslog($priority, $output); $result = syslog($priority, $output);
closelog(); closelog();
return $result; return $result;

View File

@ -67,9 +67,11 @@
<?php <?php
echo $this->Form->input('advanced', array( echo $this->Form->input('advanced', array(
'type' => 'checkbox', 'type' => 'checkbox',
'checked' => false, 'checked' => true,
'disabled' => !$advancedExtractionAvailable,
'data-disabled-reason' => !$advancedExtractionAvailable ? __('Advanced extraction is not installed') : '',
'div' => array('id' => 'advanced_input', 'style' => 'display:none'), 'div' => array('id' => 'advanced_input', 'style' => 'display:none'),
'label' => __('Advanced extraction (if installed)'), 'label' => __('Advanced extraction'),
)); ));
?> ?>
</fieldset> </fieldset>
@ -131,7 +133,7 @@ $(document).ready(function() {
$("#AttributeCategory, #AttributeDistribution").change(function() { $("#AttributeCategory, #AttributeDistribution").change(function() {
initPopoverContent('Attribute'); initPopoverContent('Attribute');
}); });
$("#AttributeMalware").change(function () { $("#AttributeMalware").change(function () {
if (this.checked) { if (this.checked) {
$('#advanced_input').show(); $('#advanced_input').show();

View File

@ -14,7 +14,7 @@
$tr_class .= ' row_' . h($k); $tr_class .= ' row_' . h($k);
} }
?> ?>
<tr id = "Object_<?php echo $object['id']; ?>_tr" class="<?php echo $tr_class; ?>" tabindex="0"> <tr id="Object_<?php echo $object['id']; ?>_tr" class="<?php echo $tr_class; ?>" tabindex="0">
<?php <?php
if ($mayModify || $extended): if ($mayModify || $extended):
?> ?>
@ -22,7 +22,7 @@
<?php <?php
if ($mayModify): if ($mayModify):
?> ?>
<input id = "select_object_<?php echo $object['id']; ?>" class="select_object row_checkbox" type="checkbox" data-id="<?php echo $object['id'];?>" /> <input id="select_object_<?php echo $object['id']; ?>" class="select_object row_checkbox" type="checkbox" data-id="<?php echo $object['id'];?>" />
<?php <?php
endif; endif;
?> ?>
@ -64,7 +64,7 @@
?> ?>
&nbsp; &nbsp;
</td> </td>
<td colspan="5"> <td colspan="<?= $includeRelatedTags ? 6 : 5 ?>">
<span class="bold"><?php echo __('Name: ');?></span><?php echo h($object['name']);?> <span class="bold"><?php echo __('Name: ');?></span><?php echo h($object['name']);?>
<span class="fa fa-expand useCursorPointer" title="<?php echo __('Expand or Collapse');?>" role="button" tabindex="0" aria-label="<?php echo __('Expand or Collapse');?>" data-toggle="collapse" data-target="#Object_<?php echo h($object['id']); ?>_collapsible"></span> <span class="fa fa-expand useCursorPointer" title="<?php echo __('Expand or Collapse');?>" role="button" tabindex="0" aria-label="<?php echo __('Expand or Collapse');?>" data-toggle="collapse" data-target="#Object_<?php echo h($object['id']); ?>_collapsible"></span>
<br /> <br />
@ -89,8 +89,8 @@
?> ?>
</td> </td>
<td class="showspaces bitwider" onmouseenter="quickEditHover(this, 'Object', '<?php echo $object['id']; ?>', 'comment', <?php echo $event['Event']['id'];?>);"> <td class="showspaces bitwider" onmouseenter="quickEditHover(this, 'Object', '<?php echo $object['id']; ?>', 'comment', <?php echo $event['Event']['id'];?>);">
<div id = "Object_<?php echo $object['id']; ?>_comment_placeholder" class = "inline-field-placeholder"></div> <div id="Object_<?php echo $object['id']; ?>_comment_placeholder" class="inline-field-placeholder"></div>
<div id = "Object_<?php echo $object['id']; ?>_comment_solid" class="inline-field-solid"> <div id="Object_<?php echo $object['id']; ?>_comment_solid" class="inline-field-solid">
<?php echo nl2br(h($object['comment'])); ?>&nbsp; <?php echo nl2br(h($object['comment'])); ?>&nbsp;
</div> </div>
</td> </td>
@ -101,8 +101,8 @@
$turnRed = ''; $turnRed = '';
if ($object['objectType'] == 0 && $object['distribution'] == 0) $turnRed = 'style="color:red"'; if ($object['objectType'] == 0 && $object['distribution'] == 0) $turnRed = 'style="color:red"';
?> ?>
<div id = "<?php echo $currentType . '_' . $object['id'] . '_distribution_placeholder'; ?>" class = "inline-field-placeholder"></div> <div id="<?php echo $currentType . '_' . $object['id'] . '_distribution_placeholder'; ?>" class="inline-field-placeholder"></div>
<div id = "<?php echo $currentType . '_' . $object['id'] . '_distribution_solid'; ?>" <?php echo $turnRed; ?> class="inline-field-solid"> <div id="<?php echo $currentType . '_' . $object['id'] . '_distribution_solid'; ?>" <?php echo $turnRed; ?> class="inline-field-solid">
<?php <?php
if ($object['objectType'] == 0) { if ($object['objectType'] == 0) {
if ($object['distribution'] == 4): if ($object['distribution'] == 4):
@ -163,4 +163,4 @@
} }
echo '<tr class="objectAddFieldTr"><td><span class="fa fa-plus-circle objectAddField" title="' . __('Add an Object Attribute') .'" onclick="popoverPopup(this, ' . h($object['id']) . ', \'objects\', \'quickFetchTemplateWithValidObjectAttributes\')"></span></td></tr>'; echo '<tr class="objectAddFieldTr"><td><span class="fa fa-plus-circle objectAddField" title="' . __('Add an Object Attribute') .'" onclick="popoverPopup(this, ' . h($object['id']) . ', \'objects\', \'quickFetchTemplateWithValidObjectAttributes\')"></span></td></tr>';
} }
?>

View File

@ -32,6 +32,7 @@
if (!$skipPagination) { if (!$skipPagination) {
$paginationData = !empty($data['paginatorOptions']) ? $data['paginatorOptions'] : array(); $paginationData = !empty($data['paginatorOptions']) ? $data['paginatorOptions'] : array();
echo $this->element('/genericElements/IndexTable/pagination', array('paginationOptions' => $paginationData)); echo $this->element('/genericElements/IndexTable/pagination', array('paginationOptions' => $paginationData));
echo $this->element('/genericElements/IndexTable/pagination_links');
} }
if (!empty($data['top_bar'])) { if (!empty($data['top_bar'])) {
echo $this->element('/genericElements/ListTopBar/scaffold', array('data' => $data['top_bar'])); echo $this->element('/genericElements/ListTopBar/scaffold', array('data' => $data['top_bar']));
@ -81,7 +82,7 @@
echo '</div>'; echo '</div>';
if (!$skipPagination) { if (!$skipPagination) {
echo $this->element('/genericElements/IndexTable/pagination_counter', $paginationData); echo $this->element('/genericElements/IndexTable/pagination_counter', $paginationData);
echo $this->element('/genericElements/IndexTable/pagination', $paginationData); echo $this->element('/genericElements/IndexTable/pagination_links');
} }
?> ?>
<script type="text/javascript"> <script type="text/javascript">

View File

@ -9,10 +9,4 @@
$options = array_merge($options, $paginationOptions); $options = array_merge($options, $paginationOptions);
} }
echo $this->Paginator->options($options); echo $this->Paginator->options($options);
echo sprintf(
'<div class="pagination"><ul>%s%s%s</ul></div>',
$this->Paginator->prev('&laquo; ' . __('previous'), array('tag' => 'li', 'escape' => false), null, array('tag' => 'li', 'class' => 'prev disabled', 'escape' => false, 'disabledTag' => 'span')),
$this->Paginator->numbers(array('modulus' => 20, 'separator' => '', 'tag' => 'li', 'currentClass' => 'active', 'currentTag' => 'span')),
$this->Paginator->next(__('next') . ' &raquo;', array('tag' => 'li', 'escape' => false), null, array('tag' => 'li', 'class' => 'next disabled', 'escape' => false, 'disabledTag' => 'span'))
);
?> ?>

View File

@ -0,0 +1,7 @@
<?php
echo sprintf(
'<div class="pagination"><ul>%s%s%s</ul></div>',
$this->Paginator->prev('&laquo; ' . __('previous'), array('tag' => 'li', 'escape' => false), null, array('tag' => 'li', 'class' => 'prev disabled', 'escape' => false, 'disabledTag' => 'span')),
$this->Paginator->numbers(array('modulus' => 20, 'separator' => '', 'tag' => 'li', 'currentClass' => 'active', 'currentTag' => 'span')),
$this->Paginator->next(__('next') . ' &raquo;', array('tag' => 'li', 'escape' => false), null, array('tag' => 'li', 'class' => 'next disabled', 'escape' => false, 'disabledTag' => 'span'))
);

View File

@ -10,7 +10,7 @@
</div> </div>
<div id="eventdistri_graph" data-event-id="<?php echo h($event['Event']['id']); ?>" data-event-distribution="<?php echo h($event['Event']['distribution']); ?>" data-event-distribution-text="<?php echo $event['Event']['distribution'] == 4 ? h($event['SharingGroup']['name']) : h($distributionLevels[$event['Event']['distribution']]); ?>" data-user-manipulation="<?php echo $mayModify || $isSiteAdmin ? 'true' : 'false'; ?>" data-extended="<?php echo $extended; ?>"> <div id="eventdistri_graph" data-event-id="<?php echo h($event['Event']['id']); ?>" data-event-distribution="<?php echo h($event['Event']['distribution']); ?>" data-event-distribution-text="<?php echo $event['Event']['distribution'] == 4 ? h($event['SharingGroup']['name']) : h($distributionLevels[$event['Event']['distribution']]); ?>" data-user-manipulation="<?php echo $mayModify || $isSiteAdmin ? 'true' : 'false'; ?>" data-extended="<?php echo $extended; ?>">
<canvas id="distribution_graph_canvas" height="290px"width="400px"></canvas> <canvas id="distribution_graph_canvas" height="290" width="400"></canvas>
</div> </div>
<div class="popupDistriSeparator"></div> <div class="popupDistriSeparator"></div>
<div id="eventdistri_pb_container"> <div id="eventdistri_pb_container">

View File

@ -301,27 +301,27 @@
) )
) )
); );
if (!Configure::read('MISP.completely_disable_correlation') && Configure::read('MISP.allow_disabling_correlation')) { }
$table_data[] = array( if (!Configure::read('MISP.completely_disable_correlation') && Configure::read('MISP.allow_disabling_correlation')) {
'key' => __('Correlation'), $table_data[] = array(
'class' => $event['Event']['disable_correlation'] ? 'background-red bold' : '', 'key' => __('Correlation'),
'html' => sprintf( 'class' => $event['Event']['disable_correlation'] ? 'background-red bold' : '',
'%s%s', 'html' => sprintf(
$event['Event']['disable_correlation'] ? __('Disabled') : __('Enabled'), '%s%s',
(!$mayModify && !$isSiteAdmin) ? '' : sprintf( $event['Event']['disable_correlation'] ? __('Disabled') : __('Enabled'),
(!$mayModify && !$isSiteAdmin) ? '' : sprintf(
sprintf(
' (<a onClick="getPopup(%s);" style="%scursor:pointer;font-weight:normal;">%s</a>)',
sprintf( sprintf(
' (<a onClick="getPopup(%s);" style="%scursor:pointer;font-weight:normal;">%s</a>)', "'%s', 'events', 'toggleCorrelation', '', '#confirmation_box'",
sprintf( h($event['Event']['id'])
"'%s', 'events', 'toggleCorrelation', '', '#confirmation_box'", ),
h($event['Event']['id']) $event['Event']['disable_correlation'] ? 'color:white;' : '',
), $event['Event']['disable_correlation'] ? __('enable') : __('disable')
$event['Event']['disable_correlation'] ? 'color:white;' : '',
$event['Event']['disable_correlation'] ? __('enable') : __('disable')
)
) )
) )
); )
} );
} }
?> ?>

View File

@ -27,8 +27,6 @@
'button' => __('Filter'), 'button' => __('Filter'),
'placeholder' => __('Enter value to search'), 'placeholder' => __('Enter value to search'),
'data' => '', 'data' => '',
'searchKey' => 'value',
'value' => $searchall
) )
) )
), ),
@ -101,6 +99,19 @@
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function(){ $(document).ready(function(){
var passedArgsArray = <?php echo $passedArgs; ?>;
var galaxyId = "<?php echo h($galaxy_id); ?>";
if (passedArgsArray['context'] === undefined || passedArgsArray['context'] === "") {
passedArgsArray['context'] = 'all';
}
$('#quickFilterButton').click(function() {
runIndexQuickFilter('/' + galaxyId + '/context:' + passedArgsArray['context']);
});
$('#quickFilterField').on('keypress', function (e) {
if(e.which === 13) {
runIndexQuickFilter('/' + galaxyId + '/context:' + passedArgsArray['context']);
}
});
}); });
</script> </script>
<?php echo $this->Js->writeBuffer(); ?> <?php echo $this->Js->writeBuffer(); ?>

View File

@ -14,7 +14,7 @@
<tr> <tr>
<td><table><tr id = "tags"></tr></table></td> <td><table><tr id = "tags"></tr></table></td>
<td id = "addTagButtonTD"> <td id = "addTagButtonTD">
<button onClick="activateTagField()" id="addTagButton" title="<?php echo __('Add tag');?>" class="btn btn-inverse noPrint" style="line-height:10px; padding: 4px 4px;">+</button> <button type="button" onClick="activateTagField()" id="addTagButton" title="<?php echo __('Add tag');?>" class="btn btn-inverse noPrint" style="line-height:10px; padding: 4px 4px;">+</button>
</td> </td>
<td id = "addTagFieldTD"> <td id = "addTagFieldTD">
<?php <?php

View File

@ -0,0 +1,30 @@
<?php echo $this->Flash->render(); ?>
<div class="actions sideMenu">
<div style="padding: 10px;">
<p> <?php echo __("Your administrator has turned on an additional authentication step which
requires you to enter a OTP (one time password) you have received via email.");?>
</p>
<p> <?php echo __("Make sure to check your SPAM folder.");?> </p>
<a href='<?php echo $baseurl; ?>/users/email_otp'> <button class='btn'> <?php echo __("Resend"); ?> </button></a>
</div>
</div>
<?php
echo $this->element('/genericElements/Form/genericForm', array(
"form" => $this->Form,
"data" => array(
"title" => __("Validate your OTP"),
"fields" => array(
array(
"field" => "otp",
"label" => __("One Time Password"),
"type" => "text",
"placeholder" => __("Enter your OTP here"),
),
),
"submit" => array (
"action" => "EmailOtp",
),
)));
?>

View File

@ -232,7 +232,7 @@
"event_id": "5655", "event_id": "5655",
"publish": false, "publish": false,
"override_ids": false, "override_ids": false,
"settings": "{\"csv\":{\"value\":\"\",\"delimiter\":\"\"},\"common\":{\"excluderegex\":\"\\/^http:\\\\\\/\\\\\\/www.phishtank.com\\/i\"}}", "settings": "{\"csv\":{\"value\":\"2\",\"delimiter\":\",\"},\"common\":{\"excluderegex\":\"\\/^http:\\\\\\/\\\\\\/www.phishtank.com\\/i\"}}",
"input_source": "network", "input_source": "network",
"delete_local_file": false, "delete_local_file": false,
"lookup_visible": false, "lookup_visible": false,

@ -1 +1 @@
Subproject commit 1ffa97389b99aa71a20e967b22e2df45750f3bff Subproject commit 3b5451c32518da3e29c575e868d245f27c18dcf4

@ -1 +1 @@
Subproject commit 28e7cb79f0ec603c232857a3bf7dca519d02cfa1 Subproject commit 8c4e2a8e8b4d3ec287c43dcae129123fcde8cb2f

View File

@ -4473,6 +4473,16 @@ function quickSelect(target) {
} }
$(document).ready(function() { $(document).ready(function() {
// Show popover for disabled input that contains `data-disabled-reason`.
$('input:disabled[data-disabled-reason]').popover("destroy").popover({
placement: 'right',
html: 'true',
trigger: 'hover',
content: function () {
return $(this).data('disabled-reason');
}
});
$('#quickFilterField').bind("enterKey",function(e){ $('#quickFilterField').bind("enterKey",function(e){
$('#quickFilterButton').trigger("click"); $('#quickFilterButton').trigger("click");
}); });

View File

@ -6567,5 +6567,5 @@
"id" "id"
] ]
}, },
"db_version": "51" "db_version": "53"
} }

View File

@ -229,10 +229,13 @@ installCoreRHEL () {
$SUDO_WWW git clone --branch master --single-branch https://github.com/lief-project/LIEF.git lief $SUDO_WWW git clone --branch master --single-branch https://github.com/lief-project/LIEF.git lief
$SUDO_WWW git clone https://github.com/CybOXProject/mixbox.git $SUDO_WWW git clone https://github.com/CybOXProject/mixbox.git
cd $PATH_TO_MISP/app/files/scripts/python-cybox
# If you umask is has been changed from the default, it is a good idea to reset it to 0022 before installing python modules # If you umask is has been changed from the default, it is a good idea to reset it to 0022 before installing python modules
UMASK=$(umask) UMASK=$(umask)
umask 0022 umask 0022
cd $PATH_TO_MISP/app/files/scripts/python-cybox
$SUDO_WWW $PATH_TO_MISP/venv/bin/pip install .
cd $PATH_TO_MISP/app/files/scripts/python-stix cd $PATH_TO_MISP/app/files/scripts/python-stix
$SUDO_WWW $PATH_TO_MISP/venv/bin/pip install . $SUDO_WWW $PATH_TO_MISP/venv/bin/pip install .
@ -257,7 +260,7 @@ installCoreRHEL () {
$SUDO_WWW $PATH_TO_MISP/venv/bin/pip install -U redis $SUDO_WWW $PATH_TO_MISP/venv/bin/pip install -U redis
# lief needs manual compilation # lief needs manual compilation
sudo yum install devtoolset-7 cmake3 cppcheck -y sudo yum install devtoolset-7 cmake3 cppcheck libcxx-devel -y
cd $PATH_TO_MISP/app/files/scripts/lief cd $PATH_TO_MISP/app/files/scripts/lief
$SUDO_WWW mkdir build $SUDO_WWW mkdir build
@ -506,6 +509,7 @@ apacheConfig_RHEL () {
sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/files/scripts/*.py sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/files/scripts/*.py
sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/files/scripts/*/*.py sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/files/scripts/*/*.py
sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/files/scripts/lief/build/api/python/lief.so sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/files/scripts/lief/build/api/python/lief.so
sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/Vendor/pear/crypt_gpg/scripts/crypt-gpg-pinentry
sudo chcon -R -t bin_t $PATH_TO_MISP/venv/bin/* sudo chcon -R -t bin_t $PATH_TO_MISP/venv/bin/*
find $PATH_TO_MISP/venv -type f -name "*.so*" -or -name "*.so.*" | xargs sudo chcon -t lib_t find $PATH_TO_MISP/venv -type f -name "*.so*" -or -name "*.so.*" | xargs sudo chcon -t lib_t
# Only run these if you want to be able to update MISP from the web interface # Only run these if you want to be able to update MISP from the web interface

View File

@ -483,6 +483,7 @@ apacheConfig_RHEL () {
sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/files/scripts/mispzmq/mispzmq.py sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/files/scripts/mispzmq/mispzmq.py
sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/files/scripts/mispzmq/mispzmqtest.py sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/files/scripts/mispzmq/mispzmqtest.py
sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/files/scripts/lief/build/api/python/lief.so sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/files/scripts/lief/build/api/python/lief.so
sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/Vendor/pear/crypt_gpg/scripts/crypt-gpg-pinentry
sudo chcon -t httpd_sys_rw_content_t /tmp sudo chcon -t httpd_sys_rw_content_t /tmp
sudo chcon -R -t usr_t $PATH_TO_MISP/venv sudo chcon -R -t usr_t $PATH_TO_MISP/venv
sudo chcon -R -t httpd_sys_rw_content_t $PATH_TO_MISP/.git sudo chcon -R -t httpd_sys_rw_content_t $PATH_TO_MISP/.git

View File

@ -1,5 +1,5 @@
# INSTALLATION INSTRUCTIONS # INSTALLATION INSTRUCTIONS
## for Ubuntu 18.04.3-server ## for Ubuntu 18.04.4-server
### -1/ Installer and Manual install instructions ### -1/ Installer and Manual install instructions
@ -181,7 +181,7 @@ installCore () {
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install git+https://github.com/kbandla/pydeep.git $SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install git+https://github.com/kbandla/pydeep.git
# install lief # 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 $SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install lief
# install zmq needed by mispzmq # install zmq needed by mispzmq
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install zmq redis $SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install zmq redis

546
docs/INSTALL.ubuntu2004.md Normal file
View File

@ -0,0 +1,546 @@
# INSTALLATION INSTRUCTIONS
## for Ubuntu 20.04-server
### -1/ Installer and Manual install instructions
Make sure you are reading the parsed version of this Document. When in doubt [click here](https://misp.github.io/MISP/INSTALL.ubuntu1804/).
To install MISP on a fresh Ubuntu 20.04, all you need to do is the following:
```bash
# Please check the installer options first to make the best choice for your install
wget -O /tmp/INSTALL.sh https://raw.githubusercontent.com/MISP/MISP/2.4/INSTALL/INSTALL.sh
bash /tmp/INSTALL.sh
# This will install MISP Core
wget -O /tmp/INSTALL.sh https://raw.githubusercontent.com/MISP/MISP/2.4/INSTALL/INSTALL.sh
bash /tmp/INSTALL.sh -c
```
### 0/ MISP Ubuntu 20.04-server install - status
-------------------------
!!! notice
Installer tested working by [@SteveClement](https://twitter.com/SteveClement) on 20200427
!!! notice
This document also serves as a source for the [INSTALL-misp.sh](https://github.com/MISP/MISP/blob/2.4/INSTALL/INSTALL.sh) script.
Which explains why you will see the use of shell *functions* in various steps.
Henceforth the document will also follow a more logical flow. In the sense that all the dependencies are installed first then config files are generated, etc...
!!! notice
If the next line is `[!generic/core.md!]()` [click here](https://misp.github.io/MISP/INSTALL.ubuntu2004/).
{!generic/core.md!}
### 1/ Minimal Ubuntu install
-------------------------
#### Install a minimal Ubuntu 20.04-server system with the software:
- OpenSSH server
- This guide assumes a user name of 'misp' with sudo working
#### Make sure your system is up2date
```bash
# <snippet-begin 0_apt-upgrade.sh>
aptUpgrade () {
debug "Upgrading system"
checkAptLock
sudo apt-get update
# 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>
```
{!generic/sudo_etckeeper.md!}
{!generic/ethX.md!}
#### install postfix, there will be some questions.
```bash
# <snippet-begin postfix.sh>
sudo apt-get install postfix dialog -qy
# <snippet-end postfix.sh>
```
!!! notice
Postfix Configuration: Satellite system<br />
change the relay server later with:
```bash
sudo postconf -e 'relayhost = example.com'
sudo postfix reload
```
{!generic/globalVariables.md!}
### 2/ Install LAMP & dependencies
------------------------------
Once the system is installed you can perform the following steps.
```bash
# <snippet-begin 0_installCoreDeps.sh>
installCoreDeps () {
debug "Installing core dependencies"
# Install the dependencies: (some might already be installed)
sudo apt-get install curl gcc git gpg-agent make python python3 openssl redis-server sudo vim zip unzip virtualenv libfuzzy-dev sqlite3 moreutils -qy
# Install MariaDB (a MySQL fork/alternative)
sudo apt-get install mariadb-client mariadb-server -qy
# Install Apache2
sudo apt-get install apache2 apache2-doc apache2-utils -qy
# install Mitre's STIX and its dependencies by running the following commands:
sudo apt-get install python3-dev python3-pip libxml2-dev libxslt1-dev zlib1g-dev python-setuptools -qy
sudo apt install expect -qy
}
# <snippet-end 0_installCoreDeps.sh>
# <snippet-begin 0_installDepsPhp74.sh>
# Install Php 7.4 dependencies
installDepsPhp74 () {
debug "Installing PHP 7.4 dependencies"
PHP_ETC_BASE=/etc/php/7.4
PHP_INI=${PHP_ETC_BASE}/apache2/php.ini
sudo apt update
sudo apt install -qy \
libapache2-mod-php \
php php-cli \
php-dev \
php-json php-xml php-mysql php-opcache php-readline php-mbstring \
php-redis php-gnupg \
php-gd
for key in upload_max_filesize post_max_size max_execution_time max_input_time memory_limit
do
sudo sed -i "s/^\($key\).*/\1 = $(eval echo \${$key})/" $PHP_INI
done
}
# <snippet-end 0_installDepsPhp74.sh>
```
### 3/ MISP code
------------
```bash
# <snippet-begin 1_mispCoreInstall.sh>
installCore () {
debug "Installing ${LBLUE}MISP${NC} core"
# Download MISP using git in the /var/www/ directory.
sudo mkdir ${PATH_TO_MISP}
sudo chown $WWW_USER:$WWW_USER ${PATH_TO_MISP}
cd ${PATH_TO_MISP}
$SUDO_WWW git clone https://github.com/MISP/MISP.git ${PATH_TO_MISP}
$SUDO_WWW git submodule update --init --recursive
# Make git ignore filesystem permission differences for submodules
$SUDO_WWW git submodule foreach --recursive git config core.filemode false
# Make git ignore filesystem permission differences
$SUDO_WWW git config core.filemode false
# Create a python3 virtualenv
$SUDO_WWW virtualenv -p python3 ${PATH_TO_MISP}/venv
# make pip happy
sudo mkdir /var/www/.cache/
sudo chown $WWW_USER:$WWW_USER /var/www/.cache
cd ${PATH_TO_MISP}/app/files/scripts
$SUDO_WWW git clone https://github.com/CybOXProject/python-cybox.git
$SUDO_WWW git clone https://github.com/STIXProject/python-stix.git
$SUDO_WWW git clone https://github.com/MAECProject/python-maec.git
# install mixbox to accommodate the new STIX dependencies:
$SUDO_WWW git clone https://github.com/CybOXProject/mixbox.git
cd ${PATH_TO_MISP}/app/files/scripts/mixbox
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install .
cd ${PATH_TO_MISP}/app/files/scripts/python-cybox
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install .
cd ${PATH_TO_MISP}/app/files/scripts/python-stix
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install .
cd $PATH_TO_MISP/app/files/scripts/python-maec
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install .
# FIXME: Remove once stix-fixed
$SUDO_WWW $PATH_TO_MISP/venv/bin/pip install -I antlr4-python3-runtime==4.7.2
# install STIX2.0 library to support STIX 2.0 export:
cd ${PATH_TO_MISP}/cti-python-stix2
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install .
# install PyMISP
cd ${PATH_TO_MISP}/PyMISP
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install .
# install pydeep
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install git+https://github.com/kbandla/pydeep.git
# install lief
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install lief
# install zmq needed by mispzmq
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install zmq redis
# install python-magic
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install python-magic
# install plyara
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install plyara
}
# <snippet-end 1_mispCoreInstall.sh>
```
### 4/ CakePHP
-----------
```bash
# <snippet-begin 1_installCake.sh>
installCake () {
debug "Installing CakePHP"
# Once done, install CakeResque along with its dependencies
# if you intend to use the built in background jobs:
cd ${PATH_TO_MISP}/app
# Make composer cache happy
# /!\ composer on Ubuntu when invoked with sudo -u doesn't set $HOME to /var/www but keeps it /home/misp \!/
sudo mkdir /var/www/.composer ; sudo chown $WWW_USER:$WWW_USER /var/www/.composer
$SUDO_WWW php composer.phar install
# Enable CakeResque with php-redis
sudo phpenmod redis
sudo phpenmod gnupg
# To use the scheduler worker for scheduled tasks, do the following:
$SUDO_WWW cp -fa ${PATH_TO_MISP}/INSTALL/setup/config.php ${PATH_TO_MISP}/app/Plugin/CakeResque/Config/config.php
# If you have multiple MISP instances on the same system, don't forget to have a different Redis per MISP instance for the CakeResque workers
# The default Redis port can be updated in Plugin/CakeResque/Config/config.php
}
# <snippet-end 1_installCake.sh>
```
### 5/ Set the permissions
----------------------
```bash
# <snippet-begin 2_permissions.sh>
# Main function to fix permissions to something sane
permissions () {
debug "Setting permissions"
sudo chown -R ${WWW_USER}:${WWW_USER} ${PATH_TO_MISP}
sudo chmod -R 750 ${PATH_TO_MISP}
sudo chmod -R g+ws ${PATH_TO_MISP}/app/tmp
sudo chmod -R g+ws ${PATH_TO_MISP}/app/files
sudo chmod -R g+ws $PATH_TO_MISP/app/files/scripts/tmp
}
# <snippet-end 2_permissions.sh>
```
### 6/ Create a database and user
-----------------------------
#### Set-up DB, User and import empty MISP DB
```bash
# <snippet-begin 1_prepareDB.sh>
prepareDB () {
if [[ ! -e /var/lib/mysql/misp/users.ibd ]]; then
debug "Setting up database"
# FIXME: If user 'misp' exists, and has a different password, the below WILL fail.
# Add your credentials if needed, if sudo has NOPASS, comment out the relevant lines
if [[ "${PACKER}" == "1" ]]; then
pw="Password1234"
else
pw=${MISP_PASSWORD}
fi
expect -f - <<-EOF
set timeout 10
spawn sudo -k mysql_secure_installation
expect "*?assword*"
send -- "${pw}\r"
expect "Enter current password for root (enter for none):"
send -- "\r"
expect "Set root password?"
send -- "y\r"
expect "New password:"
send -- "${DBPASSWORD_ADMIN}\r"
expect "Re-enter new password:"
send -- "${DBPASSWORD_ADMIN}\r"
expect "Remove anonymous users?"
send -- "y\r"
expect "Disallow root login remotely?"
send -- "y\r"
expect "Remove test database and access to it?"
send -- "y\r"
expect "Reload privilege tables now?"
send -- "y\r"
expect eof
EOF
sudo apt-get purge -y expect ; sudo apt autoremove -qy
fi
sudo mysql -u ${DBUSER_ADMIN} -p${DBPASSWORD_ADMIN} -e "CREATE DATABASE ${DBNAME};"
sudo mysql -u ${DBUSER_ADMIN} -p${DBPASSWORD_ADMIN} -e "CREATE USER '${DBUSER_MISP}'@'localhost' IDENTIFIED BY '${DBPASSWORD_MISP}';"
sudo mysql -u ${DBUSER_ADMIN} -p${DBPASSWORD_ADMIN} -e "GRANT USAGE ON *.* to ${DBUSER_MISP}@localhost;"
sudo mysql -u ${DBUSER_ADMIN} -p${DBPASSWORD_ADMIN} -e "GRANT ALL PRIVILEGES on ${DBNAME}.* to '${DBUSER_MISP}'@'localhost';"
sudo mysql -u ${DBUSER_ADMIN} -p${DBPASSWORD_ADMIN} -e "FLUSH PRIVILEGES;"
# Import the empty MISP database from MYSQL.sql
${SUDO_WWW} cat ${PATH_TO_MISP}/INSTALL/MYSQL.sql | mysql -u ${DBUSER_MISP} -p${DBPASSWORD_MISP} ${DBNAME}
}
# <snippet-end 1_prepareDB.sh>
```
### 7/ Apache configuration
-----------------------
Now configure your Apache webserver with the DocumentRoot ${PATH_TO_MISP}/app/webroot/
#### Apache version 2.4 config:
!!! notice
Be aware that the configuration files for apache 2.4 and up have changed.
The configuration file has to have the .conf extension in the sites-available directory
For more information, visit http://httpd.apache.org/docs/2.4/upgrading.html
```bash
# <snippet-begin 1_apacheConfig.sh>
apacheConfig () {
debug "Generating Apache config, if this hangs, make sure you have enough entropy (install: haveged or wait)"
sudo cp ${PATH_TO_MISP}/INSTALL/apache.24.misp.ssl /etc/apache2/sites-available/misp-ssl.conf
if [[ ! -z ${MISP_BASEURL} ]] && [[ "$(echo $MISP_BASEURL|cut -f 1 -d :)" == "http" || "$(echo $MISP_BASEURL|cut -f 1 -d :)" == "https" ]]; then
echo "Potentially replacing misp.local with $MISP_BASEURL in misp-ssl.conf"
fi
# If a valid SSL certificate is not already created for the server,
# create a self-signed certificate:
sudo openssl req -newkey rsa:4096 -days 365 -nodes -x509 \
-subj "/C=${OPENSSL_C}/ST=${OPENSSL_ST}/L=${OPENSSL_L}/O=${OPENSSL_O}/OU=${OPENSSL_OU}/CN=${OPENSSL_CN}/emailAddress=${OPENSSL_EMAILADDRESS}" \
-keyout /etc/ssl/private/misp.local.key -out /etc/ssl/private/misp.local.crt
# Enable modules, settings, and default of SSL in Apache
sudo a2dismod status
sudo a2enmod ssl
sudo a2enmod rewrite
sudo a2enmod headers
sudo a2dissite 000-default
sudo a2ensite default-ssl
# Apply all changes
sudo systemctl restart apache2
# activate new vhost
sudo a2dissite default-ssl
sudo a2ensite misp-ssl
# Restart apache
sudo systemctl restart apache2
}
# <snippet-end 1_apacheConfig.sh>
```
!!! notice
Please find a sample conf file for an SSL enabled conf file in-line below (alternatively use one of the samples provided in /var/www/MISP/INSTALL).<br />
Also remember to verify the SSLCertificateChainFile property in your config file.<br />
This is usually commented out for the self-generated certificate in the sample configurations, such as the one pasted below.<br />
Otherwise, copy the SSLCertificateFile, SSLCertificateKeyFile, and SSLCertificateChainFile to /etc/ssl/private/. (Modify path and config to fit your environment)
```
============================================= Begin sample working SSL config for MISP
<VirtualHost <IP, FQDN, or *>:80>
ServerName <your.FQDN.here>
Redirect permanent / https://<your.FQDN.here>
LogLevel warn
ErrorLog /var/log/apache2/misp.local_error.log
CustomLog /var/log/apache2/misp.local_access.log combined
ServerSignature Off
</VirtualHost>
<VirtualHost <IP, FQDN, or *>:443>
ServerAdmin admin@<your.FQDN.here>
ServerName <your.FQDN.here>
DocumentRoot /var/www/MISP/app/webroot
<Directory /var/www/MISP/app/webroot>
Options -Indexes
AllowOverride all
Order allow,deny
allow from all
</Directory>
SSLEngine On
SSLCertificateFile /etc/ssl/private/misp.local.crt
SSLCertificateKeyFile /etc/ssl/private/misp.local.key
# SSLCertificateChainFile /etc/ssl/private/misp-chain.crt
LogLevel warn
ErrorLog /var/log/apache2/misp.local_error.log
CustomLog /var/log/apache2/misp.local_access.log combined
ServerSignature Off
</VirtualHost>
============================================= End sample working SSL config for MISP
```
### 8/ Log rotation
---------------
```bash
# <snippet-begin 2_logRotation.sh>
logRotation () {
# MISP saves the stdout and stderr of its workers in ${PATH_TO_MISP}/app/tmp/logs
# To rotate these logs install the supplied logrotate script:
sudo cp ${PATH_TO_MISP}/INSTALL/misp.logrotate /etc/logrotate.d/misp
sudo chmod 0640 /etc/logrotate.d/misp
}
# <snippet-end 2_logRotation.sh>
```
### 9/ MISP configuration
---------------------
```bash
# <snippet-begin 2_configMISP.sh>
configMISP () {
debug "Generating ${LBLUE}MISP${NC} config files"
# There are 4 sample configuration files in ${PATH_TO_MISP}/app/Config that need to be copied
$SUDO_WWW cp -a ${PATH_TO_MISP}/app/Config/bootstrap.default.php ${PATH_TO_MISP}/app/Config/bootstrap.php
$SUDO_WWW cp -a ${PATH_TO_MISP}/app/Config/database.default.php ${PATH_TO_MISP}/app/Config/database.php
$SUDO_WWW cp -a ${PATH_TO_MISP}/app/Config/core.default.php ${PATH_TO_MISP}/app/Config/core.php
$SUDO_WWW cp -a ${PATH_TO_MISP}/app/Config/config.default.php ${PATH_TO_MISP}/app/Config/config.php
echo "<?php
class DATABASE_CONFIG {
public \$default = array(
'datasource' => 'Database/Mysql',
//'datasource' => 'Database/Postgres',
'persistent' => false,
'host' => '$DBHOST',
'login' => '$DBUSER_MISP',
'port' => 3306, // MySQL & MariaDB
//'port' => 5432, // PostgreSQL
'password' => '$DBPASSWORD_MISP',
'database' => '$DBNAME',
'prefix' => '',
'encoding' => 'utf8',
);
}" | $SUDO_WWW tee $PATH_TO_MISP/app/Config/database.php
# Important! Change the salt key in ${PATH_TO_MISP}/app/Config/config.php
# The salt key must be a string at least 32 bytes long.
# The admin user account will be generated on the first login, make sure that the salt is changed before you create that user
# If you forget to do this step, and you are still dealing with a fresh installation, just alter the salt,
# delete the user from mysql and log in again using the default admin credentials (admin@admin.test / admin)
# and make sure the file permissions are still OK
sudo chown -R $WWW_USER:$WWW_USER ${PATH_TO_MISP}/app/Config
sudo chmod -R 750 ${PATH_TO_MISP}/app/Config
}
# <snippet-end 2_configMISP.sh>
```
{!generic/gnupg.md!}
!!! notice
If entropy is not high enough, you can install havegd and then start the service
```bash
sudo apt install haveged -qy
sudo service haveged start
```
```bash
# <snippet-begin 2_backgroundWorkers.sh>
backgroundWorkers () {
debug "Setting up background workers"
# To make the background workers start on boot
sudo chmod +x $PATH_TO_MISP/app/Console/worker/start.sh
if [ ! -e /etc/rc.local ]
then
echo '#!/bin/sh -e' | sudo tee -a /etc/rc.local
echo 'exit 0' | sudo tee -a /etc/rc.local
sudo chmod u+x /etc/rc.local
fi
echo "[Unit]
Description=MISP background workers
After=network.target
[Service]
Type=forking
User=${WWW_USER}
Group=${WWW_USER}
ExecStart=${PATH_TO_MISP}/app/Console/worker/start.sh
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target" | sudo tee /etc/systemd/system/misp-workers.service
sudo systemctl daemon-reload
sudo systemctl enable --now misp-workers
# Add the following lines before the last line (exit 0). Make sure that you replace www-data with your apache user:
sudo sed -i -e '$i \echo never > /sys/kernel/mm/transparent_hugepage/enabled\n' /etc/rc.local
sudo sed -i -e '$i \echo 1024 > /proc/sys/net/core/somaxconn\n' /etc/rc.local
sudo sed -i -e '$i \sysctl vm.overcommit_memory=1\n' /etc/rc.local
}
# <snippet-end 2_backgroundWorkers.sh>
```
```bash
echo "Admin (root) DB Password: $DBPASSWORD_ADMIN"
echo "User (misp) DB Password: $DBPASSWORD_MISP"
```
{!generic/MISP_CAKE_init.md!}
{!generic/misp-modules-debian.md!}
{!generic/INSTALL.done.md!}
{!generic/recommended.actions.md!}
### Optional features
-----------------
#### MISP has a new pub/sub feature, using ZeroMQ. To enable it, simply run the following command
```bash
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install pyzmq
```
#### MISP has a feature for publishing events to Kafka. To enable it, simply run the following commands
```bash
# <snippet-begin 4_kafka.sh>
installKafka () {
sudo apt-get install librdkafka-dev php-dev -y
sudo pecl channel-update pecl.php.net
sudo pecl install rdkafka
echo "extension=rdkafka.so" | sudo tee ${PHP_ETC_BASE}/mods-available/rdkafka.ini
sudo phpenmod rdkafka
sudo service apache2 restart
}
# <snippet-end 4_kafka.sh>
```
{!generic/misp-dashboard-debian.md!}
{!generic/viper-debian.md!}
{!generic/ssdeep-debian.md!}
{!generic/mail_to_misp-debian.md!}
{!generic/hardening.md!}
# INSTALL.sh
!!! notice
The following section is an administrative section that is used by the "[INSTALL.sh](https://raw.githubusercontent.com/MISP/MISP/2.4/INSTALL/INSTALL.sh)" script.
Please ignore.
{!generic/supportFunctions.md!}

View File

@ -65,6 +65,7 @@ coreCAKE () {
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Plugin.Sightings_policy" 0 $SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Plugin.Sightings_policy" 0
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Plugin.Sightings_anonymise" false $SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Plugin.Sightings_anonymise" false
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Plugin.Sightings_range" 365 $SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Plugin.Sightings_range" 365
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Plugin.Sightings_sighting_db_enable" false
# Plugin CustomAuth tuneable # Plugin CustomAuth tuneable
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Plugin.CustomAuth_disable_logout" false $SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Plugin.CustomAuth_disable_logout" false
@ -107,6 +108,7 @@ coreCAKE () {
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.block_event_alert_tag" "no-alerts=\"true\"" $SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.block_event_alert_tag" "no-alerts=\"true\""
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.block_old_event_alert" false $SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.block_old_event_alert" false
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.block_old_event_alert_age" "" $SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.block_old_event_alert_age" ""
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.block_old_event_alert_by_date" ""
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.incoming_tags_disabled_by_default" false $SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.incoming_tags_disabled_by_default" false
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.maintenance_message" "Great things are happening! MISP is undergoing maintenance, but will return shortly. You can contact the administration at \$email." $SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.maintenance_message" "Great things are happening! MISP is undergoing maintenance, but will return shortly. You can contact the administration at \$email."
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.footermidleft" "This is an initial install" $SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.footermidleft" "This is an initial install"
@ -124,6 +126,10 @@ coreCAKE () {
# Force defaults to make MISP Server Settings less GREEN # Force defaults to make MISP Server Settings less GREEN
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Security.password_policy_length" 12 $SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Security.password_policy_length" 12
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Security.password_policy_complexity" '/^((?=.*\d)|(?=.*\W+))(?![\n])(?=.*[A-Z])(?=.*[a-z]).*$|.{16,}/' $SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Security.password_policy_complexity" '/^((?=.*\d)|(?=.*\W+))(?![\n])(?=.*[A-Z])(?=.*[a-z]).*$|.{16,}/'
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Security.self_registration_message" "If you would like to send us a registration request, please fill out the form below. Make sure you fill out as much information as possible in order to ease the task of the administrators."
# It is possible to updateMISP too, only here for reference how to to that on the CLI.
## $SUDO_WWW $RUN_PHP -- $CAKE Admin updateMISP
# Set MISP Live # Set MISP Live
$SUDO_WWW $RUN_PHP -- $CAKE Live $MISP_LIVE $SUDO_WWW $RUN_PHP -- $CAKE Live $MISP_LIVE

View File

@ -25,7 +25,7 @@ mail2misp () {
sudo ldconfig sudo ldconfig
cd ../../mail_to_misp cd ../../mail_to_misp
$SUDO_CMD virtualenv -p python3 venv $SUDO_CMD virtualenv -p python3 venv
$SUDO_CMD ./venv/bin/pip install https://github.com/lief-project/packages/raw/lief-master-latest/pylief-0.9.0.dev.zip $SUDO_CMD ./venv/bin/pip install lief
$SUDO_CMD ./venv/bin/pip install -r requirements.txt $SUDO_CMD ./venv/bin/pip install -r requirements.txt
$SUDO_CMD cp mail_to_misp_config.py-example mail_to_misp_config.py $SUDO_CMD cp mail_to_misp_config.py-example mail_to_misp_config.py
##$SUDO cp mail_to_misp_config.py-example mail_to_misp_config.py ##$SUDO cp mail_to_misp_config.py-example mail_to_misp_config.py

View File

@ -21,8 +21,8 @@ mispmodulesRHEL () {
[Service] [Service]
Type=simple Type=simple
User=apache User=$WWW_USER
Group=apache Group=$WWW_USER
WorkingDirectory=/usr/local/src/misp-modules WorkingDirectory=/usr/local/src/misp-modules
Environment="PATH=/var/www/MISP/venv/bin" Environment="PATH=/var/www/MISP/venv/bin"
ExecStart=\"${PATH_TO_MISP}/venv/bin/misp-modules -l 127.0.0.1 -s\" ExecStart=\"${PATH_TO_MISP}/venv/bin/misp-modules -l 127.0.0.1 -s\"

View File

@ -217,18 +217,19 @@ EOF
checkInstaller () { checkInstaller () {
# Workaround: shasum is not available on RHEL, only checking sha512 # Workaround: shasum is not available on RHEL, only checking sha512
if [[ $FLAVOUR == "rhel" ]] || [[ $FLAVOUR == "centos" ]]; then if [[ $FLAVOUR == "rhel" ]] || [[ $FLAVOUR == "centos" ]]; then
INSTsum=$(sha512sum ${0} | cut -f1 -d\ ) INSTsum=$(sha512sum ${0} | cut -f1 -d\ )
/usr/bin/wget --no-cache -q -O /tmp/INSTALL.sh.sha512 https://raw.githubusercontent.com/MISP/MISP/2.4/INSTALL/INSTALL.sh.sha512 /usr/bin/wget --no-cache -q -O /tmp/INSTALL.sh.sha512 https://raw.githubusercontent.com/MISP/MISP/2.4/INSTALL/INSTALL.sh.sha512
chsum=$(cat /tmp/INSTALL.sh.sha512) chsum=$(cat /tmp/INSTALL.sh.sha512)
if [[ "${chsum}" == "${INSTsum}" ]]; then if [[ "${chsum}" == "${INSTsum}" ]]; then
echo "SHA512 matches" echo "SHA512 matches"
else else
echo "SHA512: ${chsum} does not match the installer sum of: ${INSTsum}" echo "SHA512: ${chsum} does not match the installer sum of: ${INSTsum}"
# exit 1 # uncomment when/if PR is merged # exit 1 # uncomment when/if PR is merged
fi fi
else else
# TODO: Implement $FLAVOUR checks and install depending on the platform we are on # TODO: Implement $FLAVOUR checks and install depending on the platform we are on
if [[ $(which shasum > /dev/null 2>&1 ; echo $?) != 0 ]]; then if [[ $(which shasum > /dev/null 2>&1 ; echo $?) != 0 ]]; then
sudo apt update
sudo apt install libdigest-sha-perl -qyy sudo apt install libdigest-sha-perl -qyy
fi fi
# SHAsums to be computed, not the -- notatiation is for ease of use with rhash # SHAsums to be computed, not the -- notatiation is for ease of use with rhash
@ -541,12 +542,20 @@ setBaseURL () {
MISP_BASEURL="https://misp.local" MISP_BASEURL="https://misp.local"
# Webserver configuration # Webserver configuration
FQDN='misp.local' FQDN='misp.local'
else elif [[ "$(checkManufacturer)" == "innotek GmbH" ]]; then
MISP_BASEURL='https://localhost:8443' MISP_BASEURL='https://localhost:8443'
IP=$(ip addr show | awk '$1 == "inet" {gsub(/\/.*$/, "", $2); print $2}' |grep -v "127.0.0.1" |tail -1) IP=$(ip addr show | awk '$1 == "inet" {gsub(/\/.*$/, "", $2); print $2}' |grep -v "127.0.0.1" |tail -1)
sudo iptables -t nat -A OUTPUT -p tcp --dport 8443 -j DNAT --to ${IP}:443 sudo iptables -t nat -A OUTPUT -p tcp --dport 8443 -j DNAT --to ${IP}:443
# Webserver configuration # Webserver configuration
FQDN='localhost.localdomain' FQDN='localhost.localdomain'
elif [[ "$(checkManufacturer)" == "VMware, Inc." ]]; then
MISP_BASEURL='""'
# Webserver configuration
FQDN='misp.local'
else
MISP_BASEURL='""'
# Webserver configuration
FQDN='misp.local'
fi fi
} }

View File

@ -29,7 +29,7 @@ viper () {
# TODO: Check for current user install permissions # TODO: Check for current user install permissions
$SUDO_CMD git submodule update --init --recursive $SUDO_CMD git submodule update --init --recursive
echo "pip install deps" echo "pip install deps"
$SUDO_CMD ./venv/bin/pip install pefile olefile jbxapi Crypto pypdns pypssl r2pipe pdftools virustotal-api SQLAlchemy PrettyTable python-magic scrapy https://github.com/lief-project/packages/raw/lief-master-latest/pylief-0.9.0.dev.zip $SUDO_CMD ./venv/bin/pip install pefile olefile jbxapi Crypto pypdns pypssl r2pipe pdftools virustotal-api SQLAlchemy PrettyTable python-magic scrapy lief
$SUDO_CMD ./venv/bin/pip install . $SUDO_CMD ./venv/bin/pip install .
echo 'update-modules' |/usr/local/src/viper/venv/bin/viper echo 'update-modules' |/usr/local/src/viper/venv/bin/viper
cd /usr/local/src/viper-web cd /usr/local/src/viper-web

View File

@ -196,7 +196,7 @@ $SUDO_WWW make -j3
sudo make install sudo make install
cd api/python/lief_pybind11-prefix/src/lief_pybind11 cd api/python/lief_pybind11-prefix/src/lief_pybind11
$SUDO_WWW $PATH_TO_MISP/venv/bin/python setup.py install $SUDO_WWW $PATH_TO_MISP/venv/bin/python setup.py install
$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 $SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install lief
# install magic, pydeep # install magic, pydeep
$SUDO_WWW $PATH_TO_MISP/venv/bin/pip install -U python-magic $SUDO_WWW $PATH_TO_MISP/venv/bin/pip install -U python-magic

View File

@ -187,8 +187,8 @@ $SUDO_WWW scl enable devtoolset-7 'bash -c "cmake3 \
$SUDO_WWW make -j3 $SUDO_WWW make -j3
sudo make install sudo make install
cd api/python/lief_pybind11-prefix/src/lief_pybind11 cd api/python/lief_pybind11-prefix/src/lief_pybind11
$SUDO_WWW $PATH_TO_MISP/venv/bin/python setup.py install $SUDO_WWW ${PATH_TO_MISP}/venv/bin/python setup.py install
$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 $SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install lief
# install magic, pydeep # install magic, pydeep
$SUDO_WWW $PATH_TO_MISP/venv/bin/pip install -U python-magic git+https://github.com/kbandla/pydeep.git $SUDO_WWW $PATH_TO_MISP/venv/bin/pip install -U python-magic git+https://github.com/kbandla/pydeep.git
@ -394,6 +394,7 @@ sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/Console/worker/*.sh
sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/files/scripts/*.py sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/files/scripts/*.py
sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/files/scripts/*/*.py sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/files/scripts/*/*.py
sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/files/scripts/lief/build/api/python/lief.so sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/files/scripts/lief/build/api/python/lief.so
sudo chcon -t httpd_sys_script_exec_t $PATH_TO_MISP/app/Vendor/pear/crypt_gpg/scripts/crypt-gpg-pinentry
# Only run these if you want to be able to update MISP from the web interface # Only run these if you want to be able to update MISP from the web interface
sudo chcon -R -t httpd_sys_rw_content_t $PATH_TO_MISP/.git sudo chcon -R -t httpd_sys_rw_content_t $PATH_TO_MISP/.git
sudo chcon -R -t httpd_sys_rw_content_t $PATH_TO_MISP/app/tmp sudo chcon -R -t httpd_sys_rw_content_t $PATH_TO_MISP/app/tmp

View File

@ -172,7 +172,7 @@ $SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install .
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install git+https://github.com/kbandla/pydeep.git $SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install git+https://github.com/kbandla/pydeep.git
# install lief # 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 $SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install lief
# install zmq needed by mispzmq # install zmq needed by mispzmq
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install zmq redis $SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install zmq redis

View File

@ -197,7 +197,7 @@ $SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install .
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install git+https://github.com/kbandla/pydeep.git $SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install git+https://github.com/kbandla/pydeep.git
# install lief # 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 $SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install lief
# install zmq needed by mispzmq # install zmq needed by mispzmq
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install zmq redis $SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install zmq redis

View File

@ -629,7 +629,7 @@ function installMISPonTsurugi() {
sudo ldconfig sudo ldconfig
cd ../../mail_to_misp cd ../../mail_to_misp
$SUDO_CMD virtualenv -p python3 venv $SUDO_CMD virtualenv -p python3 venv
$SUDO_CMD ./venv/bin/pip install https://github.com/lief-project/packages/raw/lief-master-latest/pylief-0.9.0.dev.zip $SUDO_CMD ./venv/bin/pip install lief
$SUDO_CMD ./venv/bin/pip install -r requirements.txt $SUDO_CMD ./venv/bin/pip install -r requirements.txt
$SUDO_CMD cp mail_to_misp_config.py-example mail_to_misp_config.py $SUDO_CMD cp mail_to_misp_config.py-example mail_to_misp_config.py
##$SUDO cp mail_to_misp_config.py-example mail_to_misp_config.py ##$SUDO cp mail_to_misp_config.py-example mail_to_misp_config.py

View File

@ -14,7 +14,7 @@ edit_uri: ""
#dev_addr: "192.168.10.34:8000" #dev_addr: "192.168.10.34:8000"
# Copyright # Copyright
copyright: "Copyright &copy; 2019 MISP Project" copyright: "Copyright &copy; 2020 MISP Project"
# Options # Options
extra: extra:
@ -69,6 +69,7 @@ nav:
- Home: 'index.md' - Home: 'index.md'
- Install Guides: - Install Guides:
- 'Ubuntu 18.04': 'INSTALL.ubuntu1804.md' - 'Ubuntu 18.04': 'INSTALL.ubuntu1804.md'
- 'Ubuntu 20.04': 'INSTALL.ubuntu2004.md'
- 'Kali Linux': 'INSTALL.kali.md' - 'Kali Linux': 'INSTALL.kali.md'
- 'RHEL7/CentOS7': 'INSTALL.rhel7.md' - 'RHEL7/CentOS7': 'INSTALL.rhel7.md'
- 'RHEL8/CentOS8': 'INSTALL.rhel8.md' - 'RHEL8/CentOS8': 'INSTALL.rhel8.md'
@ -76,10 +77,10 @@ nav:
- 'Warning': 'xINSTALL.md' - 'Warning': 'xINSTALL.md'
- 'Centos 6': 'xINSTALL.centos6.md' - 'Centos 6': 'xINSTALL.centos6.md'
- 'Debian 10': 'xINSTALL.debian10.md' - 'Debian 10': 'xINSTALL.debian10.md'
- 'Debian 9.9': 'xINSTALL.debian9.md' - 'Debian 9': 'xINSTALL.debian9.md'
- 'Ubuntu 18.04 \w webmin': 'xINSTALL.ubuntu1804.with.webmin.md' - 'Ubuntu 18.04 \w webmin': 'xINSTALL.ubuntu1804.with.webmin.md'
- 'Tsurugi Linux': 'xINSTALL.tsurugi.md' - 'Tsurugi Linux': 'xINSTALL.tsurugi.md'
- 'OpenBSD 6.5': 'xINSTALL.OpenBSD.md' - 'OpenBSD 6.6': 'xINSTALL.OpenBSD.md'
- Config Guides: - Config Guides:
- 'Elastic Search Logging': 'CONFIG.elasticsearch-logging.md' - 'Elastic Search Logging': 'CONFIG.elasticsearch-logging.md'
- 'Amazon S3 attachments': 'CONFIG.s3-attachments.md' - 'Amazon S3 attachments': 'CONFIG.s3-attachments.md'

View File

@ -1 +1,3 @@
PATH_TO_MISP=/var/www/MISP PATH_TO_MISP=/var/www/MISP
ENABLE_WARNINGLISTS="false"
ENABLE_NOTICELISTS="false"

View File

@ -108,4 +108,23 @@ curl --header "Authorization: $AuthKey" --header "Accept: application/json" --he
echo "Updating objectTemplates" echo "Updating objectTemplates"
curl --header "Authorization: $AuthKey" --header "Accept: application/json" --header "Content-Type: application/json" -o /dev/null -s -X POST ${baseurl}/objectTemplates/update curl --header "Authorization: $AuthKey" --header "Accept: application/json" --header "Content-Type: application/json" -o /dev/null -s -X POST ${baseurl}/objectTemplates/update
echo "Updating decayingModel"
curl --header "Authorization: $AuthKey" --header "Accept: application/json" --header "Content-Type: application/json" -o /dev/null -s -X POST ${baseurl}/decayingModel/update
if [ "$ENABLE_WARNINGLISTS" = "true" ]; then
echo "Enabling warninglists"
wls=$(curl --header "Authorization: $AuthKey" --header "Accept: application/json" --header "Content-Type: application/json" -s -X POST ${baseurl}/warninglists/index | jq -r '.Warninglists[] | select(.Warninglist.enabled == false) | .Warninglist.id' 2>/dev/null)
for wl in $wls; do
curl --header "Authorization: $AuthKey" --header "Accept: application/json" --header "Content-Type: application/json" -d "{\"id\":$wl}" -o /dev/null -s -X POST ${baseurl}/warninglists/toggleEnable
done
fi
if [ "$ENABLE_NOTICELISTS" = "true" ]; then
echo "Enabling noticelists"
nls=$(curl --header "Authorization: $AuthKey" --header "Accept: application/json" --header "Content-Type: application/json" -s -X POST ${baseurl}/noticelists/index | jq -r '.[] | select(.Noticelist.enabled == false) | .Noticelist.id' 2>/dev/null)
for nl in $nls; do
curl --header "Authorization: $AuthKey" --header "Accept: application/json" --header "Content-Type: application/json" -d "{\"Noticelist\":{\"data\":$nl}}" -o /dev/null -s -X POST ${baseurl}/noticelists/toggleEnable
done
fi
echo 'MISP Wipe Complete!!!' echo 'MISP Wipe Complete!!!'

View File

@ -6,10 +6,12 @@ TRUNCATE `correlations`;
TRUNCATE `events`; TRUNCATE `events`;
TRUNCATE `event_blacklists`; TRUNCATE `event_blacklists`;
TRUNCATE `event_delegations`; TRUNCATE `event_delegations`;
TRUNCATE `event_graph`;
TRUNCATE `event_tags`; TRUNCATE `event_tags`;
TRUNCATE `favourite_tags`; TRUNCATE `favourite_tags`;
TRUNCATE `jobs`; TRUNCATE `jobs`;
TRUNCATE `logs`; TRUNCATE `logs`;
TRUNCATE `notification_logs`;
TRUNCATE `objects`; TRUNCATE `objects`;
TRUNCATE `object_references`; TRUNCATE `object_references`;
TRUNCATE `object_relationships`; TRUNCATE `object_relationships`;
@ -17,6 +19,7 @@ TRUNCATE `object_templates`;
TRUNCATE `object_template_elements`; TRUNCATE `object_template_elements`;
TRUNCATE `org_blacklists`; TRUNCATE `org_blacklists`;
TRUNCATE `posts`; TRUNCATE `posts`;
TRUNCATE `rest_client_histories`;
TRUNCATE `servers`; TRUNCATE `servers`;
TRUNCATE `shadow_attributes`; TRUNCATE `shadow_attributes`;
TRUNCATE `shadow_attribute_correlations`; TRUNCATE `shadow_attribute_correlations`;
@ -24,6 +27,8 @@ TRUNCATE `sharing_groups`;
TRUNCATE `sharing_group_orgs`; TRUNCATE `sharing_group_orgs`;
TRUNCATE `sharing_group_servers`; TRUNCATE `sharing_group_servers`;
TRUNCATE `sightings`; TRUNCATE `sightings`;
TRUNCATE `tag_collections`;
TRUNCATE `tag_collection_tags`;
TRUNCATE `tags`; TRUNCATE `tags`;
TRUNCATE `threads`; TRUNCATE `threads`;
TRUNCATE `bruteforces`; TRUNCATE `bruteforces`;
@ -33,6 +38,7 @@ TRUNCATE `whitelist`;
TRUNCATE `event_locks`; TRUNCATE `event_locks`;
TRUNCATE `fuzzy_correlate_ssdeep`; TRUNCATE `fuzzy_correlate_ssdeep`;
TRUNCATE `tasks`; TRUNCATE `tasks`;
TRUNCATE `user_settings`;
-- Clear tables that can be re-populated -- Clear tables that can be re-populated
TRUNCATE `taxonomies`; TRUNCATE `taxonomies`;
@ -47,6 +53,8 @@ TRUNCATE `galaxy_elements`;
TRUNCATE `galaxy_reference`; TRUNCATE `galaxy_reference`;
TRUNCATE `noticelists`; TRUNCATE `noticelists`;
TRUNCATE `noticelist_entries`; TRUNCATE `noticelist_entries`;
TRUNCATE `decaying_models`;
TRUNCATE `decaying_model_mappings`;
-- Clear tables that have defaults -- Clear tables that have defaults
TRUNCATE `feeds`; TRUNCATE `feeds`;