Mimecast is an email security and management platform that protects emails against cyber threats such as malware, phishing, and spam. Email remains one of the most prevalent attack vectors for cybercriminals seeking to infiltrate organizations and spread malware. Its widespread use makes it a top target for various malicious activities. Mimecast provides organizations with features like email filtering, data loss prevention (DLP), encryption, and archiving.
Wazuh is a free and open source SIEM and XDR platform that offers protection against security threats for various platforms including virtualized, cloud, and containerized environments.
In this blog post, we show the integration of Mimecast with Wazuh. This offers security analysts enhanced visibility into email-related threats by creating custom rules to alert on events of interest and show trends in certain malicious activities.
Requirements
We use the following infrastructure to demonstrate the integration of Mimecast with Wazuh:
- Wazuh 4.7.4 central components (Wazuh server, Wazuh indexer, Wazuh dashboard) installed using the Quickstart guide on an Ubuntu server.
- A Mimecast workspace and a user with administrator privileges to create API credentials.
Configuration
Follow the steps below to integrate Mimecast with Wazuh.
Mimecast web user interface
Enable logging
Follow the steps below to enable logging for your organization on your Mimecast account.
1. Login into the Mimecast administration console and navigate to Administration > Account > Account Settings to display the Account Settings page.
2. Select Enhanced Logging.
3. Select the types of logs you want to enable. The choices are:
- Inbound – logs for messages from external senders to internal recipients.
- Outbound – logs for messages from internal senders to external recipients.
- Internal – logs for messages between internal domains.
4. Select Save to apply the changes.
Once these settings are saved, Mimecast will start logging email transactions in your organization.
Note: It might take up to 30 minutes before the logs become available.
Configuring authentication and authorization
Mimecast provides the /api/audit/get-siem-logs
API endpoint to facilitate the download of logs. Follow the Mimecast documentation on Authentication (Scripts and Server Apps) to generate the following values required to authenticate to the /api/audit/get-siem-logs
API endpoint:
- APPLICATION_ID: The unique ID that identifies the application created in the Mimecast web user interface to pull logs from your account.
- APPLICATION_KEY: A secret used to authenticate and authorize the created application.
- ACCESS_KEY: The unique identifier that specifies the API user created in your mimecast account.
- SECRET_KEY: This is a shared secret between the script and the Mimecast authorization server.
Wazuh server
The following steps describe how to create a script that retrieves logs from the Mimecast API endpoint. We also create custom decoders and rules to trigger alerts when events of interest are captured by Mimecast.
Follow the steps below to configure the Wazuh server for log collection from Mimecast.
1. Create a Python script at /var/ossec/integrations/mimecast.py
to connect to the Mimecast API and retrieve logs. The file /var/log/mimecast/mimecast.log
is created upon execution of the script to store the retrieved Mimecast logs.
Replace the <APPLICATION_ID>
, <APPLICATION_KEY>
, <ACCESS_KEY>
, <BASE_URL>
, and <SECRET_KEY>
variables with the appropriate values retrieved in configuring authentication and authorization above.
The <BASE_URL>
refers to your Mimecast region, for example, https://eu-api.mimecast.com
for the EU region. Visit the Global Base URLs reference guide for a list of Mimecast URLs.
Warning: We recommend you use a secret management solution to store the value of the variables instead of hardcoding them in the script.
#!/usr/bin/env python # -*- coding: utf-8 -*- #Mimecast SIEM logs download import logging.handlers import json import os import requests import base64 import uuid import datetime import hashlib import shutil import hmac import time from zipfile import ZipFile import io from logging.handlers import RotatingFileHandler # Set up variables APP_ID = "<APPLICATION_ID>" APP_KEY = "<APPLICATION_KEY>" ACCESS_KEY = '<ACCESS_KEY>' SECRET_KEY = '<SECRET_KEY>' base_url = "<BASE_URL>" LOG_FILE_PATH = "/var/log/mimecast/log" CHK_POINT_DIR = '/var/log/mimecast' URI = "/api/audit/get-siem-logs" # delete files after fetching delete_files = False # Set threshold in number of files in log file directory log_file_threshold = 105 # Set up logging log = logging.getLogger(__name__) log.root.setLevel(logging.DEBUG) log_formatter = logging.Formatter('%(levelname)s %(message)s') log_handler = logging.StreamHandler() log_handler.setFormatter(log_formatter) log.addHandler(log_handler) # Supporting methods def rotate_file_if_needed(file_path, max_size_bytes): if os.path.exists(file_path): file_size = os.path.getsize(file_path) if file_size >= max_size_bytes: base_dir = os.path.dirname(file_path) base_name = os.path.basename(file_path) file_name, file_ext = os.path.splitext(base_name) new_file_name = f"{file_name}_1{file_ext}" new_file_path = os.path.join(base_dir, new_file_name) shutil.move(file_path, new_file_path) log.info(f"Rotated file: {file_path} -> {new_file_path}") else: log.warning(f"File not found: {file_path}") def get_hdr_date(): return datetime.datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S UTC") def read_file(file_name): try: with open(file_name, 'r') as f: data = f.read() return data except Exception as e: log.error('Error reading file ' + file_name + '. Cannot continue. Exception: ' + str(e)) quit() def write_file(file_name, data_to_write): if '.zip' in file_name: try: byte_content = io.BytesIO(data_to_write) zip_file = ZipFile(byte_content) zip_file.extractall(LOG_FILE_PATH) except Exception as e: log.error('Error writing file ' + file_name + '. Cannot continue. Exception: ' + str(e)) quit() else: try: with open(file_name, 'w') as f: f.write(data_to_write) except Exception as e: log.error('Error writing file ' + file_name + '. Cannot continue. Exception: ' + str(e)) quit() def post_request(base_url, uri, post_body, access_key, secret_key): request_id = str(uuid.uuid4()) request_date = get_hdr_date() unsigned_auth_header = '{date}:{req_id}:{uri}:{app_key}'.format( date=request_date, req_id=request_id, uri=uri, app_key=APP_KEY ) hmac_sha1 = hmac.new( base64.b64decode(secret_key), unsigned_auth_header.encode(), digestmod=hashlib.sha1).digest() sig = base64.encodebytes(hmac_sha1).rstrip() headers = { 'Authorization': 'MC ' + access_key + ':' + sig.decode(), 'x-mc-app-id': APP_ID, 'x-mc-date': request_date, 'x-mc-req-id': request_id, 'Content-Type': 'application/json' } try: log.debug('Sending request to ' + base_url + uri + ' with request Id: ' + request_id) r = requests.post(url=base_url + uri, data=json.dumps(post_body), headers=headers) if r.status_code == 429: log.warning('Rate limit hit. Sleeping for ' + str(r.headers['X-RateLimit-Reset'] * 1000)) time.sleep(r.headers['X-RateLimit-Reset'] * 1000) r = requests.post(url=base_url + uri, data=json.dumps(post_body), headers=headers) except Exception as e: log.error('Unexpected error connecting to API. Exception: ' + str(e)) return 'error' if r.status_code != 200: log.error('Request to ' + uri + ' with , request id: ' + request_id + ' returned with status code: ' + str(r.status_code) + ', response body: ' + r.text) return 'error' return r.content, r.headers def get_mta_siem_logs(checkpoint_dir, base_url, access_key, secret_key, now): uri = "/api/audit/get-siem-logs" checkpoint_filename = os.path.join(checkpoint_dir, 'get_mta_siem_logs_checkpoint') post_body = dict() post_body['data'] = [{}] post_body['data'][0]['type'] = 'MTA' post_body['data'][0]['compress'] = True if os.path.exists(checkpoint_filename): post_body['data'][0]['token'] = read_file(checkpoint_filename) resp = post_request(base_url, uri, post_body, access_key, secret_key) if resp != 'error': resp_body = resp[0] resp_headers = resp[1] content_type = resp_headers['Content-Type'] if content_type == 'application/json': log.info('No more logs available') return False elif content_type == 'application/octet-stream': file_name = resp_headers['Content-Disposition'].split('=\"') file_name = file_name[1][:-1] write_file(os.path.join(LOG_FILE_PATH, file_name), resp_body) write_file(checkpoint_filename, resp_headers['mc-siem-token']) return True else: log.error('Unexpected response') for header in resp_headers: log.error(header) return False def run_script(): try: log.info('Getting MTA log data') # Rotate merged log file if needed before downloading new logs rotate_file_if_needed(os.path.join(LOG_FILE_PATH, 'mimecast.log'), 5242880) get_mta_siem_logs(checkpoint_dir=CHK_POINT_DIR, base_url=base_url, access_key=ACCESS_KEY, secret_key=SECRET_KEY, now=time.time()) except Exception as e: log.error('Unexpected error getting MTA logs ' + str(e)) files = [os.path.join(LOG_FILE_PATH, f) for f in os.listdir(LOG_FILE_PATH)] files.sort(key=os.path.getctime) if delete_files or len(files) >= log_file_threshold: num_files_to_delete = len(files) - log_file_threshold for i in range(num_files_to_delete): try: os.unlink(files[i]) except Exception as e: log.error('Failed to delete file {}. Reason: {}'.format(files[i], e)) continue merged_file_path = os.path.join(LOG_FILE_PATH, 'mimecast.log') with open(merged_file_path, 'a') as merged_file: for filename in os.listdir(LOG_FILE_PATH): if filename.endswith('.siem') and filename != 'mimecast.log': file_path = os.path.join(LOG_FILE_PATH, filename) try: with open(file_path, 'r') as log_file: for line in log_file: merged_file.write(line) except Exception as e: log.error('Failed to merge log file {}. Reason: {}'.format(file_path, e)) os.remove(file_path) run_script()
2. Set the ownership and permissions for the /var/ossec/integrations/mimecast.py
file. This ensures the script is only available to the root
user and wazuh
group by granting them full permissions, read and execute access respectively:
# chown root:wazuh /var/ossec/integrations/mimecast.py # chmod 750 /var/ossec/integrations/mimecast.py
3. Add the following configuration to the <ossec_config>
block of the /var/ossec/etc/ossec.conf
local configuration file to automate the execution of the script. We also configure the Wazuh Logcollector module to monitor the /var/log/mimecast/log/mimecast.log
file for new logs:
<wodle name="command"> <disabled>no</disabled> <command>/var/ossec/framework/python/bin/python3 /var/ossec/integrations/mimecast.py</command> <interval>5m</interval> <ignore_output>yes</ignore_output> <run_on_start>yes</run_on_start> <timeout>120</timeout> </wodle> <localfile> <log_format>syslog</log_format> <location>/var/log/mimecast/log/mimecast.log</location> </localfile>
Note: The <interval>
tag specifies the interval between execution of the script.
If you already have logs enabled on your Mimecast account, the script will retrieve the earliest available logs on your account. Mimecast keeps your logs for up to 7 days.
Custom decoders
1. Create a decoder file /var/ossec/etc/decoders/mimecast_decoders.xml
and add the following decoders:
<!-- Mimecast SIEM Logs --> <decoder name="mimecast"> <prematch type="pcre2">datetime=.*\|aCode=</prematch> </decoder> <decoder name="mimecast"> <prematch type="pcre2">datetime=.*\|acc=</prematch> </decoder> <decoder name="mimecast"> <prematch type="pcre2">datetime=.*Mimecast</prematch> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)datetime=(?:\\)?([^|]+)</regex> <order>mimecast.datetime</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)aCode=(?:\\)?([^|]+)</regex> <order>mimecast.aCode</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)acc=(?:\\)?([^|]+)</regex> <order>mimecast.acc</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)IP=(?:\\)?([^|]+)</regex> <order>mimecast.IP</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)RejType=(?:\\)?([^|]+)</regex> <order>mimecast.RejType</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)Error=(?:\\)?([^|]+)</regex> <order>mimecast.Error</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)RejCode=(?:\\)?([^|]+)</regex> <order>mimecast.RejCode</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)Dir=(?:\\)?([^|]+)</regex> <order>mimecast.Dir</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)headerFrom=(?:\\)?([^|]+)</regex> <order>mimecast.headerFrom</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)Sender=(?:\\)?([^|]+)</regex> <order>mimecast.Sender</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)Rcpt=(?:\\)?([^|]+)</regex> <order>mimecast.Rcpt</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)Act=(?:\\)?([^|]+)</regex> <order>mimecast.Act</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)RejInfo=(?:\\)?([^|]+)</regex> <order>mimecast.RejInfo</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)TlsVer=(?:\\)?([^|]+)</regex> <order>mimecast.TlsVer</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)Cphr=(?:\\)?([^|]+)</regex> <order>mimecast.Cphr</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)Hld=(?:\\)?([^|]+)</regex> <order>mimecast.Hld</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)AttSize=(?:\\)?([^|]+)</regex> <order>mimecast.AttSize</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)IPNewDomain=(?:\\)?([^|]+)</regex> <order>mimecast.IPNewDomain</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)IPReplyMismatch=(?:\\)?([^|]+)</regex> <order>mimecast.IPReplyMismatch</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)AttCnt=(?:\\)?([^|]+)</regex> <order>mimecast.AttCnt</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)IPInternalName=(?:\\)?([^|]+)</regex> <order>mimecast.IPInternalName</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)AttNames=(?:\\)?([^|]+)</regex> <order>mimecast.AttNames</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)MsgSize=(?:\\)?([^|]+)</regex> <order>mimecast.MsgSize</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)MsgId=(?:\\)?([^|]+)</regex> <order>mimecast.MsgId</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)IPThreadDict=(?:\\)?([^|]+)</regex> <order>mimecast.IPThreadDict</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)IPSimilarDomain=(?:\\)?([^|]+)</regex> <order>mimecast.IPSimilarDomain</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)Delivered=(?:\\)?([^|]+)</regex> <order>mimecast.Delivered</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)Err=(?:\\)?([^|]+)</regex> <order>mimecast.Err</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)ReceiptAck=(?:\\)?([^|]+)</regex> <order>mimecast.ReceiptAck</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)Subject=(?:\\)?([^|]+)</regex> <order>mimecast.Subject</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)Attempt=(?:\\)?([^|]+)</regex> <order>mimecast.Attempt</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)Snt=(?:\\)?([^|]+)</regex> <order>mimecast.Snt</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)UseTls=(?:\\)?([^|]+)</regex> <order>mimecast.UseTls</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)MimecastIP=(?:\\)?([^|]+)</regex> <order>mimecast.MimecastIP</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)fileName=(?:\\)?([^|]+)</regex> <order>mimecast.fileName</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)sha256=(?:\\)?([^|]+)</regex> <order>mimecast.sha256</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)Size=(?:\\)?([^|]+)</regex> <order>mimecast.Size</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)Recipient=(?:\\)?([^|]+)</regex> <order>mimecast.Recipient</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)SenderDomain=(?:\\)?([^|]+)</regex> <order>mimecast.SenderDomain</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)fileExt=(?:\\)?([^|]+)</regex> <order>mimecast.fileExt</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)Virus=(?:\\)?([^|]+)</regex> <order>mimecast.Virus</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)sha1=(?:\\)?([^|]+)</regex> <order>mimecast.sha1</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)SenderDomainInternal=(?:\\)?([^|]+)</regex> <order>mimecast.SenderDomainInternal</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)fileMime=(?:\\)?([^|]+)</regex> <order>mimecast.fileMime</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)CustomerIP=(?:\\)?([^|]+)</regex> <order>mimecast.CustomerIP</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)Route=(?:\\)?([^|]+)</regex> <order>mimecast.Route</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)md5=(?:\\)?([^|]+)</regex> <order>mimecast.md5</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)SourceIP=(?:\\)?([^|]+)</regex> <order>mimecast.SourceIP</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)UrlCategory=(?:\\)?([^|]+)</regex> <order>mimecast.UrlCategory</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)ScanResultInfo=(?:\\)?([^|]+)</regex> <order>mimecast.ScanResultInfo</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)URL=(?:\\)?([^|]+)</regex> <order>mimecast.URL</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)Receipient=(?:\\)?([^|]+)</regex> <order>mimecast.Receipient</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)Definition=(?:\\)?([^|]+)</regex> <order>mimecast.Definition</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)Hits=(?:\\)?([^|]+)</regex> <order>mimecast.Hits</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)Action=(?:\\)?([^|]+)</regex> <order>mimecast.Action</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)TaggedExternal=(?:\\)?([^|]+)</regex> <order>mimecast.TaggedExternal</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)TaggedMalicious=(?:\\)?([^|]+)</regex> <order>mimecast.TaggedMalicious</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)InternalName=(?:\\)?([^|]+)</regex> <order>mimecast.InternalName</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)CustomName=(?:\\)?([^|]+)</regex> <order>mimecast.CustomName</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)NewDomain=(?:\\)?([^|]+)</regex> <order>mimecast.NewDomain</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)SimilarInternalDomain=(?:\\)?([^|]+)</regex> <order>mimecast.SimilarInternalDomain</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)SimilarCustomExternalDomain=(?:\\)?([^|]+)</regex> <order>mimecast.SimilarCustomExternalDomain</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)SimilarMimecastExternalDomain=(?:\\)?([^|]+)</regex> <order>mimecast.SimilarMimecastExternalDomain</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)ReplyMismatch=(?:\\)?([^|]+)</regex> <order>mimecast.ReplyMismatch</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)ThreatDictionary=(?:\\)?([^|]+)</regex> <order>mimecast.ThreatDictionary</order> </decoder> <decoder name="mimecast-siem-logs"> <parent>mimecast</parent> <regex type="pcre2">(?i)reason=(?:\\)?([^|]+)</regex> <order>mimecast.reason</order> </decoder>
Custom rules
1. Create a rule file /var/ossec/etc/rules/mimecast_rules.xml
and add the following rules:
<!-- Rules for Mimecast via API --> <!-- Mimecast SIEM Logs --> <!-- Mimecast logs grouped --> <group name="mimecast"> <rule id="106000" level="2"> <field name="mimecast.datetime">\.</field> <description>Logs from Mimecast.</description> </rule> <!-- Rule to detect mail held for admin review --> <rule id="106001" level="5"> <if_sid>106000</if_sid> <field name="mimecast.Act">Hld</field> <description>Message $(mimecast.MsgId) held for review.</description> <mitre> <id>T1566</id> </mitre> </rule> <!-- Rule to detect AV logs --> <rule id="106002" level="5"> <if_sid>106000</if_sid> <field name="mimecast.Virus">\.</field> <field name="mimecast.Subject">\.</field> <description>Malicious email with category "$(mimecast.Virus)" sent to $(mimecast.Recipient).</description> <mitre> <id>T1598.003</id> <id>T1114</id> </mitre> </rule> <rule id="106003" level="10" frequency="3" timeframe="300"> <if_matched_sid>106002</if_matched_sid> <same_field>mimecast.Sender</same_field> <description>Multiple malicious emails received from same sender $(mimecast.Sender).</description> <mitre> <id>T1598.003</id> <id>T1114</id> </mitre> </rule> <rule id="106004" level="10" frequency="5" timeframe="300"> <if_matched_sid>106002</if_matched_sid> <same_field>mimecast.Sender</same_field> <different_field>mimecast.Recipient</different_field> <description>Malicious emails received by multiple users from same sender $(mimecast.Sender).</description> <mitre> <id>T1598.003</id> <id>T1114</id> </mitre> </rule> <!-- Rules to detect Target Threat Protection - Internal Email Protect logs --> <rule id="106005" level="3"> <if_sid>106000</if_sid> <field name="mimecast.ScanResultInfo">Blocked</field> <description>User $(mimecast.Recipient) blocked from clicking a malicious/blocked link $(URL).</description> <mitre> <id>T1566.002</id> <id>T1114</id> </mitre> </rule> <rule id="106006" level="10" frequency="3" timeframe="300"> <if_matched_sid>106005</if_matched_sid> <different_field>mimecast.Recipient</different_field> <same_field>mimecast.URL</same_field> <description>Multiple users trying to access same malicious/blocked link $(URL).</description> <mitre> <id>T1566.002</id> <id>T1114</id> </mitre> </rule> <!-- Rules to detect Targeted Threat Protection - Impersonation Protect logs --> <rule id="106007" level="5"> <if_sid>106000</if_sid> <field name="mimecast.Definition">Impersonation</field> <description>Internal user $(mimecast.Sender) has been impersonated.</description> <mitre> <id>T1036</id> <id>T1586.002</id> <id>T1566</id> <id>T1114</id> </mitre> </rule> <rule id="106008" level="5"> <if_sid>106007</if_sid> <field name="mimecast.ReplyMismatch">true</field> <description>Reply address mismatch: Reply address does not correspond to the senders address.</description> <mitre> <id>T1036</id> <id>T1586.002</id> <id>T1566</id> <id>T1114</id> </mitre> </rule> <!-- Rules to detect Targeted Threat Protection - URL Protect logs --> <rule id="106009" level="4"> <if_sid>106000</if_sid> <field name="mimecast.reason">malicious</field> <field name="mimecast.URL">\.</field> <field name="mimecast.urlCategory">Blocked</field> <description>User $(mimecast.Recipient) blocked from clicking a malicious link $(URL).</description> <mitre> <id>T1566.002</id> <id>T1114</id> </mitre> </rule> <rule id="106010" level="10" frequency="3" timeframe="300"> <if_matched_sid>106009</if_matched_sid> <different_field>mimecast.Recipient</different_field> <description>Multiple users trying to access same malicious/blocked link $(URL).</description> <mitre> <id>T1566.002</id> <id>T1114</id> </mitre> </rule> <!-- Rule to detect Targeted Threat Protection - Attachment Protect logs --> <rule id="106011" level="10"> <if_sid>106000</if_sid> <field name="mimecast.fileName">\.</field> <field name="mimecast.fileMime">\.</field> <field name="mimecast.sha256">\.</field> <match negate="yes">Subject</match> <description>Mimecast sandbox has detected a potentially malicious file $(mimecast.fileName).$(mimecast.fileExt) on $(mimecast.Recipient).</description> <mitre> <id>T1204.002</id> <id>T1598.002</id> <id>T1566.001</id> <id>T1114</id> </mitre> </rule> <rule id="106012" level="10" frequency="3" timeframe="300"> <if_matched_sid>106011</if_matched_sid> <same_field>mimecast.Sender</same_field> <description>Multiple potentially malicious files received from same sender $(mimecast.Sender).</description> <mitre> <id>T1204.002</id> <id>T1598.002</id> <id>T1566.001</id> <id>T1114</id> </mitre> </rule> <rule id="106013" level="10" frequency="3" timeframe="300"> <if_matched_sid>106011</if_matched_sid> <same_field>mimecast.IP</same_field> <description>Multiple potentially malicious files received from same source $(mimecast.IP).</description> <mitre> <id>T1204.002</id> <id>T1598.002</id> <id>T1566.001</id> <id>T1114</id> </mitre> </rule> <rule id="106014" level="10" frequency="4" timeframe="300"> <if_matched_sid>106011</if_matched_sid> <same_field>mimecast.sha256</same_field> <description>Same potentially malicious file $(mimecast.fileName) detected on multiple recipients.</description> <mitre> <id>T1204.002</id> <id>T1598.002</id> <id>T1566.001</id> <id>T1114</id> </mitre> </rule> <rule id="106015" level="10" frequency="3" timeframe="300"> <if_matched_sid>106011</if_matched_sid> <same_field>mimecast.SenderDomain</same_field> <description>Multiple potentially malicious files received from same domain.</description> <mitre> <id>T1204.002</id> <id>T1598.002</id> <id>T1566.001</id> <id>T1114</id> </mitre> </rule> </group>
Where:
- Rule ID
100600
groups all Mimecast events. - Rule ID
106001
detects emails held for admin review. - Rule IDs
106002
,106003
, and106004
detect email antivirus events. - Rule IDs
106005
and106006
detect internal email protection events. - Rule IDs
106007
and106008
detect impersonation protection events. - Rule IDs
106009
and106010
detect URL protection events. - Rule IDs
106011
,106012
,106013
,106014
, and106015
detect email attachment protection events.
2. Restart the Wazuh manager to apply the changes:
# systemctl restart wazuh-manager
Visualizing alerts
When a Mimecast event that matches any of our custom rules occurs, we see alerts on the Wazuh dashboard. Navigate to Modules > Security events to view the alerts.
Conclusion
In this blog post, we demonstrated how to integrate Mimecast with Wazuh. This integration helps to streamline your security monitoring activities by offering a unified view of your email security events. It also gives administrators and security analysts deeper insights into email security events.
Wazuh is a free and open source SIEM and XDR solution. Wazuh can be deployed and managed on-premises or on the Wazuh cloud. Check out our community for support and updates.
References