7.4 通过API枚举进程权限

通过,api,枚举,进程,权限 · 浏览次数 : 156

小编点评

**GetTokenInformation 函数** `GetTokenInformation` 函数用于检索进程或线程的令牌信息。它接受一个句柄,表示要检索的令牌,以及一个指向缓冲区的指针,用于存储检索到的信息。函数返回一个布尔值,表示检索是否成功。 **参数** * `TokenHandle`:进程或线程令牌的句柄。 * `TokenInformationClass`:要检索的令牌信息类别,是 `TOKEN_INFORMATION_CLASS`枚举类型的值之一。 * `TokenInformation`:指向要接收信息的缓冲区指针。 * `TokenInformationLength`:要接收的缓冲区的大小(以字节为单位)。 * `ReturnLength`:实际缓冲区的大小(以字节为单位)。 **返回值** * 如果函数执行成功,则返回 `TRUE`。 * 如果函数返回 `FALSE`,则可以调用 `GetLastError()` 函数获取错误代码。 **常见的值** `TokenInformationClass`: * `TokenUser`:用户标识信息。 * `TokenGroups`:组信息。 * `TokenOwner`:所有者信息。 * `TokenPrimaryGroup`:主组信息。 * `TokenPrivileges`:特权信息。 * `TokenSessionId`:会话ID信息。 **示例** ```c // 获取当前进程的令牌信息 HANDLE hToken = GetCurrentProcess(); // 获取用户标识信息 TOKEN_USER* pUser = GetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize); // 打印用户名称 printf("[+] 当前进程身份: %s \\", pUser->Sid); // 释放内存 LocalFree(pUser); ``` **注意** * `GetTokenInformation` 函数需要在运行时调用,因为它需要检索进程或线程的令牌。 * 您可以使用 `TOKEN_INFORMATION_CLASS`枚举类型的值来指定要检索的令牌信息类别。 * 您可以使用 `LocalAlloc()` 和 `CopySid()` 函数来分配内存并复制用户标识符。

正文

GetTokenInformation 用于检索进程或线程的令牌(Token)信息。Token是一个数据结构,其包含有关进程或线程的安全上下文,代表当前用户或服务的安全标识符和权限信息。GetTokenInformation函数也可以用来获取这些安全信息,通常用于在运行时检查某个进程或线程的权限或安全信息。

该函数原型如下:

BOOL GetTokenInformation(
  HANDLE TokenHandle,
  TOKEN_INFORMATION_CLASS TokenInformationClass,
  LPVOID TokenInformation,
  DWORD TokenInformationLength,
  PDWORD ReturnLength
);

参数说明:

  • TokenHandle:当前进程或线程令牌的句柄。
  • TokenInformationClass:表示要检索的Token信息类别,是TOKEN_INFORMATION_CLASS枚举类型的值之一。这个参数的值确定TokenInformation参数的方案,以及返回的信息类型。
  • TokenInformation:指向要接收信息的缓冲区的指针。
  • TokenInformationLength:要接收的缓冲区的大小(以字节为单位)。
  • ReturnLength:实际缓冲区的大小(以字节为单位)。

常见的TokenInformationClass值包括:

  • TokenUser:用户标识信息;
  • TokenGroups:组信息;
  • TokenOwner:所有者信息;
  • TokenPrimaryGroup:主组信息;
  • TokenPrivileges:特权信息;
  • TokenSessionId:会话ID信息。

该函数的返回值为BOOL类型。如果函数执行成功,则返回非零值,否则返回零。如果函数返回零,则可以调用 GetLastError() 函数获取错误代码。

#include <stdio.h>
#include <ShlObj.h>
#include <Windows.h>

