Modsecurity on IIS and Winlogbeat PLEASE HELP! lol

Hey Gang, I'm really hoping for some help on this one.
Previously we have been struggling on getting our Sophos XG working as a WAF solution, this has proven to be a bit daunting due to the fact that Sophos has basically locked down and useful customizations on the appliance.
This brought us to needing to install Modsecurity on each of our IIS servers.. this is probably going to be a home run solution for us but logging is a bit hard ot get working.

Previously with the XG's we had to do a hacky process of tailing the reverseproxylog in the firewall with some creative tools and while it works ok, it is still just that , a HACK..
Moving on we immideately fell in love with the server based install mainly for the freedom to configure it the way we feel fit, but also because this version of Modsecurity reports all warnings, critical and other information into the Application log under event viewer!!
This seems like a perfect case for Winlogbeat.
Not only can we look at modsecurity events, we also can get every other event generated in every respect at our fingertips in one index.. LOVE IT!

what I don't love and desperately need help figuring out is how to break apart the event log record. What I mean is that the entire text is placed in the winlog.event_data.param1 field and I don't know how to break it apart for searching.

for instance here is what I see in kibana under the when I set up the filters agent.hostname: SERVER1, event.provider: ModSecurity and view the winlog.event_data.param1 field.

[client 192.168.0.0] ModSecurity: Warning. Operator GE matched 5 at TX:inbound_anomaly_score. [file "C:/Program Files/ModSecurity IIS/owasp_crs/rules/RESPONSE-980-CORRELATION.conf"] [line "73"] [id "980130"] [msg "Inbound Anomaly Score Exceeded (Total Inbound Score: 5 - SQLI=0,XSS=0,RFI=0,LFI=0,RCE=0,PHPI=0,HTTP=0,SESS=0): Failed to parse request body."] [tag "event-correlation"] [hostname "SERVER1"] [uri "/xv/xvservices.asmx/CheckClaims"] [unique_id "10016018801918738991"]

This data is all fine and dandy, but if I want to query the field I get stuck..
Nothing comes back.. or I just can't seem to figure out how to do it properly.
Suppose I wanted to build some visualizations bases on the id number as in [id "980130'] as shown above.
How do I achieve this task? I don't know if its something that should be addresses in ECS? I'm not sure. we previously used some filters in logstash to break down the stream from the firewall itself, but since the data is easily available in the event viewer I'd love to be able to use this ingestion method since it's already working and the logstash route is cumbersome with this particular pipeline. thanks!

-jon

It's pretty common for non-Microsoft apps to write the whole message into a single parameter in the event log (param1).

That log format is going to be hard to parse in a generic manner. I looked at the documentation for the logging format and also found that JSON logging is supported (yay!). This should make this task a lot easier.

SecAuditLogFormat JSON

Reference: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-(v2.x)#secauditlogformat

Once that data is being logged as JSON into winlog.event_data.param1 you can parse it with the decode_json_fields processor. Then after it has been decoded you can use the convert processor to do any data type conversions and also rename some of the fields according to Elastic Common Schema.

processors:
- if:
    equals.winlog.provider_name: Modsecurity # Adjust according to the data (guessing).
  then:
    - decode_json_fields:
        fields: [winlog.event_data.param1]
        target: "modsecurity.log"
    - convert:
        mode: rename
        fields:
          - {from: modsecurity.log.transaction.remote_address, to: source.ip, type: ip}

Processors Reference: https://www.elastic.co/guide/en/beats/winlogbeat/current/defining-processors.html

Oh thanks a bunch Andrew.
I'll need to look further into it, I had been trying to use the audit log as the source for ingestion, however the results were not as I had hoped. when using Modsecurity on an IIS server the default logging is sent to the Application event log, that is why I opted to move over to Winlogbeat.

Not only does it grab the modsecurity logging for me it brings in all of the other event channels which is a free value added bonus in our environment.

It felt like the low hanging fruit got lower for a few minutes there..
I'll see if the SecAuditLogFormat JSON directive has any effect on the data inserted into the event log.
It is somewhat confusing for me at times, I'm very green and I have a mountain of expectations to deliver before I have the luxury of sitting down for formal training.. ugh.. catch 22

if you have any other ideas I'd love to hear them. thanks for replying to my post.
Thanks!

Ok Andrew I was able to pipe in my JSON logs into Elastic and many useful KV pairs were pulled.
Unfortunately I want to pick apart the message field so I can search/sort on some bracketed details such as [ID "980214"] or [accuracy "9"] or other details. these aren't JSON formatted pairs, just predictable values.
What would be the best way to pull this apart? I have used a filter in logstash for a similar data set but this is a little different and because I don't know how to do it with filebeat it's seemingly impossible with my current level of competency.

The message looks something like this;

[Warning. Pattern match "(?:\b(?:A(?:DODB\.Command\b.{0,100}?\b(?:Application uses a value of the wrong type for the current operation\b|error')| trappable error occurred in an external object\. The script cannot continue running\b)|Microsoft VBScript (?:compilation (?: ..." at RESPONSE_BODY. [file "C:/Program Files/ModSecurity IIS/owasp_crs/rules/RESPONSE-954-DATA-LEAKAGES-IIS.conf"] [line "107"] [id "954120"] [rev "2"] [msg "IIS Information Leakage"] [data "Matched Data: error '800 found within RESPONSE_BODY: \x0a

Microsoft VBScript runtime error '800a000d'\x0a

\x0aType mismatch: '[string: "20.0%"]'\x0a

\x0a/RateSheet.asp, line 211 "] [severity "ERROR"] [ver "OWASP_CRS/3.0.0"] [maturity "9"] [accuracy "9"] [tag "application-multi"] [tag "language-multi"] [tag "platform-iis"] [tag "platform- Warning. Operator GE matched 4 at TX:outbound_anomaly_score. [file "C:/Program Files/ModSecurity IIS/owasp_crs/rules/RESPONSE-959-BLOCKING-EVALUATION.conf"] [line "32"] [id "959100"] [msg "Outbound Anomaly Score Exceeded.....

It's kinda like... Look for the -> open bracket -> keyname -> space -> quote -> value -> quote -> closed bracket.
if I could figure out how to pick those details out and make them KV pairs that would be nice.

can we employ Grok inside filebeat yml configs?
thanks