Reputation: 129
I want the value of an audit policy in Windows, e.g., 0cce9240-69ae-11d9-bed3-50505450303
→ Success
or 1
.
Hereby, I have to use PowerShell.
As the auditpol
is language dependent, I was looking for a language independent method.
Thus, I came across this helpful article to use the Win32.Advapi32
module.
$MemberDefinition = @'
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool AuditEnumerateCategories(
out IntPtr ppAuditCategoriesArray,
out uint pCountReturned);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool AuditLookupCategoryName(
ref Guid pAuditCategoryGuid,
out StringBuilder ppszCategoryName);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool AuditEnumerateSubCategories(
ref Guid pAuditCategoryGuid,
bool bRetrieveAllSubCategories,
out IntPtr ppAuditSubCategoriesArray,
out uint pCountReturned);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool AuditLookupSubCategoryName(
ref Guid pAuditSubCategoryGuid,
out StringBuilder ppszSubCategoryName);
[DllImport("advapi32.dll")]
public static extern void AuditFree(
IntPtr buffer);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool AuditQuerySystemPolicy(
Guid pSubCategoryGuids,
uint PolicyCount,
out IntPtr ppAuditPolicy);
'@
$Advapi32 = Add-Type -MemberDefinition $MemberDefinition -Name 'Advapi32' -Namespace 'Win32' -UsingNamespace System.Text -PassThru
$neBuild = [System.Text.StringBuilder]::new()
$res1 = [Win32.Advapi32]::AuditLookupSubCategoryName([ref]"0cce9240-69ae-11d9-bed3-505054503030",[ref]$neBuild)
Write-Host "$neBuild"
[IntPtr]$test_out = [IntPtr]::Zero
$result = [Win32.Advapi32]::AuditQuerySystemPolicy("0cce9240-69ae-11d9-bed3-505054503030", 1,[ref]$test_out)
On the one hand, the output of the Write-Host
statement is Kerberos Service Ticket Operations
and, therefore, I'm assuming that the general import is working.
On the other hand, $test_out
is always 0, no matter to which value I configure the Kerberos Service Ticket Operations
.
Did I do anything wrong here?
Is the import, e.g. public static extern bool AuditQuerySystemPolicy
, flawed?
Do I have to initialize the passed parameters differently?
Thank you for any help!
Upvotes: 1
Views: 577
Reputation: 2853
The signature of the AuditQuerySystemPolicy is a bit wrong.
Here is a full working example. I mostly rely on C# to do the pinvoke and pointer to struct conversion. Make sure to run it as administrator, otherwise it will return -1 as error result.
$TypeDefinition = @'
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace Audit
{
public class AuditPol
{
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.U1)]
public static extern bool AuditQuerySystemPolicy(
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1), In]
Guid[] pSubCategoryGuids,
uint dwPolicyCount,
out IntPtr ppAuditPolicy);
public static IEnumerable<AUDIT_POLICY_INFORMATION> AuditQuerySystemPolicy([In] Guid[] pSubCategoryGuids)
{
IntPtr ppAuditPolicy;
if (!AuditQuerySystemPolicy(pSubCategoryGuids, (uint) pSubCategoryGuids.Length, out ppAuditPolicy))
return new AUDIT_POLICY_INFORMATION[0];
return ToIEnum<AUDIT_POLICY_INFORMATION>(ppAuditPolicy, pSubCategoryGuids.Length);
}
public static IEnumerable<T> ToIEnum<T>(IntPtr ptr, int count, int prefixBytes = 0)
{
if (count != 0 && !(ptr == IntPtr.Zero))
{
int stSize = Marshal.SizeOf(typeof(T));
for (int i = 0; i < count; ++i)
yield return ToStructure<T>(new IntPtr(ptr.ToInt64() + prefixBytes + i * stSize));
}
}
public static T ToStructure<T>(IntPtr ptr, long allocatedBytes = -1)
{
Type type = typeof(T).IsEnum ? Enum.GetUnderlyingType(typeof(T)) : typeof(T);
if (allocatedBytes < 0L || allocatedBytes >= (long) Marshal.SizeOf(type))
{
return (T) Marshal.PtrToStructure(ptr, type);
}
throw new InsufficientMemoryException();
}
public struct AUDIT_POLICY_INFORMATION
{
public Guid AuditSubCategoryGuid;
public AuditCondition AuditingInformation;
public Guid AuditCategoryGuid;
}
public enum AuditCondition : uint
{
/// <summary>Do not change auditing options for the specified event type.
/// <para>This value is valid for the AuditSetSystemPolicy and AuditQuerySystemPolicy functions.</para></summary>
POLICY_AUDIT_EVENT_UNCHANGED = 0,
/// <summary>Audit successful occurrences of the specified event type.
/// <para>This value is valid for the AuditSetSystemPolicy and AuditQuerySystemPolicy functions.</para></summary>
POLICY_AUDIT_EVENT_SUCCESS = 1,
/// <summary>Audit failed attempts to cause the specified event type.
/// <para>This value is valid for the AuditSetSystemPolicy and AuditQuerySystemPolicy functions.</para></summary>
POLICY_AUDIT_EVENT_FAILURE = 2,
/// <summary>Do not audit the specified event type.
/// <para>This value is valid for the AuditSetSystemPolicy and AuditQuerySystemPolicy functions.</para></summary>
POLICY_AUDIT_EVENT_NONE = 4,
/// <summary>Do not change auditing options for the specified event type.
/// <para>This value is valid for the AuditSetPerUserPolicy and AuditQueryPerUserPolicy functions.</para></summary>
PER_USER_POLICY_UNCHANGED = 0,
/// <summary>Audit successful occurrences of the specified event type.
/// <para>This value is valid for the AuditSetPerUserPolicy and AuditQueryPerUserPolicy functions.</para></summary>
PER_USER_AUDIT_SUCCESS_INCLUDE = POLICY_AUDIT_EVENT_SUCCESS, // 0x00000001
/// <summary>Do not audit successful occurrences of the specified event type.
/// <para>This value is valid for the AuditSetPerUserPolicy and AuditQueryPerUserPolicy functions.</para></summary>
PER_USER_AUDIT_SUCCESS_EXCLUDE = POLICY_AUDIT_EVENT_FAILURE, // 0x00000002
/// <summary>Audit failed attempts to cause the specified event type.
/// <para>This value is valid for the AuditSetPerUserPolicy and AuditQueryPerUserPolicy functions.</para></summary>
PER_USER_AUDIT_FAILURE_INCLUDE = POLICY_AUDIT_EVENT_NONE, // 0x00000004
/// <summary>Do not audit failed attempts to cause the specified event type.
/// <para>This value is valid for the AuditSetPerUserPolicy and AuditQueryPerUserPolicy functions.</para></summary>
PER_USER_AUDIT_FAILURE_EXCLUDE = 8,
/// <summary>Do not audit the specified event type.
/// <para>This value is valid for the AuditSetPerUserPolicy and AuditQueryPerUserPolicy functions.</para></summary>
PER_USER_AUDIT_NONE = 16, // 0x00000010
}
public static int GetPolicy(String uid)
{
var guid = new Guid(uid);
var result = AuditQuerySystemPolicy(new[] {guid});
foreach (var info in result)
{
return (int) info.AuditingInformation;
}
return -1;
}
}
}
'@
Add-Type -TypeDefinition $TypeDefinition -Language CSharp
$result = [Audit.AuditPol]::GetPolicy("0CCE9211-69AE-11D9-BED3-505054503030")
$success = ($result -band 1) -ne 0;
$failure = ($result -band 2) -ne 0;
$none = ($result -band 4) -ne 0;
Write-Output "Success: $success, Failure: $failure, None: $none";
Upvotes: 2