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

发布于 2024-11-19 03:06:01 字数 404 浏览 3 评论 0原文

我知道 NT 标头具有像 SE_TAKE_OWNERSHIP_NAME 这样定义的所有常量,因此可以使用函数将这些常量转换为人类可读的形式(取得文件或其他对象的所有权)。

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

虽然 Windows7/2008 确实是最新且合适的标头,但它会列出所有这些标头 - 如果应用程序在较低平台上运行,则如果给定操作系统不这样做,则采用 SE 名称的函数对于给定名称将会失败。不支持(例如LsaEnumerateAccountsWithUserRight会失败)。

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

I am aware that NT header has all constants defined like SE_TAKE_OWNERSHIP_NAME, and so there are functions available to convert these into human readable form (Take ownership of files or other objects).

My question is how to enumerate these names? With different versions of Windows, not all SE-names would be applicable (i.e. privileges may not be available on particular NT system).

Whilst it is true that Windows7/2008 is the latest and appropriate header for the same would list all of them - and if the application runs on a lower platform, the function taking SE-names would simply fail for given name if given OS doesn't support (like LsaEnumerateAccountsWithUserRight would fail).

But how to make application future compatible that can facilitate listing all privileges for future versions of Windows OS?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

转瞬即逝 2024-11-26 03:06:01

使用 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);

Use LsaEnumeratePrivileges (defined in ntlsa.h, which is in the WDK - inc/api):

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

The buffer that you get is an array of POLICY_PRIVILEGE_DEFINITION structures:

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

For example:

#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);
毅然前行 2024-11-26 03:06:01

工作代码:

#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);
}

Working code:

#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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文