标题: 排查会话、令牌资源泄漏
创建: 2018-03-22 15:26 更新: 2018-04-11 16:24 链接: https://scz.617.cn/windows/201803221526.txt
Using Debugging Tools to Find Token and Session Leaks - Ryan Ries [2017-04-05] https://blogs.technet.microsoft.com/askds/2017/04/05/using-debugging-tools-to-find-token-and-session-leaks/
应用程序、服务编写不当的话,很容易出现资源泄漏。MS16-111安全补丁使得资源泄 漏的后果更加严重。当某个令牌泄漏时,与之相关的登录会话将永不释放,即使用户 做了logout操作。如果这种情况发生在使用频繁的远程桌面、远程终端上,很容易导 致内存耗尽,最终只能重启OS恢复正常。
Ryan Ries用windbg排查会话、令牌资源泄漏,具体细节直接看原文。
Ryan Ries用DumpConfigurator配置Crash Dump,如果熟悉这些,可以不用它。
Ryan Ries的原文演示了微软自己的MEX插件的使用,推荐学习。
单就"排查会话、令牌资源泄漏"而言,不需要关心:
nt!SeTokenLeakTracking nt!SepLogonSessions nt!_SEP_LOGON_SESSION_REFERENCES nt!_SID_AND_ATTRIBUTES !kdexts.logonsession !exts.sid !exts.token
本文将其工程实践部分介绍一下。
0)
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel] "SeTokenLeakDiag"=dword:00000001
这是一个自MS16-111开始才存在的注册表设置。
将SeTokenLeakDiag设为1,重启OS使之生效。这步将打开会话、令牌相关的一个调试 开关,使得内核额外记录令牌由谁创建以及创建时的调用栈回溯信息。
1)
qwinsta.exe
用qwinsta检查RDS session ID,如果未被复用,意味着有Logon session泄漏。
2)
logonsessions.exe
用Sysinternals的logonsessions获取Logon session与RDS session ID之间的对应关 系。
以下述会话为例:
[x] Logon session 00000000:0000e66a: User name: Window Manager\DWM-1 Auth package: Negotiate Logon type: Interactive Session: 1 Sid: S-1-5-90-0-1 Logon time: 2018-03-22 15:57:59 Logon server: DNS Domain: UPN: 1052: dwm.exe
Session字段即RDS session ID。
更简单的办法是用Process Explorer,右键查看指定进程属性,在Security标签页有 Session、Logon Session这两项,比如服务一般位于"Session 0"。
3)
用Process Explorer搜索":e66a",找出关联的Token,右键属性可以看到Token地址
4)
在kd里执行:
r $t1=
dt nt!_SEP_TOKEN_DIAG_TRACK_ENTRY @$t2 da @$t3 dps @$t4 l 0n30
显示与指定Token相关的进程名和调用栈回溯,主要是后者,因为前者已经确定。
Sysinternals的handle.exe、Process Explorer搜索Token时有局限,但在标题所言 上下文内,这种局限性基本不影响什么。Ryan Ries在评论区里留了一句话:
I will leave it as an exercise for the reader as to why the two methods produce different sets of output.
这个问题,献给那些永远充满着好奇心的人们。