Unable to decode suricata eve.json from syslog

200 views
Skip to first unread message

autumnwalker

unread,
Jun 7, 2025, 1:21:26 AM6/7/25
to Wazuh | Mailing List
I have setup syslog forwarding from pfSense to Wazuh using syslog-ng. Syslog-ng running on pfSense grabs eve.json from Suricata and sends it over to Wazuh which ingests via remote syslog. I have confirmed that I can see the flow in archives.json on the Wazuh server.

I am struggling with the right combination of decoders and rules to get anything to trigger in Wazuh though. I believe the issue I am running into is that the Wazuh syslog remote is wrapping the json output from syslog-ng in a syslog header that the decoders don't know how to deal with (and I don't know how to solution around).

I've put a sample suricata entry as recorded in archives.json - any idea how to make Wazuh play nice with this or make pfSense / syslog-ng play nice with Wazuh? NOTE - I replaced actual IP addresses with 0.0.0.0 in the data sample.

{"timestamp":"2025-06-06T14:10:55.394+0000","agent":{"id":"000","name":"wazuh"},"manager":{"name":"wazuh"},"id":"1749219055.1716572","full_log":"Jun  6 11:10:55 pfsense suricata: {\"timestamp\":\"2025-06-06T11:10:54.657789-0300\",\"flow_id\":124385591293410,\"in_iface\":\"bge0.35\",\"event_type\":\"fileinfo\",\"src_ip\":\"0.0.0.0\",\"src_port\":5149,\"dest_ip\":\"0.0.0.0\",\"dest_port\":80,\"proto\":\"TCP\",\"pkt_src\":\"wire/pcap\",\"http\":{\"hostname\":\"www.acinfinityserver.com\",\"url\":\"/api/dev/getdevModeSettingList\",\"http_user_agent\":\"ACController/1.8.2 (com.acinfinity.humiture; build:489; iOS 16.5.1) Alamofire/5.4.4\",\"http_content_type\":\"application/json\",\"http_method\":\"POST\",\"protocol\":\"HTTP/1.1\",\"status\":200,\"length\":1201},\"app_proto\":\"http\",\"fileinfo\":{\"filename\":\"/api/dev/getdevModeSettingList\",\"gaps\":false,\"state\":\"CLOSED\",\"stored\":false,\"size\":32,\"tx_id\":598}}","predecoder":{"program_name":"suricata","timestamp":"Jun  6 11:10:55","hostname":"pfsense"},"decoder":{},"location":"0.0.0.0"}

hasitha.u...@wazuh.com

unread,
Jun 7, 2025, 2:45:34 AM6/7/25
to Wazuh | Mailing List
Hi autumnwalker,

Based on the shared log, I have written a custom JSON decoder using the JSON decoder plugin to extract fields from your log. I have tested it, and it is working fine for me. You can test the decoder below on your end as well and check if it works correctly.

You can place this decoder into /var/ossec/etc/decoders/local_decoder.xml file.
For example: nano /var/ossec/etc/decoders/local_decoder.xml

  1. <decoder name="suricata-custom">
  2.     <program_name>suricata</program_name>
  3.     <plugin_decoder>JSON_Decoder</plugin_decoder>
  4. </decoder>

After saving and closing the file, you need to restart the Wazuh manager to apply changes.
systemctl restart wazuh-manager

In your custom log, the beginning part is pre-decoded, and the rest is in JSON format. Due to the header (Jun  6 11:10:55 pfsense suricata: ) at the beginning of your log, Wazuh is unable to decode the log using the default JSON decoder. Therefore, I have used the Wazuh JSON decoder plugin to extract the JSON data included within the log.
You can refer to the Wazuh JSON decoder documentation for more details.

