枚举权限(本地安全策略)

时间:2011-07-10 18:15:55

标签: c++ windows security policy user-accounts

我知道NT标头的所有常量都定义为SE_TAKE_OWNERSHIP_NAME,因此可以使用函数将它们转换为人类可读形式(Take ownership of files or other objects)。

我的问题是如何枚举这些名字?对于不同版本的Windows,并非所有SE名称都适用(即特定NT系统上可能无法使用特权)。

虽然Windows7 / 2008确实是最新且适当的标题会列出所有这些 - 并且如果应用程序在较低的平台上运行,那么使用SE名称的函数如果给定给定名称将会失败操作系统不支持(如LsaEnumerateAccountsWithUserRight会失败)。

但是如何使应用程序未来兼容,以便于列出未来版本的Windows操作系统的所有权限?

2 个答案:

答案 0 :(得分:2)

使用LsaEnumeratePrivileges(在ntlsa.h中定义,位于WDK - inc / api中):

NTSTATUS
NTAPI
LsaEnumeratePrivileges(
    __in LSA_HANDLE PolicyHandle,
    __inout PLSA_ENUMERATION_HANDLE EnumerationContext,
    __out PVOID *Buffer,
    __in ULONG PreferedMaximumLength,
    __out PULONG CountReturned
    );

你得到的缓冲区是一个POLICY_PRIVILEGE_DEFINITION结构数组:

typedef struct _POLICY_PRIVILEGE_DEFINITION
{
    LSA_UNICODE_STRING Name;
    LUID LocalValue;
} POLICY_PRIVILEGE_DEFINITION, *PPOLICY_PRIVILEGE_DEFINITION;

例如:

#include <ntlsa.h>

NTSTATUS status;
LSA_HANDLE policyHandle;
LSA_ENUMERATION_HANDLE enumerationContext = 0;
PPOLICY_PRIVILEGE_DEFINITION buffer;
ULONG countReturned;
ULONG i;

LsaOpenPolicy(..., &policyHandle);

while (TRUE)
{
    status = LsaEnumeratePrivileges(policyHandle, &enumerationContext, &buffer, 256, &countReturned);

    if (status == STATUS_NO_MORE_ENTRIES)
        break; // no more privileges
    if (!NT_SUCCESS(status))
        break; // error

    for (i = 0; i < countReturned; i++)
    {
        // Privilege definition in buffer[i]
    }

    LsaFreeMemory(buffer);
}

LsaClose(policyHandle);

答案 1 :(得分:0)

工作代码:

#include <Windows.h>
#include <iostream>
#include <ntstatus.h>
typedef LONG NTSTATUS, *PNTSTATUS;

typedef struct _UNICODE_STRING {
  USHORT Length;
  USHORT MaximumLength;
  PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

typedef struct _STRING {
  USHORT Length;
  USHORT MaximumLength;
  PCHAR Buffer;
} STRING, *PSTRING;

typedef LARGE_INTEGER OLD_LARGE_INTEGER;
typedef LARGE_INTEGER POLD_LARGE_INTEGER;

#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#include <ntlsa.h>

LSA_HANDLE GetPolicyHandle() {
  LSA_OBJECT_ATTRIBUTES ObjectAttributes;
  NTSTATUS ntsResult;
  LSA_HANDLE lsahPolicyHandle;

  // Object attributes are reserved, so initialize to zeros.
  ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));

  // Get a handle to the Policy object.
  ntsResult = LsaOpenPolicy(NULL,              // 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;
}

void main() {
  NTSTATUS status;
  LSA_HANDLE policyHandle;
  LSA_ENUMERATION_HANDLE enumerationContext = 0;
  PPOLICY_PRIVILEGE_DEFINITION buffer;
  ULONG countReturned;
  ULONG i;
  policyHandle = GetPolicyHandle();

  while (TRUE) {
    status = LsaEnumeratePrivileges(policyHandle, &enumerationContext,
                                    (PVOID *)&buffer, 256, &countReturned);

    if (status == STATUS_NO_MORE_ENTRIES)
      break; // no more privileges
    if (!NT_SUCCESS(status))
      break; // error

    for (i = 0; i < countReturned; i++) {
      // Privilege definition in buffer[i]
      std::wcout << L"KEY:" << buffer[i].Name.Buffer << L" HIGH VALUE:"
                 << buffer[i].LocalValue.HighPart << L"LOW VALUE:"
                 << buffer[i].LocalValue.LowPart << std::endl;
    }

    LsaFreeMemory(buffer);
  }

  LsaClose(policyHandle);
}