PyMISP icon indicating copy to clipboard operation
PyMISP copied to clipboard

MISP integration with WAZUH

Open alidhehibi opened this issue 2 years ago • 3 comments

Hi Community I'm integrating MISP with WAZUH I did all the necessary configuration on the files: -Ossec.conf: on wazuh server -misp.xml: new rule on the wazuh server -custom-misp.py: on the integrations folder of the server After testing a windows client (Dns query) I got the alert on wazuh server through Sysmon, unfortunately, there is no feedback from MISP You find below my configuration for each file your help would be much appreciated Custom-misp.py #!/var/ossec/framework/python/bin/python3

MISP API Integration

import sys import os from socket import socket, AF_UNIX, SOCK_DGRAM from datetime import date, datetime, timedelta import time import requests from requests.exceptions import ConnectionError import json import ipaddress import hashlib import re pwd = os.path.dirname(os.path.dirname(os.path.realpath(file))) socket_addr = '{0}/queue/sockets/queue'.format(pwd) def send_event(msg, agent = None): if not agent or agent["id"] == "000": string = '1:misp:{0}'.format(json.dumps(msg)) else: string = '1:[{0}] ({1}) {2}->misp:{3}'.format(agent["id"], agent["name"], agent["ip"] if "ip" in agent else "any", json.dumps(msg)) sock = socket(AF_UNIX, SOCK_DGRAM) sock.connect(socket_addr) sock.send(string.encode()) sock.close() false = False

Read configuration parameters

alert_file = open(sys.argv[1])

Read the alert file

alert = json.loads(alert_file.read()) alert_file.close()

New Alert Output if MISP Alert or Error calling the API

alert_output = {}

MISP Server Base URL

misp_base_url = "https://172.16.1.101/attributes/restSearch/"

MISP Server API AUTH KEY

misp_api_auth_key = "*Your API Key"

API - HTTP Headers

misp_apicall_headers = {"Content-Type":"application/json", "Authorization":f"{misp_api_auth_key}", "Accept":"application/json"}

Extract Sysmon for Windows/Sysmon for Linux and Sysmon Event ID

event_source = alert["rule"]["groups"][0] event_type = alert["rule"]["groups"][2]

Regex Pattern used based on SHA256 lenght (64 characters)

