mirror of https://github.com/MISP/MISP
Merge remote-tracking branch 'origin/2.4' into eventTimeline-sightings
commit
8525dda7f8
|
@ -16,6 +16,7 @@
|
|||
# 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
|
||||
# 20190208: Kali Linux tested and working. -- sCl
|
||||
#
|
||||
|
@ -376,18 +377,19 @@ EOF
|
|||
checkInstaller () {
|
||||
# Workaround: shasum is not available on RHEL, only checking sha512
|
||||
if [[ $FLAVOUR == "rhel" ]] || [[ $FLAVOUR == "centos" ]]; then
|
||||
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
|
||||
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
|
||||
chsum=$(cat /tmp/INSTALL.sh.sha512)
|
||||
if [[ "${chsum}" == "${INSTsum}" ]]; then
|
||||
echo "SHA512 matches"
|
||||
else
|
||||
echo "SHA512: ${chsum} does not match the installer sum of: ${INSTsum}"
|
||||
# exit 1 # uncomment when/if PR is merged
|
||||
fi
|
||||
if [[ "${chsum}" == "${INSTsum}" ]]; then
|
||||
echo "SHA512 matches"
|
||||
else
|
||||
echo "SHA512: ${chsum} does not match the installer sum of: ${INSTsum}"
|
||||
# exit 1 # uncomment when/if PR is merged
|
||||
fi
|
||||
else
|
||||
# TODO: Implement $FLAVOUR checks and install depending on the platform we are on
|
||||
if [[ $(which shasum > /dev/null 2>&1 ; echo $?) != 0 ]]; then
|
||||
sudo apt update
|
||||
sudo apt install libdigest-sha-perl -qyy
|
||||
fi
|
||||
# SHAsums to be computed, not the -- notatiation is for ease of use with rhash
|
||||
|
@ -700,12 +702,20 @@ setBaseURL () {
|
|||
MISP_BASEURL="https://misp.local"
|
||||
# Webserver configuration
|
||||
FQDN='misp.local'
|
||||
else
|
||||
elif [[ "$(checkManufacturer)" == "innotek GmbH" ]]; then
|
||||
MISP_BASEURL='https://localhost:8443'
|
||||
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
|
||||
# Webserver configuration
|
||||
FQDN='localhost.localdomain'
|
||||
elif [[ "$(checkManufacturer)" == "VMware, Inc." ]]; then
|
||||
MISP_BASEURL='""'
|
||||
# Webserver configuration
|
||||
FQDN='misp.local'
|
||||
else
|
||||
MISP_BASEURL='""'
|
||||
# Webserver configuration
|
||||
FQDN='misp.local'
|
||||
fi
|
||||
}
|
||||
|
||||
|
@ -1136,6 +1146,26 @@ installCoreDeps () {
|
|||
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
|
||||
installDepsPhp73 () {
|
||||
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
|
||||
|
||||
# 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
|
||||
$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_anonymise" false
|
||||
$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
|
||||
$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_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_by_date" ""
|
||||
$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.footermidleft" "This is an initial install"
|
||||
|
@ -1526,6 +1558,10 @@ coreCAKE () {
|
|||
# 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_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
|
||||
$SUDO_WWW $RUN_PHP -- $CAKE Live $MISP_LIVE
|
||||
|
@ -1798,7 +1834,7 @@ mail2misp () {
|
|||
sudo ldconfig
|
||||
cd ../../mail_to_misp
|
||||
$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 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
|
||||
$SUDO_CMD git submodule update --init --recursive
|
||||
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 .
|
||||
echo 'update-modules' |/usr/local/src/viper/venv/bin/viper
|
||||
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 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
|
||||
UMASK=$(umask)
|
||||
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
|
||||
$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
|
||||
|
||||
# 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
|
||||
$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/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/*
|
||||
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
|
||||
|
@ -2391,8 +2431,8 @@ mispmodulesRHEL () {
|
|||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=apache
|
||||
Group=apache
|
||||
User=$WWW_USER
|
||||
Group=$WWW_USER
|
||||
WorkingDirectory=/usr/local/src/misp-modules
|
||||
Environment="PATH=/var/www/MISP/venv/bin"
|
||||
ExecStart=\"${PATH_TO_MISP}/venv/bin/misp-modules -l 127.0.0.1 -s\"
|
||||
|
@ -2487,7 +2527,7 @@ generateInstaller () {
|
|||
cp ../INSTALL.tpl.sh .
|
||||
|
||||
# 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}
|
||||
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_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_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_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
|
||||
|
@ -2619,13 +2660,16 @@ installSupported () {
|
|||
|
||||
if [[ "$1" =~ ^PHP= ]]; then
|
||||
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')
|
||||
[[ -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')
|
||||
[[ -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')
|
||||
[[ -n $CORE ]] || [[ -n $ALL ]] && installDepsPhp70
|
||||
fi
|
||||
|
@ -2723,7 +2767,7 @@ installSupported () {
|
|||
theEnd
|
||||
}
|
||||
|
||||
# Main Kalin Install function
|
||||
# Main Kali Install function
|
||||
installMISPonKali () {
|
||||
# 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
|
||||
|
@ -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
|
||||
|
||||
# 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
|
||||
$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-buster
|
||||
x86_64-ubuntu-bionic
|
||||
x86_64-ubuntu-focal
|
||||
x86_64-kali-2019.1
|
||||
x86_64-kali-2019.2
|
||||
x86_64-kali-2019.3
|
||||
|
@ -3152,6 +3197,7 @@ armv7l-debian-jessie
|
|||
armv7l-debian-stretch
|
||||
armv7l-debian-buster
|
||||
armv7l-ubuntu-bionic
|
||||
armv7l-ubuntu-focal
|
||||
"
|
||||
|
||||
# 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"
|
||||
installSupported && exit || exit
|
||||
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
|
||||
echo "Install on Ubuntu 18.10 partially supported, bye."
|
||||
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
|
||||
installSupported && exit || exit
|
||||
fi
|
||||
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"
|
||||
installSupported && exit || exit
|
||||
exit 1
|
||||
|
|
|
@ -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/
|
||||
;
|
||||
; 129017 11:27.22 2020-03-28 INSTALL.sh
|
||||
INSTALL.sh D13A40A737C9FC7BCB6085F7557EAE47E48AF57A FBD4920A02D7811FF6280306FE1ED0CF6ADDD3707B2E0F9D1FF58F808CC92784 66A1518CCBBAC090C84748D59BE0D45CF9EB4882AF3B65CFA0E0F1CD76CE82D928A5EB16B4927A297C29BBE964B104F9 ED28FA2445A350193E6089E44E1451E34DE3C4A49643B8A8F2690488067AD05E806FA5A169044525F4686D3E5171F6A8EE65415EF5BB3DE6884BA93F9EE7BA05
|
||||
; 131010 15:20.13 2020-04-30 INSTALL.sh
|
||||
INSTALL.sh 660E0D51D88B57CE5BE725117482207E39371038 DCF69118CD37B43C308FD25E6BADAF03549BAF0FFA2AC11A1E919005D700F4AC 74E03A8054AF2E4BCB90426A3B813F57BF032734AB7B4E9D4F6F96961D7371FB051180BEE8357642EB9CC58603C13DA3 C4D1D02980808A92E8E11C72A49AA354DDEFA71C6E85FAC739645CEDEB4B36415243F7FB4B8BC75B6AE7B5D9660E0F88A35E884EBD51EA107128B0D7FB20C946
|
||||
|
|
|
@ -1 +1 @@
|
|||
d13a40a737c9fc7bcb6085f7557eae47e48af57a INSTALL.sh
|
||||
660e0d51d88b57ce5be725117482207e39371038 INSTALL.sh
|
||||
|
|
|
@ -1 +1 @@
|
|||
fbd4920a02d7811ff6280306fe1ed0cf6addd3707b2e0f9d1ff58f808cc92784 INSTALL.sh
|
||||
dcf69118cd37b43c308fd25e6badaf03549baf0ffa2ac11a1e919005d700f4ac INSTALL.sh
|
||||
|
|
|
@ -1 +1 @@
|
|||
66a1518ccbbac090c84748d59be0d45cf9eb4882af3b65cfa0e0f1cd76ce82d928a5eb16b4927a297c29bbe964b104f9 INSTALL.sh
|
||||
74e03a8054af2e4bcb90426a3b813f57bf032734ab7b4e9d4f6f96961d7371fb051180bee8357642eb9cc58603c13da3 INSTALL.sh
|
||||
|
|
|
@ -1 +1 @@
|
|||
ed28fa2445a350193e6089e44e1451e34de3c4a49643b8a8f2690488067ad05e806fa5a169044525f4686d3e5171f6a8ee65415ef5bb3de6884ba93f9ee7ba05 INSTALL.sh
|
||||
c4d1d02980808a92e8e11c72a49aa354ddefa71c6e85fac739645cedeb4b36415243f7fb4b8bc75b6ae7b5d9660e0f88a35e884ebd51ea107128b0d7fb20c946 INSTALL.sh
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
# 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
|
||||
# 20190208: Kali Linux tested and working. -- sCl
|
||||
#
|
||||
|
@ -70,6 +71,7 @@
|
|||
## 0_apt-upgrade.sh ##
|
||||
## 0_sudoKeeper.sh ##
|
||||
## 0_installCoreDeps.sh ##
|
||||
## 0_installDepsPhp74.sh ##
|
||||
## 0_installDepsPhp73.sh ##
|
||||
## 0_installDepsPhp72.sh ##
|
||||
## 0_installDepsPhp70.sh ##
|
||||
|
@ -143,7 +145,7 @@ generateInstaller () {
|
|||
cp ../INSTALL.tpl.sh .
|
||||
|
||||
# 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}
|
||||
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_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_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_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
|
||||
|
@ -275,13 +278,16 @@ installSupported () {
|
|||
|
||||
if [[ "$1" =~ ^PHP= ]]; then
|
||||
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')
|
||||
[[ -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')
|
||||
[[ -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')
|
||||
[[ -n $CORE ]] || [[ -n $ALL ]] && installDepsPhp70
|
||||
fi
|
||||
|
@ -379,7 +385,7 @@ installSupported () {
|
|||
theEnd
|
||||
}
|
||||
|
||||
# Main Kalin Install function
|
||||
# Main Kali Install function
|
||||
installMISPonKali () {
|
||||
# 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
|
||||
|
@ -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
|
||||
|
||||
# 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
|
||||
$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-buster
|
||||
x86_64-ubuntu-bionic
|
||||
x86_64-ubuntu-focal
|
||||
x86_64-kali-2019.1
|
||||
x86_64-kali-2019.2
|
||||
x86_64-kali-2019.3
|
||||
|
@ -808,6 +815,7 @@ armv7l-debian-jessie
|
|||
armv7l-debian-stretch
|
||||
armv7l-debian-buster
|
||||
armv7l-ubuntu-bionic
|
||||
armv7l-ubuntu-focal
|
||||
"
|
||||
|
||||
# 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"
|
||||
installSupported && exit || exit
|
||||
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
|
||||
echo "Install on Ubuntu 18.10 partially supported, bye."
|
||||
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
|
||||
installSupported && exit || exit
|
||||
fi
|
||||
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"
|
||||
installSupported && exit || exit
|
||||
exit 1
|
||||
|
|
|
@ -916,7 +916,7 @@ CREATE TABLE IF NOT EXISTS `shadow_attribute_correlations` (
|
|||
-- 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,
|
||||
`sharing_group_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`
|
||||
--
|
||||
|
||||
CREATE TABLE `sharing_group_servers` (
|
||||
CREATE TABLE IF NOT EXISTS `sharing_group_servers` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`sharing_group_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`
|
||||
--
|
||||
|
||||
CREATE TABLE `sharing_groups` (
|
||||
CREATE TABLE IF NOT EXISTS `sharing_groups` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) 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
|
||||
--
|
||||
|
||||
INSERT INTO `admin_settings` (`id`, `setting`, `value`) VALUES
|
||||
INSERT IGNORE INTO `admin_settings` (`id`, `setting`, `value`) VALUES
|
||||
(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),
|
||||
(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'),
|
||||
(2, '/.:.Documents and Settings.All Users./i', '%ALLUSERSPROFILE%\\\\', '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
|
||||
--
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
@ -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
|
||||
--
|
||||
|
||||
INSERT INTO `threat_levels` (`id`, `name`, `description`, `form_description`)
|
||||
INSERT IGNORE INTO `threat_levels` (`id`, `name`, `description`, `form_description`)
|
||||
VALUES
|
||||
(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'),
|
||||
|
@ -1444,13 +1444,13 @@ VALUES
|
|||
-- 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),
|
||||
(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),
|
||||
(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'),
|
||||
(2, 1, 3, 'attribute'),
|
||||
(3, 1, 1, 'text'),
|
||||
|
@ -1497,7 +1497,7 @@ INSERT INTO `template_elements` (`id`, `template_id`, `position`, `element_defin
|
|||
(46, 4, 2, '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),
|
||||
(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),
|
||||
|
@ -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),
|
||||
(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),
|
||||
(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),
|
||||
(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.'),
|
||||
(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'),
|
||||
|
@ -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'),
|
||||
(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'),
|
||||
('58d38326-eda8-443a-9fa8-4e12950d210f', NOW(), 'Acme Finance', 'default example');
|
||||
|
|
|
@ -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:
|
||||
```
|
||||
INSTALL.debian9.txt
|
||||
INSTALL.kali.txt
|
||||
INSTALL.ubuntu1804.txt
|
||||
```
|
||||
|
|
2
PyMISP
2
PyMISP
|
@ -1 +1 @@
|
|||
Subproject commit 5e46724646c0aa779b827678333a21a5e9eb2034
|
||||
Subproject commit 0faa75824f4dbac2b14919bb17e9d0fef79026d7
|
|
@ -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.
|
|
@ -5,6 +5,7 @@ require_once 'AppShell.php';
|
|||
class ServerShell extends AppShell
|
||||
{
|
||||
public $uses = array('Server', 'Task', 'Job', 'User', 'Feed');
|
||||
public $tasks = array('ConfigLoad');
|
||||
|
||||
public function listServers()
|
||||
{
|
||||
|
|
|
@ -57,6 +57,8 @@ class AppController extends Controller
|
|||
public $baseurl = '';
|
||||
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
|
||||
// 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(
|
||||
|
@ -204,7 +206,14 @@ class AppController extends Controller
|
|||
$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
|
||||
if ($this->_isRest() || $this->_isAutomation()) {
|
||||
// disable CSRF for REST access
|
||||
|
@ -354,7 +363,11 @@ class AppController extends Controller
|
|||
}
|
||||
}
|
||||
} 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')) {
|
||||
$this->Session->write('pre_login_requested_url', $this->here);
|
||||
}
|
||||
|
@ -673,6 +686,11 @@ class AppController extends Controller
|
|||
|
||||
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']);
|
||||
if (isset($this->RequestHandler) && ($api || $this->RequestHandler->isXml() || $this->_isJson() || $this->_isCsv())) {
|
||||
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.');
|
||||
}
|
||||
}
|
||||
$this->isRest = true;
|
||||
return true;
|
||||
} else {
|
||||
$this->isRest = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,9 @@ App::uses('AppController', 'Controller');
|
|||
App::uses('Folder', 'Utility');
|
||||
App::uses('File', 'Utility');
|
||||
|
||||
/**
|
||||
* @property Attribute $Attribute
|
||||
*/
|
||||
class AttributesController extends AppController
|
||||
{
|
||||
public $components = array('Security', 'RequestHandler', 'Cidr');
|
||||
|
@ -148,6 +151,12 @@ class AttributesController extends AppController
|
|||
if (!isset($this->request->data['Attribute'])) {
|
||||
$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
|
||||
//
|
||||
|
@ -410,22 +419,19 @@ class AttributesController extends AppController
|
|||
public function add_attachment($eventId = null)
|
||||
{
|
||||
if ($this->request->is('post')) {
|
||||
$hashes = array('md5' => 'malware-sample', 'sha1' => 'filename|sha1', 'sha256' => 'filename|sha256');
|
||||
$this->loadModel('Event');
|
||||
$this->Event->id = $this->request->data['Attribute']['event_id'];
|
||||
$this->Event->recursive = -1;
|
||||
$event = $this->Event->read();
|
||||
$this->Attribute->Event->id = $this->request->data['Attribute']['event_id'];
|
||||
$this->Attribute->Event->recursive = -1;
|
||||
$event = $this->Attribute->Event->read();
|
||||
if (empty($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.'));
|
||||
}
|
||||
$partialFails = array();
|
||||
$fails = array();
|
||||
$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
|
||||
// only keep the last part of the filename, this should prevent directory attacks
|
||||
$filename = basename($value['name']);
|
||||
|
@ -449,11 +455,6 @@ class AttributesController extends AppController
|
|||
$filename,
|
||||
$tmpfile
|
||||
);
|
||||
if ($result) {
|
||||
$success++;
|
||||
} else {
|
||||
$fails[] = $filename;
|
||||
}
|
||||
} else {
|
||||
$result = $this->Attribute->simpleAddMalwareSample(
|
||||
$eventId,
|
||||
|
@ -461,15 +462,16 @@ class AttributesController extends AppController
|
|||
$filename,
|
||||
$tmpfile
|
||||
);
|
||||
if ($result) {
|
||||
$success++;
|
||||
} else {
|
||||
$fails[] = $filename;
|
||||
}
|
||||
}
|
||||
|
||||
if ($result) {
|
||||
$success++;
|
||||
} else {
|
||||
$fails[] = $filename;
|
||||
}
|
||||
|
||||
if (!empty($result)) {
|
||||
foreach ($result['Object'] as $object) {
|
||||
$this->loadModel('MispObject');
|
||||
$object['distribution'] = $this->request->data['Attribute']['distribution'];
|
||||
if (!empty($this->request->data['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) {
|
||||
$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'])) {
|
||||
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.';
|
||||
if (!empty($partialFails)) {
|
||||
$message .= ' Some of the attributes however could not be created.';
|
||||
}
|
||||
$message = __('The attachment(s) have been uploaded.');
|
||||
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($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 {
|
||||
$this->Event->id = $this->request->data['Attribute']['event_id'];
|
||||
$this->Event->saveField('published', 0);
|
||||
$this->Attribute->Event->id = $this->request->data['Attribute']['event_id'];
|
||||
$this->Attribute->Event->saveField('published', 0);
|
||||
}
|
||||
if (empty($success) && !empty($fails)) {
|
||||
$this->Flash->error($message);
|
||||
|
@ -536,57 +535,43 @@ class AttributesController extends AppController
|
|||
// set the event_id in the form
|
||||
$this->request->data['Attribute']['event_id'] = $eventId;
|
||||
}
|
||||
|
||||
$event = $this->Attribute->Event->findById($eventId);
|
||||
if (empty($event)) {
|
||||
throw new NotFoundException(__('Invalid Event.'));
|
||||
}
|
||||
|
||||
if (!$this->_isRest()) {
|
||||
$this->Attribute->Event->insertLock($this->Auth->user(), $eventId);
|
||||
}
|
||||
// combobox for categories
|
||||
$categories = array_keys($this->Attribute->categoryDefinitions);
|
||||
// just get them with attachments..
|
||||
|
||||
// Filter categories that contains attachment type
|
||||
$selectedCategories = array();
|
||||
foreach ($categories as $category) {
|
||||
$types = $this->Attribute->categoryDefinitions[$category]['types'];
|
||||
$alreadySet = false;
|
||||
foreach ($types as $type) {
|
||||
if ($this->Attribute->typeIsAttachment($type) && !$alreadySet) {
|
||||
// add to the whole..
|
||||
foreach ($this->Attribute->categoryDefinitions as $category => $values) {
|
||||
foreach ($values['types'] as $type) {
|
||||
if ($this->Attribute->typeIsAttachment($type)) {
|
||||
$selectedCategories[] = $category;
|
||||
$alreadySet = true;
|
||||
continue;
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
$categories = $this->_arrayToValuesIndexArray($selectedCategories);
|
||||
$this->set('categories', $categories);
|
||||
|
||||
$this->set('attrDescriptions', $this->Attribute->fieldDescriptions);
|
||||
$this->set('typeDefinitions', $this->Attribute->typeDefinitions);
|
||||
$this->set('categoryDefinitions', $this->Attribute->categoryDefinitions);
|
||||
|
||||
$this->set('zippedDefinitions', $this->Attribute->zippedDefinitions);
|
||||
$this->set('uploadDefinitions', $this->Attribute->uploadDefinitions);
|
||||
$this->set('advancedExtractionAvailable', $this->Attribute->isAdvancedExtractionAvailable());
|
||||
|
||||
// combobox for distribution
|
||||
$this->loadModel('Event');
|
||||
$this->set('distributionLevels', $this->Event->Attribute->distributionLevels);
|
||||
|
||||
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->set('distributionLevels', $this->Attribute->distributionLevels);
|
||||
$this->set('info', $this->__getInfo());
|
||||
|
||||
$this->loadModel('SharingGroup');
|
||||
$sgs = $this->SharingGroup->fetchAllAuthorised($this->Auth->user(), 'name', 1);
|
||||
$this->set('sharingGroups', $sgs);
|
||||
|
||||
$events = $this->Event->findById($eventId);
|
||||
if (empty($events)) {
|
||||
throw new NotFoundException(__('Invalid Event.'));
|
||||
}
|
||||
$this->set('currentDist', $events['Event']['distribution']);
|
||||
$this->set('published', $events['Event']['published']);
|
||||
$this->set('currentDist', $event['Event']['distribution']);
|
||||
$this->set('published', $event['Event']['published']);
|
||||
}
|
||||
|
||||
|
||||
|
@ -852,6 +837,12 @@ class AttributesController extends AppController
|
|||
if (!isset($this->request->data['Attribute'])) {
|
||||
$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']);
|
||||
// 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
|
||||
|
@ -3250,4 +3241,28 @@ class AttributesController extends AppController
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -569,6 +569,7 @@ class ACLComponent extends Component
|
|||
'discardRegistrations' => array('perm_site_admin'),
|
||||
'downloadTerms' => array('*'),
|
||||
'edit' => array('*'),
|
||||
'email_otp' => array('*'),
|
||||
'searchGpgKey' => array('*'),
|
||||
'fetchGpgKey' => array('*'),
|
||||
'histogram' => array('*'),
|
||||
|
|
|
@ -1403,12 +1403,8 @@ class EventsController extends AppController
|
|||
$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) {
|
||||
if (in_array($eventTag['Tag']['name'], $cluster_names)) {
|
||||
unset($event['EventTag'][$k]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->Event->removeGalaxyClusterTags($event);
|
||||
|
||||
$tagConflicts = $this->Taxonomy->checkIfTagInconsistencies($event['EventTag']);
|
||||
foreach ($tagConflicts['global'] as $tagConflict) {
|
||||
|
@ -1430,11 +1426,9 @@ class EventsController extends AppController
|
|||
}
|
||||
$modDate = date("Y-m-d", $attribute['timestamp']);
|
||||
$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)) {
|
||||
unset($event['Attribute'][$k]['AttributeTag'][$k2]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->Event->Attribute->removeGalaxyClusterTags($event['Attribute'][$k]);
|
||||
|
||||
$tagConflicts = $this->Taxonomy->checkIfTagInconsistencies($attribute['AttributeTag']);
|
||||
foreach ($tagConflicts['global'] as $tagConflict) {
|
||||
$warningTagConflicts[$tagConflict['taxonomy']['Taxonomy']['namespace']] = $tagConflict['taxonomy'];
|
||||
|
@ -1463,11 +1457,9 @@ class EventsController extends AppController
|
|||
}
|
||||
$modDate = date("Y-m-d", $attribute['timestamp']);
|
||||
$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)) {
|
||||
unset($event['Object'][$k]['Attribute'][$k2]['AttributeTag'][$k3]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->Event->Attribute->removeGalaxyClusterTags($event['Object'][$k]['Attribute'][$k2]);
|
||||
|
||||
$tagConflicts = $this->Taxonomy->checkIfTagInconsistencies($attribute['AttributeTag']);
|
||||
foreach ($tagConflicts['global'] as $tagConflict) {
|
||||
$warningTagConflicts[$tagConflict['taxonomy']['Taxonomy']['namespace']] = $tagConflict['taxonomy'];
|
||||
|
@ -1659,7 +1651,7 @@ class EventsController extends AppController
|
|||
if (!empty($this->params['named']['excludeGalaxy'])) {
|
||||
$conditions['excludeGalaxy'] = 1;
|
||||
}
|
||||
if (!empty($this->params['named']['extended'])) {
|
||||
if (!empty($this->params['named']['extended']) || !empty($this->request->data['extended'])) {
|
||||
$conditions['extended'] = 1;
|
||||
$this->set('extended', 1);
|
||||
} else {
|
||||
|
@ -2280,18 +2272,34 @@ class EventsController extends AppController
|
|||
}
|
||||
}
|
||||
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(
|
||||
'conditions' => array('OR' => array('Attribute.value1' => $result['value'], 'Attribute.value2' => $result['value'])),
|
||||
'fields' => array('Attribute.type', 'Attribute.category', 'Attribute.value', 'Attribute.comment'),
|
||||
'order' => false
|
||||
'conditions' => array('OR' => $or),
|
||||
'fields' => array('Attribute.type', 'Attribute.category', 'Attribute.value', 'Attribute.comment'),
|
||||
'order' => false
|
||||
);
|
||||
$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('resultArray', $resultArray);
|
||||
$this->set('typeList', array_keys($this->Event->Attribute->typeDefinitions));
|
||||
$this->set('defaultCategories', $this->Event->Attribute->defaultCategories);
|
||||
$this->set('typeCategoryMapping', $typeCategoryMapping);
|
||||
$this->set('distributions', $distributions);
|
||||
$this->set('sgs', $sgs);
|
||||
$this->set('title', 'Merge Results');
|
||||
$this->set('importComment', 'Merged from event ' . $source_id);
|
||||
$this->render('resolved_attributes');
|
||||
|
@ -3715,8 +3723,15 @@ class EventsController extends AppController
|
|||
}
|
||||
}
|
||||
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(
|
||||
'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'),
|
||||
'order' => false,
|
||||
'flatten' => 1
|
||||
|
@ -4987,10 +5002,17 @@ class EventsController extends AppController
|
|||
}
|
||||
}
|
||||
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(
|
||||
'conditions' => array('OR' => array('Attribute.value1' => $result['value'], 'Attribute.value2' => $result['value'])),
|
||||
'fields' => array('Attribute.type', 'Attribute.category', 'Attribute.value', 'Attribute.comment'),
|
||||
'order' => false
|
||||
'conditions' => array('OR' => $or),
|
||||
'fields' => array('Attribute.type', 'Attribute.category', 'Attribute.value', 'Attribute.comment'),
|
||||
'order' => false
|
||||
);
|
||||
$resultArray[$key]['related'] = $this->Event->Attribute->fetchAttributes($this->Auth->user(), $options);
|
||||
if (isset($result['data'])) {
|
||||
|
@ -5170,10 +5192,17 @@ class EventsController extends AppController
|
|||
}
|
||||
}
|
||||
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(
|
||||
'conditions' => array('OR' => array('Attribute.value1' => $result['value'], 'Attribute.value2' => $result['value'])),
|
||||
'fields' => array('Attribute.type', 'Attribute.category', 'Attribute.value', 'Attribute.comment'),
|
||||
'order' => false
|
||||
'conditions' => array('OR' => $or),
|
||||
'fields' => array('Attribute.type', 'Attribute.category', 'Attribute.value', 'Attribute.comment'),
|
||||
'order' => false
|
||||
);
|
||||
$resultArray[$key]['related'] = $this->Event->Attribute->fetchAttributes($this->Auth->user(), $options);
|
||||
}
|
||||
|
|
|
@ -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[0] = 'None';
|
||||
$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->set('orgs', $this->Event->Orgc->find('list', array(
|
||||
|
|
|
@ -992,13 +992,15 @@ class ServersController extends AppController
|
|||
if ($tab == 'diagnostics' || $tab == 'download' || $this->_isRest()) {
|
||||
$php_ini = php_ini_loaded_file();
|
||||
$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 {
|
||||
$advanced_attachments = json_decode($advanced_attachments, true);
|
||||
$advanced_attachments = $malwareTool->checkAdvancedExtractionStatus($this->Server->getPythonVersion());
|
||||
} catch (Exception $e) {
|
||||
$this->log($e->getMessage(), LOG_NOTICE);
|
||||
$advanced_attachments = false;
|
||||
}
|
||||
|
||||
$this->set('advanced_attachments', $advanced_attachments);
|
||||
// check if the current version of MISP is outdated or not
|
||||
$version = $this->__checkVersion();
|
||||
|
|
|
@ -31,6 +31,9 @@ class UsersController extends AppController
|
|||
|
||||
// what pages are allowed for non-logged-in users
|
||||
$allowedActions = array('login', 'logout');
|
||||
if(!empty(Configure::read('Security.email_otp_enabled'))) {
|
||||
$allowedActions[] = 'email_otp';
|
||||
}
|
||||
if (!empty(Configure::read('Security.allow_self_registration'))) {
|
||||
$allowedActions[] = 'register';
|
||||
}
|
||||
|
@ -1116,33 +1119,15 @@ class UsersController extends AppController
|
|||
$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()) {
|
||||
$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(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'));
|
||||
$this->_postlogin();
|
||||
} else {
|
||||
$dataSourceConfig = ConnectionManager::getDataSource('default')->config;
|
||||
$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()
|
||||
{
|
||||
// Events list
|
||||
|
@ -1473,7 +1487,7 @@ class UsersController extends AppController
|
|||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->saveFailResponse('Users', 'admin_quickEmail', false, $error, $this->response->type());
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
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'));
|
||||
}
|
||||
}
|
||||
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) {
|
||||
$result = $this->User->registerUser(
|
||||
$this->Auth->user(),
|
||||
|
|
|
@ -131,12 +131,12 @@ class NidsSuricataExport extends NidsExport
|
|||
$data['host'] = NidsExport::replaceIllegalChars($data['host']);
|
||||
$tag = 'tag:session,600,seconds;';
|
||||
# IP: classic IP rule for HTTPS
|
||||
$suricata_protocol = 'tcp';
|
||||
$suricata_protocol = 'tls';
|
||||
$suricata_src_ip = '$HOME_NET';
|
||||
$suricata_src_port = 'any';
|
||||
$suricata_dst_ip = $data['host'];
|
||||
$suricata_dst_ip = '$EXTERNAL_NET';
|
||||
$suricata_dst_port = NidsExport::getProtocolPort($scheme, $data['port']);
|
||||
$content = 'flow:to_server; app-layer-protocol:tls;';
|
||||
$content = 'tls_sni; content:"' . $data['host'] . '";';
|
||||
break;
|
||||
|
||||
case "ssh":
|
||||
|
|
|
@ -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
|
@ -1,7 +1,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"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"
|
||||
"Language-Team: German\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"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"
|
||||
"Language-Team: Italian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -82,11 +82,12 @@ msgstr ""
|
|||
#: Console/Command/AdminShell.php:563
|
||||
msgid "\n"
|
||||
"Error: %s\n"
|
||||
msgstr ""
|
||||
msgstr "\n"
|
||||
"Errore: %s\n"
|
||||
|
||||
#: Console/Command/AdminShell.php:565
|
||||
msgid "%s events purged.\n"
|
||||
msgstr ""
|
||||
msgstr "%s eventi eliminati.\n"
|
||||
|
||||
#: Console/Command/AdminShell.php:587
|
||||
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
|
@ -1,7 +1,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"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"
|
||||
"Language-Team: Russian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"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"
|
||||
"Language-Team: Chinese Simplified\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -73,11 +73,11 @@ msgstr ""
|
|||
#: Console/Command/AdminShell.php:536
|
||||
#: Controller/UsersController.php:1234
|
||||
msgid "Invalid user."
|
||||
msgstr ""
|
||||
msgstr "无效用户"
|
||||
|
||||
#: Console/Command/AdminShell.php:539
|
||||
msgid "User has to be a site admin."
|
||||
msgstr ""
|
||||
msgstr "用户必须是站点管理员。"
|
||||
|
||||
#: Console/Command/AdminShell.php:563
|
||||
msgid "\n"
|
||||
|
@ -181,7 +181,7 @@ msgstr "未设置事件ID。"
|
|||
|
||||
#: Controller/AttributesController.php:112
|
||||
msgid "You do not have permissions to create attributes"
|
||||
msgstr ""
|
||||
msgstr "你没有权限创建属性."
|
||||
|
||||
#: Controller/AttributesController.php:132;422;602;832;3127;3142
|
||||
#: Controller/EventGraphController.php:88
|
||||
|
@ -350,7 +350,7 @@ msgstr "此功能只能通过AJAX访问。"
|
|||
|
||||
#: Controller/AttributesController.php:2241
|
||||
msgid "You do not have permission to do that"
|
||||
msgstr ""
|
||||
msgstr "您无权执行此操作。"
|
||||
|
||||
#: Controller/AttributesController.php:2271;2279
|
||||
#: Controller/EventsController.php:3643;3796;4999
|
||||
|
@ -395,7 +395,7 @@ msgstr "无效请求类型。"
|
|||
#: Controller/AttributesController.php:2823;3030
|
||||
#: Controller/TagCollectionsController.php:254
|
||||
msgid "Invalid tag"
|
||||
msgstr ""
|
||||
msgstr "无效标签"
|
||||
|
||||
#: Controller/AttributesController.php:3120
|
||||
#: Controller/EventsController.php:5197
|
||||
|
@ -409,11 +409,11 @@ msgstr "无效属性。"
|
|||
|
||||
#: Controller/CommunitiesController.php:150
|
||||
msgid "Request sent."
|
||||
msgstr ""
|
||||
msgstr "请求已发送"
|
||||
|
||||
#: Controller/CommunitiesController.php:150
|
||||
msgid "Something went wrong and the request could not be sent."
|
||||
msgstr ""
|
||||
msgstr "出错了,请求无法发送。"
|
||||
|
||||
#: 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."
|
||||
|
|
|
@ -78,7 +78,7 @@ class AppModel extends Model
|
|||
33 => false, 34 => false, 35 => false, 36 => false, 37 => false, 38 => 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,
|
||||
51 => false
|
||||
51 => false, 52 => false, 53 => false
|
||||
);
|
||||
|
||||
public $advanced_updates_description = array(
|
||||
|
@ -1268,7 +1268,7 @@ class AppModel extends Model
|
|||
case 39:
|
||||
$sqlArray[] = "CREATE TABLE IF NOT EXISTS user_settings (
|
||||
`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,
|
||||
`user_id` 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";
|
||||
$this->__addIndex('feeds', 'orgc_id');
|
||||
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':
|
||||
$sqlArray[] = 'UPDATE `events` 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)
|
||||
{
|
||||
$message = sprintf("%s\n[%s] %s",
|
||||
$message,
|
||||
get_class($exception),
|
||||
$exception->getMessage()
|
||||
);
|
||||
$message .= "\nStack Trace:\n" . $exception->getTraceAsString();
|
||||
$message .= "\n";
|
||||
|
||||
do {
|
||||
$message .= sprintf("[%s] %s",
|
||||
get_class($exception),
|
||||
$exception->getMessage()
|
||||
);
|
||||
$message .= "\nStack Trace:\n" . $exception->getTraceAsString();
|
||||
$exception = $exception->getPrevious();
|
||||
} while ($exception !== null);
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ App::uses('Folder', 'Utility');
|
|||
App::uses('File', 'Utility');
|
||||
App::uses('FinancialTool', 'Tools');
|
||||
App::uses('RandomTool', 'Tools');
|
||||
App::uses('MalwareTool', 'Tools');
|
||||
|
||||
class Attribute extends AppModel
|
||||
{
|
||||
|
@ -698,7 +699,7 @@ class Attribute extends AppModel
|
|||
* Only recorrelate if:
|
||||
* - We are dealing with a new attribute OR
|
||||
* - 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
|
||||
*/
|
||||
if (!$created) {
|
||||
|
@ -706,7 +707,9 @@ class Attribute extends AppModel
|
|||
empty($this->old) ||
|
||||
$this->data['Attribute']['value'] != $this->old['Attribute']['value'] ||
|
||||
$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->__afterSaveCorrelation($this->data['Attribute'], false, $passedEvent);
|
||||
|
@ -3348,6 +3351,9 @@ class Attribute extends AppModel
|
|||
} else {
|
||||
$options['includeDecayScore'] = true;
|
||||
}
|
||||
if ($options['includeDecayScore']) {
|
||||
$options['includeEventTags'] = true;
|
||||
}
|
||||
if (!$user['Role']['perm_sync'] || !isset($options['deleted']) || !$options['deleted']) {
|
||||
$params['conditions']['AND']['(Attribute.deleted + 0)'] = 0;
|
||||
} else {
|
||||
|
@ -3477,7 +3483,13 @@ class Attribute extends AppModel
|
|||
if ($options['includeDecayScore']) {
|
||||
$this->DecayingModel = ClassRegistry::init('DecayingModel');
|
||||
$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);
|
||||
unset($results[$key]['Attribute']['AttributeTag']);
|
||||
unset($results[$key]['Attribute']['EventTag']);
|
||||
if ($options['excludeDecayed'] && !empty($results[$key]['Attribute']['decay_score'])) { // filter out decayed attribute
|
||||
$decayed_flag = true;
|
||||
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)) {
|
||||
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)) {
|
||||
$attachments_dir = $this->getDefaultAttachments_dir();
|
||||
|
||||
$content = base64_decode($base64);
|
||||
|
||||
$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
|
||||
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();
|
||||
$result = array_merge(array('data' => base64_encode($encrypted), 'success' => true), $hashes);
|
||||
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');
|
||||
if (!in_array($hashType, $validHashes)) {
|
||||
$malwareTool = new MalwareTool();
|
||||
try {
|
||||
$types = $malwareTool->checkAdvancedExtractionStatus($this->getPythonVersion());
|
||||
} catch (Exception $e) {
|
||||
return false;
|
||||
}
|
||||
switch ($hashType) {
|
||||
case 'md5':
|
||||
case 'sha1':
|
||||
case 'sha256':
|
||||
return hash_file($hashType, $file);
|
||||
break;
|
||||
|
||||
foreach ($types as $type => $missing) {
|
||||
if ($missing === false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3961,7 +3950,7 @@ class Attribute extends AppModel
|
|||
'event_id' => $event_id,
|
||||
'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) {
|
||||
$attribute = array(
|
||||
'distribution' => 5,
|
||||
|
@ -3992,33 +3981,34 @@ class Attribute extends AppModel
|
|||
|
||||
public function advancedAddMalwareSample($event_id, $attribute_settings, $filename, $tmpfile)
|
||||
{
|
||||
$execRetval = '';
|
||||
$execOutput = array();
|
||||
$result = shell_exec($this->getPythonVersion() . ' ' . APP . 'files/scripts/generate_file_objects.py -p ' . $tmpfile->path);
|
||||
if (!empty($result)) {
|
||||
$result = json_decode($result, true);
|
||||
if (isset($result['objects'])) {
|
||||
$result['Object'] = $result['objects'];
|
||||
unset($result['objects']);
|
||||
}
|
||||
if (isset($result['references'])) {
|
||||
$result['ObjectReference'] = $result['references'];
|
||||
unset($result['references']);
|
||||
}
|
||||
foreach ($result['Object'] as $k => $object) {
|
||||
$result['Object'][$k]['distribution'] = $attribute_settings['distribution'];
|
||||
$result['Object'][$k]['sharing_group_id'] = isset($attribute_settings['distribution']) ? $attribute_settings['distribution'] : 0;
|
||||
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;
|
||||
}
|
||||
$malwareTool = new MalwareTool();
|
||||
try {
|
||||
$result = $malwareTool->advancedExtraction($this->getPythonVersion(), $tmpfile->path);
|
||||
} catch (Exception $e) {
|
||||
$this->logException("Could not finish advanced extraction", $e);
|
||||
return $this->simpleAddMalwareSample($event_id, $attribute_settings, $filename, $tmpfile);
|
||||
}
|
||||
|
||||
if (isset($result['objects'])) {
|
||||
$result['Object'] = $result['objects'];
|
||||
unset($result['objects']);
|
||||
}
|
||||
if (isset($result['references'])) {
|
||||
$result['ObjectReference'] = $result['references'];
|
||||
unset($result['references']);
|
||||
}
|
||||
foreach ($result['Object'] as $k => $object) {
|
||||
$result['Object'][$k]['distribution'] = $attribute_settings['distribution'];
|
||||
$result['Object'][$k]['sharing_group_id'] = isset($attribute_settings['distribution']) ? $attribute_settings['distribution'] : 0;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -4639,4 +4629,28 @@ class Attribute extends AppModel
|
|||
}
|
||||
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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -536,7 +536,7 @@ class DecayingModel extends AppModel
|
|||
'sightings' => $sightings,
|
||||
'base_score_config' => $base_score_config,
|
||||
'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']
|
||||
);
|
||||
}
|
||||
|
@ -587,9 +587,10 @@ class DecayingModel extends AppModel
|
|||
$model = $this->overrideModelParameters($model, $model_overrides);
|
||||
}
|
||||
$score = $this->getScore($attribute, $model, $user);
|
||||
$decayed = $this->isDecayed($attribute, $model, $score);
|
||||
$decayed = $this->isDecayed($attribute, $model, $score['score']);
|
||||
$to_attach = array(
|
||||
'score' => $score,
|
||||
'score' => $score['score'],
|
||||
'base_score' => $score['base_score'],
|
||||
'decayed' => $decayed,
|
||||
'DecayingModel' => array(
|
||||
'id' => $model['DecayingModel']['id'],
|
||||
|
@ -626,7 +627,7 @@ class DecayingModel extends AppModel
|
|||
public function isDecayed($attribute, $model, $score=false, $user=false)
|
||||
{
|
||||
if ($score === false) {
|
||||
$score = $this->getScore($attribute, $model, $user);
|
||||
$score = $this->getScore($attribute, $model, $user)['score'];
|
||||
}
|
||||
$this->Computation = $this->getModelClass($model);
|
||||
return $this->Computation->isDecayed($model, $attribute, $score);
|
||||
|
|
|
@ -144,7 +144,11 @@ abstract class DecayingModelBase
|
|||
$last_sighting_timestamp = $attribute['timestamp'];
|
||||
}
|
||||
$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
|
||||
|
|
|
@ -641,6 +641,12 @@ class Event extends AppModel
|
|||
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'])));
|
||||
}
|
||||
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')) {
|
||||
$pubSubTool = $this->getPubSubTool();
|
||||
|
@ -2150,6 +2156,22 @@ class Event extends AppModel
|
|||
'Object' => array('name', 'meta-category')
|
||||
);
|
||||
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);
|
||||
$event = $this->Orgc->attachOrgsToEvent($event, $fieldsOrg);
|
||||
if (!$options['sgReferenceOnly'] && $event['Event']['sharing_group_id']) {
|
||||
|
@ -2448,7 +2470,11 @@ class Event extends AppModel
|
|||
}
|
||||
foreach ($data as $k => $v) {
|
||||
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;
|
||||
|
@ -3237,10 +3263,10 @@ class Event extends AppModel
|
|||
return array($bodyevent, $body);
|
||||
}
|
||||
|
||||
private function __captureSGForElement($element, $user)
|
||||
private function __captureSGForElement($element, $user, $syncLocal=false)
|
||||
{
|
||||
if (isset($element['SharingGroup'])) {
|
||||
$sg = $this->SharingGroup->captureSG($element['SharingGroup'], $user);
|
||||
$sg = $this->SharingGroup->captureSG($element['SharingGroup'], $user, $syncLocal);
|
||||
unset($element['SharingGroup']);
|
||||
} elseif (isset($element['sharing_group_id'])) {
|
||||
$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
|
||||
// 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
|
||||
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'])) {
|
||||
foreach ($data['Event']['Attribute'] as $k => $a) {
|
||||
unset($data['Event']['Attribute']['id']);
|
||||
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) {
|
||||
unset($data['Event']['Attribute']);
|
||||
}
|
||||
|
@ -3277,7 +3303,7 @@ class Event extends AppModel
|
|||
if (!empty($data['Event']['Object'])) {
|
||||
foreach ($data['Event']['Object'] as $k => $o) {
|
||||
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) {
|
||||
unset($data['Event']['Object'][$k]);
|
||||
continue;
|
||||
|
@ -3285,7 +3311,7 @@ class Event extends AppModel
|
|||
}
|
||||
foreach ($o['Attribute'] as $k2 => $a) {
|
||||
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) {
|
||||
unset($data['Event']['Object'][$k]['Attribute'][$k2]);
|
||||
}
|
||||
|
@ -3453,6 +3479,24 @@ class Event extends AppModel
|
|||
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) {
|
||||
// Workaround for different structure in XML/array than what CakePHP expects
|
||||
$data = $this->cleanupEventArrayFromXML($data);
|
||||
|
@ -3479,7 +3523,7 @@ class Event extends AppModel
|
|||
return $existingEvent['Event']['id'];
|
||||
} else {
|
||||
if ($fromXml) {
|
||||
$data = $this->__captureObjects($data, $user);
|
||||
$data = $this->__captureObjects($data, $user, $server['Server']['internal']);
|
||||
}
|
||||
if ($data === false) {
|
||||
$failedCapture = true;
|
||||
|
@ -3487,7 +3531,7 @@ class Event extends AppModel
|
|||
}
|
||||
} else {
|
||||
if ($fromXml) {
|
||||
$data = $this->__captureObjects($data, $user);
|
||||
$data = $this->__captureObjects($data, $user, $server['Server']['internal']);
|
||||
}
|
||||
if ($data === false) {
|
||||
$failedCapture = true;
|
||||
|
@ -3548,19 +3592,6 @@ class Event extends AppModel
|
|||
$this->Log = ClassRegistry::init('Log');
|
||||
if ($saveResult) {
|
||||
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) {
|
||||
$st = "enabled";
|
||||
} else {
|
||||
|
@ -3703,6 +3734,23 @@ class Event extends AppModel
|
|||
} else {
|
||||
$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...
|
||||
$dateObj = new DateTime();
|
||||
$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.'));
|
||||
}
|
||||
} 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']);
|
||||
if ($data['Event']['sharing_group_id'] === false) {
|
||||
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'])) {
|
||||
// The edited event is from a remote server ?
|
||||
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) {
|
||||
$st = "enabled";
|
||||
} else {
|
||||
|
@ -6948,4 +6983,27 @@ class Event extends AppModel
|
|||
}
|
||||
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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -247,10 +247,7 @@ class Feed extends AppModel
|
|||
$data = $this->feedGetUri($feed, $feedUrl, $HttpSocket, true);
|
||||
|
||||
if (!$isLocal) {
|
||||
$redis = $this->setupRedis();
|
||||
if ($redis === false) {
|
||||
throw new Exception('Could not reach Redis.');
|
||||
}
|
||||
$redis = $this->setupRedisWithException();
|
||||
$redis->del('misp:feed_cache:' . $feed['Feed']['id']);
|
||||
file_put_contents($feedCache, $data);
|
||||
}
|
||||
|
@ -502,12 +499,17 @@ class Feed extends AppModel
|
|||
|
||||
$result = array(
|
||||
'header' => array(
|
||||
'Accept' => array('application/json', 'text/plain'),
|
||||
'Content-Type' => 'application/json',
|
||||
'MISP-version' => $version,
|
||||
'MISP-uuid' => Configure::read('MISP.uuid')
|
||||
'Accept' => array('application/json', 'text/plain'),
|
||||
'MISP-version' => $version,
|
||||
'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) {
|
||||
$result['header']['commit'] = $commit;
|
||||
}
|
||||
|
@ -1029,14 +1031,14 @@ class Feed extends AppModel
|
|||
} elseif ($scope == 'freetext' || $scope == 'csv') {
|
||||
$params['conditions']['source_format'] = array('csv', 'freetext');
|
||||
} 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';
|
||||
} else {
|
||||
throw new InvalidArgumentException("Invalid value for scope, it must be integer or 'freetext', 'csv', 'misp' or 'all' string.");
|
||||
}
|
||||
} else {
|
||||
$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);
|
||||
$atLeastOneSuccess = false;
|
||||
|
@ -1590,24 +1592,51 @@ class Feed extends AppModel
|
|||
if ($data === false) {
|
||||
throw new Exception("Could not read local file '$uri'.");
|
||||
}
|
||||
return $data;
|
||||
} else {
|
||||
throw new Exception("Local file '$uri' doesn't exists.");
|
||||
}
|
||||
}
|
||||
|
||||
$request = $this->__createFeedRequest($feed['Feed']['headers']);
|
||||
|
||||
if ($followRedirect) {
|
||||
$response = $this->getFollowRedirect($HttpSocket, $uri, $request);
|
||||
} else {
|
||||
$request = $this->__createFeedRequest($feed['Feed']['headers']);
|
||||
$response = $HttpSocket->get($uri, array(), $request);
|
||||
}
|
||||
|
||||
if ($followRedirect) {
|
||||
$response = $this->getFollowRedirect($HttpSocket, $uri, $request);
|
||||
} else {
|
||||
$response = $HttpSocket->get($uri, array(), $request);
|
||||
}
|
||||
if ($response === false) {
|
||||
throw new Exception("Could not reach '$uri'.");
|
||||
} else if ($response->code != 200) { // intentionally !=
|
||||
throw new Exception("Fetching the '$uri' failed with HTTP error {$response->code}: {$response->reasonPhrase}");
|
||||
}
|
||||
|
||||
if ($response === false) {
|
||||
throw new Exception("Could not reach '$uri'.");
|
||||
} else if ($response->code != 200) { // intentionally !=
|
||||
throw new Exception("Fetching the '$uri' failed with HTTP error {$response->code}: {$response->reasonPhrase}");
|
||||
$data = $response->body;
|
||||
|
||||
$contentEncoding = $response->getHeader('Content-Encoding');
|
||||
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;
|
||||
|
@ -1720,4 +1749,47 @@ class Feed extends AppModel
|
|||
$this->save($feed);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,18 +96,6 @@ class Log extends AppModel
|
|||
'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())
|
||||
{
|
||||
if (!empty(Configure::read('MISP.log_skip_db_logs_completely'))) {
|
||||
|
@ -125,7 +113,7 @@ class Log extends AppModel
|
|||
if (!isset($this->data['Log']['created'])) {
|
||||
$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';
|
||||
}
|
||||
$truncate_fields = array('title', 'change', 'description');
|
||||
|
|
|
@ -1261,6 +1261,54 @@ class Server extends AppModel
|
|||
'type' => 'boolean',
|
||||
'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(
|
||||
'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.'),
|
||||
|
@ -3113,15 +3161,6 @@ class Server extends AppModel
|
|||
private function readModuleSettings($serverSettings, $moduleTypes)
|
||||
{
|
||||
$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) {
|
||||
if (Configure::read('Plugin.' . $moduleType . '_services_enable')) {
|
||||
$results = $this->Module->getModuleSettings($moduleType);
|
||||
|
@ -3550,7 +3589,7 @@ class Server extends AppModel
|
|||
if ($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;
|
||||
}
|
||||
|
@ -3740,6 +3779,14 @@ class Server extends AppModel
|
|||
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)
|
||||
{
|
||||
if ($this->testForEmpty($value) !== true) {
|
||||
|
@ -3901,7 +3948,6 @@ class Server extends AppModel
|
|||
} else {
|
||||
$serverSettings = $this->serverSettings;
|
||||
}
|
||||
$relevantSettings = (array_intersect_key(Configure::read(), $serverSettings));
|
||||
$setting = false;
|
||||
foreach ($serverSettings as $k => $s) {
|
||||
if (isset($s['branch'])) {
|
||||
|
@ -5752,7 +5798,7 @@ class Server extends AppModel
|
|||
$params['conditions']['Server.id'] = $id;
|
||||
} else {
|
||||
$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);
|
||||
if ($jobId) {
|
||||
|
|
|
@ -54,6 +54,10 @@ class SharingGroup extends AppModel
|
|||
);
|
||||
|
||||
private $__sgoCache = array();
|
||||
private $__sgAuthorisationCache = array(
|
||||
'save' => array(),
|
||||
'access' => 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
|
||||
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)) {
|
||||
$sgid = $this->SharingGroup->find('first', array(
|
||||
'conditions' => array('SharingGroup.uuid' => $id),
|
||||
|
@ -372,8 +379,10 @@ class SharingGroup extends AppModel
|
|||
return false;
|
||||
}
|
||||
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;
|
||||
}
|
||||
$this->__sgAuthorisationCache['access'][boolval($adminCheck)][$id] = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -485,7 +494,7 @@ class SharingGroup extends AppModel
|
|||
return $results;
|
||||
}
|
||||
|
||||
public function captureSG($sg, $user)
|
||||
public function captureSG($sg, $user, $syncLocal=false)
|
||||
{
|
||||
$existingSG = !isset($sg['uuid']) ? null : $this->find('first', array(
|
||||
'recursive' => -1,
|
||||
|
@ -501,6 +510,34 @@ class SharingGroup extends AppModel
|
|||
if (!$user['Role']['perm_sharing_group']) {
|
||||
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();
|
||||
$newSG = array();
|
||||
$attributes = array(
|
||||
|
|
|
@ -68,10 +68,10 @@ class SysLog {
|
|||
} else if (in_array($type, $debugTypes)) {
|
||||
$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)) {
|
||||
return false;
|
||||
}
|
||||
$output = date('Y-m-d H:i:s') . ' ' . ucfirst($type) . ': ' . $message;
|
||||
$result = syslog($priority, $output);
|
||||
closelog();
|
||||
return $result;
|
||||
|
|
|
@ -67,9 +67,11 @@
|
|||
<?php
|
||||
echo $this->Form->input('advanced', array(
|
||||
'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'),
|
||||
'label' => __('Advanced extraction (if installed)'),
|
||||
'label' => __('Advanced extraction'),
|
||||
));
|
||||
?>
|
||||
</fieldset>
|
||||
|
@ -131,7 +133,7 @@ $(document).ready(function() {
|
|||
$("#AttributeCategory, #AttributeDistribution").change(function() {
|
||||
initPopoverContent('Attribute');
|
||||
});
|
||||
|
||||
|
||||
$("#AttributeMalware").change(function () {
|
||||
if (this.checked) {
|
||||
$('#advanced_input').show();
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
$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
|
||||
if ($mayModify || $extended):
|
||||
?>
|
||||
|
@ -22,7 +22,7 @@
|
|||
<?php
|
||||
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
|
||||
endif;
|
||||
?>
|
||||
|
@ -64,7 +64,7 @@
|
|||
?>
|
||||
|
||||
</td>
|
||||
<td colspan="5">
|
||||
<td colspan="<?= $includeRelatedTags ? 6 : 5 ?>">
|
||||
<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>
|
||||
<br />
|
||||
|
@ -89,8 +89,8 @@
|
|||
?>
|
||||
</td>
|
||||
<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_solid" class="inline-field-solid">
|
||||
<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">
|
||||
<?php echo nl2br(h($object['comment'])); ?>
|
||||
</div>
|
||||
</td>
|
||||
|
@ -101,8 +101,8 @@
|
|||
$turnRed = '';
|
||||
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_solid'; ?>" <?php echo $turnRed; ?> class="inline-field-solid">
|
||||
<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">
|
||||
<?php
|
||||
if ($object['objectType'] == 0) {
|
||||
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>';
|
||||
}
|
||||
?>
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
if (!$skipPagination) {
|
||||
$paginationData = !empty($data['paginatorOptions']) ? $data['paginatorOptions'] : array();
|
||||
echo $this->element('/genericElements/IndexTable/pagination', array('paginationOptions' => $paginationData));
|
||||
echo $this->element('/genericElements/IndexTable/pagination_links');
|
||||
}
|
||||
if (!empty($data['top_bar'])) {
|
||||
echo $this->element('/genericElements/ListTopBar/scaffold', array('data' => $data['top_bar']));
|
||||
|
@ -81,7 +82,7 @@
|
|||
echo '</div>';
|
||||
if (!$skipPagination) {
|
||||
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">
|
||||
|
|
|
@ -9,10 +9,4 @@
|
|||
$options = array_merge($options, $paginationOptions);
|
||||
}
|
||||
echo $this->Paginator->options($options);
|
||||
echo sprintf(
|
||||
'<div class="pagination"><ul>%s%s%s</ul></div>',
|
||||
$this->Paginator->prev('« ' . __('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') . ' »', array('tag' => 'li', 'escape' => false), null, array('tag' => 'li', 'class' => 'next disabled', 'escape' => false, 'disabledTag' => 'span'))
|
||||
);
|
||||
?>
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
echo sprintf(
|
||||
'<div class="pagination"><ul>%s%s%s</ul></div>',
|
||||
$this->Paginator->prev('« ' . __('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') . ' »', array('tag' => 'li', 'escape' => false), null, array('tag' => 'li', 'class' => 'next disabled', 'escape' => false, 'disabledTag' => 'span'))
|
||||
);
|
|
@ -10,7 +10,7 @@
|
|||
</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; ?>">
|
||||
<canvas id="distribution_graph_canvas" height="290px"width="400px"></canvas>
|
||||
<canvas id="distribution_graph_canvas" height="290" width="400"></canvas>
|
||||
</div>
|
||||
<div class="popupDistriSeparator"></div>
|
||||
<div id="eventdistri_pb_container">
|
||||
|
|
|
@ -301,27 +301,27 @@
|
|||
)
|
||||
)
|
||||
);
|
||||
if (!Configure::read('MISP.completely_disable_correlation') && Configure::read('MISP.allow_disabling_correlation')) {
|
||||
$table_data[] = array(
|
||||
'key' => __('Correlation'),
|
||||
'class' => $event['Event']['disable_correlation'] ? 'background-red bold' : '',
|
||||
'html' => sprintf(
|
||||
'%s%s',
|
||||
$event['Event']['disable_correlation'] ? __('Disabled') : __('Enabled'),
|
||||
(!$mayModify && !$isSiteAdmin) ? '' : sprintf(
|
||||
}
|
||||
if (!Configure::read('MISP.completely_disable_correlation') && Configure::read('MISP.allow_disabling_correlation')) {
|
||||
$table_data[] = array(
|
||||
'key' => __('Correlation'),
|
||||
'class' => $event['Event']['disable_correlation'] ? 'background-red bold' : '',
|
||||
'html' => sprintf(
|
||||
'%s%s',
|
||||
$event['Event']['disable_correlation'] ? __('Disabled') : __('Enabled'),
|
||||
(!$mayModify && !$isSiteAdmin) ? '' : sprintf(
|
||||
sprintf(
|
||||
' (<a onClick="getPopup(%s);" style="%scursor:pointer;font-weight:normal;">%s</a>)',
|
||||
sprintf(
|
||||
' (<a onClick="getPopup(%s);" style="%scursor:pointer;font-weight:normal;">%s</a>)',
|
||||
sprintf(
|
||||
"'%s', 'events', 'toggleCorrelation', '', '#confirmation_box'",
|
||||
h($event['Event']['id'])
|
||||
),
|
||||
$event['Event']['disable_correlation'] ? 'color:white;' : '',
|
||||
$event['Event']['disable_correlation'] ? __('enable') : __('disable')
|
||||
)
|
||||
"'%s', 'events', 'toggleCorrelation', '', '#confirmation_box'",
|
||||
h($event['Event']['id'])
|
||||
),
|
||||
$event['Event']['disable_correlation'] ? 'color:white;' : '',
|
||||
$event['Event']['disable_correlation'] ? __('enable') : __('disable')
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
|
@ -27,8 +27,6 @@
|
|||
'button' => __('Filter'),
|
||||
'placeholder' => __('Enter value to search'),
|
||||
'data' => '',
|
||||
'searchKey' => 'value',
|
||||
'value' => $searchall
|
||||
)
|
||||
)
|
||||
),
|
||||
|
@ -101,6 +99,19 @@
|
|||
|
||||
<script type="text/javascript">
|
||||
$(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>
|
||||
<?php echo $this->Js->writeBuffer(); ?>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<tr>
|
||||
<td><table><tr id = "tags"></tr></table></td>
|
||||
<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 id = "addTagFieldTD">
|
||||
<?php
|
||||
|
|
|
@ -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",
|
||||
),
|
||||
)));
|
||||
?>
|
|
@ -232,7 +232,7 @@
|
|||
"event_id": "5655",
|
||||
"publish": 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",
|
||||
"delete_local_file": false,
|
||||
"lookup_visible": false,
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 1ffa97389b99aa71a20e967b22e2df45750f3bff
|
||||
Subproject commit 3b5451c32518da3e29c575e868d245f27c18dcf4
|
|
@ -1 +1 @@
|
|||
Subproject commit 28e7cb79f0ec603c232857a3bf7dca519d02cfa1
|
||||
Subproject commit 8c4e2a8e8b4d3ec287c43dcae129123fcde8cb2f
|
|
@ -4473,6 +4473,16 @@ function quickSelect(target) {
|
|||
}
|
||||
|
||||
$(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){
|
||||
$('#quickFilterButton').trigger("click");
|
||||
});
|
||||
|
|
|
@ -6567,5 +6567,5 @@
|
|||
"id"
|
||||
]
|
||||
},
|
||||
"db_version": "51"
|
||||
}
|
||||
"db_version": "53"
|
||||
}
|
||||
|
|
|
@ -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 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
|
||||
UMASK=$(umask)
|
||||
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
|
||||
$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
|
||||
|
||||
# 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
|
||||
$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/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/*
|
||||
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
|
||||
|
|
|
@ -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/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/Vendor/pear/crypt_gpg/scripts/crypt-gpg-pinentry
|
||||
sudo chcon -t httpd_sys_rw_content_t /tmp
|
||||
sudo chcon -R -t usr_t $PATH_TO_MISP/venv
|
||||
sudo chcon -R -t httpd_sys_rw_content_t $PATH_TO_MISP/.git
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# INSTALLATION INSTRUCTIONS
|
||||
## for Ubuntu 18.04.3-server
|
||||
## for Ubuntu 18.04.4-server
|
||||
|
||||
### -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
|
||||
|
||||
# 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
|
||||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install zmq redis
|
||||
|
|
|
@ -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!}
|
|
@ -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_anonymise" false
|
||||
$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
|
||||
$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_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_by_date" ""
|
||||
$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.footermidleft" "This is an initial install"
|
||||
|
@ -124,6 +126,10 @@ coreCAKE () {
|
|||
# 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_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
|
||||
$SUDO_WWW $RUN_PHP -- $CAKE Live $MISP_LIVE
|
||||
|
|
|
@ -25,7 +25,7 @@ mail2misp () {
|
|||
sudo ldconfig
|
||||
cd ../../mail_to_misp
|
||||
$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 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
|
||||
|
|
|
@ -21,8 +21,8 @@ mispmodulesRHEL () {
|
|||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=apache
|
||||
Group=apache
|
||||
User=$WWW_USER
|
||||
Group=$WWW_USER
|
||||
WorkingDirectory=/usr/local/src/misp-modules
|
||||
Environment="PATH=/var/www/MISP/venv/bin"
|
||||
ExecStart=\"${PATH_TO_MISP}/venv/bin/misp-modules -l 127.0.0.1 -s\"
|
||||
|
|
|
@ -217,18 +217,19 @@ EOF
|
|||
checkInstaller () {
|
||||
# Workaround: shasum is not available on RHEL, only checking sha512
|
||||
if [[ $FLAVOUR == "rhel" ]] || [[ $FLAVOUR == "centos" ]]; then
|
||||
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
|
||||
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
|
||||
chsum=$(cat /tmp/INSTALL.sh.sha512)
|
||||
if [[ "${chsum}" == "${INSTsum}" ]]; then
|
||||
echo "SHA512 matches"
|
||||
else
|
||||
echo "SHA512: ${chsum} does not match the installer sum of: ${INSTsum}"
|
||||
# exit 1 # uncomment when/if PR is merged
|
||||
fi
|
||||
if [[ "${chsum}" == "${INSTsum}" ]]; then
|
||||
echo "SHA512 matches"
|
||||
else
|
||||
echo "SHA512: ${chsum} does not match the installer sum of: ${INSTsum}"
|
||||
# exit 1 # uncomment when/if PR is merged
|
||||
fi
|
||||
else
|
||||
# TODO: Implement $FLAVOUR checks and install depending on the platform we are on
|
||||
if [[ $(which shasum > /dev/null 2>&1 ; echo $?) != 0 ]]; then
|
||||
sudo apt update
|
||||
sudo apt install libdigest-sha-perl -qyy
|
||||
fi
|
||||
# SHAsums to be computed, not the -- notatiation is for ease of use with rhash
|
||||
|
@ -541,12 +542,20 @@ setBaseURL () {
|
|||
MISP_BASEURL="https://misp.local"
|
||||
# Webserver configuration
|
||||
FQDN='misp.local'
|
||||
else
|
||||
elif [[ "$(checkManufacturer)" == "innotek GmbH" ]]; then
|
||||
MISP_BASEURL='https://localhost:8443'
|
||||
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
|
||||
# Webserver configuration
|
||||
FQDN='localhost.localdomain'
|
||||
elif [[ "$(checkManufacturer)" == "VMware, Inc." ]]; then
|
||||
MISP_BASEURL='""'
|
||||
# Webserver configuration
|
||||
FQDN='misp.local'
|
||||
else
|
||||
MISP_BASEURL='""'
|
||||
# Webserver configuration
|
||||
FQDN='misp.local'
|
||||
fi
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ viper () {
|
|||
# TODO: Check for current user install permissions
|
||||
$SUDO_CMD git submodule update --init --recursive
|
||||
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 .
|
||||
echo 'update-modules' |/usr/local/src/viper/venv/bin/viper
|
||||
cd /usr/local/src/viper-web
|
||||
|
|
|
@ -196,7 +196,7 @@ $SUDO_WWW make -j3
|
|||
sudo make install
|
||||
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/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
|
||||
$SUDO_WWW $PATH_TO_MISP/venv/bin/pip install -U python-magic
|
||||
|
|
|
@ -187,8 +187,8 @@ $SUDO_WWW scl enable devtoolset-7 'bash -c "cmake3 \
|
|||
$SUDO_WWW make -j3
|
||||
sudo make install
|
||||
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/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/python setup.py install
|
||||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install lief
|
||||
|
||||
# install magic, pydeep
|
||||
$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/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
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
||||
# 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
|
||||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install zmq redis
|
||||
|
|
|
@ -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
|
||||
|
||||
# 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
|
||||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install zmq redis
|
||||
|
|
|
@ -629,7 +629,7 @@ function installMISPonTsurugi() {
|
|||
sudo ldconfig
|
||||
cd ../../mail_to_misp
|
||||
$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 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
|
||||
|
|
|
@ -14,7 +14,7 @@ edit_uri: ""
|
|||
#dev_addr: "192.168.10.34:8000"
|
||||
|
||||
# Copyright
|
||||
copyright: "Copyright © 2019 MISP Project"
|
||||
copyright: "Copyright © 2020 MISP Project"
|
||||
|
||||
# Options
|
||||
extra:
|
||||
|
@ -69,6 +69,7 @@ nav:
|
|||
- Home: 'index.md'
|
||||
- Install Guides:
|
||||
- 'Ubuntu 18.04': 'INSTALL.ubuntu1804.md'
|
||||
- 'Ubuntu 20.04': 'INSTALL.ubuntu2004.md'
|
||||
- 'Kali Linux': 'INSTALL.kali.md'
|
||||
- 'RHEL7/CentOS7': 'INSTALL.rhel7.md'
|
||||
- 'RHEL8/CentOS8': 'INSTALL.rhel8.md'
|
||||
|
@ -76,10 +77,10 @@ nav:
|
|||
- 'Warning': 'xINSTALL.md'
|
||||
- 'Centos 6': 'xINSTALL.centos6.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'
|
||||
- 'Tsurugi Linux': 'xINSTALL.tsurugi.md'
|
||||
- 'OpenBSD 6.5': 'xINSTALL.OpenBSD.md'
|
||||
- 'OpenBSD 6.6': 'xINSTALL.OpenBSD.md'
|
||||
- Config Guides:
|
||||
- 'Elastic Search Logging': 'CONFIG.elasticsearch-logging.md'
|
||||
- 'Amazon S3 attachments': 'CONFIG.s3-attachments.md'
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
PATH_TO_MISP=/var/www/MISP
|
||||
ENABLE_WARNINGLISTS="false"
|
||||
ENABLE_NOTICELISTS="false"
|
||||
|
|
|
@ -108,4 +108,23 @@ curl --header "Authorization: $AuthKey" --header "Accept: application/json" --he
|
|||
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
|
||||
|
||||
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!!!'
|
||||
|
|
|
@ -6,10 +6,12 @@ TRUNCATE `correlations`;
|
|||
TRUNCATE `events`;
|
||||
TRUNCATE `event_blacklists`;
|
||||
TRUNCATE `event_delegations`;
|
||||
TRUNCATE `event_graph`;
|
||||
TRUNCATE `event_tags`;
|
||||
TRUNCATE `favourite_tags`;
|
||||
TRUNCATE `jobs`;
|
||||
TRUNCATE `logs`;
|
||||
TRUNCATE `notification_logs`;
|
||||
TRUNCATE `objects`;
|
||||
TRUNCATE `object_references`;
|
||||
TRUNCATE `object_relationships`;
|
||||
|
@ -17,6 +19,7 @@ TRUNCATE `object_templates`;
|
|||
TRUNCATE `object_template_elements`;
|
||||
TRUNCATE `org_blacklists`;
|
||||
TRUNCATE `posts`;
|
||||
TRUNCATE `rest_client_histories`;
|
||||
TRUNCATE `servers`;
|
||||
TRUNCATE `shadow_attributes`;
|
||||
TRUNCATE `shadow_attribute_correlations`;
|
||||
|
@ -24,6 +27,8 @@ TRUNCATE `sharing_groups`;
|
|||
TRUNCATE `sharing_group_orgs`;
|
||||
TRUNCATE `sharing_group_servers`;
|
||||
TRUNCATE `sightings`;
|
||||
TRUNCATE `tag_collections`;
|
||||
TRUNCATE `tag_collection_tags`;
|
||||
TRUNCATE `tags`;
|
||||
TRUNCATE `threads`;
|
||||
TRUNCATE `bruteforces`;
|
||||
|
@ -33,6 +38,7 @@ TRUNCATE `whitelist`;
|
|||
TRUNCATE `event_locks`;
|
||||
TRUNCATE `fuzzy_correlate_ssdeep`;
|
||||
TRUNCATE `tasks`;
|
||||
TRUNCATE `user_settings`;
|
||||
|
||||
-- Clear tables that can be re-populated
|
||||
TRUNCATE `taxonomies`;
|
||||
|
@ -47,6 +53,8 @@ TRUNCATE `galaxy_elements`;
|
|||
TRUNCATE `galaxy_reference`;
|
||||
TRUNCATE `noticelists`;
|
||||
TRUNCATE `noticelist_entries`;
|
||||
TRUNCATE `decaying_models`;
|
||||
TRUNCATE `decaying_model_mappings`;
|
||||
|
||||
-- Clear tables that have defaults
|
||||
TRUNCATE `feeds`;
|
||||
|
|
Loading…
Reference in New Issue