#!/usr/bin/env python3 """Emit synthetic Windows Security-style JSONL events for Graylog/Filebeat testing.""" from __future__ import annotations import argparse import json import random import time from datetime import UTC, datetime from pathlib import Path EVENTS = [4624, 4625, 4634, 4672, 4688] USERS = ["alice", "bob", "svc_backup", "administrator"] HOSTS = ["WIN-CLIENT-01", "WIN-CLIENT-02", "WIN-SRV-01"] def event() -> dict[str, object]: event_id = random.choices(EVENTS, weights=[45, 25, 15, 5, 10])[0] failed = event_id == 4625 return { "timestamp": datetime.now(UTC).isoformat(), "event_id": event_id, "user": random.choice(USERS), "hostname": random.choice(HOSTS), "source_ip": f"192.168.1.{random.randint(20, 90)}", "logon_type": random.choice([2, 3, 10]), "status": "failure" if failed else "success", "action": "deny" if failed else "accept", "event_provider": "Microsoft-Windows-Security-Auditing", "stream_hint": "Windows", "synthetic": True, "message": "Synthetic Windows Security event generated by SignalScope test harness", } def main() -> int: parser = argparse.ArgumentParser() parser.add_argument("--output", default="logs/windows-synthetic.jsonl") parser.add_argument("--interval", type=float, default=1.0) parser.add_argument("--count", type=int, default=0, help="0 runs until interrupted") args = parser.parse_args() path = Path(args.output); path.parent.mkdir(parents=True, exist_ok=True) emitted = 0 with path.open("a", encoding="utf-8", buffering=1) as handle: while not args.count or emitted < args.count: handle.write(json.dumps(event()) + "\n"); emitted += 1; time.sleep(args.interval) return 0 if __name__ == "__main__": raise SystemExit(main())