首页 > 系统相关 >7.4 通过API枚举进程权限

7.4 通过API枚举进程权限

时间:2023-09-23 11:05:50浏览次数:41  
标签:GetTokenInformation 令牌 句柄 TOKEN 枚举 API 7.4 hToken dwLen

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 许可协议。转载请注明出处!

标签:GetTokenInformation,令牌,句柄,TOKEN,枚举,API,7.4,hToken,dwLen
From: https://blog.51cto.com/lyshark/7576504

相关文章

  • 7.3 通过API枚举进程
    首先实现枚举当前系统中所有进程信息,枚举该进程的核心点在于使用CreateToolhelp32Snapshot()函数,该函数用于创建系统进程和线程快照,它可以捕获当前系统中进程和线程相关的信息(如PID、线程数量、线程ID等),在对这些信息进行处理后,可以获得很多有用的数据,如当前系统中所有正在执行的进......
  • 7.4 通过API枚举进程权限
    GetTokenInformation用于检索进程或线程的令牌(Token)信息。Token是一个数据结构,其包含有关进程或线程的安全上下文,代表当前用户或服务的安全标识符和权限信息。GetTokenInformation函数也可以用来获取这些安全信息,通常用于在运行时检查某个进程或线程的权限或安全信息。该函数......
  • 访问api地址时添加cookie头,防止cookie刷新
    putSession(){wx.request({url:'http://127.0.0.1:8000/api/test1',success(res){console.log(res);wx.setStorageSync('session',res.cookies)},dataType:'json'})},get......
  • Apipost最佳实践
    自诞生以来,Apipost凭借其简洁直观的用户界面、强大的功能以及简单、易上手的操作,让Apipost成为了开发人员不可或缺的工具。本文将详细介绍Apipost的主要功能和使用方法,帮助大家更好地了解这款优秀的API开发工具。下载安装直接进入Apipost官网下载即可,也可以直接使用web端无需下......
  • 2023-09-22 uniapp之canvas调用api【uni.canvasToTempFilePath】报错返回:canvasToTemp
    canvasToTempFilePath:失败-失败画布为空一般的解决方案就是查看uni.canvasToTempFilePath的传参是否正确,一个是canvasId必须正确,另一个就是第二个参数为this;但事情显示没那么简单,这二者我都有填写,却仍旧报这个错,我把canvasid换成别的,最后我想起了一件事情,就是canvas为空是因为......
  • FastAPI Request中存储信息
    在请求前拦截,检测token使用Request.state.XXX存信息fromfastapiimportRequest,FastAPIfrompy_jwt.use_jwtimportdecode_tokende......
  • 枚举与类的区别
    枚举的构造方法是私有的private修饰可以,public修饰报错类的构造方法是公有的public修饰2说到枚举只能私有构造,所以如果枚举类里定义抽象方法,每个实例里边都需要实现这个方法如果要实现一个接口,每个实例方法里边也要实现接口里的所有方法如果枚举类里定义了普通方法,实例是......
  • 在线问诊 Python、FastAPI、Neo4j — 创建 节点关系
    目录关系:症状-检查关系:疾病-症状代码重构relationship_data.csv症状,检查,疾病,药品,宜吃,忌吃"上下楼梯疼,不能久站,感觉有点肿","膝关节核磁","右膝髌上囊及关节腔少量积液","扶他林","西红柿,香蕉","辣椒,大蒜""眼睛胀痛,干涩,畏光,眼胀,眼痛,看东西有时候清楚有时候不清楚......
  • 7.1 实现进程内存块枚举
    在Windows操作系统中,每个进程的虚拟地址空间都被划分为若干内存块,每个内存块都具有一些属性,如内存大小、保护模式、类型等。这些属性可以通过VirtualQueryEx函数查询得到。该函数可用于查询进程虚拟地址空间中的内存信息的函数。它的作用类似于Windows操作系统中的TaskManager中......
  • 7.2 通过API创建新进程
    创建新的进程是Windows程序开发的重要部分,它可以用于实现许多功能,例如进程间通信、并行处理等。其中,常用的三种创建进程的方式分别是WinExec()、ShellExecute()和CreateProcessA(),这三种创建进程的方式各有特点。如果需要创建简单进程或从其他程序启动新进程,可以使用WinExec()或Sh......