Access Token访问令牌的操作

access token 访问令牌的概念

Windows操作系统安全性的一个概念。一个访问令牌包含了此登陆会话的安全信息。当用
  Access Token访问令牌的操作_第1张图片

用户权利指派

户登陆时,系统创建一个访问令牌 然后以该用户身份运行的的所以进程都拥有该令牌的一个拷贝。该令牌唯一表示该用户、用户的组和用户的特权。系统使用令牌控制用户可以访问哪些安全对象,并控制用户执行相关系统操作的能力。有两种令牌:主令牌和模拟的令牌。主令牌是与进程相关的;模拟的令牌是与模拟令牌的线程相关的。  进程拥有某种令牌就表示它拥有某种特权。什么是特权呢?特权是指用户进程进行各种系统操作的权利。如:关机,加载设备驱动程序,改变系统时间也是一种特权。可以对用户或用户所在的组授予特权。见图。

WinNT定义的特权

在WinNT.h头文件中定义了这些特权的名称:  #define SE_CREATE_TOKEN_NAME TEXT("SeCreateTokenPrivilege")  #define SE_ASSIGNPRIMARYTOKEN_NAME TEXT("SeAssignPrimaryTokenPrivilege")  #define SE_LOCK_MEMORY_NAME TEXT("SeLockMemoryPrivilege")  #define SE_INCREASE_QUOTA_NAME TEXT("SeIncreaseQuotaPrivilege")  #define SE_UNSOLICITED_INPUT_NAME TEXT("SeUnsolicitedInputPrivilege")  #define SE_MACHINE_ACCOUNT_NAME TEXT("SeMachineAccountPrivilege")  #define SE_TCB_NAME TEXT("SeTcbPrivilege")  #define SE_SECURITY_NAME TEXT("SeSecurityPrivilege")  #define SE_TAKE_OWNERSHIP_NAME TEXT("SeTakeOwnershipPrivilege")  #define SE_LOAD_DRIVER_NAME TEXT("SeLoadDriverPrivilege")  #define SE_SYSTEM_PROFILE_NAME TEXT("SeSystemProfilePrivilege")  #define SE_SYSTEMTIME_NAME TEXT("SeSystemtimePrivilege")  #define SE_PROF_SINGLE_PROCESS_NAME TEXT("SeProfileSingleProcessPrivilege")  #define SE_INC_BASE_PRIORITY_NAME TEXT("SeIncreaseBasePriorityPrivilege")  #define SE_CREATE_PAGEFILE_NAME TEXT("SeCreatePagefilePrivilege")  #define SE_CREATE_PERMANENT_NAME TEXT("SeCreatePermanentPrivilege")  #define SE_BACKUP_NAME TEXT("SeBackupPrivilege")  #define SE_RESTORE_NAME TEXT("SeRestorePrivilege")  #define SE_SHUTDOWN_NAME TEXT("SeShutdownPrivilege")  #define SE_DEBUG_NAME TEXT("SeDebugPrivilege")  #define SE_AUDIT_NAME TEXT("SeAuditPrivilege")  #define SE_SYSTEM_ENVIRONMENT_NAME TEXT("SeSystemEnvironmentPrivilege")  #define SE_CHANGE_NOTIFY_NAME TEXT("SeChangeNotifyPrivilege")  #define SE_REMOTE_SHUTDOWN_NAME TEXT("SeRemoteShutdownPrivilege")  #define SE_UNDOCK_NAME TEXT("SeUndockPrivilege")  #define SE_SYNC_AGENT_NAME TEXT("SeSyncAgentPrivilege")  #define SE_ENABLE_DELEGATION_NAME TEXT("SeEnableDelegationPrivilege")  #define SE_MANAGE_VOLUME_NAME TEXT("SeManageVolumePrivilege")  #define SE_IMPERSONATE_NAME TEXT("SeImpersonatePrivilege")  #define SE_CREATE_GLOBAL_NAME TEXT("SeCreateGlobalPrivilege")  #define SE_TRUSTED_CREDMAN_ACCESS_NAME TEXT("SeTrustedCredManAccessPrivilege")  #define SE_RELABEL_NAME TEXT("SeRelabelPrivilege")  #define SE_INC_WORKING_SET_NAME TEXT("SeIncreaseWorkingSetPrivilege")  #define SE_TIME_ZONE_NAME TEXT("SeTimeZonePrivilege")  #define SE_CREATE_SYMBOLIC_LINK_NAME TEXT("SeCreateSymbolicLinkPrivilege")

