We've recently been working on CIS compliance reporting within the XIA Configuration Server platform.
Part of the compliance for Server 2012 R2 includes the ability to document the configuration of the Windows Advanced Audit Policy (also known as audit subcategories).
This is a bit of a problem due to the fact that Microsoft provide no PowerShell or WMI interface for this and the raw settings are stored in an obfuscated part of the registry.
You can however read the Windows Advanced Audit Policy by using C# .NET with the low level Win32 API.
We've provided the wrapper as an example. The one issue with this API is that it can only be executed for the local machine as is the case with the AuditPol.exe tool...
Part of the compliance for Server 2012 R2 includes the ability to document the configuration of the Windows Advanced Audit Policy (also known as audit subcategories).
This is a bit of a problem due to the fact that Microsoft provide no PowerShell or WMI interface for this and the raw settings are stored in an obfuscated part of the registry.
You can however read the Windows Advanced Audit Policy by using C# .NET with the low level Win32 API.
We've provided the wrapper as an example. The one issue with this API is that it can only be executed for the local machine as is the case with the AuditPol.exe tool...
///<summary>
/// Provides management functions of the advanced audit policy (audit policy subcategory settings).
///</summary>
publicclassAdvancedAuditPolicyWrapper
{
///<summary>
/// Initializes a new instance of the CENTREL.XIA.Management.AdvancedAuditPolicyWrapper class.
///</summary>
publicAdvancedAuditPolicyWrapper()
{
}
///<summary>
/// The AuditEnumerateCategories function enumerates the available audit-policy categories.
///</summary>
///<param name="ppAuditCategoriesArray">A pointer to a single buffer that contains both an array of pointers to GUID structures and the structures themselves. </param>
///<param name="pCountReturned">A pointer to the number of elements in the ppAuditCategoriesArray array.</param>
///<returns>A System.Boolean value that indicates whether the function completed successfully.</returns>
///<remarks>https://msdn.microsoft.com/en-us/library/windows/desktop/aa375636(v=vs.85).aspx</remarks>
[DllImport("advapi32.dll", SetLastError = true)]
privatestaticexternbool AuditEnumerateCategories(outIntPtrppAuditCategoriesArray, outuint pCountReturned);
///<summary>
/// The AuditLookupCategoryName function retrieves the display name of the specified audit-policy category.
///</summary>
///<param name="pAuditCategoryGuid">A pointer to a GUID structure that specifies an audit-policy category.</param>
///<param name="ppszCategoryName">The address of a pointer to a null-terminated string that contains the display name of the audit-policy category specified by the pAuditCategoryGuid function.</param>
///<returns>A System.Boolean value that indicates whether the function completed successfully.</returns>
///<remarks>https://msdn.microsoft.com/en-us/library/windows/desktop/aa375687(v=vs.85).aspx</remarks>
[DllImport("advapi32.dll", SetLastError = true)]
privatestaticexternbool AuditLookupCategoryName(refGuid pAuditCategoryGuid, outStringBuilderppszCategoryName);
///<summary>
/// The AuditEnumerateSubCategories function enumerates the available audit-policy subcategories.
///</summary>
///<param name="pAuditCategoryGuid">The GUID of an audit-policy category for which subcategories are enumerated. If the value of the bRetrieveAllSubCategories parameter is TRUE, this parameter is ignored.</param>
///<param name="bRetrieveAllSubCategories">TRUE to enumerate all audit-policy subcategories; FALSE to enumerate only the subcategories of the audit-policy category specified by the pAuditCategoryGuid parameter.</param>
///<param name="ppAuditSubCategoriesArray">A pointer to a single buffer that contains both an array of pointers to GUID structures and the structures themselves. The GUID structures specify the audit-policy subcategories available on the computer.</param>
///<param name="pCountReturned">A pointer to the number of audit-policy subcategories returned in the ppAuditSubCategoriesArray array.</param>
///<returns>A System.Boolean value that indicates whether the function completed successfully.</returns>
///<remarks>https://msdn.microsoft.com/en-us/library/windows/desktop/aa375648(v=vs.85).aspx</remarks>
[DllImport("advapi32.dll", SetLastError = true)]
privatestaticexternbool AuditEnumerateSubCategories(refGuidpAuditCategoryGuid, boolbRetrieveAllSubCategories, outIntPtr ppAuditSubCategoriesArray, outuintpCountReturned);
///<summarThe AuditLookupSubCategoryName function retrieves the display name of the specified audit-policy subcategory. y>
/// The AuditLookupSubCategoryName function retrieves the display name of the specified audit-policy subcategory.
///</summary>
///<param name="pAuditSubCategoryGuid">A pointer to a GUID structure that specifies an audit-policy subcategory.</param>
///<param name="ppszSubCategoryName">The address of a pointer to a null-terminated string that contains the display name of the audit-policy subcategory specified by the pAuditSubCategoryGuid parameter.</param>
///<returns>A System.Boolean value that indicates whether the function completed successfully.</returns>
///<remarks>https://msdn.microsoft.com/en-us/library/windows/desktop/aa375693(v=vs.85).aspx</remarks>
[DllImport("advapi32.dll", SetLastError = true)]
privatestaticexternbool AuditLookupSubCategoryName(refGuidpAuditSubCategoryGuid, outStringBuilder ppszSubCategoryName);
///<summary>
/// The AuditFree function frees the memory allocated by audit functions for the specified buffer.
///</summary>
///<param name="buffer">A pointer to the buffer to free.</param>
///<remarks>https://msdn.microsoft.com/en-us/library/windows/desktop/aa375654(v=vs.85).aspx</remarks>
[DllImport("advapi32.dll")]
privatestaticexternvoid AuditFree(IntPtrbuffer);
///<summary>
/// The AuditQuerySystemPolicy function retrieves system audit policy for one or more audit-policy subcategories.
///</summary>
///<param name="pSubCategoryGuids">A pointer to an array of GUID values that specify the subcategories for which to query audit policy. </param>
///<param name="PolicyCount">The number of elements in each of the pSubCategoryGuids and ppAuditPolicy arrays.</param>
///<param name="ppAuditPolicy">A pointer to a single buffer that contains both an array of pointers to AUDIT_POLICY_INFORMATION structures and the structures themselves. </param>
///<returns>https://msdn.microsoft.com/en-us/library/windows/desktop/aa375702(v=vs.85).aspx</returns>
[DllImport("advapi32.dll", SetLastError = true)]
privatestaticexternbool AuditQuerySystemPolicy(GuidpSubCategoryGuids, uint PolicyCount, outIntPtrppAuditPolicy);
///<summary>
/// Gets the GUIDs of the audit categories.
///</summary>
///<returns>The GUIDs of the audit categories on the local machine.</returns>
publicSerializableStringCollectionGetCategoryIdentifiers()
{
SerializableStringCollectionidentifiers = newSerializableStringCollection();
IntPtr buffer;
uintcategoryCount;
boolsuccess = AuditEnumerateCategories(out buffer, out categoryCount);
if(!success) { thrownewWin32Exception(Marshal.GetLastWin32Error()); }
for (int i = 0, elemOffs = (int)buffer; i < categoryCount; i++)
{
Guidguid = (Guid)Marshal.PtrToStructure((IntPtr)elemOffs, typeof(Guid));
identifiers.Add(Convert.ToString(guid));
elemOffs += Marshal.SizeOf(typeof(Guid));
}
AuditFree(buffer);
returnidentifiers;
}
///<summary>
/// Returns the display name of the audit category with the specified GUID.
///</summary>
///<param name="guid">The GUID of the category for which the display name should be returned.</param>
///<returns>The display name of the category - for example "Account Management".</returns>
publicString GetCategoryDisplayName(String guid)
{
returnGetCategoryDisplayName(newGuid(guid));
}
///<summary>
/// Returns the display name of the audit category with the specified GUID.
///</summary>
///<param name="guid">The GUID of the category for which the display name should be returned.</param>
///<returns>The display name of the category - for example "Account Management".</returns>
publicString GetCategoryDisplayName(Guid guid)
{
StringBuilderbuffer = newStringBuilder();
boolsuccess = AuditLookupCategoryName(ref guid, out buffer);
if(!success) { thrownewWin32Exception(Marshal.GetLastWin32Error()); }
if(buffer == null) { thrownewArgumentException(String.Format(Resources.Common.CategoryDisplayNameNotFoundException, guid)); }
StringcategoryDisplayName = buffer.ToString();
buffer = null;
returncategoryDisplayName;
}
///<summary>
/// Gets the GUIDs of the audit subcategories of the specified category.
///</summary>
///<param name="guid">The GUID of the category for which the subcategories should be returned.</param>
///<returns>The GUIDs of the audit subcategories for the specified category.</returns>
publicSerializableStringCollectionGetSubCategoryIdentifiers(StringcategoryGuid)
{
returnGetSubCategoryIdentifiers(newGuid(categoryGuid));
}
///<summary>
/// Gets the GUIDs of the audit subcategories of the specified category.
///</summary>
///<param name="guid">The GUID of the category for which the subcategories should be returned.</param>
///<returns>The GUIDs of the audit subcategories for the specified category.</returns>
publicSerializableStringCollectionGetSubCategoryIdentifiers(Guid categoryGuid)
{
SerializableStringCollectionidentifiers = newSerializableStringCollection();
IntPtrbuffer;
uintsubCategoryCount;
boolsuccess = AuditEnumerateSubCategories(refcategoryGuid, false, outbuffer, out subCategoryCount);
if(!success) { thrownewWin32Exception(Marshal.GetLastWin32Error()); }
for (int i = 0, elemOffs = (int)buffer; i < subCategoryCount; i++)
{
Guidguid = (Guid)Marshal.PtrToStructure((IntPtr)elemOffs, typeof(Guid));
identifiers.Add(Convert.ToString(guid));
elemOffs += Marshal.SizeOf(typeof(Guid));
}
AuditFree(buffer);
returnidentifiers;
}
///<summary>
/// Returns the display name of the audit subcategory with the specified GUID.
///</summary>
///<param name="guid">The GUID of the subcategory for which the display name should be returned.</param>
///<returns>The display name of the subcategory - for example "Audit Credential Validation".</returns>
publicString GetSubCategoryDisplayName(String guid)
{
returnGetSubCategoryDisplayName(newGuid(guid));
}
///<summary>
/// Returns the display name of the audit subcategory with the specified GUID.
///</summary>
///<param name="guid">The GUID of the subcategory for which the display name should be returned.</param>
///<returns>The display name of the subcategory - for example "Audit Credential Validation".</returns>
publicString GetSubCategoryDisplayName(Guid guid)
{
StringBuilderbuffer = newStringBuilder();
boolsuccess = AuditLookupSubCategoryName(ref guid, out buffer);
if (!success) { thrownewWin32Exception(Marshal.GetLastWin32Error()); }
StringsubCategoryDisplayName = buffer.ToString();
buffer = null;
returnsubCategoryDisplayName;
}
///<summary>
/// Gets the audit policy configured for the specified subcategory GUID.
///</summary>
///<param name="subCategoryGuid">The GUID of the subcategory for which the policy should be returned.</param>
///<returns>Returns an AUDIT_POLICY_INFORMATION that contains information about the policy.</returns>
publicAUDIT_POLICY_INFORMATION GetSystemPolicy(String subCategoryGuid)
{
returnGetSystemPolicy(newGuid(subCategoryGuid));
}
///<summary>
/// Gets the audit policy configured for the specified subcategory GUID.
///</summary>
///<param name="subCategoryGuid">The GUID of the subcategory for which the policy should be returned.</param>
///<returns>Returns an AUDIT_POLICY_INFORMATION that contains information about the policy.</returns>
publicAUDIT_POLICY_INFORMATION GetSystemPolicy(Guid subCategoryGuid)
{
SerializableStringCollectionidentifiers = newSerializableStringCollection();
IntPtrbuffer;
boolsuccess = AuditQuerySystemPolicy(subCategoryGuid, 1, outbuffer);
if(!success) { thrownewWin32Exception(Marshal.GetLastWin32Error()); }
AUDIT_POLICY_INFORMATIONpolicyInformation = (AUDIT_POLICY_INFORMATION)Marshal.PtrToStructure(buffer, typeof(AUDIT_POLICY_INFORMATION));
AuditFree(buffer);
returnpolicyInformation;
}
}
///<summary>
/// The AUDIT_POLICY_INFORMATION structure specifies a security event type and when to audit that type.
///</summary>
///<remarks>https://msdn.microsoft.com/en-us/library/windows/desktop/aa965467(v=vs.85).aspx</remarks>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
publicstructAUDIT_POLICY_INFORMATION
{
///<summary>
/// A GUID structure that specifies an audit subcategory.
///</summary>
publicGuid AuditSubCategoryGuid;
///<summary>
/// A set of bit flags that specify the conditions under which the security event type specified by the AuditSubCategoryGuid and AuditCategoryGuid members are audited.
///</summary>
publicAUDIT_POLICY_INFORMATION_TYPE AuditingInformation;
///<summary>
/// A GUID structure that specifies an audit-policy category.
///</summary>
publicGuid AuditCategoryGuid;
}
///<summary>
/// Represents the auditing type.
///</summary>
[Flags]
publicenumAUDIT_POLICY_INFORMATION_TYPE
{
///<summary>
/// Do not audit the specified event type.
///</summary>
None = 0,
///<summary>
/// Audit successful occurrences of the specified event type.
///</summary>
Success = 1,
///<summary>
/// Audit failed attempts to cause the specified event type.
///</summary>
Failure = 2,
}