
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。
3)
用Process Explorer搜索":e66a",找出关联的Token,右键属性可以看到Token地址
4)
在kd里执行:
r $t1=<Token>
r $t2=@@(((nt!_TOKEN*)@$t1)->DiagnosticInfo)
r $t3=@@(((nt!_SEP_TOKEN_DIAG_TRACK_ENTRY*)@$t2)->ImageFileName)
r $t4=@@(((nt!_SEP_TOKEN_DIAG_TRACK_ENTRY*)@$t2)->CreateTrace)
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.
这个问题,献给那些永远充满着好奇心的人们。




