7.4 通过API枚举进程权限

打印 上一主题 下一主题

主题 870|帖子 870|积分 2610

GetTokenInformation 用于检索进程或线程的令牌(Token)信息。Token是一个数据结构,其包含有关进程或线程的安全上下文,代表当前用户或服务的安全标识符和权限信息。GetTokenInformation函数也可以用来获取这些安全信息,通常用于在运行时检查某个进程或线程的权限或安全信息。
该函数原型如下:
  1. BOOL GetTokenInformation(
  2.   HANDLE TokenHandle,
  3.   TOKEN_INFORMATION_CLASS TokenInformationClass,
  4.   LPVOID TokenInformation,
  5.   DWORD TokenInformationLength,
  6.   PDWORD ReturnLength
  7. );
复制代码
参数说明:

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

  • TokenUser:用户标识信息;
  • TokenGroups:组信息;
  • TokenOwner:所有者信息;
  • TokenPrimaryGroup:主组信息;
  • TokenPrivileges:特权信息;
  • TokenSessionId:会话ID信息。
该函数的返回值为BOOL类型。如果函数执行成功,则返回非零值,否则返回零。如果函数返回零,则可以调用 GetLastError() 函数获取错误代码。
  1. #include <stdio.h>
  2. #include <ShlObj.h>
  3. #include <Windows.h>
  4. void ShowPrviliges(HANDLE process)
  5. {
  6.   // 通过进程句柄获取到进程令牌
  7.   HANDLE hToken;
  8.   OpenProcessToken(process, TOKEN_QUERY, &hToken);
  9.   // 获取查询到的令牌信息
  10.   DWORD dwSize;
  11.   GetTokenInformation(hToken, TokenPrivileges, NULL, NULL, &dwSize);
  12.   // 根据令牌中的大小分配空间
  13.   char* pBuf = new char[dwSize] {};
  14.   GetTokenInformation(hToken, TokenPrivileges, pBuf, dwSize, &dwSize);
  15.   // 将内存中的内容用要查询数据结构体解析
  16.   TOKEN_PRIVILEGES* pTp = (TOKEN_PRIVILEGES*)pBuf;
  17.   DWORD dwCount = pTp->PrivilegeCount;               // 解析出权限个数
  18.   LUID_AND_ATTRIBUTES* pluid = pTp->Privileges;      // 具备的权限类型
  19.   for (int i = 0; i < dwCount; i++, pluid++)
  20.   {
  21.     char szName[100] = {};
  22.     DWORD dwLen = sizeof(szName);
  23.     LookupPrivilegeNameA(0, &pluid->Luid, szName, &dwLen);
  24.     switch (pluid->Attributes)
  25.     {
  26.     case 0:
  27.       printf("ID => %3d \t 状态 => 关闭 \t\t 类型 => %s \n", i, szName); break;
  28.     case 1:
  29.       printf("ID => %3d \t 状态 => 默认 \t\t 类型 => %s \n", i, szName); break;
  30.     case 2:
  31.       printf("ID => %3d \t 状态 => 开启 \t\t 类型 => %s \n", i, szName); break;
  32.     case 3:
  33.       printf("ID => %3d \t 状态 => 默认开启 \t\t 类型 => %s \n", i, szName); break;
  34.     }
  35.   }
  36.   delete pBuf;
  37. }
  38. int main(int argc, char* argv[])
  39. {
  40.   // 拿到自身程序的句柄
  41.   HANDLE LocalProcess = GetCurrentProcess();
  42.   ShowPrviliges(LocalProcess);
  43.   system("pause");
  44.   return 0;
  45. }
复制代码
如下所示代码同样是一段权限检索的实现,函数EnumOwner()接受一个指向进程令牌的句柄,并使用它来检索有关令牌用户的信息。使用GetTokenInformation()获取一个包含令牌用户的安全标识符(SID)指针的TOKEN_USER结构。然后,它使用LocalAlloc()为SID分配内存,并使用CopySid()将SID复制到该内存中。最后使用LookupAccountSid()检索与SID相关联的用户账户的名称。函数返回指向包含账户名称的字符字符串的指针。
在main()函数中使用OpenProcess()和PROCESS_QUERY_INFORMATION标志检索当前进程的句柄。然后,它使用OpenProcessToken()和TOKEN_QUERY标志检索进程令牌的句柄。将该句柄传递给EnumOwner()以检索与令牌相关联的用户账户名称。最后使用printf()打印账户名称,使用CloseHandle()关闭令牌句柄,使用CloseHandle()关闭进程句柄。
  1. #include <stdio.h>
  2. #include <Windows.h>
  3. #include <TlHelp32.h>
  4. // 通过进程Token获取进程权限类型
  5. char * __stdcall EnumOwner(HANDLE htoken)
  6. {
  7.   DWORD dwLen;
  8.   PSID pSid = 0;
  9.   TOKEN_USER* pWork;
  10.   SID_NAME_USE use;
  11.   TCHAR User[256], Domain[256];
  12.   GetTokenInformation(htoken, TokenUser, NULL, 0, &dwLen);
  13.   pWork = (TOKEN_USER*)LocalAlloc(LMEM_ZEROINIT, dwLen);
  14.   if (GetTokenInformation(htoken, TokenUser, pWork, dwLen, &dwLen))
  15.   {
  16.     dwLen = GetLengthSid(pWork->User.Sid);
  17.     pSid = (PSID)LocalAlloc(LMEM_ZEROINIT, dwLen);
  18.     CopySid(dwLen, pSid, pWork->User.Sid);
  19.     dwLen = 256;
  20.     LookupAccountSid(NULL, pSid, &User[0], &dwLen, &Domain[0], &dwLen, &use);
  21.     // printf("\t 主机 => %s \t 权限用户 => %s ", Domain, User);
  22.     return User;
  23.   }
  24.   return NULL;
  25. }
  26. int main(int argc, char* argv[])
  27. {
  28.   HANDLE ProcessHandle, hToken;
  29.   ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION, TRUE,GetCurrentProcessId());
  30.   if (ProcessHandle != NULL)
  31.   {
  32.     if (OpenProcessToken(ProcessHandle, TOKEN_QUERY, &hToken))
  33.     {
  34.       char *token = EnumOwner(hToken);
  35.       printf("[+] 当前进程身份: %s \n", token);
  36.       CloseHandle(hToken);
  37.       CloseHandle(ProcessHandle);
  38.     }
  39.   }
  40.   system("pause");
  41.   return 0;
  42. }
复制代码
本文作者: 王瑞
本文链接: https://www.lyshark.com/post/136e2c9d.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

冬雨财经

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表