Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,14 @@ jobs:
- uses: actions/checkout@v4
- name: Test
run: ./tests/test-linux.sh

macos:
strategy:
fail-fast: false
matrix:
os: [macos-14, macos-15]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Test
run: sudo ./tests/test-macos.sh
34 changes: 23 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ WinLogs turns on the telemetry you want **before** you detonate malware, validat

Built for disposable VMs: malware analysis sandboxes, DFIR and threat-hunting practice, Sigma rule testing, purple-team and blue-team labs. **Do not run it on production or work machines.** It turns on very verbose logging.

**Scope:** logging only. WinLogs configures the logs and the components that produce and keep them (audit policy, Sysmon, `auditd`, `eslogger`, retention). Other tooling, such as network capture, endpoint query tools or evidence collectors, belongs in a separate setup stage that can read the logs this one produces.

## Quick start

**Windows 10 / 11 / Server 2022 / 2025** (elevated PowerShell 5.1 or 7):
Expand All @@ -22,18 +24,26 @@ sudo ./linux/install.sh --dry-run # preview
sudo ./linux/install.sh --revert # undo
```

**macOS 13+** (as root; nothing to download):
```bash
sudo ./macos/install.sh # asks for confirmation, then applies everything
sudo ./macos/install.sh --dry-run # preview
sudo ./macos/install.sh --revert # undo
```
`eslogger` needs Full Disk Access, which macOS only lets a person grant by hand; the installer tells you exactly where. See [docs/logged-macos.md](docs/logged-macos.md).

## What you get

| | Windows | Linux |
|---|---|---|
| Audit policy | Advanced audit policy via `auditpol` (logon, account and group management, process creation 4688 with command line, object access, policy change, DPAPI, SAM, ...) plus a Server profile (Kerberos, Directory Service) | `auditd` with the [Neo23x0 ruleset](https://github.com/Neo23x0/auditd): exec, file, network, privilege and persistence rules |
| Scripting visibility | PowerShell Script Block (4104), Module (4103) and Transcription logging for Windows PowerShell and PowerShell 7 | Interactive bash commands logged to syslog |
| Process / network / DNS / file telemetry | **Sysmon** with the [sysmon-modular](https://github.com/olafhartong/sysmon-modular) config (on by default) | `auditd` execve rules; **Sysmon for Linux** is opt-in with `--with-sysmon` |
| Retention | Event logs raised to 1 GB for Security, Sysmon and PowerShell; Task Scheduler, DNS-Client and more channels enabled | `auditd` keeps 10 x 200 MB with synchronous writes; `journald` persistent with rate limiting off |
| Object auditing | Per-object audit rules (SACLs) on persistence and tamper-prone registry keys and folders | n/a (covered by `auditd` watches) |
| Undo | `-Revert` | `--revert` |
| | Windows | Linux | macOS |
|---|---|---|---|
| Audit policy | Advanced audit policy via `auditpol` (logon, account and group management, process creation 4688 with command line, object access, policy change, DPAPI, SAM, ...) plus a Server profile (Kerberos, Directory Service) | `auditd` with the [Neo23x0 ruleset](https://github.com/Neo23x0/auditd): exec, file, network, privilege and persistence rules | Apple's `eslogger` (Endpoint Security) as a LaunchDaemon: exec, file create/delete/rename, persistence items, XProtect, logins, sudo/su, profile and TCC changes |
| Scripting visibility | PowerShell Script Block (4104), Module (4103) and Transcription logging for Windows PowerShell and PowerShell 7 | Interactive bash commands logged to syslog | Interactive zsh commands logged to the unified log |
| Process / network / DNS / file telemetry | **Sysmon** with the [sysmon-modular](https://github.com/olafhartong/sysmon-modular) config (on by default) | `auditd` execve rules; **Sysmon for Linux** is opt-in with `--with-sysmon` | `eslogger` JSON events (no Sysmon equivalent; no network connect events) |
| Retention | Event logs raised to 1 GB for Security, Sysmon and PowerShell; Task Scheduler, DNS-Client and more channels enabled | `auditd` keeps 10 x 200 MB with synchronous writes; `journald` persistent with rate limiting off | `/var/log/winlogs/eslogger.ndjson` rotated at 100 MB x 10; optional daily unified-log archives |
| Object auditing | Per-object audit rules (SACLs) on persistence and tamper-prone registry keys and folders | n/a (covered by `auditd` watches) | n/a (covered by `eslogger` file events) |
| Undo | `-Revert` | `--revert` | `--revert` |

Details and event IDs: [docs/what-gets-logged.md](docs/what-gets-logged.md).
Per-OS details, event IDs and limits: [Windows](docs/logged-windows.md) · [Linux](docs/logged-linux.md) · [macOS](docs/logged-macos.md) · [side-by-side overview](docs/what-gets-logged.md).

## Air-gapped labs

Expand All @@ -47,19 +57,21 @@ Sysmon is Microsoft software that this repo does not redistribute, and lab machi
sudo ./linux/prepare-offline.sh ./winlogs-offline # run on a machine matching the lab image
sudo ./linux/install.sh --offline-dir ./winlogs-offline # verified against SHA256SUMS
```
macOS needs no offline step: it only uses tools that ship with the OS.

