锐英源软件
第一信赖

精通

英语

开源

擅长

开发

培训

胸怀四海 

第一信赖

当前位置:锐英源 / 开源技术 / C++API和类开源 / Windows访问控制模型的启用令牌权限
服务方向
人工智能数据处理
人工智能培训
kaldi数据准备
小语种语音识别
语音识别标注
语音识别系统
语音识别转文字
kaldi开发技术服务
软件开发
运动控制卡上位机
机械加工软件
软件开发培训
Java 安卓移动开发
VC++
C#软件
汇编和破解
驱动开发
联系方式
固话:0371-63888850
手机:138-0381-0136
Q Q:396806883
微信:ryysoft

Windows访问控制模型的启用令牌权限


12. Enabling Token Privileges启用令牌特权

Q. You need to read and edit the SACL of an object, but you can only read SACLs by having the "Manage auditing and security log" policy enabled. How do you enable this "SeSecurityPrivilege"?问:您需要读取和编辑对象的SACL,但是只能通过启用“管理审核和安全日志”策略来读取SACL。如何启用此“ SeSecurityPrivilege”?

  1. Inside the Platform SDK is a function called SetPrivilege(). This sample code will allow us to enable the "SeSecurityPrivilege" (provided the administrator has allowed us), and therefore read SACLs. This function simplifies the task of enabling the privilege into just one line. Before you copy it though, you'll want to add error handling to the function, and make the function call OpenThreadToken() itself.
  2. Use method 1.
  3. The ATL team found the SetPrivilege() function so useful, they created a method called CAccessToken::EnablePrivilege(), which is just SetPrivilege() ATL style.
  4. Platform SDK内有一个名为SetPrivilege()的函数。此示例代码将使我们能够启用“ SeSecurityPrivilege”(如果管理员允许我们启用),因此可以读取SACL。此功能简化了仅将特权启用到一行的任务。不过,在复制之前,您需要向函数添加错误处理,并使函数OpenThreadToken()本身调用。
  5. 使用方法1。
  6. ATL小组发现该SetPrivilege()功能非常有用,因此他们创建了一个称为CAccessToken::EnablePrivilege()的方法,它只是SetPrivilege()ATL样式。
void SetPrivilege(
     const ATL::CStringT< <TCHAR,
     ATL::StrTraitATL< <TCHAR> > &lpszPrivilege,
     bool bEnablePrivilege)
{
  ATL::CAccessToken ProcToken;
  ProcToken.GetEffectiveToken(TOKEN_QUERY |
    TOKEN_ADJUST_PRIVILEGES);

  if(bEnablePrivilege)
  {
    ProcToken.EnablePrivilege(lpszPrivilege);
  }
  else
  {
    ProcToken.DisablePrivilege(lpszPrivilege);
  }
}

Figure 12: Enabling a group policy privilege.

