📄 11.1 使用者环境.htm
字号:
<TD><FONT style="LINE-HEIGHT: 25px"
size=2>权杖的类型可以是主要或者模拟的类型,在本章稍后有更详细的讨论。</FONT></TD></TR>
<TR>
<TD><FONT style="LINE-HEIGHT: 25px" size=2>限制SIDs</FONT></TD>
<TD><FONT style="LINE-HEIGHT: 25px"
size=2>选择信任成员帐户用来为在此权杖下执行的程序代码限制存取。受限的SIDs在本章稍后有详细的讨论。</FONT></TD></TR>
<TR>
<TD><FONT style="LINE-HEIGHT: 25px" size=2>模拟等级</FONT></TD>
<TD><FONT style="LINE-HEIGHT: 25px"
size=2>权杖的模拟等级指出服务器可充当客户端的等级,本章稍后亦有讨论。</FONT></TD></TR>
<TR>
<TD><FONT style="LINE-HEIGHT: 25px" size=2>安全描述项</FONT></TD>
<TD><FONT style="LINE-HEIGHT: 25px"
size=2>权杖是Windows中的安全物件,而且就如同所有的安全物件,它拥有一个安全描述项以控制对物件的存取。</FONT></TD></TR>
<TR>
<TD><FONT style="LINE-HEIGHT: 25px" size=2>凭证资讯</FONT></TD>
<TD><FONT style="LINE-HEIGHT: 25px"
size=2>某些权杖有凭证资讯,这些权杖可以扮演网路和本地端机器上的权杖使用者。凭证资讯在本章各处有详细的讨论。</FONT></TD></TR></TBODY></TABLE></CENTER>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>当您程序中的任何线程执行一个需要了解安全性的系统函数时,系统会检查该程序的权杖资讯。这意味着每次您向系统要求安全物件的handle时(例如登录机码或Mutex(互斥)),系统就会执行存取检查,并查询权杖中必需的资讯。同样地,每次您呼叫例如<FONT
style="LINE-HEIGHT: 25px" face=arial color=#3e80d7 size=2><B
style="LINE-HEIGHT: 25px"> GetUserName </B></FONT>的函数或任何其他必需识别执行程序代码之使用者环境函数时,系统会从权杖中撷取资讯。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>尽管您可以为处理程序撷取权杖物件的handle,但是为处理程序设定权杖是不可行的(实际上,系统有权为程序设定权杖,但是并不让开发人员经由API使用)。所以在处理程序结束之前,它无法摆脱权杖,或身分识别。Windows的情形也是一样,然而它提供一个非常棒的特色可让您改变在其之下的执行程序代码权杖,称为<FONT
style="LINE-HEIGHT: 25px" face=arial color=#3e80d7 size=2><B
style="LINE-HEIGHT: 25px"> 模拟 </B></FONT>。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#3e74d7
size=3><B style="LINE-HEIGHT: 25px">模拟的概述<BR
style="LINE-HEIGHT: 25px"> </B></FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>模拟是联系权杖与处理程序中执行的线程所实作的。当您如此做时,此线程(大部分)会用它的<FONT
style="LINE-HEIGHT: 25px" face=arial color=#3e80d7 size=2><B
style="LINE-HEIGHT: 25px"> 模拟权杖 </B></FONT>来呈现身分识别。这个线程被称为「模拟」一个使用者或一个安全性环境。处理程序中的所有其他线程将会继续执行代表处理程序权杖的程序代码,除非它们也模拟了另一个使用者环境。当线程不再需要被视为另一个使用者而工作时,就可以回复到标准状态,这会导致线程再次变回原样并使用处理程序的权杖。如您所想像,模拟在主从架构环境中是非常方便的,在这个环境中,服务器使用不同的安全性环境执行代表客户端的工作。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>在继续之前,应该先阐明我的主张,即一个线程(大部分)具有与它的模拟权杖相关之身份识别。通常,在您呼叫要求权杖资讯的函数时,系统会检查线程权杖,如果没有找到,系统会预设为处理程序的权杖。由于线程并非天生就拥有权杖,所以处理程序的权杖即是处理程序原始的安全性环境。然而,在某些个案中,系统函数仍旧会使用处理程序的权杖,甚至是在模拟权杖之下执行呼叫线程的情形。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>例如,一个模拟线程呼叫CreateProcess在系统中建立一个新的处理程序,此时新的处理程序会继承与呼叫与处理程序关联的handle,而不是与呼叫线程关联的模拟权杖。此外,任何要求SE_TCB_NAME或SE_
AUDIT_NAME权限的函数(本章稍后至少会讨论一个,即LogonUser)使用程序的权杖而不是检查模拟权杖的线程。本章稍后将会有更多关于模拟的讨论。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>您现在可以了解当您登入时,系统如何为您建立权杖。您知道系统如何在您的权杖(或者安全性环境)之下执行程序代码,也知道线程可以使用模拟暂时地呈现另一个身分识别。然而,截至目前为止,我们只讨论过因使用者帐户登入而建立的权杖,例如「JClark」或是「v-JeffrR」。现在您要开始学习在使用者帐户下执行的程序代码如何取得它的权杖。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#3e72d7
size=4><B style="LINE-HEIGHT: 25px">本机(LocalSystem)帐户<BR
style="LINE-HEIGHT: 25px"> </B></FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>假如您读过第叁章,就应该知道不管使用者是否以互动的方式登入系统皆可以设定让服务执行。您也可以设定让服务像使用者帐户一样地执行,而且要求您输入帐户名称及信任成员帐户的密码。我们可以轻易想像系统秘密地登入这个使用者的情形,以及当执行服务程序代码的程序执行时建立一个权杖来使用。然而,您也可以设定让服务像本机帐户一样的执行,而不需要帐户名称或密码。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>本机帐户是Windows
2000系统上的特殊帐户,它不理会服务及其他程序,而就像「操作系统的一部份」一样地执行。结果,本机帐户中的任何程序皆会被指派给权杖,它确实非常有效。以下是一些本机帐户的特性:</FONT></P><FONT
style="LINE-HEIGHT: 25px" face=arial color=#000000 size=2>
<UL style="LINE-HEIGHT: 25px">
<LI style="LINE-HEIGHT: 25px">本机帐户几乎拥有系统中指派的每个权限。<BR
style="LINE-HEIGHT: 25px">
<LI
style="LINE-HEIGHT: 25px">本机帐户是内建管理者群组的暗示性成员,而且本身拥有管理者的所有存取权。<BR
style="LINE-HEIGHT: 25px">
<LI
style="LINE-HEIGHT: 25px">假如本机帐户没有明确地被授予物件的存取权,则必要时,它可以一直取得物件的拥有权及修改它的DACL。<BR
style="LINE-HEIGHT: 25px">
<LI
style="LINE-HEIGHT: 25px">本机帐户拥有SE_TCB_NAME或者「扮演操作系统一部份」权限,所以它可以登入使用者(以获得权杖),并且任意地执行代表使用者的程序代码。<BR
style="LINE-HEIGHT: 25px">
<LI style="LINE-HEIGHT: 25px">本机帐户拥有本地端机器上每件事的直接或间接存取权。<BR
style="LINE-HEIGHT: 25px"> </LI></UL></FONT>
<HR style="LINE-HEIGHT: 25px">
<P><FONT style="LINE-HEIGHT: 25px" face=Arial color=#3e77d7 size=3
Black><B style="LINE-HEIGHT: 25px">说明</B></FONT> </P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>Microsoft Windows
NT里的本机帐户经历了一个讽刺的生活-它拥有本地端机器的无限制存取权,而且几乎没有存取网路上其他机器的安全物件。原因是某台机器的本机帐户在另一台机器上没有身分识别(同样的方法,某台机器的管理者帐户在另一台机器上没有意义)。所以其他机器上的物件当然会被保护,以预防本机帐户的存取。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>这个限制已经受到注意,然而在网路环境中,网域控制站是使用Active Directory执行Windows
2000的服务器。本机帐户现在于Active
Directory中拥有信任成员帐户的状态,因此可以给予网域中其他机器上安全物件的权利。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>本机帐户现在没有个别机器被用来做它的监狱。这个改变大大地增加了本机帐户的弹性,但是也出现了潜在的安全性风险,必需被严密地管理。</FONT></P>
<HR style="LINE-HEIGHT: 25px">
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>注意一些提供权杖操作的函数和其他使用者环境—相关的活动通常需要只授予本机帐户的权限。这不是个真实的问题,因为您的服务很有可能在本机帐户中执行。然而,当您正在测试程序代码及试验函数时,例如LogonUser及CreateProcessAsUser(两者在本章稍后都有讨论),这种权限需求会是个麻烦。我们将讨论处理权限议题的方法,以及稍后将讨论其他由本机帐户程序代码引起的问题。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#3e72d7
size=4><B style="LINE-HEIGHT: 25px">使用者环境及存取控制<BR
style="LINE-HEIGHT: 25px"> </B></FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>尽管前面的章节专注于研究存取控制的部份,而只花了很少的时间集中在使用者环境的重要性。您的处理程序(或者线程)权杖所代表的安全性环境,对存取控制的函数来说绝对是必要的。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>每次系统执行存取检查时,它会在物件的DACL中查看符合使用者SID以及权杖中的群组SIDs之存取控制项目(ACEs)。假如您没有明确地允许读取或修改物件的安全性,却要求允许这样做时,系统会比较物件拥有者SID与您权杖中的SIDs,并寻找相配的一组。假如有找到,您会被授予存取权,因为您是物件的拥有者。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>如您所见,存取控制完全依赖于权杖。事实上,我们将讨论您如何利用杖严重的影响您的软件及系统中存取控制的方法。愈深入了解这些元件如何一起运作以及在Windows
2000下实作安全性,将会使您确实成为强大的安全性开发人员。</FONT></P><A
style="LINE-HEIGHT: 25px" name=211002>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#3e70d7
size=5><B style="LINE-HEIGHT: 25px">程序设计使用者环境<BR
style="LINE-HEIGHT: 25px"> </B></FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>我们将学习一些强大且有趣的技巧,它可以经由操作Windows
2000的权杖而执行。第一个步骤是取得权杖的handle。让我们经由获得处理程序权杖的handle来开始我们的旅程:</FONT></P>
<DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT
style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">BOOL OpenProcessToken( <BR> HANDLE hProcessHandle, <BR> DWORD dwDesiredAccess, <BR> PHANDLE phTokenHandle);</PRE></FONT></DIV>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>OpenProcessToken函数会撷取处理程序权杖的handle。hProcessHandle参数是我们想要开启权杖的处理程序handle。不幸地,系统并不让您传递NULL值,所以请指出您要求撷取自己的处理程序权杖之handle。迅速的呼叫GetCurrentProcess传回一个可被传递作为hProcessHandle参数的虚拟handle。dwDesiredAccess参数指出如何使用权杖。您应该只要求程序代码需要的权利。表格11-2叙述可用的权杖存取权利。许多表格中列出的函数,将在本章稍后讨论。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>这个变数的位址被您传递作为phTokenHandle,它收到要求的权杖handle。假如OpenProcessToken的传回值是TRUE,则表示此函数执行成功;否则表示失败,这种实例应该呼叫GetLastError以得到更多资讯。</FONT></P></A><A
style="LINE-HEIGHT: 25px" name=591_1></A>
<CENTER style="LINE-HEIGHT: 25px">
<TABLE border=0>
<TBODY style="LINE-HEIGHT: 25px">
<TR>
<TD align=middle><FONT style="LINE-HEIGHT: 25px" face=arial
color=#000000 size=2><FONT style="LINE-HEIGHT: 25px"
face=arial color=#3e80d7 size=2><B
style="LINE-HEIGHT: 25px"> 表格11-2 </B></FONT>权杖存取权利</FONT></TD></TR></TBODY></TABLE></CENTER>
<CENTER style="LINE-HEIGHT: 25px">
<TABLE border=1>
<TBODY style="LINE-HEIGHT: 25px">
<TR>
<TH style="LINE-HEIGHT: 25px"><FONT style="LINE-HEIGHT: 25px"
size=2>值</FONT> </TH>
<TH style="LINE-HEIGHT: 25px"><FONT style="LINE-HEIGHT: 25px"
size=2>叙述</FONT></TH></TR>
<TR>
<TD><FONT style="LINE-HEIGHT: 25px"
size=2>TOKEN_ADJUST_DEFAULT 当呼叫SetTokenInformtion</FONT></TD>
<TD><FONT style="LINE-HEIGHT: 25px"
size=2>(简短地讨论)改变权杖的特色时要求,例如预设的拥有者、主要的群组或是预设的DACL。</FONT></TD></TR>
<TR>
<TD><FONT style="LINE-HEIGHT: 25px"
size=2>TOKEN_ADJUST_GROUPS</FONT></TD>
<TD><FONT style="LINE-HEIGHT: 25px"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -