diff --git a/README.md b/README.md index 2f01486..4b501f2 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ sudo ./macos/install.sh --revert # undo | 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` | -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). +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) · [comparison with STIG and CIS](docs/baseline-comparison.md). ## Air-gapped labs diff --git a/docs/baseline-comparison.md b/docs/baseline-comparison.md new file mode 100644 index 0000000..9916985 --- /dev/null +++ b/docs/baseline-comparison.md @@ -0,0 +1,23 @@ +# How this compares to STIG and CIS baselines + +WinLogs is **not** a STIG or CIS implementation and does not try to be. Those baselines mix two things: *what to log* and *how to harden the system*. This project aims to log **at least everything they require, and more**, and it deliberately ignores the hardening parts that get in the way of a disposable lab. + +Sources checked: the DISA Windows 11 STIG, the RHEL 9 STIG, the macOS 14/15 STIGs, and CIS Windows 11 Benchmark v5 (via public mirrors of the benchmark text, not DISA's own files, so confirm against the release you care about). Only the items below were confirmed; this is a comparison of the logging requirements we could read, not a certification. + +## What we log beyond the baselines +- **Windows:** Success and Failure on every audit subcategory that can fail, per-object audit rules on persistence and tamper-prone registry keys and folders, PowerShell Script Block, Module and Transcription logging for Windows PowerShell and PowerShell 7, Sysmon, and a long list of operational channels (WinRM, RDP, LSA, DeviceGuard, SMB, NTLM, AppLocker, PrintService, ...). +- **Linux:** the Neo23x0 best-practice ruleset (every `execve`, file, network, kernel-module, BPF and container rules), plus privileged-execution keys, with synchronous audit writes and a persistent, unthrottled journal. +- **macOS:** Endpoint Security events through `eslogger` (a wider set than the legacy audit flags), including task-port access, ptrace, permission changes and authorization decisions. + +## Where we deliberately differ + +| Topic | Baselines | WinLogs | Why | +|---|---|---|---| +| Security log size (Windows) | CIS: at least 196,608 KB. Current STIG: one week of records (its example is 5,120,000 KB); older STIG: 1,024,000 KB | 1 GiB (1,048,576 KB) by default; `-LogSizeMB` raises it | Meets CIS and the older STIG figure. Raise `-LogSizeMB` for a week of a busy host. | +| Audit rules immutable (Linux STIG) | `-e 2`, rules locked until reboot | `-e 1` | Rules must stay editable and revertable in a lab. | +| Disk full action (Linux STIG) | halt / single-user | distro default | Halting a machine mid-detonation destroys the evidence. | +| Central forwarding (CIS, STIG) | forward events to a collector | not done | Labs are usually air-gapped; forwarding is a separate stage. | +| macOS audit system | legacy OpenBSM flags in `audit_control` (`aa`, `ad`, `lo`, ...) and `expire-after:7d` | `eslogger` (Endpoint Security) | Apple deprecated the audit system (macOS 11) and disables it from macOS 14; `eslogger` is the supported replacement. Retention is by size, not days. | +| Log-size scanners (Windows) | read the Event Log *policy* value | we set both the channel and the policy value | Policy overrides the channel setting, so a policy refresh cannot shrink our logs. | + +A STIG or CIS scanner will still report findings against this setup for the hardening items above. That is expected. diff --git a/docs/logged-linux.md b/docs/logged-linux.md index b720952..1f33d8c 100644 --- a/docs/logged-linux.md +++ b/docs/logged-linux.md @@ -8,7 +8,7 @@ See also: [Windows](logged-windows.md) · [macOS](logged-macos.md) · [overview] | 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 `, `/var/log/audit/audit.log` | +| Audit rules | `auditd` plus the [Neo23x0 ruleset](https://github.com/Neo23x0/auditd) (Apache-2.0), installed as `/etc/audit/rules.d/90-winlogs.rules` (plus `91-` extras and a `99-` enable file); `UID_MIN` is read from `/etc/login.defs` | `ausearch -k `, `/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` | @@ -28,6 +28,8 @@ Rule keys in the Neo23x0 set, grouped. Use them with `ausearch -k `. - **Containers:** `docker`, `containers` - **Package and software changes:** `software_mgmt` +WinLogs adds `linux/audit/winlogs-extra.rules` (installed as `91-winlogs-extra.rules`): the password-history file, `execpriv` (setuid/setgid binaries running as root) and `exec_as_root` (a logged-in human running something as root). A third file, `99-winlogs-enable.rules`, switches auditing on. + 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 diff --git a/docs/logged-macos.md b/docs/logged-macos.md index 92bb025..afef631 100644 --- a/docs/logged-macos.md +++ b/docs/logged-macos.md @@ -13,7 +13,7 @@ See also: [Windows](logged-windows.md) · [Linux](logged-linux.md) · [overview] | 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. +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, local account/group changes, file permission, ownership, flag, ACL and extended-attribute changes, hard links, clones and copies, system time changes, ptrace, task-port access (`get_task`), process suspend/resume, and authorization decisions. ## One manual step: Full Disk Access diff --git a/docs/logged-windows.md b/docs/logged-windows.md index 3dc6210..1ab5312 100644 --- a/docs/logged-windows.md +++ b/docs/logged-windows.md @@ -9,8 +9,8 @@ See also: [Linux](logged-linux.md) · [macOS](logged-macos.md) · [overview](wha | 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 | +| Channels enabled / enlarged | Task Scheduler, DNS-Client, DriverFrameworks-UserMode (usually off); Defender, WMI-Activity, BITS-Client, Firewall, TerminalServices, CodeIntegrity, NTLM, WinRM, RDP client and RdpCoreTS, LSA, DeviceGuard, Netlogon, SMB Server, Shell-Core, AppX deployment, Winlogon, 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. Security, System and Application also get the Event Log *policy* size value, which overrides the per-channel setting, so a policy refresh cannot shrink them. | n/a | ## Client vs Server @@ -22,14 +22,16 @@ See also: [Linux](logged-linux.md) · [macOS](logged-macos.md) · [overview](wha | 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. +## Audit policy +Everything we audit that can fail is audited for **Success and Failure**: failed attempts (denied access, lockouts, rejected IPsec, system faults) are often the first sign of something wrong. +- Added over the original 2016 baseline: PNP Activity (USB / device insertion, 6416), Group Membership (4627), Other Object Access Events (scheduled task creation 4698/4702), SAM (4661), Other Policy Change Events, MPSSVC Rule-Level Policy Change (firewall rule changes 4946-4948), DPAPI Activity (4692/4693), Removable Storage, and the IPsec Main / Quick / Extended Mode categories. +- Turned from Success-only to Success and Failure: Account Lockout, IPsec Driver, Other System Events, Detailed File Share, File System, Registry. +- 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. +- Filtering Platform Connection stays Success only (failures are every blocked connection). ## 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. +- 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. Rules audit failed attempts as well as successes. - 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. diff --git a/linux/audit/winlogs-extra.rules b/linux/audit/winlogs-extra.rules new file mode 100644 index 0000000..5693357 --- /dev/null +++ b/linux/audit/winlogs-extra.rules @@ -0,0 +1,16 @@ +# WinLogs extra audit rules, loaded after the Neo23x0 set (91-winlogs-extra.rules). +# Fills the few gaps left by the bundled ruleset: privileged-execution keys and the password-history file. +# "auid>=1000" is replaced with the host's UID_MIN at install time, like the main ruleset. + +## Password history +-w /etc/security/opasswd -p wa -k etcpasswd + +## Executions that change privilege: setuid/setgid binaries running as root +-a always,exit -F arch=b64 -S execve -S execveat -C uid!=euid -F euid=0 -k execpriv +-a always,exit -F arch=b32 -S execve -S execveat -C uid!=euid -F euid=0 -k execpriv +-a always,exit -F arch=b64 -S execve -S execveat -C gid!=egid -F egid=0 -k execpriv +-a always,exit -F arch=b32 -S execve -S execveat -C gid!=egid -F egid=0 -k execpriv + +## A logged-in human running something as root (sudo, su, pkexec, setuid) +-a always,exit -F arch=b64 -S execve -S execveat -F euid=0 -F auid>=1000 -F auid!=unset -k exec_as_root +-a always,exit -F arch=b32 -S execve -S execveat -F euid=0 -F auid>=1000 -F auid!=unset -k exec_as_root diff --git a/linux/install.sh b/linux/install.sh index b76760d..ee1ee96 100755 --- a/linux/install.sh +++ b/linux/install.sh @@ -15,6 +15,8 @@ STATE_DIR=/var/lib/winlogs BACKUP_DIR="$STATE_DIR/backup" MANIFEST="$STATE_DIR/manifest" # lines: "created " | "backup " | "pkg " RULES_DST=/etc/audit/rules.d/90-winlogs.rules +EXTRA_DST=/etc/audit/rules.d/91-winlogs-extra.rules +ENABLE_DST=/etc/audit/rules.d/99-winlogs-enable.rules JOURNAL_DROPIN=/etc/systemd/journald.conf.d/90-winlogs.conf PROFILE_DST=/etc/profile.d/winlogs-cmdlog.sh AUDITD_CONF=/etc/audit/auditd.conf @@ -118,11 +120,17 @@ install_audit_rules() { uid_min="${uid_min:-1000}" [ -d "$(dirname "$RULES_DST")" ] || run mkdir -p "$(dirname "$RULES_DST")" claim "$RULES_DST" - if [ "$DRY" = 1 ]; then echo " (dry-run) write $RULES_DST (UID_MIN=$uid_min)"; return; fi + if [ "$DRY" = 1 ]; then echo " (dry-run) write $RULES_DST, $EXTRA_DST, $ENABLE_DST (UID_MIN=$uid_min)"; return; fi sed "s/auid>=1000/auid>=$uid_min/g" "$HERE/audit/neo23x0-audit.rules" > "$RULES_DST" - # Some kernels boot with audit disabled; make sure it is switched on after the rules load. - printf '\n# WinLogs: make sure auditing is enabled\n-e 1\n' >> "$RULES_DST" chmod 640 "$RULES_DST" + # Extra rules go in a later file: augenrules concatenates in name order and 90's "-D" would delete them. + claim "$EXTRA_DST" + sed "s/auid>=1000/auid>=$uid_min/g" "$HERE/audit/winlogs-extra.rules" > "$EXTRA_DST" + chmod 640 "$EXTRA_DST" + # Some kernels boot with audit disabled; make sure it is switched on after the rules load. + claim "$ENABLE_DST" + printf '# WinLogs: make sure auditing is enabled\n-e 1\n' > "$ENABLE_DST" + chmod 640 "$ENABLE_DST" # Keep more audit history than the distro default. if [ -f "$AUDITD_CONF" ]; then diff --git a/macos/install.sh b/macos/install.sh index 76048bf..778ba72 100755 --- a/macos/install.sh +++ b/macos/install.sh @@ -42,7 +42,9 @@ WANTED_EVENTS="exec create unlink rename mount kextload btm_launch_item_add btm_ xp_malware_detected xp_malware_remediated login_login login_logout lw_session_login lw_session_logout \ sudo su openssh_login openssh_logout screensharing_attach screensharing_detach profile_add profile_remove \ authentication gatekeeper_user_override tcc_modify remote_thread_create cs_invalidated \ -od_create_user od_delete_user od_modify_password od_group_add od_group_remove od_group_set" +od_create_user od_delete_user od_modify_password od_group_add od_group_remove od_group_set \ +setmode setowner setflags setacl setextattr deleteextattr link clone copyfile exchangedata settime \ +trace proc_suspend_resume get_task get_task_read get_task_inspect authorization_judgement" usage() { sed -n '2,15p' "$0" | sed 's/^# \{0,1\}//'; echo "Options: --yes --dry-run --revert --no-shell-logging --with-log-archive --keep-days N --es-max-mb N"; } diff --git a/tests/Test-WinLogs.ps1 b/tests/Test-WinLogs.ps1 index 80d7a4d..159de79 100644 --- a/tests/Test-WinLogs.ps1 +++ b/tests/Test-WinLogs.ps1 @@ -49,6 +49,8 @@ $runKey = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run' $startup = Join-Path $env:ProgramData 'Microsoft\Windows\Start Menu\Programs\StartUp' $runSaclBefore = Get-AuditRuleCount $runKey $startupSaclBefore = Get-AuditRuleCount $startup +$polKey = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security' +$maxBefore = Reg $polKey 'MaxSize' $isServer = (Get-CimInstance Win32_OperatingSystem).ProductType -ne 1 Write-Host " (server profile expected: $isServer)" @@ -70,6 +72,11 @@ Check 'PowerShell 7 policy mirrored' ((Reg 'HKLM:\SOFTWARE\Policies\Microsoft\Po Check 'Process Creation audited (Success)' ((Audit 'Process Creation') -match 'Success') Check 'Security log >= 1 GB' ((Get-WinEvent -ListLog Security).MaximumSizeInBytes -ge 1GB) Check 'Group Membership audited' ((Audit 'Group Membership') -match 'Success') +Check 'Other System Events: Success and Failure' ((Audit 'Other System Events') -match 'Success and Failure') +Check 'Account Lockout: Success and Failure' ((Audit 'Account Lockout') -match 'Success and Failure') +Check 'File System: Success and Failure' ((Audit 'File System') -match 'Success and Failure') +Check 'Registry: Success and Failure' ((Audit 'Registry') -match 'Success and Failure') +Check 'Event Log policy MaxSize set (Security, >= 1 GiB)' ((Reg $polKey 'MaxSize') -ge 1048576) Check 'SAM audited (Success and Failure)' ((Audit 'SAM') -match 'Success and Failure') if ($isServer) { Check 'Kerberos Service Ticket audited (server overlay)' ((Audit 'Kerberos Service Ticket Operations') -match 'Success and Failure') @@ -130,6 +137,7 @@ Check 'state.json removed' (-not (Test-Path $state)) Check 'cmdline auditing restored' ((Reg $cmdKey 'ProcessCreationIncludeCmdLine_Enabled') -eq $before) Check 'PowerShell policy removed' ($null -eq (Reg "$psw\ScriptBlockLogging" 'EnableScriptBlockLogging')) Check 'audit policy restored' ((Audit 'Process Creation') -eq $auditBefore) +Check 'Event Log policy MaxSize restored' ((Reg $polKey 'MaxSize') -eq $maxBefore) Check 'Run key SACL removed' ((Get-AuditRuleCount $runKey) -eq $runSaclBefore) Check 'StartUp SACL removed' ((Get-AuditRuleCount $startup) -eq $startupSaclBefore) Check 'Sysmon service removed' ($null -eq (Get-Service -Name 'Sysmon*' -ErrorAction SilentlyContinue)) diff --git a/tests/test-linux.sh b/tests/test-linux.sh index 60edf8d..1dd79ca 100755 --- a/tests/test-linux.sh +++ b/tests/test-linux.sh @@ -32,7 +32,9 @@ check "SHA256SUMS written" test -s /tmp/winlogs-offline/SHA256SUMS echo "== install (offline)" runq ./linux/install.sh --yes --offline-dir /tmp/winlogs-offline check "audit rules file installed" test -s /etc/audit/rules.d/90-winlogs.rules -if [ "$LIVE" = 1 ]; then check "audit rules loaded in kernel" rules_loaded; else skip "audit rules loaded in kernel"; fi +check "extra rules file installed" test -s /etc/audit/rules.d/91-winlogs-extra.rules +check "enable rule file installed" test -s /etc/audit/rules.d/99-winlogs-enable.rules +if [ "$LIVE" = 1 ]; then check "audit rules loaded in kernel" rules_loaded; check "extra execpriv rules loaded" bash -c "auditctl -l | grep -q execpriv"; else skip "audit rules loaded in kernel"; fi check "auditd.conf retention raised" grep -q '^max_log_file = 200' /etc/audit/auditd.conf check "journald drop-in present" test -s /etc/systemd/journald.conf.d/90-winlogs.conf if [ "$LIVE" = 1 ]; then check "journald is persistent" test -d /var/log/journal; else skip "journald is persistent"; fi @@ -57,6 +59,8 @@ check "second run kept one backup of auditd.conf" test "$(grep -c '^backup /etc/ echo "== revert" runq ./linux/install.sh --yes --revert check "rules file removed" test ! -e /etc/audit/rules.d/90-winlogs.rules +check "extra rules file removed" test ! -e /etc/audit/rules.d/91-winlogs-extra.rules +check "enable rule file removed" test ! -e /etc/audit/rules.d/99-winlogs-enable.rules check "journald drop-in gone" test ! -e /etc/systemd/journald.conf.d/90-winlogs.conf check "profile hook gone" test ! -e /etc/profile.d/winlogs-cmdlog.sh check "state dir removed" test ! -d /var/lib/winlogs diff --git a/windows/Install-WinLogs.ps1 b/windows/Install-WinLogs.ps1 index 6829885..9441bb3 100644 --- a/windows/Install-WinLogs.ps1 +++ b/windows/Install-WinLogs.ps1 @@ -161,6 +161,9 @@ function Confirm-Lab { # --- audit helpers ---------------------------------------------------------------------------- +# Per-object rules audit failed attempts too (access denied on a persistence key is a signal). +$AuditRuleFlags = 'Success, Failure' + function Resolve-AuditProfile { if ($AuditProfile -ne 'Auto') { return $AuditProfile } # ProductType: 1 = workstation (Windows 10/11), 2 = domain controller, 3 = server @@ -168,11 +171,11 @@ function Resolve-AuditProfile { return 'Server' } -function New-AuditRule([string]$Kind, [string]$Rights, [string]$Inherit) { +function New-AuditRule([string]$Kind, [string]$Rights, [string]$Inherit, [string]$Flags = 'Success') { $everyone = New-Object Security.Principal.SecurityIdentifier('S-1-1-0') $inh = [Security.AccessControl.InheritanceFlags]$Inherit $prop = [Security.AccessControl.PropagationFlags]::None - $flag = [Security.AccessControl.AuditFlags]::Success + $flag = [Security.AccessControl.AuditFlags]$Flags if ($Kind -eq 'Registry') { return New-Object Security.AccessControl.RegistryAuditRule($everyone, [Security.AccessControl.RegistryRights]$Rights, $inh, $prop, $flag) } @@ -202,10 +205,10 @@ function Add-ObjectAudit($State, [string]$Kind, [string]$Path, [string]$Rights, if (-not (Test-Path -LiteralPath $Path)) { Write-Verbose "Audit target not present, skipping: $Path"; return } if ($PSCmdlet.ShouldProcess($Path, "Add audit rule ($Rights)")) { try { - $rule = New-AuditRule $Kind $Rights $Inherit + $rule = New-AuditRule $Kind $Rights $Inherit $AuditRuleFlags Edit-ObjectAudit $Kind $Path { param($sec) $sec.AddAuditRule($rule) } if (-not (@($State.sacls) | Where-Object { $_.path -eq $Path -and $_.rights -eq $Rights })) { - $State.sacls += [ordered]@{ kind = $Kind; path = $Path; rights = $Rights; inherit = $Inherit } + $State.sacls += [ordered]@{ kind = $Kind; path = $Path; rights = $Rights; inherit = $Inherit; flags = $AuditRuleFlags } } } catch { Write-Warn "Could not set audit rule on '$Path': $($_.Exception.Message)" } } @@ -215,7 +218,9 @@ function Remove-ObjectAudit($Entry) { if (-not (Test-Path -LiteralPath $Entry.path)) { return } if ($PSCmdlet.ShouldProcess($Entry.path, 'Remove audit rule')) { try { - $rule = New-AuditRule $Entry.kind $Entry.rights $Entry.inherit + # State files from earlier versions have no 'flags' (those rules audited Success only). + $flags = if ($Entry.PSObject.Properties['flags']) { $Entry.flags } else { 'Success' } + $rule = New-AuditRule $Entry.kind $Entry.rights $Entry.inherit $flags Edit-ObjectAudit $Entry.kind $Entry.path { param($sec) [void]$sec.RemoveAuditRuleSpecific($rule) } } catch { Write-Warn "Could not remove audit rule from '$($Entry.path)': $($_.Exception.Message)" } } @@ -489,7 +494,18 @@ $medium = 'System', 'Application', 'Microsoft-Windows-AppLocker/MSI and Script', 'Microsoft-Windows-AppLocker/Packaged app-Deployment', 'Microsoft-Windows-AppLocker/Packaged app-Execution', - 'Microsoft-Windows-Diagnosis-Scripted/Operational' + 'Microsoft-Windows-Diagnosis-Scripted/Operational', + 'Microsoft-Windows-WinRM/Operational', + 'Microsoft-Windows-TerminalServices-RDPClient/Operational', + 'Microsoft-Windows-RemoteDesktopServices-RdpCoreTS/Operational', + 'Microsoft-Windows-LSA/Operational', + 'Microsoft-Windows-DeviceGuard/Operational', + 'Microsoft-Windows-Security-Netlogon/Operational', + 'Microsoft-Windows-SMBServer/Security', + 'Microsoft-Windows-SMBServer/Operational', + 'Microsoft-Windows-Shell-Core/Operational', + 'Microsoft-Windows-AppXDeploymentServer/Operational', + 'Microsoft-Windows-Winlogon/Operational' if ($profileName -eq 'Server') { # Present only when the role is installed; Set-TrackedLog skips channels that do not exist. $medium += 'Directory Service', 'DNS Server', 'Microsoft-Windows-DNSServer/Audit', 'DFS Replication' @@ -501,6 +517,16 @@ foreach ($n in 'Microsoft-Windows-TaskScheduler/Operational', 'Microsoft-Windows Set-TrackedLog $state $n ([math]::Min(256, $LogSizeMB)) $true } +# Event Log policy values override the per-channel setting, so a policy refresh could shrink the logs we just +# sized. Writing the policy value keeps the size (and lets compliance scanners that read it see it). +foreach ($n in 'Security', 'System', 'Application') { + $want = if ($n -eq 'Security') { $LogSizeMB } else { [math]::Min(256, $LogSizeMB) } + $cur = 0 + try { $cur = [int64]((Get-WinEvent -ListLog $n -ErrorAction Stop).MaximumSizeInBytes / 1KB) } catch { } + $kb = [int64][math]::Max($cur, [int64]$want * 1024) + Set-TrackedValue $state "HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\$n" 'MaxSize' $kb +} + Save-State $state Write-Host '' diff --git a/windows/audit-server.csv b/windows/audit-server.csv index d2b4bdd..a9c3007 100644 --- a/windows/audit-server.csv +++ b/windows/audit-server.csv @@ -2,4 +2,4 @@ Machine Name,Policy Target,Subcategory,Subcategory GUID,Inclusion Setting,Exclus ,System,Audit Kerberos Authentication Service,{0cce9242-69ae-11d9-bed3-505054503030},Success and Failure,,3 ,System,Audit Kerberos Service Ticket Operations,{0cce9240-69ae-11d9-bed3-505054503030},Success and Failure,,3 ,System,Audit Directory Service Access,{0cce923b-69ae-11d9-bed3-505054503030},Success and Failure,,3 -,System,Audit Directory Service Replication,{0cce923d-69ae-11d9-bed3-505054503030},Success,,1 \ No newline at end of file +,System,Audit Directory Service Replication,{0cce923d-69ae-11d9-bed3-505054503030},Success and Failure,,3 \ No newline at end of file diff --git a/windows/audit.csv b/windows/audit.csv index 1392495..7fdc1aa 100644 --- a/windows/audit.csv +++ b/windows/audit.csv @@ -18,11 +18,11 @@ Machine Name,Policy Target,Subcategory,Subcategory GUID,Inclusion Setting,Exclus ,System,Audit Directory Service Access,{0cce923b-69ae-11d9-bed3-505054503030},No Auditing,,0 ,System,Audit Directory Service Changes,{0cce923c-69ae-11d9-bed3-505054503030},Success and Failure,,3 ,System,Audit Directory Service Replication,{0cce923d-69ae-11d9-bed3-505054503030},No Auditing,,0 -,System,Audit Account Lockout,{0cce9217-69ae-11d9-bed3-505054503030},Success,,1 +,System,Audit Account Lockout,{0cce9217-69ae-11d9-bed3-505054503030},Success and Failure,,3 ,System,Audit User / Device Claims,{0cce9247-69ae-11d9-bed3-505054503030},No Auditing,,0 -,System,Audit IPsec Extended Mode,{0cce921a-69ae-11d9-bed3-505054503030},No Auditing,,0 -,System,Audit IPsec Main Mode,{0cce9218-69ae-11d9-bed3-505054503030},No Auditing,,0 -,System,Audit IPsec Quick Mode,{0cce9219-69ae-11d9-bed3-505054503030},No Auditing,,0 +,System,Audit IPsec Extended Mode,{0cce921a-69ae-11d9-bed3-505054503030},Success and Failure,,3 +,System,Audit IPsec Main Mode,{0cce9218-69ae-11d9-bed3-505054503030},Success and Failure,,3 +,System,Audit IPsec Quick Mode,{0cce9219-69ae-11d9-bed3-505054503030},Success and Failure,,3 ,System,Audit Logoff,{0cce9216-69ae-11d9-bed3-505054503030},Success,,1 ,System,Audit Logon,{0cce9215-69ae-11d9-bed3-505054503030},Success and Failure,,3 ,System,Audit Group Membership,{0cce9249-69ae-11d9-bed3-505054503030},Success,,1 @@ -31,15 +31,15 @@ Machine Name,Policy Target,Subcategory,Subcategory GUID,Inclusion Setting,Exclus ,System,Audit Special Logon,{0cce921b-69ae-11d9-bed3-505054503030},Success and Failure,,3 ,System,Audit Application Generated,{0cce9222-69ae-11d9-bed3-505054503030},Success and Failure,,3 ,System,Audit Certification Services,{0cce9221-69ae-11d9-bed3-505054503030},Success and Failure,,3 -,System,Audit Detailed File Share,{0cce9244-69ae-11d9-bed3-505054503030},Success,,1 +,System,Audit Detailed File Share,{0cce9244-69ae-11d9-bed3-505054503030},Success and Failure,,3 ,System,Audit File Share,{0cce9224-69ae-11d9-bed3-505054503030},Success and Failure,,3 -,System,Audit File System,{0cce921d-69ae-11d9-bed3-505054503030},Success,,1 +,System,Audit File System,{0cce921d-69ae-11d9-bed3-505054503030},Success and Failure,,3 ,System,Audit Filtering Platform Connection,{0cce9226-69ae-11d9-bed3-505054503030},Success,,1 ,System,Audit Filtering Platform Packet Drop,{0cce9225-69ae-11d9-bed3-505054503030},No Auditing,,0 ,System,Audit Handle Manipulation,{0cce9223-69ae-11d9-bed3-505054503030},No Auditing,,0 ,System,Audit Kernel Object,{0cce921f-69ae-11d9-bed3-505054503030},Success and Failure,,3 ,System,Audit Other Object Access Events,{0cce9227-69ae-11d9-bed3-505054503030},Success and Failure,,3 -,System,Audit Registry,{0cce921e-69ae-11d9-bed3-505054503030},Success,,1 +,System,Audit Registry,{0cce921e-69ae-11d9-bed3-505054503030},Success and Failure,,3 ,System,Audit Removable Storage,{0cce9245-69ae-11d9-bed3-505054503030},Success and Failure,,3 ,System,Audit SAM,{0cce9220-69ae-11d9-bed3-505054503030},Success and Failure,,3 ,System,Audit Central Access Policy Staging,{0cce9246-69ae-11d9-bed3-505054503030},No Auditing,,0 @@ -52,8 +52,8 @@ Machine Name,Policy Target,Subcategory,Subcategory GUID,Inclusion Setting,Exclus ,System,Audit Non Sensitive Privilege Use,{0cce9229-69ae-11d9-bed3-505054503030},No Auditing,,0 ,System,Audit Other Privilege Use Events,{0cce922a-69ae-11d9-bed3-505054503030},No Auditing,,0 ,System,Audit Sensitive Privilege Use,{0cce9228-69ae-11d9-bed3-505054503030},Success and Failure,,3 -,System,Audit IPsec Driver,{0cce9213-69ae-11d9-bed3-505054503030},Success,,1 -,System,Audit Other System Events,{0cce9214-69ae-11d9-bed3-505054503030},Failure,,2 +,System,Audit IPsec Driver,{0cce9213-69ae-11d9-bed3-505054503030},Success and Failure,,3 +,System,Audit Other System Events,{0cce9214-69ae-11d9-bed3-505054503030},Success and Failure,,3 ,System,Audit Security State Change,{0cce9210-69ae-11d9-bed3-505054503030},Success and Failure,,3 ,System,Audit Security System Extension,{0cce9211-69ae-11d9-bed3-505054503030},Success and Failure,,3 ,System,Audit System Integrity,{0cce9212-69ae-11d9-bed3-505054503030},Success and Failure,,3