尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Shiro密钥字典构建与实战:从反序列化漏洞到高效密钥爆破

Shiro密钥字典构建与实战:从反序列化漏洞到高效密钥爆破 1. 项目缘起一次真实的渗透测试复盘那次渗透测试的授权范围是一个典型的Java Web应用。前期信息收集很顺利端口、目录、框架指纹都摸得七七八八。当看到响应头里明晃晃的Set-Cookie: rememberMedeleteMe;时心里基本就有谱了——这八成是Apache Shiro。Shiro这个Java安全框架用起来方便但历史上因为密钥硬编码问题出过好几次大篓子最著名的就是Shiro-550CVE-2016-4437和Shiro-721CVE-2019-12422。前者是反序列化漏洞后者是Padding Oracle攻击但它们的根子都差不多开发者使用了默认的或者强度不足的加密密钥cipherKey。问题来了知道它有漏洞怎么利用核心就是那个密钥。没有正确的密钥你构造的恶意序列化数据就无法被服务端成功解密攻击链就断了。当时我手头有几个从网上搜集的、流传很广的所谓“Shiro默认密钥”字典大概几十上百个的样子。跑了一遍没一个能对上。测试一时间卡住了。我意识到光靠网上那些“经典”密钥列表在实战中成功率会越来越低。一方面安全意识提升用默认密钥的少了另一方面很多开发团队会自定义密钥但这些自定义的密钥往往也有规律可循。于是我决定自己动手系统性地整理、研究和扩充一份真正面向实战的Shiro密钥字典。这就是“shiro_keys字典”项目的由来。它不是一个简单的列表复制粘贴而是一个基于漏洞原理、编码习惯和实战经验构建的动态武器库。2. 理解Shiro RememberMe的加密机制为什么密钥如此关键要搞懂密钥字典的价值必须得先明白Shiro的RememberMe功能是怎么工作的。这绝不仅仅是“一个加密cookie”那么简单。2.1 核心流程拆解当用户登录成功并勾选“记住我”时Shiro会执行以下操作序列化将用户的身份信息Principal、凭证以及其他必要的状态数据通过Java的序列化机制转换成一个二进制字节流。加密使用一个对称加密算法默认是AES-CBC配合一个密钥cipherKey对这个序列化后的字节流进行加密得到密文。编码将加密后的密文进行Base64编码使其可以安全地放在HTTP的Cookie字段中即rememberMe的值。发送将这个Base64字符串通过Set-Cookie响应头设置给浏览器。当用户再次访问时浏览器会带上这个rememberMe的Cookie。Shiro服务端则反向操作解码对Cookie值进行Base64解码得到密文。解密使用同一个密钥对密文进行AES解密得到序列化字节流。反序列化直接使用ObjectInputStream.readObject()反序列化该字节流还原用户对象完成自动登录。2.2 漏洞的根源密钥与反序列化的耦合漏洞就潜伏在上述流程的第3步服务端反序列化。如果攻击者能够伪造或篡改Cookie。并且让服务端能用正确的密钥解密这个伪造的Cookie。那么解密后得到的字节流就可以是攻击者精心构造的恶意序列化数据例如包含CommonsCollections或CB链的Payload。由于Shiro在解密后没有任何白名单或安全检查直接进行反序列化就会导致远程代码执行。因此整个攻击链成立的两个必要条件就是存在可用的反序列化利用链Java环境通常有和获取到正确的AES加密密钥。前者是环境问题后者就是我们攻击者需要突破的核心。密钥成了打开Shiro安全大门的唯一一把或少数几把钥匙。2.3 密钥的常见来源与分类基于多年的代码审计和渗透经验Shiro的密钥通常来源于以下几个地方这也构成了我们字典的主要分类依据硬编码在源码中的默认密钥这是最“经典”的来源。Shiro早期版本或者一些不负责任的示例代码、开源项目中直接像String cipherKey kPHbIxk5D2deZiIxcaaaA;这样把密钥写在配置类里。这类密钥虽然公开但仍有大量未修复的遗留系统在使用。框架或中间件默认配置某些基于Shiro二次开发的开源系统、CMS或脚手架会自带一个默认密钥。攻击者拿到一套系统默认密钥可能就是那个。通过代码泄露或配置错误获取GitHub等代码仓库泄露、配置文件如shiro.ini,application.yml,application.properties被错误地部署到Web目录可被直接访问都可能直接暴露密钥。弱密钥或常见密钥开发者虽然不用默认密钥但可能会自己设置一些简单的密钥如“123456”、“admin”、“companyname2023”等或者使用公司名、项目名、域名等变换而来如MD5、Base64编码后。这类密钥强度低可通过字典爆破。基于特定算法或字符串生成的密钥例如用org.apache.shiro.crypto.AbstractSymmetricCipherService#generateNewKey()方法生成密钥但该方法的默认密钥长度和生成逻辑可能被推测。3. 构建高质量Shiro密钥字典的方法论一份好的字典不是数据的堆砌而是策略的体现。我的构建思路主要分为四个层次静态收集、动态生成、上下文关联和实战过滤。3.1 第一层静态收集与去重这是基础工作目标是建立一个“已知密钥库”。来源从公开的漏洞利用框架如ShiroAttack2、Behinder的Shiro插件、历史漏洞报告CVE详情、安全厂商分析文章、GitHub上的开源PoC项目、以及各大渗透测试工具内置的字典中提取所有出现过的Shiro密钥。处理收集到的密钥可能是Base64格式的也可能是Hex格式的甚至是原始字符串。需要进行统一格式化通常统一为Base64并进行严格的去重。这一步能解决约20%-30%的“低垂果实”。示例部分kPHbIxk5D2deZiIxcaaaA 4AvVhmFLUs0KTA3Kprsdag Z3VucwAAAAAAAAAAAAAAAA fCq/xW488hMTCDcmJ3aQ 0AvVhmFLUs0KTA3Kprsdag 1AvVhmFLUs0KTA3Kprsdag ...3.2 第二层基于规则的动态生成这是提升覆盖面的关键。很多自定义密钥并非完全随机而是有迹可循。弱口令模式将常见的弱口令如123456, admin, password, 123123、短数字序列、键盘组合如qwert, asdfgh等进行AES密钥所需的长度填充或变换后再Base64编码。字符串变换模式对“shiro”、“rememberMe”、“admin”、“root”等关键词本身进行Base64编码。对上述关键词进行MD5、SHA-1哈希后取前16位或32位对应AES-128或AES-256的密钥长度再进行Base64编码。对域名、公司名、项目名进行类似变换。例如针对target.com生成target、Target、TARGET、target2024、target123等变体再进行哈希和编码。时间戳模式有些自动化部署脚本会用时间戳作为密钥的一部分如20240101、2024等。编码模式直接尝试对空字符串、空格、常见符号进行Base64编码有时会有意外收获。这部分可以通过编写简单的Python或Go脚本批量生成字典大小可以轻易扩展到数万甚至数十万条能覆盖大量“自以为安全”的自定义场景。3.3 第三层上下文关联与智能猜测在针对特定目标进行攻击时这一层策略尤为重要。它需要结合信息收集的结果。GitHub/GitLab挖掘如果目标公司或项目有公开的代码仓库可以搜索cipherKey、setCipherKey、shiro.ini、rememberMe等关键词尝试直接找到密钥。配置文件泄露扫描目标网站的/WEB-INF/classes/shiro.ini、/config/application.properties等路径看是否能直接下载到配置文件。文档与注释有些开发文档、部署手册或代码注释里可能会不经意间写出测试用的密钥。社会工程学了解目标公司的命名规范、项目代号、常用密码策略可以极大提高生成字典的针对性。3.4 第四层实战过滤与字典维护字典不是一成不变的需要在使用中迭代。有效性验证不是所有收集来的密钥都是有效的AES密钥。有些可能是错误的、格式不对的。最好在构建字典时就用一个简单的脚本比如用Python的Crypto.Cipher.AES尝试用每个密钥去解密一个已知的测试数据包过滤掉那些根本不能初始化AES cipher的无效密钥。这能减少后续爆破时的无效请求。去失效化随着时间推移一些公开的密钥被广泛加入扫描器导致很多系统修复。定期用这些密钥去测试一些常见的蜜罐或测试环境如果某个密钥长期无法命中可以考虑将其标记或移至低频词库。增量更新关注新的漏洞披露、新的开源项目持续将新发现的默认密钥或常见密钥加入字典。4. 密钥字典的使用与爆破实战技巧有了字典怎么用最高效这里分享几个从实战中总结的心得。4.1 工具选择与组合单纯用一个庞大的字典去撞效率低下且容易被封IP。需要结合工具特性。专用漏洞利用工具如ShiroAttack2、shiro-exploit等。它们集成了密钥字典、利用链和Payload一键化程度高适合快速验证。但它们的字典可能更新不及时需要替换成我们自己维护的、更全的字典文件。通用爆破工具适配有时需要集成到Burp Suite的Intruder或ffuf、wfuzz这类工具中。这就需要将攻击流程拆解先获取一个合法的rememberMeCookie可以是未登录状态下的Shiro也会返回一个加密的Cookie只不过内容是空的或固定的。用我们的密钥字典在本地离线尝试解密这个合法Cookie。如果能用某个密钥成功解密出一个看似合理的序列化数据或者能解密但数据乱码这也很可能说明密钥正确只是数据不是Java序列化对象那么这个密钥就是候选密钥。将候选密钥用于实际攻击发送真正的恶意Payload。注意直接在线用所有密钥尝试解密并反序列化攻击会产生大量请求极易触发WAF或封禁。先本地离线筛选一波候选密钥能大幅减少在线攻击的尝试次数提升隐蔽性和成功率。4.2 爆破策略与流量优化在线爆破时策略很重要。速率限制务必设置合理的请求间隔如-t 2或--delay 1避免洪水攻击。Payload编码确保你的恶意序列化Payload在加密前是正确的并且最终生成的rememberMeCookie的Base64编码符合规范。有时候Padding不对都会导致请求被提前拒绝。判断依据成功利用的响应与失败响应通常有差异。成功执行命令后响应体可能包含命令执行结果响应时间可能变长或者返回一个错误页面因为反序列化后流程异常。而密钥错误导致的解密失败Shiro通常会返回一个rememberMedeleteMe的Cookie或者一个固定的错误状态。需要仔细分析对比。分阶段爆破可以先用一个小的、高概率的“快速字典”如50个最常见密钥进行第一轮试探。如果没有命中再使用完整的“深度字典”。这样能更快地发现那些仍然使用默认密钥的“简单目标”。4.3 一个典型的踩坑案例密钥正确但利用失败有一次遇到一个系统我的字典成功匹配到了一个密钥工具显示“Key is correct”但后续的CommonsCollections和CB链Payload全部失败返回500错误。排查了很久最后发现问题是JDK版本。目标服务器是JDK 8u342以上的高版本。众所周知高版本JDK对Jdk7u21、CommonsCollections等传统利用链设置了默认的序列化过滤器JEP 290导致反序列化被阻止。密钥对了门开了但Payload被门后的保安拦住了。解决方案尝试其他利用链换用针对高版本JDK的利用链例如CommonsBeanutils链不带PropertyUtils的变种、或者一些基于Tomcat内存马、Spring内存马的链。这些链可能绕过过滤。利用回显技术如果命令执行无回显可以尝试DNSLog、HTTP请求外带数据等方式验证漏洞是否存在。结合其他漏洞如果Shiro反序列化被过滤但密钥已获取可以看看是否有其他入口点能利用这个密钥比如某些自定义的、使用了相同密钥的加密接口。这个坑告诉我拿到密钥只是第一步。现代Java安全防护是立体的需要我们对整个漏洞利用链有更深入的理解和更丰富的武器储备。5. 防御视角如何让你的Shiro应用免于密钥爆破站在防御者角度如何构建一个不易被字典攻破的Shiro应用以下是一些切实可行的建议。绝对不要使用默认密钥或硬编码密钥这是最根本的一条。在项目启动时必须生成一个随机的、强密码学强度的密钥。安全地生成和管理密钥使用KeyGenerator如AESKeyGenerator生成符合长度要求的随机密钥。将密钥作为机密信息管理存储在环境变量、云服务商的密钥管理服务如AWS KMS, Azure Key Vault或专用的配置中心里而不是写在代码或配置文件中。对于容器化部署可以通过Secret卷挂载的方式注入密钥。定期轮换密钥谨慎操作定期更换密钥可以降低密钥泄露带来的长期风险。但请注意轮换密钥会使所有已发出的“记住我”Cookie立即失效导致用户需要重新登录需要权衡安全性与用户体验。如果实施要有平滑过渡方案。升级Shiro版本并关闭危险特性升级到最新稳定版Shiro以修复已知漏洞。如果业务不需要RememberMe功能强烈建议直接禁用它shiro.rememberMe.enabledfalse。这是最有效的防御。如果确实需要考虑使用更安全的替代方案如增强的Session管理或者采用JWT等无状态令牌但JWT也需要妥善管理签名密钥。实施网络与应用层防护WAF可以配置规则识别和拦截Shiro反序列化攻击的常见特征。在应用层面可以尝试集成反序列化过滤器如SerialKiller对反序列化的类进行白名单控制。但这需要对Shiro内部机制有较深改造实施成本较高。6. 总结与字典项目展望“shiro_keys字典”项目从一个渗透测试受阻时的应急工具逐渐演变成一个需要持续维护的安全研究副产品。它让我深刻体会到在攻防对抗中自动化工具的背后核心是高质量的数据和清晰的策略。一个不断更新的、分层的、智能的字典其价值远大于一个只会用固定列表扫描的工具。目前这个字典项目我依然在私下维护它包含了从最初几十个到现在数千个经过筛选和分类的密钥条目并配有一套简单的生成和测试脚本。未来我考虑从以下几个方向深化机器学习辅助生成尝试分析已收集的有效密钥的字符分布、编码模式训练简单的模型来生成更“像”真实密钥的新候选进一步扩大探测范围。与指纹识别联动将Shiro密钥字典与更精准的Shiro版本指纹、相关组件指纹如特定的CMS关联起来实现“识别到特定系统 - 加载其历史相关密钥字典”的精准打击模式。动态密钥探测研究探索在极端情况下是否存在不依赖密钥字典而通过其他侧信道或密码学手段推测或攻击密钥本身的可能性这属于更前沿的研究范畴。最后必须强调所有关于漏洞利用和字典构建的技术讨论仅限用于获得合法授权的安全测试、渗透测试和教育研究。未经授权对任何系统进行测试都是违法行为。作为安全从业者我们研究攻击手段的终极目的是为了更好地构建防御。希望这篇从一次实战卡壳引发的、关于一个密钥字典的深度剖析能为你理解Shiro安全乃至整个应用安全攻防提供一个扎实的剖面。
返回列表