天天看點

使用Wazuh和TheHive的開源SIEM解決方案

作者:吉祥莊鋼鐵俠

Wazuh采用多層架構,包括這些主要元件:代理、索引器、儀表闆和中央伺服器。

代理被安裝在每個要監測的系統上,它們收集事件資料、日志和其他系統資訊。代理可以安裝在虛拟(包括雲)和實體機上。

wazuh中央伺服器負責管理代理,遠端配置和更新它們。代理商收集的資料被發送到伺服器,伺服器負責處理和分析資訊,根據預先配置的規則和它的威脅情報引擎尋找入侵點。

然後,資料從伺服器被發送到索引器,索引器負責存儲和索引日志和警報。索引器也是一個可擴充的文本搜尋和分析引擎。

wazuh系統中的每個資料都可以從儀表盤上檢視,這也是管理wazuh元件、建立規則和分析資料的好方法。

Wazuh SIEM還包括一個API,可以與其他安全工具和服務內建,進而實作更全面的安全解決方案。它可以作為一個單節點叢集實施,也可以作為一個分布式解決方案。但在本實驗過程中,我将把Wazuh作為一個單節點叢集使用。

使用Wazuh和TheHive的開源SIEM解決方案

開源解決方案的優勢。

  1. 它們為定制提供了更大的靈活性,因為使用者可以通路源代碼,可以為開發做出貢獻,并修改軟體以适應他們的具體使用情況。
  2. 它們大多是免費使用和分發的;這就使它們成為使用者的成本效益選擇。
  3. 它們通常有一個使用者(開發者)社群的支援,他們為軟體做出貢獻,提供支援,并分享知識。

開源供應商是如何賺錢的。

  1. 進階功能。大多數開放源碼供應商提供免費版軟體所不具備的進階特性和功能;是以他們對這些特性的使用收費。
  2. 付費支援和服務。許多開源供應商提供付費支援和服務,如咨詢、教育訓練和定制,以幫助公司實施和維護軟體。
  3. 雙重許可。一些開放源碼供應商提供雙重或多重許可模式,允許軟體在開放源碼許可和商業許可下可用。這使他們能夠向需要商業許可的企業出售該軟體。

任務1:建立基礎設施

  1. 我使用安裝助手安裝了Wazuh伺服器。關于如何做的詳細步驟見這裡。運作以下指令。
curl -sO https://packages.wazuh.com/4.3/wazuh-install.sh && sudo bash ./wazuh-install.sh -a
           
使用Wazuh和TheHive的開源SIEM解決方案
  1. 現在伺服器已經安裝成功,我使用https://<伺服器的ip>通路它,并使用安裝後提供的初始admnin憑證登入。
使用Wazuh和TheHive的開源SIEM解決方案

裝置1(Windows端點)。

我按照以下步驟在我的windows端點上安裝了wazuh代理。

使用Wazuh和TheHive的開源SIEM解決方案

我重新整理了頁面,我的windows代理被注冊,并在儀表闆上被檢測到是一個代理,如下圖所示。

使用Wazuh和TheHive的開源SIEM解決方案

裝置2(Linux端點)。

我按照這些步驟為我的ubuntu機器重複了上述步驟。

使用Wazuh和TheHive的開源SIEM解決方案

我重新整理了頁面,我的linux代理被注冊了,并在儀表闆上被檢測到是一個代理,如下圖所示。

使用Wazuh和TheHive的開源SIEM解決方案

裝置3(Linux端點)。

我按照裝置2的相同步驟登上了裝置3,這是一台ubuntu機器。

使用Wazuh和TheHive的開源SIEM解決方案

我現在可以檢視所有3個被監控的終端的日志,如下圖所示。

使用Wazuh和TheHive的開源SIEM解決方案
使用Wazuh和TheHive的開源SIEM解決方案

為什麼我可以檢視日志? 我可以檢視這些日志,因為安裝在端點上的wazuh代理從機器上收集日志,并将其發送到wazuh中央伺服器(管理器),後者分析日志并根據配置的規則集運作,包括威脅情報。然後,日志被發送到索引器,存儲在索引中以便于查詢。然後我可以從索引器中查詢日志,并使用wazuh儀表闆進行分析,如上文圖1.8所示。

