Sunday, June 5, 2011

Audit Policy in Windows 7 and 2008 R2

Introduced granular auditing in Windows Vista and a few years later we released Advanced Audit Policy Configuration. Legacy Windows audit policy didn’t go away, of course. To make things interesting, all of this can be configured through domain policy, local policy, multiple-local policy, per-user, or using command-line tools. Like most security policy that has evolved through 20 years of Windows, it’s a bit of a Frankenstein’s monster. Making sense of what settings are actually in place in Win7 and 2008 R2 can be a real pain in the neck. Today we’ll see if I can make it easier.
Fire good!
A Scenario
You commonly configure audit settings using the following:
  • Domain based group policy (via GPMC.MSC)
  • Local policy (via GPEDIT.MSC)
  • Directly (only advanced audit policy, via auditpol.exe)
But depending on how you set the policy, your reporting tools may be misleading you around effective settings. For instance, I have specified the following policies using the following techniques.
1. I have a legacy audit policy applying from domain policy that configures Object Access auditing:

2. I have advanced audit configuration applying from domain policy that sets AD changes, account lockouts, and logons:

3. I have advanced audit configuration applying from local policy for process startup and termination:

4. I have granular audit settings configured using auditpol.exe /set for file share access:
Pro tip: this is not awesome auditing technique, on a number of levels. :) Just for demo purposes, mmmkay?
Initial Results
Now I generate a resultant set of policy report. I am not using RSOP.MSC as it’s deprecated and often wrong and generally evil. I run GPRESULT /H foo.htm instead:


Looks pretty good so far. I can’t see my policy that I set through auditpol.exe though; that kinda sucks but whatevah.
So now I start generating some audit events for the areas I am tracking from my four audit points. Immediately I see some weirdness:
  • All the advanced audit configuration coming from “Local Group Policy” and “Advanced Audit DC Policy” is working great.

  • My event log should be flooded with Object Access events but there are zero. 
  • Accessing file shares doesn’t generate any audit events.
The lack of Object Access auditing is expected: as soon as you start applying Advanced Audit Configuration Policy, legacy policies will be completely ignored. The only way to get a Win7/R2 computer to start using legacy policy is to set the security policy “Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings” to DISABLED. That disables the use of the newer policy type.
Not seeing the File Share events makes sense too: after all, I created domain based and local policy to set all of this; they are just blowing away my local settings, right?
Yes and no.
First, I delete my link for the “Advanced audit DC policy” and run GPUPDATE /FORCE. Now I am only getting local policy settings for process creation and termination as expected. If I then re-run my auditpol /set /subcategory:”file share” /success:enable command and access a file share, I get an event. Yay team. Except after a while, this will stop working, because the local policy setting is going to reapply when the computer restarts or every 16 hours when security policy is reapplied arbitrarily.
Here’s where things get weird.
Unlike most security settings that directly edit registry keys as preferences, advanced audit policy stores all of its local security policy values in an audit.csv file located here:
%systemroot%\system32\grouppolicy\machine\microsoft\windows nt\audit\audit.csv
Which is then copied here:
%systemroot%\security\audit\audit.csv
But the domain-based policy settings are in an audit.csv in SYSVOL and that is never stored locally to the computer. So examining any of them is rather useless. Unfortunately for you, those audit.csv files are what RSOP data is returning, not the actual applied settings. And if you use legacy tools like SECEDIT.EXE /EXPORT it won’t even mention the advanced audit configuration at all – it was never updated to include those settings.
The Truth
All of this boils down to one lesson: you should not trust any of the Group Policy reporting tools when it comes to audit settings. There’s only one safe bet and it’s this command:
auditpol.exe /get /category:*

Only auditpol reads the actual super-top-secret-eyes-only-licensed-to-kill-shaken-not-stirred registry key that stores the current, effective set of auditing policy that LSASS.EXE consumes:
HKEY_Local_Machine\Security\Policy\PolAdtEv

If it’s not in that key, it’s not getting audited.
Before you get all excited and start plowing into this key, understand that this key is intended to be opaque and proprietary. We don’t really document it and you certainly cannot safely edit it with regedit. In fact, as an experiment I once renamed it in order to see if it would be automatically recreated using “default, out of box” settings. Instead, the computer refused to boot to a logon prompt anymore! I had to load that hive using regedit in WIN PE and name it back (Last Known Good Configuration boot does not apply to the Security hive). If you want to write your own version of auditpol you use the functionAuditQuerySystemPolicy (part of the gigantor Advapi32 library of Authorization functions; have fun with that goo and don’t call me about it, it’s grody).
As a side note - if you want a safe way to remove auditing settings you can easily clear that registry key by running auditpol /clear and removing policy. That puts you to “nothing”. If you want to restore to “out of the box” experience you would useauditpol /backup on a nice clean unadulterated repro computer that was installed from media and never joined to a domain. That gives you the “before”. Then if you ever want to reset a computer to OOB you auditpol /restore it.
Until next time.
Ned “Wait. Where are you going? I was going to make Espresso!” Pyle