## Tested

CI runs the full install, verify-events and revert cycle on Windows Server 2022 and 2025 (Windows PowerShell 5.1 and PowerShell 7), Windows 11 on ARM64, and Ubuntu 22.04 and 24.04. The Fedora job runs in a container, so it covers package install, config and revert but not live auditing.
CI runs the full install, verify-events and revert cycle on Windows Server 2022 and 2025 (Windows PowerShell 5.1 and PowerShell 7), Windows 11 on ARM64, Ubuntu 22.04 and 24.04, and macOS 14 and 15 (Apple silicon). The Fedora job runs in a container, so it covers package install, config and revert but not live auditing.

Not yet tested: Windows 10 and x64 Windows 11 client builds, a real domain controller, RHEL-family live auditing (Rocky/Alma), Debian, Kali, openSUSE, Arch, and Sysmon for Linux. Treat the first run as a test inside a snapshot-able VM. macOS is planned.
Not yet tested: Windows 10 and x64 Windows 11 client builds, a real domain controller, RHEL-family live auditing (Rocky/Alma), Debian, Kali, openSUSE, Arch, and Sysmon for Linux, and on macOS: Intel Macs, macOS 13, and a Mac where Full Disk Access has not been granted. Treat the first run as a test inside a snapshot-able VM.

## Related projects

