提升权限令牌

摘要:
AdjustTokenPrivileges()简介:函数:用于启用或禁用,指定访问令牌的权限。);参数TokenHandle包含要修改的权限的访问令牌的句柄。如果PreviousState参数不为NULL,则句柄还必须具有TOKEN_QUERY访问权限。DisableAllPrivileges指定函数是否禁用所有标记的权限。NewState指向指向PRIVILEGES结构的TOKEN_指针,该结构指定特权数组及其属性。也就是说,如果此函数修改权限,则权限及其先前状态将包含在PreviousState_PRIVILEGES结构引用的TOKEN中。如果TOKEN_如果PRIVILEGES的PrivilegeCount成员为零,则此函数不会更改任何权限。

提权相关函数:

GetCurrentProcess() 介绍:

功能:检索当前进程的伪句柄。

函数原型:HANDLE GetCurrentProcess();

返回值:返回值是当前进程的伪句柄。

OpenProcessToken() 介绍:
功能:打开与进程相关联的访问令牌。

函数原型:BOOL WINAPI OpenProcessToken(

                  HANDLE  ProcessHandle,   // 要修改访问权限的进程句柄。
                  DWORD   DesiredAccess, // 指定你要进行的操作类型。
                  PHANDLE TokenHandle  // 返回的访问令牌的指针。
                  );

参数

DesiredAccess

常用值:

TOKEN_ADJUST_PRIVILEGESTOKEN_ADJUST_GROUPSTOKEN_ADJUST_DEFAULTTOKEN_EXECUTE
TOKEN_QUERYTOKEN_READTOKEN_WRITETOKEN_ALL_ACCESS

如要修改访问令牌的特权,我们要指定第二个参数为 TOKEN_ADJUST_PRIVILEGES

返回值:非零表示成功,零表示失败。

AdjustTokenPrivileges() 介绍:

功能:用于启用或禁止,指定访问令牌的特权。

函数原型:BOOL WINAPI AdjustTokenPrivileges(
                  HANDLE   TokenHandle,  // 要修改的权限的访问令牌的句柄。
                  BOOL  DisableAllPrivileges, // 指定函数是否禁用所有标记的权限。
                  PTOKEN_PRIVILEGES  NewState, // 指向 TOKEN_PRIVILEGES 结构的指针, 它指定特权数组及其属性。
                  DWORD  BufferLength, // 指定由 PreviousState 参数指向的缓冲区的大小 (以字节为单位)。
                  PTOKEN_PRIVILEGES  PreviousState, // 一个指向缓冲区的指针。
                  PDWORD  ReturnLength // 一个指针, 该变量接收 PreviousState 参数指向的缓冲区所需的大小 (以字节为单位)。
                  );

参数

TokenHandle

包含要修改的权限的访问令牌的句柄。句柄必须具有对令牌的 TOKEN_ADJUST_PRIVILEGES 访问权限。

如果 PreviousState 参数不是 NULL, 则句柄还必须具有 TOKEN_QUERY 访问权限。

DisableAllPrivileges

指定函数是否禁用所有标记的权限。如果此值为 TRUE, 则该函数将禁用所有权限并忽略 NewState 参数。

如果是 FALSE, 则该函数根据 NewState 参数指向的信息修改权限。

NewState

指向 TOKEN_PRIVILEGES 结构的指针, 它指定特权数组及其属性。

如果 DisableAllPrivileges 参数为 FALSE, 则 AdjustTokenPrivileges 函数启用、禁用或删除令牌的这些特权。

它的值有这三个:SE_PRIVILEGE_ENABLED,SE_PRIVILEGE_REMOVED,None

BufferLength

指定由 PreviousState 参数指向的缓冲区的大小 (以字节为单位)。如果 PreviousState 参数为 NULL, 则此参数可以为零。

PreviousState

一个指向缓冲区的指针, 该函数用包含该函数修改的任何特权的以前状态的 TOKEN_PRIVILEGES 结构填充。

即, 如果此函数修改了权限, 则该特权及其以前的状态将包含在 PreviousState 引用的 TOKEN_PRIVILEGES 结构中。

如果 TOKEN_PRIVILEGES 的 PrivilegeCount 成员为零, 则此函数不更改任何特权。此参数可以为 NULL。

ReturnLength

一个指针, 该变量接收 PreviousState 参数指向的缓冲区所需的大小 (以字节为单位)。

返回值:如果函数成功, 则返回值为非零。如果失败,则可以是:ERROR_SUCCESS,ERROR_NOT_ALL_ASSIGNED。

TOKEN_PRIVLEGES 结构体:

typedef struct _TOKEN_PRIVILEGES {
  DWORD               PrivilegeCount; // 这必须设置为权限数组中的项数。
  LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY]; // ANYSIZE_ARRAY 宏定义为 1
  } TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;

LUID_AND_ATTRIBUTES 结构体:

typedef struct _LUID_AND_ATTRIBUTES {
  LUID  Luid; 
  DWORD Attributes; // 指定 LUID 的属性。此值最多包含32个单比特标志。它的意思取决于 LUID 的定义和用途。
  } LUID_AND_ATTRIBUTES, *PLUID_AND_ATTRIBUTES;
属性
描述
SE_PRIVILEGE_ENABLED_BY_DEFAULT
特权默认启用
SE_PRIVILEGE_ENABLED
特权启用.
SE_PRIVILEGE_REMOVED
删除特权
SE_PRIVILEGE_USED_FOR_ACCESS
特权被用来访问一个对象或服务。
这个标志 被用于 标识有关特权,因为
通过一组客户端应用程序,可能包含不必要的特权

LUDI 结构体:

typedef struct _LUID {
  DWORD LowPart; // 低阶位。
  LONG  HighPart; // 高阶位。
  } LUID, *PLUID;

