Impacket内网渗透实战:从NTLM/Kerberos协议到横向移动与权限提升

发布时间:2026/7/7 16:49:20
Impacket内网渗透实战:从NTLM/Kerberos协议到横向移动与权限提升 1. 项目概述为什么Impacket是内网渗透的“瑞士军刀”如果你在网络安全特别是内网渗透测试领域摸爬滚打过一段时间那么Impacket这个名字对你来说一定如雷贯耳。它远不止是一个简单的工具集更像是一个由Python编写的、针对Windows网络协议的“活字典”和“万能工具箱”。我第一次接触Impacket是在一次复杂的红队评估中面对一个庞大的企业内网传统的扫描器和漏洞利用框架在复杂的Windows认证和协议交互面前显得力不从心。直到我深入使用了Impacket才真正体会到什么叫“庖丁解牛”——它让你能直接与SMB、LDAP、RPC、Kerberos这些核心协议对话从最底层理解认证流程进而实现从信息收集、凭证窃取到横向移动、权限维持的全链条操作。简单来说Impacket是一套Python类库它实现了大量底层的、专有的网络协议尤其是微软的协议栈。它的核心价值在于它将这些复杂的、通常只有微软官方文档才详细描述的协议如NTLM、Kerberos、MS-RPC、DCE-RPC等封装成了易于调用的Python类和方法。这意味着安全研究员和渗透测试人员可以不再依赖现成的、功能固定的GUI工具而是能够编写脚本灵活地构造、发送、解析这些协议数据包实现高度定制化的攻击、检测或研究任务。从实战角度看Impacket解决了几个关键痛点一是协议交互的透明化让你清楚知道每一次握手、每一次认证背后发生了什么二是攻击的精准化和隐蔽性你可以构造出极其符合特定环境或绕过特定检测的数据包三是工具的扩展性当遇到新型的、非标准的或高度定制化的内网环境时你可以基于Impacket快速开发出针对性的利用工具。无论是经典的Pass-the-Hash哈希传递、Pass-the-Ticket票据传递还是近年来热门的AD CS活动目录证书服务滥用、无约束委派利用其底层实现都离不开对SMB、LDAP、RPC等协议的精准操控而这正是Impacket的用武之地。2. 核心协议解析从NTLM握手到实战利用要玩转Impacket绝不能只停留在调用现成脚本的层面。理解其核心实现的协议尤其是认证协议是进阶的关键。NTLMNT LAN Manager协议是Windows环境中历史最悠久、也最基础的认证协议之一尽管Kerberos已成为域环境默认首选但NTLM在内网、工作组环境以及某些特定服务中依然广泛存在是横向移动的常见突破口。Impacket对NTLM协议的实现堪称教科书级别为我们理解其机制和构造攻击提供了绝佳范本。2.1 NTLM协议的三步握手与Impacket实现NTLM认证是一个典型的挑战-响应Challenge-Response过程包含Type 1协商、Type 2挑战和Type 3认证三种消息。Impacket在impacket/ntlm.py文件中用三个核心的Structure类完美映射了这三种消息的结构。Type 1 (NEGOTIATE): 由客户端发起声明自身支持的能力。在Impacket中NTLMAuthNegotiate类负责构建此消息。其核心是flags字段这是一个32位的位图每一位代表一种能力协商。例如NTLMSSP_NEGOTIATE_UNICODE (0x00000001): 声明使用Unicode编码。NTLMSSP_NEGOTIATE_NTLM (0x00000200): 声明使用NTLM认证。NTLMSSP_REQUEST_TARGET (0x00000004): 要求服务器在Type 2消息中返回目标信息域名或服务器名。NTLMSSP_NEGOTIATE_128 (0x20000000)和NTLMSSP_NEGOTIATE_56 (0x80000000): 协商加密强度。在实战中你可以通过修改flags来模拟不同客户端的行为或者用于探测服务器支持的特性。getNTLMSSPType1()函数是生成Type 1消息的快捷方式它预设了一套常见的flags组合。Type 2 (CHALLENGE): 服务器响应发送一个8字节的随机数Challenge以及一些目标信息Target Info。NTLMAuthChallenge类用于解析此消息。最重要的字段就是challenge8字节随机数和TargetInfoFields。TargetInfoFields是一个AV_PAIRS结构包含了服务器时间、NetBIOS名、DNS名等信息在NTLMv2响应计算中至关重要。Type 3 (AUTHENTICATE): 客户端用密码衍生的密钥对服务器发来的Challenge进行加密运算生成响应Response并连同用户名、域名等信息一并发送给服务器。NTLMAuthChallengeResponse类封装了此消息。其核心字段是ntlmNT响应和lmLM响应以及可选的MIC消息完整性校验码。注意在实际抓包分析时你会经常看到Type 3消息中的lm字段是空的或固定的值如client_challenge 0x00*16这是因为现代系统默认使用NTLMv2或仅使用NTLM响应古老的LM响应由于安全性极弱已被弃用。Impacket在生成响应时会根据协商的flags自动选择正确的算法。2.2 NTLMv1 vs NTLMv2响应计算的本质区别这是理解哈希传递Pass-the-Hash, PTH攻击的基础。两者的根本区别在于响应Response的计算方式这直接影响了攻击的可行性和复杂度。NTLMv1 响应计算: 核心是使用DES算法。用户的密码经过固定算法生成一个16字节的NTLM Hash更准确地说是NT Hash。在认证时将16字节的NTLM Hash拆分成两个7字节的密钥每个字节取前7位共56位符合DES密钥长度。用这两个DES密钥分别对8字节的Server Challenge进行加密得到两个8字节的密文。将这两个8字节密文拼接起来就形成了16字节的NTLMv1响应实际传输为24字节后8字节为保留位通常为0。由于其响应仅依赖于静态的NTLM Hash和一次性的Server Challenge攻击者如果窃取到了NTLM Hash就可以在不知道明文密码的情况下直接计算并发送正确的响应完成认证。这就是经典的PTH攻击。NTLMv2 响应计算: 安全性大幅提升引入了HMAC-MD5和客户端随机数Client Challenge。首先使用用户名、域名和NTLM Hash或明文密码通过更复杂的算法生成一个16字节的ResponseKeyNT。客户端生成一个8字节的随机数ClientChallenge。构造一个NTLMv2_CLIENT_CHALLENGE结构体其中包含时间戳、ClientChallenge和从服务器Type 2消息中获取的TargetInfo等信息。计算NTProofStr HMAC_MD5(ResponseKeyNT, ServerChallenge NTLMv2_CLIENT_CHALLENGE)。这是一个16字节的消息认证码。最终的NTLMv2响应是NTProofStr NTLMv2_CLIENT_CHALLENGE。NTLMv2响应的关键在于它不仅依赖于静态Hash和Server Challenge还加入了时间戳和客户端随机数。这意味着即使攻击者拥有NTLM Hash也无法直接重放一个之前捕获的Type 3消息因为时间戳和ClientChallenge变了。但是NTLMv2仍然无法抵御哈希传递攻击因为攻击者可以在获知Server Challenge后实时地使用窃取的Hash计算出正确的NTProofStr。这就是为什么在Impacket的工具中如psexec.py,wmiexec.py只要提供了NTLM Hash无论是v1还是v2都能成功进行PTH攻击。2.3 Impacket中的关键函数与攻击面理解了数据结构再看Impacket提供的上层函数就豁然开朗了。computeResponseNTLMv1和computeResponseNTLMv2: 这两个函数是攻击引擎的核心。它们根据输入的Hash或密码、Server Challenge、Client Challenge等参数计算出正确的LM/NTLM响应。在PTH攻击中我们就是跳过了密码输入直接调用这些函数用Hash生成响应。getNTLMSSPType3: 这是构造最终攻击载荷的函数。它内部会调用上述的computeResponse函数生成完整的Type 3消息。当你使用-hashes参数运行Impacket脚本时幕后功臣就是它。一个实战中的细微差别在computeResponseNTLMv2函数中Impacket默认会向TargetInfo中添加一个AV_TARGET_NAME字段其值为cifs/ 服务器主机名。这是为了满足某些服务器端启用的“SPN目标名称验证”安全策略。如果你在自定义脚本或研究中发现认证失败可以检查服务器是否要求了特定的SPN并相应调整这个字段。3. 工具链实战从信息收集到权限提升Impacket的强大不仅在于库更在于其提供的一系列开箱即用的脚本。这些脚本覆盖了内网渗透的完整链条。下面我们以一次模拟的渗透测试流程为例串联起几个核心工具。3.1 信息收集与侦察lookupsid.py与samrdump.py假设我们通过某种方式例如利用一个Web漏洞获得了命令执行权限获得了一台内网Windows主机的初始立足点并抓取到了本地管理员的NTLM Hash。现在我们需要探索内网。用户枚举与SID爆破使用lookupsid.py它可以通过MSRPC over SMB协议远程查询目标主机的用户、组信息而不需要高权限凭证只需要一个有效的空会话Null Session或一个低权限账户。# 使用空会话如果目标未禁用枚举用户 python3 lookupsid.py no-pass192.168.1.10 # 使用获得的低权限凭据进行枚举 python3 lookupsid.py domain/user:password192.168.1.10这个工具的原理是尝试遍历一系列相对SID如500是管理员1000是普通用户通过查询响应差异来判断用户/组是否存在。在防守方监控对SAMR接口的大量LookupNames或LookupSids调用是发现此类枚举行为的重要指标。SAM数据库远程访问samrdump.py脚本则更进一步它通过MSRPC的SAMR接口尝试远程读取目标主机的SAM数据库信息包括用户名、RID相对标识符以及用户密码哈希如果权限足够。这通常需要管理员权限。python3 samrdump.py domain/admin_user:password192.168.1.10实操心得在实际环境中samrdump.py的成功率受目标系统版本和配置影响很大。较新版本的Windows默认配置下通过网络远程读取SAM哈希已被严格限制。但它仍然是检查目标安全配置的一个有效方式。如果它能成功说明目标的安全策略存在严重问题。3.2 横向移动哈希传递PTH的多种姿势拿到哈希后横向移动是首要目标。Impacket提供了多种执行PTH的工具对应不同的远程执行协议。1. 经典SMB执行psexec.py这是最广为人知的工具模仿了Sysinternals的PsExec工具。它通过SMB协议上传一个服务二进制文件到目标主机的ADMIN$共享然后通过服务控制管理器SCM远程启动该服务来执行命令。python3 psexec.py domain/admin_user192.168.1.10 -hashes aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0-hashes参数格式为LMHash:NTHash。如果只有NTLM Hash通常情况LMHash部分用aad3b435b51404eeaad3b435b51404ee空LM Hash填充。它会返回一个半交互式的shell。优点是功能强大稳定缺点是动作大上传文件、创建服务容易被AV/EDR检测。2. 基于WMI的执行wmiexec.pyWMIWindows Management Instrumentation是微软提供的系统管理框架。wmiexec.py通过DCOM协议远程调用WMI的Win32_Process类的Create方法来执行命令。python3 wmiexec.py domain/admin_user192.168.1.10 -hashes aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0与psexec相比wmiexec不需要上传文件所有操作在内存中通过WMI类完成因此相对更隐蔽。它返回的是一个全交互式的、功能更完整的shell支持TAB补全、上下键历史等。3. 基于计划任务的执行atexec.py该工具通过SMB或RPC创建远程计划任务来执行命令。python3 atexec.py domain/admin_user192.168.1.10 -hashes aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0 “whoami”它更适合执行单条命令而非获取交互式shell。在某些严格限制WMI或SMB服务执行的环境中计划任务可能是一个备选方案。4. 基于DCOMMMC的执行dcomexec.py利用DCOM协议通过调用MMC20.Application或ShellWindows等COM对象的特定方法来执行命令。这是另一种“无文件”远程执行的方式。python3 dcomexec.py domain/admin_user192.168.1.10 -hashes aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0这种方法非常依赖目标系统上已注册和可远程访问的特定COM组件环境适应性不如WMI和SMB广泛但在绕过某些特定防护规则时可能有效。工具选型建议首选wmiexec.py在大多数现代内网中它兼具了成功率和相对隐蔽性。备选psexec.py如果WMI被禁用或连接不稳定可以尝试此方法但需做好被检测的准备。特殊情况根据目标环境的具体配置如出网协议、防火墙规则、已安装组件灵活选择atexec.py或dcomexec.py。3.3 凭证窃取与中继secretsdump.py与ntlmrelayx.py离线哈希抓取secretsdump.py是内网渗透的“核武器”。它可以通过多种方式注册表、卷影拷贝、DCsync从远程主机或域控制器上提取所有用户的哈希值。# 本地执行需已获得管理员权限的shell python3 secretsdump.py LOCAL -sam sam.save -system system.save -security security.save # 远程通过SMB需管理员凭证 python3 secretsdump.py domain/admin_user:password192.168.1.10 # 黄金票据攻击后使用DCsync从域控拉取所有用户哈希 python3 secretsdump.py domain/域控机器名\$域控IP -k -no-pass-k参数表示使用Kerberos认证这通常在已获得域内某账户的Kerberos票据如黄金票据时使用。secretsdump.py的DCsync功能模拟域控制器之间的复制协议可以直接请求域控制器返回指定用户的密码哈希这是获取域管哈希的最致命手段之一。NTLM中继攻击ntlmrelayx.py是另一把利器。它监听网络流量截获NTLM认证请求并将其“中继”到另一个目标服务。如果中继成功攻击者就能以受害者的身份访问目标服务。# 基础用法中继到SMB并自动在目标上执行命令或转储哈希 python3 ntlmrelayx.py -t smb://192.168.1.20 -c “whoami” -smb2support # 中继到LDAPS并尝试为指定用户添加DCSync权限 python3 ntlmrelayx.py -t ldaps://dc.domain.com --escalate-user vulnerable_userNTLM中继攻击成功的关键在于目标服务必须禁用SMB签名和LDAP签名或SSL通道绑定。在现代Windows Server中域控制器的LDAP/SMB签名默认是开启的但许多第三方应用、打印机、IIS WebDAV等服务可能配置不当。ntlmrelayx.py的强大之处在于它能自动化地在中继成功后执行预定义的操作如执行命令、转储哈希、创建用户、授予权限等。4. 高级利用与Kerberos协议实战当渗透测试进入域环境Kerberos协议就成为无法绕开的主题。Impacket同样提供了对Kerberos协议的完整支持使得针对Kerberos的攻击如黄金票据、白银票据、委派攻击变得可编程化。4.1 Kerberos基础与票据操作Kerberos是一种基于票据Ticket的认证协议比NTLM更安全、更高效。核心票据有两种TGTTicket Granting Ticket由密钥分发中心KDC颁发证明用户身份用于申请访问其他服务的票据。STService Ticket由KDC颁发用于访问特定服务。Impacket的impacket/krb5目录下包含了Kerberos协议的实现。ticketer.py和ticketConverter.py是两个直接操作票据的实用脚本。伪造黄金票据Golden Ticket黄金票据是Kerberos攻击中最危险的手段之一。它需要获取域控制器的krbtgt用户的NTLM Hash。有了这个Hash就可以伪造任意用户的TGT从而访问域内任何服务。# 使用 krbtgt 哈希伪造一个属于域管理员的黄金票据 python3 ticketer.py -nthash b18e4c5a6d7e8f9a0b1c2d3e4f5a6b7c -domain-sid S-1-5-21-123456789-987654321-111111111 -domain domain.com administrator-nthash: 域控krbtgt用户的NTLM Hash通过secretsdump.py获取。-domain-sid: 域的SID可以通过lookupsid.py枚举域用户获取通常第一个就是域SID。命令执行后会生成一个administrator.ccache文件这就是伪造的Kerberos票据。使用票据在Linux上可以通过设置KRB5CCNAME环境变量来使用ccache格式的票据。export KRB5CCNAME/path/to/administrator.ccache python3 psexec.py domain/administratordc.domain.com -k -no-pass-k参数告诉工具使用Kerberos认证-no-pass表示不使用密码。此时工具会使用环境变量中的票据进行认证实现“无密码”的域管理员访问。4.2 委派攻击与getST.pyKerberos委派Delegation允许一个服务代表用户去访问另一个服务。这带来了两种主要的攻击面无约束委派和基于资源的约束委派。无约束委派攻击如果一台服务器被配置了无约束委派那么任何用户向该服务器进行Kerberos认证时其TGT而不仅仅是ST会被缓存在该服务器的内存中。攻击者如果控制了这台服务器就可以提取这些TGT并冒充对应的用户。利用secretsdump.py或其他方式获取配置了无约束委派的服务器权限。使用mimikatz或Rubeus从该服务器的内存中导出缓存的TGT票据。使用Impacket的脚本配合导出的TGT即可冒充受害用户访问其他资源。基于资源的约束委派RBCD攻击这是近年来更热门的攻击手法。它允许服务A被攻击者控制配置自己对自己或对其他服务的委派权限。攻击者需要拥有一个在域内拥有GenericAll、GenericWrite或WriteProperty权限的账户通常通过权限提升获得。使用该账户为被控制的服务账户计算机账户设置msDS-AllowedToActOnBehalfOfOtherIdentity属性指向目标服务例如域控制器。然后攻击者可以代表被控制的服务账户请求一个访问目标服务的ST。由于委派关系是自己设置的KDC会批准这个请求。最后使用这个ST就可以访问目标服务如域控制器的CIFS服务。Impacket的getST.py脚本可以用于执行RBCD攻击的最后一步——请求服务票据。# 假设我们已经控制了服务账户 COMPUTER$并为其配置了到 DC$ 的RBCD # 首先为 COMPUTER$ 账户请求一个访问 DC$ 的ST python3 getST.py domain.com/COMPUTER\$ -spn cifs/dc.domain.com -impersonate administrator -dc-ip 192.168.1.1 # 使用得到的票据访问域控制器 export KRB5CCNAMEadministrator.ccache python3 smbclient.py domain.com/administratordc.domain.com -k -no-pass这个攻击链的关键在于如何为服务账户设置RBCD属性这通常需要借助powermad、powerview或直接使用LDAP修改工具。5. 常见问题排查与防御视角在实际使用Impacket进行测试或研究时你肯定会遇到各种错误。从错误中学习是理解协议和工具的最佳途径。5.1 连接与认证类错误错误信息/现象可能原因排查思路与解决方案Connection refused或Timeout目标端口未开放或网络不通。1. 使用nc -zv target_ip port确认端口可达性。2. 检查防火墙规则主机防火墙、网络防火墙。3. 确认目标服务是否运行如netstat -ano | findstr :445。SMB SessionError: STATUS_ACCESS_DENIED提供的凭据权限不足或哈希不正确。1. 确认用户名、域名、密码/哈希完全正确注意大小写。2. 确认账户对目标资源如ADMIN$共享、WMI命名空间有访问权限。3. 尝试使用其他协议如WMI代替SMB。SMB SessionError: STATUS_LOGON_FAILURE明确的登录失败。密码错误、账户被锁定、或账户在此计算机上无权登录。1. 核对密码。2. 检查账户状态是否被锁定、禁用。3. 检查目标机器的“本地安全策略”-“用户权限分配”-“允许本地登录”等设置。Kerberos SessionError: KDC_ERR_PREAUTH_FAILEDKerberos预认证失败。密码错误或时钟偏差过大。1. 核对密码。2. 同步测试机和域控的时间ntpdate或w32tm。3. 检查是否使用了正确的Salt在AS-REP Roasting攻击中常见。SMB SessionError: STATUS_NOT_SUPPORTED客户端请求的SMB版本或特性服务器不支持。尝试为工具添加-smb2support参数强制使用SMB2/3或降级到SMB1不推荐安全性低。5.2 协议与功能类错误错误信息/现象可能原因排查思路与解决方案psexec.py执行失败提示文件上传或服务创建问题防病毒软件拦截、杀毒软件删除上传的二进制文件、或权限不足。1. 尝试使用wmiexec.py等无文件落地的工具。2. 检查AV日志。3. 使用-codec参数指定不同的编码尝试绕过。4. 手动检查C:\Windows目录下是否生成了临时文件。secretsdump.py远程执行失败目标系统版本过高如Win10 1809 Server 2016默认禁止远程SAM访问。1. 尝试使用-use-vss参数通过卷影拷贝技术读取。2. 如果已获得交互式shell在目标机器上本地运行secretsdump.py。3. 转向DCSync攻击需要域管权限。ntlmrelayx.py监听无流量触发条件未满足或网络不可达。1. 确保监听网卡正确IP/端口无误。2. 使用-debug参数查看详细日志。3. 检查触发方式是等待用户访问攻击者架设的恶意服务还是需要配合Responder等工具进行LLMNR/NBT-NS毒化ntlmrelayx.py中继失败提示签名问题目标服务如域控强制要求SMB/LDAP签名。1. 这是正常的安全配置。中继攻击对强制签名的服务无效。2. 寻找内网中不要求签名的服务作为中继目标如打印机、旧版IIS、某些Web应用。getST.py请求票据失败委派配置不正确、SPN设置错误、或时钟偏差。1. 使用setspn -L检查目标服务的SPN是否正确注册。2. 使用Get-ADComputer或ldapsearch检查计算机账户的msDS-AllowedToActOnBehalfOfOtherIdentity属性是否已正确设置。3. 同步时间。5.3 从防御者视角看Impacket攻击了解攻击手法是为了更好地防御。针对Impacket所利用的攻击面防御者可以采取以下措施强化认证禁用NTLM在域环境中通过组策略逐步禁用NTLMv1并最终禁用NTLM强制使用Kerberos。启用SMB签名对所有服务器尤其是域控制器强制启用SMB签名。这能有效防御SMB中继攻击。启用LDAP签名与通道绑定对域控制器启用LDAP签名和LDAPS通道绑定防御LDAP中继攻击。监控与检测监控异常登录行为关注非工作时间、非常用IP地址、短时间内的大量登录失败/成功事件Windows事件ID 4624, 4625, 4768, 4769。检测PsExec/WMI滥用监控服务创建事件ID 4697、进程创建事件ID 4688特别是来自psexesvc.exe、wmiprvse.exe的异常父进程或命令行参数。检测哈希传递同一用户凭证在短时间内从多个不同IP地址登录多台计算机是典型的PTH特征。监控事件ID 4624对比登录IP和计算机名。检测DCSync攻击监控域控制器上的事件ID 4662目录服务访问关注Replicating Directory Changes All和Replicating Directory Changes In Filtered Set权限的使用情况。权限与配置管理限制本地管理员权限避免域用户同时是多个工作站的本地管理员防止凭据在多个系统间复用。审查委派配置定期审计域内配置了无约束委派和约束委派的账户确保其必要性和安全性。对于服务账户优先使用基于资源的约束委派。保护特权账户对域管理员、企业管理员等特权账户实施严格的保护策略如禁止其登录非域控制器、使用特权访问工作站PAW、启用“受保护用户”组等。Impacket就像一把精密的解剖刀它让你能深入到Windows网络协议的毛细血管中去观察和操作。从最初的协议数据包构造到自动化攻击脚本的编写再到针对新型攻击手法如AD CS攻击的研究Impacket都是不可或缺的基石。我个人的体会是不要满足于运行几个现成的.py脚本。多读它的源码特别是ntlm.py,smb.py,krb5目录下的代码理解每一个Structure类、每一个flags位的含义。当你能够基于Impacket库为了一个特定的、奇怪的内网环境自己写出一小段能完成特定协议交互的脚本时你才真正算得上是掌握了它。这过程中踩过的坑、调通的每一个协议字段都会成为你面对更复杂安全挑战时最坚实的底气。