可見日志的解釋

日志1:這是一個從windows伺服器端點記錄的windows登入成功事件。如果前面的事件是暴力攻擊的名額,如多次失敗的登入嘗試,這個事件可以作為防禦規避、特權更新和成功的暴力攻擊的名額。

在windows機器上,登入成功被登記為安全事件日志。如前所述,Wazuh代理會将這些日志發送到Wazuh核心結構之上。如圖2.8所示,你可以确定機器的IP位址和其他相關細節,以幫助分析日志資料。

由分析員在檢視了前面的日志後确定這是否是成功入侵的名額。

使用Wazuh和TheHive的開源SIEM解決方案

日志2:這是我的一個Linux端點的登入失敗。如果在很短的時間内反複出現失敗,這也可以作為企圖入侵的一個名額。linux機器将該事件注冊為日志,并将其儲存在/var/log/auth.log中,由wazuh代理收集并運送到wazuh中央結構進行分析和展示。

它也可能是一個假陽性(一個合法的使用者可能忘記了登入細節)。

使用Wazuh和TheHive的開源SIEM解決方案

任務2:阻止惡意的IP位址

設定Wazuh代理。

  1. 為了開始阻止惡意的IP位址,我在裝置3上使用以下指令安裝了Nginx。
sudo apt install nginx
           
使用Wazuh和TheHive的開源SIEM解決方案
  1. 我測試了一下,我可以從我的IP位址為10.1.1.42的 "惡意機器 "用curl到達伺服器。
使用Wazuh和TheHive的開源SIEM解決方案
  1. 為了讓wazuh代理監控Nginx日志,我在/var/ossec/etc/ossec.conf檔案中添加了以下配置,并使用sudo systemctl重新開機wazuh-agent,重新啟動了wazuh代理。
<localfile>
    <log_format>syslog</log_format>
  <location>/var/log/nginx/access.log</location>
</localfile>
           

設定Wazuh伺服器。

  1. 我下載下傳了Alienvault的IP信譽資料庫,并使用以下指令将其輸出到檔案/var/ossec/etc/lists/alienvault_reputation.ipset中。
sudo wget https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/alienvault_reputation.ipset -O /var/ossec/etc/lists/alienvault_reputation.ipset
           
  1. 然後我用下面的指令将攻擊機器的IP輸入到Alienvault的IP信譽資料庫中。
sudo echo "10.1.1.42" >> /var/ossec/etc/lists/alienvault_reputation.ipset
           
使用Wazuh和TheHive的開源SIEM解決方案

圖3.2: 在信譽資料庫中添加惡意IP。

  1. 我從wazuh下載下傳了一個腳本,用以下指令将.ipset格式轉換為.cdb。
sudo wget https://wazuh.com/resources/iplist-to-cdblist.py -O /tmp/iplist-to-cdblist.py
           
  1. 然後我用之前下載下傳的腳本将之前建立的 alienvault_reputation.ipset 檔案轉換為 .cdb 格式。下面的指令完成了轉換。
sudo /var/ossec/framework/python/bin/python3 /tmp/iplist-to-cdblist.py /var/ossec/etc/lists/alienvault_reputation.ipset /var/ossec/etc/lists/blacklist-alienvault
           
  1. 由于我不再需要 alienvault_reputation.ipset 檔案和 iplist-to-cdblist.py 腳本,我用以下指令丢棄了它們。
sudo rm -rf /var/ossec/etc/lists/alienvault_reputation.ipset
sudo rm -rf /tmp/iplist-to-cdblist.py
           
  1. 我用下面的指令給了wazuh足夠的權限給新的和轉換的/var/ossec/etc/lists/blacklist-alienvault檔案。
sudo chown wazuh:wazuh /var/ossec/etc/lists/blacklist-alienvault
           
  1. 成功完成上述程式後,我繼續配置Wazuh的主動響應子產品,阻止 "惡意IP"
  2. 我在/var/ossec/etc/rules/local_rules.xml檔案中建立了一個自定義規則,以觸發主動響應腳本,規則嚴重程度為12級。自定義規則集如下。
