美图欣赏 | 设为首页 | 加入收藏 | 网站地图

当前位置:新锦江平台:www.xjj7.com-电脑中国 > 系统 > winXP >

Windows下如何创建低权限进程

2017-10-11 11:30|来源:未知 |作者:dnzg |点击:

   1.  前言

在使用 Sysinternals 出品的 Process Explorer 过程中,对 “Run as Limited User” 功能的实现方式颇感兴趣,一番搜寻之下发现Mark大神在《Running as Limited User – the Easy Way》中对该功能的实现做了相关的阐述:

use the CreateRestrictedToken API to create a security context, called a token, that’s a stripped-down version of its own, removing administrative privileges and group membership. After generating a token that looks like one that Windows assigns to standard users Process Explorer calls CreateProcessAsUser to launch the target process with the new token.

使用 CreateRestrictedToken API来创建安全上下文,降低令牌(Token)的管理员权限和组成员资格,使其创建的令牌看起来像Windows赋予普通用户时一样,然后使用此令牌作为传入参数调用CreateProcessAsUser来创建新的子进程。

Process Explorer queries the privileges assigned to the Users group and strips out all other privileges, including powerful ones like SeDebugPrivilege, SeLoadDriverPrivilege and SeRestorePrivilege.

查询赋予用户组的特权并从当前进程权限中剔除这些权限比如SeDebugPrivilege、SeLoadDriverPrivilege和SeRestorePrivilege。

 

刚好最近有个项目需要实现降低进程权限的功能,在一翻折腾下就将其实现了,下面将谈谈实现的历程,如果纰漏之处,不吝指出。

   2.  知识背书

在列出代码前需要了解一下一些实现原理,下面是一些相关的知识点,如果无耐心往下看,可以直接点击这里跳到代码实现处。

 

安全对象

有资格拥有安全描述符的对象如文件、管道、进程、进程间同步对象等。所有已命名的Windows对象都是安全的,那些未被命名的对象比如线程或进程对象也可以拥有安全描述符。

对于大多数的安全对象,当创建该对象时可以指定它的安全描述符。当一个安全对象被创建时,系统会对其赋予一个安全描述符,安全描述符包含由其创建者指定的安全信息,或者缺省的安全信息(如果没有特意进行指定的话)。

  • ž   应用程序可以使特定的函数对已有的对象进行操作以来获取和设置安全信息。
  • ž   每种类型的安全对象定义了它自身的访问权限和自身映射的通用访问权限。

更详细内容见:https://msdn.microsoft.com/en-us/library/windows/desktop/aa379557(v=vs.85).aspx

 

安全描述符(security descriptor)

包含用于保护安全对象的安全信息。

安全描述符描述 对象的所有者(SIDs) 和 以下的访问控制列表:

  • 自由访问控制列表(DACL):指明特定用户或组对该对象的访问是允许或拒绝;
  • 安全访问控制列表(SACL):控制系统审计如何访问对象。

 

安全标识(Security Identifiers)

一定长度用来表示托管的唯一值。

安全标识主要运用于如下几个方面:

  • 在安全描述符中定义对象的所有者和基本组;
  • 在访问控制项中定义托管的权限是允许、拒绝或是审计;
  • 在访问令牌中定义用户和用户所在的组。

 

访问令牌

包含登录用户的信息。用来描述一个进程或线程的安全上下文的对象,令牌的信息包含关联到进程或线程的账号的标识和特权。

当一个用户登录时,系统对用户的账号和密码进行认证,如果登录成功,系统则创建一个访问令牌,每个进程运行时都有一个访问令牌代表当前的用户,访问令牌中的安全描述符指明当前用户所属的账号和所属的组账号,令牌也包含一系列由用户或用户所在组进行维护的权限,在一个进程试图进行访问安全对象或执行系统管理员任务过程中需要权限时,系统通过这个令牌来确认关联的用户。

 

访问控制列表及其访问控制项

自由访问控制列表(DACL)包含若干个访问控制项(ACEs)。

约定的执行规则如下:

  • ž   如果对象没有自由访问控制列表(DACL),则任何用户对其均有完全的访问权限;
  • ž   如果对象拥有DACL,那么系统仅允许那些在访问控制项(ACE)显式指明的访问权限;
  • ž   如果在访问控制列表(DACL)中不存在访问控制项(ACE),那么系统不允许任何用户对其进行访问;
  • ž   如果访问控制列表中的访问控制项对准许访问的用户或组数目有限,那么系统会隐式拒绝那些不在访问控制项中的其他托管的访问

需要注意的是访问控制项的排序很重要。因为系统按照队列的方式读取访问控制项,直到访问被拒绝或允许。用户的访问拒绝ACE必须放在访问允许ACE的前头,否则当系统读到对组的访问允许ACE时,它会给当前限制的用户赋予访问的权限。系统在检测到请求访问被允许或拒绝后就不再往下检查。

你可以通过标识允许访问的ACE来控制对对象的访问,你无需显式地拒绝一个对象的访问。

 

线程和安全对象间的交互

当一个线程想要使用一个安全对象时,系统在线程执行前会进行访问审核,在访问审核中,系统将线程访问令牌中的安全信息与对象安全描述符中的安全信息进行比对。

访问令牌中包含的安全标识(SIDs)可以指明与线程关联的用户,系统查看线程访问令牌中用户或组的SID,同时检查对象的自由访问控制列表(DACL),自由访问控制列表(DACL)中包含存储有指明对指定的用户或组的访问权限是允许或拒绝信息的访问控制项(ACE),系统检查每个访问控制项(ACE)直至出现指明针对此线程(的用户或组的SID)的访问权限是允许还是拒绝的ACE,或者到最终都没有对应的ACEs可以检查。

 

(图片出处:https://msdn.microsoft.com/en-us/library/windows/desktop/aa378890(v=vs.85).aspx)

 

系统按照序列检查每个ACE,查询ACE中的托管与定义在线程中的托管(根据托管的SID)一致的ACE,直到如下的情况出现:

  • ž   表明访问拒绝的ACE显式拒绝在线程的访问令牌中的一个托管的任何访问权限;
  • ž   一个或多个表明访问允许的ACEs显式地为线程访问令牌中的托管提供所有访问权限;
  • ž   所有ACEs已经比对审核完但至少有一个请求访问权限没有显式允许,这种情况下该访问权限则被隐式拒绝。

一个访问控制列表(ACL)可以有多个的访问控制项(ACE)针对令牌的(同一个)SIDs,这种情况下每个ACE授予的访问权限是可以进行累积叠加,比如,如果一个ACE对一个组允许读的访问权限,而另一个ACE对该组内的一个用户允许写的访问权限,那么该用户对于当前对象就拥有了读和写的访问权限。

(责任编辑:dnzg)