Sample log used after removing escape characters:

  1. Jun  6 11:10:55 pfsense suricata: {"timestamp":"2025-06-06T11:10:54.657789-0300","flow_id":124385591293410,"in_iface":"bge0.35","event_type":"fileinfo","src_ip":"0.0.0.0","src_port":5149,"dest_ip":"0.0.0.0","dest_port":80,"proto":"TCP","pkt_src":"wire/pcap","http":{"hostname":"www.acinfinityserver.com","url":"/api/dev/getdevModeSettingList","http_user_agent":"ACController/1.8.2 (com.acinfinity.humiture; build:489; iOS 16.5.1) Alamofire/5.4.4","http_content_type":"application/json","http_method":"POST","protocol":"HTTP/1.1","status":200,"length":1201},"app_proto":"http","fileinfo":{"filename":"/api/dev/getdevModeSettingList","gaps":false,"state":"CLOSED","stored":false,"size":32,"tx_id":598}}
You can also refer Wazuh decoder syntax documentation for writing further custom decoders.
I have also attached a screenshot of my testing for your reference.

Screenshot 2025-06-07 120951.png
Let me know if you need further assistance on this.

Regards,
Hasitha Upeksihtha

autumnwalker

unread,
Jun 9, 2025, 7:45:20 AM6/9/25
to Wazuh | Mailing List
Thanks Hasitha!

I have added the custom decoder to local_decoder.xml and restarted wazuh-manager, but I do not get the same decoding that you do. I get:

**Phase 1: Completed pre-decoding. full event: '{"timestamp":"2025-06-06T14:10:55.394+0000","agent":{"id":"000","name":"wazuh"},"manager":{"name":"wazuh"},"id":"1749219055.1716572","full_log":"Jun 6 11:10:55 pfsense suricata: {\"timestamp\":\"2025-06-06T11:10:54.657789-0300\",\"flow_id\":124385591293410,\"in_iface\":\"bge0.35\",\"event_type\":\"fileinfo\",\"src_ip\":\"0.0.0.0\",\"src_port\":5149,\"dest_ip\":\"0.0.0.0\",\"dest_port\":80,\"proto\":\"TCP\",\"pkt_src\":\"wire/pcap\",\"http\":{\"hostname\":\"www.acinfinityserver.com\",\"url\":\"/api/dev/getdevModeSettingList\",\"http_user_agent\":\"ACController/1.8.2 (com.acinfinity.humiture; build:489; iOS 16.5.1) Alamofire/5.4.4\",\"http_content_type\":\"application/json\",\"http_method\":\"POST\",\"protocol\":\"HTTP/1.1\",\"status\":200,\"length\":1201},\"app_proto\":\"http\",\"fileinfo\":{\"filename\":\"/api/dev/getdevModeSettingList\",\"gaps\":false,\"state\":\"CLOSED\",\"stored\":false,\"size\":32,\"tx_id\":598}}","predecoder":{"program_name":"suricata","timestamp":"Jun 6 11:10:55","hostname":"pfsense"},"decoder":{},"location":"0.0.0.0"}' **Phase 2: Completed decoding. name: 'json' agent.id: '000' agent.name: 'wazuh' full_log: 'Jun 6 11:10:55 pfsense suricata: {"timestamp":"2025-06-06T11:10:54.657789-0300","flow_id":124385591293410,"in_iface":"bge0.35","event_type":"fileinfo","src_ip":"0.0.0.0","src_port":5149,"dest_ip":"0.0.0.0","dest_port":80,"proto":"TCP","pkt_src":"wire/pcap","http":{"hostname":"www.acinfinityserver.com","url":"/api/dev/getdevModeSettingList","http_user_agent":"ACController/1.8.2 (com.acinfinity.humiture; build:489; iOS 16.5.1) Alamofire/5.4.4","http_content_type":"application/json","http_method":"POST","protocol":"HTTP/1.1","status":200,"length":1201},"app_proto":"http","fileinfo":{"filename":"/api/dev/getdevModeSettingList","gaps":false,"state":"CLOSED","stored":false,"size":32,"tx_id":598}}' id: '1749219055.1716572' location: '0.0.0.0' manager.name: 'wazuh' predecoder.hostname: 'pfsense' predecoder.program_name: 'suricata' predecoder.timestamp: 'Jun 6 11:10:55' timestamp: '2025-06-06T14:10:55.394+0000'

