Hello,
I'm not very strong in Python. The alerts are notifications generated by the Wazuh manager after processing events received from Wazuh agents and non-agent devices. By default, alerts are stored in the files /var/ossec/logs/alerts/alerts.log and /var/ossec/logs/alerts/alerts.json.
The output file that your script generates for alerts seems to be a temporary one specific to your script. The closest functionality I can think of regarding what you're trying to achieve is logging and saving data to a file that you can monitor. You can refer to this guide in our manual to understand how it works.
If I'm not understanding your goal or how the script functions, please feel free to respond with a more detailed explanation so that I can assist you better.
Best regards,
Thank you for sharing the documentation you used to create your script, it helps me understand better.
For this to work, you need to have the logall_json settings enabled in the file /var/ossec/etc/ossec.conf so that these events are sent to the archive.json. Here’s an example of how it should look:
Once you have done this, please run the script and retrieve the event from the archive.log or the archive.json that is not generating alerts so that I can help you create a decoder and a rule that matches that event.
Cheers#!/usr/bin/env python3
import sys
import time
import os
from socket import socket, AF_UNIX, SOCK_DGRAM
import json
try:
import requests
except ImportError:
print("O módulo 'requests' não está instalado. Por favor, instale: pip install requests")
sys.exit(1)
# Global variables
debug_enabled = True
pwd = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
log_file = f"{pwd}/logs/integrations.log"
socket_addr = f"{pwd}/queue/sockets/queue"
now = time.strftime("%a %b %d %H:%M:%S %Z %Y")
# ================== Funções Utilitárias ==================
def debug(msg):
if debug_enabled:
msg = f"{now}: {msg}\n"
print(msg)
with open(log_file, "a") as log:
log.write(msg)
def load_alert(file_path):
try:
with open(file_path, "r") as alert_file:
return json.load(alert_file)
except Exception as e:
debug(f"Erro ao carregar o alerta: {str(e)}")
return None
def query_api(content, apikey):
headers = {
'Authorization': f'Bearer {apikey}',
'Content-Type': 'application/json',
}
json_data = {
'model': 'gpt-3.5-turbo',
'messages': [{'role': 'user', 'content': content}],
}
try:
response = requests.post('https://api.openai.com/v1/chat/completions', headers=headers, json=json_data)
response.raise_for_status()
return response.json()["choices"][0]["message"]["content"]
except requests.exceptions.RequestException as e:
debug(f"Erro ao conectar à API do ChatGPT: {str(e)}")
return None
def send_event(msg, agent=None):
try:
event_string = f'1:chatgpt:{json.dumps(msg)}'
if agent:
event_string = f'1:[{agent["id"]}] ({agent["name"]}) {agent.get("ip", "any")}->chatgpt:{json.dumps(msg)}'
debug(f"Enviando evento para o Wazuh Manager: {event_string}")
with socket(AF_UNIX, SOCK_DGRAM) as sock:
sock.connect(socket_addr)
sock.sendall(event_string.encode())
except Exception as e:
debug(f"Erro ao enviar evento para o Wazuh Manager: {str(e)}")
# ================== Processamento de Alerta ==================
def process_alert(alert, apikey):
"""Process alert and analyze using ChatGPT API"""
if '_source' in alert:
alert_data = alert['_source']
eventdata = alert_data['data']['win']['eventdata']
description = alert_data['rule']['description']
event_id = alert_data['data']['win']['system']['eventID']
content = prepare_content(eventdata, description, event_id)
response = query_api(content, apikey)
if not response:
return None
alert_output = {
"chatgpt": {
"response": response,
"source": {
"alert_id": alert_data['id'],
"rule": alert_data['rule']['id'],
"description": alert_data['rule']['description'],
"full_log": alert.get("full_log", ""),
"srcip": alert_data.get("srcip", "N/A"),
"eventID": event_id,
}
},
"integration": "custom-chatgpt"
}
return alert_output
else:
debug("A chave '_source' não está presente no alerta.")
return None
def prepare_content(eventdata, description, event_id):
""" Prepare content based on event type for ChatGPT API query """
base_message = f"Um alerta foi gerado pelo sistema Wazuh com os seguintes detalhes:\n- Descrição da Regra: {description}\n- Evento detalhes: {eventdata}"
if event_id == "4625":
account_name = eventdata.get("TargetUserName", "N/A")
workstation = eventdata.get("WorkstationName", "N/A")
failure_reason = eventdata.get("Status", "N/A")
return f"{base_message}\n- Nome da Conta: {account_name}\n- Nome da Estação de Trabalho: {workstation}\n- Motivo da Falha: {failure_reason}"
return base_message
if __name__ == "__main__":
if len(sys.argv) < 3:
debug("Erro: Argumentos insuficientes fornecidos. Encerrando.")
sys.exit(1)
alert_file_location = sys.argv[1]
apikey = sys.argv[2]
debug(f"Iniciando processamento para o alerta: {alert_file_location}")
alert = load_alert(alert_file_location)
if alert is None:
debug("Falha ao carregar o alerta. Encerrando a execução.")
sys.exit(1)
enriched_alert = process_alert(alert, apikey)
if enriched_alert:
send_event(enriched_alert, alert.get("agent"))
debug("Processamento concluído com sucesso.")
else:
debug("Nenhuma resposta gerada para o alerta.”)
My integration configuration ossec.conf
<!-- ChatGPT Integration -->
<integration>
<name>custom-chatgpt.py</name>
<hook_url>/var/ossec/integrations/custom-chatgpt.py</hook_url>
<api_key>######################################################</api_key>
<level>10</level>
<rule_id>4104,4625,5715,5720,92200,92151,31302,31303,61601,61605,5541,5542,100031,100120,100124,200006</rule_id>
<alert_format>json</alert_format>
</integration>
<global>
<jsonout_output>yes</jsonout_output>
<alerts_log>yes</alerts_log>
<logall>yes</logall>
<logall_json>yes</logall_json>
root@tcv06:/var/ossec/integrations# grep 'chatgpt' /var/ossec/logs/ossec.log
2025/01/07 12:28:54 wazuh-integratord: INFO: Enabling integration for: 'custom-chatgpt.py'.
2025/01/07 12:39:07 wazuh-integratord: INFO: Enabling integration for: 'custom-chatgpt.py'.
2025/01/07 12:41:23 wazuh-integratord: INFO: Enabling integration for: 'custom-chatgpt.py'.
root@tcv06:/var/ossec/integrations# grep 'chatgpt' /var/ossec/logs/ossec.log
Tue Jan 07 12:39:27 -03 2025: Iniciando processamento para o alerta: /tmp/custom-chatgpt.py-1736264367--1769589083.alert
Tue Jan 07 12:39:27 -03 2025: Iniciando processamento para o alerta: /tmp/custom-chatgpt.py-1736264367-1720742002.alert
Tue Jan 07 12:39:28 -03 2025: Iniciando processamento para o alerta: /tmp/custom-chatgpt.py-1736264367--2128293783.alert
Tue Jan 07 12:39:28 -03 2025: Iniciando processamento para o alerta: /tmp/custom-chatgpt.py-1736264368--1203610639.alert
Tue Jan 07 12:39:28 -03 2025: Iniciando processamento para o alerta: /tmp/custom-chatgpt.py-1736264368-1728336815.alert
Tue Jan 07 12:39:28 -03 2025: Iniciando processamento para o alerta: /tmp/custom-chatgpt.py-1736264368-1891860211.alert
Tue Jan 07 12:39:28 -03 2025: Iniciando processamento para o alerta: /tmp/custom-chatgpt.py-1736264368--67579865.alert
Tue Jan 07 12:39:29 -03 2025: Iniciando processamento para o alerta: /tmp/custom-chatgpt.py-1736264369-253186973.alert
Tue Jan 07 12:39:29 -03 2025: Iniciando processamento para o alerta: /tmp/custom-chatgpt.py-1736264369-1341084957.alert
Tue Jan 07 12:39:29 -03 2025: Iniciando processamento para o alerta: /tmp/custom-chatgpt.py-1736264369--308873912.alert
Tue Jan 07 12:39:29 -03 2025: Iniciando processamento para o alerta: /tmp/custom-chatgpt.py-1736264369-2018575327.alert
Tue Jan 07 12:39:29 -03 2025: Iniciando processamento para o alerta: /tmp/custom-chatgpt.py-1736264369--270852397.alert
Tue Jan 07 12:39:30 -03 2025: Iniciando processamento para o alerta: /tmp/custom-chatgpt.py-1736264369--1396615295.alert
Tue Jan 07 12:39:30 -03 2025: Iniciando processamento para o alerta: /tmp/custom-chatgpt.py-1736264370--2114931108.alert
Tue Jan 07 12:39:30 -03 2025: Iniciando processamento para o alerta: /tmp/custom-chatgpt.py-1736264370--1414674701.alert
Tue Jan 07 12:39:30 -03 2025: Iniciando processamento para o alerta: /tmp/custom-chatgpt.py-1736264370--1725816066.alert
Tue Jan 07 12:44:48 -03 2025: Enviando evento para o Wazuh Manager: 1:chatgpt:{"chatgpt": {"response": "Com base nos detalhes fornecidos, o alerta indica que um arquivo execut\u00e1vel foi colocado em uma pasta comumente usada por malwares. O arquivo em quest\u00e3o \u00e9 o 'msedge.exe' localizado em 'C:\\\\Program Files (x86)\\\\Microsoft\\\\Edge\\\\Application\\\\'. O evento ocorreu em 07 de janeiro de 2025 \u00e0s 15:39:25 UTC, com o processo de ID 17252 e GUID '{713e769a-4a59-677d-7ff7-060000003800}'. O arquivo suspeito foi encontrado em 'C:\\\\Users\\\\ANA~1.PAU\\\\AppData\\\\Local\\\\Temp\\\\216\\\\chrome_Unpacker_BeginUnzipping17252_1418738848\\\\webui-setup.js'. A regra associada ao alerta \u00e9 'technique_id=T1059.007,technique_name=JavaScript'. O login do usu\u00e1rio relacionado a esse evento \u00e9 'ZUOV02\\\\ana.paula'. A verifica\u00e7\u00e3o adicional e a remo\u00e7\u00e3o segura do arquivo suspeito s\u00e3o recomendadas para evitar poss\u00edveis amea\u00e7as de seguran\u00e7a.", "source": {"alert_id": "1736264365.334344208", "rule": "92213", "description": "Executable file dropped in folder commonly used by malware", "full_log": "", "srcip": "N/A", "eventID": "11"}}, "integration": "custom-chatgpt"}
root@tcv06:/var/ossec/integrations# python3 /var/ossec/integrations/custom-chatgpt.py /tmp/alert6.json ################################################
Tue Jan 07 12:57:57 -03 2025: Iniciando processamento para o alerta: /tmp/alert6.json
Tue Jan 07 12:57:57 -03 2025: Enviando evento para o Wazuh Manager: 1:chatgpt:{"chatgpt": {"response": "Com base nas informa\u00e7\u00f5es fornecidas, o alerta indica que um arquivo execut\u00e1vel foi deixado em uma pasta comumente usada por malwares. O arquivo em quest\u00e3o \u00e9 o 'msedge.exe' localizado em 'C:\\\\Program Files (x86)\\\\Microsoft\\\\Edge\\\\Application\\\\'. \n\nO arquivo suspeito foi identificado como 'webui-setup.js' e foi deixado em 'C:\\\\Users\\\\ANA~1.PAU\\\\AppData\\\\Local\\\\Temp\\\\216\\\\chrome_Unpacker_BeginUnzipping17252_1418738848\\\\'. O evento aconteceu em 07 de janeiro de 2025 \u00e0s 15:39:25 e o usu\u00e1rio associado foi 'ZUOV02\\\\ana.paula'.\n\nA regra associada ao alerta \u00e9 'JavaScript' com o ID da t\u00e9cnica T1059.007. Recomenda-se investiga\u00e7\u00e3o adicional para garantir a seguran\u00e7a do sistema e mitigar poss\u00edveis amea\u00e7as.", "source": {"alert_id": "1736264365.334344208", "rule": "92213", "description": "Executable file dropped in folder commonly used by malware", "full_log": "", "srcip": "N/A", "eventID": "11"}}, "integration": "custom-chatgpt"}
Tue Jan 07 12:57:57 -03 2025: Processamento concluído com sucesso.
In the test above, apparently the integration is working, because if I test it by running it directly, it handles the alert, but in Wazuh nothing appears, I believe there must be an error somewhere that I haven't discovered yet, can you give me some light?