有两种方法:
1、使用API LsaQueryInformationPolicy,测试Win2003,2008,Win7都可以,应该和Windows版本无关。
上代码:
LSA_HANDLE CDlgSysInfo::GetPolicyHandle()
{
LSA_OBJECT_ATTRIBUTES ObjectAttributes;
// WCHAR SystemName[] = TARGET_SYSTEM_NAME;
USHORT SystemNameLength;
LSA_UNICODE_STRING lusSystemName;
NTSTATUS ntsResult;
LSA_HANDLE lsahPolicyHandle;
// 对象属性被保留,初始化为0
ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
//初始化服务器名称/Initialize an LSA_UNICODE_STRING to the server name.
// SystemNameLength = wcslen(SystemName);
// lusSystemName.Buffer = SystemName;
// lusSystemName.Length = SystemNameLength * sizeof(WCHAR);
// lusSystemName.MaximumLength = (SystemNameLength+1) * sizeof(WCHAR);
// 获得一个策略对象句柄Get a handle to the Policy object.
ntsResult = LsaOpenPolicy(
NULL,//&lusSystemName, //Name of the target system.
&ObjectAttributes, //Object attributes.
POLICY_ALL_ACCESS, //Desired access permissions.
&lsahPolicyHandle //Receives the policy handle.
);
if (ntsResult != STATUS_SUCCESS)
{
// 显示错误信息An error occurred. Display it as a win32 error code.
wprintf(L"OpenPolicy returned %lu\n",
LsaNtStatusToWinError(ntsResult));
return NULL;
}
return lsahPolicyHandle;
}
BOOL CDlgSysInfo::GetSecAuditSetting(CString & strInfo)
{
LSA_HANDLE handle = GetPolicyHandle();
PPOLICY_AUDIT_EVENTS_INFO pInfo;
if(NULL != handle)
{
NTSTATUS status = LsaQueryInformationPolicy(handle,PolicyAuditEventsInformation,(void **)&pInfo);
if(status == STATUS_SUCCESS
&&pInfo->AuditingMode)
{
for(int i=0;i<pInfo->MaximumAuditEventCount;i++)
{
switch(i)
{
#define GET_AUDIT_STR(x) do{\
CString str;\
if(POLICY_AUDIT_EVENT_SUCCESS&pInfo->EventAuditingOptions[i]){\
str+="成功";\
}\
if(POLICY_AUDIT_EVENT_FAILURE&pInfo->EventAuditingOptions[i]){\
str+=str.GetLength()==0?"失败":"|失败";\
}\
if(str.GetLength() == 0){\
str+="无审核";\
}\
str+="\r\n";\
strInfo+=x;\
strInfo+=str;\
}while(0)
case AuditCategorySystem:
GET_AUDIT_STR("审核系统事件 ");
break;
case AuditCategoryLogon:
GET_AUDIT_STR("审核登录事件 ");
break;
case AuditCategoryObjectAccess:
GET_AUDIT_STR("审核对象访问 ");
break;
case AuditCategoryPrivilegeUse:
GET_AUDIT_STR("审核特权使用 ");
break;
case AuditCategoryDetailedTracking:
GET_AUDIT_STR("审核过程跟踪 ");
break;
case AuditCategoryPolicyChange:
GET_AUDIT_STR("审核策略更改 ");
break;
case AuditCategoryAccountManagement:
GET_AUDIT_STR("审核账户管理 ");
break;
case AuditCategoryDirectoryServiceAccess:
GET_AUDIT_STR("审核目录服务访问 ");
break;
case AuditCategoryAccountLogon:
GET_AUDIT_STR("审核账户登录事件 ");
break;
default:
break;
}
}
}
else
{
Log::info(LOG_MARK,"LsaQueryInformationPolicy ret:%u",status);
}
}
return TRUE;
}
2、注册表,这里只测试了Win2003,通过读写注册表都能得到或者修改安全日志的审计策略。
注册表键:
//系统安全日志配置选项对应注册表节点
#define REG_SECPOLICY_OPT "HKEY_LOCAL_MACHINE\\SECURITY\\Policy\\PolAdtEv"
这个注册表键值是个二进制值,共有11个DWORD,中间9个DWORD对应审核策略,每个策略对应一个DWORD,前后两个DWORD作用位置,跟踪了一下和审计策略关系:
定义数组:
struct _SEC_EDIT_
{
int uIndex;
char szName[50];
}g_sec_dirc[] = {
{0,""},
{1,"审核系统事件"},
{2,"审核登录事件"},
{3,"审核对象访问"},
{4,"审核特权访问"},
{5,"审核过程跟踪"},
{6,"审核策略更改"},
{7,"审核账户管理"},
{8,"审核目录服务访问"},
{9,"审核账户登录事件"},
{10,""}
};
然后读取注册表值,对照这个结构数组就能获得审核策略配置。通过修改注册表也能实现修改策略。