引子
首先我得承认用这个Title确实有点哗众取宠,不过这也是Blog的魅力所在,在ITECN上我们可以任意发表自己对微软技术的心得体会,甚至可以发某些悬而未决、半成品的东西,只要是值得和大家分享的,都可以放上来~~扯远了,打住~~
为何取名“鉴证实录”?其实该系列的文章都取材于微软中文新闻组(所遴选的帖子大多有笔者的参与)。“鉴证实录”系列文章,将尽可能忠实地记载帖子的原文(当然会根据实际情况,加以适当的调整),同时笔者将会对其中的每个问题,尽可能地提供背景知识的解析,同时尽可能加以相应的实验论证,既保证“原汁原味”,又确保“营养丰富”……
微软中文新闻组的web地址如下,大家有任何有关微软产品的相关问题,都可以到那里交流::
http://www.microsoft.com/China/community/dgbrowser/zh-cn/default.mspx
领衔主演
参与这次问答的一共有三位朋友,都是领衔主演,呵呵。其中一名是提问的网友,他提出一个非常棒的技术问题;其他两位是回答者,其中一位是网友Youyang,另一位就是笔者(盆盆)。在这里,非常感谢提问网友和Youyang对笔者的启发。
鉴证实录
网友:在Windows XP中启动“系统信息”程序窗口,在左侧控制台树中展开软件环境→正在运行任务,无意中发现有9个任务的路径、最小(最大)工作设置、版本、大小、开始时间、文件日期等项均显示为不可用,如图1所示。这些进程包括:alg.exe、csrss.exe、wdfmgr.exe、wmiprvse.exe、system、system idle process、svchost.exe(共有5个同名进程,其中有3个进程显示“不可用”)。因不清楚是究竟是怎么回事,特此请教大家,希望能够详细说明原因,谢谢!
Youyang:正常的,我们的系统也是相同现象,关于Svchost.exe进程,你可以看看这里:
http://support.microsoft.com/default.aspx?scid=kb;zh-cn;314056
网友:感谢Youyang的回复,我亦感觉应该没有什么问题,并且排除了系统及病毒等方面的可能因素。不过,还想请教一下为何会这样,某些进程显示为不可用?谢谢!
盆盆:system和system idle process并没有真正的进程映象,所以找不到是正常的。至于其他五个进程信息为什么找不到,可能涉及到“系统信息”这个组件的工作机理,推荐你到开发新闻组去提问,以了解更详细的信息。
我目前仅发现,除了system和system idle process和csrss.exe之外,其他几个进程都有以下的共性:
(1)都是服务的宿主进程
(2)进程的启动帐户是network service或者local service(笔者注:这些进程将会处于各自不同的Logon Session,从而具有不同的Logon SID)
Youyang:呵呵,我也准备找问题的答案。我现在脑子里面的一个想法就是,Msinfo32的所使用的线程的访问令牌没有访问某些Svchost.exe背后进程信息的权限,因此会显示出来无信息。不知道大家理解没,就像注册表中的SAM数据库,我们使用的帐户如果没有对他的Read权限的时候,是看不到内容的。
笔者注释
System和System Idle Process,都不是真正意义上的用户模式进程,它们并没有对应的映象文件,例如System进程并不存在一个对应的system.exe进程映象文件。所以“系统信息”程序无法找到它们的进程信息,这是正常的。
System进程实际上是代表内核模式线程的总和,而System Idle Process只是用来统计空闲的CPU时间。
csrss.exe进程是Windows子系统的用户模式部分,它工作在LocalSystem帐户下。
三个“不可用”的svchost进程工作在network service或者local service帐户下,Youyang网友在前面提到,可以参考知识库文章KB31456了解svchost进程的详细信息。
network service和local service帐户,是Windows XP(Windows Server 2003)新引入的帐户,和LocalSystem帐户一样,它们都不是Interactive组的成员,也就是说,不能在用户登录界面使用这些帐户进行“交互”登录。由Windows自动为这些帐户分配和管理密码,有关这些帐户的详细信息,可以参考以下微软官方网页:
http://www.microsoft.com/technet/security/topics/serversecurity/serviceaccount/sspgch02.mspx
实验论证
本文认为,Youyang朋友在最后所提到的解释应该就是问题的真正原因。接下来笔者将用实验进行论证和扩展。为了方便讲述,这里假设测试计算机上的管理员帐户为Admin,同时假设Windows XP安装在C盘。
1.准备知识
首先需要理解,进程是一个很奇妙的东东,它既可以像文件夹和打印机那样,可以对进程指定访问权限(例如谁可以query进程的信息、谁可以Terminate这个进程等等),也就是说每一个进程都可以关联一个ACL(访问控制列表)。
然而和文件夹和打印机不一样的是,进程不但可以有ACL,同时还具有一个访问令牌(Access Token),访问令牌里定义一个帐户SID的列表和该进程所具有的一组特权(Priviledge)。
可以把进程想像成具有“双重性格”,或者高中物理所学的“光的波粒二相性”,这样就不会忘记进程的这种双重特性。
当进程(或者线程)需要访问某个共享资源(包括其他进程)时,就需要出示它访问令牌。然后安全子系统就会根据共享资源的ACL中的帐户和组,来逐个比对进程访问令牌中的帐户和组,以确认是否允许进程访问该共享资源。
要了解关于访问令牌的详细信息,请参考以下微软官方网页:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/secauthz/security/access_tokens.asp
2.实验工具
(1)Process Explorer:可以利用该工具来查看进程的ACL和访问令牌,可以到以下站点下载该工具:
http://www.sysinternals.com/Utilities/ProcessExplorer.html
(2)PsExec:可以利用该工具来以其他帐户身份启动某个进程,可以到以下站点下载该工具:
http://www.sysinternals.com/Utilities/PsExec.html
3.实验步骤
由于没有官方的内部文档,我们无法知道“系统信息”进程中的“正在运行任务”这个线程,到底获得什么访问令牌。所以这里我们只能假设“正在运行任务”这个线程,继承“系统信息”进程的访问令牌。
首先我们可以查看“系统信息”进程的访问令牌:
(1)以Admin帐户登录系统,启动“系统信息”程序窗口,然后打开Process Explorer,双击“系统信息”的对应进程HelpCtr.exe,切换到“Security”标签页,这就是“系统信息”进程所获得的访问令牌,如图2所示。我们可以假设“正在运行任务”这个线程,自动继承“系统信息”进程的访问令牌。
提示 尽管“系统信息”程序的对应Image文件应该是msinfo32.exe,但是通过Process Explorer监控发现,其对应的进程应该是HelpCtr.exe。
(2)接下来可以查看这些“不可用”进程的访问控制列表,首先查看一下csrss.exe进程。在Process Explorer中双击该csrss.exe进程,切换到“Security”标签页,然后单击其右下角的“Permission”按钮,即可查看csrss进程的访问权限设置。可以看到该进程只允许LocalSystem帐户访问,单击打开对话框上的“高级”按钮,还可以查看LocalSystem帐户的详细权限分配,如图3所示。
这样就可以解释为什么无法查看csrss进程信息,原来只有LocalSystem帐户才可以有权限访问csrss进程,而“系统信息”进程的访问令牌里并不包含LocalSystem帐户!
(3)接下来查看“不可用”的svchost进程的访问控制列表,在“系统信息”窗口里记下“不可用”svchost进程的PID,然后在Process Explorer窗口里打开该进程的权限查看窗口,如图4所示。
和csrss进程相比,除了LocalSystem帐户外,svchost进程的访问控制列表中还包含了一个未知帐户SID(本例是S-1-5-5-0-35860)。实际上这是该svchost进程的Logon SID,也就是该svchost进程所在登录会话的SID。也就是说,只要是在同一个登录会话里运行的进程,都能访问该svchost进程的信息。
对比一下图2,发现“系统信息”进程的访问令牌中的Logon SID是S-1-5-5-0-40881,和svchost进程ACL中的Logon SID不同,这就是为什么该svchost进程的信息不可用的原因!
用同样的方法,可以找到alg和wdfmgr.exe的进程信息不可用的原因。
提示 关于Logon SID和其他内置SID的详细信息,可以参考以下的微软官方网页:
http://www.microsoft.com/resources/documentation/Windows/XP/all/reskit/en-us/Default.asp?url=/resources/documentation/Windows/XP/all/reskit/en-us/prnc_sid_cids.asp
4.提升系统信息的启动身份
为了证明以上的结论,还需要进行逆向验证。
由于以上“不可用”进程,都允许LocalSystem帐户访问其进程信息,所以这里我们尝试用LocalSystem帐户的身份启动“系统信息”进程,然后查看是否可以正常显示进程的信息。
(1)要以LocalSystem帐户身份启动进程,可以借助PsExec,可以在CMD窗口运行以下命令,以LocalSystem帐户的身份启动“系统信息”进程:
PsExec -d -i -s "C:/Program Files/Common Files/Microsoft Shared/MSInfo/msinfo32.exe"
(2)现在可以看到,能够访问几乎所有进程的信息(除system和system idle process之外),如图5所示。
而如果以普通用户的身份启动“系统信息”程序(可以借助runas或者PsExec命令),则可以发现有更多进程的信息现在都变成“不可用”,如下图所示。您能说出问题的原因吗?
5.如何设置进程的权限
我知道不少朋友已经跃跃欲试,想通过Process Explorer来修改进程的权限。但是让人沮丧的是,结果会是“拒绝访问”。不过不要紧,我们可以借助Windows Server Resource Kit Tools工具包中的SubInAcl来设置进程的访问权限。这里以alg.exe为例:
(1)打开命令提示符窗口,运行以下命令:
SubInAcl /process alg.exe /grant=Admin=F
(2)运行以下命令,查看alg.exe进程现在的权限设置,命令结果如下:
C:/>SubInAcl /process alg.exe /display
========================
+Process alg.exe - 1840
========================
/control=0x0
/owner =local service
/primary group =local service
/audit ace count =0
/perm. ace count =3
/pace =S-1-5-5-0-55078 ACCESS_ALLOWED_ACE_TYPE-0x0 AccessMask=0x1f0fff
/pace =system ACCESS_ALLOWED_ACE_TYPE-0x0 AccessMask=0x100201
/pace =testxp/admin ACCESS_ALLOWED_ACE_TYPE-0x0 AccessMask=0x1f0fff
Elapsed Time: 00 00:00:00
Done: 1, Modified 0, Failed 0, Syntax errors 0
Last Done : alg.exe - 1840
可以看到,现在Admin帐户对alg.exe进程具有完全控制权限。
(3)打开“系统信息”窗口,应该可以看到alg进程的详细信息了!
6. Process ACL Internals
阅读了《Windows Internals》和以下MSDN文章,可以了解到Windows进程是调用CreateProcess函数创建的,其中的lpProcessAttributes参数“貌似”可以自定义进程的访问权限,这大概可以解释为什么csrss和winlogon进程都是smss进程的子进程,却会有不同访问权限(winlogon进程直接继承父进程的ACL,而csrss进程则有不同的ACL)。然而笔者本人对开发方面的内容不了解,还望诸兄多多加以指正,非常感谢!
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/createprocess.asp
悬而未决
到这里为止,已经可以解释为什么“系统信息”窗口无法列出某些进程的信息。
但是以下的两个问题,还是让笔者觉得疑惑不解:
(1)Process Explorer获得的是和“系统信息”进程一样的访问令牌,为什么它可以查看所有进程的详细信息?是不是其线程可以模拟(Impersonate)相关进程的访问令牌?
另注 MVP Smallfrogs的提示是:Process Explorer可能使用AdjustTokenPrivileges这个API函数,在自己进程的访问令牌里激活了SeDebugPrivilege特权,如下图所示。由于这个令牌的存在,使得Process Explorer能够绕过进程的ACL,对进程进行枚举。
(2)在即将粉墨登场的Windows Vista上,如果以提升特权运行“系统信息”窗口,这个“Bug”似乎消失了,这又是为什么?微软似乎不应该去逐个调整这些进程的ACL,因为这样既吃力不讨好、又不利于安全。