void ShowPrviliges(HANDLE process)
{
  // 通过进程句柄获取到进程令牌
  HANDLE hToken;
  OpenProcessToken(process, TOKEN_QUERY, &hToken);

  // 获取查询到的令牌信息
  DWORD dwSize;
  GetTokenInformation(hToken, TokenPrivileges, NULL, NULL, &dwSize);

  // 根据令牌中的大小分配空间
  char* pBuf = new char[dwSize] {};
  GetTokenInformation(hToken, TokenPrivileges, pBuf, dwSize, &dwSize);

  // 将内存中的内容用要查询数据结构体解析
  TOKEN_PRIVILEGES* pTp = (TOKEN_PRIVILEGES*)pBuf;
  DWORD dwCount = pTp->PrivilegeCount;               // 解析出权限个数
  LUID_AND_ATTRIBUTES* pluid = pTp->Privileges;      // 具备的权限类型

  for (int i = 0; i < dwCount; i++, pluid++)
  {
    char szName[100] = {};
    DWORD dwLen = sizeof(szName);
    LookupPrivilegeNameA(0, &pluid->Luid, szName, &dwLen);
    switch (pluid->Attributes)
    {
    case 0:
      printf("ID => %3d \t 状态 => 关闭 \t\t 类型 => %s \n", i, szName); break;
    case 1:
      printf("ID => %3d \t 状态 => 默认 \t\t 类型 => %s \n", i, szName); break;
    case 2:
      printf("ID => %3d \t 状态 => 开启 \t\t 类型 => %s \n", i, szName); break;
    case 3:
      printf("ID => %3d \t 状态 => 默认开启 \t\t 类型 => %s \n", i, szName); break;
    }
  }
  delete pBuf;
}

int main(int argc, char* argv[])
{
  // 拿到自身程序的句柄
  HANDLE LocalProcess = GetCurrentProcess();
  ShowPrviliges(LocalProcess);

  system("pause");
  return 0;
}

如下所示代码同样是一段权限检索的实现,函数EnumOwner()接受一个指向进程令牌的句柄,并使用它来检索有关令牌用户的信息。使用GetTokenInformation()获取一个包含令牌用户的安全标识符(SID)指针的TOKEN_USER结构。然后,它使用LocalAlloc()SID分配内存,并使用CopySid()SID复制到该内存中。最后使用LookupAccountSid()检索与SID相关联的用户账户的名称。函数返回指向包含账户名称的字符字符串的指针。

main()函数中使用OpenProcess()PROCESS_QUERY_INFORMATION标志检索当前进程的句柄。然后,它使用OpenProcessToken()TOKEN_QUERY标志检索进程令牌的句柄。将该句柄传递给EnumOwner()以检索与令牌相关联的用户账户名称。最后使用printf()打印账户名称,使用CloseHandle()关闭令牌句柄,使用CloseHandle()关闭进程句柄。

#include <stdio.h>
#include <Windows.h>
#include <TlHelp32.h>

// 通过进程Token获取进程权限类型
char * __stdcall EnumOwner(HANDLE htoken)
{
  DWORD dwLen;
  PSID pSid = 0;
  TOKEN_USER* pWork;
  SID_NAME_USE use;
  TCHAR User[256], Domain[256];

  GetTokenInformation(htoken, TokenUser, NULL, 0, &dwLen);
  pWork = (TOKEN_USER*)LocalAlloc(LMEM_ZEROINIT, dwLen);
  if (GetTokenInformation(htoken, TokenUser, pWork, dwLen, &dwLen))
  {
    dwLen = GetLengthSid(pWork->User.Sid);
    pSid = (PSID)LocalAlloc(LMEM_ZEROINIT, dwLen);
    CopySid(dwLen, pSid, pWork->User.Sid);
    dwLen = 256;
    LookupAccountSid(NULL, pSid, &User[0], &dwLen, &Domain[0], &dwLen, &use);
    // printf("\t 主机 => %s \t 权限用户 => %s ", Domain, User);
    return User;
  }
  return NULL;
}

int main(int argc, char* argv[])
{
  HANDLE ProcessHandle, hToken;

  ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION, TRUE,GetCurrentProcessId());
  if (ProcessHandle != NULL)
  {
    if (OpenProcessToken(ProcessHandle, TOKEN_QUERY, &hToken))
    {
      char *token = EnumOwner(hToken);
      printf("[+] 当前进程身份: %s \n", token);
      CloseHandle(hToken);
      CloseHandle(ProcessHandle);
    }
  }

  system("pause");
  return 0;
}

