进程访问令牌-提升进程权限

   访问令牌是一个被保护的对象,包含了与用户帐户相关的辨识和特权信息。当用户登陆到一台windows计算机,登陆进程会验证用户的登陆凭据。成功后,登陆进程返回一个对应用户的SID(安全标识符)和一个用户的安全组SID列表。计算机LSA使用这些信息创建一个访问令牌(主访问令牌)。该访问令牌包括了由登录进程返回的SIDs和一份由本地安全策略分发给用户以及用户安全组的特权列表。此后,这份访问令牌的拷贝会跟每个代表用户执行的线程和进程链接。

    如果拿到访问令牌,登录成功,要是访问某台本域内计算机的共享资源时,则必须出示访问令牌。从而来决定将拥有何种权限来访问。

    在使用OpenProcess()函数打开一个进程时,通常是没有权限的,这时就需要设置进程访问令牌,更改进程的权限。

 

    我们要修改一个进程的访问令牌,首先要获得进程访问令牌的句柄,这可以通过 OpenProcessToken得到,函数的原型如下:
BOOL OpenProcessToken(

           HANDLE ProcessHandle,
           DWORD DesiredAccess,
           PHANDLE TokenHandle
);
第一参数是要修改访问权限的进程句柄;第三个参数就是返回的访问令牌指针;第二个参数指定你要进行的操作类型,如要修改令牌我们要指定第二个参数为TOKEN_ADJUST_PRIVILEGES(其它一些参数可参考Platform SDK)。通过这个函数我们就可以得到当前进程的访问令牌的句柄(指定函数的第一个参数为GetCurrentProcess()就可以了)。

 

    要修改进程的什么权限?通过函数LookupPrivilegevalue()查看系统权限的特权值,返回信息到一个LUID结构体里。

BOOL LookupPrivilegevalue(
            LPCTSTR lpSystemName, // system name
            LPCTSTR lpName, // privilege name
            PLUID lpLuid // locally unique identifier
);

第一个参数是系统的名称,如果是本地系统只要指明为NULL就可以了,第三个参数就是返回LUID的指针,第二个参数就是指明了权限的名称,如“SeDebugPrivilege”(Winnt.h有详细定义),如果要对一个任意进程进行指定了写相关的访问权限,设为"SeDeDebug"权限就可以了。

 

typedef struct _TOKEN_PRIVILEGES {
          DWORD PrivilegeCount ;
          LUID_AND_ATTRIBUTES Privileges [ANYSIZE_ARRAY];

} TOKEN_PRIVILEGES

该结构包含一个数组,数据组的每个项指明了权限的类型和要进行的操作,PrivilegeCount指的数组元素的个数,接着是一个LUID_AND_ATTRIBUTES类型的数组,再来看一下LUID_AND_ATTRIBUTES这个结构的内容,声明如下:

typedef struct _LUID_AND_ATTRIBUTES {
          LUID Luid;
          DWORD Attributes;
} LUID_AND_ATTRIBUTES, *PLUID_AND_ATTRIBUTES

第一个参数就是指权限的类型,是一个LUID的值,LUID就是指locally unique identifier,保证局部唯一,就是指在系统的每一次运行期间保证是唯一的就可以了。这个就是LookupPrivilegevalue()返回的值。第二个参数就指明了我们要进行的操作类型,有3个可选项: SE_PRIVILEGE_ENABLED、SE_PRIVILEGE_ENABLED_BY_DEFAULT、SE_PRIVILEGE_USED_FOR_ACCESS。

 

最后,调用AdjustTokenPrivileges对这个访问令牌进行修改。AdjustTokenPrivileges的原型如下:
BOOL AdjustTokenPrivileges(
            HANDLE TokenHandle, 
            BOOL DisableAllPrivileges, 
            PTOKEN_PRIVILEGES NewState, 
            DWORD BufferLength, 
            PTOKEN_PRIVILEGES PreviousState, 
            PDWORD ReturnLength
);
第一个参数是访问令牌的句柄(OpenProcessToken()返回的),第二个参数决定是进行权限修改还是Disable所有权限;第三个参数指明要修改的权限,是一个指向 TOKEN_PRIVILEGES结构的指针; 第四个参数是结构NewStateS的长度,如果NewState为空,该参数应为NULL;第五个参数也是一个指向 TOKEN_PRIVILEGES结构的指针,存放修改前的访问权限的信息,可空;最后一个参数为实际PreviousState结构返回的大小。

通过上述的调用,就可以提升OpenProcess()访问权限了。

 

源自:http://blog.csdn.net/proing/article/details/5857642

 

践行渐远

1. OpenProcessToken()获得进程访问令牌句柄

2. LookupPrivilegevalue()查看系统权限的特权值,返回信息到一个LUID结构体里

3. TOKEN_PRIVILEGES 变量的设置

4.  AdjustTokenPrivileges对这个访问令牌进行修改

5. 进行修改权限后的操作

 

让系统重启的代码

BOOL SetProcessPermission(LPCWSTR pszName,DWORD dwPrivilege)
{
    HANDLE hProcess = NULL;
    HANDLE hToken = NULL;
    LUID luid;
    TOKEN_PRIVILEGES Privileges;
    OSVERSIONINFO osv;
    BOOL bRet = FALSE;

    osv.dwOSVersionInfoSize = sizeof OSVERSIONINFO;
    GetVersionEx(&osv);

    if (VER_PLATFORM_WIN32_NT == osv.dwPlatformId)
    {
        hProcess=GetCurrentProcess();

        if (OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken))
        {
            Privileges.PrivilegeCount = 1;
            LookupPrivilegeValue(NULL, pszName, &luid);
            Privileges.Privileges[0].Luid = luid;
            Privileges.Privileges[0].Attributes = dwPrivilege;
            if(AdjustTokenPrivileges(hToken, FALSE, &Privileges, NULL, NULL, NULL))
            {
                bRet = TRUE;
            }
        }
    }

    if (hProcess)
    {
        CloseHandle(hProcess);
        hProcess = NULL;
    }

    if (hToken)
    {
        CloseHandle(hToken);
        hToken = NULL;
    }

    return bRet;
}

 

VOID ExitReboot()
{
  SetProcessPermission(SE_SHUTDOWN_NAME,SE_PRIVILEGE_ENABLED);
  ExitWindowsEx(EWX_REBOOT,NULL);
  return ;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值