autumnwalker

unread,
Jun 11, 2025, 7:59:57 AM6/11/25
to Wazuh | Mailing List
Following up - is there a way to have Wazuh remove the escape characters from the JSON? The example I provided in my initial message is a direct copy and paste from the message in the syslog that Wazuh is trying to decode.

hasitha.u...@wazuh.com

unread,
Jun 14, 2025, 3:49:40 AM6/14/25
to Wazuh | Mailing List
Hi autumnwalker,

We recommend test rules and decoders based on archives.json because in these logs we can see the field full_log, which is the one being parsed by analysis. Sample archives.json log you shared (the field of need is in bold to test with ruleset test):

{"timestamp":"2025-06-06T14:10:55.394+0000","agent":{"id":"000","name":"wazuh"},"manager":{"name":"wazuh"},"id":"1749219055.1716572","full_log":"Jun  6 11:10:55 pfsense suricata: {\"timestamp\":\"2025-06-06T11:10:54.657789-0300\",\"flow_id\":124385591293410,\"in_iface\":\"bge0.35\",\"event_type\":\"fileinfo\",\"src_ip\":\"0.0.0.0\",\"src_port\":5149,\"dest_ip\":\"0.0.0.0\",\"dest_port\":80,\"proto\":\"TCP\",\"pkt_src\":\"wire/pcap\",\"http\":{\"hostname\":\"www.acinfinityserver.com\",\"url\":\"/api/dev/getdevModeSettingList\",\"http_user_agent\":\"ACController/1.8.2 (com.acinfinity.humiture; build:489; iOS 16.5.1) Alamofire/5.4.4\",\"http_content_type\":\"application/json\",\"http_method\":\"POST\",\"protocol\":\"HTTP/1.1\",\"status\":200,\"length\":1201},\"app_proto\":\"http\",\"fileinfo\":{\"filename\":\"/api/dev/getdevModeSettingList\",\"gaps\":false,\"state\":\"CLOSED\",\"stored\":false,\"size\":32,\"tx_id\":598}}","predecoder":{"program_name":"suricata","timestamp":"Jun  6 11:10:55","hostname":"pfsense"},"decoder":{},"location":"0.0.0.0"}

The actual full log is this after unescaping the JSON log: 

Jun 6 11:10:55 pfsense suricata: {"timestamp":"2025-06-06T11:10:54.657789-0300","flow_id":124385591293410,"in_iface":"bge0.35","event_type":"fileinfo","src_ip":"0.0.0.0","src_port":5149,"dest_ip":"0.0.0.0","dest_port":80,"proto":"TCP","pkt_src":"wire/pcap","http":{"hostname":"www.acinfinityserver.com","url":"/api/dev/getdevModeSettingList","http_user_agent":"ACController/1.8.2 (com.acinfinity.humiture; build:489; iOS 16.5.1) Alamofire/5.4.4","http_content_type":"application/json","http_method":"POST","protocol":"HTTP/1.1","status":200,"length":1201},"app_proto":"http","fileinfo":{"filename":"/api/dev/getdevModeSettingList","gaps":false,"state":"CLOSED","stored":false,"size":32,"tx_id":598}}
You can use this tool to unescape the JSON log: https://www.freeformatter.com/json-escape.html

Then you can copy this log and test with the Ruleset Test.
Screenshot 2025-06-14 131707.png


Let me know if you need further assistance on this.

autumnwalker

unread,
Jun 18, 2025, 12:48:15 AM6/18/25
to Wazuh | Mailing List
Thanks Hasitha.

I am unclear about something. The sample I provided is a direct copy / paste from archives.json - the escaped characters are present in the archives.json file.

Are you saying that Wazuh uses a different log file to decode and only the "full_log" content is present in that file?

Do I somehow need to have Wazuh unescape the log files being sent from Suricata / pfSense?

I found a sample log in Suricata that should have triggered an alert (validated with a decoder test) and it did not based on my current configuration - so something isn't working properly.

Reply all
Reply to author
Forward
0 new messages