<group name="attack,">
    <rule id="100100" level="12">
          <if_group>web|attack|attacks</if_group>
    <list field="srcip" lookup="address_match_key">etc/lists/blacklist-alienvault</list>
    <description>IP address found in AlienVault reputation database.</description>
  </rule>
</group>
           
使用Wazuh和TheHive的開源SIEM解決方案
  1. 我編輯了wazuh伺服器上的/var/ossec/etc/ossec.conf檔案,并在規則集部分建立了一個etc/lists/blacklist-alienvault清單。
使用Wazuh和TheHive的開源SIEM解決方案
  1. 我編輯了/var/ossec/etc/ossec.conf檔案的主動響應部分,確定來自攻擊者機器的流量被丢棄300秒,如下圖3.5所示。
使用Wazuh和TheHive的開源SIEM解決方案
  1. 在攻擊者的機器上進行的快速測試表明,第一次curl測試是成功的,但随後5分鐘内的curl操作是不成功的。
使用Wazuh和TheHive的開源SIEM解決方案
  1. 我也能在我的wazuh儀表闆上檢測到該事件,如以下圖檔所示。
使用Wazuh和TheHive的開源SIEM解決方案
使用Wazuh和TheHive的開源SIEM解決方案
使用Wazuh和TheHive的開源SIEM解決方案

任務3:模拟蠻力攻擊檢測

我通過在短時間内通過ssh和rdp會話輸入錯誤的憑證,模拟了對所有3個端點的暴力攻擊。在這次模拟中,我使用了一個帶有使用者名的無效憑證攻擊者。

下面的圖檔顯示了在我的SIEM儀表闆上對攻擊的檢測。

  1. 我在安全事件儀表闆上發現認證失敗的數量增加了。
使用Wazuh和TheHive的開源SIEM解決方案

作為一個分析員,這應該引起注意,不僅是因為其嚴重程度,而且是因為其在短時間内的頻率。這可能是來自Hydra等自動化工具的暴力攻擊的一個名額。

  1. 我鑽研了一下,通過探索安全警報來确定認證失敗激增的根本原因。我發現在很短的時間内,我的基礎設施内的主機出現了多次一緻的登入失敗。
使用Wazuh和TheHive的開源SIEM解決方案
  1. 我進一步分析了其中一個顯示攻擊的日志,我可以檢測到登入會話來自一個遠端IP 10.1.1.100,有一個不存在的使用者攻擊者。這些嘗試的一緻性是一個明顯的暴力嘗試名額,可以通過使用網絡保護裝置或該節點上的wazuh代理阻止攻擊者的IP來暫時補救,這可以通過遵循本指南實作。

一個更持久的修複方法是審查IAM政策,以進一步加強基礎設施。

使用Wazuh和TheHive的開源SIEM解決方案

配置電子郵件或Slack通道警報也可以用來檢測此類警報,方法是為規則的嚴重程度設定警報,或調整規則的嚴重程度,使其與預設電子郵件警報的最低門檻值相比對。

任務4:SOC整合(将theHive與Wazuh整合)。

  1. 為了開始實施,我決定使用容器版的theHive。我運作了以下docker指令來運作最新版本的theHive。
sudo docker run -d --rm -p 9000:9000 strangebee/thehive:latest
           
  1. 我登入到蜂巢,建立了一個組織,如下圖5.0所示。
使用Wazuh和TheHive的開源SIEM解決方案
  1. 我在組織中添加了一個新的管理使用者,具有完全的管理權限,如下圖所示。
使用Wazuh和TheHive的開源SIEM解決方案

我還建立了更多的使用者,如老闆和分析師,并将他們加入到組織中,以便有一個更好的模拟。

  1. 我為先前建立的使用者賬戶生成了一個API密鑰,并複制了它。
使用Wazuh和TheHive的開源SIEM解決方案
  1. 我繼續配置Wazuh管理器,首先用下面的指令安裝Hive python子產品。
sudo /var/ossec/framework/python/bin/pip3 install thehive4py==1.8.1
           
  1. 我在/var/ossec/integrations/custom-w2thive.py檔案中粘貼了以下python腳本,以便建立一個自定義的內建腳本。
