
1. 从一次内网排查说起为什么白银票据值得单独拎出来讲很多人第一次听到白银票据这个词是在做内网安全评估或者域环境排查的时候。它不像黄金票据那样一出场就自带光环、动辄控制整个域但恰恰因为它的门槛更低、更隐蔽反而成了实战中出现频率极高的一类攻击手法。我在实际项目里遇到过好几次这样的情况明明没有拿到域控权限也没有域管哈希但攻击者就是能访问某台文件服务器、某台数据库服务器甚至能横向到其他机器上执行命令。追查下来问题往往就出在服务账户的密钥泄露上而利用这个密钥伪造出来的正是所谓的白银票据。先把概念说清楚。在Windows域环境里Kerberos是默认的认证协议。正常流程下你输入账号密码登录域控KDC验证通过后给你发一张票据授权票据TGT你拿着TGT再去向域控申请针对某个具体服务的服务票据ST最后拿ST去访问那个服务。整个过程里域控是核心所有票据都得它盖章才有效。而白银票据的核心思路是我不经过域控直接用某个服务账户的密钥NTLM Hash或AES Key自己伪造一张服务票据因为服务端只认自己账户密钥加密的票据不关心这张票是不是域控发的。这就绕过了域控的整个认证环节直接骗过目标服务。这个手法为什么危险因为它把攻击面从必须拿下域控降到了拿下任意一台运行服务的机器上的服务账户凭据。而服务账户的凭据在域环境里到处都是——IIS的应用池账户、SQL Server的服务账户、各种计划任务用的账户这些账户的密码哈希可能被缓存在本地也可能通过Kerberoasting被离线破解出来。一旦拿到攻击者就能伪造票据访问该服务所在的主机甚至以该服务的权限执行操作。更麻烦的是这种伪造的票据在服务端日志里看起来一切正常因为票据本身是合法的、用正确密钥加密的只是签发者不是域控而已。我写这篇东西的目的不是教人怎么攻击而是把这件事的来龙去脉、技术细节、检测思路和防御手段讲透。因为只有真正理解了票据是怎么被伪造出来的你才知道该在哪里设卡、该监控什么日志、该给服务账户做什么样的加固。下面我会从Kerberos的票据结构讲起一步步拆到白银票据的构造方式、利用条件、检测点和防御策略中间穿插我在实际排查中踩过的坑和总结的经验。2. Kerberos票据的防伪标识到底藏在哪2.1 服务票据的加密结构为什么服务端只认自己的密钥要理解白银票据必须先搞清楚一张服务票据ST里面到底装了什么。Kerberos的ST本质上是一个被服务账户密钥加密的数据结构里面包含了客户端身份、会话密钥、票据有效期、权限信息等。关键点在于这张票据是用服务账户的长期密钥加密的而不是域控的密钥。域控在签发ST的时候会从活动目录里读取目标服务对应的账户密钥用它来加密票据内容然后发给客户端。客户端拿着这张加密后的票据去找服务服务用自己的密钥解密验证通过后就认为这是域控认可的用户然后根据票据里的信息决定给什么权限。这里有个容易被忽略的细节服务端在验证票据时并不会去联系域控确认这张票是不是真的由域控签发的。它只做一件事——用自己的密钥解密能解开就认。这个设计本身是为了性能考虑避免每次服务访问都去骚扰域控。但正是这个只解密不验证来源的机制给了白银票据可乘之机。攻击者只要拿到服务账户的密钥就能自己构造一张一模一样的票据服务端照样能解密照样认。我在一次排查中遇到过这样的情况某台文件服务器的安全日志里显示某个普通域用户访问了共享目录但那个用户当天根本没登录过。后来发现是攻击者用文件服务器机器账户的哈希伪造了ST把自己伪装成了那个用户。服务端日志里记录的访问者是伪造票据里填的那个用户名而不是攻击者真实的身份。这就是白银票据最迷惑人的地方——日志里看到的人和实际操作的人可能完全对不上。2.2 服务账户密钥的几种来源为什么它比想象中好拿服务账户的密钥在域环境里其实并不难获取这也是白银票据泛滥的根本原因。常见的来源有这么几类第一类是机器账户的哈希。每台加入域的计算机都有一个机器账户它的密码是自动维护的默认30天轮换一次。但如果你拿到了某台机器的本地管理员权限就可以从内存里把机器账户的哈希抓出来。这个哈希可以用来伪造针对该机器上各种服务的白银票据。第二类是服务账户的密码哈希。很多服务在配置的时候会指定一个域用户作为服务账户比如IIS的应用池身份、SQL Server的启动账户。这些账户的密码哈希可能被缓存在服务所在机器的LSASS进程里也可能通过Kerberoasting攻击被离线破解。Kerberoasting的原理是任何域用户都可以向域控请求任意服务账户的ST而这张ST是用服务账户密钥加密的拿回来之后可以离线暴力破解。如果服务账户的密码强度不够很快就能破出来。第三类是组托管服务账户gMSA的密钥。gMSA是微软后来推出的一种更安全的服务账户方案密码由域控自动管理且复杂度很高理论上很难破解。但如果攻击者拿到了域控权限或者拿到了能读取gMSA密码的权限照样能提取出密钥。不过相比传统服务账户gMSA的门槛已经高了很多。第四类是计划任务和应用程序的硬编码凭据。这个说起来有点尴尬但确实常见——有些应用程序的配置文件里直接写了服务账户的明文密码或者脚本里硬编码了凭据。攻击者拿到这些文件就等于拿到了服务账户的密钥。我个人的经验是在做内网评估的时候Kerberoasting几乎是必做的动作。因为它的门槛极低——只要有一个普通域用户权限就能发起而且很多老系统的服务账户密码还是几年前设的强度堪忧。一旦破出来一个服务账户的密码对应的白银票据就能直接安排上。2.3 白银票据与黄金票据的本质区别权限范围决定隐蔽性很多人会把白银票据和黄金票据搞混这里必须掰扯清楚。黄金票据伪造的是TGT用的是域控上krbtgt账户的哈希。有了krbtgt哈希你可以伪造任意用户的TGT然后拿这个TGT去申请任意服务的ST等于拿到了整个域的通行证。但krbtgt哈希只在域控上有拿到它意味着你已经拿下了域控这是域渗透的终极目标之一。白银票据伪造的是ST用的是某个具体服务账户的哈希。你只能伪造针对那个服务的票据访问那个服务所在的主机或资源权限范围局限在服务账户能触及的范围内。但好处是你不需要域控权限只需要拿到某个服务账户的密钥就行。门槛低、范围小、隐蔽性强这是白银票据的特点。从检测角度看黄金票据因为伪造的是TGT而TGT的签发在域控上有严格日志记录所以相对容易被发现。白银票据伪造的是STST的签发在域控上也有日志但服务端验证票据时不会去域控核对所以如果攻击者直接用伪造的ST去访问服务域控那边根本不会有对应的ST签发记录。这就造成了一个检测盲区服务端有访问日志域控端没有签发日志两边对不上。这个日志缺口恰恰是检测白银票据的重要线索。3. 伪造一张白银票据需要凑齐哪些零件3.1 域SID、服务账户哈希与目标SPN三样缺一不可要伪造一张能用的白银票据你需要凑齐三个核心要素域的SID、服务账户的密钥NTLM Hash或AES Key、目标服务的SPN。这三个东西缺一不可少一个票据就构造不出来或者构造出来服务端解不开。域的SID是标识这个域的唯一字符串格式类似S-1-5-21-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx。它的作用是放在票据的权限信息里告诉服务端这个用户属于哪个域。获取域SID的方法很多普通域用户就能通过whoami /user或者查询活动目录拿到不算什么秘密。服务账户的密钥是核心。如果是NTLM Hash就是那个32位的十六进制字符串如果是AES Key就是更长的字符串。获取方式前面已经说了Kerberoasting、内存抓取、配置文件泄露等等。这里要注意一点用NTLM Hash和用AES Key伪造出来的票据在服务端看来可能有些细微差别因为加密算法不同。有些老服务只支持RC4加密那就只能用NTLM Hash新一点的服务支持AES用AES Key更稳妥。目标SPN是你要访问的服务的标识格式类似MSSQLSvc/sqlserver.domain.com:1433或者CIFS/fileserver.domain.com。SPN必须填对因为服务端在解密票据后会检查票据里的SPN是否和自己匹配。填错了服务端直接拒绝。获取SPN的方法也简单普通域用户就能查询活动目录里的SPN记录。我见过有人伪造票据失败排查半天发现是SPN写错了——把CIFS写成了HOST或者端口号漏了。这种细节看着小但直接决定票据能不能用。所以构造之前一定要先用工具把目标服务的SPN确认清楚。3.2 票据里的PAC字段权限信息的暗箱票据里还有一个关键部分叫PACPrivilege Attribute Certificate里面装着用户的SID、所属组、权限信息等。服务端在解密票据后会读取PAC里的信息来决定给用户什么权限。白银票据的伪造者可以自定义PAC里的内容比如把自己塞进域管理员组这样访问服务时就能拿到最高权限。但这里有个坑PAC字段是有签名的。正常情况下PAC会由域控用krbtgt密钥签名服务端验证签名确保PAC没被篡改。如果攻击者伪造的票据里PAC签名不对有些服务会拒绝。不过在实际环境中很多服务对PAC签名的验证并不严格尤其是那些只做简单认证的服务。所以白银票据能不能拿到高权限取决于目标服务的具体配置。我在测试中遇到过这样的情况用伪造的票据访问文件共享能列目录、能读文件但想写文件就被拒了。后来分析发现服务端虽然认了票据但在做写操作时额外检查了PAC里的组信息而伪造的PAC里没有对应的权限组。这说明白银票据的权限不是无限的它受限于服务端的授权逻辑。想拿到更高权限要么伪造更完整的PAC要么目标服务本身对PAC校验不严。3.3 时间戳与票据有效期别让过期票坏了事票据里还有时间戳字段包括签发时间和过期时间。服务端在验证票据时会检查当前时间是否在有效期内。如果伪造的票据时间设置不对比如签发时间在未来或者已经过期服务端会直接拒绝。所以构造票据时时间字段要设置得合理——通常签发时间设为当前时间稍早一点过期时间设为当前时间之后若干小时。这个细节看似简单但实际构造时容易忽略。有些工具默认的时间设置可能和目标的时区不一致导致票据看起来过期了。我在一次测试中就因为这个卡了半天后来把时间字段手动调整了一下才通过。所以如果你自己写脚本构造票据时间字段一定要仔细处理。4. 从零构造一张白银票据的完整实操链路4.1 信息收集先把域SID、SPN和目标账户摸清楚构造白银票据的第一步是信息收集。你需要确认三件事域的SID是什么、目标服务的SPN是什么、服务账户的哈希有没有拿到。前两个用普通域用户权限就能查第三个取决于你之前的渗透成果。查域SID可以在域内任意一台机器上执行whoami /user输出里的SID去掉最后的RID部分就是域SID。比如输出是S-1-5-21-1234567890-1234567890-1234567890-1105那域SID就是S-1-5-21-1234567890-1234567890-1234567890。也可以用PowerShell的Get-ADDomain命令直接拿到DomainSID属性。查SPN可以用setspn -T domain.com -Q */*列出所有SPN或者用PowerShell的Get-ADUser -Filter {ServicePrincipalName -like *} -Properties ServicePrincipalName。找到目标服务对应的SPN后记下来格式要完整。服务账户哈希的获取方式前面说过了这里不再展开。假设你已经拿到了某个服务账户的NTLM Hash接下来就可以进入构造环节。4.2 用Mimikatz构造票据参数逐个拆解Mimikatz是构造白银票据最常用的工具之一它的kerberos::golden命令虽然名字叫golden但通过指定参数也可以用来构造白银票据。核心参数有这么几个/domain域名比如domain.com/sid域SID就是前面查到的那个/target目标服务的SPN比如CIFS/fileserver.domain.com/service服务类型比如cifs、mssql、http/rc4服务账户的NTLM Hash/user你想伪装成的用户名可以随便填/ptt直接注入到当前会话不生成文件一个典型的命令长这样kerberos::golden /domain:domain.com /sid:S-1-5-21-1234567890-1234567890-1234567890 /target:fileserver.domain.com /service:cifs /rc4:abcdef1234567890abcdef1234567890 /user:fakeuser /ptt执行完之后当前会话就多了一张伪造的ST。你可以用klist命令查看当前会话里的票据确认伪造的票据已经注入。然后尝试访问目标服务比如dir \\fileserver.domain.com\share如果能列目录说明票据生效了。这里有几个实操细节值得注意。第一/user字段填什么名字不影响票据能不能用但会影响服务端日志里记录的用户名。如果你想隐蔽一点可以填一个真实存在的普通用户名这样日志看起来更正常。第二/ptt参数是直接注入内存不落盘相对隐蔽如果不加这个参数Mimikatz会生成一个.kirbi文件你需要用kerberos::ptt命令手动注入。第三如果目标服务支持AES加密可以用/aes256参数替代/rc4票据的兼容性更好。4.3 不用Mimikatz的替代方案Rubeus与自写脚本Mimikatz虽然强大但在某些环境下会被杀软拦截。这时候可以考虑用Rubeus它是一个专门针对Kerberos的工具用C#写的功能很全。Rubeus构造白银票据的命令是rubeus.exe silver参数和Mimikatz类似rubeus.exe silver /service:cifs/fileserver.domain.com /rc4:abcdef1234567890abcdef1234567890 /user:fakeuser /domain:domain.com /sid:S-1-5-21-1234567890-1234567890-1234567890 /pttRubeus的好处是它可以直接在内存里执行不依赖外部库而且对某些杀软的绕过效果更好。不过它也不是万能的具体能不能用还得看目标环境的防护情况。如果连Rubeus都用不了还可以自己写脚本构造票据。Kerberos票据的格式是公开的用Python的impacket库就能构造。impacket里的ticketer.py脚本就是干这个的python ticketer.py -nthash abcdef1234567890abcdef1234567890 -domain-sid S-1-5-21-1234567890-1234567890-1234567890 -domain domain.com -spn cifs/fileserver.domain.com fakeuser执行完会生成一个.ccache文件然后用export KRB5CCNAMEfakeuser.ccache设置环境变量就可以用这个票据访问目标服务了。这种方式的优点是跨平台Linux环境下也能用适合在渗透测试的后期阶段使用。4.4 票据注入后的验证怎么确认票真的能用构造完票据、注入到会话之后怎么确认它真的生效了最直接的方法就是尝试访问目标服务。如果是CIFS服务就试着列共享目录如果是MSSQL服务就试着连接数据库如果是HTTP服务就试着访问Web页面。能正常访问说明票据被服务端认可了。但这里有个容易误判的情况有时候你访问成功了但用的其实不是伪造的票据而是当前会话里本来就有的合法票据。所以验证之前最好先用klist purge清空当前会话的所有票据然后再注入伪造的票据再访问。这样才能确保访问成功是因为伪造的票据生效了。另一个验证方法是看服务端日志。如果服务端记录了你的访问但域控端没有对应的ST签发记录那就基本可以确认是白银票据在起作用。这个日志缺口也是后面检测环节要重点关注的。5. 服务端日志里的幽灵访问白银票据的检测思路5.1 域控端没有ST签发记录服务端却有访问日志白银票据最核心的检测思路就是找日志缺口。正常情况下用户访问某个服务流程是这样的用户先拿TGT向域控申请ST域控签发ST并记录事件日志事件ID 4769然后用户拿ST访问服务服务端记录访问日志。所以域控端有4769事件服务端有访问日志两边能对上。但白银票据绕过了域控攻击者直接伪造ST访问服务。服务端照样记录访问日志但域控端没有对应的4769事件。如果你在服务端看到某个用户访问了服务但在域控端查不到该用户申请该服务ST的记录这就非常可疑了。实际操作中可以把服务端的访问日志和域控端的4769事件做关联分析。具体做法是从服务端日志里提取访问者的用户名、访问时间、目标服务然后去域控的Security日志里查同一时间窗口内该用户是否有对应的4769事件。如果没有基本可以判定是伪造票据。这个方法的难点在于日志量可能很大手工比对不现实。通常需要写脚本或者用SIEM平台做自动化关联。我在项目里用PowerShell写过简单的关联脚本从两台机器的日志里分别导出数据然后用哈希表做匹配效率还可以。5.2 票据里的异常字段SPN不匹配与PAC签名缺失除了日志缺口票据本身的异常字段也是检测点。比如服务端在解密票据后会检查票据里的SPN是否和自己匹配。如果攻击者构造票据时SPN填错了服务端会拒绝并在日志里记录异常。这种异常日志可以作为检测线索。另一个检测点是PAC签名。正常情况下PAC会由域控用krbtgt密钥签名。如果服务端配置了严格的PAC验证伪造的票据因为签名不对会被拒绝。但很多服务默认不验证PAC签名所以这个检测点不是万能的。不过如果服务端日志里出现了PAC验证失败的记录那就值得深挖。还有一个细节伪造票据里的加密类型可能和正常票据不同。比如正常环境里服务端可能偏好AES加密但攻击者用NTLM Hash伪造的票据是RC4加密的。如果服务端日志里记录了加密类型可以对比正常访问和可疑访问的加密类型差异。这个差异不一定能直接定性但可以作为辅助判断。5.3 访问行为异常非工作时间、非常用IP、异常权限除了技术层面的检测行为层面的异常也很重要。白银票据伪造出来的身份是攻击者自己填的可能是一个真实存在的用户也可能是一个虚构的用户。如果服务端日志里出现了不存在的用户名或者某个用户在不正常的时间比如凌晨三点访问了服务或者访问来源IP和该用户平时的习惯不符这些都是可疑信号。更隐蔽的一种情况是权限异常。攻击者伪造票据时可能把自己塞进了高权限组导致一个普通用户在服务端表现出了不该有的权限。比如一个普通域用户突然能访问只有管理员才能访问的共享目录这就是明显的异常。服务端如果配置了权限变更审计这类异常会被记录下来。我在一次排查中就是通过权限异常发现的线索某台文件服务器的日志显示一个普通用户读取了一个敏感目录但该用户所属的组并没有这个目录的权限。深入分析后发现是伪造票据里塞了额外的组信息。这个案例说明光看认证日志不够还得结合授权日志一起分析。6. 把门关紧针对白银票据的防御加固清单6.1 服务账户密码强度与轮换策略让哈希破不出来白银票据的根基是服务账户密钥泄露所以最直接的防御就是让密钥难以获取。具体措施包括给服务账户设置足够复杂的密码长度至少25位包含大小写字母、数字和特殊字符定期轮换服务账户密码尤其是那些长期未更换的账户避免多个服务共用同一个账户降低单点泄露的影响范围。如果条件允许尽量使用组托管服务账户gMSA。gMSA的密码由域控自动管理复杂度高且定期轮换攻击者即使拿到了哈希能用的时间窗口也很短。而且gMSA的密码不会缓存在本地内存抓取也拿不到。这是目前防御白银票据最有效的措施之一。另外要定期检查域内是否存在密码强度弱的服务账户。可以用工具做Kerberoasting模拟攻击看看哪些账户的哈希能被快速破解。发现弱密码账户后立即更换密码并排查是否已经被利用。6.2 限制服务账户权限别让一张票通吃服务账户的权限应该遵循最小权限原则。很多环境里服务账户被随手加进了域管理员组或者本地管理员组这是非常危险的。一旦这个账户的密钥泄露攻击者伪造的票据就能拿到管理员权限后果严重。正确的做法是为每个服务账户单独配置所需的权限只授予它完成工作所必需的最小权限。比如一个只负责读取数据库的服务账户就不应该给它写文件的权限一个只负责运行Web应用的服务账户就不应该给它域管权限。这样即使票据被伪造攻击者能做的事情也有限。还要注意服务账户的委派权限。Kerberos委派允许服务代表用户去访问其他服务如果配置不当攻击者可以利用委派链扩大访问范围。对于不需要委派的服务应该禁用委派对于需要委派的服务应该使用约束委派或基于资源的约束委派限制委派的目标范围。6.3 开启PAC签名验证与审计策略让伪造票据露馅前面提到PAC签名验证是检测伪造票据的一个手段。虽然默认情况下很多服务不验证PAC签名但可以通过组策略开启。具体来说可以在域控上配置安全选项里的Kerberos策略启用PAC签名验证。开启后服务端会验证票据里的PAC签名伪造的票据因为签名不对会被拒绝。不过这个措施有个副作用可能会影响一些老系统的兼容性。因为有些老系统不支持PAC签名开启验证后它们可能无法正常认证。所以开启之前要做好测试确认所有关键服务都能正常工作。审计策略方面要确保域控和服务端都开启了详细的Kerberos审计。域控上要记录4769事件ST申请服务端要记录访问日志和认证日志。只有日志齐全才能做关联分析发现日志缺口。同时建议把日志集中收集到SIEM平台设置告警规则比如服务端有访问但域控无对应ST签发就触发告警。6.4 监控Kerberoasting行为从源头掐断密钥泄露Kerberoasting是获取服务账户哈希的主要手段之一所以监控Kerberoasting行为能从源头减少白银票据的风险。Kerberoasting的典型特征是一个普通用户短时间内向域控请求大量不同服务的ST。正常情况下用户只会请求自己需要访问的少数几个服务不会到处请求。检测方法是在域控上监控4769事件统计每个用户请求ST的频率和目标服务数量。如果某个用户在短时间内请求了大量不同SPN的ST尤其是那些该用户平时不访问的服务就可能是Kerberoasting。可以设置阈值告警比如5分钟内请求超过10个不同SPN就触发。另外Kerberoasting请求的ST通常是用RC4加密的因为RC4更容易破解而正常环境里可能已经升级到AES。如果发现大量RC4加密的ST请求也是一个可疑信号。可以在域控策略里禁用RC4加密强制使用AES这样即使攻击者拿到ST破解难度也会大很多。7. 几个我在实操中踩过的坑和总结的经验第一个坑是时间同步问题。Kerberos对时间非常敏感域内机器的时间偏差默认不能超过5分钟。伪造票据时如果时间字段设置不当或者攻击机和目标机的时间不同步票据可能直接被拒。我有一次在虚拟机里做测试宿主机休眠后虚拟机时间没跟上导致伪造的票据怎么都用不了排查了半天才发现是时间问题。所以做这类操作之前先确认时间同步是正常的。第二个坑是SPN格式。前面提过SPN必须填对但具体怎么填有时候容易搞混。比如CIFS服务的SPN有的环境是CIFS/fileserver.domain.com有的是CIFS/fileserver还有的带端口号。填错了服务端就不认。我的经验是先用setspn -Q把目标服务的SPN原样查出来然后一字不差地填进去不要自己猜。第三个坑是票据注入后的会话问题。用Mimikatz的/ptt参数注入票据后票据是注入到当前进程的会话里的。如果你新开一个命令行窗口新窗口里是没有这张票据的。所以注入之后要在同一个会话里操作或者用klist确认票据在当前会话里。这个细节看着小但新手很容易在这里卡住。第四个坑是日志关联的复杂度。做检测的时候域控日志和服务端日志的时间戳可能有时区差异直接比对会对不上。要先统一时区再做关联。另外域控日志量很大全量导出分析不现实最好先按时间窗口和目标服务过滤缩小范围。最后一个经验是关于权限的。白银票据能拿到什么权限取决于服务端的授权逻辑和票据里的PAC内容。不要想当然地认为伪造了票据就一定能拿到管理员权限。实际测试中很多服务只做认证不做细粒度授权伪造票据能访问服务但具体能做什么还得看服务本身的配置。所以评估影响范围时要针对具体服务具体分析不要一概而论。把这些东西串起来看白银票据本质上是一个信任错位的问题服务端信任域控签发的票据但验证时只看密钥不看签发者攻击者利用这个错位用泄露的服务账户密钥自己签发票据。防御的核心也就清晰了要么让密钥拿不到强密码、gMSA、最小权限要么让伪造票据露馅PAC验证、日志关联、行为监控。两条路都走通白银票据的空间就会被大幅压缩。