regex_file_hash = re.compile('\w{64}') if event_source == 'windows': if event_type == 'sysmon_event1': try: wazuh_event_param = regex_file_hash.search(alert["data"]["win"]["eventdata"]["hashes"]).group(0) except IndexError: sys.exit() elif event_type == 'sysmon_event3' and alert["data"]["win"]["eventdata"]["destinationIsIpv6"] == 'false': try: dst_ip = alert["data"]["win"]["eventdata"]["destinationIp"] if ipaddress.ip_address(dst_ip).is_global: wazuh_event_param = dst_ip else: sys.exit() except IndexError: sys.exit() elif event_type == 'sysmon_event3' and alert_output["data"]["win"]["eventdata"]["destinationIsIpv6"] == 'true': sys.exit() elif event_type == 'sysmon_event6': try: wazuh_event_param = regex_file_hash.search(alert["data"]["win"]["eventdata"]["hashes"]).group(0) except IndexError: sys.exit() elif event_type == 'sysmon_event7': try: wazuh_event_param = regex_file_hash.search(alert["data"]["win"]["eventdata"]["hashes"]).group(0) except IndexError: sys.exit() elif event_type == 'sysmon_event_15': try: wazuh_event_param = regex_file_hash.search(alert["data"]["win"]["eventdata"]["hashes"]).group(0) except IndexError: sys.exit() elif event_type == 'sysmon_event_22': try: wazuh_event_param = alert["data"]["win"]["eventdata"]["queryName"] except IndexError: sys.exit() elif event_type == 'sysmon_event_23': try: wazuh_event_param = regex_file_hash.search(alert["data"]["win"]["eventdata"]["hashes"]).group(0) except IndexError: sys.exit() elif event_type == 'sysmon_event_24': try: wazuh_event_param = regex_file_hash.search(alert["data"]["win"]["eventdata"]["hashes"]).group(0) except IndexError: sys.exit() elif event_type == 'sysmon_event_25': try: wazuh_event_param = regex_file_hash.search(alert["data"]["win"]["eventdata"]["hashes"]).group(0) except IndexError: sys.exit() else: sys.exit() misp_search_value = "value:"f"{wazuh_event_param}" misp_search_url = ''.join([misp_base_url, misp_search_value]) try: misp_api_response = requests.get(misp_search_url, headers=misp_apicall_headers, verify=False) except ConnectionError: alert_output["misp"] = {} alert_output["integration"] = "misp" alert_output["misp"]["error"] = 'Connection Error to MISP API' send_event(alert_output, alert["agent"]) else: misp_api_response = misp_api_response.json() # Check if response includes Attributes (IoCs) if (misp_api_response["response"]["Attribute"]): # Generate Alert Output from MISP Response alert_output["misp"] = {} alert_output["misp"]["source"] = {} alert_output["misp"]["event_id"] = misp_api_response["response"]["Attribute"][0]["event_id"] alert_output["misp"]["category"] = misp_api_response["response"]["Attribute"][0]["category"] alert_output["misp"]["value"] = misp_api_response["response"]["Attribute"][0]["value"] alert_output["misp"]["type"] = misp_api_response["response"]["Attribute"][0]["type"] alert_output["misp"]["source"]["description"] = alert["rule"]["description"] send_event(alert_output, alert["agent"]) elif event_source == 'linux': if event_type == 'sysmon_event3' and alert["data"]["eventdata"]["destinationIsIpv6"] == 'false': try: dst_ip = alert["data"]["eventdata"]["DestinationIp"] if ipaddress.ip_address(dst_ip).is_global: wazuh_event_param = dst_ip misp_search_value = "value:"f"{wazuh_event_param}" misp_search_url = ''.join([misp_base_url, misp_search_value]) try: misp_api_response = requests.get(misp_search_url, headers=misp_apicall_headers, verify=False) except ConnectionError: alert_output["misp"] = {} alert_output["integration"] = "misp" alert_output["misp"]["error"] = 'Connection Error to MISP API' send_event(alert_output, alert["agent"]) else: misp_api_response = misp_api_response.json() # Check if response includes Attributes (IoCs) if (misp_api_response["response"]["Attribute"]): # Generate Alert Output from MISP Response alert_output["misp"] = {} alert_output["misp"]["event_id"] = misp_api_response["response"]["Attribute"][0]["event_id"] alert_output["misp"]["category"] = misp_api_response["response"]["Attribute"][0]["category"] alert_output["misp"]["value"] = misp_api_response["response"]["Attribute"][0]["value"] alert_output["misp"]["type"] = misp_api_response["response"]["Attribute"][0]["type"] send_event(alert_output, alert["agent"]) else: sys.exit() except IndexError: sys.exit() else: sys.exit() elif event_source == 'ossec' and event_type == "syscheck_entry_added": try: wazuh_event_param = alert["syscheck"]["sha256_after"] except IndexError: sys.exit() misp_search_value = "value:"f"{wazuh_event_param}" misp_search_url = ''.join([misp_base_url, misp_search_value]) try: misp_api_response = requests.get(misp_search_url, headers=misp_apicall_headers, verify=false) except ConnectionError: alert_output["misp"] = {} alert_output["integration"] = "misp" alert_output["misp"]["error"] = 'Connection Error to MISP API' send_event(alert_output, alert["agent"]) else: misp_api_response = misp_api_response.json() # Check if response includes Attributes (IoCs) if (misp_api_response["response"]["Attribute"]): # Generate Alert Output from MISP Response alert_output["misp"] = {} alert_output["misp"]["event_id"] = misp_api_response["response"]["Attribute"][0]["event_id"] alert_output["misp"]["category"] = misp_api_response["response"]["Attribute"][0]["category"] alert_output["misp"]["value"] = misp_api_response["response"]["Attribute"][0]["value"] alert_output["misp"]["type"] = misp_api_response["response"]["Attribute"][0]["type"] send_event(alert_output, alert["agent"]) else: sys.exit() Block added to ossec.config custom-misp.py sysmon_event1,sysmon_event3,sysmon_event6,sysmon_event7,sysmon_event_15,sysmon_event_22,syscheck <alert_format>json</alert_format> The file: MISP.XML misp misp MISP Events no_full_log <if_sid>100620</if_sid> .+ MISP - Error connecting to API no_full_log misp_error, .+ MISP - IoC found in Threat Intel - Category: $(misp.category), Attribute: $(misp.value) no_full_log misp_alert, image

alidhehibi avatar Sep 02 '22 16:09 alidhehibi

I edited your issue to display your code as a script because that was wholly unintelligible.

I have no idea what wazuh is, so I'm not sure I can help much on that. Also, you're not using PyMISP. Can you please use PyMISP and be more specific on what you're trying to do?

Rafiot avatar Sep 04 '22 12:09 Rafiot

also i have same issue......."MISP : Error connecting to API" Even i have checked my base URL and Auth key was properly configure with wazuh from all admin privillege...

vaibhavvvv avatar Apr 11 '24 11:04 vaibhavvvv

Okay. My answer above still stands.

Rafiot avatar Apr 11 '24 11:04 Rafiot