如何取得一个进程的访问令牌 通过API函数OpenProcessToken 取得进程令牌。其定义如下:  BOOL WINAPI  OpenProcessToken(  __in HANDLE  ProcessHandle, //进程句柄。通过GetCurrentProcess函数取得当前进程句柄  __in DWORD  DesiredAccess, //要对令牌进行何种操作。如TOKEN_ADJUST_PRIVILEGES用于调整权限  __out PHANDLE  TokenHandle //进程令牌句柄  );  如下代码取得进程的令牌,并告诉系统我们想调整令牌的权限  HANDLE hToken;  if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES,  &hToken)) {  ......  }

对令牌可以进行的操作

Value Meaning
TOKEN_ADJUST_DEFAULT 改变令牌所有者、主组或访问控制列表DACL
TOKEN_ADJUST_GROUPS 改变令牌的组属性
TOKEN_ADJUST_PRIVILEGES enable or disable 令牌的特权
TOKEN_ADJUST_SESSIONID 调整令牌的Session ID。进程需要 SE_TCB_NAME 特权.
TOKEN_ASSIGN_PRIMARY 为进程分配主令牌。需要 SE_ASSIGNPRIMARYTOKEN_NAME 特权
TOKEN_DUPLICATE 复制令牌
TOKEN_EXECUTE 合并 STANDARD_RIGHTS_EXECUTE 和 TOKEN_IMPERSONATE.
TOKEN_IMPERSONATE 附加一个模拟令牌到进程
TOKEN_QUERY 查询令牌
TOKEN_QUERY_SOURCE 查询令牌源
TOKEN_READ 合并 STANDARD_RIGHTS_READ 和TOKEN_QUERY.
TOKEN_WRITE 合并 STANDARD_RIGHTS_WRITE, TOKEN_ADJUST_PRIVILEGES, TOKEN_ADJUST_GROUPS, 和 TOKEN_ADJUST_DEFAULT.
TOKEN_ALL_ACCESS 合并所以可能的操作

与访问令牌关联的特权 TOKEN_PRIVILEGES令牌特权结构体,该结构体定义了访问令牌所拥有的一系列特权。其原型定义如下:  typedef struct  _TOKEN_PRIVILEGES {  DWORD  PrivilegeCount; //特权数量(数组的长度)  LUID_AND_ATTRIBUTES  Privileges[ANYSIZE_ARRAY]; //特权数组  }  TOKEN_PRIVILEGES, * PTOKEN_PRIVILEGES;  其中,Privileges数组类型为  LUID_AND_ATTRIBUTES结构体,其原型定义如下:  typedef struct _LUID_AND_ATTRIBUTES {  LUID Luid; //局部唯一标识符,代表某种特权的Value  DWORD Attributes; //Luid的属性,代表特权的属性(Enabled or Disabled)  }  LUID_AND_ATTRIBUTES, * PLUID_AND_ATTRIBUTES;  其特权属性Attributes可以是如下常量:  
含义
SE_PRIVILEGE_ENABLED 使特权有效
SE_PRIVILEGE_ENABLED_BY_DEFAULT 使特权默认有效
SE_PRIVILEGE_REMOVED 移除该特权
SE_PRIVILEGE_USED_FOR_ACCESS 取得对象或服务的访问权

如何调整访问令牌的特权

取得特权的LUID值

首先通过LookupPrivilegeValue函数取得某种特权的LUID,通过特权的名称查找特权的LUID。  BOOL WINAPI  LookupPrivilegeValue(  __in_opt LPCTSTR lpSystemName, //特权所在的系统名称,NULL表示本地系统  __in LPCTSTR lpName, //特权名称,在WInNT.h 中定义的特权名称  __out PLUID lpLuid //取得的特权的LUID  );  如下代码取得SE_DEBUG_NAME特权的LUID,并将特权属性设为SE_PRIVILEGE_ENABLED  TOKEN_PRIVILEGES tp;  tp.PrivilegeCount = 1;  LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);  tp.Privileges[0].Attributes =SE_PRIVILEGE_ENABLED;

调整令牌特权

AdjustTokenPrivileges函数可以调整令牌的特权。函数定义如下:  BOOL WINAPI AdjustTokenPrivileges(  __in HANDLE TokenHandle, //令牌句柄  __in BOOL DisableAllPrivileges, //是否禁用所有特权,如为TRUE,则忽略NewState参数  __in_opt PTOKEN_PRIVILEGES NewState,//调整为NewState结构定义的特权  __in DWORD BufferLength, // PreviousState 参数的字节大小  __out_opt PTOKEN_PRIVILEGES PreviousState, 可选,调整之前的TOKEN_PRIVILEGES结构体指针  __out_opt PDWORD ReturnLength //可选,返回的结构体的长度  );  //调用  AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);

你可能感兴趣的:(C#)