rsyslog/tests/mmsnareparse-comprehensive.sh
Cursor Agent b3a124b0ae plugins/docs/tests: rename mmsnarewinsec to mmsnareparse
Rename the Snare Windows Security parser module from "mmsnarewinsec"
to "mmsnareparse" for clearer naming and consistency with other parser
modules. Update code identifiers, build system, docs, tests, CI flags,
and paths accordingly.

What changed
- MODULE_CNFNAME set to "mmsnareparse"; default macro renamed
- Log/error/debug tags updated to "mmsnareparse"
- plugins/mmsnarewinsec/* moved to plugins/mmsnareparse/*
- configure.ac:
  - add --enable-mmsnareparse
  - AM_CONDITIONAL(ENABLE_MMSNAREPARSE)
  - AC_CONFIG_FILES now includes plugins/mmsnareparse/Makefile
- Makefile.am subdir switch to plugins/mmsnareparse
- Tests renamed and updated (scripts and testsuites directory)
- Docs page renamed and examples updated
- CI workflow uses --enable-mmsnareparse
- Rebase to main; resolved configure.ac conflict

Impact
- Backwards-incompatible module name and configure flag changes.

Migration
- Config: module(load="mmsnareparse"), action(type="mmsnareparse")
- Build: use --enable-mmsnareparse

Co-authored-by: alorbach <alorbach@adiscon.com>
2025-10-06 12:02:22 +02:00

184 lines
10 KiB
Bash
Executable File

#!/bin/bash
# Comprehensive test for mmsnareparse module field extraction capabilities
# This test validates the module's ability to extract structured fields from
# Windows Security Event Log description sections using dynamic test data from
# sample-windows2022-security.data and sample-windows2025-security.data files.
unset RSYSLOG_DYNNAME
. ${srcdir:=.}/diag.sh init
generate_conf
add_conf '
module(load="../plugins/imtcp/.libs/imtcp")
module(load="../plugins/mmsnareparse/.libs/mmsnareparse")
# Template to extract comprehensive structured JSON output
template(name="jsonfmt" type="list" option.jsonf="on") {
# Event fields
property(outname="eventid" name="$!win!Event!EventID" format="jsonf")
property(outname="channel" name="$!win!Event!Channel" format="jsonf")
property(outname="eventtype" name="$!win!Event!EventType" format="jsonf")
property(outname="categorytext" name="$!win!Event!CategoryText" format="jsonf")
property(outname="computer" name="$!win!Event!Computer" format="jsonf")
property(outname="provider" name="$!win!Event!Provider" format="jsonf")
# Subject fields
property(outname="subjectsecurityid" name="$!win!Subject!SecurityID" format="jsonf")
property(outname="subjectaccountname" name="$!win!Subject!AccountName" format="jsonf")
property(outname="subjectaccountdomain" name="$!win!Subject!AccountDomain" format="jsonf")
property(outname="subjectlogonid" name="$!win!Subject!LogonID" format="jsonf")
# LogonInformation fields
property(outname="logontype" name="$!win!LogonInformation!LogonType" format="jsonf")
property(outname="logontypename" name="$!win!LogonInformation!LogonTypeName" format="jsonf")
property(outname="restrictedadminmode" name="$!win!LogonInformation!RestrictedAdminMode" format="jsonf")
property(outname="virtualaccount" name="$!win!LogonInformation!VirtualAccount" format="jsonf")
property(outname="elevatedtoken" name="$!win!LogonInformation!ElevatedToken" format="jsonf")
property(outname="impersonationlevel" name="$!win!LogonInformation!ImpersonationLevel" format="jsonf")
# NewLogon fields
property(outname="newlogonsecurityid" name="$!win!NewLogon!SecurityID" format="jsonf")
property(outname="newlogonaccountname" name="$!win!NewLogon!AccountName" format="jsonf")
property(outname="newlogonaccountdomain" name="$!win!NewLogon!AccountDomain" format="jsonf")
property(outname="newlogonlogonid" name="$!win!NewLogon!LogonID" format="jsonf")
property(outname="linkedlogonid" name="$!win!NewLogon!LinkedLogonID" format="jsonf")
property(outname="networkaccountname" name="$!win!NewLogon!NetworkAccountName" format="jsonf")
property(outname="logonguid" name="$!win!NewLogon!LogonGUID" format="jsonf")
# Process fields
property(outname="processid" name="$!win!Process!ProcessID" format="jsonf")
property(outname="processname" name="$!win!Process!ProcessName" format="jsonf")
property(outname="processcommandline" name="$!win!Process!ProcessCommandLine" format="jsonf")
property(outname="tokenelevationtype" name="$!win!Process!TokenElevationType" format="jsonf")
property(outname="mandatorylabel" name="$!win!Process!MandatoryLabel" format="jsonf")
# Network fields
property(outname="workstationname" name="$!win!Network!WorkstationName" format="jsonf")
property(outname="sourcenetworkaddress" name="$!win!Network!SourceNetworkAddress" format="jsonf")
property(outname="sourceport" name="$!win!Network!SourcePort" format="jsonf")
# DetailedAuthentication fields
property(outname="logonprocess" name="$!win!DetailedAuthentication!LogonProcess" format="jsonf")
property(outname="authenticationpackage" name="$!win!DetailedAuthentication!AuthenticationPackage" format="jsonf")
property(outname="transitedservices" name="$!win!DetailedAuthentication!TransitedServices" format="jsonf")
property(outname="packagename" name="$!win!DetailedAuthentication!PackageName" format="jsonf")
property(outname="keylength" name="$!win!DetailedAuthentication!KeyLength" format="jsonf")
# Privileges fields
property(outname="privilegelist" name="$!win!Privileges!PrivilegeList" format="jsonf")
}
# Template for basic field extraction (for comparison)
template(name="basicfmt" type="list") {
property(name="$!win!Event!EventID")
constant(value=",")
property(name="$!win!Event!Channel")
constant(value=",")
property(name="$!win!Event!EventType")
constant(value=",")
property(name="$!win!Event!CategoryText")
constant(value=",")
property(name="$!win!Event!Computer")
constant(value=",")
property(name="$!win!Event!Provider")
constant(value="\n")
}
ruleset(name="winsec") {
action(type="mmsnareparse")
action(type="omfile" file="'$RSYSLOG_OUT_LOG'.json" template="jsonfmt")
action(type="omfile" file="'$RSYSLOG_OUT_LOG'.basic" template="basicfmt")
}
input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="winsec")
'
startup
assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port
# Use dynamic test data from sample files
echo "Using Windows 2022 sample data..."
tcpflood -m 1 -I ${srcdir}/testsuites/mmsnareparse/sample-windows2022-security.data
echo "Using Windows 2025 sample data..."
tcpflood -m 1 -I ${srcdir}/testsuites/mmsnareparse/sample-windows2025-security.data
echo "Using sample events with detailed field information..."
tcpflood -m 1 -I ${srcdir}/testsuites/mmsnareparse/sample-events.data
shutdown_when_empty
wait_shutdown
# Validate basic fields are extracted correctly from Windows 2022 data
content_check '4624,Security,Success Audit,Logon,WIN-5SB1I3G0V7U,Microsoft-Windows-Security-Auditing' $RSYSLOG_OUT_LOG.basic
content_check '4634,Security,Success Audit,Logoff,WIN-5SB1I3G0V7U,Microsoft-Windows-Security-Auditing' $RSYSLOG_OUT_LOG.basic
content_check '4647,Security,Success Audit,Logoff,WIN-5SB1I3G0V7U,Microsoft-Windows-Security-Auditing' $RSYSLOG_OUT_LOG.basic
content_check '4648,Security,Success Audit,Logon,WIN-5SB1I3G0V7U,Microsoft-Windows-Security-Auditing' $RSYSLOG_OUT_LOG.basic
content_check '4672,Security,Success Audit,Special Logon,WIN-5SB1I3G0V7U,Microsoft-Windows-Security-Auditing' $RSYSLOG_OUT_LOG.basic
content_check '4688,Security,Success Audit,Process Creation,WIN-5SB1I3G0V7U,Microsoft-Windows-Security-Auditing' $RSYSLOG_OUT_LOG.basic
# Validate basic fields are extracted correctly from Windows 2025 data
content_check '4624,Security,Success Audit,Audit Policy Change,WIN-IKCCUTRJI52,Microsoft-Windows-Security-Auditing' $RSYSLOG_OUT_LOG.basic
content_check '4647,Security,Success Audit,Audit Policy Change,WIN-IKCCUTRJI52,Microsoft-Windows-Security-Auditing' $RSYSLOG_OUT_LOG.basic
content_check '4648,Security,Success Audit,Audit Policy Change,WIN-IKCCUTRJI52,Microsoft-Windows-Security-Auditing' $RSYSLOG_OUT_LOG.basic
content_check '4672,Security,Success Audit,Audit Policy Change,WIN-IKCCUTRJI52,Microsoft-Windows-Security-Auditing' $RSYSLOG_OUT_LOG.basic
content_check '4688,Security,Success Audit,Audit Policy Change,WIN-IKCCUTRJI52,Microsoft-Windows-Security-Auditing' $RSYSLOG_OUT_LOG.basic
# Validate that both Windows versions are properly parsed
content_check 'WIN-5SB1I3G0V7U' $RSYSLOG_OUT_LOG.json
content_check 'WIN-IKCCUTRJI52' $RSYSLOG_OUT_LOG.json
# Validate structured JSON extraction from Windows 2022 data
# Check for complete records with specific field combinations that actually exist
content_check '"eventid":"4624"' $RSYSLOG_OUT_LOG.json
content_check '"categorytext":"Logon"' $RSYSLOG_OUT_LOG.json
content_check '"computer":"DC25-PREVIEW"' $RSYSLOG_OUT_LOG.json
content_check '"subjectaccountname":"WIN-IKCCUTRJI52$"' $RSYSLOG_OUT_LOG.json
content_check '"logontype":"5"' $RSYSLOG_OUT_LOG.json
content_check '"logontypename":"Service"' $RSYSLOG_OUT_LOG.json
content_check '"processname":"C:\\Windows\\System32\\services.exe"' $RSYSLOG_OUT_LOG.json
content_check '"newlogonaccountname":"SYSTEM"' $RSYSLOG_OUT_LOG.json
content_check '"newlogonaccountdomain":"NT AUTHORITY"' $RSYSLOG_OUT_LOG.json
content_check '"logonprocess":"Advapi"' $RSYSLOG_OUT_LOG.json
content_check '"authenticationpackage":"Negotiate"' $RSYSLOG_OUT_LOG.json
# Placeholder tokens such as "-" should now be dropped entirely by the parser.
# The JSON template still emits empty strings when a property is missing, so we
# assert that hyphen placeholders never surface in the flattened output.
check_not_present '"restrictedadminmode":"-"' "$RSYSLOG_OUT_LOG.json"
check_not_present '"networkaccountname":"-"' "$RSYSLOG_OUT_LOG.json"
check_not_present '"sourcenetworkaddress":"-"' "$RSYSLOG_OUT_LOG.json"
check_not_present '"sourceport":"-"' "$RSYSLOG_OUT_LOG.json"
check_not_present '"transitedservices":"-"' "$RSYSLOG_OUT_LOG.json"
check_not_present '"packagename":"-"' "$RSYSLOG_OUT_LOG.json"
# Validate structured JSON extraction from Windows 2025 data
content_check '"categorytext":"Audit Policy Change"' $RSYSLOG_OUT_LOG.json
content_check '"computer":"WIN-IKCCUTRJI52"' $RSYSLOG_OUT_LOG.json
content_check '"subjectaccountname":"WIN-IKCCUTRJI52$"' $RSYSLOG_OUT_LOG.json
content_check '"subjectaccountdomain":"WORKGROUP"' $RSYSLOG_OUT_LOG.json
# Validate privileges extraction for 4672 events
content_check '"privilegelist":"SeAssignPrimaryTokenPrivilege' $RSYSLOG_OUT_LOG.json
# Validate that DWM-1 account is extracted correctly for virtual accounts
content_check '"newlogonaccountname":"DWM-1"' $RSYSLOG_OUT_LOG.json
content_check '"newlogonaccountdomain":"Window Manager"' $RSYSLOG_OUT_LOG.json
# Validate that Administrator account is extracted correctly
content_check '"subjectaccountname":"Administrator"' $RSYSLOG_OUT_LOG.json
content_check '"subjectaccountdomain":"WIN-5SB1I3G0V7U"' $RSYSLOG_OUT_LOG.json
# Validate various logon types are present
content_check '"virtualaccount":"No"' $RSYSLOG_OUT_LOG.json
content_check '"elevatedtoken":"Yes"' $RSYSLOG_OUT_LOG.json
# Validate different event types have appropriate fields
content_check '"eventid":"4634"' $RSYSLOG_OUT_LOG.json
content_check '"eventid":"4647"' $RSYSLOG_OUT_LOG.json
content_check '"eventid":"4648"' $RSYSLOG_OUT_LOG.json
content_check '"eventid":"4672"' $RSYSLOG_OUT_LOG.json
content_check '"eventid":"4688"' $RSYSLOG_OUT_LOG.json
exit_test