MCP sample fetch now asks for common Winlogbeat/ECS fields before
This commit is contained in:
@@ -88,6 +88,17 @@ class GraylogSourceTests(unittest.TestCase):
|
||||
self.assertIn("fw_action", client.arguments["fields"])
|
||||
self.assertIn("full_message", client.arguments["fields"])
|
||||
|
||||
def test_requests_winlogbeat_discovery_fields_before_profile_exists(self):
|
||||
client = _Client()
|
||||
GraylogStreamSource(client, "windows").fetch()
|
||||
self.assertIn("winlog.event_id", client.arguments["fields"])
|
||||
self.assertIn("event.code", client.arguments["fields"])
|
||||
self.assertIn("user.name", client.arguments["fields"])
|
||||
self.assertIn("host.name", client.arguments["fields"])
|
||||
self.assertIn("source.ip", client.arguments["fields"])
|
||||
self.assertIn("winlog.channel", client.arguments["fields"])
|
||||
self.assertIn("process.name", client.arguments["fields"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -44,6 +44,22 @@ class NormalizationTests(unittest.TestCase):
|
||||
self.assertEqual(event.fields["hostname"], "host01")
|
||||
self.assertEqual(event.fields["eventid"], "4625")
|
||||
|
||||
def test_winlogbeat_ecs_aliases_populate_common_fields(self):
|
||||
event = parse_log_line(
|
||||
"@timestamp=2026-06-30T10:00:00Z event.code=4625 event.action=logon-failed "
|
||||
"event.outcome=failure log.level=warning user.name=alice host.name=win01 "
|
||||
"source.ip=10.0.0.5 winlog.channel=Security winlog.provider_name=Microsoft-Windows-Security-Auditing "
|
||||
"winlog.event_data.LogonType=3 process.name=lsass.exe"
|
||||
)
|
||||
|
||||
self.assertEqual(event.fields["eventtime"], "2026-06-30T10:00:00Z")
|
||||
self.assertEqual(event.fields["eventid"], "4625")
|
||||
self.assertEqual(event.fields["action"], "logon-failed")
|
||||
self.assertEqual(event.fields["severity"], "warning")
|
||||
self.assertEqual(event.fields["username"], "alice")
|
||||
self.assertEqual(event.fields["hostname"], "win01")
|
||||
self.assertEqual(event.fields["srcip"], "10.0.0.5")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -25,9 +25,10 @@ class ProfileSuggestionTests(unittest.TestCase):
|
||||
def test_suggests_windows_event_fields(self):
|
||||
events = [
|
||||
parse_log_line(
|
||||
f"fgai_stream_id=windows fgai_stream=Windows winlog_event_id=4625 "
|
||||
f"fgai_stream_id=windows fgai_stream='Illuminate:Windows Security Event Log Messages' winlog_event_id=4625 "
|
||||
f"winlog_event_data_targetusername=alice winlog_computer_name=host{index % 3} "
|
||||
f"event_provider=Microsoft-Windows-Security-Auditing logon_type=3 "
|
||||
f"event_provider=Microsoft-Windows-Security-Auditing channel=Security logon_type=3 "
|
||||
f"winlog_event_data_ipaddress=10.0.0.{index % 5} "
|
||||
f"eventtime=2026-06-29T10:00:{index:02d}Z action=failure"
|
||||
)
|
||||
for index in range(1, 30)
|
||||
@@ -37,8 +38,60 @@ class ProfileSuggestionTests(unittest.TestCase):
|
||||
|
||||
self.assertIn("username", profile["entity_fields"])
|
||||
self.assertIn("hostname", profile["entity_fields"])
|
||||
self.assertIn("srcip", profile["entity_fields"])
|
||||
self.assertNotIn("winlog_event_data_targetusername", profile["entity_fields"])
|
||||
self.assertIn("eventid", profile["categorical_fields"])
|
||||
self.assertIn("logon_type", profile["categorical_fields"])
|
||||
self.assertIn("event_provider", profile["categorical_fields"])
|
||||
self.assertNotIn("policyid", profile["categorical_fields"])
|
||||
self.assertNotIn("dstport", profile["categorical_fields"])
|
||||
self.assertNotIn("srcip", profile["categorical_fields"])
|
||||
self.assertNotIn("eventid", profile["numeric_fields"])
|
||||
self.assertIn("auth_failure", profile["detectors"])
|
||||
|
||||
def test_windows_named_stream_gets_auth_profile_even_before_failures(self):
|
||||
events = [
|
||||
parse_log_line(
|
||||
f"fgai_stream_id=winsec fgai_stream='Illuminate:Windows Security Event Log Messages' "
|
||||
f"eventid=4624 username=user{index % 4} hostname=host{index % 2} channel=Security "
|
||||
f"eventtime=2026-06-29T10:00:{index:02d}Z action=success"
|
||||
)
|
||||
for index in range(1, 30)
|
||||
]
|
||||
|
||||
suggestion = suggest_stream_profiles(events)[0]
|
||||
profile = suggestion["profile"]
|
||||
|
||||
self.assertEqual(suggestion["stream_name"], "Illuminate:Windows Security Event Log Messages")
|
||||
self.assertIn("username", profile["entity_fields"])
|
||||
self.assertIn("hostname", profile["entity_fields"])
|
||||
self.assertIn("eventid", profile["categorical_fields"])
|
||||
self.assertIn("auth_failure", profile["detectors"])
|
||||
|
||||
def test_winlogbeat_ecs_fields_build_windows_profile(self):
|
||||
events = [
|
||||
parse_log_line(
|
||||
f"fgai_stream_id=winbeat fgai_stream='Winlogbeat Security' "
|
||||
f"@timestamp=2026-06-30T10:00:{index:02d}Z event.code=4625 event.action=logon-failed "
|
||||
f"event.outcome=failure event.category=authentication event.type=start "
|
||||
f"user.name=user{index % 4} host.name=win{index % 3} source.ip=10.0.0.{index % 5} "
|
||||
f"winlog.channel=Security winlog.provider_name=Microsoft-Windows-Security-Auditing "
|
||||
f"winlog.event_data.LogonType=3 process.name=proc{index % 3}.exe"
|
||||
)
|
||||
for index in range(1, 30)
|
||||
]
|
||||
|
||||
profile = suggest_stream_profiles(events)[0]["profile"]
|
||||
|
||||
self.assertEqual(profile["timestamp_field"], "eventtime")
|
||||
self.assertEqual(profile["entity_fields"][:3], ["username", "hostname", "srcip"])
|
||||
self.assertIn("eventid", profile["categorical_fields"])
|
||||
self.assertIn("action", profile["categorical_fields"])
|
||||
self.assertIn("event.category", profile["categorical_fields"])
|
||||
self.assertIn("winlog.channel", profile["categorical_fields"])
|
||||
self.assertIn("process.name", profile["categorical_fields"])
|
||||
self.assertNotIn("user.name", profile["categorical_fields"])
|
||||
self.assertNotIn("source.ip", profile["categorical_fields"])
|
||||
self.assertIn("auth_failure", profile["detectors"])
|
||||
|
||||
def test_discovers_non_priority_application_fields(self):
|
||||
|
||||
Reference in New Issue
Block a user