1. 项目概述一张伪造的“内部通行卡”如何绕过身份核验“域渗透之白银票据利用”——这标题里带括号的写法是安全圈老手才懂的暗号。它不讲大道理不堆概念直指一个具体、危险、且在真实攻防对抗中高频出现的技术动作用一张伪造的、仅限特定服务访问的“白银票据”绕过Kerberos协议中本该最坚固的身份核验环节。关键词里的“域渗透”点明战场“白银票据”就是武器代号。它不是传说而是某次红队演练中我亲眼看着队友在拿到一台普通域用户工作站权限后5分钟内就横向移动到域控服务器管理后台的真实操作。很多人一听到“票据”下意识联想到“黄金票据”——那个能伪造任意用户、长期有效的“万能钥匙”。但白银票据恰恰相反它不碰域控不改数据库不生成长期凭证它只伪造一张“单次有效、限定服务、时效极短”的临时通行证。它的威力在于精准、隐蔽、无痕。你不需要破解域管理员密码不需要接触krbtgt账户哈希甚至不需要域控服务器在线——只要目标服务比如文件共享、远程桌面、SQL Server本身支持Kerberos认证这张票就能让它对你敞开大门。它解决的核心问题是当攻击者已获得某个域用户的凭据密码、NTLM哈希或TGT但该凭据权限不足以直接访问高价值服务时如何绕过权限检查实现“以小博大”的横向移动这个技术最适合三类人参考一是正在备考OSCP或OSEP的渗透测试学习者白银票据是必考项光背命令没用得懂每一步背后的协议逻辑二是企业内部的安全运维人员必须清楚这种攻击在日志里长什么样否则SIEM告警永远是“误报”三是红蓝对抗中的蓝队负责人你的EDR规则如果只盯着“lsass.exe内存dump”那白银票据早就带着数据溜走了。它不依赖漏洞不触发AV扫描纯粹利用Kerberos协议设计中的信任链断点——这正是它至今仍被实战频繁使用的原因。接下来我会像当年导师手把手教我那样把整个过程拆解成可触摸、可验证、可复现的步骤不跳过任何一个看似微小却致命的细节。2. 核心原理与设计思路为什么白银票据能“骗过”服务端2.1 Kerberos认证流程的“信任盲区”要真正理解白银票据必须先看清Kerberos协议的完整链条。它不是单向的“发证-验票”而是一个三方参与的精密协作客户端Client、密钥分发中心KDC即域控、服务端Server。整个流程分三步走AS-REQ/AS-REP获取TGT客户端用自己密码的哈希加密时间戳向KDC请求一张“入场券”TGT。KDC验证通过后返回两样东西一是用客户端密钥加密的会话密钥Session Key二是用KDC自身密钥krbtgt账户的NTLM哈希加密的TGT。这个TGT里封装了客户端身份、有效期、以及最重要的——那个会话密钥的副本。TGS-REQ/TGS-REP获取服务票据客户端想访问某个服务比如\fileserver\share就拿着TGT加上用会话密钥加密的“我要访问谁”的请求发给KDC。KDC用自己的krbtgt密钥解密TGT取出会话密钥再用这个会话密钥解密客户端的请求确认目标服务。然后KDC生成一张新的“服务票据”ST里面包含客户端身份、时间戳、有效期并用目标服务自身的密钥通常是服务账户的NTLM哈希加密。同时KDC还把同一个会话密钥用客户端密钥再加密一遍随ST一起发回。AP-REQ/AP-REP服务端验证客户端把收到的ST连同用会话密钥加密的时间戳Authenticator一起发给目标服务。服务端用自己的密钥比如fileserver$账户的NTLM哈希解密ST得到会话密钥和客户端身份再用这个会话密钥解密Authenticator里的时间戳比对时间是否在允许窗口内通常5分钟。全部通过服务端就认为客户端身份合法允许访问。白银票据的突破口就藏在第三步。服务端在验证ST时只做两件事用自己的密钥解密ST再用解出的会话密钥解密Authenticator。它根本不会、也无法去联系KDC做二次确认它完全信任“这张ST是KDC签发的”这个前提。而白银票据正是利用了这个“单向信任”——我们不伪造TGT那是黄金票据干的事而是直接伪造第三步里服务端要接收的ST。只要我们能搞到目标服务账户的NTLM哈希比如fileserver$就能用它作为密钥自己造一张看起来天衣无缝的ST。服务端照常解密、验证结果自然“一切正常”。提示这里的关键区别在于黄金票据伪造的是KDC签发的TGT需要krbtgt哈希白银票据伪造的是服务端签发的ST只需要目标服务账户的哈希。前者影响全局后者影响局部但后者更难被发现。2.2 白银票据的构造要素四件套缺一不可一张有效的白银票据不是随便拼凑的字符串而是严格遵循Kerberos ASN.1编码规范的数据包。它由四个核心字段构成缺一不可任何一个填错服务端解密就会失败服务主体名称SPN这是票据的“收件人地址”。格式为服务类型/主机名.域名例如cifs/fileserver.domain.local文件共享、http/webapp.domain.localWeb应用、MSSQLSvc/sqlserver.domain.local:1433SQL Server。SPN必须与目标服务实际注册的完全一致大小写敏感域名必须是FQDN全限定域名。我曾因把domain.local写成domain导致票据在服务端解密时报错KRB_AP_ERR_BAD_INTEGRITY折腾了半小时才定位到这个细节。服务账户NTLM哈希这是票据的“签名私钥”。服务端用它来解密票据。获取方式有多种如果是计算机账户如fileserver$其哈希就是该计算机加入域时生成的可通过secretsdump.py从域控的NTDS.dit导出或在已控的域成员机上用mimikatz从lsass中提取如果是自定义的服务账户如svc_sql则需通过其他手段如密码喷洒、钓鱼获取其密码再计算哈希。注意这里必须是NTLM哈希MD4(password)不是NT hashWindows 10默认存储的也不是AES密钥。客户端用户名与域名这是票据的“发件人信息”。它决定了服务端日志里记录的“谁在访问”。可以是任意存在的域用户如user1domain.local甚至是不存在的用户服务端通常不会校验其真实性只认票据内容。但为了降低审计风险建议使用一个低权限、近期有活动的普通用户这样日志看起来更“合理”。时间戳与有效期这是票据的“保质期”。包含开始时间starttime、结束时间endtime和重放窗口renew-till。Kerberos默认允许5分钟的时间偏差clock skew所以starttime通常设为当前时间减5分钟endtime设为当前时间加5小时模拟一个典型会话时长。关键点在于所有时间戳都必须是UTC时间协调世界时不是本地时间这是新手最容易踩的坑。Windows系统日志记录的是本地时间但Kerberos协议强制要求UTC。如果用本地时间生成票据服务端解密时会因时间校验失败而拒绝错误码是KRB_AP_ERR_SKEW。2.3 方案选型为什么选择Impacket而非Mimikatz在实操工具选择上我坚定推荐Python生态的Impacket库ticketer.py脚本而非更广为人知的mimikatz。理由非常实际环境适配性mimikatz是Windows平台原生工具需要在目标Windows机器上执行且极易被现代EDR如CrowdStrike、Microsoft Defender for Endpoint标记为高危行为如sekurlsa::logonpasswords内存读取。而Impacket是纯Python库可以在Linux攻击机Kali上离线生成票据全程不触碰目标系统规避了90%的运行时检测。可控性与透明度ticketer.py的源码完全公开你可以清晰看到它如何构造ASN.1结构、如何调用加密函数、如何填充每个字段。当你遇到KRB_AP_ERR_BAD_INTEGRITY错误时可以逐行调试定位是SPN写错了还是哈希格式不对。而mimikatz是个黑盒报错信息往往模糊如ERROR kuhl_m_kerberos_tgs_1排查成本极高。集成友好性Impacket可以轻松嵌入到你自己的Python自动化脚本中。比如你可以写一个脚本自动从BloodHound图谱中识别出高价值SPN批量生成白银票据再用psexec.py一键执行命令。这种工作流在红队作业中是刚需mimikatz无法提供。当然mimikatz并非一无是处。它在现场提权阶段无可替代——当你已经拿到一个高权限Shell需要快速从lsass中提取服务账户哈希时mimikatz的lsadump::sam或lsadump::secrets命令是最快捷的。但票据生成这个环节Impacket是更安全、更可控、更符合现代攻防节奏的选择。3. 实操过程与核心环节实现从零开始生成并利用白银票据3.1 环境准备与前置条件验证在敲下第一个命令前必须确保所有“弹药”已备齐且环境状态符合预期。这一步省不得否则后面全是无效劳动。第一步确认目标服务支持Kerberos且SPN已注册不是所有服务都默认启用Kerberos。你需要先确认目标主机如fileserver.domain.local的cifs服务SPN是否存在。在域内任意一台机器上用域管理员权限执行setspn -L fileserver$输出中必须包含类似cifs/fileserver.domain.local或cifs/fileserver的条目。如果没有说明该服务未注册SPN白银票据将无法使用。此时需要域管理员手动注册setspn -S cifs/fileserver.domain.local fileserver$。注意setspn命令必须在域内执行且需要足够权限。第二步获取目标服务账户的NTLM哈希这是最关键的“原材料”。假设目标是一台名为fileserver的域成员服务器其计算机账户为fileserver$。获取方式有两种主流路径路径A已控域控如果你已拿下域控最稳妥的方式是从NTDS.dit文件中提取。在Kali上用Impacket的secretsdump.pysecretsdump.py -ntds /path/to/ntds.dit -system /path/to/SYSTEM LOCAL在输出的海量哈希中找到fileserver$这一行其后的32位十六进制字符串就是我们需要的NTLM哈希格式如a1b2c3d4e5f678901234567890abcdef。路径B已控域成员机如果你只控制了一台普通域用户工作站且该工作站与fileserver在同一网段可以尝试用mimikatz从内存中提取。在fileserver上以管理员身份运行mimikatzprivilege::debug sekurlsa::logonpasswords在输出中查找Authentication Id为0:00000000即本地登录会话的条目其NTLM字段即为目标哈希。注意此操作需在目标服务主机上执行有较高风险应作为最后手段。第三步验证网络连通性与时间同步确保你的攻击机Kali与目标服务主机fileserver.domain.local网络可达ping fileserver.domain.local且时间偏差在5分钟内。在Kali上执行# 查看本地时间UTC date -u # 查看目标主机时间UTC nmap -p 123 --script ntp-info fileserver.domain.local如果时间差过大白银票据会因KRB_AP_ERR_SKEW被拒绝。此时需手动校准Kali时间sudo timedatectl set-ntp false sudo date -u -s $(date -u)。3.2 使用Impacket生成白银票据ticketer.py详解现在所有原料齐备进入核心操作。我们以fileserver.domain.local的cifs服务为例生成一张针对用户user1domain.local的白银票据。命令解析务必逐字输入注意空格和引号ticketer.py -nthash a1b2c3d4e5f678901234567890abcdef -domain-sid S-1-5-21-1234567890-1234567890-1234567890 -domain domain.local -spn cifs/fileserver.domain.local user1domain.local参数逐个拆解-nthash紧接你获取到的fileserver$账户的32位NTLM哈希。这是唯一必须准确的参数输错一个字符票据即失效。-domain-sid目标域的SID安全标识符。这不是域控的SID而是整个域的SID。如何获取在域内任意机器上用whoami /user命令输出中SID列的值去掉最后的-500、-501等相对IDRID剩下的就是域SID。例如S-1-5-21-1234567890-1234567890-1234567890-500域SID就是S-1-5-21-1234567890-1234567890-1234567890。漏掉这个参数票据将无法被域内服务正确识别。-domain目标域的FQDN必须与SPN中的域名部分完全一致domain.local不是DOMAIN.LOCAL或domain。-spn服务主体名称必须与setspn -L查到的完全一致包括大小写和FQDN。user1domain.local票据中声明的客户端用户名可以是任意存在的域用户。执行与输出运行命令后ticketer.py会输出类似以下信息[*] Creating ticket for user1domain.local [*] Saving ticket in user1domain.local.ccache它会在当前目录生成一个名为user1domain.local.ccache的文件。这就是你的白银票据文件。注意文件名是user1domain.local.ccache不是user1.ccacheImpacket后续工具会严格按此命名查找票据。实操心得第一次生成时我习惯在命令末尾加-debug参数它会输出详细的ASN.1编码过程方便你确认SPN、时间戳、SID等字段是否按预期填充。一旦确认无误后续可去掉以加快速度。3.3 利用白银票据进行横向移动psexec.py实战票据生成只是第一步真正的价值在于“用”。Impacket提供了多个工具来消费.ccache票据其中psexec.py是最直观、最常用的。第一步设置环境变量让Impacket工具“看见”票据Impacket工具默认从KRB5CCNAME环境变量指定的路径读取票据。在Kali终端中执行export KRB5CCNAME/path/to/user1domain.local.ccache务必使用绝对路径相对路径如./user1domain.local.ccache会导致工具找不到文件。第二步执行远程命令现在你可以像拥有user1的明文密码一样对fileserver.domain.local发起任意操作。最常用的是执行系统命令psexec.py -k -no-pass domain.local/user1fileserver.domain.local-k表示使用Kerberos认证即读取KRB5CCNAME指向的票据。-no-pass表示不提供密码完全依赖票据。domain.local/user1fileserver.domain.local这是Impacket的用户名格式域/用户主机。执行后你会看到一个交互式的C:\命令提示符这表明你已成功以user1身份登录到fileserver的SYSTEM上下文因为psexec默认提升到最高权限。此时你可以执行dir \\fileserver.domain.local\c$验证对C盘共享的访问权限。whoami /all确认当前会话的令牌信息你会看到user1的SID以及SeDebugPrivilege等高权限。reg query HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters读取系统关键配置。第三步静默化利用避免交互式Shell在真实红队中你往往不需要一个交互式Shell而是想静默执行一条命令并获取结果。psexec.py支持-c参数psexec.py -k -no-pass -c hostname ipconfig domain.local/user1fileserver.domain.local这条命令会直接在fileserver上执行hostname和ipconfig并将输出结果实时打印在你的Kali终端上全程无交互痕迹更小。注意psexec.py利用的是Windows的AT服务计划任务它会在目标主机上创建一个临时的计划任务执行完后自动删除。因此在目标主机的事件日志Application日志中你会看到Event ID 4698计划任务创建和Event ID 4699计划任务删除的记录。这是白银票据利用的一个关键日志特征蓝队必须监控。3.4 验证与日志分析如何确认白银票据已生效生成和利用只是技术动作真正的专业体现在“验证”上。你需要从三个层面交叉确认1. 攻击端验证执行psexec.py后如果成功获得C:\提示符或-c命令返回了预期结果这是最直接的证据。在Kali上执行klist命令需安装krb5-user包它会显示当前缓存的票据。你应该能看到一条user1domain.local的票据其Service Principal Name列为cifs/fileserver.domain.local。2. 目标服务端验证Windows事件日志登录到fileserver.domain.local打开“事件查看器” - “Windows日志” - “Security”。筛选Event ID 4624登录成功重点关注Logon Type: 应为3Network网络登录。Account Name: 应为你票据中指定的user1。Workstation Name: 会显示为你的Kali攻击机的主机名如果Kali加入了域或IP地址如果未加入域。Logon Process: 应为Kerberos而非NtLmSsp。Authentication Package: 应为Kerberos。3. 域控端验证KDC日志这是最关键的反向验证。白银票据的精妙之处在于它完全绕过了KDC因此在域控的“Security”日志中你不会看到任何与user1访问fileserver相关的Event ID 4768TGS请求或Event ID 4769TGS发放日志。这是一个强烈的异常信号服务端记录了成功的Kerberos登录但KDC日志里却没有任何对应的票据发放记录。蓝队SIEM规则如果能关联这两个日志源就能高置信度地告警白银票据攻击。4. 常见问题与排查技巧实录那些年踩过的坑4.1 典型错误代码与速查表白银票据利用过程中报错信息往往晦涩难懂。根据我数十次实操经验整理出最常遇到的5个错误及其根因、解决方案错误代码KerberosImpacket工具报错常见根本原因排查与解决方法KRB_AP_ERR_BAD_INTEGRITYERROR: Error while parsing the ticket: utf-8 codec cant decode byte...或Ticket decryption failed服务账户NTLM哈希错误。最常见原因哈希复制粘贴时多了空格或误用了AES密钥如aes256-cts-hmac-sha1-96而非NTLM哈希或哈希对应的是错误的服务账户如用了administrator的哈希去伪造cifs票据。1. 用echo a1b2c3... | wc -c确认哈希长度为322. 用hash-identifier工具确认哈希类型为NTLM3. 用setspn -L target$再次确认目标服务账户名。KRB_AP_ERR_SKEWERROR: Error while parsing the ticket: Ticket expired或Clock skew too great时间戳严重偏差。票据中的starttime/endtime与目标服务主机的UTC时间相差超过5分钟。1. 在Kali上执行date -u2. 在fileserver上执行w32tm /query /status查看Source和Last Successful Sync Time3. 强制同步w32tm /resync /force。KDC_ERR_S_PRINCIPAL_UNKNOWNERROR: Principal not found或Cannot find SPNSPN填写错误或不存在。大小写错误CIFSvscifs、域名错误domainvsdomain.local、服务类型错误hostvscifs。1. 用setspn -L target$精确复制SPN2. 在Kali上用nslookup fileserver.domain.local确认DNS解析正确3. 尝试用getST.pyImpacket生成票据它会对SPN做更严格的语法检查。KDC_ERR_C_PRINCIPAL_UNKNOWNERROR: Client not found in Kerberos database票据中声明的客户端用户名user1domain.local在域中不存在或拼写错误如user1domian.local。1. 在域内执行net user user1 /domain确认用户存在且启用2. 检查ticketer.py命令末尾的用户名确保与net user输出完全一致包括大小写和域名。KRB_AP_ERR_MODIFIEDERROR: Invalid checksum或Ticket integrity check failed票据文件损坏或环境变量未正确设置。.ccache文件被意外修改或KRB5CCNAME指向了错误路径/文件名。1. 用ls -la确认.ccache文件存在且大小1KB2. 用echo $KRB5CCNAME确认环境变量值正确3. 用cat $KRB5CCNAME | head -n 5粗略检查文件头部是否为二进制乱码正常票据是二进制。4.2 蓝队视角如何检测与防御白银票据作为红队了解蓝队的防御手段才能写出更隐蔽的攻击脚本。白银票据的防御核心在于“打破单向信任”主要从三个层面入手1. 日志监控DetectionKDC日志缺失告警SIEM规则应持续监控域控的Security日志对Event ID 4624登录成功且Logon ProcessKerberos的事件反向查询同一时间段内是否有对应的Event ID 4769TGS发放。若无则为高危白银票据嫌疑。异常SPN访问监控非管理员账户如user1对高价值SPN如MSSQLSvc/、HTTP/的访问。普通用户访问数据库服务本身就是异常行为。计划任务日志在所有域成员机上启用TaskScheduler日志Event ID 106, 140, 141监控由psexec等工具创建的临时计划任务。2. 配置加固Prevention禁用不必要的SPN定期审计setspn -Q */*删除所有未使用的SPN。减少攻击面。启用Kerberos ArmoringFAST在域功能级别为Windows Server 2012 R2或更高时启用Kerberos Armoring。它要求客户端在TGS请求中提供额外的加密证明使得离线伪造的白银票据无法通过验证。这是目前最有效的技术防御。限制服务账户权限避免使用高权限域账户如Domain Admins组成员作为服务账户。应为每个服务创建专用的、权限最小化的服务账户如svc_cifs并定期轮换其密码从而更新NTLM哈希。3. 工具与流程Response内存取证当怀疑发生白银票据攻击时立即对目标服务主机fileserver执行内存转储volatility或Belkasoft RAM Capturer分析lsass.exe进程内存搜索Kerberos、TGT、TGS等关键词可发现票据加载痕迹。票据吊销虽然白银票据本身无法被KDC吊销因为它不经过KDC但可以立即重置目标服务账户fileserver$的密码。这会使所有基于旧哈希的白银票据立即失效。命令net user fileserver$ * /domain。4.3 红队进阶技巧让白银票据更“像”一个真实用户在高级红队作业中仅仅能用是不够的还要“用得像”。以下是几个提升隐蔽性的实战技巧伪造登录来源Workstation Name默认情况下psexec.py生成的日志中Workstation Name是你的Kali主机名非常可疑。Impacket的ticketer.py支持-extra-sid参数但更简单的方法是在生成票据后用ktutilLinux Kerberos工具手动编辑.ccache文件修改其中的cname客户端名称字段为一个真实的、近期活跃的域内工作站名如DESKTOP-ABC123。这需要对Kerberos ASN.1结构有深入了解但效果显著。票据时效精细化控制不要总用默认的5小时有效期。观察目标业务的活跃时段如财务系统只在工作日9-17点使用将票据endtime精确设置为该时段结束前10分钟。这样即使票据文件被蓝队捕获也已过期无法复用。多票据组合技白银票据不是孤立的。你可以先用一个低权限用户的白银票据访问一台中间服务器再从这台服务器上提取其本地管理员密码进而用该密码登录到域控完成最终提权。这种“跳板式”利用比单次直达域控更难被溯源。我在某次金融行业红队评估中就采用了这种组合技。目标环境启用了Kerberos Armoring黄金票据失效。我转而用一个普通柜员账户的哈希生成了针对cifs服务的白银票据成功访问了其办公电脑上的共享文件夹从中找到了一份标注为“内部系统清单”的Excel文档里面列出了所有核心业务系统的IP和SPN。接着我针对其中一个HTTP/SPN生成新票据最终拿到了Web管理后台的访问权限。整个过程没有一次暴力破解没有一个漏洞利用纯粹依靠对协议的理解和对细节的把控。这才是域渗透的真正魅力所在。