Group policy privileges are turned off by default, even when enabled in group policy. You have to turn them on by changing your access token. You should be prepared to handle the case when the privilege is disabled in group policy (and you can't turn it on, no matter how hard you try). When you've finished with the privilege, don't forget to turn it back off.即使在组策略中启用了组策略特权,默认情况下也会将其关闭。您必须通过更改访问令牌来打开它们。当组策略中的特权被禁用时,您应该准备好处理这种情况(无论您如何努力,都无法将其打开)。完成特权后,别忘了将其关闭。

Q. Print out the current user, the list of available privileges, the list of restricted SIDs and the list of groups from a token.问:打印当前用户,可用特权列表,受限SID列表和令牌中的组列表。

This is a Whoami clone. To make life easier, we won't decrypt the attributes from a number to text (unlike what Whoami does).

  1. You can get the needed information by calling GetTokenInformation() with the TokenInformation parameter set to TokenGroupsAndPrivileges. Then it is simply a matter of printing out the contents of the returned structure.
  2. See method 1.
  3. To get the groups from the token, call the CAccessToken::GetGroups() method, to return a CSidArray and a CAtlArray of DWORDs (the SIDS_AND_ATTRIBUTES map). This list contains a merged view of mandatory SIDs and restricted SIDs. You can use CAccessToken::GetPrivileges() to get similar results for the privileges.
  4. 这是Whoami克隆。为了使生活更轻松,我们不会解密从数字到文本的属性(与Whoami有所不同)。

    1. 您可以通过GetTokenInformation()将TokenInformation参数设置为来获取所需的信息TokenGroupsAndPrivileges。然后,只需打印出返回结构的内容即可。
    2. 请参阅方法1。
    3. 为了从令牌获得组,调用CAccessToken::GetGroups()方法,返回一个CSidArray和CAtlArray的DWORD(SIDS_AND_ATTRIBUTES图)。此列表包含强制SID和受限SID的合并视图。您可以使用CAccessToken::GetPrivileges()这些获得类似特权的结果。
void DoWhoAmI(void)
{
  size_t i = 0;
  ATL::CAccessToken ProcToken;
  ATL::CSid SidUser;
  ProcToken.GetEffectiveToken(TOKEN_QUERY);

  /* First print off the user. */
  ProcToken.GetUser(&SidUser);
  std::wcout << _T("Owner: ") << 
        SidUser.AccountName() << _T("\r\n");

  /* Now print the groups */
  ATL::CTokenGroups pGroups;
  ProcToken.GetGroups(&pGroups);
  ATL::CSid::CSidArray pSids;
  ATL::CAtlArray pAttributes;
  pGroups.GetSidsAndAttributes(&pSids, &pAttributes);

  /* Iterate both pSids and pAttributes simultaneously */
  std::wcout << _T("\r\nGroups\r\n");
  for(i = 0; i < pGroups.GetCount() ; i++)
    std::wcout << pSids[i].AccountName() << _T(": ") <<
        pAttributes.GetAt(i) << _T("\r\n");

  /* Get the list of Privileges */
  ATL::CTokenPrivileges pPrivileges;
  ProcToken.GetPrivileges(&pPrivileges);
  ATL::CTokenPrivileges::CNames pNames;
  ATL::CTokenPrivileges::CAttributes pGroupAttributes;
  pPrivileges.GetNamesAndAttributes(&pNames, &pGroupAttributes);

  /* Printing Privileges is very similar to */
  std::wcout << _T("\r\nPrivileges\r\n");
  for(i = 0; i < pGroups.GetCount() ; i++)
  std::wcout << static_cast(pNames.GetAt(i))
  << _T(": ") << pGroupAttributes.GetAt(i) << _T("\r\n");

  /** TODO: the DWORDs are printed out as numbers. Convert these
  * DWORDs into text, the same text that whoami displays.
  **/
}

Figure 13: Regenerating the information from Whoami.

Q. How do you run IE with low rights in Windows XP / Server 2003?问:如何在Windows XP / Server 2003中以低权限运行IE?

This technique only applies to just Windows XP and Server 2003. The next version of Windows will change this technique.

  1. An example of using this method is not available. You'd have to resort to method 2 or 3 if you want to implement this.
  2. You can either use the CreateRestrictedToken() function to handle the necessary tasks, or for XP and above, you can utilize the Software Restriction Policies (SAFER for short). The SAFER functions are basically a set of predefined restricted tokens you can use to lower the rights of a process token.
  3. ATL has encapsulated the list of privileges into a CAtlArray, which makes it quite easy to iterate and disable the privileges. It's just as easy to create restricted tokens. However, these tokens can be a little too restrictive (restrictive enough to prevent the application initializing). Therefore, you may want to consider using the Software Restriction Policies as an alternative.
  4. 该技术仅适用于Windows XP和Server2003。Windows的下一版本更改此技术。

    1. 没有使用此方法的示例。如果要实现此方法,则必须求助于方法2或3。
    2. 您可以使用该CreateRestrictedToken()功能来处理必要的任务,或者对于XP及更高版本,可以使用软件限制策略(简称SAFER)。SAFER函数基本上是一组预定义的受限令牌,可用于降低进程令牌的权限。
    3. ATL已将特权列表封装到中CAtlArray,这使得迭代和禁用特权非常容易。创建受限令牌也很容易。但是,这些标记可能过于严格(足以阻止应用程序初始化)。因此,您可能要考虑使用软件限制策略作为替代方法。

For method 2, I wrapped the SAFER routines into a class (to abstract object management from the caller).对于方法2,我将SAFER例程包装到一个类中(以从调用方抽象对象管理)。

class SaferRaiiWrapper {
public:
  /** Error handling has been added in the
  *downloadable version of this class
  **/
  explicit SaferRaiiWrapper(
    const DWORD dwScopeIdIn = SAFER_LEVELID_NORMALUSER,
    const HANDLE hTokenIn = NULL) : hToken(hTokenIn),
    LevelHandle(NULL), dwScopeId(dwScopeIdIn)
  {
    ::SaferCreateLevel(SAFER_SCOPEID_USER, this->dwScopeId,
                       SAFER_LEVEL_OPEN, &LevelHandle, NULL);
    ::SaferComputeTokenFromLevel(this->get_LevelHandle(),
                       NULL, &hToken, NULL, NULL);
  } ;


  virtual PROCESS_INFORMATION CreateProcessAsUser(const
    const std::basic_string &lpCommandLine,
    STARTUPINFO *lpStartupInfoIn = NULL,
    DWORD dwCreationFlags = CREATE_NEW_CONSOLE,
    const std::basic_string &lpApplicationName = _T(""),
    const std::basic_string &lpCurrentDirectory = _T(""),
    LPVOID lpEnvironment = NULL, BOOL bInheritHandles = FALSE,
    SECURITY_ATTRIBUTES *lpProcessAttributes = NULL,
    SECURITY_ATTRIBUTES *lpThreadAttributes = NULL)
  {
    STARTUPINFO StartupInfoAlt = {0};
    LPSTARTUPINFO lpStartupInfoActual = (lpStartupInfoIn != NULL) ?
    lpStartupInfoIn : &StartupInfoAlt;
    PROCESS_INFORMATION Result = {0};

    TCHAR *lpCmdLineWritable = new TCHAR[sCmdLine.capacity() + 1];
    /** The command line needs to be writable.
    * So make a writable copy of our command line.
    **/
    sCmdLine.copy(lpCmdLineWritable, sCmdLine.size());
    lpCmdLineWritable[sCmdLine.size()] = _T('\0');

    lpStartupInfoActual->cb = sizeof(STARTUPINFO);
    lpStartupInfoActual->lpDesktop = NULL;
    ::CreateProcessAsUser(this->hToken,
      (sAppName.empty() ? NULL : sAppName.c_str()),
      lpCmdLineWritable, lpProcessAttributes,
      lpThreadAttributes, bInheritHandles,
      dwCreationFlags, lpEnvironment,
      (sCurDir.empty() ? NULL : sCurDir.c_str()),
      lpStartupInfoActual, &Result);

    delete [] lpCmdLineWritable;

    return Result;
  } ;

  HANDLE get_hToken(void) const
  {
    return hToken;
  } ;

  virtual ~SaferRaiiWrapper()
  {
    ::CloseHandle(this->hToken);
    ::SaferCloseLevel(this->LevelHandle);
  } ;

protected:

  const SAFER_LEVEL_HANDLE &get_LevelHandle(void) const
  {
    return LevelHandle;
  } ;
  void set_LevelHandle(const SAFER_LEVEL_HANDLE &LevelHandleIn)
  {
    this->LevelHandle = LevelHandleIn;
  } ;

  void set_hToken(const HANDLE hToken)
  {
    this->hToken = hToken;
  } ;

private:
  HANDLE hToken;
  SAFER_LEVEL_HANDLE LevelHandle;
  const DWORD dwScopeId;
};

Figure 14: Creating a restricted token using the Software Restriction Policies.

友情链接
版权所有 Copyright(c)2004-2015 锐英源软件

公司注册号:410105000449586 豫ICP备08007559号 最佳分辨率 1024*768

地址:郑州市文化路47号院1号楼4层(47-1楼位于文化路和红专路十字路口东北角,郑州大学工学院招待所南边,工学院科技报告厅西边。)