Skip to content
By Shahrukh Khan··3 min read

I got tired of waiting for attacks to test my detection rules

You write a Wazuh rule, and then you wait for something to trigger it. Maybe that happens this week. Maybe the rule sits there with a typo in it for two months. LogGen is what I built to close that gap.

The problem with testing detection rules

You write a Wazuh rule on a Tuesday afternoon. It looks right. The regex is sound, the field names match the decoder, the severity is sensible. Now what?

You wait. You wait for somebody to fail a login enough times, or for a firewall to see traffic it does not like, or for a Mac in the finance team to download something Gatekeeper refuses to run. Maybe that happens this week. Maybe the rule sits there for two months with a typo in it and nobody finds out until the day it was supposed to fire and did not.

That is the gap I kept running into, and it is why I built LogGen.

What it does

LogGen generates correctly structured log records for the sources you actually onboard, then ships them over syslog to your SIEM. You click a control, the record goes on the wire, and you watch your rule fire. No waiting, no test environment, no attack simulation against your own estate.

It is a single static binary written in Go with zero third party dependencies. Download it, run it, open the console. There is no runtime to install and nothing to configure before the first record goes out.

The LogGen console with a Windows record on the wire

The catalogue currently sits at 348 controls across 16 log sources. Windows Security events with real event IDs and matching EventData. Linux auth and sudo. Nginx and Apache. Oracle audit trails. Palo Alto, FortiGate, Sophos, Cisco ASA and FTD. Trend Micro Vision One. CrowdStrike Falcon, SentinelOne, AWS CloudTrail. macOS, which matters more than people expect once you have a Mac fleet and no idea what normal looks like on it.

Why the formats are the point

It would have been much faster to write plausible looking log lines. I did not, because a record that does not match what the real device emits is worse than no record at all.

Think about what happens. You write a rule against a fake format. It passes in the lab. You ship it. The real device sends something slightly different, a field in a different position or a key spelled another way, and the rule never fires. You now have a rule you trust and a blind spot you do not know about. That is worse than having written nothing.

So every source in LogGen is researched against vendor documentation before a line of Go is written, and every source file states plainly which parts of the format are confirmed and which are inferred. Where I could not reach the authoritative field table, the file says so rather than looking authoritative.

One consistent fake organisation

Every record refers to the same invented estate: a domain, a Windows host, a Linux host, a Mac, a web server, a database, a firewall, a subnet. This sounds like a detail and it is not.

Without it, each source would invent its own hostnames, and a Windows logon, a sudo call and an Nginx hit would look like three unrelated companies. Correlation rules would never fire, because there would be nothing to correlate on. With it, a rule that joins a failed Windows logon to a privilege escalation on the same subnet has something to join.

The domain also seeds the SIDs. The same user keeps the same SID across restarts, so a rule matching a specific SID stays valid between sessions.

The LogGen administration screen

Controls you define yourself

The built in catalogue will not cover everything. If you have a bespoke application writing its own format, or a vendor I have not got to yet, you can define a control in the console: pick a source, write a template with placeholder tokens, declare the parameters you want to fill in before sending, and it appears alongside the built in ones. They persist to disk and survive restarts.

Where it is

LogGen is open source under MIT at github.com/theshahrukh98khan/LogGen. It runs on Windows and Linux, x86-64 and ARM64, and there is a container image if you prefer that.

It writes synthetic records to a SIEM you control, for validating parsers and detection logic in a lab you own. It is not an attack tool and it performs no exploitation of anything.

If you try it and something is missing, or a format does not match what your own devices send, tell me. The formats are the part I most want to be wrong about in public, because that is how they get fixed.

  • Testing a Wazuh rule end to end without waiting for an attack

    Prove the pipe before you trust a rule, remember that Wazuh does not listen for syslog by default, read the archives log before the alerts log, and always test the negative case. Most of the time lost onboarding a log source goes on not knowing which half of the chain is broken.

  • Getting log formats right is the whole job

    A detection rule written against a format that does not match the real device passes in the lab and never fires in production. Notes from building 16 log sources: CEF that is not CEF, positional CSV where order is everything, and a published sample that turned out to be hand edited.

  • Essential SOC Tools and Technologies

    Explore the essential tools used by SOC analysts, including SIEM, EDR, SOAR, TIPs, XDR, CSPM, UEBA, and vulnerability scanners.

● introducing shahrukhOS · crafted for a new perspective
© 2026 · shipped through vibecoding