本地唯一标识符 (LUID) 是仅在生成它的系统上保证唯一的64位值。只有在系统重新启动之前, 才能保证 LUID 的唯一性。

LUID 不是直接操纵的。驱动程序必须使用支持例程和结构来操作 LUID 值。

若要获取与 LUID 关联的特权的名称, 请调用 LookupPrivilegeName():

LookupPrivilegeName() 介绍:

功能:检索与指定的本地唯一标识符 (LUID) 在特定系统上表示的权限相对应的名称。

函数原型:BOOL LookupPrivilegeName(
                  LPCSTR  lpSystemName,  // 一个指针, 它指定检索特权名称的系统的名称。本地系统为 NULL。
                  PLUID   lpLuid, // 指向目标系统上已知权限的 LUID 的指针。
                  LPSTR   lpName, // 一个指向缓冲区的指针, 它接收表示特权名称的以 NULL 结尾的字符串。
                  LPDWORD cchName // 一个指针, 该变量指定 lpName 缓冲区的大小。
                  ); 

https://docs.microsoft.com/zh-cn/windows/desktop/SecAuthZ/privilege-constants

返回值:非零表示成功,零表示失败。

LookupPrivilegeValue() 介绍:

功能:查看系统权限的特权值,返回信息到一个LUID结构体里。

函数原型:BOOL LookupPrivilegeValue(
                  LPCSTR lpSystemName, // 一个指针, 它指定检索特权名称的系统的名称。本地系统为 NULL。
                  LPCSTR lpName, // 一个指针, 指定特权的名称.
                  PLUID  lpLuid // 一个指向一个变量的指针, 它接收到由 lpSystemName 参数指定的系统上已知权限的 LUID。
                   );

参数 lpName:

返回值:非零表示成功,零表示失败。

DEMOCODE:

BOOL PreProcess()
{
    HANDLE hToken;
    TOKEN_PRIVILEGES TKP;
    //PTOKEN_PRIVILEGES TKP = (PTOKEN_PRIVILEGES)malloc(sizeof(TOKEN_PRIVILEGES) + N * sizeof(LUID_AND_ATTRIBUTES));
    if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken) == 0)
    {
        return FALSE;
    }

    if (LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &TKP.Privileges->Luid) == 0)
    {
        return FALSE;
    }

/*    if (LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &TKP->Privileges[0].Luid) == 0 ||
          LookupPrivilegeValue(NULL, SE_SECURITY_NAME, &TKP->Privileges[1].Luid) == 0
          ......)
    {
        return FALSE;
    }
*/
    TKP.PrivilegeCount = 1;
    TKP.Privileges->Attributes = SE_PRIVILEGE_ENABLED;
/*    TKP->PrivilegeCount = N+1;
    for ( i = 0; i <= N; i++)
    {
        TKP->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED;
    }
*/
    if (AdjustTokenPrivileges(hToken, FALSE, &TKP, 0, NULL, 0) == 0)
    {
        return FALSE;
    }
CloseHandle(hToken);
return TRUE; } BOOL ShutDown() { if (ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE, 0) == 0) return FALSE; return TRUE; }

步骤应该很清楚了......

免责声明:文章转载自《提升权限令牌》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇H5离线缓存基础DDD从入门到精通:基础篇下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

快速打造 react 后台管理系统

前言 相信很多小伙伴都有可能碰到开发后台管理系统这样的需求,那么我们该如何快速的完成这个需求呢 本文将以 react 为切入点,记录打造一个基础管理系统模板的过程,以此加深对 react 技术栈以及项目实战的理解,希望对大家开发一个这样的项目有所帮助 如果文章中有出现纰漏、错误之处,还请看到的小伙伴多多指教,先行谢过 项目简介 react-admin 是由...

权限认证机制

一、Form表单认证 之前的项目以MVC为主,采用的是from表单认证,Forms认证示意图如下: HTTP是一个无状态的协议,WEB服务器在处理所有传入HTTP请求时,根本就不知道某个请求是否是一个用户的第一次请求与后续请求,或者是另一个用户的请求。 WEB服务器每次在处理请求时,都会按照用户所访问的资源所对应的处理代码,从头到尾执行一遍,然后输出响应...

三个给进程提权的方法 (c/cpp)

三个给进程提权的方法 方法一: C/C++ code bool EnableDebugPrivilege() { HANDLE hToken; LUID sedebugnameValue; TOKEN_PRIVILEGES tkp; if (!OpenProcessToken(GetCur...

澄清VB调用API时字符串参数的困惑

声明:本文部分内容来源于网络! 首先,我认为这样花费精力去研究VB调用API字符串的种种猫腻是很有必要的。本着严谨和发现问题与解决问题的原则,和为了能更好的认识问题的本质,我特写了这篇冗长的讨论。网上有很多关于此的讨论,但比较杂乱,目的不明确,也很难懂。在此也就是做个总结吧!让大家能有一个清楚认识。 我的问题是从调用内存API时参数的ByVal VarPt...

c语言进阶6-指针

指针是c语言的一个重要组成部分 是c语言的核心、精髓所在,用好指针可以在c语言编程中起到事半功倍的效果。一方面,可以提高程序的编译效率和执行速度以及实现动态的存储分配;另一方面,使用指针可使程序更灵活,全球表示各种数据结构,编写高质量的程序。 指针是c语言显著的优点之一,其使用起来十分灵活而且能提高某些程序的效率,但是如果使用不当则很容易造成系统错误。许多...

防止表单重复提交

1.方法一 在servlet中模拟网络延迟造成表单重复提交 //解决表单重复提交方法 //接收数据 String username = req.getParameter("username"); System.out.println("接收的数据为:"+username);...