Monitoring my Windows endpoints is where Active Directory, the firewall and the SIEM meet. A single failed logon on a file server is just a line in a log. It becomes something I can work with once it has been collected, decoded, matched to a rule, raised as an alert and put in front of me as a case with its evidence attached.
SOCFortress CoPilot is the centre of this design: the one queue where alerts from Wazuh and Graylog become cases. The path follows the SOCFortress reference stack. My 8 November inventory lists no running Wazuh or CoPilot guest (a container named wazuh was stopped on 1 November), so the alerts below are worked examples; the commands are the real ones for each step. The SOC service catalog shows every service in the stack and what each one does.
Windows endpoints
- Wazuh
- SOCFortress CoPilot
Active Directory
- Wazuh
- Sophos Firewall
Graylog
- SOCFortress CoPilot
Windows endpoints
Splunk
Windows endpoints
- Defender for Endpoint
Windows events feed Wazuh, Sophos syslog feeds Graylog, and both feed CoPilot. Splunk and Defender for Endpoint hang off the Windows endpoints on their own lines because they are parallel views, not stages after Wazuh.
Open the full lab consoleCollection: getting events into Wazuh
On Windows, the Wazuh agent reads the event channels it is configured for, such as Security and System, and ships them to the Wazuh manager. PowerShell logging needs its own channel added. The firewall cannot run an agent, so Sophos sends its log over syslog to the manager instead. Both inputs are documented setups; the check I care about is that each source actually arrives.
Before trusting an empty dashboard, I make sure the agent on the endpoint is running. Missing data and quiet machines look the same from the SIEM.
Get-Service -Name WazuhSvc | Select-Object Status, StartTypeShow output
Status StartType
------ ---------
Running AutomaticExample output. If the service is stopped, the absence of alerts from that machine means nothing.
Analysis: from event to alert
The manager decodes each event into fields (event ID, account, logon type, source workstation) and runs them through rules. A single 4625 is low severity; several from the same source in a short window match a rule for repeated failures and raise the level. The indexer stores the alerts, and the dashboard shows them. Those are four roles, and when something is missing it helps to know which one to blame.
Cases: from alert to CoPilot
CoPilot reads alerts from the Wazuh indexer through its connector and puts them in an alert queue. From there I group related alerts into a case, attach the evidence, and record what I decided. The case is the part that outlives the dashboard: it says what happened, what I looked at, and why I closed or escalated it.
| Hand-off | Source | Destination | What it is for | How I verify it |
|---|---|---|---|---|
| Endpoint to Wazuh | Wazuh agent | Wazuh manager | Windows Security and System events, plus any channels added | A test logon failure appears within the expected interval |
| Firewall to Graylog | Sophos syslog | Graylog input | Allow, drop, IPS and threat-feed records | A test drop from a known host appears with its rule name parsed into a field |
| Wazuh to CoPilot | Wazuh indexer | CoPilot alert queue | Alerts for triage | Alert counts match the Wazuh dashboard for the same window |
| Graylog to CoPilot | Graylog | CoPilot alert queue | Firewall events worth a case | The same test drop shows up linked to the right asset |
| Alert to case | CoPilot | Case record | Evidence and decisions | The case lists its alerts and a disposition |
The SOC-0142 case walks through that last step with a simulated cluster of failed logons, and the lab console has the alert queue it comes from.
One burst of failures, traced into two alerts
This is the comparison I wanted the design to make easy: the endpoint’s view and the SIEM’s view of the same thing. It uses the first exercise from the AD entry: 12 wrong passwords for one lab account, in two bursts.
Worked example · invented times, example rule and threshold
| # | Time | Account | Sub status | Workstation | What the rule did |
|---|---|---|---|---|---|
| 1 | 08:14:00 | student01 | 0xC000006A | WS-02 | counts toward alert 1 |
| 2 | 08:14:12 | student01 | 0xC000006A | WS-02 | counts toward alert 1 |
| 3 | 08:14:25 | student01 | 0xC000006A | WS-02 | counts toward alert 1 |
| 4 | 08:14:38 | student01 | 0xC000006A | WS-02 | counts toward alert 1 |
| 5 | 08:14:51 | student01 | 0xC000006A | WS-02 | counts toward alert 1 |
| 6 | 08:15:04 | student01 | 0xC000006A | WS-02 | Alert 1 raised |
| 7 | 08:20:00 | student01 | 0xC000006A | WS-02 | counts toward alert 2 |
| 8 | 08:20:13 | student01 | 0xC000006A | WS-02 | counts toward alert 2 |
| 9 | 08:20:26 | student01 | 0xC000006A | WS-02 | counts toward alert 2 |
| 10 | 08:20:39 | student01 | 0xC000006A | WS-02 | counts toward alert 2 |
| 11 | 08:20:52 | student01 | 0xC000006A | WS-02 | counts toward alert 2 |
| 12 | 08:21:05 | student01 | 0xC000006A | WS-02 | Alert 2 raised |
The endpoint holds 12 events and the SIEM shows two alerts, and both are right. Three things only make sense side by side:
- The alert count is not the attempt count. Each alert means “the threshold was crossed”, not “six things happened”. A burst of 30 failures would still be a handful of alerts.
- The sub status lives on the endpoint. All 12 are 0xC000006A: a real account and a wrong password. That points at a person or a saved credential, not someone guessing usernames.
- The gap is the lead. Alert 1 fires at 08:15:04, and the next failure comes at 08:20:00. A retry on a fixed timer, such as a mapped drive with an old password, produces a gap like that every time; a person retyping does not.
Does a test failure arrive in the SIEM at all?
Practice walkthrough · substituted names and addresses- Objective
- Prove that a Windows Security event travels from the endpoint into the SIEM before trusting a quiet dashboard.
- Lab scope
- One lab workstation, the lab test account, and the SIEM search for that host.
- Technique
- Generate one failed logon on purpose at a time I write down, then look for it in the SIEM.
- Command or action
- PowerShell · Lab workstation · read-only
Get-WinEvent -FilterHashtable @{ LogName = 'Security'; Id = 4625 } -MaxEvents 1 | Select-Object TimeCreated, MachineName - Windows evidence
- One event 4625 on the workstation at the time I wrote down.
- SIEM finding
- The same event, with the same time and host, within the collection interval. Nothing arriving means the collection is broken, not that the endpoint is quiet.
- Response
- If it is missing, check the agent or forwarder service on the endpoint first, then the receiving side.
- Result
- Practice walkthrough. No recorded run yet.
For the same path driven from the attacking side, see the Kali Red and Blue walkthroughs: a bounded failed-logon test traced from event 4625 through Wazuh into a CoPilot case.
What I learned
Designing the hand-offs taught me to ask every alert two questions: which events made it, and which events it left out. The SIEM is good at telling me that a pattern happened. The endpoint is where I find out why.
Takeaway: when an alert fires, open the raw events behind it before deciding anything. Count them, read the sub status, and look at the spacing between them.
Further reading: Wazuh architecture · CoPilot project · CoPilot docs · Sophos syslog server setup
Skills used
- Choosing which Windows events to collect, and why
- Tracing an alert back to the events behind it
- Separating firewall logs from endpoint logs in one case
Tools in this entry
- Wazuh External reference
Official documentation for Wazuh - SOCFortress CoPilot External reference
Official documentation for SOCFortress CoPilot Graylog External reference
Official documentation for Graylog- Sophos Firewall In my lab
Official documentation for Sophos Firewall Windows security auditing I use it
Official documentation for Windows security auditing