#!/var/ossec/framework/python/bin/python3
import json
import sys
import os
import re
import logging
import uuid
from thehive4py.api import TheHiveApi
from thehive4py.models import Alert, AlertArtifact

# start user config
# Global vars

#threshold for wazuh rules level
lvl_threshold=0
#threshold for suricata rules level
suricata_lvl_threshold=3
debug_enabled = False
#info about created alert
info_enabled = True
#end user config
# Set paths
pwd = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
log_file = '{0}/logs/integrations.log'.format(pwd)
logger = logging.getLogger(__name__)
#set logging level
logger.setLevel(logging.WARNING)
if info_enabled:
      logger.setLevel(logging.INFO)
if debug_enabled:
      logger.setLevel(logging.DEBUG)
# create the logging file handler
fh = logging.FileHandler(log_file)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
logger.addHandler(fh)

def main(args):
    logger.debug('#start main')
    logger.debug('#get alert file location')
    alert_file_location = args[1]
    logger.debug('#get TheHive url')
    thive = args[3]
    logger.debug('#get TheHive api key')
    thive_api_key = args[2]
    thive_api = TheHiveApi(thive, thive_api_key )
    logger.debug('#open alert file')
    w_alert = json.load(open(alert_file_location))
    logger.debug('#alert data')
    logger.debug(str(w_alert))
    logger.debug('#gen json to dot-key-text')
    alt = pr(w_alert,'',[])
    logger.debug('#formatting description')
    format_alt = md_format(alt)
    logger.debug('#search artifacts')
    artifacts_dict = artifact_detect(format_alt)
    alert = generate_alert(format_alt, artifacts_dict, w_alert)
    logger.debug('#threshold filtering')
    if w_alert['rule']['groups']==['ids','suricata']:
            #checking the existence of the data.alert.severity field
                    if 'data' in w_alert.keys():
                                if 'alert' in w_alert['data']:
                                                #checking the level of the source event
                                                                if int(w_alert['data']['alert']['severity'])<=suricata_lvl_threshold:
                                                                                    send_alert(alert, thive_api)
    elif int(w_alert['rule']['level'])>=lvl_threshold:
            #if the event is different from suricata AND suricata-event-type: alert check lvl_threshold
                    send_alert(alert, thive_api)

def pr(data,prefix, alt):
    for key,value in data.items():
            if hasattr(value,'keys'):
                        pr(value,prefix+'.'+str(key),alt=alt)
        else:
                    alt.append((prefix+'.'+str(key)+'|||'+str(value)))
    return alt

def md_format(alt,format_alt=''):
    md_title_dict = {}
    #sorted with first key
        for now in alt:
                now = now[1:]
        #fix first key last symbol
                dot = now.split('|||')[0].find('.')
        if dot==-1:
                    md_title_dict[now.split('|||')[0]] =[now]
        else:
                    if now[0:dot] in md_title_dict.keys():
                                    (md_title_dict[now[0:dot]]).append(now)
            else:
                            md_title_dict[now[0:dot]]=[now]
    for now in md_title_dict.keys():
            format_alt+='### '+now.capitalize()+'\n'+'| key | val |\n| ------ | ------ |\n'
        for let in md_title_dict[now]:
                    key,val = let.split('|||')[0],let.split('|||')[1]
            format_alt+='| **' + key + '** | ' + val + ' |\n'
    return format_alt

