From 9cf758a0475fdefc24bc88d2f66cc497ca87a6dc Mon Sep 17 00:00:00 2001 From: Kahla Date: Wed, 22 Jul 2020 23:05:45 +0200 Subject: [PATCH 1/3] added MISP config --- package/docker/entrypoint | 98 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/package/docker/entrypoint b/package/docker/entrypoint index cdbf897d2a..aa00684fe5 100755 --- a/package/docker/entrypoint +++ b/package/docker/entrypoint @@ -20,6 +20,10 @@ test "${TH_NO_CONFIG}" == 1 CONFIG=$? CONFIG_FILE=${TH_CONFIG_FILE:-/etc/thehive/application.conf} CORTEX_KEYS=${TH_CORTEX_KEYS} +CONFIG_MISP=0 +MISP_HOSTNAMES="misp" +MISP_PROTO="http" +MISP_PORT="80" function usage { cat <<- _EOF_ Available options: @@ -41,6 +45,17 @@ function usage { --cortex-port | define port to connect to Cortex (default: 9001) --cortex-hostname ,,... | resolve this hostname to find Cortex instances --cortex-keys ,,... | define Cortex key + --config-misp | Enable adding MISP configuration + --misp-hostnames ,, ... | Resolve this hostname to find MISP instances (default: misp) + --misp-proto | Define protocol to connect to MISP (default: http) + --misp-port | Define port to connect to MISP ( default: 80) + --misp-keys ,, ... | Define MISP key + --misp-template | Name of the case template in TheHive that shall be used to import MISP events as cases by default (Optional) + --misp-tags ,, ... | Optional tags to add to each observable imported from an event (Optional) + --misp-max-age days | Maximum age of the last publish date of event to be imported in TheHive (Optional) + --misp-exc-orgs ,, ... | List of MISP organisation from which event will not be imported (Optional) + --misp-exc-tags ,, ... | Don't import MISP events which have one of these tags (Optional) + --misp-wh-tags ,, ... | Import only MISP events which have one of these tags (Optional) _EOF_ exit 1 } @@ -68,6 +83,17 @@ do "--cortex-port") shift; CORTEX_PORT=$1 ;; "--cortex-hostnames") shift; CORTEX_HOSTNAMES=$1 ;; "--cortex-keys") shift; CORTEX_KEYS=$1 ;; + "--config-misp") CONFIG_MISP=1 ;; + "--misp-hostnames") shift; MISP_HOSTNAMES=$1 ;; + "--misp-proto") shift; MISP_PROTO=$1 ;; + "--misp-port") shift; MISP_PORT=$1 ;; + "--misp-keys") shift; MISP_KEYS=$1 ;; + "--misp-template") shift; MISP_TEMPLATE=$1 ;; + "--misp-tags") shift; MISP_TAGS=$1 ;; + "--misp-max-age") shift; MISP_AGE=$1 ;; + "--misp-exc-orgs") shift; MISP_EXC_ORG=$1 ;; + "--misp-exc-tags") shift; MISP_EXC_TAGS=$1 ;; + "--misp-wh-tags") shift; MISP_WH_TAGS=$1 ;; "--") STOP=1;; *) usage esac @@ -174,6 +200,78 @@ then fi fi +if [[ $CONFIG_MISP -eq 1 ]];then + declare -a MISP_URLS + IFS=',' read -r -a MH <<< "${MISP_HOSTNAMES}" + IFS=',' read -r -a MK <<< "${MISP_KEYS}" + for M in "${MH[@]}";do + test -n "${M}" && MISP_URLS+=("${MISP_PROTO}://${M}:${MISP_PORT}") + done + if [[ ${#MISP_URLS[@]} -gt 0 ]];then + echo "play.modules.enabled += org.thp.thehive.connector.misp.MispModule" >> ${CONFIG_FILE} + echo "misp.interval = 1 hour" >> ${CONFIG_FILE} + echo "misp.servers = [">> ${CONFIG_FILE} + i=0 + for M in ${MISP_URLS[@]};do + echo "Add MISP n${i} : ${M}" + echo "{" >> ${CONFIG_FILE} + echo "name = \"MISP${i}\"" >> ${CONFIG_FILE} + echo "url = \"${M}\"" >> ${CONFIG_FILE} + echo "auth {" >> ${CONFIG_FILE} + echo "type = key" >> ${CONFIG_FILE} + echo "key = \"${MK[$i]}\"" >> ${CONFIG_FILE} + echo "}" >> ${CONFIG_FILE} + echo "wsConfig {}" >> ${CONFIG_FILE} + +# Optional Config # + # MISP Template # + if [[ -n $MISP_TEMPLATE ]];then + echo "caseTemplate = \"${MISP_TEMPLATE}\"" >> ${CONFIG_FILE} + fi + # MISP Tags # + IFS=',' read -r -a MT <<< ${MISP_TAGS} + if [[ ${#MT[@]} -gt 0 ]];then + for tag in ${MT[@]};do + tags="${tags}\"${tag}\"," + done + echo "tags = [${tags:0:$((${#tags}-1))}]" >> ${CONFIG_FILE} + fi + + # MISP Max-Age # + if [[ -n $MISP_AGE ]];then + echo "max-age = ${MISP_AGE}" >> ${CONFIG_FILE} + fi + + # MISP Exclusion # + IFS=',' read -r -a MEO <<< ${MISP_EXC_ORG} + if [[ ${#MEO[@]} -gt 0 ]];then + for org in ${MEO[@]};do + orgs="${orgs}\"${org}\"," + done + echo "exclusion.organisation = [${orgs:0:$((${#orgs}-1))}]" >> ${CONFIG_FILE} + fi + IFS=',' read -r -a MET <<< ${MISP_EXC_TAGS} + if [[ ${#MET[@]} -gt 0 ]];then + for tag in ${MET[@]};do + etags="${etags}\"${tag}\"," + done + echo "exclusion.tags = [${etags:0:$((${#etags}-1))}]" >> ${CONFIG_FILE} + fi + # MISP Whitelist # + IFS=',' read -r -a MWT <<< ${MISP_WH_TAGS} + if [[ ${#MWT[@]} -gt 0 ]];then + for tag in ${MWT[@]};do + wtags="${wtags}\"${tag}\"," + done + echo "whitelist.tags = [${wtags:0:$((${#wtags}-1))}]" >> ${CONFIG_FILE} + fi + echo "}" >> ${CONFIG_FILE} + i=$((${i}+1)) + done + echo "]" >> ${CONFIG_FILE} + fi +fi + echo "include file(\"secret.conf\")" >> ${CONFIG_FILE} fi From 187b95a8ff9f30f2a72910b71f2256b25997868d Mon Sep 17 00:00:00 2001 From: Kahla Date: Thu, 23 Jul 2020 11:21:50 +0200 Subject: [PATCH 2/3] fixed max-age option --- package/docker/entrypoint | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package/docker/entrypoint b/package/docker/entrypoint index aa00684fe5..7d043d9568 100755 --- a/package/docker/entrypoint +++ b/package/docker/entrypoint @@ -52,7 +52,7 @@ function usage { --misp-keys ,, ... | Define MISP key --misp-template | Name of the case template in TheHive that shall be used to import MISP events as cases by default (Optional) --misp-tags ,, ... | Optional tags to add to each observable imported from an event (Optional) - --misp-max-age days | Maximum age of the last publish date of event to be imported in TheHive (Optional) + --misp-max-age | Maximum age of the last publish date of event to be imported in TheHive in days (Optional) --misp-exc-orgs ,, ... | List of MISP organisation from which event will not be imported (Optional) --misp-exc-tags ,, ... | Don't import MISP events which have one of these tags (Optional) --misp-wh-tags ,, ... | Import only MISP events which have one of these tags (Optional) @@ -239,7 +239,7 @@ if [[ $CONFIG_MISP -eq 1 ]];then # MISP Max-Age # if [[ -n $MISP_AGE ]];then - echo "max-age = ${MISP_AGE}" >> ${CONFIG_FILE} + echo "max-age = ${MISP_AGE} days" >> ${CONFIG_FILE} fi # MISP Exclusion # From 8d0f6e804cfe79af92d022547a593bb21ca5b0f7 Mon Sep 17 00:00:00 2001 From: Kahla Date: Tue, 28 Jul 2020 01:07:23 +0200 Subject: [PATCH 3/3] Added Auth config --- package/docker/entrypoint | 141 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) diff --git a/package/docker/entrypoint b/package/docker/entrypoint index 7d043d9568..f782ed7ac1 100755 --- a/package/docker/entrypoint +++ b/package/docker/entrypoint @@ -24,6 +24,11 @@ CONFIG_MISP=0 MISP_HOSTNAMES="misp" MISP_PROTO="http" MISP_PORT="80" +# Default values for Auth part +CONFIG_AUTH=0 +AUTH_USERHEADER="TheHiveAuth" +AUTH_SSL="false" +AUTH_AUTHHEADER="Bearer " function usage { cat <<- _EOF_ Available options: @@ -56,6 +61,32 @@ function usage { --misp-exc-orgs ,, ... | List of MISP organisation from which event will not be imported (Optional) --misp-exc-tags ,, ... | Don't import MISP events which have one of these tags (Optional) --misp-wh-tags ,, ... | Import only MISP events which have one of these tags (Optional) + --config-auth | Enable adding authentication configuration + --auth-header | Enable header authentication module + --auth-ad | Enable Active Directory authentication module + --auth-ldap | Enable LDAP authentication module + --auth-oauth | Enable Oauth2 authentication module + --auth-userheader
| The name of the header that contain the user login (default: TheHiveAuth) + --auth-windomain | The Windows domain name (ex: MYDOMAIN) + --auth-dnsdomain | The Windows domain name in DNS format (ex: mydomain.local) + --auth-ssl | Indicate if SSL must be used to connect to Domain Dontroller/LDAP server (default: false) + --auth-ad-hosts ,, ... | The addresses of the domain controllers. If missing, the dnsDomain is used. + --auth-binddn | DN of the service account in LDAP. This account is used to search the user. + --auth-bindpw | Password of the service account. + --auth-basedn | DN where the users are located in. + --auth-filter | Filter used to search the user. "{0}" is replaced by the user login. A valid filter is: (&(uid={0})(objectClass=posixAccount)) + --auth-ldap-hosts ,, ... | The addresses of the LDAP servers. + --auth-clientid | Client ID in the OAuth2 server. + --auth-clientsecret | Client secret in the OAuth2 server. + --thehive-url | Url or domain of TheHive (ex: http://www.thehive.com) + --auth-url | The url of the OAuth2 server. + --auth-authheader | Prefix of the authorization header to get user info: Bearer, token, .. (default: Bearer) + --token-url | The token url of the OAuth2 server. + --user-url | The url to get user information in OAuth2 server. + --auth-scope ,, ... | List of scope + --auth-userid | The field that contains the id of the user in user info + --auth-org | The field that contains the organisation name in user info (Optional) + --auth-deforg | The default organisation used to login if not present on user info (Optional) _EOF_ exit 1 } @@ -94,6 +125,32 @@ do "--misp-exc-orgs") shift; MISP_EXC_ORG=$1 ;; "--misp-exc-tags") shift; MISP_EXC_TAGS=$1 ;; "--misp-wh-tags") shift; MISP_WH_TAGS=$1 ;; + "--config-auth") CONFIG_AUTH=1 ;; + "--auth-header") AUTH_HEADER=1 ;; + "--auth-ad") AUTH_AD=1 ;; + "--auth-ldap") AUTH_LDAP ;; + "--auth-oauth") AUTH_OAUTH=1 ;; + "--auth-userheader") shift; AUTH_USERHEADER=$1 ;; + "--auth-windomain") shift; AUTH_WINDOMAIN=$1 ;; + "--auth-dnsdomain") shift; AUTH_DNSDOMAIN=$1 ;; + "--auth-ssl") shift; AUTH_SSL=$1 ;; + "--auth-ad-hosts") shift; AUTH_AD_HOSTS=$1 ;; + "--auth-binddn") shift; AUTH_BINDDN=$1 ;; + "--auth-bindpw") shift; AUTH_BINDPW=$1 ;; + "--auth-basedn") shift; AUTH_BASEDN=$1 ;; + "--auth-filter") shift; AUTH_FILTER=$1 ;; + "--auth-ldap-hosts") shift; AUTH_LDAP_HOSTS=$1 ;; + "--auth-clientid") shift; AUTH_CLIENTID=$1 ;; + "--auth-clientsecret") shift; AUTH_CLIENTSECRET=$1 ;; + "--thehive-url") shift; THEHIVE_URL=$1 ;; + "--auth-url") shift; AUTH_URL=$1 ;; + "--auth-authheader") shift; AUTH_AUTHHEADER=$1 ;; + "--token-url") shift; TOKEN_URL=$1 ;; + "--user-url") shift; USER_URL=$1 ;; + "--auth-scope") shift; AUTH_SCOPE=$1 ;; + "--auth-userid") shift; AUTH_USERID=$1 ;; + "--auth-org") shift; AUTH_ORG=$1 ;; + "--auth-deforg") shift; AUTH_DEFORG=$1 ;; "--") STOP=1;; *) usage esac @@ -148,6 +205,90 @@ then echo "}" >> ${CONFIG_FILE} fi +## Auth Config ## +if [[ $CONFIG_AUTH -eq 1 ]];then + echo "auth.providers = [" >> ${CONFIG_FILE} + echo "{name: session}" >> ${CONFIG_FILE} + echo "{name: basic, realm: thehive}" >> ${CONFIG_FILE} + echo "{name: local}" >> ${CONFIG_FILE} + echo "{name: key}" >> ${CONFIG_FILE} + if [[ $AUTH_HEADER -eq 1 ]];then + echo "{" >> ${CONFIG_FILE} + echo "name = header" >> ${CONFIG_FILE} + echo "Setting Header Authentication and the HeaderName=${AUTH_HEADER}" + echo "userHeader = \"${AUTH_USERHEADER}\"" >> ${CONFIG_FILE} + echo "}" >> ${CONFIG_FILE} + fi + if [[ $AUTH_AD -eq 1 ]];then + echo "{" >> ${CONFIG_FILE} + echo "name = ad" >> ${CONFIG_FILE} + echo "winDomain = \"${AUTH_WINDOMAIN}\"" >> ${CONFIG_FILE} + echo "dnsDomain = \"${AUTH_DNSDOMAIN}\"" >> ${CONFIG_FILE} + echo "useSSL = ${AUTH_SSL}" >> ${CONFIG_FILE} + echo "Using AD Authentication with the domain ${AUTH_WINDOMAIN}" + # Converting hosts to list of strings # + IFS="," read -r -a authhosts <<<"${AUTH_AD_HOSTS}" + if [[ ${#authhosts[@]} -gt 0 ]];then + for host in ${authhosts[@]};do + ahosts="${ahosts}\"${host}\"," + done + echo "hosts = [${ahosts:0:${#ahosts}-1}]" >> ${CONFIG_FILE} + fi + echo "}" >> ${CONFIG_FILE} + fi + if [[ $AUTH_LDAP -eq 1 ]];then + echo "{" >> ${CONFIG_FILE} + echo "name = ldap" >> ${CONFIG_FILE} + echo "bindDN = \"${AUTH_BINDDN}\"" >> ${CONFIG_FILE} + echo "bindPW = \"${AUTH_BINDPW}\"" >> ${CONFIG_FILE} + echo "baseDN = \"${AUTH_BASEDN}\"" >> ${CONFIG_FILE} + echo "filter = \"${AUTH_FILTER}\"" >> ${CONFIG_FILE} + echo "useSSL = ${AUTH_SSL}" >> ${CONFIG_FILE} + # Converting hosts to list of strings # + IFS="," read -r -a authhosts <<<"${AUTH_LDAP_HOSTS}" + if [[ ${#authhosts[@]} -gt 0 ]];then + for host in ${authhosts[@]};do + ahosts="${ahosts}\"${host}\"," + done + echo "hosts = [${ahosts:0:${#ahosts}-1}]" >> ${CONFIG_FILE} + fi + echo "}" >> ${CONFIG_FILE} + fi + if [[ $AUTH_OAUTH -eq 1 ]];then + echo "{" >> ${CONFIG_FILE} + echo "name = oauth2" >> ${CONFIG_FILE} + echo "clientId = \"${AUTH_CLIENTID}\"" >> ${CONFIG_FILE} + echo "clientSecret = \"${AUTH_CLIENTSECRET}\"" >> ${CONFIG_FILE} + echo "redirectUri = \"${THEHIVE_URL}/api/ssoLogin\"" >> ${CONFIG_FILE} + echo "responseType = \"code\"" >> ${CONFIG_FILE} + echo "grantType = \"authorization_code\"" >> ${CONFIG_FILE} + echo "authorizationUrl = \"${AUTH_URL}\"" >> ${CONFIG_FILE} + echo "tokenUrl = \"${TOKEN_URL}\"" >> ${CONFIG_FILE} + echo "userUrl = \"${USER_URL}\"" >> ${CONFIG_FILE} + echo "authorizationHeader = \"${AUTH_AUTHHEADER}\"" >> ${CONFIG_FILE} + # Converting scopes to list of strings # + IFS="," read -r -a authscope <<<"${AUTH_SCOPE}" + if [[ ${#authscope[@]} -gt 0 ]];then + for scope in ${authscope[@]};do + scopes="${scopes}\"${scope}\"," + done + echo "scope = [${scopes:0:${#scopes}-1}]" >> ${CONFIG_FILE} + fi + ### + echo "userIdField = \"${AUTH_USERID}\"" >> ${CONFIG_FILE} + if [[ -n $AUTH_ORG ]];then + echo "organisationField = \"${AUTH_ORG}\"" >> ${CONFIG_FILE} + fi + if [[ -n $AUTH_DEFORG ]];then + echo "defaultOrganisation = \"${AUTH_DEFORG}\"" >> ${CONFIG_FILE} + fi + echo "}" >> ${CONFIG_FILE} + fi + +echo "]" >> ${CONFIG_FILE} +fi +##### + if test "${CONFIG_STORAGE}" = 1 then echo "storage {" >> ${CONFIG_FILE}