Maintained logging guidance and tools worth knowing, and what inspired this one:
- [Yamato-Security/EnableWindowsLogSettings](https://github.com/Yamato-Security/EnableWindowsLogSettings): Windows log settings aimed at Sigma coverage
- [olafhartong/sysmon-modular](https://github.com/olafhartong/sysmon-modular): modular Sysmon configs
- [Neo23x0/auditd](https://github.com/Neo23x0/auditd): best-practice auditd rules
- [Cybereason: Blue teaming on macOS with eslogger](https://www.cybereason.com/blog/blue-teaming-on-macos-with-eslogger): how Apple's `eslogger` is used for detection and analysis
- [Malware Archaeology logging cheat sheets](https://www.malwarearchaeology.com/cheat-sheets) and [Log-MD](https://www.log-md.com/): the original inspiration (the core Windows sheet dates from 2019)
- [Microsoft Sysmon documentation](https://learn.microsoft.com/windows-server/administration/windows-commands/sysmon) and [advanced security auditing](https://learn.microsoft.com/windows/security/threat-protection/auditing/advanced-security-auditing)

Expand Down
2 changes: 2 additions & 0 deletions THIRD_PARTY.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@
Rule for this repo: only bundle what the license clearly allows, and keep each license text next to the file.
Anything else is fetched by the user, with a signature or SHA-256 check.

The Linux ruleset is bundled as `linux/audit/neo23x0-audit.rules` with its Apache-2.0 license next to it. Sysmon for Linux is installed from Microsoft's package repo and never bundled. macOS bundles nothing: it uses `eslogger` and other tools that ship with the OS.

The WinLogs scripts and docs themselves are MIT licensed; see `LICENSE`.
42 changes: 42 additions & 0 deletions docs/logged-linux.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Linux: what gets logged

See also: [Windows](logged-windows.md) · [macOS](logged-macos.md) · [overview](what-gets-logged.md)

`linux/install.sh` (run with `sudo`) supports Debian/Ubuntu/Kali (`apt`), RHEL/Fedora/Rocky/Alma (`dnf`/`yum`), openSUSE (`zypper`) and Arch (`pacman`). CI exercises Ubuntu 22.04 and 24.04 on real VMs and Fedora in a container.

## What it turns on

| Piece | How | Where to look |
|---|---|---|
| Audit rules | `auditd` plus the [Neo23x0 ruleset](https://github.com/Neo23x0/auditd) (Apache-2.0), installed as `/etc/audit/rules.d/90-winlogs.rules`; `UID_MIN` is read from `/etc/login.defs` | `ausearch -k <key>`, `/var/log/audit/audit.log` |
| Audit retention | `max_log_file = 200` (MB), `num_logs = 10`, rotate, `flush = SYNC` so events hit disk immediately | `/etc/audit/auditd.conf` |
| journald | Persistent storage (`/var/log/journal`), `SystemMaxUse` 2G by default (`--journal-size`), rate limiting off so bursts are not dropped | `journalctl`, `/etc/systemd/journald.conf.d/90-winlogs.conf` |
| Shell commands | Interactive bash commands logged to syslog, facility `local6`, tag `winlogs-cmd` (`--no-shell-logging` skips it) | `journalctl -t winlogs-cmd` or `/var/log/syslog` |
| Sysmon for Linux (opt-in) | `--with-sysmon` installs Microsoft's package and a small config (process create/terminate, network connect, file create/delete); experimental, not bundled | syslog (`/var/log/syslog` or the journal) |
| Auditing switched on | The last step runs `auditctl -e 1` (restarting journald on Ubuntu 22.04 turns kernel auditing back off) | `auditctl -s` shows `enabled 1` |

## What the audit rules cover

Rule keys in the Neo23x0 set, grouped. Use them with `ausearch -k <key>`.

- **Process execution:** `process_creation` (every `execve`/`execveat`; the highest-volume rule), `32bit_abi`, `process_vm`, `tracing`, `userfaultfd`
- **Persistence and startup:** `cron`, `systemd`, `init`, `udev`, `shell_profiles`, `systemwide_preloads`, `libpath`, `boot_writes`, `sysconfig`, `svc_defaults`
- **Accounts and authentication:** `etcpasswd`, `etcgroup`, `rootkey`, `sshd`, `pam`, `login`, `session`
- **Files and permissions:** `file_creation`, `file_modification`, `file_access`, `perm_mod`, `delete`, `specialfiles`, `bin_writes`, `usr_writes`, `unauthedfileaccess`, `T1070_006_timestomp`
- **Kernel and tampering:** `modules`, `modprobe`, `KEXEC`, `bpf`, `socket_bpf_filter_attached`, `io_uring`, `sysctl`, `mac_policy`, `namespaces`, `auditlog`, `auditconfig`
- **Network:** `network_socket_created`, `raw_network_socket_created`, `network_modifications`, `firewall`, `network`
- **Containers:** `docker`, `containers`
- **Package and software changes:** `software_mgmt`

The ruleset is broad on purpose. If volume is a problem, comment out `process_creation` or the `file_*` rules in `/etc/audit/rules.d/90-winlogs.rules` and run `sudo augenrules --load`.

## Good to know

- **Kernel and container limits:** auditing needs a real kernel audit subsystem. In a container the install warns instead of failing, and no audit events are produced.
- **Shell logging** covers interactive bash only and is easy for an attacker to bypass; treat it as a convenience, not evidence.
- **Reboots:** the rules persist through `rules.d`, and journald and auditd start at boot.
- **Offline:** `linux/prepare-offline.sh` downloads the packages with a `SHA256SUMS` file; `install.sh --offline-dir DIR` verifies it first. Run it on a machine that matches the lab image.
- **Revert:** `sudo ./linux/install.sh --revert` restores edited files from backups and removes the ones it created. Installed packages are left in place.

## Not yet verified
Rocky/Alma (RHEL-family live auditing), Debian, Kali, openSUSE, Arch, and `--with-sysmon`.
37 changes: 37 additions & 0 deletions docs/logged-macos.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# macOS: what gets logged

See also: [Windows](logged-windows.md) · [Linux](logged-linux.md) · [overview](what-gets-logged.md)

`macos/install.sh` (macOS 13 Ventura or newer, run with `sudo`) uses only tools that ship with macOS, so there is nothing to download and no offline bundle to prepare.

## What it turns on

| Piece | How | Where to look |
|---|---|---|
| Endpoint Security events | Apple's `eslogger` runs as a LaunchDaemon (`com.winlogs.eslogger`) writing newline-delimited JSON | `/var/log/winlogs/eslogger.ndjson` (rotated at 100 MB, 10 kept, gzip, by `newsyslog`) |
| zsh command history | A marker block in `/etc/zshrc` logs each interactive command through `logger` | `log show --predicate 'eventMessage contains "winlogs-cmd"'` |
| Application firewall logging | `socketfilterfw --setloggingmode on` (previous mode restored on revert) | unified log / `/var/log/appfirewall.log` on older releases |
| Unified log snapshots (opt-in, `--with-log-archive`) | Daily `log collect --last 1d`, pruned after `--keep-days` (default 7) | `/var/log/winlogs/unified-YYYY-MM-DD.logarchive` |

Event types recorded (those this macOS supports; the list is checked against `eslogger --list-events` at install time): process exec, file create/unlink/rename, mount, kext load, background-item (persistence) add/remove, XProtect malware detected/remediated, logins (local, ssh, screen sharing), sudo/su, profile install/remove, Gatekeeper overrides, TCC changes, remote thread creation, code-signature invalidation, and local account/group changes.

## One manual step: Full Disk Access

`eslogger` is an Endpoint Security client, and macOS only lets a person (or an MDM) grant it Full Disk Access:

System Settings > Privacy & Security > Full Disk Access > `+` > press Cmd+Shift+G > `/usr/bin/eslogger`

Then restart it: `sudo launchctl kickstart -k system/com.winlogs.eslogger`.
The installer checks the daemon's error output and prints this reminder when access is missing. CI runners come with permissions already granted, so a green CI run does not prove a fresh Mac is configured.

## Limits worth knowing

- **No Sysmon equivalent and no network connection events.** Endpoint Security has no TCP/UDP connect event, so this project cannot log connections on macOS. Collecting network telemetry is out of scope here; if you need it, handle it in a separate setup stage.
- **OpenBSM (`audit`) is deliberately not used.** It is deprecated; `eslogger` is Apple's replacement.
- **Unified log redaction.** Many messages show `<private>` values. Turning private data on needs a configuration profile or reduced SIP, which this script does not do.
- **Log rotation gap.** After `newsyslog` rotates the file, `eslogger` is restarted by launchd, so a few seconds of events can be missed at rotation time.
- **Shell logging covers zsh only** (the default shell) and is easy for an attacker to bypass.
- `/etc/zshrc` is edited between marker comments; `--revert` restores the original file exactly.

## Not yet verified
Intel Macs, macOS 13, and behaviour on a Mac where Full Disk Access has not been granted. CI covers macOS 14 and 15 on Apple silicon.
41 changes: 41 additions & 0 deletions docs/logged-windows.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Windows: what gets logged

See also: [Linux](logged-linux.md) · [macOS](logged-macos.md) · [overview](what-gets-logged.md)

| Area | Setting | Where to look |
|---|---|---|
| Audit policy | `windows/audit.csv` via `auditpol /restore` (logon, account/group mgmt, process creation/termination, object access, policy change, sensitive privilege use, ...) | Security log |
| Command lines | `ProcessCreationIncludeCmdLine_Enabled=1` | Security 4688 |
| Legacy override | `SCENoApplyLegacyAuditPolicy=1` so advanced audit policy wins | n/a |
| PowerShell | Script Block (incl. invocation start/stop), Module (`*`), Transcription to `C:\ProgramData\WinLogs\transcripts`; set for Windows PowerShell and PowerShell 7 | Microsoft-Windows-PowerShell/Operational 4103/4104, transcript files |
| Sysmon | sysmon-modular balanced config (process, network, DNS, image load, registry, WMI, pipes, ...) | Microsoft-Windows-Sysmon/Operational |
| Channels enabled / enlarged | Task Scheduler, DNS-Client, DriverFrameworks-UserMode (usually off); Defender, WMI-Activity, BITS-Client, Firewall, TerminalServices, CodeIntegrity, NTLM, Security-Mitigations, PrintService, SmbClient Security, AppLocker (4 logs), Diagnosis-Scripted, PowerShellCore, System, Application | each channel |
| Sizes | Security, Sysmon, PowerShell: `-LogSizeMB` (default 1024). Others: up to 256 MB. Logs are never shrunk. | n/a |

## Client vs Server

`Install-WinLogs.ps1` picks an audit profile automatically (`-AuditProfile Auto|Workstation|Server`):

| | Windows 10 / 11 | Windows Server (incl. domain controllers) |
|---|---|---|
| Base policy (`audit.csv`) | yes | yes |
| Kerberos Authentication Service and Service Ticket Operations (4768/4769/4771...), Directory Service Access, Directory Service Replication (`audit-server.csv`) | no (these only generate events on a DC) | yes |
| Extra channels | n/a | Directory Service, DNS Server, DNS Server Audit, DFS Replication (only if the role is installed) |

## Audit policy changes from the original 2016 baseline
Added: PNP Activity (USB / device insertion, 6416), Group Membership (4627), and Other Object Access Events set to Success and Failure (scheduled task creation 4698/4702).
Turned on: SAM (4661 handle requests to the SAM), Other Policy Change Events, MPSSVC Rule-Level Policy Change (firewall rule changes, 4946-4948), DPAPI Activity (4692/4693).
Still off on purpose because they are very noisy: Handle Manipulation, Non Sensitive Privilege Use, Other Privilege Use, Filtering Platform Packet Drop, Detailed Directory Service Replication.

## Per-object auditing (SACLs)
The File System and Registry audit categories only log access to objects that carry an audit rule. `windows/sacls.psd1` lists what gets one (success audit for Everyone) and is meant to be edited:
- Registry: Run / RunOnce (native and WOW6432Node), Policies\Explorer\Run, Active Setup, Winlogon, Windows (AppInit_DLLs), Services, Session Manager, Image File Execution Options, SilentProcessExit, Lsa, SecurityProviders (WDigest), and the Defender policy key. Events: 4657 (value change), 4656/4663.
- Files: the all-users StartUp folder, `System32\Tasks`, `System32\drivers`, and the hosts file. Events: 4663 (and 4656).
- Per-user hives (HKCU Run keys) are not covered, since each user's hive is only loaded while that user is signed in.
- Tamper-protected keys (for example Defender) may refuse the rule; that is reported as a warning and the run continues.
- `-SkipObjectAuditing` leaves these out; `-Revert` removes exactly the rules it added.

Notes
- Filtering Platform Connection (5156/5158) is very noisy and overlaps Sysmon event 3. Remove that row from `audit.csv` if logs roll too quickly.
- Transcripts are plain files that malware running as admin can delete. Fine for a lab, not evidence-grade.
- Everything is recorded in `C:\ProgramData\WinLogs\state.json`; `-Revert` restores it.
Loading
Loading