ShiroAttack2:一体化Shiro反序列化漏洞武器化平台实战解析
1. 项目概述为什么我们需要一个“完整”的Shiro漏洞解决方案在渗透测试和红队评估的实战中Apache Shiro反序列化漏洞是一个绕不开的经典课题。几乎每个有一定规模的应用系统只要历史稍微久远一点你都有可能与它不期而遇。但真正处理过这个漏洞的朋友都知道从“发现可能存在Shiro”到“最终拿到Shell”中间是一条布满荆棘、充满不确定性的漫漫长路。传统的检测工具比如经典的ShiroScan往往只解决了“识别密钥”这一步后续的利用链构造、Payload生成、内存马注入等环节都需要测试人员手动拼接各种脚本和工具过程繁琐且极易出错。更别提那些因为版本差异、依赖冲突、WAF拦截导致的“玄学”问题了。这就是“ShiroAttack2”诞生的背景。它不是一个简单的密钥检测工具而是一个旨在将Shiro反序列化漏洞的检测、利用、后渗透整个链路一体化的解决方案。你可以把它理解为一个高度集成的“武器化平台”它把过去需要你手动在BurpSuite、命令行、各种小脚本之间来回切换的工作全部整合到了一个流程化的框架里。从发送第一个探测包开始到最终在目标服务器上植入一个稳定的内存Webshell整个过程可以近乎自动化地完成。这对于企业安全团队进行内部攻防演练、渗透测试人员提升效率甚至对于蓝队构建更精准的检测模型都有着非常实际的价值。2. 核心设计思路从单点工具到流程化作战平台ShiroAttack2的设计哲学非常明确流程化、场景化、高可用。它摒弃了“工具集合”的堆砌思路而是围绕一次完整的攻击链来构建功能模块。2.1 模块化攻击链设计整个工具的核心流程可以抽象为四个关键阶段每个阶段都解决了传统手工测试中的痛点指纹识别与存活确认这不仅仅是检测rememberMeCookie是否存在。ShiroAttack2会结合多种特征如特定错误页面、默认URL路径等进行低干扰的预判断避免盲目发送大量攻击载荷触发告警。密钥爆破与算法识别这是传统工具的强项但ShiroAttack2将其做到了极致。它内置了涵盖常见开源项目、框架默认配置、历史漏洞泄露密钥在内的超大规模字典。更重要的是它支持多种爆破模式如基于响应时间、响应差异、DNSLog外带并能自动识别目标使用的加密模式如CBC/GCM。利用链动态组装与Payload生成这是最具技术含量的部分。工具内置了主流的Java反序列化利用链如CommonsBeanutils, CommonsCollections系列等并能根据目标环境的实际情况如通过报错信息判断依赖库版本动态推荐或尝试最有可能成功的链。Payload生成器则负责将利用链与用户指定的命令如whoami或内存马模板进行结合并处理序列化、加密、编码等繁琐步骤。内存马注入与管理漏洞利用的终点不应该是执行一次命令而是建立一个持久的、隐蔽的控制通道。ShiroAttack2深度集成了多种形态的Java内存Webshell如Filter型、Servlet型、Interceptor型、Spring Controller型等。它能够自动将内存马注入到目标应用的运行时中并提供连接管理、心跳检测、批量管理等功能实现了真正的“漏洞利用即服务”。2.2 高度可扩展的插件架构任何工具都无法覆盖所有场景。ShiroAttack2采用了插件化的架构将核心引擎与具体功能解耦。这意味着利用链插件当出现新的利用链例如针对Shiro 1.4.2的Padding Oracle攻击时可以快速编写插件集成而无需修改核心代码。Payload编码插件针对不同的WAF规则可以自定义Payload的编码、混淆方式如多重Base64、十六进制、随机注释插入等。内存马模板插件安全研究人员可以贡献更隐蔽、功能更强的内存马实现直接嵌入到工具生态中。这种设计保证了工具的生命力能够快速适应攻防对抗的演进。3. 核心功能深度解析与实操要点理解了设计思路我们深入到每个核心功能模块看看它们具体如何工作以及在实际操作中需要注意什么。3.1 智能密钥爆破不仅仅是跑字典密钥爆破是Shiro漏洞利用的基石。ShiroAttack2在此环节做了大量优化。原理与实现 Shiro的rememberMeCookie值由三部分组成序列化数据 加密算法 密钥。加密过程可以简化为AES_Encrypt(序列化数据, 密钥)。爆破的本质就是用候选密钥去解密Cookie中的密文如果解密后能成功反序列化或符合某种特征则认为密钥正确。ShiroAttack2的爆破引擎支持以下模式标准模式发送携带rememberMeCookie的请求根据HTTP响应状态码、长度、内容的关键词如java.开头的异常信息来判断是否成功。时间盲注模式有些应用无论成功失败都返回200但处理异常时可能会有细微的时间差。工具会统计每个密钥尝试的响应时间通过统计分析找出异常值。DNSLog外带模式这是最隐蔽、最可靠的方式。Payload被构造为在反序列化时会触发一次DNS查询如利用URLDNS链。我们将DNSLog域名如xxx.dnslog.cn嵌入Payload如果密钥正确Payload被执行我们的DNSLog平台就会收到查询记录从而确认密钥。这种方式几乎不依赖于目标应用的任何回显。实操心得字典的质量决定成功率工具自带的字典很全但实战中我习惯结合目标特点进行补充。例如如果目标是金融或国企单位我会加入一些与单位名称拼音、缩写、常用数字组合相关的弱口令。如果目标是互联网公司则可能加入一些从GitHub泄露的该公司的历史配置代码中提取的字符串。一个高质量的、场景化的自定义字典往往能起到奇效。3.2 利用链的自动化选择与兼容性处理拿到密钥只是拿到了“门禁卡”利用链才是打开“内室”的“钥匙”。Java反序列化利用链高度依赖于目标ClassPath中存在的第三方库。ShiroAttack2的策略主动探测在爆破密钥前后工具可以发送一些精心构造的、能触发特定类ClassNotFoundException的Payload通过报错信息来推断目标环境中存在的库及其版本范围。链优先级排序工具内部为每条利用链如CommonsBeanutils1,CommonsCollections2,Jdk7u21等定义了权重。权重基于链的通用性、稳定性、所需依赖的普遍性。它会优先尝试高权重的链。回显测试在正式执行命令前工具通常会先发送一个无害的测试Payload如执行sleep 5或ping一个不存在的地址通过响应延迟来判断链是否真正可用避免“假阳性”。常见问题与排查问题密钥爆破成功但所有利用链都失败返回500错误或无反序列化迹象。排查思路Java版本检查目标Java版本。高版本Java如8u191对许多传统利用链有内置限制如Jdk7u21链失效。依赖缺失目标可能缺少commons-collections,commons-beanutils等关键依赖。此时需要尝试不依赖这些库的“通用链”或利用Shiro自身依赖中的类如BeanComparator构造链。序列化数据过滤有些Shiro版本或定制化开发可能对反序列化的类进行了过滤。需要尝试使用不同序列化流构造方式或利用原生Java类构造的链来绕过。3.3 内存马注入从一次执行到持久化控制执行单条命令如whoami是脆弱的。ShiroAttack2的核心优势在于其强大的内存马管理能力。内存马类型与选择类型注入位置优点缺点适用场景Filter型Servlet Filter 链兼容性极好几乎所有Java Web容器都支持容易被基于Filter链的监控工具发现通用首选兼容性要求高时使用Servlet型动态注册Servlet访问路径固定管理方便需要特定的URL模式可能与其他Servlet冲突需要固定API接口的场景Spring Controller型Spring MVC 控制器与Spring应用无缝集成极其隐蔽仅适用于Spring Boot/ MVC应用Spring生态系统的目标Interceptor型Spring/Struts2 拦截器执行时机早可获取更多上下文信息实现复杂依赖特定框架对深度和上下文有要求的渗透注入流程详解模板编译工具内置了各种内存马的Java源代码模板。在运行时它会根据用户配置如连接密码、通信加密方式动态编译这些模板生成字节码。类加载器劫持利用反序列化漏洞执行代码核心目的是定义一个自定义的ClassLoader或者利用当前线程的ClassLoader将内存马的字节码直接加载到JVM中。动态注册加载内存马类后调用其初始化方法。该方法会通过反射机制获取当前Web应用的上下文如ServletContext然后将自身实例Filter或Servlet动态添加到相应的容器结构中。连接建立注入成功后内存马会监听特定的URL路径。攻击者通过访问该路径并携带正确的密码即可建立一个交互式的Webshell通道支持文件管理、命令执行、代理转发等高级功能。注意事项内存马的隐蔽性与清理隐蔽性默认的内存马路径和密码一定要修改不要使用/favicon.ico、/test这类常见路径。密码应设置得复杂一些。工具应支持AES加密通信避免流量被明文检测。清理痕迹内存马驻留在JVM中重启应用即消失。但注入过程中可能会在日志、临时文件中留下痕迹。高级的内存马会主动清理这些痕迹或通过无文件落地的方式执行。在实战中需权衡持久性与风险。对抗检测越来越多的RASP和主机安全软件能检测内存马。注入时可以考虑使用“冰蝎”、“哥斯拉”等成熟Webshell的通信协议进行伪装或者将内存马功能拆解分散到多个看似正常的类中。4. 实战操作流程一次完整的攻防演练假设我们目标为http://vuln-app.example.com。下面演示如何使用ShiroAttack2进行全流程攻击。4.1 环境准备与目标侦察首先启动ShiroAttack2通常是一个图形化客户端或命令行工具。在目标URL栏输入http://vuln-app.example.com。第一步基础指纹探测工具会自动发送几个低干扰的请求访问根路径/分析响应头如Set-Cookie是否包含rememberMe和页面内容。尝试访问Shiro默认的登录/登出URL如/login,/logout。发送一个格式正确但密钥错误的rememberMeCookie观察响应与正常请求的差异如是否出现rememberMe字段被删除、是否有特定的错误信息。这个阶段的目标是确认目标应用很可能使用了Shiro框架并且rememberMe功能处于开启状态。4.2 密钥爆破阶段在工具界面选择“爆破”模块。爆破模式优先选择DNSLog模式。这是最隐蔽可靠的。你需要配置一个DNSLog平台如ceye.io或自建的域名和API Token。密钥字典加载内置的top100.txt字典进行快速尝试。如果失败再切换至完整字典shiro_keys.txt。并发线程根据目标网络状况调整一般设置为5-10过高可能触发WAF或导致请求失败。点击开始工具会为字典中的每个密钥构造一个特殊的Payload。这个Payload被密钥加密后作为Cookie发送。如果密钥正确Payload中的DNS查询代码会被执行我们将在DNSLog平台看到一条新的解析记录。成功示例[] 目标: http://vuln-app.example.com [] 模式: DNSLog [] 尝试密钥: kPHbIxk5D2deZiIxcaaaA [!] DNSLog 收到记录: 7a89b1c2.kPHbIxk5D2deZiIxcaaaA.dnslog.cn [] 爆破成功确认密钥: kPHbIxk5D2deZiIxcaaaA4.3 利用链检测与命令执行获取密钥后进入“利用”模块。工具会自动加载所有可用的利用链插件。自动检测点击“检测可用链”工具会依次发送各利用链的测试Payload通常是一个无害的sleep 3命令。通过比较响应时间判断链是否可用。选择链与命令从检测成功的链中选择一个通常选最通用的如CommonsBeanutils1。在命令输入框填入whoami或id。执行点击“执行”。工具会完成以下工作将命令拼接进利用链、序列化、用刚才爆破的密钥进行AES加密、Base64编码、构造HTTP请求并发送、解密并解析响应中的命令执行结果。结果回显处理 命令执行的结果标准输出和错误输出需要被回传。ShiroAttack2支持多种回显方式直接回显如果应用将异常信息打印到页面可以利用报错信息带出数据。这是最理想的情况。HTTP请求外带将命令结果通过HTTP请求发送到攻击者控制的服务器。这是最通用的方式。DNS外带同密钥爆破将结果分段编码到子域名中进行外带适用于网络限制严格的场景。工具会自动选择最合适的回显方式并将最终结果显示在界面上。4.4 内存马注入与持久化控制在成功执行命令后切换到“内存马”模块。选择类型根据前期信息搜集如页面特征判断是否为Spring Boot选择合适的内存马类型。不确定时选“Filter型”。配置参数路径设置为一个不易被扫描到的路径如/static/upload/xxx.css。密码设置一个强密码用于连接认证。加密密钥启用AES加密通信确保流量内容不被识别。生成与注入点击“生成”工具会编译内存马字节码并将其作为Payload通过已验证的利用链发送执行。连接管理注入成功后在工具的“连接管理”界面添加一个新的连接填写目标URL、内存马路径和密码。点击“连接”如果成功你将获得一个功能完整的Webshell管理界面可以进行文件浏览、终端命令执行、数据库连接等操作。5. 高级对抗与疑难问题排查实录在实际企业环境中你会遇到各种加固和防护措施。以下是常见问题及应对策略。5.1 绕过WAF与流量检测现象爆破或利用请求被WAF拦截返回403/405等状态码。解决方案Payload编码与混淆多重编码对最终的rememberMeCookie值进行多次URL编码、HTML实体编码。大小写变换将Cookie名rememberMe改为RememberMe、REMEMBERME等。分块传输尝试使用HTTP分块传输编码Chunked Transfer Encoding来拆分请求体绕过一些基于正则的检测。协议层面尝试使用HTTPS协议如果目标支持有时WAF对HTTPS流量的检测规则不同。利用ShiroAttack2的插件功能编写或使用现有的“编码插件”在Payload生成后、发送前自动进行上述混淆操作。5.2 目标环境依赖复杂或版本过高现象密钥正确但所有内置利用链都失败。解决方案尝试“无依赖”链重点尝试Jdk7u21、Jdk8u20这类仅依赖JDK自身类的链。虽然高版本Java可能受限但仍有一线希望。利用Shiro自身类深入研究Shiro 1.2.4及以上版本自带的org.apache.shiro.jndi.JndiLocator等类尝试构造JNDI注入链配合LDAP服务器实现RCE。这在某些禁止出网但能访问内部LDAP的环境中有奇效。自定义利用链这是高级玩法。通过分析目标应用依赖的jar包有时可以从错误信息或/WEB-INF/lib/目录列出寻找可利用的getter/setter或compare方法手工构造一条新的利用链并制作成插件导入ShiroAttack2使用。5.3 内存马被安全软件或RASP杀死现象内存马注入成功但连接几次后失效或一开始就无法连接。排查与应对检查注入的Filter顺序通过内存马的管理功能如果支持或发送特殊指令查看当前Filter链。确保你的内存马Filter排在安全软件或防护Filter之前否则请求可能被拦截。使用更隐蔽的内存马类型尝试从Filter型切换到Spring Controller型或Interceptor型。后两者更贴近业务代码被通用规则检测的概率更低。模拟合法流量修改内存马的通信协议使其HTTP请求和响应的格式、头部看起来与正常业务API完全一致。使用“无文件”落地技术避免在注入过程中产生任何临时的class文件。确保整个字节码的加载和类的定义完全在内存中完成。5.4 工具使用中的常见报错与处理错误现象可能原因排查步骤爆破时所有密钥都快速失败目标可能未开启rememberMe或WAF拦截了所有异常请求1. 确认指纹探测阶段是否明确识别出Shiro。2. 换用DNSLog模式并检查DNSLog平台配置是否正确。3. 降低并发线程数增加请求间隔。密钥正确但执行命令无回显利用链执行成功但回显方式不匹配1. 在“利用”模块切换不同的“回显方式”尝试如从“直接回显”切换到“HTTP外带”。2. 检查外带服务器如HTTP监听端口是否收到请求。内存马连接失败内存马未成功注入路径/密码错误流量被拦截1. 先用命令执行功能验证ls /或dir确保利用链依然有效。2. 尝试访问内存马路径不带参数看是否返回特定错误如404或空响应。3. 使用Wireshark等工具抓包查看连接请求是否发出以及服务器返回了什么。工具运行时Java内存溢出加载的字典过大或并发过高1. 为启动命令增加JVM参数-Xmx2048m -Xms512m。2. 使用更精简的字典文件。3. 降低爆破和检测的并发数。真正的企业级攻防工具只是辅助。ShiroAttack2这样的集成化解决方案极大地提升了效率但面对高度定制化、深度防护的目标依然需要测试人员深厚的技术功底、丰富的经验和对目标环境的持续分析。它把我们从重复的机械劳动中解放出来让我们能更专注于策略的思考和边界的突破。记住工具是死的思路是活的。理解每一个步骤背后的原理才能在遇到问题时游刃有余也能在工具失效时自己创造出新的“武器”。