def artifact_detect(format_alt):
    artifacts_dict = {}
    artifacts_dict['ip'] = re.findall(r'\d+\.\d+\.\d+\.\d+',format_alt)
    artifacts_dict['url'] =  re.findall(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+',format_alt)
    artifacts_dict['domain'] = []
    for now in artifacts_dict['url']: artifacts_dict['domain'].append(now.split('//')[1].split('/')[0])
    return artifacts_dict

def generate_alert(format_alt, artifacts_dict,w_alert):
    #generate alert sourceRef
        sourceRef = str(uuid.uuid4())[0:6]
    artifacts = []
    if 'agent' in w_alert.keys():
            if 'ip' not in w_alert['agent'].keys():
                        w_alert['agent']['ip']='no agent ip'
    else:
            w_alert['agent'] = {'id':'no agent id', 'name':'no agent name'}
    for key,value in artifacts_dict.items():
            for val in value:
                        artifacts.append(AlertArtifact(dataType=key, data=val))
    alert = Alert(title=w_alert['rule']['description'],
                                tlp=2,
                                tags=['wazuh', 
                                                    'rule='+w_alert['rule']['id'], 
                                                    'agent_name='+w_alert['agent']['name'],
                                                    'agent_id='+w_alert['agent']['id'],
                                                    'agent_ip='+w_alert['agent']['ip'],],
                                description=format_alt ,
                                type='wazuh_alert',
                                source='wazuh',
                                sourceRef=sourceRef,
                                artifacts=artifacts,)
    return alert

def send_alert(alert, thive_api):
    response = thive_api.create_alert(alert)
    if response.status_code == 201:
            logger.info('Create TheHive alert: '+ str(response.json()['id']))
    else:
            logger.error('Error create TheHive alert: {}/{}'.format(response.status_code, response.text))

if __name__ == "__main__":
    try:
           logger.debug('debug mode') # if debug enabled       
                  # Main function
       main(sys.argv)
    except Exception:
       logger.exception('EGOR')ssec/integrations/custom-w2thive
           
  1. 我建立了一個bash腳本來執行先前在這個檔案/var/ossec/integrations/custom-w2thive中建立的python腳本。
#!/bin/sh
# Copyright (C) 2015-2020, Wazuh Inc.
# Created by Wazuh, Inc. <[email protected]>.
# This program is free software; you can redistribute it and/or modify it under the terms of GP>
  
  WPYTHON_BIN="framework/python/bin/python3"
SCRIPT_PATH_NAME="$0"
DIR_NAME="$(cd $(dirname ${SCRIPT_PATH_NAME}); pwd -P)"
SCRIPT_NAME="$(basename ${SCRIPT_PATH_NAME})"
case ${DIR_NAME} in
      */active-response/bin | */wodles*)
        if [ -z "${WAZUH_PATH}" ]; then
                    WAZUH_PATH="$(cd ${DIR_NAME}/../..; pwd)"
        fi
            PYTHON_SCRIPT="${DIR_NAME}/${SCRIPT_NAME}.py"
    ;;
    */bin)
    if [ -z "${WAZUH_PATH}" ]; then
            WAZUH_PATH="$(cd ${DIR_NAME}/..; pwd)"
    fi
        PYTHON_SCRIPT="${WAZUH_PATH}/framework/scripts/${SCRIPT_NAME}.py"
    ;;
     */integrations)
        if [ -z "${WAZUH_PATH}" ]; then
                    WAZUH_PATH="$(cd ${DIR_NAME}/..; pwd)"
        fi
            PYTHON_SCRIPT="${DIR_NAME}/${SCRIPT_NAME}.py"
    ;;
esac

${WAZUH_PATH}/${WPYTHON_BIN} ${PYTHON_SCRIPT} $@
           
  1. 為了使wazuh成功運作內建腳本,我在wazuh管理器的confi檔案/var/ossec/etc/ossec.conf中加入了以下幾行。我還輸入了IP位址、端口和之前生成的API密鑰。
<ossec_config>
  …
  <integration>
      <name>custom-w2thive</name>
    <hook_url>http://10.1.1.34:9000</hook_url>    
        <api_key>bs+UW9HBLkDbw4tHeiAwQw413El3qO4W</api_key>
    <alert_format>json</alert_format>
  </integration>
…
</ossec_config>
           
  1. 我用sudo systemctl重新啟動了wazuh-manager服務。
  2. 為了測試theHive是否在接收日志,我以其中一個使用者的身份登入,我可以看到所有建立的案例,并對它們進行深入研究,以及配置設定給組織内的使用者。
使用Wazuh和TheHive的開源SIEM解決方案
使用Wazuh和TheHive的開源SIEM解決方案
使用Wazuh和TheHive的開源SIEM解決方案

繼續閱讀