本文作者: 王瑞
本文链接: https://www.lyshark.com/post/136e2c9d.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

与7.4 通过API枚举进程权限相似的内容:

7.4 通过API枚举进程权限

GetTokenInformation 用于检索进程或线程的令牌(Token)信息。Token是一个数据结构,其包含有关进程或线程的安全上下文,代表当前用户或服务的安全标识符和权限信息。GetTokenInformation函数也可以用来获取这些安全信息,通常用于在运行时检查某个进程或线程的权限或安全信息。

手把手带你通过API创建一个loT边缘应用

摘要:使用API Arts&API Explorer调用IoT边缘服务接口创建应用,了解边缘计算在物联网行业的应用。 本文分享自华为云社区《使用API Arts&API Explorer调用IoT边缘服务接口创建应用》,作者:华为IoT云服务。 开始体验前需注册华为云账号并完成实名认证,实验过程中请

7.4 C/C++ 实现链表栈

相对于顺序栈,链表栈的内存使用更加灵活,因为链表栈的内存空间是通过动态分配获得的,它不需要在创建时确定其大小,而是根据需要逐个分配节点。当需要压入一个新的元素时,只需要分配一个新的节点,并将其插入到链表的头部;当需要弹出栈顶元素时,只需要删除链表头部的节点,并释放其所占用的内存空间即可。由于链表栈的空间利用率更高,因此在实际应用中,链表栈通常比顺序栈更受欢迎。在实现上,链表栈通过使用`malloc

Java第二次Blog

7-4~6题目集 前言 这些题目主要用到对象与类的处理继承与多态的使用: 继承和多态是面向对象编程中相互关联的两个概念。继承为多态提供了基础,而多态则通过继承实现了代码的灵活性和可扩展性。 1.字符串处理:需要对输入的题目信息和答题信息进行字符串分割、提取和处理,以获取题目编号、题目内容、标准答案和

[转帖]vm内核参数之缓存回收drop_caches

注:本文分析基于3.10.0-693.el7内核版本,即CentOS 7.4 1、关于drop_caches 通常在内存不足时,我们习惯通过echo 3 > /proc/sys/vm/drop_caches 的方式手动清理系统缓存, [root@localhost ~]# free -m total

4.7 x64dbg 应用层的钩子扫描

所谓的应用层钩子(Application-level hooks)是一种编程技术,它允许应用程序通过在特定事件发生时执行特定代码来自定义或扩展其行为。这些事件可以是用户交互,系统事件,或者其他应用程序内部的事件。应用层钩子是在应用程序中添加自定义代码的一种灵活的方式。它们可以用于许多不同的用途,如安全审计、性能监视、访问控制和行为修改等。应用层钩子通常在应用程序的运行时被调用,可以执行一些预定义的

NetMvc通过亚马逊方式服务器端和客户端上传MinIO顺利解决

前言: 1、由于项目是.NET Framework 4.7 MVC LayUI,所以需要找一个资源站点存放项目中静态资源文件; 2、需要支持服务端和客户端都支持上传文件方式; 3、调用简单,涉及库越少越好。 结果: 调用 AWSSDK.S3 和 AWSSDK.Core 实现文件上传到 MinIO ;

[转帖]【压测】通过Jemeter进行压力测试(超详细)

文章目录 背景一、前言二、关于JMeter三、准备工作四、创建测试4.1、创建线程组4.2、配置元件4.3、构造HTTP请求4.4、添加HTTP请求头4.5、添加断言4.6、添加察看结果树4.7、添加Summary Report4.8、测试计划创建完成 五、执行测试计划总结 背景 通过SpringC

[4]自定义Lua解析器管理器-------演化脚本V0.7

使用自定义委托通过tolua来调用多返回值和长参数类型的函数。 防踩坑指南,使用自定义委托需要将委托类型添加到CustomSettings中。

[转帖]Sql Server中通过sql命令获取cpu占用及产生锁的sql

https://www.jb51.net/article/266255.htm 这篇文章主要介绍了Sql Server中通过sql命令获取cpu占用及产生锁的sql,需要的朋友可以参考下 获取SQLSERVER中产生锁的SQL语句 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1